diff --git a/vendor/sebastian/recursion-context/.gitignore b/.gitignore similarity index 50% rename from vendor/sebastian/recursion-context/.gitignore rename to .gitignore index 77aae3d..a305491 100644 --- a/vendor/sebastian/recursion-context/.gitignore +++ b/.gitignore @@ -1,3 +1,3 @@ -/.idea -/composer.lock /vendor +/.idea +composer.lock \ No newline at end of file diff --git a/composer.json b/composer.json index 934a71e..5325c45 100644 --- a/composer.json +++ b/composer.json @@ -4,7 +4,7 @@ "type": "cakephp-plugin", "require": { "php": ">=5.4.16", - "cakephp/cakephp": "~3.0" + "cakephp/cakephp": "^3.6", }, "require-dev": { "phpunit/phpunit": "*" diff --git a/vendor/aura/intl/.gitignore b/vendor/aura/intl/.gitignore deleted file mode 100644 index 75d706b..0000000 --- a/vendor/aura/intl/.gitignore +++ /dev/null @@ -1,3 +0,0 @@ -/tests/tmp -/vendor -/composer.lock diff --git a/vendor/aura/intl/.travis.yml b/vendor/aura/intl/.travis.yml deleted file mode 100644 index 823c704..0000000 --- a/vendor/aura/intl/.travis.yml +++ /dev/null @@ -1,14 +0,0 @@ -sudo: false -language: php -php: - - 5.6 - - hhvm - - 7 -before_script: - - composer self-update - - composer install -script: - - phpunit --coverage-clover=coverage.clover -after_script: - - wget https://scrutinizer-ci.com/ocular.phar - - php ocular.phar code-coverage:upload --format=php-clover coverage.clover diff --git a/vendor/aura/intl/LICENSE b/vendor/aura/intl/LICENSE deleted file mode 100644 index 5f5f3b6..0000000 --- a/vendor/aura/intl/LICENSE +++ /dev/null @@ -1,21 +0,0 @@ -The MIT License (MIT) - -Copyright (c) 2017, Aura for PHP - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in -all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -THE SOFTWARE. diff --git a/vendor/aura/intl/README.md b/vendor/aura/intl/README.md deleted file mode 100644 index 0537d47..0000000 --- a/vendor/aura/intl/README.md +++ /dev/null @@ -1,59 +0,0 @@ -# Aura.Intl - -The Aura.Intl package provides internationalization (I18N) tools, specifically -package-oriented per-locale message translation. - -## Installation and Autoloading - -This package is installable and PSR-4 autoloadable via Composer as -[aura/intl][]. - -Alternatively, [download a release][], or clone this repository, then map the -`Aura\Intl\` namespace to the package `src/` directory. - -## Dependencies - -This package requires PHP 5.6 or later; it has been tested on PHP 5.6, 7.0 -and HHVM. We recommend using the latest available version of PHP as a matter of -principle. - -Aura library packages may sometimes depend on external interfaces, but never on -external implementations. This allows compliance with community standards -without compromising flexibility. For specifics, please examine the package -[composer.json][] file. - -## Quality - -[![Scrutinizer Code Quality](https://scrutinizer-ci.com/g/auraphp/Aura.Intl/badges/quality-score.png?b=3.x)](https://scrutinizer-ci.com/g/auraphp/Aura.Intl/) -[![Code Coverage](https://scrutinizer-ci.com/g/auraphp/Aura.Intl/badges/coverage.png?b=3.x)](https://scrutinizer-ci.com/g/auraphp/Aura.Intl/) -[![Build Status](https://travis-ci.org/auraphp/Aura.Intl.png?branch=3.x)](https://travis-ci.org/auraphp/Aura.Intl) - -This project adheres to [Semantic Versioning](http://semver.org/). - -To run the unit tests at the command line, issue `composer install` and then -`phpunit` at the package root. This requires [Composer][] to be available as -`composer`, and [PHPUnit][] to be available as `phpunit`. - -This package attempts to comply with [PSR-1][], [PSR-2][], and [PSR-4][]. If -you notice compliance oversights, please send a patch via pull request. - -## Community - -To ask questions, provide feedback, or otherwise communicate with other Aura -users, please join our [Google Group][], follow [@auraphp][], or chat with us -on Freenode in the #auraphp channel. - -## Documentation - -This package is fully documented [here](./docs/index.md). - -[PSR-1]: https://github.com/php-fig/fig-standards/blob/master/accepted/PSR-1-basic-coding-standard.md -[PSR-2]: https://github.com/php-fig/fig-standards/blob/master/accepted/PSR-2-coding-style-guide.md -[PSR-4]: https://github.com/php-fig/fig-standards/blob/master/accepted/PSR-4-autoloader.md -[Composer]: http://getcomposer.org/ -[PHPUnit]: http://phpunit.de/ -[Google Group]: http://groups.google.com/group/auraphp -[@auraphp]: http://twitter.com/auraphp -[download a release]: https://github.com/auraphp/Aura.Intl/releases -[aura/intl]: https://packagist.org/packages/aura/intl -[composer.json]: ./composer.json diff --git a/vendor/aura/intl/composer.json b/vendor/aura/intl/composer.json deleted file mode 100644 index 6366d0a..0000000 --- a/vendor/aura/intl/composer.json +++ /dev/null @@ -1,35 +0,0 @@ -{ - "name": "aura/intl", - "type": "library", - "description": "The Aura Intl package provides internationalization tools, specifically message translation.", - "keywords": [ - "intl", - "internationalization", - "i18n", - "l10n", - "localization", - "globalization", - "g11n" - ], - "homepage": "https://github.com/auraphp/Aura.Intl", - "license": "MIT", - "authors": [ - { - "name": "Aura.Intl Contributors", - "homepage": "https://github.com/auraphp/Aura.Intl/contributors" - } - ], - "require": { - "php": "^5.6|^7.0" - }, - "autoload": { - "psr-4": { - "Aura\\Intl\\": "src/" - } - }, - "autoload-dev": { - "psr-4": { - "Aura\\Intl\\": "tests/" - } - } -} diff --git a/vendor/autoload.php b/vendor/autoload.php deleted file mode 100644 index 2677eba..0000000 --- a/vendor/autoload.php +++ /dev/null @@ -1,7 +0,0 @@ - - - CakePHP - -

-

- - Software License - - - Build Status - - - Coverage Status - - - Code Consistency - - - Total Downloads - - - Latest Stable Version - -

- -[CakePHP](https://cakephp.org) is a rapid development framework for PHP which -uses commonly known design patterns like Associative Data -Mapping, Front Controller, and MVC. Our primary goal is to provide a structured -framework that enables PHP users at all levels to rapidly develop robust web -applications, without any loss to flexibility. - -## Installing CakePHP via Composer - -You can install CakePHP into your project using -[Composer](https://getcomposer.org). If you're starting a new project, we -recommend using the [app skeleton](https://github.com/cakephp/app) as -a starting point. For existing applications you can run the following: - -``` bash -$ composer require cakephp/cakephp:"~3.6" -``` - -## Running Tests - -Assuming you have PHPUnit installed system wide using one of the methods stated -[here](https://phpunit.de/manual/current/en/installation.html), you can run the -tests for CakePHP by doing the following: - -1. Copy `phpunit.xml.dist` to `phpunit.xml`. -2. Add the relevant database credentials to your `phpunit.xml` if you want to run tests against - a non-SQLite datasource. -3. Run `phpunit`. - -## Some Handy Links - -* [CakePHP](https://cakephp.org) - The rapid development PHP framework. -* [CookBook](https://book.cakephp.org) - The CakePHP user documentation; start learning here! -* [API](https://api.cakephp.org) - A reference to CakePHP's classes. -* [Awesome CakePHP](https://github.com/FriendsOfCake/awesome-cakephp) - A list of featured resources around the framework. -* [Plugins](https://plugins.cakephp.org) - A repository of extensions to the framework. -* [The Bakery](https://bakery.cakephp.org) - Tips, tutorials and articles. -* [Community Center](https://community.cakephp.org) - A source for everything community related. -* [Training](https://training.cakephp.org) - Join a live session and get skilled with the framework. -* [CakeFest](https://cakefest.org) - Don't miss our annual CakePHP conference. -* [Cake Software Foundation](https://cakefoundation.org) - Promoting development related to CakePHP. - -## Get Support! - -* [Slack](https://cakesf.herokuapp.com/) - Join us on Slack. -* [#cakephp](https://webchat.freenode.net/?channels=#cakephp) on irc.freenode.net - Come chat with us, we have cake. -* [Forum](https://discourse.cakephp.org/) - Official CakePHP forum. -* [GitHub Issues](https://github.com/cakephp/cakephp/issues) - Got issues? Please tell us! -* [Roadmaps](https://github.com/cakephp/cakephp/wiki#roadmaps) - Want to contribute? Get involved! - -## Contributing - -* [CONTRIBUTING.md](.github/CONTRIBUTING.md) - Quick pointers for contributing to the CakePHP project. -* [CookBook "Contributing" Section](https://book.cakephp.org/3.0/en/contributing.html) - Details about contributing to the project. - -# Security - -If you’ve found a security issue in CakePHP, please use the following procedure instead of the normal bug reporting system. Instead of using the bug tracker, mailing list or IRC please send an email to security [at] cakephp.org. Emails sent to this address go to the CakePHP core team on a private mailing list. - -For each report, we try to first confirm the vulnerability. Once confirmed, the CakePHP team will take the following actions: - -- Acknowledge to the reporter that we’ve received the issue, and are working on a fix. We ask that the reporter keep the issue confidential until we announce it. -- Get a fix/patch prepared. -- Prepare a post describing the vulnerability, and the possible exploits. -- Release new versions of all affected versions. -- Prominently feature the problem in the release announcement. diff --git a/vendor/cakephp/cakephp/VERSION.txt b/vendor/cakephp/cakephp/VERSION.txt deleted file mode 100644 index 36d2335..0000000 --- a/vendor/cakephp/cakephp/VERSION.txt +++ /dev/null @@ -1,19 +0,0 @@ -//////////////////////////////////////////////////////////////////////////////////////////////////// -// +--------------------------------------------------------------------------------------------+ // -// CakePHP Version -// -// Holds a static string representing the current version of CakePHP -// -// CakePHP(tm) : Rapid Development Framework (https://cakephp.org) -// Copyright (c) Cake Software Foundation, Inc. (https://cakefoundation.org) -// -// Licensed under The MIT License -// Redistributions of files must retain the above copyright notice. -// -// @copyright Copyright (c) Cake Software Foundation, Inc. (https://cakefoundation.org) -// @link https://cakephp.org -// @since CakePHP(tm) v 0.2.9 -// @license https://opensource.org/licenses/mit-license.php MIT License -// +--------------------------------------------------------------------------------------------+ // -//////////////////////////////////////////////////////////////////////////////////////////////////// -3.6.2 diff --git a/vendor/cakephp/cakephp/composer.json b/vendor/cakephp/cakephp/composer.json deleted file mode 100644 index 8818ca5..0000000 --- a/vendor/cakephp/cakephp/composer.json +++ /dev/null @@ -1,100 +0,0 @@ -{ - "name": "cakephp/cakephp", - "description": "The CakePHP framework", - "type": "library", - "keywords": [ - "framework", - "mvc", - "rapid-development", - "conventions over configuration", - "dry", - "orm", - "form", - "validation", - "psr-7" - ], - "homepage": "https://cakephp.org", - "license": "MIT", - "authors": [ - { - "name": "CakePHP Community", - "homepage": "https://github.com/cakephp/cakephp/graphs/contributors" - } - ], - "support": { - "issues": "https://github.com/cakephp/cakephp/issues", - "forum": "https://stackoverflow.com/tags/cakephp", - "irc": "irc://irc.freenode.org/cakephp", - "source": "https://github.com/cakephp/cakephp" - }, - "require": { - "php": ">=5.6.0", - "ext-intl": "*", - "ext-mbstring": "*", - "cakephp/chronos": "^1.0.1", - "aura/intl": "^3.0.0", - "psr/log": "^1.0.0", - "zendframework/zend-diactoros": "^1.4.0" - }, - "suggest": { - "ext-openssl": "To use Security::encrypt() or have secure CSRF token generation.", - "lib-ICU": "The intl PHP library, to use Text::transliterate() or Text::slug()" - }, - "require-dev": { - "phpunit/phpunit": "^5.7.14|^6.0", - "cakephp/cakephp-codesniffer": "^3.0" - }, - "autoload": { - "psr-4": { - "Cake\\": "src/" - }, - "files": [ - "src/Core/functions.php", - "src/Collection/functions.php", - "src/I18n/functions.php", - "src/Utility/bootstrap.php" - ] - }, - "autoload-dev": { - "psr-4": { - "Cake\\PHPStan\\": "tests/PHPStan/", - "Cake\\Test\\": "tests/", - "TestApp\\": "tests/test_app/TestApp/", - "TestPlugin\\": "tests/test_app/Plugin/TestPlugin/src/", - "TestPlugin\\Test\\": "tests/test_app/Plugin/TestPlugin/tests/", - "TestPluginTwo\\": "tests/test_app/Plugin/TestPluginTwo/src/", - "Company\\TestPluginThree\\": "tests/test_app/Plugin/Company/TestPluginThree/src/", - "Company\\TestPluginThree\\Test\\": "tests/test_app/Plugin/Company/TestPluginThree/tests/", - "ParentPlugin\\": "tests/test_app/Plugin/ParentPlugin/src/", - "PluginJs\\": "tests/test_app/Plugin/PluginJs/src/" - } - }, - "replace": { - "cakephp/cache": "self.version", - "cakephp/collection": "self.version", - "cakephp/core": "self.version", - "cakephp/datasource": "self.version", - "cakephp/database": "self.version", - "cakephp/event": "self.version", - "cakephp/filesystem": "self.version", - "cakephp/form": "self.version", - "cakephp/i18n": "self.version", - "cakephp/log": "self.version", - "cakephp/orm": "self.version", - "cakephp/utility": "self.version", - "cakephp/validation": "self.version" - }, - "conflict": { - "phpunit/phpunit": "<5.7" - }, - "scripts": { - "check": [ - "@cs-check", - "@test" - ], - "cs-check": "phpcs --colors -p ./src ./tests", - "cs-fix": "phpcbf --colors ./src ./tests", - "test": "phpunit", - "test-coverage": "phpunit --coverage-clover=clover.xml" - } -} diff --git a/vendor/cakephp/cakephp/config/bootstrap.php b/vendor/cakephp/cakephp/config/bootstrap.php deleted file mode 100644 index 1e40cbf..0000000 --- a/vendor/cakephp/cakephp/config/bootstrap.php +++ /dev/null @@ -1,23 +0,0 @@ - trim(array_pop($versionFile)) -]; diff --git a/vendor/cakephp/cakephp/contrib/pre-commit b/vendor/cakephp/cakephp/contrib/pre-commit deleted file mode 100644 index 17332fc..0000000 --- a/vendor/cakephp/cakephp/contrib/pre-commit +++ /dev/null @@ -1,38 +0,0 @@ -#!/bin/sh -FILES=`git diff --cached --name-only --diff-filter=ACMR HEAD | grep \\\\.php` -PROJECT=`php -r "echo dirname(dirname(realpath('$0')));"` - -# Determine if a file list is passed -if [ "$#" -eq 1 ] -then - oIFS=$IFS - IFS=' - ' - SFILES="$1" - IFS=$oIFS -fi -SFILES=${SFILES:-$FILES} - -echo "Checking PHP Lint..." -for FILE in $SFILES -do - php -l -d display_errors=0 $PROJECT/$FILE - if [ $? != 0 ] - then - echo "Fix the error before commit." - exit 1 - fi - FILES="$FILES $PROJECT/$FILE" -done - -if [ "$SFILES" != "" ] -then - echo "Running PHPCS" - ./vendor/bin/phpcs --standard=vendor/cakephp/cakephp-codesniffer/CakePHP $SFILES - if [ $? != 0 ] - then - echo "PHPCS Errors found; commit aborted." - exit 1 - fi -fi -exit $? diff --git a/vendor/cakephp/cakephp/phpcs.xml.dist b/vendor/cakephp/cakephp/phpcs.xml.dist deleted file mode 100644 index 9d4c21b..0000000 --- a/vendor/cakephp/cakephp/phpcs.xml.dist +++ /dev/null @@ -1,9 +0,0 @@ - - - - - - - 0 - - diff --git a/vendor/cakephp/cakephp/src/Auth/AbstractPasswordHasher.php b/vendor/cakephp/cakephp/src/Auth/AbstractPasswordHasher.php deleted file mode 100644 index 3aef37c..0000000 --- a/vendor/cakephp/cakephp/src/Auth/AbstractPasswordHasher.php +++ /dev/null @@ -1,79 +0,0 @@ -setConfig($config); - } - - /** - * Generates password hash. - * - * @param string|array $password Plain text password to hash or array of data - * required to generate password hash. - * @return string Password hash - */ - abstract public function hash($password); - - /** - * Check hash. Generate hash from user provided password string or data array - * and check against existing hash. - * - * @param string|array $password Plain text password to hash or data array. - * @param string $hashedPassword Existing hashed password. - * @return bool True if hashes match else false. - */ - abstract public function check($password, $hashedPassword); - - /** - * Returns true if the password need to be rehashed, due to the password being - * created with anything else than the passwords generated by this class. - * - * Returns true by default since the only implementation users should rely - * on is the one provided by default in php 5.5+ or any compatible library - * - * @param string $password The password to verify - * @return bool - */ - public function needsRehash($password) - { - return password_needs_rehash($password, PASSWORD_DEFAULT); - } -} diff --git a/vendor/cakephp/cakephp/src/Auth/BaseAuthenticate.php b/vendor/cakephp/cakephp/src/Auth/BaseAuthenticate.php deleted file mode 100644 index d5678d2..0000000 --- a/vendor/cakephp/cakephp/src/Auth/BaseAuthenticate.php +++ /dev/null @@ -1,268 +0,0 @@ - ['some_finder_option' => 'some_value']] - * - `passwordHasher` Password hasher class. Can be a string specifying class name - * or an array containing `className` key, any other keys will be passed as - * config to the class. Defaults to 'Default'. - * - Options `scope` and `contain` have been deprecated since 3.1. Use custom - * finder instead to modify the query to fetch user record. - * - * @var array - */ - protected $_defaultConfig = [ - 'fields' => [ - 'username' => 'username', - 'password' => 'password' - ], - 'userModel' => 'Users', - 'scope' => [], - 'finder' => 'all', - 'contain' => null, - 'passwordHasher' => 'Default' - ]; - - /** - * A Component registry, used to get more components. - * - * @var \Cake\Controller\ComponentRegistry - */ - protected $_registry; - - /** - * Password hasher instance. - * - * @var \Cake\Auth\AbstractPasswordHasher - */ - protected $_passwordHasher; - - /** - * Whether or not the user authenticated by this class - * requires their password to be rehashed with another algorithm. - * - * @var bool - */ - protected $_needsPasswordRehash = false; - - /** - * Constructor - * - * @param \Cake\Controller\ComponentRegistry $registry The Component registry used on this request. - * @param array $config Array of config to use. - */ - public function __construct(ComponentRegistry $registry, array $config = []) - { - $this->_registry = $registry; - $this->setConfig($config); - - if ($this->getConfig('scope') || $this->getConfig('contain')) { - deprecationWarning( - 'The `scope` and `contain` options for Authentication are deprecated. ' . - 'Use the `finder` option instead to define additional conditions.' - ); - } - } - - /** - * Find a user record using the username and password provided. - * - * Input passwords will be hashed even when a user doesn't exist. This - * helps mitigate timing attacks that are attempting to find valid usernames. - * - * @param string $username The username/identifier. - * @param string|null $password The password, if not provided password checking is skipped - * and result of find is returned. - * @return bool|array Either false on failure, or an array of user data. - */ - protected function _findUser($username, $password = null) - { - $result = $this->_query($username)->first(); - - if (empty($result)) { - $hasher = $this->passwordHasher(); - $hasher->hash((string)$password); - - return false; - } - - $passwordField = $this->_config['fields']['password']; - if ($password !== null) { - $hasher = $this->passwordHasher(); - $hashedPassword = $result->get($passwordField); - if (!$hasher->check($password, $hashedPassword)) { - return false; - } - - $this->_needsPasswordRehash = $hasher->needsRehash($hashedPassword); - $result->unsetProperty($passwordField); - } - $hidden = $result->getHidden(); - if ($password === null && in_array($passwordField, $hidden)) { - $key = array_search($passwordField, $hidden); - unset($hidden[$key]); - $result->setHidden($hidden); - } - - return $result->toArray(); - } - - /** - * Get query object for fetching user from database. - * - * @param string $username The username/identifier. - * @return \Cake\ORM\Query - */ - protected function _query($username) - { - $config = $this->_config; - $table = $this->getTableLocator()->get($config['userModel']); - - $options = [ - 'conditions' => [$table->aliasField($config['fields']['username']) => $username] - ]; - - if (!empty($config['scope'])) { - $options['conditions'] = array_merge($options['conditions'], $config['scope']); - } - if (!empty($config['contain'])) { - $options['contain'] = $config['contain']; - } - - $finder = $config['finder']; - if (is_array($finder)) { - $options += current($finder); - $finder = key($finder); - } - - if (!isset($options['username'])) { - $options['username'] = $username; - } - - return $table->find($finder, $options); - } - - /** - * Return password hasher object - * - * @return \Cake\Auth\AbstractPasswordHasher Password hasher instance - * @throws \RuntimeException If password hasher class not found or - * it does not extend AbstractPasswordHasher - */ - public function passwordHasher() - { - if ($this->_passwordHasher) { - return $this->_passwordHasher; - } - - $passwordHasher = $this->_config['passwordHasher']; - - return $this->_passwordHasher = PasswordHasherFactory::build($passwordHasher); - } - - /** - * Returns whether or not the password stored in the repository for the logged in user - * requires to be rehashed with another algorithm - * - * @return bool - */ - public function needsPasswordRehash() - { - return $this->_needsPasswordRehash; - } - - /** - * Authenticate a user based on the request information. - * - * @param \Cake\Http\ServerRequest $request Request to get authentication information from. - * @param \Cake\Http\Response $response A response object that can have headers added. - * @return mixed Either false on failure, or an array of user data on success. - */ - abstract public function authenticate(ServerRequest $request, Response $response); - - /** - * Get a user based on information in the request. Primarily used by stateless authentication - * systems like basic and digest auth. - * - * @param \Cake\Http\ServerRequest $request Request object. - * @return mixed Either false or an array of user information - */ - public function getUser(ServerRequest $request) - { - return false; - } - - /** - * Handle unauthenticated access attempt. In implementation valid return values - * can be: - * - * - Null - No action taken, AuthComponent should return appropriate response. - * - Cake\Http\Response - A response object, which will cause AuthComponent to - * simply return that response. - * - * @param \Cake\Http\ServerRequest $request A request object. - * @param \Cake\Http\Response $response A response object. - * @return void - */ - public function unauthenticated(ServerRequest $request, Response $response) - { - } - - /** - * Returns a list of all events that this authenticate class will listen to. - * - * An authenticate class can listen to following events fired by AuthComponent: - * - * - `Auth.afterIdentify` - Fired after a user has been identified using one of - * configured authenticate class. The callback function should have signature - * like `afterIdentify(Event $event, array $user)` when `$user` is the - * identified user record. - * - * - `Auth.logout` - Fired when AuthComponent::logout() is called. The callback - * function should have signature like `logout(Event $event, array $user)` - * where `$user` is the user about to be logged out. - * - * @return array List of events this class listens to. Defaults to `[]`. - */ - public function implementedEvents() - { - return []; - } -} diff --git a/vendor/cakephp/cakephp/src/Auth/BaseAuthorize.php b/vendor/cakephp/cakephp/src/Auth/BaseAuthorize.php deleted file mode 100644 index d030924..0000000 --- a/vendor/cakephp/cakephp/src/Auth/BaseAuthorize.php +++ /dev/null @@ -1,66 +0,0 @@ -_registry = $registry; - $this->setConfig($config); - } - - /** - * Checks user authorization. - * - * @param array|\ArrayAccess $user Active user data - * @param \Cake\Http\ServerRequest $request Request instance. - * @return bool - */ - abstract public function authorize($user, ServerRequest $request); -} diff --git a/vendor/cakephp/cakephp/src/Auth/BasicAuthenticate.php b/vendor/cakephp/cakephp/src/Auth/BasicAuthenticate.php deleted file mode 100644 index 9ca589a..0000000 --- a/vendor/cakephp/cakephp/src/Auth/BasicAuthenticate.php +++ /dev/null @@ -1,115 +0,0 @@ - [ - * 'authenticate' => ['Basic'] - * ] - * ]; - * ``` - * - * You should also set `AuthComponent::$sessionKey = false;` in your AppController's - * beforeFilter() to prevent CakePHP from sending a session cookie to the client. - * - * Since HTTP Basic Authentication is stateless you don't need a login() action - * in your controller. The user credentials will be checked on each request. If - * valid credentials are not provided, required authentication headers will be sent - * by this authentication provider which triggers the login dialog in the browser/client. - * - * You may also want to use `$this->Auth->unauthorizedRedirect = false;`. - * By default, unauthorized users are redirected to the referrer URL, - * `AuthComponent::$loginAction`, or '/'. If unauthorizedRedirect is set to - * false, a ForbiddenException exception is thrown instead of redirecting. - */ -class BasicAuthenticate extends BaseAuthenticate -{ - - /** - * Authenticate a user using HTTP auth. Will use the configured User model and attempt a - * login using HTTP auth. - * - * @param \Cake\Http\ServerRequest $request The request to authenticate with. - * @param \Cake\Http\Response $response The response to add headers to. - * @return mixed Either false on failure, or an array of user data on success. - */ - public function authenticate(ServerRequest $request, Response $response) - { - return $this->getUser($request); - } - - /** - * Get a user based on information in the request. Used by cookie-less auth for stateless clients. - * - * @param \Cake\Http\ServerRequest $request Request object. - * @return mixed Either false or an array of user information - */ - public function getUser(ServerRequest $request) - { - $username = $request->getEnv('PHP_AUTH_USER'); - $pass = $request->getEnv('PHP_AUTH_PW'); - - if (!is_string($username) || $username === '' || !is_string($pass) || $pass === '') { - return false; - } - - return $this->_findUser($username, $pass); - } - - /** - * Handles an unauthenticated access attempt by sending appropriate login headers - * - * @param \Cake\Http\ServerRequest $request A request object. - * @param \Cake\Http\Response $response A response object. - * @return void - * @throws \Cake\Http\Exception\UnauthorizedException - */ - public function unauthenticated(ServerRequest $request, Response $response) - { - $Exception = new UnauthorizedException(); - $Exception->responseHeader($this->loginHeaders($request)); - throw $Exception; - } - - /** - * Generate the login headers - * - * @param \Cake\Http\ServerRequest $request Request object. - * @return array Headers for logging in. - */ - public function loginHeaders(ServerRequest $request) - { - $realm = $this->getConfig('realm') ?: $request->getEnv('SERVER_NAME'); - - return [ - 'WWW-Authenticate' => sprintf('Basic realm="%s"', $realm) - ]; - } -} diff --git a/vendor/cakephp/cakephp/src/Auth/ControllerAuthorize.php b/vendor/cakephp/cakephp/src/Auth/ControllerAuthorize.php deleted file mode 100644 index fc69fab..0000000 --- a/vendor/cakephp/cakephp/src/Auth/ControllerAuthorize.php +++ /dev/null @@ -1,95 +0,0 @@ -request->getParam('admin')) { - * return $user['role'] === 'admin'; - * } - * return !empty($user); - * } - * ``` - * - * The above is simple implementation that would only authorize users of the - * 'admin' role to access admin routing. - * - * @see \Cake\Controller\Component\AuthComponent::$authenticate - */ -class ControllerAuthorize extends BaseAuthorize -{ - - /** - * Controller for the request. - * - * @var \Cake\Controller\Controller - */ - protected $_Controller; - - /** - * {@inheritDoc} - */ - public function __construct(ComponentRegistry $registry, array $config = []) - { - parent::__construct($registry, $config); - $this->controller($registry->getController()); - } - - /** - * Get/set the controller this authorize object will be working with. Also - * checks that isAuthorized is implemented. - * - * @param \Cake\Controller\Controller|null $controller null to get, a controller to set. - * @return \Cake\Controller\Controller - * @throws \Cake\Core\Exception\Exception If controller does not have method `isAuthorized()`. - */ - public function controller(Controller $controller = null) - { - if ($controller) { - if (!method_exists($controller, 'isAuthorized')) { - throw new Exception(sprintf( - '%s does not implement an isAuthorized() method.', - get_class($controller) - )); - } - $this->_Controller = $controller; - } - - return $this->_Controller; - } - - /** - * Checks user authorization using a controller callback. - * - * @param array|\ArrayAccess $user Active user data - * @param \Cake\Http\ServerRequest $request Request instance. - * @return bool - */ - public function authorize($user, ServerRequest $request) - { - return (bool)$this->_Controller->isAuthorized($user); - } -} diff --git a/vendor/cakephp/cakephp/src/Auth/DefaultPasswordHasher.php b/vendor/cakephp/cakephp/src/Auth/DefaultPasswordHasher.php deleted file mode 100644 index dc9420c..0000000 --- a/vendor/cakephp/cakephp/src/Auth/DefaultPasswordHasher.php +++ /dev/null @@ -1,79 +0,0 @@ - PASSWORD_DEFAULT, - 'hashOptions' => [] - ]; - - /** - * Generates password hash. - * - * @param string $password Plain text password to hash. - * @return bool|string Password hash or false on failure - * @link https://book.cakephp.org/3.0/en/controllers/components/authentication.html#hashing-passwords - */ - public function hash($password) - { - return password_hash( - $password, - $this->_config['hashType'], - $this->_config['hashOptions'] - ); - } - - /** - * Check hash. Generate hash for user provided password and check against existing hash. - * - * @param string $password Plain text password to hash. - * @param string $hashedPassword Existing hashed password. - * @return bool True if hashes match else false. - */ - public function check($password, $hashedPassword) - { - return password_verify($password, $hashedPassword); - } - - /** - * Returns true if the password need to be rehashed, due to the password being - * created with anything else than the passwords generated by this class. - * - * @param string $password The password to verify - * @return bool - */ - public function needsRehash($password) - { - return password_needs_rehash($password, $this->_config['hashType'], $this->_config['hashOptions']); - } -} diff --git a/vendor/cakephp/cakephp/src/Auth/DigestAuthenticate.php b/vendor/cakephp/cakephp/src/Auth/DigestAuthenticate.php deleted file mode 100644 index fbc6629..0000000 --- a/vendor/cakephp/cakephp/src/Auth/DigestAuthenticate.php +++ /dev/null @@ -1,288 +0,0 @@ - [ - * 'authenticate' => ['Digest'] - * ] - * ]; - * ``` - * - * You should also set `AuthComponent::$sessionKey = false;` in your AppController's - * beforeFilter() to prevent CakePHP from sending a session cookie to the client. - * - * Since HTTP Digest Authentication is stateless you don't need a login() action - * in your controller. The user credentials will be checked on each request. If - * valid credentials are not provided, required authentication headers will be sent - * by this authentication provider which triggers the login dialog in the browser/client. - * - * You may also want to use `$this->Auth->unauthorizedRedirect = false;`. - * This causes AuthComponent to throw a ForbiddenException exception instead of - * redirecting to another page. - * - * ### Generating passwords compatible with Digest authentication. - * - * DigestAuthenticate requires a special password hash that conforms to RFC2617. - * You can generate this password using `DigestAuthenticate::password()` - * - * ``` - * $digestPass = DigestAuthenticate::password($username, $password, env('SERVER_NAME')); - * ``` - * - * If you wish to use digest authentication alongside other authentication methods, - * it's recommended that you store the digest authentication separately. For - * example `User.digest_pass` could be used for a digest password, while - * `User.password` would store the password hash for use with other methods like - * Basic or Form. - */ -class DigestAuthenticate extends BasicAuthenticate -{ - - /** - * Constructor - * - * Besides the keys specified in BaseAuthenticate::$_defaultConfig, - * DigestAuthenticate uses the following extra keys: - * - * - `secret` The secret to use for nonce validation. Defaults to Security::getSalt(). - * - `realm` The realm authentication is for, Defaults to the servername. - * - `qop` Defaults to 'auth', no other values are supported at this time. - * - `opaque` A string that must be returned unchanged by clients. - * Defaults to `md5($config['realm'])` - * - `nonceLifetime` The number of seconds that nonces are valid for. Defaults to 300. - * - * @param \Cake\Controller\ComponentRegistry $registry The Component registry - * used on this request. - * @param array $config Array of config to use. - */ - public function __construct(ComponentRegistry $registry, array $config = []) - { - $this->setConfig([ - 'nonceLifetime' => 300, - 'secret' => Security::getSalt(), - 'realm' => null, - 'qop' => 'auth', - 'opaque' => null, - ]); - - parent::__construct($registry, $config); - } - - /** - * Get a user based on information in the request. Used by cookie-less auth for stateless clients. - * - * @param \Cake\Http\ServerRequest $request Request object. - * @return mixed Either false or an array of user information - */ - public function getUser(ServerRequest $request) - { - $digest = $this->_getDigest($request); - if (empty($digest)) { - return false; - } - - $user = $this->_findUser($digest['username']); - if (empty($user)) { - return false; - } - - if (!$this->validNonce($digest['nonce'])) { - return false; - } - - $field = $this->_config['fields']['password']; - $password = $user[$field]; - unset($user[$field]); - - $hash = $this->generateResponseHash($digest, $password, $request->getEnv('ORIGINAL_REQUEST_METHOD')); - if (hash_equals($hash, $digest['response'])) { - return $user; - } - - return false; - } - - /** - * Gets the digest headers from the request/environment. - * - * @param \Cake\Http\ServerRequest $request Request object. - * @return array|bool Array of digest information. - */ - protected function _getDigest(ServerRequest $request) - { - $digest = $request->getEnv('PHP_AUTH_DIGEST'); - if (empty($digest) && function_exists('apache_request_headers')) { - $headers = apache_request_headers(); - if (!empty($headers['Authorization']) && substr($headers['Authorization'], 0, 7) === 'Digest ') { - $digest = substr($headers['Authorization'], 7); - } - } - if (empty($digest)) { - return false; - } - - return $this->parseAuthData($digest); - } - - /** - * Parse the digest authentication headers and split them up. - * - * @param string $digest The raw digest authentication headers. - * @return array|null An array of digest authentication headers - */ - public function parseAuthData($digest) - { - if (substr($digest, 0, 7) === 'Digest ') { - $digest = substr($digest, 7); - } - $keys = $match = []; - $req = ['nonce' => 1, 'nc' => 1, 'cnonce' => 1, 'qop' => 1, 'username' => 1, 'uri' => 1, 'response' => 1]; - preg_match_all('/(\w+)=([\'"]?)([a-zA-Z0-9\:\#\%\?\&@=\.\/_-]+)\2/', $digest, $match, PREG_SET_ORDER); - - foreach ($match as $i) { - $keys[$i[1]] = $i[3]; - unset($req[$i[1]]); - } - - if (empty($req)) { - return $keys; - } - - return null; - } - - /** - * Generate the response hash for a given digest array. - * - * @param array $digest Digest information containing data from DigestAuthenticate::parseAuthData(). - * @param string $password The digest hash password generated with DigestAuthenticate::password() - * @param string $method Request method - * @return string Response hash - */ - public function generateResponseHash($digest, $password, $method) - { - return md5( - $password . - ':' . $digest['nonce'] . ':' . $digest['nc'] . ':' . $digest['cnonce'] . ':' . $digest['qop'] . ':' . - md5($method . ':' . $digest['uri']) - ); - } - - /** - * Creates an auth digest password hash to store - * - * @param string $username The username to use in the digest hash. - * @param string $password The unhashed password to make a digest hash for. - * @param string $realm The realm the password is for. - * @return string the hashed password that can later be used with Digest authentication. - */ - public static function password($username, $password, $realm) - { - return md5($username . ':' . $realm . ':' . $password); - } - - /** - * Generate the login headers - * - * @param \Cake\Http\ServerRequest $request Request object. - * @return array Headers for logging in. - */ - public function loginHeaders(ServerRequest $request) - { - $realm = $this->_config['realm'] ?: $request->getEnv('SERVER_NAME'); - - $options = [ - 'realm' => $realm, - 'qop' => $this->_config['qop'], - 'nonce' => $this->generateNonce(), - 'opaque' => $this->_config['opaque'] ?: md5($realm) - ]; - - $digest = $this->_getDigest($request); - if ($digest && isset($digest['nonce']) && !$this->validNonce($digest['nonce'])) { - $options['stale'] = true; - } - - $opts = []; - foreach ($options as $k => $v) { - if (is_bool($v)) { - $v = $v ? 'true' : 'false'; - $opts[] = sprintf('%s=%s', $k, $v); - } else { - $opts[] = sprintf('%s="%s"', $k, $v); - } - } - - return [ - 'WWW-Authenticate' => 'Digest ' . implode(',', $opts) - ]; - } - - /** - * Generate a nonce value that is validated in future requests. - * - * @return string - */ - protected function generateNonce() - { - $expiryTime = microtime(true) + $this->getConfig('nonceLifetime'); - $secret = $this->getConfig('secret'); - $signatureValue = hash_hmac('sha256', $expiryTime . ':' . $secret, $secret); - $nonceValue = $expiryTime . ':' . $signatureValue; - - return base64_encode($nonceValue); - } - - /** - * Check the nonce to ensure it is valid and not expired. - * - * @param string $nonce The nonce value to check. - * @return bool - */ - protected function validNonce($nonce) - { - $value = base64_decode($nonce); - if ($value === false) { - return false; - } - $parts = explode(':', $value); - if (count($parts) !== 2) { - return false; - } - list($expires, $checksum) = $parts; - if ($expires < microtime(true)) { - return false; - } - $secret = $this->getConfig('secret'); - $check = hash_hmac('sha256', $expires . ':' . $secret, $secret); - - return hash_equals($check, $checksum); - } -} diff --git a/vendor/cakephp/cakephp/src/Auth/FallbackPasswordHasher.php b/vendor/cakephp/cakephp/src/Auth/FallbackPasswordHasher.php deleted file mode 100644 index 7f7e7cd..0000000 --- a/vendor/cakephp/cakephp/src/Auth/FallbackPasswordHasher.php +++ /dev/null @@ -1,104 +0,0 @@ - [] - ]; - - /** - * Holds the list of password hasher objects that will be used - * - * @var array - */ - protected $_hashers = []; - - /** - * Constructor - * - * @param array $config configuration options for this object. Requires the - * `hashers` key to be present in the array with a list of other hashers to be - * used - */ - public function __construct(array $config = []) - { - parent::__construct($config); - foreach ($this->_config['hashers'] as $key => $hasher) { - if (is_array($hasher) && !isset($hasher['className'])) { - $hasher['className'] = $key; - } - $this->_hashers[] = PasswordHasherFactory::build($hasher); - } - } - - /** - * Generates password hash. - * - * Uses the first password hasher in the list to generate the hash - * - * @param string $password Plain text password to hash. - * @return string Password hash - */ - public function hash($password) - { - return $this->_hashers[0]->hash($password); - } - - /** - * Verifies that the provided password corresponds to its hashed version - * - * This will iterate over all configured hashers until one of them returns - * true. - * - * @param string $password Plain text password to hash. - * @param string $hashedPassword Existing hashed password. - * @return bool True if hashes match else false. - */ - public function check($password, $hashedPassword) - { - foreach ($this->_hashers as $hasher) { - if ($hasher->check($password, $hashedPassword)) { - return true; - } - } - - return false; - } - - /** - * Returns true if the password need to be rehashed, with the first hasher present - * in the list of hashers - * - * @param string $password The password to verify - * @return bool - */ - public function needsRehash($password) - { - return $this->_hashers[0]->needsRehash($password); - } -} diff --git a/vendor/cakephp/cakephp/src/Auth/FormAuthenticate.php b/vendor/cakephp/cakephp/src/Auth/FormAuthenticate.php deleted file mode 100644 index d2311c9..0000000 --- a/vendor/cakephp/cakephp/src/Auth/FormAuthenticate.php +++ /dev/null @@ -1,81 +0,0 @@ -Auth->authenticate = [ - * 'Form' => [ - * 'finder' => ['auth' => ['some_finder_option' => 'some_value']] - * ] - * ] - * ``` - * - * When configuring FormAuthenticate you can pass in config to which fields, model and additional conditions - * are used. See FormAuthenticate::$_config for more information. - * - * @see \Cake\Controller\Component\AuthComponent::$authenticate - */ -class FormAuthenticate extends BaseAuthenticate -{ - - /** - * Checks the fields to ensure they are supplied. - * - * @param \Cake\Http\ServerRequest $request The request that contains login information. - * @param array $fields The fields to be checked. - * @return bool False if the fields have not been supplied. True if they exist. - */ - protected function _checkFields(ServerRequest $request, array $fields) - { - foreach ([$fields['username'], $fields['password']] as $field) { - $value = $request->getData($field); - if (empty($value) || !is_string($value)) { - return false; - } - } - - return true; - } - - /** - * Authenticates the identity contained in a request. Will use the `config.userModel`, and `config.fields` - * to find POST data that is used to find a matching record in the `config.userModel`. Will return false if - * there is no post data, either username or password is missing, or if the scope conditions have not been met. - * - * @param \Cake\Http\ServerRequest $request The request that contains login information. - * @param \Cake\Http\Response $response Unused response object. - * @return mixed False on login failure. An array of User data on success. - */ - public function authenticate(ServerRequest $request, Response $response) - { - $fields = $this->_config['fields']; - if (!$this->_checkFields($request, $fields)) { - return false; - } - - return $this->_findUser( - $request->getData($fields['username']), - $request->getData($fields['password']) - ); - } -} diff --git a/vendor/cakephp/cakephp/src/Auth/PasswordHasherFactory.php b/vendor/cakephp/cakephp/src/Auth/PasswordHasherFactory.php deleted file mode 100644 index aa163d7..0000000 --- a/vendor/cakephp/cakephp/src/Auth/PasswordHasherFactory.php +++ /dev/null @@ -1,58 +0,0 @@ -_user; - } - - /** - * {@inheritDoc} - */ - public function write($user) - { - $this->_user = $user; - } - - /** - * {@inheritDoc} - */ - public function delete() - { - $this->_user = null; - } - - /** - * {@inheritDoc} - */ - public function redirectUrl($url = null) - { - if ($url === null) { - return $this->_redirectUrl; - } - - if ($url === false) { - $this->_redirectUrl = null; - - return null; - } - - $this->_redirectUrl = $url; - } -} diff --git a/vendor/cakephp/cakephp/src/Auth/Storage/SessionStorage.php b/vendor/cakephp/cakephp/src/Auth/Storage/SessionStorage.php deleted file mode 100644 index 749e88e..0000000 --- a/vendor/cakephp/cakephp/src/Auth/Storage/SessionStorage.php +++ /dev/null @@ -1,140 +0,0 @@ - 'Auth.User', - 'redirect' => 'Auth.redirect' - ]; - - /** - * Constructor. - * - * @param \Cake\Http\ServerRequest $request Request instance. - * @param \Cake\Http\Response $response Response instance. - * @param array $config Configuration list. - */ - public function __construct(ServerRequest $request, Response $response, array $config = []) - { - $this->_session = $request->getSession(); - $this->setConfig($config); - } - - /** - * Read user record from session. - * - * @return array|null User record if available else null. - */ - public function read() - { - if ($this->_user !== null) { - return $this->_user ?: null; - } - - $this->_user = $this->_session->read($this->_config['key']) ?: false; - - return $this->_user ?: null; - } - - /** - * Write user record to session. - * - * The session id is also renewed to help mitigate issues with session replays. - * - * @param array|\ArrayAccess $user User record. - * @return void - */ - public function write($user) - { - $this->_user = $user; - - $this->_session->renew(); - $this->_session->write($this->_config['key'], $user); - } - - /** - * Delete user record from session. - * - * The session id is also renewed to help mitigate issues with session replays. - * - * @return void - */ - public function delete() - { - $this->_user = false; - - $this->_session->delete($this->_config['key']); - $this->_session->renew(); - } - - /** - * {@inheritDoc} - */ - public function redirectUrl($url = null) - { - if ($url === null) { - return $this->_session->read($this->_config['redirect']); - } - - if ($url === false) { - $this->_session->delete($this->_config['redirect']); - - return null; - } - - $this->_session->write($this->_config['redirect'], $url); - } -} diff --git a/vendor/cakephp/cakephp/src/Auth/Storage/StorageInterface.php b/vendor/cakephp/cakephp/src/Auth/Storage/StorageInterface.php deleted file mode 100644 index 5ed9d51..0000000 --- a/vendor/cakephp/cakephp/src/Auth/Storage/StorageInterface.php +++ /dev/null @@ -1,53 +0,0 @@ - null - ]; - - /** - * {@inheritDoc} - */ - public function __construct(array $config = []) - { - if (Configure::read('debug')) { - Debugger::checkSecurityKeys(); - } - - parent::__construct($config); - } - - /** - * Generates password hash. - * - * @param string $password Plain text password to hash. - * @return string Password hash - */ - public function hash($password) - { - return Security::hash($password, $this->_config['hashType'], true); - } - - /** - * Check hash. Generate hash for user provided password and check against existing hash. - * - * @param string $password Plain text password to hash. - * @param string $hashedPassword Existing hashed password. - * @return bool True if hashes match else false. - */ - public function check($password, $hashedPassword) - { - return $hashedPassword === $this->hash($password); - } -} diff --git a/vendor/cakephp/cakephp/src/Cache/Cache.php b/vendor/cakephp/cakephp/src/Cache/Cache.php deleted file mode 100644 index 7b74c5f..0000000 --- a/vendor/cakephp/cakephp/src/Cache/Cache.php +++ /dev/null @@ -1,670 +0,0 @@ - 'Cake\Cache\Engine\ApcuEngine', - * 'prefix' => 'my_app_' - * ]); - * ``` - * - * This would configure an APCu cache engine to the 'shared' alias. You could then read and write - * to that cache alias by using it for the `$config` parameter in the various Cache methods. - * - * In general all Cache operations are supported by all cache engines. - * However, Cache::increment() and Cache::decrement() are not supported by File caching. - * - * There are 6 built-in caching engines: - * - * - `FileEngine` - Uses simple files to store content. Poor performance, but good for - * storing large objects, or things that are not IO sensitive. Well suited to development - * as it is an easy cache to inspect and manually flush. - * - `ApcuEngine` - Uses the APCu object cache, one of the fastest caching engines. - * - `MemcacheEngine` - Uses the PECL::Memcache extension and Memcached for storage. - * Fast reads/writes, and benefits from memcache being distributed. - * - `XcacheEngine` - Uses the Xcache extension, an alternative to APCu. - * - `WincacheEngine` - Uses Windows Cache Extension for PHP. Supports wincache 1.1.0 and higher. - * This engine is recommended to people deploying on windows with IIS. - * - `RedisEngine` - Uses redis and php-redis extension to store cache data. - * - * See Cache engine documentation for expected configuration keys. - * - * @see config/app.php for configuration settings - */ -class Cache -{ - - use StaticConfigTrait; - - /** - * An array mapping url schemes to fully qualified caching engine - * class names. - * - * @var array - */ - protected static $_dsnClassMap = [ - 'apc' => 'Cake\Cache\Engine\ApcuEngine', // @deprecated Since 3.6. Use apcu instead. - 'apcu' => 'Cake\Cache\Engine\ApcuEngine', - 'file' => 'Cake\Cache\Engine\FileEngine', - 'memcached' => 'Cake\Cache\Engine\MemcachedEngine', - 'null' => 'Cake\Cache\Engine\NullEngine', - 'redis' => 'Cake\Cache\Engine\RedisEngine', - 'wincache' => 'Cake\Cache\Engine\WincacheEngine', - 'xcache' => 'Cake\Cache\Engine\XcacheEngine', - ]; - - /** - * Flag for tracking whether or not caching is enabled. - * - * @var bool - */ - protected static $_enabled = true; - - /** - * Group to Config mapping - * - * @var array - */ - protected static $_groups = []; - - /** - * Cache Registry used for creating and using cache adapters. - * - * @var \Cake\Core\ObjectRegistry - */ - protected static $_registry; - - /** - * Returns the Cache Registry instance used for creating and using cache adapters. - * - * @return \Cake\Core\ObjectRegistry - */ - public static function getRegistry() - { - if (!static::$_registry) { - static::$_registry = new CacheRegistry(); - } - - return static::$_registry; - } - - /** - * Sets the Cache Registry instance used for creating and using cache adapters. - * - * Also allows for injecting of a new registry instance. - * - * @param \Cake\Core\ObjectRegistry $registry Injectable registry object. - * @return void - */ - public static function setRegistry(ObjectRegistry $registry) - { - static::$_registry = $registry; - } - - /** - * Returns the Cache Registry instance used for creating and using cache adapters. - * Also allows for injecting of a new registry instance. - * - * @param \Cake\Core\ObjectRegistry|null $registry Injectable registry object. - * @return \Cake\Core\ObjectRegistry - * @deprecated Deprecated since 3.5. Use getRegistry() and setRegistry() instead. - */ - public static function registry(ObjectRegistry $registry = null) - { - deprecationWarning('Use Cache::getRegistry() and Cache::setRegistry() instead.'); - if ($registry) { - static::setRegistry($registry); - } - - return static::getRegistry(); - } - - /** - * Finds and builds the instance of the required engine class. - * - * @param string $name Name of the config array that needs an engine instance built - * @return void - * @throws \InvalidArgumentException When a cache engine cannot be created. - */ - protected static function _buildEngine($name) - { - $registry = static::getRegistry(); - - if (empty(static::$_config[$name]['className'])) { - throw new InvalidArgumentException( - sprintf('The "%s" cache configuration does not exist.', $name) - ); - } - - $config = static::$_config[$name]; - - try { - $registry->load($name, $config); - } catch (RuntimeException $e) { - if (!array_key_exists('fallback', $config)) { - $registry->set($name, new NullEngine()); - trigger_error($e->getMessage(), E_USER_WARNING); - - return; - } - - if ($config['fallback'] === false) { - throw $e; - } - - if ($config['fallback'] === $name) { - throw new InvalidArgumentException(sprintf('"%s" cache configuration cannot fallback to itself.', $name), null, $e); - } - - $fallbackEngine = clone static::engine($config['fallback']); - $newConfig = $config + ['groups' => [], 'prefix' => null]; - $fallbackEngine->setConfig('groups', $newConfig['groups'], false); - if ($newConfig['prefix']) { - $fallbackEngine->setConfig('prefix', $newConfig['prefix'], false); - } - $registry->set($name, $fallbackEngine); - } - - if ($config['className'] instanceof CacheEngine) { - $config = $config['className']->getConfig(); - } - - if (!empty($config['groups'])) { - foreach ($config['groups'] as $group) { - static::$_groups[$group][] = $name; - static::$_groups[$group] = array_unique(static::$_groups[$group]); - sort(static::$_groups[$group]); - } - } - } - - /** - * Fetch the engine attached to a specific configuration name. - * - * If the cache engine & configuration are missing an error will be - * triggered. - * - * @param string $config The configuration name you want an engine for. - * @return \Cake\Cache\CacheEngine When caching is disabled a null engine will be returned. - */ - public static function engine($config) - { - if (!static::$_enabled) { - return new NullEngine(); - } - - $registry = static::getRegistry(); - - if (isset($registry->{$config})) { - return $registry->{$config}; - } - - static::_buildEngine($config); - - return $registry->{$config}; - } - - /** - * Garbage collection - * - * Permanently remove all expired and deleted data - * - * @param string $config [optional] The config name you wish to have garbage collected. Defaults to 'default' - * @param int|null $expires [optional] An expires timestamp. Defaults to NULL - * @return void - */ - public static function gc($config = 'default', $expires = null) - { - $engine = static::engine($config); - $engine->gc($expires); - } - - /** - * Write data for key into cache. - * - * ### Usage: - * - * Writing to the active cache config: - * - * ``` - * Cache::write('cached_data', $data); - * ``` - * - * Writing to a specific cache config: - * - * ``` - * Cache::write('cached_data', $data, 'long_term'); - * ``` - * - * @param string $key Identifier for the data - * @param mixed $value Data to be cached - anything except a resource - * @param string $config Optional string configuration name to write to. Defaults to 'default' - * @return bool True if the data was successfully cached, false on failure - */ - public static function write($key, $value, $config = 'default') - { - $engine = static::engine($config); - if (is_resource($value)) { - return false; - } - - $success = $engine->write($key, $value); - if ($success === false && $value !== '') { - trigger_error( - sprintf( - "%s cache was unable to write '%s' to %s cache", - $config, - $key, - get_class($engine) - ), - E_USER_WARNING - ); - } - - return $success; - } - - /** - * Write data for many keys into cache. - * - * ### Usage: - * - * Writing to the active cache config: - * - * ``` - * Cache::writeMany(['cached_data_1' => 'data 1', 'cached_data_2' => 'data 2']); - * ``` - * - * Writing to a specific cache config: - * - * ``` - * Cache::writeMany(['cached_data_1' => 'data 1', 'cached_data_2' => 'data 2'], 'long_term'); - * ``` - * - * @param array $data An array of data to be stored in the cache - * @param string $config Optional string configuration name to write to. Defaults to 'default' - * @return array of bools for each key provided, indicating true for success or false for fail - * @throws \RuntimeException - */ - public static function writeMany($data, $config = 'default') - { - $engine = static::engine($config); - $return = $engine->writeMany($data); - foreach ($return as $key => $success) { - if ($success === false && $data[$key] !== '') { - throw new RuntimeException(sprintf( - '%s cache was unable to write \'%s\' to %s cache', - $config, - $key, - get_class($engine) - )); - } - } - - return $return; - } - - /** - * Read a key from the cache. - * - * ### Usage: - * - * Reading from the active cache configuration. - * - * ``` - * Cache::read('my_data'); - * ``` - * - * Reading from a specific cache configuration. - * - * ``` - * Cache::read('my_data', 'long_term'); - * ``` - * - * @param string $key Identifier for the data - * @param string $config optional name of the configuration to use. Defaults to 'default' - * @return mixed The cached data, or false if the data doesn't exist, has expired, or if there was an error fetching it - */ - public static function read($key, $config = 'default') - { - $engine = static::engine($config); - - return $engine->read($key); - } - - /** - * Read multiple keys from the cache. - * - * ### Usage: - * - * Reading multiple keys from the active cache configuration. - * - * ``` - * Cache::readMany(['my_data_1', 'my_data_2]); - * ``` - * - * Reading from a specific cache configuration. - * - * ``` - * Cache::readMany(['my_data_1', 'my_data_2], 'long_term'); - * ``` - * - * @param array $keys an array of keys to fetch from the cache - * @param string $config optional name of the configuration to use. Defaults to 'default' - * @return array An array containing, for each of the given $keys, the cached data or false if cached data could not be - * retrieved. - */ - public static function readMany($keys, $config = 'default') - { - $engine = static::engine($config); - - return $engine->readMany($keys); - } - - /** - * Increment a number under the key and return incremented value. - * - * @param string $key Identifier for the data - * @param int $offset How much to add - * @param string $config Optional string configuration name. Defaults to 'default' - * @return mixed new value, or false if the data doesn't exist, is not integer, - * or if there was an error fetching it. - */ - public static function increment($key, $offset = 1, $config = 'default') - { - $engine = static::engine($config); - if (!is_int($offset) || $offset < 0) { - return false; - } - - return $engine->increment($key, $offset); - } - - /** - * Decrement a number under the key and return decremented value. - * - * @param string $key Identifier for the data - * @param int $offset How much to subtract - * @param string $config Optional string configuration name. Defaults to 'default' - * @return mixed new value, or false if the data doesn't exist, is not integer, - * or if there was an error fetching it - */ - public static function decrement($key, $offset = 1, $config = 'default') - { - $engine = static::engine($config); - if (!is_int($offset) || $offset < 0) { - return false; - } - - return $engine->decrement($key, $offset); - } - - /** - * Delete a key from the cache. - * - * ### Usage: - * - * Deleting from the active cache configuration. - * - * ``` - * Cache::delete('my_data'); - * ``` - * - * Deleting from a specific cache configuration. - * - * ``` - * Cache::delete('my_data', 'long_term'); - * ``` - * - * @param string $key Identifier for the data - * @param string $config name of the configuration to use. Defaults to 'default' - * @return bool True if the value was successfully deleted, false if it didn't exist or couldn't be removed - */ - public static function delete($key, $config = 'default') - { - $engine = static::engine($config); - - return $engine->delete($key); - } - - /** - * Delete many keys from the cache. - * - * ### Usage: - * - * Deleting multiple keys from the active cache configuration. - * - * ``` - * Cache::deleteMany(['my_data_1', 'my_data_2']); - * ``` - * - * Deleting from a specific cache configuration. - * - * ``` - * Cache::deleteMany(['my_data_1', 'my_data_2], 'long_term'); - * ``` - * - * @param array $keys Array of cache keys to be deleted - * @param string $config name of the configuration to use. Defaults to 'default' - * @return array of boolean values that are true if the value was successfully deleted, false if it didn't exist or - * couldn't be removed - */ - public static function deleteMany($keys, $config = 'default') - { - $engine = static::engine($config); - - return $engine->deleteMany($keys); - } - - /** - * Delete all keys from the cache. - * - * @param bool $check if true will check expiration, otherwise delete all - * @param string $config name of the configuration to use. Defaults to 'default' - * @return bool True if the cache was successfully cleared, false otherwise - */ - public static function clear($check = false, $config = 'default') - { - $engine = static::engine($config); - - return $engine->clear($check); - } - - /** - * Delete all keys from the cache from all configurations. - * - * @param bool $check if true will check expiration, otherwise delete all - * @return array Status code. For each configuration, it reports the status of the operation - */ - public static function clearAll($check = false) - { - $status = []; - - foreach (self::configured() as $config) { - $status[$config] = self::clear($check, $config); - } - - return $status; - } - - /** - * Delete all keys from the cache belonging to the same group. - * - * @param string $group name of the group to be cleared - * @param string $config name of the configuration to use. Defaults to 'default' - * @return bool True if the cache group was successfully cleared, false otherwise - */ - public static function clearGroup($group, $config = 'default') - { - $engine = static::engine($config); - - return $engine->clearGroup($group); - } - - /** - * Retrieve group names to config mapping. - * - * ``` - * Cache::config('daily', ['duration' => '1 day', 'groups' => ['posts']]); - * Cache::config('weekly', ['duration' => '1 week', 'groups' => ['posts', 'archive']]); - * $configs = Cache::groupConfigs('posts'); - * ``` - * - * $configs will equal to `['posts' => ['daily', 'weekly']]` - * Calling this method will load all the configured engines. - * - * @param string|null $group group name or null to retrieve all group mappings - * @return array map of group and all configuration that has the same group - * @throws \InvalidArgumentException - */ - public static function groupConfigs($group = null) - { - foreach (array_keys(static::$_config) as $config) { - static::engine($config); - } - if ($group === null) { - return static::$_groups; - } - - if (isset(self::$_groups[$group])) { - return [$group => self::$_groups[$group]]; - } - - throw new InvalidArgumentException(sprintf('Invalid cache group %s', $group)); - } - - /** - * Re-enable caching. - * - * If caching has been disabled with Cache::disable() this method will reverse that effect. - * - * @return void - */ - public static function enable() - { - static::$_enabled = true; - } - - /** - * Disable caching. - * - * When disabled all cache operations will return null. - * - * @return void - */ - public static function disable() - { - static::$_enabled = false; - } - - /** - * Check whether or not caching is enabled. - * - * @return bool - */ - public static function enabled() - { - return static::$_enabled; - } - - /** - * Provides the ability to easily do read-through caching. - * - * When called if the $key is not set in $config, the $callable function - * will be invoked. The results will then be stored into the cache config - * at key. - * - * Examples: - * - * Using a Closure to provide data, assume `$this` is a Table object: - * - * ``` - * $results = Cache::remember('all_articles', function () { - * return $this->find('all'); - * }); - * ``` - * - * @param string $key The cache key to read/store data at. - * @param callable $callable The callable that provides data in the case when - * the cache key is empty. Can be any callable type supported by your PHP. - * @param string $config The cache configuration to use for this operation. - * Defaults to default. - * @return mixed If the key is found: the cached data, false if the data - * missing/expired, or an error. If the key is not found: boolean of the - * success of the write - */ - public static function remember($key, $callable, $config = 'default') - { - $existing = self::read($key, $config); - if ($existing !== false) { - return $existing; - } - $results = call_user_func($callable); - self::write($key, $results, $config); - - return $results; - } - - /** - * Write data for key into a cache engine if it doesn't exist already. - * - * ### Usage: - * - * Writing to the active cache config: - * - * ``` - * Cache::add('cached_data', $data); - * ``` - * - * Writing to a specific cache config: - * - * ``` - * Cache::add('cached_data', $data, 'long_term'); - * ``` - * - * @param string $key Identifier for the data. - * @param mixed $value Data to be cached - anything except a resource. - * @param string $config Optional string configuration name to write to. Defaults to 'default'. - * @return bool True if the data was successfully cached, false on failure. - * Or if the key existed already. - */ - public static function add($key, $value, $config = 'default') - { - $engine = static::engine($config); - if (is_resource($value)) { - return false; - } - - return $engine->add($key, $value); - } -} diff --git a/vendor/cakephp/cakephp/src/Cache/CacheEngine.php b/vendor/cakephp/cakephp/src/Cache/CacheEngine.php deleted file mode 100644 index 32658f0..0000000 --- a/vendor/cakephp/cakephp/src/Cache/CacheEngine.php +++ /dev/null @@ -1,298 +0,0 @@ - 3600, - 'groups' => [], - 'prefix' => 'cake_', - 'probability' => 100, - 'warnOnWriteFailures' => true, - ]; - - /** - * Contains the compiled string with all groups - * prefixes to be prepended to every key in this cache engine - * - * @var string - */ - protected $_groupPrefix; - - /** - * Initialize the cache engine - * - * Called automatically by the cache frontend. Merge the runtime config with the defaults - * before use. - * - * @param array $config Associative array of parameters for the engine - * @return bool True if the engine has been successfully initialized, false if not - */ - public function init(array $config = []) - { - $this->setConfig($config); - - if (!empty($this->_config['groups'])) { - sort($this->_config['groups']); - $this->_groupPrefix = str_repeat('%s_', count($this->_config['groups'])); - } - if (!is_numeric($this->_config['duration'])) { - $this->_config['duration'] = strtotime($this->_config['duration']) - time(); - } - - return true; - } - - /** - * Garbage collection - * - * Permanently remove all expired and deleted data - * - * @param int|null $expires [optional] An expires timestamp, invalidating all data before. - * @return void - */ - public function gc($expires = null) - { - } - - /** - * Write value for a key into cache - * - * @param string $key Identifier for the data - * @param mixed $value Data to be cached - * @return bool True if the data was successfully cached, false on failure - */ - abstract public function write($key, $value); - - /** - * Write data for many keys into cache - * - * @param array $data An array of data to be stored in the cache - * @return array of bools for each key provided, true if the data was successfully cached, false on failure - */ - public function writeMany($data) - { - $return = []; - foreach ($data as $key => $value) { - $return[$key] = $this->write($key, $value); - } - - return $return; - } - - /** - * Read a key from the cache - * - * @param string $key Identifier for the data - * @return mixed The cached data, or false if the data doesn't exist, has expired, or if there was an error fetching it - */ - abstract public function read($key); - - /** - * Read multiple keys from the cache - * - * @param array $keys An array of identifiers for the data - * @return array For each cache key (given as the array key) the cache data associated or false if the data doesn't - * exist, has expired, or if there was an error fetching it - */ - public function readMany($keys) - { - $return = []; - foreach ($keys as $key) { - $return[$key] = $this->read($key); - } - - return $return; - } - - /** - * Increment a number under the key and return incremented value - * - * @param string $key Identifier for the data - * @param int $offset How much to add - * @return bool|int New incremented value, false otherwise - */ - abstract public function increment($key, $offset = 1); - - /** - * Decrement a number under the key and return decremented value - * - * @param string $key Identifier for the data - * @param int $offset How much to subtract - * @return bool|int New incremented value, false otherwise - */ - abstract public function decrement($key, $offset = 1); - - /** - * Delete a key from the cache - * - * @param string $key Identifier for the data - * @return bool True if the value was successfully deleted, false if it didn't exist or couldn't be removed - */ - abstract public function delete($key); - - /** - * Delete all keys from the cache - * - * @param bool $check if true will check expiration, otherwise delete all - * @return bool True if the cache was successfully cleared, false otherwise - */ - abstract public function clear($check); - - /** - * Deletes keys from the cache - * - * @param array $keys An array of identifiers for the data - * @return array For each provided cache key (given back as the array key) true if the value was successfully deleted, - * false if it didn't exist or couldn't be removed - */ - public function deleteMany($keys) - { - $return = []; - foreach ($keys as $key) { - $return[$key] = $this->delete($key); - } - - return $return; - } - - /** - * Add a key to the cache if it does not already exist. - * - * Defaults to a non-atomic implementation. Subclasses should - * prefer atomic implementations. - * - * @param string $key Identifier for the data. - * @param mixed $value Data to be cached. - * @return bool True if the data was successfully cached, false on failure. - */ - public function add($key, $value) - { - $cachedValue = $this->read($key); - if ($cachedValue === false) { - return $this->write($key, $value); - } - - return false; - } - - /** - * Clears all values belonging to a group. Is up to the implementing engine - * to decide whether actually delete the keys or just simulate it to achieve - * the same result. - * - * @param string $group name of the group to be cleared - * @return bool - */ - public function clearGroup($group) - { - return false; - } - - /** - * Does whatever initialization for each group is required - * and returns the `group value` for each of them, this is - * the token representing each group in the cache key - * - * @return array - */ - public function groups() - { - return $this->_config['groups']; - } - - /** - * Generates a safe key for use with cache engine storage engines. - * - * @param string $key the key passed over - * @return bool|string string key or false - */ - public function key($key) - { - if (!$key) { - return false; - } - - $prefix = ''; - if ($this->_groupPrefix) { - $prefix = md5(implode('_', $this->groups())); - } - - $key = preg_replace('/[\s]+/', '_', strtolower(trim(str_replace([DIRECTORY_SEPARATOR, '/', '.'], '_', (string)$key)))); - - return $prefix . $key; - } - - /** - * Generates a safe key, taking account of the configured key prefix - * - * @param string $key the key passed over - * @return mixed string $key or false - * @throws \InvalidArgumentException If key's value is empty - */ - protected function _key($key) - { - $key = $this->key($key); - if ($key === false) { - throw new InvalidArgumentException('An empty value is not valid as a cache key'); - } - - return $this->_config['prefix'] . $key; - } - - /** - * Cache Engines may trigger warnings if they encounter failures during operation, - * if option warnOnWriteFailures is set to true. - * - * @param string $message The warning message. - * @return void - */ - protected function warning($message) - { - if ($this->getConfig('warnOnWriteFailures') !== true) { - return; - } - - triggerWarning($message); - } -} diff --git a/vendor/cakephp/cakephp/src/Cache/CacheRegistry.php b/vendor/cakephp/cakephp/src/Cache/CacheRegistry.php deleted file mode 100644 index 706632f..0000000 --- a/vendor/cakephp/cakephp/src/Cache/CacheRegistry.php +++ /dev/null @@ -1,114 +0,0 @@ -init($config)) { - throw new RuntimeException( - sprintf('Cache engine %s is not properly configured.', get_class($instance)) - ); - } - - $config = $instance->getConfig(); - if ($config['probability'] && time() % $config['probability'] === 0) { - $instance->gc(); - } - - return $instance; - } - - /** - * Remove a single adapter from the registry. - * - * @param string $name The adapter name. - * @return void - */ - public function unload($name) - { - unset($this->_loaded[$name]); - } -} diff --git a/vendor/cakephp/cakephp/src/Cache/Engine/ApcEngine.php b/vendor/cakephp/cakephp/src/Cache/Engine/ApcEngine.php deleted file mode 100644 index 982ed31..0000000 --- a/vendor/cakephp/cakephp/src/Cache/Engine/ApcEngine.php +++ /dev/null @@ -1,20 +0,0 @@ - 3600, - 'groups' => [], - 'isWindows' => false, - 'lock' => true, - 'mask' => 0664, - 'path' => null, - 'prefix' => 'cake_', - 'probability' => 100, - 'serialize' => true - ]; - - /** - * True unless FileEngine::__active(); fails - * - * @var bool - */ - protected $_init = true; - - /** - * Initialize File Cache Engine - * - * Called automatically by the cache frontend. - * - * @param array $config array of setting for the engine - * @return bool True if the engine has been successfully initialized, false if not - */ - public function init(array $config = []) - { - parent::init($config); - - if ($this->_config['path'] === null) { - $this->_config['path'] = sys_get_temp_dir() . DIRECTORY_SEPARATOR . 'cake_cache' . DIRECTORY_SEPARATOR; - } - if (DIRECTORY_SEPARATOR === '\\') { - $this->_config['isWindows'] = true; - } - if (substr($this->_config['path'], -1) !== DIRECTORY_SEPARATOR) { - $this->_config['path'] .= DIRECTORY_SEPARATOR; - } - if ($this->_groupPrefix) { - $this->_groupPrefix = str_replace('_', DIRECTORY_SEPARATOR, $this->_groupPrefix); - } - - return $this->_active(); - } - - /** - * Garbage collection. Permanently remove all expired and deleted data - * - * @param int|null $expires [optional] An expires timestamp, invalidating all data before. - * @return bool True if garbage collection was successful, false on failure - */ - public function gc($expires = null) - { - return $this->clear(true); - } - - /** - * Write data for key into cache - * - * @param string $key Identifier for the data - * @param mixed $data Data to be cached - * @return bool True if the data was successfully cached, false on failure - */ - public function write($key, $data) - { - if ($data === '' || !$this->_init) { - return false; - } - - $key = $this->_key($key); - - if ($this->_setKey($key, true) === false) { - return false; - } - - $lineBreak = "\n"; - - if ($this->_config['isWindows']) { - $lineBreak = "\r\n"; - } - - if (!empty($this->_config['serialize'])) { - if ($this->_config['isWindows']) { - $data = str_replace('\\', '\\\\\\\\', serialize($data)); - } else { - $data = serialize($data); - } - } - - $duration = $this->_config['duration']; - $expires = time() + $duration; - $contents = implode([$expires, $lineBreak, $data, $lineBreak]); - - if ($this->_config['lock']) { - $this->_File->flock(LOCK_EX); - } - - $this->_File->rewind(); - $success = $this->_File->ftruncate(0) && - $this->_File->fwrite($contents) && - $this->_File->fflush(); - - if ($this->_config['lock']) { - $this->_File->flock(LOCK_UN); - } - $this->_File = null; - - return $success; - } - - /** - * Read a key from the cache - * - * @param string $key Identifier for the data - * @return mixed The cached data, or false if the data doesn't exist, has - * expired, or if there was an error fetching it - */ - public function read($key) - { - $key = $this->_key($key); - - if (!$this->_init || $this->_setKey($key) === false) { - return false; - } - - if ($this->_config['lock']) { - $this->_File->flock(LOCK_SH); - } - - $this->_File->rewind(); - $time = time(); - $cachetime = (int)$this->_File->current(); - - if ($cachetime < $time || ($time + $this->_config['duration']) < $cachetime) { - if ($this->_config['lock']) { - $this->_File->flock(LOCK_UN); - } - - return false; - } - - $data = ''; - $this->_File->next(); - while ($this->_File->valid()) { - $data .= $this->_File->current(); - $this->_File->next(); - } - - if ($this->_config['lock']) { - $this->_File->flock(LOCK_UN); - } - - $data = trim($data); - - if ($data !== '' && !empty($this->_config['serialize'])) { - if ($this->_config['isWindows']) { - $data = str_replace('\\\\\\\\', '\\', $data); - } - $data = unserialize((string)$data); - } - - return $data; - } - - /** - * Delete a key from the cache - * - * @param string $key Identifier for the data - * @return bool True if the value was successfully deleted, false if it didn't - * exist or couldn't be removed - */ - public function delete($key) - { - $key = $this->_key($key); - - if ($this->_setKey($key) === false || !$this->_init) { - return false; - } - - $path = $this->_File->getRealPath(); - $this->_File = null; - - //@codingStandardsIgnoreStart - return @unlink($path); - //@codingStandardsIgnoreEnd - } - - /** - * Delete all values from the cache - * - * @param bool $check Optional - only delete expired cache items - * @return bool True if the cache was successfully cleared, false otherwise - */ - public function clear($check) - { - if (!$this->_init) { - return false; - } - $this->_File = null; - - $threshold = $now = false; - if ($check) { - $now = time(); - $threshold = $now - $this->_config['duration']; - } - - $this->_clearDirectory($this->_config['path'], $now, $threshold); - - $directory = new RecursiveDirectoryIterator($this->_config['path']); - $contents = new RecursiveIteratorIterator( - $directory, - RecursiveIteratorIterator::SELF_FIRST - ); - $cleared = []; - foreach ($contents as $path) { - if ($path->isFile()) { - continue; - } - - $path = $path->getRealPath() . DIRECTORY_SEPARATOR; - if (!in_array($path, $cleared)) { - $this->_clearDirectory($path, $now, $threshold); - $cleared[] = $path; - } - } - - return true; - } - - /** - * Used to clear a directory of matching files. - * - * @param string $path The path to search. - * @param int $now The current timestamp - * @param int $threshold Any file not modified after this value will be deleted. - * @return void - */ - protected function _clearDirectory($path, $now, $threshold) - { - if (!is_dir($path)) { - return; - } - $prefixLength = strlen($this->_config['prefix']); - - $dir = dir($path); - while (($entry = $dir->read()) !== false) { - if (substr($entry, 0, $prefixLength) !== $this->_config['prefix']) { - continue; - } - - try { - $file = new SplFileObject($path . $entry, 'r'); - } catch (Exception $e) { - continue; - } - - if ($threshold) { - $mtime = $file->getMTime(); - if ($mtime > $threshold) { - continue; - } - - $expires = (int)$file->current(); - if ($expires > $now) { - continue; - } - } - if ($file->isFile()) { - $filePath = $file->getRealPath(); - $file = null; - - //@codingStandardsIgnoreStart - @unlink($filePath); - //@codingStandardsIgnoreEnd - } - } - } - - /** - * Not implemented - * - * @param string $key The key to decrement - * @param int $offset The number to offset - * @return void - * @throws \LogicException - */ - public function decrement($key, $offset = 1) - { - throw new LogicException('Files cannot be atomically decremented.'); - } - - /** - * Not implemented - * - * @param string $key The key to increment - * @param int $offset The number to offset - * @return void - * @throws \LogicException - */ - public function increment($key, $offset = 1) - { - throw new LogicException('Files cannot be atomically incremented.'); - } - - /** - * Sets the current cache key this class is managing, and creates a writable SplFileObject - * for the cache file the key is referring to. - * - * @param string $key The key - * @param bool $createKey Whether the key should be created if it doesn't exists, or not - * @return bool true if the cache key could be set, false otherwise - */ - protected function _setKey($key, $createKey = false) - { - $groups = null; - if ($this->_groupPrefix) { - $groups = vsprintf($this->_groupPrefix, $this->groups()); - } - $dir = $this->_config['path'] . $groups; - - if (!is_dir($dir)) { - mkdir($dir, 0775, true); - } - - $path = new SplFileInfo($dir . $key); - - if (!$createKey && !$path->isFile()) { - return false; - } - if (empty($this->_File) || $this->_File->getBasename() !== $key) { - $exists = file_exists($path->getPathname()); - try { - $this->_File = $path->openFile('c+'); - } catch (Exception $e) { - trigger_error($e->getMessage(), E_USER_WARNING); - - return false; - } - unset($path); - - if (!$exists && !chmod($this->_File->getPathname(), (int)$this->_config['mask'])) { - trigger_error(sprintf( - 'Could not apply permission mask "%s" on cache file "%s"', - $this->_File->getPathname(), - $this->_config['mask'] - ), E_USER_WARNING); - } - } - - return true; - } - - /** - * Determine is cache directory is writable - * - * @return bool - */ - protected function _active() - { - $dir = new SplFileInfo($this->_config['path']); - $path = $dir->getPathname(); - $success = true; - if (!is_dir($path)) { - //@codingStandardsIgnoreStart - $success = @mkdir($path, 0775, true); - //@codingStandardsIgnoreEnd - } - - $isWritableDir = ($dir->isDir() && $dir->isWritable()); - if (!$success || ($this->_init && !$isWritableDir)) { - $this->_init = false; - trigger_error(sprintf( - '%s is not writable', - $this->_config['path'] - ), E_USER_WARNING); - } - - return $success; - } - - /** - * Generates a safe key for use with cache engine storage engines. - * - * @param string $key the key passed over - * @return mixed string $key or false - */ - public function key($key) - { - if (empty($key)) { - return false; - } - - $key = Inflector::underscore(str_replace( - [DIRECTORY_SEPARATOR, '/', '.', '<', '>', '?', ':', '|', '*', '"'], - '_', - (string)$key - )); - - return $key; - } - - /** - * Recursively deletes all files under any directory named as $group - * - * @param string $group The group to clear. - * @return bool success - */ - public function clearGroup($group) - { - $this->_File = null; - $directoryIterator = new RecursiveDirectoryIterator($this->_config['path']); - $contents = new RecursiveIteratorIterator( - $directoryIterator, - RecursiveIteratorIterator::CHILD_FIRST - ); - foreach ($contents as $object) { - $containsGroup = strpos($object->getPathname(), DIRECTORY_SEPARATOR . $group . DIRECTORY_SEPARATOR) !== false; - $hasPrefix = true; - if (strlen($this->_config['prefix']) !== 0) { - $hasPrefix = strpos($object->getBasename(), $this->_config['prefix']) === 0; - } - if ($object->isFile() && $containsGroup && $hasPrefix) { - $path = $object->getPathname(); - $object = null; - //@codingStandardsIgnoreStart - @unlink($path); - //@codingStandardsIgnoreEnd - } - } - - return true; - } -} diff --git a/vendor/cakephp/cakephp/src/Cache/Engine/MemcachedEngine.php b/vendor/cakephp/cakephp/src/Cache/Engine/MemcachedEngine.php deleted file mode 100644 index 8e6b1c5..0000000 --- a/vendor/cakephp/cakephp/src/Cache/Engine/MemcachedEngine.php +++ /dev/null @@ -1,534 +0,0 @@ - value. - * Use the \Memcached::OPT_* constants as keys. - * - * @var array - */ - protected $_defaultConfig = [ - 'compress' => false, - 'duration' => 3600, - 'groups' => [], - 'host' => null, - 'username' => null, - 'password' => null, - 'persistent' => false, - 'port' => null, - 'prefix' => 'cake_', - 'probability' => 100, - 'serialize' => 'php', - 'servers' => ['127.0.0.1'], - 'options' => [], - ]; - - /** - * List of available serializer engines - * - * Memcached must be compiled with json and igbinary support to use these engines - * - * @var array - */ - protected $_serializers = []; - - /** - * @var string[] - */ - protected $_compiledGroupNames = []; - - /** - * Initialize the Cache Engine - * - * Called automatically by the cache frontend - * - * @param array $config array of setting for the engine - * @return bool True if the engine has been successfully initialized, false if not - * @throws \InvalidArgumentException When you try use authentication without - * Memcached compiled with SASL support - */ - public function init(array $config = []) - { - if (!extension_loaded('memcached')) { - return false; - } - - $this->_serializers = [ - 'igbinary' => Memcached::SERIALIZER_IGBINARY, - 'json' => Memcached::SERIALIZER_JSON, - 'php' => Memcached::SERIALIZER_PHP - ]; - if (defined('Memcached::HAVE_MSGPACK') && Memcached::HAVE_MSGPACK) { - $this->_serializers['msgpack'] = Memcached::SERIALIZER_MSGPACK; - } - - parent::init($config); - - if (!empty($config['host'])) { - if (empty($config['port'])) { - $config['servers'] = [$config['host']]; - } else { - $config['servers'] = [sprintf('%s:%d', $config['host'], $config['port'])]; - } - } - - if (isset($config['servers'])) { - $this->setConfig('servers', $config['servers'], false); - } - - if (!is_array($this->_config['servers'])) { - $this->_config['servers'] = [$this->_config['servers']]; - } - - if (isset($this->_Memcached)) { - return true; - } - - if ($this->_config['persistent']) { - $this->_Memcached = new Memcached((string)$this->_config['persistent']); - } else { - $this->_Memcached = new Memcached(); - } - $this->_setOptions(); - - if (count($this->_Memcached->getServerList())) { - return true; - } - - $servers = []; - foreach ($this->_config['servers'] as $server) { - $servers[] = $this->parseServerString($server); - } - - if (!$this->_Memcached->addServers($servers)) { - return false; - } - - if (is_array($this->_config['options'])) { - foreach ($this->_config['options'] as $opt => $value) { - $this->_Memcached->setOption($opt, $value); - } - } - - if (empty($this->_config['username']) && !empty($this->_config['login'])) { - throw new InvalidArgumentException( - 'Please pass "username" instead of "login" for connecting to Memcached' - ); - } - - if ($this->_config['username'] !== null && $this->_config['password'] !== null) { - if (!method_exists($this->_Memcached, 'setSaslAuthData')) { - throw new InvalidArgumentException( - 'Memcached extension is not built with SASL support' - ); - } - $this->_Memcached->setOption(Memcached::OPT_BINARY_PROTOCOL, true); - $this->_Memcached->setSaslAuthData( - $this->_config['username'], - $this->_config['password'] - ); - } - - return true; - } - - /** - * Settings the memcached instance - * - * @return void - * @throws \InvalidArgumentException When the Memcached extension is not built - * with the desired serializer engine. - */ - protected function _setOptions() - { - $this->_Memcached->setOption(Memcached::OPT_LIBKETAMA_COMPATIBLE, true); - - $serializer = strtolower($this->_config['serialize']); - if (!isset($this->_serializers[$serializer])) { - throw new InvalidArgumentException( - sprintf('%s is not a valid serializer engine for Memcached', $serializer) - ); - } - - if ($serializer !== 'php' && - !constant('Memcached::HAVE_' . strtoupper($serializer)) - ) { - throw new InvalidArgumentException( - sprintf('Memcached extension is not compiled with %s support', $serializer) - ); - } - - $this->_Memcached->setOption( - Memcached::OPT_SERIALIZER, - $this->_serializers[$serializer] - ); - - // Check for Amazon ElastiCache instance - if (defined('Memcached::OPT_CLIENT_MODE') && - defined('Memcached::DYNAMIC_CLIENT_MODE') - ) { - $this->_Memcached->setOption( - Memcached::OPT_CLIENT_MODE, - Memcached::DYNAMIC_CLIENT_MODE - ); - } - - $this->_Memcached->setOption( - Memcached::OPT_COMPRESSION, - (bool)$this->_config['compress'] - ); - } - - /** - * Parses the server address into the host/port. Handles both IPv6 and IPv4 - * addresses and Unix sockets - * - * @param string $server The server address string. - * @return array Array containing host, port - */ - public function parseServerString($server) - { - $socketTransport = 'unix://'; - if (strpos($server, $socketTransport) === 0) { - return [substr($server, strlen($socketTransport)), 0]; - } - if (substr($server, 0, 1) === '[') { - $position = strpos($server, ']:'); - if ($position !== false) { - $position++; - } - } else { - $position = strpos($server, ':'); - } - $port = 11211; - $host = $server; - if ($position !== false) { - $host = substr($server, 0, $position); - $port = substr($server, $position + 1); - } - - return [$host, (int)$port]; - } - - /** - * Backwards compatible alias of parseServerString - * - * @param string $server The server address string. - * @return array Array containing host, port - * @deprecated 3.4.13 Will be removed in 4.0.0 - */ - protected function _parseServerString($server) - { - return $this->parseServerString($server); - } - - /** - * Read an option value from the memcached connection. - * - * @param string $name The option name to read. - * @return string|int|null|bool - */ - public function getOption($name) - { - return $this->_Memcached->getOption($name); - } - - /** - * Write data for key into cache. When using memcached as your cache engine - * remember that the Memcached pecl extension does not support cache expiry - * times greater than 30 days in the future. Any duration greater than 30 days - * will be treated as never expiring. - * - * @param string $key Identifier for the data - * @param mixed $value Data to be cached - * @return bool True if the data was successfully cached, false on failure - * @see https://secure.php.net/manual/en/memcache.set.php - */ - public function write($key, $value) - { - $duration = $this->_config['duration']; - if ($duration > 30 * DAY) { - $duration = 0; - } - - $key = $this->_key($key); - - return $this->_Memcached->set($key, $value, $duration); - } - - /** - * Write many cache entries to the cache at once - * - * @param array $data An array of data to be stored in the cache - * @return array of bools for each key provided, true if the data was - * successfully cached, false on failure - */ - public function writeMany($data) - { - $cacheData = []; - foreach ($data as $key => $value) { - $cacheData[$this->_key($key)] = $value; - } - - $success = $this->_Memcached->setMulti($cacheData); - - $return = []; - foreach (array_keys($data) as $key) { - $return[$key] = $success; - } - - return $return; - } - - /** - * Read a key from the cache - * - * @param string $key Identifier for the data - * @return mixed The cached data, or false if the data doesn't exist, has - * expired, or if there was an error fetching it. - */ - public function read($key) - { - $key = $this->_key($key); - - return $this->_Memcached->get($key); - } - - /** - * Read many keys from the cache at once - * - * @param array $keys An array of identifiers for the data - * @return array An array containing, for each of the given $keys, the cached data or - * false if cached data could not be retrieved. - */ - public function readMany($keys) - { - $cacheKeys = []; - foreach ($keys as $key) { - $cacheKeys[] = $this->_key($key); - } - - $values = $this->_Memcached->getMulti($cacheKeys); - $return = []; - foreach ($keys as &$key) { - $return[$key] = array_key_exists($this->_key($key), $values) ? - $values[$this->_key($key)] : false; - } - - return $return; - } - - /** - * Increments the value of an integer cached key - * - * @param string $key Identifier for the data - * @param int $offset How much to increment - * @return bool|int New incremented value, false otherwise - */ - public function increment($key, $offset = 1) - { - $key = $this->_key($key); - - return $this->_Memcached->increment($key, $offset); - } - - /** - * Decrements the value of an integer cached key - * - * @param string $key Identifier for the data - * @param int $offset How much to subtract - * @return bool|int New decremented value, false otherwise - */ - public function decrement($key, $offset = 1) - { - $key = $this->_key($key); - - return $this->_Memcached->decrement($key, $offset); - } - - /** - * Delete a key from the cache - * - * @param string $key Identifier for the data - * @return bool True if the value was successfully deleted, false if it didn't - * exist or couldn't be removed. - */ - public function delete($key) - { - $key = $this->_key($key); - - return $this->_Memcached->delete($key); - } - - /** - * Delete many keys from the cache at once - * - * @param array $keys An array of identifiers for the data - * @return array of boolean values that are true if the key was successfully - * deleted, false if it didn't exist or couldn't be removed. - */ - public function deleteMany($keys) - { - $cacheKeys = []; - foreach ($keys as $key) { - $cacheKeys[] = $this->_key($key); - } - - $success = $this->_Memcached->deleteMulti($cacheKeys); - - $return = []; - foreach ($keys as $key) { - $return[$key] = $success; - } - - return $return; - } - - /** - * Delete all keys from the cache - * - * @param bool $check If true will check expiration, otherwise delete all. - * @return bool True if the cache was successfully cleared, false otherwise - */ - public function clear($check) - { - if ($check) { - return true; - } - - $keys = $this->_Memcached->getAllKeys(); - if ($keys === false) { - return false; - } - - foreach ($keys as $key) { - if (strpos($key, $this->_config['prefix']) === 0) { - $this->_Memcached->delete($key); - } - } - - return true; - } - - /** - * Add a key to the cache if it does not already exist. - * - * @param string $key Identifier for the data. - * @param mixed $value Data to be cached. - * @return bool True if the data was successfully cached, false on failure. - */ - public function add($key, $value) - { - $duration = $this->_config['duration']; - if ($duration > 30 * DAY) { - $duration = 0; - } - - $key = $this->_key($key); - - return $this->_Memcached->add($key, $value, $duration); - } - - /** - * Returns the `group value` for each of the configured groups - * If the group initial value was not found, then it initializes - * the group accordingly. - * - * @return array - */ - public function groups() - { - if (empty($this->_compiledGroupNames)) { - foreach ($this->_config['groups'] as $group) { - $this->_compiledGroupNames[] = $this->_config['prefix'] . $group; - } - } - - $groups = $this->_Memcached->getMulti($this->_compiledGroupNames) ?: []; - if (count($groups) !== count($this->_config['groups'])) { - foreach ($this->_compiledGroupNames as $group) { - if (!isset($groups[$group])) { - $this->_Memcached->set($group, 1, 0); - $groups[$group] = 1; - } - } - ksort($groups); - } - - $result = []; - $groups = array_values($groups); - foreach ($this->_config['groups'] as $i => $group) { - $result[] = $group . $groups[$i]; - } - - return $result; - } - - /** - * Increments the group value to simulate deletion of all keys under a group - * old values will remain in storage until they expire. - * - * @param string $group name of the group to be cleared - * @return bool success - */ - public function clearGroup($group) - { - return (bool)$this->_Memcached->increment($this->_config['prefix'] . $group); - } -} diff --git a/vendor/cakephp/cakephp/src/Cache/Engine/NullEngine.php b/vendor/cakephp/cakephp/src/Cache/Engine/NullEngine.php deleted file mode 100644 index 83ba3cd..0000000 --- a/vendor/cakephp/cakephp/src/Cache/Engine/NullEngine.php +++ /dev/null @@ -1,116 +0,0 @@ - 0, - 'duration' => 3600, - 'groups' => [], - 'password' => false, - 'persistent' => true, - 'port' => 6379, - 'prefix' => 'cake_', - 'probability' => 100, - 'host' => null, - 'server' => '127.0.0.1', - 'timeout' => 0, - 'unix_socket' => false, - ]; - - /** - * Initialize the Cache Engine - * - * Called automatically by the cache frontend - * - * @param array $config array of setting for the engine - * @return bool True if the engine has been successfully initialized, false if not - */ - public function init(array $config = []) - { - if (!extension_loaded('redis')) { - return false; - } - - if (!empty($config['host'])) { - $config['server'] = $config['host']; - } - - parent::init($config); - - return $this->_connect(); - } - - /** - * Connects to a Redis server - * - * @return bool True if Redis server was connected - */ - protected function _connect() - { - try { - $this->_Redis = new Redis(); - if (!empty($this->_config['unix_socket'])) { - $return = $this->_Redis->connect($this->_config['unix_socket']); - } elseif (empty($this->_config['persistent'])) { - $return = $this->_Redis->connect($this->_config['server'], $this->_config['port'], $this->_config['timeout']); - } else { - $persistentId = $this->_config['port'] . $this->_config['timeout'] . $this->_config['database']; - $return = $this->_Redis->pconnect($this->_config['server'], $this->_config['port'], $this->_config['timeout'], $persistentId); - } - } catch (RedisException $e) { - return false; - } - if ($return && $this->_config['password']) { - $return = $this->_Redis->auth($this->_config['password']); - } - if ($return) { - $return = $this->_Redis->select($this->_config['database']); - } - - return $return; - } - - /** - * Write data for key into cache. - * - * @param string $key Identifier for the data - * @param mixed $value Data to be cached - * @return bool True if the data was successfully cached, false on failure - */ - public function write($key, $value) - { - $key = $this->_key($key); - - if (!is_int($value)) { - $value = serialize($value); - } - - $duration = $this->_config['duration']; - if ($duration === 0) { - return $this->_Redis->set($key, $value); - } - - return $this->_Redis->setex($key, $duration, $value); - } - - /** - * Read a key from the cache - * - * @param string $key Identifier for the data - * @return mixed The cached data, or false if the data doesn't exist, has expired, or if there was an error fetching it - */ - public function read($key) - { - $key = $this->_key($key); - - $value = $this->_Redis->get($key); - if (preg_match('/^[-]?\d+$/', $value)) { - return (int)$value; - } - if ($value !== false && is_string($value)) { - return unserialize($value); - } - - return $value; - } - - /** - * Increments the value of an integer cached key & update the expiry time - * - * @param string $key Identifier for the data - * @param int $offset How much to increment - * @return bool|int New incremented value, false otherwise - */ - public function increment($key, $offset = 1) - { - $duration = $this->_config['duration']; - $key = $this->_key($key); - - $value = (int)$this->_Redis->incrBy($key, $offset); - if ($duration > 0) { - $this->_Redis->setTimeout($key, $duration); - } - - return $value; - } - - /** - * Decrements the value of an integer cached key & update the expiry time - * - * @param string $key Identifier for the data - * @param int $offset How much to subtract - * @return bool|int New decremented value, false otherwise - */ - public function decrement($key, $offset = 1) - { - $duration = $this->_config['duration']; - $key = $this->_key($key); - - $value = (int)$this->_Redis->decrBy($key, $offset); - if ($duration > 0) { - $this->_Redis->setTimeout($key, $duration); - } - - return $value; - } - - /** - * Delete a key from the cache - * - * @param string $key Identifier for the data - * @return bool True if the value was successfully deleted, false if it didn't exist or couldn't be removed - */ - public function delete($key) - { - $key = $this->_key($key); - - return $this->_Redis->delete($key) > 0; - } - - /** - * Delete all keys from the cache - * - * @param bool $check If true will check expiration, otherwise delete all. - * @return bool True if the cache was successfully cleared, false otherwise - */ - public function clear($check) - { - if ($check) { - return true; - } - $keys = $this->_Redis->getKeys($this->_config['prefix'] . '*'); - - $result = []; - foreach ($keys as $key) { - $result[] = $this->_Redis->delete($key) > 0; - } - - return !in_array(false, $result); - } - - /** - * Write data for key into cache if it doesn't exist already. - * If it already exists, it fails and returns false. - * - * @param string $key Identifier for the data. - * @param mixed $value Data to be cached. - * @return bool True if the data was successfully cached, false on failure. - * @link https://github.com/phpredis/phpredis#setnx - */ - public function add($key, $value) - { - $duration = $this->_config['duration']; - $key = $this->_key($key); - - if (!is_int($value)) { - $value = serialize($value); - } - - // setnx() doesn't have an expiry option, so follow up with an expiry - if ($this->_Redis->setnx($key, $value)) { - return $this->_Redis->setTimeout($key, $duration); - } - - return false; - } - - /** - * Returns the `group value` for each of the configured groups - * If the group initial value was not found, then it initializes - * the group accordingly. - * - * @return array - */ - public function groups() - { - $result = []; - foreach ($this->_config['groups'] as $group) { - $value = $this->_Redis->get($this->_config['prefix'] . $group); - if (!$value) { - $value = 1; - $this->_Redis->set($this->_config['prefix'] . $group, $value); - } - $result[] = $group . $value; - } - - return $result; - } - - /** - * Increments the group value to simulate deletion of all keys under a group - * old values will remain in storage until they expire. - * - * @param string $group name of the group to be cleared - * @return bool success - */ - public function clearGroup($group) - { - return (bool)$this->_Redis->incr($this->_config['prefix'] . $group); - } - - /** - * Disconnects from the redis server - */ - public function __destruct() - { - if (empty($this->_config['persistent']) && $this->_Redis instanceof Redis) { - $this->_Redis->close(); - } - } -} diff --git a/vendor/cakephp/cakephp/src/Cache/Engine/WincacheEngine.php b/vendor/cakephp/cakephp/src/Cache/Engine/WincacheEngine.php deleted file mode 100644 index de32067..0000000 --- a/vendor/cakephp/cakephp/src/Cache/Engine/WincacheEngine.php +++ /dev/null @@ -1,198 +0,0 @@ -_key($key); - $duration = $this->_config['duration']; - - return wincache_ucache_set($key, $value, $duration); - } - - /** - * Read a key from the cache - * - * @param string $key Identifier for the data - * @return mixed The cached data, or false if the data doesn't exist, - * has expired, or if there was an error fetching it - */ - public function read($key) - { - $key = $this->_key($key); - - return wincache_ucache_get($key); - } - - /** - * Increments the value of an integer cached key - * - * @param string $key Identifier for the data - * @param int $offset How much to increment - * @return bool|int New incremented value, false otherwise - */ - public function increment($key, $offset = 1) - { - $key = $this->_key($key); - - return wincache_ucache_inc($key, $offset); - } - - /** - * Decrements the value of an integer cached key - * - * @param string $key Identifier for the data - * @param int $offset How much to subtract - * @return bool|int New decremented value, false otherwise - */ - public function decrement($key, $offset = 1) - { - $key = $this->_key($key); - - return wincache_ucache_dec($key, $offset); - } - - /** - * Delete a key from the cache - * - * @param string $key Identifier for the data - * @return bool True if the value was successfully deleted, false if it didn't exist or couldn't be removed - */ - public function delete($key) - { - $key = $this->_key($key); - - return wincache_ucache_delete($key); - } - - /** - * Delete all keys from the cache. This will clear every - * item in the cache matching the cache config prefix. - * - * @param bool $check If true, nothing will be cleared, as entries will - * naturally expire in wincache.. - * @return bool True Returns true. - */ - public function clear($check) - { - if ($check) { - return true; - } - $info = wincache_ucache_info(); - $cacheKeys = $info['ucache_entries']; - unset($info); - foreach ($cacheKeys as $key) { - if (strpos($key['key_name'], $this->_config['prefix']) === 0) { - wincache_ucache_delete($key['key_name']); - } - } - - return true; - } - - /** - * Returns the `group value` for each of the configured groups - * If the group initial value was not found, then it initializes - * the group accordingly. - * - * @return array - */ - public function groups() - { - if (empty($this->_compiledGroupNames)) { - foreach ($this->_config['groups'] as $group) { - $this->_compiledGroupNames[] = $this->_config['prefix'] . $group; - } - } - - $groups = wincache_ucache_get($this->_compiledGroupNames); - if (count($groups) !== count($this->_config['groups'])) { - foreach ($this->_compiledGroupNames as $group) { - if (!isset($groups[$group])) { - wincache_ucache_set($group, 1); - $groups[$group] = 1; - } - } - ksort($groups); - } - - $result = []; - $groups = array_values($groups); - foreach ($this->_config['groups'] as $i => $group) { - $result[] = $group . $groups[$i]; - } - - return $result; - } - - /** - * Increments the group value to simulate deletion of all keys under a group - * old values will remain in storage until they expire. - * - * @param string $group The group to clear. - * @return bool success - */ - public function clearGroup($group) - { - $success = false; - wincache_ucache_inc($this->_config['prefix'] . $group, 1, $success); - - return $success; - } -} diff --git a/vendor/cakephp/cakephp/src/Cache/Engine/XcacheEngine.php b/vendor/cakephp/cakephp/src/Cache/Engine/XcacheEngine.php deleted file mode 100644 index 9e1097f..0000000 --- a/vendor/cakephp/cakephp/src/Cache/Engine/XcacheEngine.php +++ /dev/null @@ -1,256 +0,0 @@ - 3600, - 'groups' => [], - 'prefix' => null, - 'probability' => 100, - 'PHP_AUTH_USER' => 'user', - 'PHP_AUTH_PW' => 'password' - ]; - - /** - * Initialize the Cache Engine - * - * Called automatically by the cache frontend - * - * @param array $config array of setting for the engine - * @return bool True if the engine has been successfully initialized, false if not - */ - public function init(array $config = []) - { - if (!extension_loaded('xcache')) { - return false; - } - - parent::init($config); - - return true; - } - - /** - * Write data for key into cache - * - * @param string $key Identifier for the data - * @param mixed $value Data to be cached - * @return bool True if the data was successfully cached, false on failure - */ - public function write($key, $value) - { - $key = $this->_key($key); - - if (!is_numeric($value)) { - $value = serialize($value); - } - - $duration = $this->_config['duration']; - $expires = time() + $duration; - xcache_set($key . '_expires', $expires, $duration); - - return xcache_set($key, $value, $duration); - } - - /** - * Read a key from the cache - * - * @param string $key Identifier for the data - * @return mixed The cached data, or false if the data doesn't exist, - * has expired, or if there was an error fetching it - */ - public function read($key) - { - $key = $this->_key($key); - - if (xcache_isset($key)) { - $time = time(); - $cachetime = (int)xcache_get($key . '_expires'); - if ($cachetime < $time || ($time + $this->_config['duration']) < $cachetime) { - return false; - } - - $value = xcache_get($key); - if (is_string($value) && !is_numeric($value)) { - $value = unserialize($value); - } - - return $value; - } - - return false; - } - - /** - * Increments the value of an integer cached key - * If the cache key is not an integer it will be treated as 0 - * - * @param string $key Identifier for the data - * @param int $offset How much to increment - * @return bool|int New incremented value, false otherwise - */ - public function increment($key, $offset = 1) - { - $key = $this->_key($key); - - return xcache_inc($key, $offset); - } - - /** - * Decrements the value of an integer cached key. - * If the cache key is not an integer it will be treated as 0 - * - * @param string $key Identifier for the data - * @param int $offset How much to subtract - * @return bool|int New decremented value, false otherwise - */ - public function decrement($key, $offset = 1) - { - $key = $this->_key($key); - - return xcache_dec($key, $offset); - } - - /** - * Delete a key from the cache - * - * @param string $key Identifier for the data - * @return bool True if the value was successfully deleted, false if it didn't exist or couldn't be removed - */ - public function delete($key) - { - $key = $this->_key($key); - - return xcache_unset($key); - } - - /** - * Delete all keys from the cache - * - * @param bool $check If true no deletes will occur and instead CakePHP will rely - * on key TTL values. - * Unused for Xcache engine. - * @return bool True if the cache was successfully cleared, false otherwise - */ - public function clear($check) - { - $this->_auth(); - $max = xcache_count(XC_TYPE_VAR); - for ($i = 0; $i < $max; $i++) { - xcache_clear_cache(XC_TYPE_VAR, $i); - } - $this->_auth(true); - - return true; - } - - /** - * Returns the `group value` for each of the configured groups - * If the group initial value was not found, then it initializes - * the group accordingly. - * - * @return array - */ - public function groups() - { - $result = []; - foreach ($this->_config['groups'] as $group) { - $value = xcache_get($this->_config['prefix'] . $group); - if (!$value) { - $value = 1; - xcache_set($this->_config['prefix'] . $group, $value, 0); - } - $result[] = $group . $value; - } - - return $result; - } - - /** - * Increments the group value to simulate deletion of all keys under a group - * old values will remain in storage until they expire. - * - * @param string $group The group to clear. - * @return bool success - */ - public function clearGroup($group) - { - return (bool)xcache_inc($this->_config['prefix'] . $group, 1); - } - - /** - * Populates and reverses $_SERVER authentication values - * Makes necessary changes (and reverting them back) in $_SERVER - * - * This has to be done because xcache_clear_cache() needs to pass Basic Http Auth - * (see xcache.admin configuration config) - * - * @param bool $reverse Revert changes - * @return void - */ - protected function _auth($reverse = false) - { - static $backup = []; - $keys = ['PHP_AUTH_USER' => 'user', 'PHP_AUTH_PW' => 'password']; - foreach ($keys as $key => $value) { - if ($reverse) { - if (isset($backup[$key])) { - $_SERVER[$key] = $backup[$key]; - unset($backup[$key]); - } else { - unset($_SERVER[$key]); - } - } else { - $value = env($key); - if (!empty($value)) { - $backup[$key] = $value; - } - if (!empty($this->_config[$value])) { - $_SERVER[$key] = $this->_config[$value]; - } elseif (!empty($this->_config[$key])) { - $_SERVER[$key] = $this->_config[$key]; - } else { - $_SERVER[$key] = $value; - } - } - } - } -} diff --git a/vendor/cakephp/cakephp/src/Cache/README.md b/vendor/cakephp/cakephp/src/Cache/README.md deleted file mode 100644 index befe20f..0000000 --- a/vendor/cakephp/cakephp/src/Cache/README.md +++ /dev/null @@ -1,57 +0,0 @@ -# CakePHP Caching Library - -The Cache library provides a `Cache` service locator for interfacing with multiple caching backends using -a simple to use interface. - -The caching backends supported are: - -* Files -* APC -* Memcached -* Redis -* Wincache -* Xcache - -## Usage - -Caching engines need to be configured with the `Cache::config()` method. - -```php -use Cake\Cache\Cache; - -// Using a short name -Cache::config('default', [ - 'className' => 'File', - 'duration' => '+1 hours', - 'path' => sys_get_tmp_dir(), - 'prefix' => 'my_app_' -]); - -// Using a fully namespaced name. -Cache::config('long', [ - 'className' => 'Cake\Cache\Engine\ApcuEngine', - 'duration' => '+1 week', - 'prefix' => 'my_app_' -]); - -// Using a constructed object. -$object = new FileEngine($config); -Cache::config('other', $object); -``` - -You can now read a write from the cache: - -```php -$data = Cache::remember('my_cache_key', function () { - return Service::expensiveCall(); -}); -``` - -The code above will try to look for data stored in cache under the `my_cache_key`, if not found -the callback will be executed and the returned data will be cached for future calls. - -## Documentation - -Please make sure you check the [official documentation](https://book.cakephp.org/3.0/en/core-libraries/caching.html) - - diff --git a/vendor/cakephp/cakephp/src/Cache/composer.json b/vendor/cakephp/cakephp/src/Cache/composer.json deleted file mode 100644 index 23289aa..0000000 --- a/vendor/cakephp/cakephp/src/Cache/composer.json +++ /dev/null @@ -1,33 +0,0 @@ -{ - "name": "cakephp/cache", - "description": "Easy to use Caching library with support for multiple caching backends", - "type": "library", - "keywords": [ - "cakephp", - "caching", - "cache" - ], - "homepage": "https://cakephp.org", - "license": "MIT", - "authors": [ - { - "name": "CakePHP Community", - "homepage": "https://github.com/cakephp/cache/graphs/contributors" - } - ], - "support": { - "issues": "https://github.com/cakephp/cakephp/issues", - "forum": "https://stackoverflow.com/tags/cakephp", - "irc": "irc://irc.freenode.org/cakephp", - "source": "https://github.com/cakephp/cache" - }, - "require": { - "php": ">=5.6.0", - "cakephp/core": "^3.6.0" - }, - "autoload": { - "psr-4": { - "Cake\\Cache\\": "." - } - } -} diff --git a/vendor/cakephp/cakephp/src/Collection/Collection.php b/vendor/cakephp/cakephp/src/Collection/Collection.php deleted file mode 100644 index ab7f725..0000000 --- a/vendor/cakephp/cakephp/src/Collection/Collection.php +++ /dev/null @@ -1,113 +0,0 @@ -buffered()); - } - - /** - * Unserializes the passed string and rebuilds the Collection instance - * - * @param string $collection The serialized collection - * @return void - */ - public function unserialize($collection) - { - $this->__construct(unserialize($collection)); - } - - /** - * {@inheritDoc} - * - * @return int - */ - public function count() - { - $traversable = $this->optimizeUnwrap(); - - if (is_array($traversable)) { - return count($traversable); - } - - return iterator_count($traversable); - } - - /** - * {@inheritDoc} - * - * @return int - */ - public function countKeys() - { - return count($this->toArray()); - } - - /** - * Returns an array that can be used to describe the internal state of this - * object. - * - * @return array - */ - public function __debugInfo() - { - return [ - 'count' => $this->count(), - ]; - } -} diff --git a/vendor/cakephp/cakephp/src/Collection/CollectionInterface.php b/vendor/cakephp/cakephp/src/Collection/CollectionInterface.php deleted file mode 100644 index ef2723e..0000000 --- a/vendor/cakephp/cakephp/src/Collection/CollectionInterface.php +++ /dev/null @@ -1,1101 +0,0 @@ -each(function ($value, $key) { - * echo "Element $key: $value"; - * }); - * ``` - * - * @param callable $c callable function that will receive each of the elements - * in this collection - * @return \Cake\Collection\CollectionInterface - */ - public function each(callable $c); - - /** - * Looks through each value in the collection, and returns another collection with - * all the values that pass a truth test. Only the values for which the callback - * returns true will be present in the resulting collection. - * - * Each time the callback is executed it will receive the value of the element - * in the current iteration, the key of the element and this collection as - * arguments, in that order. - * - * ### Example: - * - * Filtering odd numbers in an array, at the end only the value 2 will - * be present in the resulting collection: - * - * ``` - * $collection = (new Collection([1, 2, 3]))->filter(function ($value, $key) { - * return $value % 2 === 0; - * }); - * ``` - * - * @param callable|null $c the method that will receive each of the elements and - * returns true whether or not they should be in the resulting collection. - * If left null, a callback that filters out falsey values will be used. - * @return \Cake\Collection\CollectionInterface - */ - public function filter(callable $c = null); - - /** - * Looks through each value in the collection, and returns another collection with - * all the values that do not pass a truth test. This is the opposite of `filter`. - * - * Each time the callback is executed it will receive the value of the element - * in the current iteration, the key of the element and this collection as - * arguments, in that order. - * - * ### Example: - * - * Filtering even numbers in an array, at the end only values 1 and 3 will - * be present in the resulting collection: - * - * ``` - * $collection = (new Collection([1, 2, 3]))->reject(function ($value, $key) { - * return $value % 2 === 0; - * }); - * ``` - * - * @param callable $c the method that will receive each of the elements and - * returns true whether or not they should be out of the resulting collection. - * @return \Cake\Collection\CollectionInterface - */ - public function reject(callable $c); - - /** - * Returns true if all values in this collection pass the truth test provided - * in the callback. - * - * Each time the callback is executed it will receive the value of the element - * in the current iteration and the key of the element as arguments, in that - * order. - * - * ### Example: - * - * ``` - * $overTwentyOne = (new Collection([24, 45, 60, 15]))->every(function ($value, $key) { - * return $value > 21; - * }); - * ``` - * - * Empty collections always return true because it is a vacuous truth. - * - * @param callable $c a callback function - * @return bool true if for all elements in this collection the provided - * callback returns true, false otherwise. - */ - public function every(callable $c); - - /** - * Returns true if any of the values in this collection pass the truth test - * provided in the callback. - * - * Each time the callback is executed it will receive the value of the element - * in the current iteration and the key of the element as arguments, in that - * order. - * - * ### Example: - * - * ``` - * $hasYoungPeople = (new Collection([24, 45, 15]))->every(function ($value, $key) { - * return $value < 21; - * }); - * ``` - * - * @param callable $c a callback function - * @return bool true if the provided callback returns true for any element in this - * collection, false otherwise - */ - public function some(callable $c); - - /** - * Returns true if $value is present in this collection. Comparisons are made - * both by value and type. - * - * @param mixed $value The value to check for - * @return bool true if $value is present in this collection - */ - public function contains($value); - - /** - * Returns another collection after modifying each of the values in this one using - * the provided callable. - * - * Each time the callback is executed it will receive the value of the element - * in the current iteration, the key of the element and this collection as - * arguments, in that order. - * - * ### Example: - * - * Getting a collection of booleans where true indicates if a person is female: - * - * ``` - * $collection = (new Collection($people))->map(function ($person, $key) { - * return $person->gender === 'female'; - * }); - * ``` - * - * @param callable $c the method that will receive each of the elements and - * returns the new value for the key that is being iterated - * @return \Cake\Collection\CollectionInterface - */ - public function map(callable $c); - - /** - * Folds the values in this collection to a single value, as the result of - * applying the callback function to all elements. $zero is the initial state - * of the reduction, and each successive step of it should be returned - * by the callback function. - * If $zero is omitted the first value of the collection will be used in its place - * and reduction will start from the second item. - * - * @param callable $c The callback function to be called - * @param mixed $zero The state of reduction - * @return mixed - */ - public function reduce(callable $c, $zero = null); - - /** - * Returns a new collection containing the column or property value found in each - * of the elements, as requested in the $matcher param. - * - * The matcher can be a string with a property name to extract or a dot separated - * path of properties that should be followed to get the last one in the path. - * - * If a column or property could not be found for a particular element in the - * collection, that position is filled with null. - * - * ### Example: - * - * Extract the user name for all comments in the array: - * - * ``` - * $items = [ - * ['comment' => ['body' => 'cool', 'user' => ['name' => 'Mark']], - * ['comment' => ['body' => 'very cool', 'user' => ['name' => 'Renan']] - * ]; - * $extracted = (new Collection($items))->extract('comment.user.name'); - * - * // Result will look like this when converted to array - * ['Mark', 'Renan'] - * ``` - * - * It is also possible to extract a flattened collection out of nested properties - * - * ``` - * $items = [ - * ['comment' => ['votes' => [['value' => 1], ['value' => 2], ['value' => 3]]], - * ['comment' => ['votes' => [['value' => 4]] - * ]; - * $extracted = (new Collection($items))->extract('comment.votes.{*}.value'); - * - * // Result will contain - * [1, 2, 3, 4] - * ``` - * - * @param string $matcher a dot separated string symbolizing the path to follow - * inside the hierarchy of each value so that the column can be extracted. - * @return \Cake\Collection\CollectionInterface - */ - public function extract($matcher); - - /** - * Returns the top element in this collection after being sorted by a property. - * Check the sortBy method for information on the callback and $type parameters - * - * ### Examples: - * - * ``` - * // For a collection of employees - * $max = $collection->max('age'); - * $max = $collection->max('user.salary'); - * $max = $collection->max(function ($e) { - * return $e->get('user')->get('salary'); - * }); - * - * // Display employee name - * echo $max->name; - * ``` - * - * @param callable|string $callback the callback or column name to use for sorting - * @param int $type the type of comparison to perform, either SORT_STRING - * SORT_NUMERIC or SORT_NATURAL - * @see \Cake\Collection\CollectionIterface::sortBy() - * @return mixed The value of the top element in the collection - */ - public function max($callback, $type = SORT_NUMERIC); - - /** - * Returns the bottom element in this collection after being sorted by a property. - * Check the sortBy method for information on the callback and $type parameters - * - * ### Examples: - * - * ``` - * // For a collection of employees - * $min = $collection->min('age'); - * $min = $collection->min('user.salary'); - * $min = $collection->min(function ($e) { - * return $e->get('user')->get('salary'); - * }); - * - * // Display employee name - * echo $min->name; - * ``` - * - * @param callable|string $callback the callback or column name to use for sorting - * @param int $type the type of comparison to perform, either SORT_STRING - * SORT_NUMERIC or SORT_NATURAL - * @see \Cake\Collection\CollectionInterface::sortBy() - * @return mixed The value of the bottom element in the collection - */ - public function min($callback, $type = SORT_NUMERIC); - - /** - * Returns the average of all the values extracted with $matcher - * or of this collection. - * - * ### Example: - * - * ``` - * $items = [ - * ['invoice' => ['total' => 100]], - * ['invoice' => ['total' => 200]] - * ]; - * - * $total = (new Collection($items))->avg('invoice.total'); - * - * // Total: 150 - * - * $total = (new Collection([1, 2, 3]))->avg(); - * // Total: 2 - * ``` - * - * @param string|callable|null $matcher The property name to sum or a function - * If no value is passed, an identity function will be used. - * that will return the value of the property to sum. - * @return float|int|null - */ - public function avg($matcher = null); - - /** - * Returns the median of all the values extracted with $matcher - * or of this collection. - * - * ### Example: - * - * ``` - * $items = [ - * ['invoice' => ['total' => 400]], - * ['invoice' => ['total' => 500]] - * ['invoice' => ['total' => 100]] - * ['invoice' => ['total' => 333]] - * ['invoice' => ['total' => 200]] - * ]; - * - * $total = (new Collection($items))->median('invoice.total'); - * - * // Total: 333 - * - * $total = (new Collection([1, 2, 3, 4]))->median(); - * // Total: 2.5 - * ``` - * - * @param string|callable|null $matcher The property name to sum or a function - * If no value is passed, an identity function will be used. - * that will return the value of the property to sum. - * @return float|int|null - */ - public function median($matcher = null); - - /** - * Returns a sorted iterator out of the elements in this collection, - * ranked in ascending order by the results of running each value through a - * callback. $callback can also be a string representing the column or property - * name. - * - * The callback will receive as its first argument each of the elements in $items, - * the value returned by the callback will be used as the value for sorting such - * element. Please note that the callback function could be called more than once - * per element. - * - * ### Example: - * - * ``` - * $items = $collection->sortBy(function ($user) { - * return $user->age; - * }); - * - * // alternatively - * $items = $collection->sortBy('age'); - * - * // or use a property path - * $items = $collection->sortBy('department.name'); - * - * // output all user name order by their age in descending order - * foreach ($items as $user) { - * echo $user->name; - * } - * ``` - * - * @param callable|string $callback the callback or column name to use for sorting - * @param int $dir either SORT_DESC or SORT_ASC - * @param int $type the type of comparison to perform, either SORT_STRING - * SORT_NUMERIC or SORT_NATURAL - * @return \Cake\Collection\CollectionInterface - */ - public function sortBy($callback, $dir = SORT_DESC, $type = SORT_NUMERIC); - - /** - * Splits a collection into sets, grouped by the result of running each value - * through the callback. If $callback is a string instead of a callable, - * groups by the property named by $callback on each of the values. - * - * When $callback is a string it should be a property name to extract or - * a dot separated path of properties that should be followed to get the last - * one in the path. - * - * ### Example: - * - * ``` - * $items = [ - * ['id' => 1, 'name' => 'foo', 'parent_id' => 10], - * ['id' => 2, 'name' => 'bar', 'parent_id' => 11], - * ['id' => 3, 'name' => 'baz', 'parent_id' => 10], - * ]; - * - * $group = (new Collection($items))->groupBy('parent_id'); - * - * // Or - * $group = (new Collection($items))->groupBy(function ($e) { - * return $e['parent_id']; - * }); - * - * // Result will look like this when converted to array - * [ - * 10 => [ - * ['id' => 1, 'name' => 'foo', 'parent_id' => 10], - * ['id' => 3, 'name' => 'baz', 'parent_id' => 10], - * ], - * 11 => [ - * ['id' => 2, 'name' => 'bar', 'parent_id' => 11], - * ] - * ]; - * ``` - * - * @param callable|string $callback the callback or column name to use for grouping - * or a function returning the grouping key out of the provided element - * @return \Cake\Collection\CollectionInterface - */ - public function groupBy($callback); - - /** - * Given a list and a callback function that returns a key for each element - * in the list (or a property name), returns an object with an index of each item. - * Just like groupBy, but for when you know your keys are unique. - * - * When $callback is a string it should be a property name to extract or - * a dot separated path of properties that should be followed to get the last - * one in the path. - * - * ### Example: - * - * ``` - * $items = [ - * ['id' => 1, 'name' => 'foo'], - * ['id' => 2, 'name' => 'bar'], - * ['id' => 3, 'name' => 'baz'], - * ]; - * - * $indexed = (new Collection($items))->indexBy('id'); - * - * // Or - * $indexed = (new Collection($items))->indexBy(function ($e) { - * return $e['id']; - * }); - * - * // Result will look like this when converted to array - * [ - * 1 => ['id' => 1, 'name' => 'foo'], - * 3 => ['id' => 3, 'name' => 'baz'], - * 2 => ['id' => 2, 'name' => 'bar'], - * ]; - * ``` - * - * @param callable|string $callback the callback or column name to use for indexing - * or a function returning the indexing key out of the provided element - * @return \Cake\Collection\CollectionInterface - */ - public function indexBy($callback); - - /** - * Sorts a list into groups and returns a count for the number of elements - * in each group. Similar to groupBy, but instead of returning a list of values, - * returns a count for the number of values in that group. - * - * When $callback is a string it should be a property name to extract or - * a dot separated path of properties that should be followed to get the last - * one in the path. - * - * ### Example: - * - * ``` - * $items = [ - * ['id' => 1, 'name' => 'foo', 'parent_id' => 10], - * ['id' => 2, 'name' => 'bar', 'parent_id' => 11], - * ['id' => 3, 'name' => 'baz', 'parent_id' => 10], - * ]; - * - * $group = (new Collection($items))->countBy('parent_id'); - * - * // Or - * $group = (new Collection($items))->countBy(function ($e) { - * return $e['parent_id']; - * }); - * - * // Result will look like this when converted to array - * [ - * 10 => 2, - * 11 => 1 - * ]; - * ``` - * - * @param callable|string $callback the callback or column name to use for indexing - * or a function returning the indexing key out of the provided element - * @return \Cake\Collection\CollectionInterface - */ - public function countBy($callback); - - /** - * Returns the total sum of all the values extracted with $matcher - * or of this collection. - * - * ### Example: - * - * ``` - * $items = [ - * ['invoice' => ['total' => 100]], - * ['invoice' => ['total' => 200]] - * ]; - * - * $total = (new Collection($items))->sumOf('invoice.total'); - * - * // Total: 300 - * - * $total = (new Collection([1, 2, 3]))->sumOf(); - * // Total: 6 - * ``` - * - * @param string|callable|null $matcher The property name to sum or a function - * If no value is passed, an identity function will be used. - * that will return the value of the property to sum. - * @return float|int - */ - public function sumOf($matcher = null); - - /** - * Returns a new collection with the elements placed in a random order, - * this function does not preserve the original keys in the collection. - * - * @return \Cake\Collection\CollectionInterface - */ - public function shuffle(); - - /** - * Returns a new collection with maximum $size random elements - * from this collection - * - * @param int $size the maximum number of elements to randomly - * take from this collection - * @return \Cake\Collection\CollectionInterface - */ - public function sample($size = 10); - - /** - * Returns a new collection with maximum $size elements in the internal - * order this collection was created. If a second parameter is passed, it - * will determine from what position to start taking elements. - * - * @param int $size the maximum number of elements to take from - * this collection - * @param int $from A positional offset from where to take the elements - * @return \Cake\Collection\CollectionInterface - */ - public function take($size = 1, $from = 0); - - /** - * Returns a new collection that will skip the specified amount of elements - * at the beginning of the iteration. - * - * @param int $howMany The number of elements to skip. - * @return \Cake\Collection\CollectionInterface - */ - public function skip($howMany); - - /** - * Looks through each value in the list, returning a Collection of all the - * values that contain all of the key-value pairs listed in $conditions. - * - * ### Example: - * - * ``` - * $items = [ - * ['comment' => ['body' => 'cool', 'user' => ['name' => 'Mark']], - * ['comment' => ['body' => 'very cool', 'user' => ['name' => 'Renan']] - * ]; - * - * $extracted = (new Collection($items))->match(['user.name' => 'Renan']); - * - * // Result will look like this when converted to array - * [ - * ['comment' => ['body' => 'very cool', 'user' => ['name' => 'Renan']] - * ] - * ``` - * - * @param array $conditions a key-value list of conditions where - * the key is a property path as accepted by `Collection::extract, - * and the value the condition against with each element will be matched - * @return \Cake\Collection\CollectionInterface - */ - public function match(array $conditions); - - /** - * Returns the first result matching all of the key-value pairs listed in - * conditions. - * - * @param array $conditions a key-value list of conditions where the key is - * a property path as accepted by `Collection::extract`, and the value the - * condition against with each element will be matched - * @see \Cake\Collection\CollectionInterface::match() - * @return mixed - */ - public function firstMatch(array $conditions); - - /** - * Returns the first result in this collection - * - * @return mixed The first value in the collection will be returned. - */ - public function first(); - - /** - * Returns the last result in this collection - * - * @return mixed The last value in the collection will be returned. - */ - public function last(); - - /** - * Returns a new collection as the result of concatenating the list of elements - * in this collection with the passed list of elements - * - * @param array|\Traversable $items Items list. - * @return \Cake\Collection\CollectionInterface - */ - public function append($items); - - /** - * Returns a new collection where the values extracted based on a value path - * and then indexed by a key path. Optionally this method can produce parent - * groups based on a group property path. - * - * ### Examples: - * - * ``` - * $items = [ - * ['id' => 1, 'name' => 'foo', 'parent' => 'a'], - * ['id' => 2, 'name' => 'bar', 'parent' => 'b'], - * ['id' => 3, 'name' => 'baz', 'parent' => 'a'], - * ]; - * - * $combined = (new Collection($items))->combine('id', 'name'); - * - * // Result will look like this when converted to array - * [ - * 1 => 'foo', - * 2 => 'bar', - * 3 => 'baz', - * ]; - * - * $combined = (new Collection($items))->combine('id', 'name', 'parent'); - * - * // Result will look like this when converted to array - * [ - * 'a' => [1 => 'foo', 3 => 'baz'], - * 'b' => [2 => 'bar'] - * ]; - * ``` - * - * @param callable|string $keyPath the column name path to use for indexing - * or a function returning the indexing key out of the provided element - * @param callable|string $valuePath the column name path to use as the array value - * or a function returning the value out of the provided element - * @param callable|string|null $groupPath the column name path to use as the parent - * grouping key or a function returning the key out of the provided element - * @return \Cake\Collection\CollectionInterface - */ - public function combine($keyPath, $valuePath, $groupPath = null); - - /** - * Returns a new collection where the values are nested in a tree-like structure - * based on an id property path and a parent id property path. - * - * @param callable|string $idPath the column name path to use for determining - * whether an element is parent of another - * @param callable|string $parentPath the column name path to use for determining - * whether an element is child of another - * @param string $nestingKey The key name under which children are nested - * @return \Cake\Collection\CollectionInterface - */ - public function nest($idPath, $parentPath, $nestingKey = 'children'); - - /** - * Returns a new collection containing each of the elements found in `$values` as - * a property inside the corresponding elements in this collection. The property - * where the values will be inserted is described by the `$path` parameter. - * - * The $path can be a string with a property name or a dot separated path of - * properties that should be followed to get the last one in the path. - * - * If a column or property could not be found for a particular element in the - * collection as part of the path, the element will be kept unchanged. - * - * ### Example: - * - * Insert ages into a collection containing users: - * - * ``` - * $items = [ - * ['comment' => ['body' => 'cool', 'user' => ['name' => 'Mark']], - * ['comment' => ['body' => 'awesome', 'user' => ['name' => 'Renan']] - * ]; - * $ages = [25, 28]; - * $inserted = (new Collection($items))->insert('comment.user.age', $ages); - * - * // Result will look like this when converted to array - * [ - * ['comment' => ['body' => 'cool', 'user' => ['name' => 'Mark', 'age' => 25]], - * ['comment' => ['body' => 'awesome', 'user' => ['name' => 'Renan', 'age' => 28]] - * ]; - * ``` - * - * @param string $path a dot separated string symbolizing the path to follow - * inside the hierarchy of each value so that the value can be inserted - * @param mixed $values The values to be inserted at the specified path, - * values are matched with the elements in this collection by its positional index. - * @return \Cake\Collection\CollectionInterface - */ - public function insert($path, $values); - - /** - * Returns an array representation of the results - * - * @param bool $preserveKeys whether to use the keys returned by this - * collection as the array keys. Keep in mind that it is valid for iterators - * to return the same key for different elements, setting this value to false - * can help getting all items if keys are not important in the result. - * @return array - */ - public function toArray($preserveKeys = true); - - /** - * Returns an numerically-indexed array representation of the results. - * This is equivalent to calling `toArray(false)` - * - * @return array - */ - public function toList(); - - /** - * Convert a result set into JSON. - * - * Part of JsonSerializable interface. - * - * @return array The data to convert to JSON - */ - public function jsonSerialize(); - - /** - * Iterates once all elements in this collection and executes all stacked - * operations of them, finally it returns a new collection with the result. - * This is useful for converting non-rewindable internal iterators into - * a collection that can be rewound and used multiple times. - * - * A common use case is to re-use the same variable for calculating different - * data. In those cases it may be helpful and more performant to first compile - * a collection and then apply more operations to it. - * - * ### Example: - * - * ``` - * $collection->map($mapper)->sortBy('age')->extract('name'); - * $compiled = $collection->compile(); - * $isJohnHere = $compiled->some($johnMatcher); - * $allButJohn = $compiled->filter($johnMatcher); - * ``` - * - * In the above example, had the collection not been compiled before, the - * iterations for `map`, `sortBy` and `extract` would've been executed twice: - * once for getting `$isJohnHere` and once for `$allButJohn` - * - * You can think of this method as a way to create save points for complex - * calculations in a collection. - * - * @param bool $preserveKeys whether to use the keys returned by this - * collection as the array keys. Keep in mind that it is valid for iterators - * to return the same key for different elements, setting this value to false - * can help getting all items if keys are not important in the result. - * @return \Cake\Collection\CollectionInterface - */ - public function compile($preserveKeys = true); - - /** - * Returns a new collection where the operations performed by this collection. - * No matter how many times the new collection is iterated, those operations will - * only be performed once. - * - * This can also be used to make any non-rewindable iterator rewindable. - * - * @return \Cake\Collection\CollectionInterface - */ - public function buffered(); - - /** - * Returns a new collection with each of the elements of this collection - * after flattening the tree structure. The tree structure is defined - * by nesting elements under a key with a known name. It is possible - * to specify such name by using the '$nestingKey' parameter. - * - * By default all elements in the tree following a Depth First Search - * will be returned, that is, elements from the top parent to the leaves - * for each branch. - * - * It is possible to return all elements from bottom to top using a Breadth First - * Search approach by passing the '$dir' parameter with 'asc'. That is, it will - * return all elements for the same tree depth first and from bottom to top. - * - * Finally, you can specify to only get a collection with the leaf nodes in the - * tree structure. You do so by passing 'leaves' in the first argument. - * - * The possible values for the first argument are aliases for the following - * constants and it is valid to pass those instead of the alias: - * - * - desc: TreeIterator::SELF_FIRST - * - asc: TreeIterator::CHILD_FIRST - * - leaves: TreeIterator::LEAVES_ONLY - * - * ### Example: - * - * ``` - * $collection = new Collection([ - * ['id' => 1, 'children' => [['id' => 2, 'children' => [['id' => 3]]]]], - * ['id' => 4, 'children' => [['id' => 5]]] - * ]); - * $flattenedIds = $collection->listNested()->extract('id'); // Yields [1, 2, 3, 4, 5] - * ``` - * - * @param string|int $dir The direction in which to return the elements - * @param string|callable $nestingKey The key name under which children are nested - * or a callable function that will return the children list - * @return \Cake\Collection\CollectionInterface - */ - public function listNested($dir = 'desc', $nestingKey = 'children'); - - /** - * Creates a new collection that when iterated will stop yielding results if - * the provided condition evaluates to false. - * - * This is handy for dealing with infinite iterators or any generator that - * could start returning invalid elements at a certain point. For example, - * when reading lines from a file stream you may want to stop the iteration - * after a certain value is reached. - * - * ### Example: - * - * Get an array of lines in a CSV file until the timestamp column is less than a date - * - * ``` - * $lines = (new Collection($fileLines))->stopWhen(function ($value, $key) { - * return (new DateTime($value))->format('Y') < 2012; - * }) - * ->toArray(); - * ``` - * - * Get elements until the first unapproved message is found: - * - * ``` - * $comments = (new Collection($comments))->stopWhen(['is_approved' => false]); - * ``` - * - * @param callable $condition the method that will receive each of the elements and - * returns false when the iteration should be stopped. - * If an array, it will be interpreted as a key-value list of conditions where - * the key is a property path as accepted by `Collection::extract`, - * and the value the condition against with each element will be matched. - * @return \Cake\Collection\CollectionInterface - */ - public function stopWhen($condition); - - /** - * Creates a new collection where the items are the - * concatenation of the lists of items generated by the transformer function - * applied to each item in the original collection. - * - * The transformer function will receive the value and the key for each of the - * items in the collection, in that order, and it must return an array or a - * Traversable object that can be concatenated to the final result. - * - * If no transformer function is passed, an "identity" function will be used. - * This is useful when each of the elements in the source collection are - * lists of items to be appended one after another. - * - * ### Example: - * - * ``` - * $items [[1, 2, 3], [4, 5]]; - * $unfold = (new Collection($items))->unfold(); // Returns [1, 2, 3, 4, 5] - * ``` - * - * Using a transformer - * - * ``` - * $items [1, 2, 3]; - * $allItems = (new Collection($items))->unfold(function ($page) { - * return $service->fetchPage($page)->toArray(); - * }); - * ``` - * - * @param callable|null $transformer A callable function that will receive each of - * the items in the collection and should return an array or Traversable object - * @return \Cake\Collection\CollectionInterface - */ - public function unfold(callable $transformer = null); - - /** - * Passes this collection through a callable as its first argument. - * This is useful for decorating the full collection with another object. - * - * ### Example: - * - * ``` - * $items = [1, 2, 3]; - * $decorated = (new Collection($items))->through(function ($collection) { - * return new MyCustomCollection($collection); - * }); - * ``` - * - * @param callable $handler A callable function that will receive - * this collection as first argument. - * @return \Cake\Collection\CollectionInterface - */ - public function through(callable $handler); - - /** - * Combines the elements of this collection with each of the elements of the - * passed iterables, using their positional index as a reference. - * - * ### Example: - * - * ``` - * $collection = new Collection([1, 2]); - * $collection->zip([3, 4], [5, 6])->toList(); // returns [[1, 3, 5], [2, 4, 6]] - * ``` - * - * @param array|\Traversable ...$items The collections to zip. - * @return \Cake\Collection\CollectionInterface - */ - public function zip($items); - - /** - * Combines the elements of this collection with each of the elements of the - * passed iterables, using their positional index as a reference. - * - * The resulting element will be the return value of the $callable function. - * - * ### Example: - * - * ``` - * $collection = new Collection([1, 2]); - * $zipped = $collection->zipWith([3, 4], [5, 6], function (...$args) { - * return array_sum($args); - * }); - * $zipped->toList(); // returns [9, 12]; [(1 + 3 + 5), (2 + 4 + 6)] - * ``` - * - * @param array|\Traversable ...$items The collections to zip. - * @param callable $callable The function to use for zipping the elements together. - * @return \Cake\Collection\CollectionInterface - */ - public function zipWith($items, $callable); - - /** - * Breaks the collection into smaller arrays of the given size. - * - * ### Example: - * - * ``` - * $items [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11]; - * $chunked = (new Collection($items))->chunk(3)->toList(); - * // Returns [[1, 2, 3], [4, 5, 6], [7, 8, 9], [10, 11]] - * ``` - * - * @param int $chunkSize The maximum size for each chunk - * @return \Cake\Collection\CollectionInterface - */ - public function chunk($chunkSize); - - /** - * Breaks the collection into smaller arrays of the given size. - * - * ### Example: - * - * ``` - * $items ['a' => 1, 'b' => 2, 'c' => 3, 'd' => 4, 'e' => 5, 'f' => 6]; - * $chunked = (new Collection($items))->chunkWithKeys(3)->toList(); - * // Returns [['a' => 1, 'b' => 2, 'c' => 3], ['d' => 4, 'e' => 5, 'f' => 6]] - * ``` - * - * @param int $chunkSize The maximum size for each chunk - * @param bool $preserveKeys If the keys of the array should be preserved - * @return \Cake\Collection\CollectionInterface - */ - public function chunkWithKeys($chunkSize, $preserveKeys = true); - - /** - * Returns whether or not there are elements in this collection - * - * ### Example: - * - * ``` - * $items [1, 2, 3]; - * (new Collection($items))->isEmpty(); // false - * ``` - * - * ``` - * (new Collection([]))->isEmpty(); // true - * ``` - * - * @return bool - */ - public function isEmpty(); - - /** - * Returns the closest nested iterator that can be safely traversed without - * losing any possible transformations. This is used mainly to remove empty - * IteratorIterator wrappers that can only slowdown the iteration process. - * - * @return \Traversable - */ - public function unwrap(); - - /** - * Transpose rows and columns into columns and rows - * - * ### Example: - * - * ``` - * $items = [ - * ['Products', '2012', '2013', '2014'], - * ['Product A', '200', '100', '50'], - * ['Product B', '300', '200', '100'], - * ['Product C', '400', '300', '200'], - * ] - * - * $transpose = (new Collection($items))->transpose()->toList(); - * - * // Returns - * // [ - * // ['Products', 'Product A', 'Product B', 'Product C'], - * // ['2012', '200', '300', '400'], - * // ['2013', '100', '200', '300'], - * // ['2014', '50', '100', '200'], - * // ] - * ``` - * - * @return \Cake\Collection\CollectionInterface - */ - public function transpose(); - - /** - * Returns the amount of elements in the collection. - * - * ## WARNINGS: - * - * ### Consumes all elements for NoRewindIterator collections: - * - * On certain type of collections, calling this method may render unusable afterwards. - * That is, you may not be able to get elements out of it, or to iterate on it anymore. - * - * Specifically any collection wrapping a Generator (a function with a yield statement) - * or a unbuffered database cursor will not accept any other function calls after calling - * `count()` on it. - * - * Create a new collection with `buffered()` method to overcome this problem. - * - * ### Can report more elements than unique keys: - * - * Any collection constructed by appending collections together, or by having internal iterators - * returning duplicate keys, will report a larger amount of elements using this functions than - * the final amount of elements when converting the collections to a keyed array. This is because - * duplicate keys will be collapsed into a single one in the final array, whereas this count method - * is only concerned by the amount of elements after converting it to a plain list. - * - * If you need the count of elements after taking the keys in consideration - * (the count of unique keys), you can call `countKeys()` - * - * ### Will change the current position of the iterator: - * - * Calling this method at the same time that you are iterating this collections, for example in - * a foreach, will result in undefined behavior. Avoid doing this. - * - * - * @return int - */ - public function count(); - - /** - * Returns the number of unique keys in this iterator. This is, the number of - * elements the collection will contain after calling `toArray()` - * - * This method comes with a number of caveats. Please refer to `CollectionInterface::count()` - * for details. - * - * @see \Cake\Collection\CollectionInterface::count() - * @return int - */ - public function countKeys(); -} diff --git a/vendor/cakephp/cakephp/src/Collection/CollectionTrait.php b/vendor/cakephp/cakephp/src/Collection/CollectionTrait.php deleted file mode 100644 index 6b39b57..0000000 --- a/vendor/cakephp/cakephp/src/Collection/CollectionTrait.php +++ /dev/null @@ -1,892 +0,0 @@ -optimizeUnwrap() as $k => $v) { - $c($v, $k); - } - - return $this; - } - - /** - * {@inheritDoc} - * - * @return \Cake\Collection\Iterator\FilterIterator - */ - public function filter(callable $c = null) - { - if ($c === null) { - $c = function ($v) { - return (bool)$v; - }; - } - - return new FilterIterator($this->unwrap(), $c); - } - - /** - * {@inheritDoc} - * - * @return \Cake\Collection\Iterator\FilterIterator - */ - public function reject(callable $c) - { - return new FilterIterator($this->unwrap(), function ($key, $value, $items) use ($c) { - return !$c($key, $value, $items); - }); - } - - /** - * {@inheritDoc} - */ - public function every(callable $c) - { - foreach ($this->optimizeUnwrap() as $key => $value) { - if (!$c($value, $key)) { - return false; - } - } - - return true; - } - - /** - * {@inheritDoc} - */ - public function some(callable $c) - { - foreach ($this->optimizeUnwrap() as $key => $value) { - if ($c($value, $key) === true) { - return true; - } - } - - return false; - } - - /** - * {@inheritDoc} - */ - public function contains($value) - { - foreach ($this->optimizeUnwrap() as $v) { - if ($value === $v) { - return true; - } - } - - return false; - } - - /** - * {@inheritDoc} - * - * @return \Cake\Collection\Iterator\ReplaceIterator - */ - public function map(callable $c) - { - return new ReplaceIterator($this->unwrap(), $c); - } - - /** - * {@inheritDoc} - */ - public function reduce(callable $c, $zero = null) - { - $isFirst = false; - if (func_num_args() < 2) { - $isFirst = true; - } - - $result = $zero; - foreach ($this->optimizeUnwrap() as $k => $value) { - if ($isFirst) { - $result = $value; - $isFirst = false; - continue; - } - $result = $c($result, $value, $k); - } - - return $result; - } - - /** - * {@inheritDoc} - */ - public function extract($matcher) - { - $extractor = new ExtractIterator($this->unwrap(), $matcher); - if (is_string($matcher) && strpos($matcher, '{*}') !== false) { - $extractor = $extractor - ->filter(function ($data) { - return $data !== null && ($data instanceof Traversable || is_array($data)); - }) - ->unfold(); - } - - return $extractor; - } - - /** - * {@inheritDoc} - */ - public function max($callback, $type = SORT_NUMERIC) - { - return (new SortIterator($this->unwrap(), $callback, SORT_DESC, $type))->first(); - } - - /** - * {@inheritDoc} - */ - public function min($callback, $type = SORT_NUMERIC) - { - return (new SortIterator($this->unwrap(), $callback, SORT_ASC, $type))->first(); - } - - /** - * {@inheritDoc} - */ - public function avg($matcher = null) - { - $result = $this; - if ($matcher != null) { - $result = $result->extract($matcher); - } - $result = $result - ->reduce(function ($acc, $current) { - list($count, $sum) = $acc; - - return [$count + 1, $sum + $current]; - }, [0, 0]); - - if ($result[0] === 0) { - return null; - } - - return $result[1] / $result[0]; - } - - /** - * {@inheritDoc} - */ - public function median($matcher = null) - { - $elements = $this; - if ($matcher != null) { - $elements = $elements->extract($matcher); - } - $values = $elements->toList(); - sort($values); - $count = count($values); - - if ($count === 0) { - return null; - } - - $middle = (int)($count / 2); - - if ($count % 2) { - return $values[$middle]; - } - - return ($values[$middle - 1] + $values[$middle]) / 2; - } - - /** - * {@inheritDoc} - */ - public function sortBy($callback, $dir = SORT_DESC, $type = SORT_NUMERIC) - { - return new SortIterator($this->unwrap(), $callback, $dir, $type); - } - - /** - * {@inheritDoc} - */ - public function groupBy($callback) - { - $callback = $this->_propertyExtractor($callback); - $group = []; - foreach ($this->optimizeUnwrap() as $value) { - $group[$callback($value)][] = $value; - } - - return new Collection($group); - } - - /** - * {@inheritDoc} - */ - public function indexBy($callback) - { - $callback = $this->_propertyExtractor($callback); - $group = []; - foreach ($this->optimizeUnwrap() as $value) { - $group[$callback($value)] = $value; - } - - return new Collection($group); - } - - /** - * {@inheritDoc} - */ - public function countBy($callback) - { - $callback = $this->_propertyExtractor($callback); - - $mapper = function ($value, $key, $mr) use ($callback) { - $mr->emitIntermediate($value, $callback($value)); - }; - - $reducer = function ($values, $key, $mr) { - $mr->emit(count($values), $key); - }; - - return new Collection(new MapReduce($this->unwrap(), $mapper, $reducer)); - } - - /** - * {@inheritDoc} - */ - public function sumOf($matcher = null) - { - if ($matcher === null) { - return array_sum($this->toList()); - } - - $callback = $this->_propertyExtractor($matcher); - $sum = 0; - foreach ($this->optimizeUnwrap() as $k => $v) { - $sum += $callback($v, $k); - } - - return $sum; - } - - /** - * {@inheritDoc} - */ - public function shuffle() - { - $elements = $this->toArray(); - shuffle($elements); - - return new Collection($elements); - } - - /** - * {@inheritDoc} - */ - public function sample($size = 10) - { - return new Collection(new LimitIterator($this->shuffle(), 0, $size)); - } - - /** - * {@inheritDoc} - */ - public function take($size = 1, $from = 0) - { - return new Collection(new LimitIterator($this, $from, $size)); - } - - /** - * {@inheritDoc} - */ - public function skip($howMany) - { - return new Collection(new LimitIterator($this, $howMany)); - } - - /** - * {@inheritDoc} - */ - public function match(array $conditions) - { - return $this->filter($this->_createMatcherFilter($conditions)); - } - - /** - * {@inheritDoc} - */ - public function firstMatch(array $conditions) - { - return $this->match($conditions)->first(); - } - - /** - * {@inheritDoc} - */ - public function first() - { - $iterator = new LimitIterator($this, 0, 1); - foreach ($iterator as $result) { - return $result; - } - } - - /** - * {@inheritDoc} - */ - public function last() - { - $iterator = $this->optimizeUnwrap(); - if (is_array($iterator)) { - return array_pop($iterator); - } - - if ($iterator instanceof Countable) { - $count = count($iterator); - if ($count === 0) { - return null; - } - $iterator = new LimitIterator($iterator, $count - 1, 1); - } - - $result = null; - foreach ($iterator as $result) { - // No-op - } - - return $result; - } - - /** - * {@inheritDoc} - */ - public function append($items) - { - $list = new AppendIterator(); - $list->append($this->unwrap()); - $list->append((new Collection($items))->unwrap()); - - return new Collection($list); - } - - /** - * {@inheritDoc} - */ - public function appendItem($item, $key = null) - { - if ($key !== null) { - $data = [$key => $item]; - } else { - $data = [$item]; - } - - return $this->append($data); - } - - /** - * {@inheritDoc} - */ - public function prepend($items) - { - return (new Collection($items))->append($this); - } - - /** - * {@inheritDoc} - */ - public function prependItem($item, $key = null) - { - if ($key !== null) { - $data = [$key => $item]; - } else { - $data = [$item]; - } - - return $this->prepend($data); - } - - /** - * {@inheritDoc} - */ - public function combine($keyPath, $valuePath, $groupPath = null) - { - $options = [ - 'keyPath' => $this->_propertyExtractor($keyPath), - 'valuePath' => $this->_propertyExtractor($valuePath), - 'groupPath' => $groupPath ? $this->_propertyExtractor($groupPath) : null - ]; - - $mapper = function ($value, $key, $mapReduce) use ($options) { - $rowKey = $options['keyPath']; - $rowVal = $options['valuePath']; - - if (!$options['groupPath']) { - $mapReduce->emit($rowVal($value, $key), $rowKey($value, $key)); - - return null; - } - - $key = $options['groupPath']($value, $key); - $mapReduce->emitIntermediate( - [$rowKey($value, $key) => $rowVal($value, $key)], - $key - ); - }; - - $reducer = function ($values, $key, $mapReduce) { - $result = []; - foreach ($values as $value) { - $result += $value; - } - $mapReduce->emit($result, $key); - }; - - return new Collection(new MapReduce($this->unwrap(), $mapper, $reducer)); - } - - /** - * {@inheritDoc} - */ - public function nest($idPath, $parentPath, $nestingKey = 'children') - { - $parents = []; - $idPath = $this->_propertyExtractor($idPath); - $parentPath = $this->_propertyExtractor($parentPath); - $isObject = true; - - $mapper = function ($row, $key, $mapReduce) use (&$parents, $idPath, $parentPath, $nestingKey) { - $row[$nestingKey] = []; - $id = $idPath($row, $key); - $parentId = $parentPath($row, $key); - $parents[$id] =& $row; - $mapReduce->emitIntermediate($id, $parentId); - }; - - $reducer = function ($values, $key, $mapReduce) use (&$parents, &$isObject, $nestingKey) { - static $foundOutType = false; - if (!$foundOutType) { - $isObject = is_object(current($parents)); - $foundOutType = true; - } - if (empty($key) || !isset($parents[$key])) { - foreach ($values as $id) { - $parents[$id] = $isObject ? $parents[$id] : new ArrayIterator($parents[$id], 1); - $mapReduce->emit($parents[$id]); - } - - return null; - } - - $children = []; - foreach ($values as $id) { - $children[] =& $parents[$id]; - } - $parents[$key][$nestingKey] = $children; - }; - - return (new Collection(new MapReduce($this->unwrap(), $mapper, $reducer))) - ->map(function ($value) use (&$isObject) { - return $isObject ? $value : $value->getArrayCopy(); - }); - } - - /** - * {@inheritDoc} - * - * @return \Cake\Collection\Iterator\InsertIterator - */ - public function insert($path, $values) - { - return new InsertIterator($this->unwrap(), $path, $values); - } - - /** - * {@inheritDoc} - */ - public function toArray($preserveKeys = true) - { - $iterator = $this->unwrap(); - if ($iterator instanceof ArrayIterator) { - $items = $iterator->getArrayCopy(); - - return $preserveKeys ? $items : array_values($items); - } - // RecursiveIteratorIterator can return duplicate key values causing - // data loss when converted into an array - if ($preserveKeys && get_class($iterator) === 'RecursiveIteratorIterator') { - $preserveKeys = false; - } - - return iterator_to_array($this, $preserveKeys); - } - - /** - * {@inheritDoc} - */ - public function toList() - { - return $this->toArray(false); - } - - /** - * {@inheritDoc} - */ - public function jsonSerialize() - { - return $this->toArray(); - } - - /** - * {@inheritDoc} - */ - public function compile($preserveKeys = true) - { - return new Collection($this->toArray($preserveKeys)); - } - - /** - * {@inheritDoc} - * - * @return \Cake\Collection\Iterator\BufferedIterator - */ - public function buffered() - { - return new BufferedIterator($this->unwrap()); - } - - /** - * {@inheritDoc} - * - * @return \Cake\Collection\Iterator\TreeIterator - */ - public function listNested($dir = 'desc', $nestingKey = 'children') - { - $dir = strtolower($dir); - $modes = [ - 'desc' => TreeIterator::SELF_FIRST, - 'asc' => TreeIterator::CHILD_FIRST, - 'leaves' => TreeIterator::LEAVES_ONLY - ]; - - return new TreeIterator( - new NestIterator($this, $nestingKey), - isset($modes[$dir]) ? $modes[$dir] : $dir - ); - } - - /** - * {@inheritDoc} - * - * @return \Cake\Collection\Iterator\StoppableIterator - */ - public function stopWhen($condition) - { - if (!is_callable($condition)) { - $condition = $this->_createMatcherFilter($condition); - } - - return new StoppableIterator($this->unwrap(), $condition); - } - - /** - * {@inheritDoc} - */ - public function unfold(callable $transformer = null) - { - if ($transformer === null) { - $transformer = function ($item) { - return $item; - }; - } - - return new Collection( - new RecursiveIteratorIterator( - new UnfoldIterator($this->unwrap(), $transformer), - RecursiveIteratorIterator::LEAVES_ONLY - ) - ); - } - - /** - * {@inheritDoc} - */ - public function through(callable $handler) - { - $result = $handler($this); - - return $result instanceof CollectionInterface ? $result : new Collection($result); - } - - /** - * {@inheritDoc} - */ - public function zip($items) - { - return new ZipIterator(array_merge([$this->unwrap()], func_get_args())); - } - - /** - * {@inheritDoc} - */ - public function zipWith($items, $callable) - { - if (func_num_args() > 2) { - $items = func_get_args(); - $callable = array_pop($items); - } else { - $items = [$items]; - } - - return new ZipIterator(array_merge([$this->unwrap()], $items), $callable); - } - - /** - * {@inheritDoc} - */ - public function chunk($chunkSize) - { - return $this->map(function ($v, $k, $iterator) use ($chunkSize) { - $values = [$v]; - for ($i = 1; $i < $chunkSize; $i++) { - $iterator->next(); - if (!$iterator->valid()) { - break; - } - $values[] = $iterator->current(); - } - - return $values; - }); - } - - /** - * {@inheritDoc} - */ - public function chunkWithKeys($chunkSize, $preserveKeys = true) - { - return $this->map(function ($v, $k, $iterator) use ($chunkSize, $preserveKeys) { - $key = 0; - if ($preserveKeys) { - $key = $k; - } - $values = [$key => $v]; - for ($i = 1; $i < $chunkSize; $i++) { - $iterator->next(); - if (!$iterator->valid()) { - break; - } - if ($preserveKeys) { - $values[$iterator->key()] = $iterator->current(); - } else { - $values[] = $iterator->current(); - } - } - - return $values; - }); - } - - /** - * {@inheritDoc} - */ - public function isEmpty() - { - foreach ($this as $el) { - return false; - } - - return true; - } - - /** - * {@inheritDoc} - */ - public function unwrap() - { - $iterator = $this; - while (get_class($iterator) === 'Cake\Collection\Collection') { - $iterator = $iterator->getInnerIterator(); - } - - if ($iterator !== $this && $iterator instanceof CollectionInterface) { - $iterator = $iterator->unwrap(); - } - - return $iterator; - } - - /** - * Backwards compatible wrapper for unwrap() - * - * @return \Traversable - * @deprecated 3.0.10 Will be removed in 4.0.0 - */ - // @codingStandardsIgnoreLine - public function _unwrap() - { - deprecationWarning('CollectionTrait::_unwrap() is deprecated. Use CollectionTrait::unwrap() instead.'); - - return $this->unwrap(); - } - - /** - * {@inheritDoc} - * - * @return \Cake\Collection\CollectionInterface - */ - public function cartesianProduct(callable $operation = null, callable $filter = null) - { - if ($this->isEmpty()) { - return new Collection([]); - } - - $collectionArrays = []; - $collectionArraysKeys = []; - $collectionArraysCounts = []; - - foreach ($this->toList() as $value) { - $valueCount = count($value); - if ($valueCount !== count($value, COUNT_RECURSIVE)) { - throw new LogicException('Cannot find the cartesian product of a multidimensional array'); - } - - $collectionArraysKeys[] = array_keys($value); - $collectionArraysCounts[] = $valueCount; - $collectionArrays[] = $value; - } - - $result = []; - $lastIndex = count($collectionArrays) - 1; - // holds the indexes of the arrays that generate the current combination - $currentIndexes = array_fill(0, $lastIndex + 1, 0); - - $changeIndex = $lastIndex; - - while (!($changeIndex === 0 && $currentIndexes[0] === $collectionArraysCounts[0])) { - $currentCombination = array_map(function ($value, $keys, $index) { - return $value[$keys[$index]]; - }, $collectionArrays, $collectionArraysKeys, $currentIndexes); - - if ($filter === null || $filter($currentCombination)) { - $result[] = ($operation === null) ? $currentCombination : $operation($currentCombination); - } - - $currentIndexes[$lastIndex]++; - - for ($changeIndex = $lastIndex; $currentIndexes[$changeIndex] === $collectionArraysCounts[$changeIndex] && $changeIndex > 0; $changeIndex--) { - $currentIndexes[$changeIndex] = 0; - $currentIndexes[$changeIndex - 1]++; - } - } - - return new Collection($result); - } - - /** - * {@inheritDoc} - * - * @return \Cake\Collection\CollectionInterface - */ - public function transpose() - { - $arrayValue = $this->toList(); - $length = count(current($arrayValue)); - $result = []; - foreach ($arrayValue as $column => $row) { - if (count($row) != $length) { - throw new LogicException('Child arrays do not have even length'); - } - } - - for ($column = 0; $column < $length; $column++) { - $result[] = array_column($arrayValue, $column); - } - - return new Collection($result); - } - - /** - * {@inheritDoc} - * - * @return int - */ - public function count() - { - $traversable = $this->optimizeUnwrap(); - - if (is_array($traversable)) { - return count($traversable); - } - - return iterator_count($traversable); - } - - /** - * {@inheritDoc} - * - * @return int - */ - public function countKeys() - { - return count($this->toArray()); - } - - /** - * Unwraps this iterator and returns the simplest - * traversable that can be used for getting the data out - * - * @return \Traversable|array - */ - protected function optimizeUnwrap() - { - $iterator = $this->unwrap(); - - if (get_class($iterator) === ArrayIterator::class) { - $iterator = $iterator->getArrayCopy(); - } - - return $iterator; - } -} diff --git a/vendor/cakephp/cakephp/src/Collection/ExtractTrait.php b/vendor/cakephp/cakephp/src/Collection/ExtractTrait.php deleted file mode 100644 index 2beb22d..0000000 --- a/vendor/cakephp/cakephp/src/Collection/ExtractTrait.php +++ /dev/null @@ -1,147 +0,0 @@ -_extract($element, $path); - }; - } - - return function ($element) use ($path) { - return $this->_simpleExtract($element, $path); - }; - } - - /** - * Returns a column from $data that can be extracted - * by iterating over the column names contained in $path. - * It will return arrays for elements in represented with `{*}` - * - * @param array|\ArrayAccess $data Data. - * @param array $path Path to extract from. - * @return mixed - */ - protected function _extract($data, $path) - { - $value = null; - $collectionTransform = false; - - foreach ($path as $i => $column) { - if ($column === '{*}') { - $collectionTransform = true; - continue; - } - - if ($collectionTransform && - !($data instanceof Traversable || is_array($data))) { - return null; - } - - if ($collectionTransform) { - $rest = implode('.', array_slice($path, $i)); - - return (new Collection($data))->extract($rest); - } - - if (!isset($data[$column])) { - return null; - } - - $value = $data[$column]; - $data = $value; - } - - return $value; - } - - /** - * Returns a column from $data that can be extracted - * by iterating over the column names contained in $path - * - * @param array|\ArrayAccess $data Data. - * @param array $path Path to extract from. - * @return mixed - */ - protected function _simpleExtract($data, $path) - { - $value = null; - foreach ($path as $column) { - if (!isset($data[$column])) { - return null; - } - $value = $data[$column]; - $data = $value; - } - - return $value; - } - - /** - * Returns a callable that receives a value and will return whether or not - * it matches certain condition. - * - * @param array $conditions A key-value list of conditions to match where the - * key is the property path to get from the current item and the value is the - * value to be compared the item with. - * @return callable - */ - protected function _createMatcherFilter(array $conditions) - { - $matchers = []; - foreach ($conditions as $property => $value) { - $extractor = $this->_propertyExtractor($property); - $matchers[] = function ($v) use ($extractor, $value) { - return $extractor($v) == $value; - }; - } - - return function ($value) use ($matchers) { - foreach ($matchers as $match) { - if (!$match($value)) { - return false; - } - } - - return true; - }; - } -} diff --git a/vendor/cakephp/cakephp/src/Collection/Iterator/BufferedIterator.php b/vendor/cakephp/cakephp/src/Collection/Iterator/BufferedIterator.php deleted file mode 100644 index cc7adf0..0000000 --- a/vendor/cakephp/cakephp/src/Collection/Iterator/BufferedIterator.php +++ /dev/null @@ -1,212 +0,0 @@ -_buffer = new SplDoublyLinkedList(); - parent::__construct($items); - } - - /** - * Returns the current key in the iterator - * - * @return mixed - */ - public function key() - { - return $this->_key; - } - - /** - * Returns the current record in the iterator - * - * @return mixed - */ - public function current() - { - return $this->_current; - } - - /** - * Rewinds the collection - * - * @return void - */ - public function rewind() - { - if ($this->_index === 0 && !$this->_started) { - $this->_started = true; - parent::rewind(); - - return; - } - - $this->_index = 0; - } - - /** - * Returns whether or not the iterator has more elements - * - * @return bool - */ - public function valid() - { - if ($this->_buffer->offsetExists($this->_index)) { - $current = $this->_buffer->offsetGet($this->_index); - $this->_current = $current['value']; - $this->_key = $current['key']; - - return true; - } - - $valid = parent::valid(); - - if ($valid) { - $this->_current = parent::current(); - $this->_key = parent::key(); - $this->_buffer->push([ - 'key' => $this->_key, - 'value' => $this->_current - ]); - } - - $this->_finished = !$valid; - - return $valid; - } - - /** - * Advances the iterator pointer to the next element - * - * @return void - */ - public function next() - { - $this->_index++; - - if (!$this->_finished) { - parent::next(); - } - } - - /** - * Returns the number or items in this collection - * - * @return int - */ - public function count() - { - if (!$this->_started) { - $this->rewind(); - } - - while ($this->valid()) { - $this->next(); - } - - return $this->_buffer->count(); - } - - /** - * Returns a string representation of this object that can be used - * to reconstruct it - * - * @return string - */ - public function serialize() - { - if (!$this->_finished) { - $this->count(); - } - - return serialize($this->_buffer); - } - - /** - * Unserializes the passed string and rebuilds the BufferedIterator instance - * - * @param string $buffer The serialized buffer iterator - * @return void - */ - public function unserialize($buffer) - { - $this->__construct([]); - $this->_buffer = unserialize($buffer); - $this->_started = true; - $this->_finished = true; - } -} diff --git a/vendor/cakephp/cakephp/src/Collection/Iterator/ExtractIterator.php b/vendor/cakephp/cakephp/src/Collection/Iterator/ExtractIterator.php deleted file mode 100644 index 2ffe139..0000000 --- a/vendor/cakephp/cakephp/src/Collection/Iterator/ExtractIterator.php +++ /dev/null @@ -1,107 +0,0 @@ - ['body' => 'cool', 'user' => ['name' => 'Mark']], - * ['comment' => ['body' => 'very cool', 'user' => ['name' => 'Renan']] - * ]; - * $extractor = new ExtractIterator($items, 'comment.user.name''); - * ``` - * - * @param array|\Traversable $items The list of values to iterate - * @param string $path a dot separated string symbolizing the path to follow - * inside the hierarchy of each value so that the column can be extracted. - */ - public function __construct($items, $path) - { - $this->_extractor = $this->_propertyExtractor($path); - parent::__construct($items); - } - - /** - * Returns the column value defined in $path or null if the path could not be - * followed - * - * @return mixed - */ - public function current() - { - $extractor = $this->_extractor; - - return $extractor(parent::current()); - } - - /** - * {@inheritDoc} - * - * We perform here some strictness analysis so that the - * iterator logic is bypassed entirely. - * - * @return \Iterator - */ - public function unwrap() - { - $iterator = $this->getInnerIterator(); - - if ($iterator instanceof CollectionInterface) { - $iterator = $iterator->unwrap(); - } - - if (get_class($iterator) !== ArrayIterator::class) { - return $this; - } - - // ArrayIterator can be traversed strictly. - // Let's do that for performance gains - - $callback = $this->_extractor; - $res = []; - - foreach ($iterator->getArrayCopy() as $k => $v) { - $res[$k] = $callback($v); - } - - return new ArrayIterator($res); - } -} diff --git a/vendor/cakephp/cakephp/src/Collection/Iterator/FilterIterator.php b/vendor/cakephp/cakephp/src/Collection/Iterator/FilterIterator.php deleted file mode 100644 index 4612f2b..0000000 --- a/vendor/cakephp/cakephp/src/Collection/Iterator/FilterIterator.php +++ /dev/null @@ -1,95 +0,0 @@ -_callback = $callback; - $wrapper = new CallbackFilterIterator($items, $callback); - parent::__construct($wrapper); - } - - /** - * {@inheritDoc} - * - * We perform here some strictness analysis so that the - * iterator logic is bypassed entirely. - * - * @return \Iterator - */ - public function unwrap() - { - $filter = $this->getInnerIterator(); - $iterator = $filter->getInnerIterator(); - - if ($iterator instanceof CollectionInterface) { - $iterator = $iterator->unwrap(); - } - - if (get_class($iterator) !== ArrayIterator::class) { - return $filter; - } - - // ArrayIterator can be traversed strictly. - // Let's do that for performance gains - - $callback = $this->_callback; - $res = []; - - foreach ($iterator as $k => $v) { - if ($callback($v, $k, $iterator)) { - $res[$k] = $v; - } - } - - return new ArrayIterator($res); - } -} diff --git a/vendor/cakephp/cakephp/src/Collection/Iterator/InsertIterator.php b/vendor/cakephp/cakephp/src/Collection/Iterator/InsertIterator.php deleted file mode 100644 index 8941116..0000000 --- a/vendor/cakephp/cakephp/src/Collection/Iterator/InsertIterator.php +++ /dev/null @@ -1,135 +0,0 @@ -_path = $path; - $this->_target = $target; - $this->_values = $values; - } - - /** - * Advances the cursor to the next record - * - * @return void - */ - public function next() - { - parent::next(); - if ($this->_validValues) { - $this->_values->next(); - } - $this->_validValues = $this->_values->valid(); - } - - /** - * Returns the current element in the target collection after inserting - * the value from the source collection into the specified path. - * - * @return mixed - */ - public function current() - { - $row = parent::current(); - - if (!$this->_validValues) { - return $row; - } - - $pointer =& $row; - foreach ($this->_path as $step) { - if (!isset($pointer[$step])) { - return $row; - } - $pointer =& $pointer[$step]; - } - - $pointer[$this->_target] = $this->_values->current(); - - return $row; - } - - /** - * Resets the collection pointer. - * - * @return void - */ - public function rewind() - { - parent::rewind(); - $this->_values->rewind(); - $this->_validValues = $this->_values->valid(); - } -} diff --git a/vendor/cakephp/cakephp/src/Collection/Iterator/MapReduce.php b/vendor/cakephp/cakephp/src/Collection/Iterator/MapReduce.php deleted file mode 100644 index c8b6090..0000000 --- a/vendor/cakephp/cakephp/src/Collection/Iterator/MapReduce.php +++ /dev/null @@ -1,193 +0,0 @@ -emitIntermediate($value, $type); - * }; - * - * $reducer = function ($numbers, $type, $mr) { - * $mr->emit(array_unique($numbers), $type); - * }; - * $results = new MapReduce($data, $mapper, $reducer); - * ``` - * - * Previous example will generate the following result: - * - * ``` - * ['odd' => [1, 3, 5], 'even' => [2, 4]] - * ``` - * - * @param \Traversable $data the original data to be processed - * @param callable $mapper the mapper callback. This function will receive 3 arguments. - * The first one is the current value, second the current results key and third is - * this class instance so you can call the result emitters. - * @param callable|null $reducer the reducer callback. This function will receive 3 arguments. - * The first one is the list of values inside a bucket, second one is the name - * of the bucket that was created during the mapping phase and third one is an - * instance of this class. - */ - public function __construct(Traversable $data, callable $mapper, callable $reducer = null) - { - $this->_data = $data; - $this->_mapper = $mapper; - $this->_reducer = $reducer; - } - - /** - * Returns an iterator with the end result of running the Map and Reduce - * phases on the original data - * - * @return \ArrayIterator - */ - public function getIterator() - { - if (!$this->_executed) { - $this->_execute(); - } - - return new ArrayIterator($this->_result); - } - - /** - * Appends a new record to the bucket labelled with $key, usually as a result - * of mapping a single record from the original data. - * - * @param mixed $val The record itself to store in the bucket - * @param string $bucket the name of the bucket where to put the record - * @return void - */ - public function emitIntermediate($val, $bucket) - { - $this->_intermediate[$bucket][] = $val; - } - - /** - * Appends a new record to the final list of results and optionally assign a key - * for this record. - * - * @param mixed $val The value to be appended to the final list of results - * @param string|null $key and optional key to assign to the value - * @return void - */ - public function emit($val, $key = null) - { - $this->_result[$key === null ? $this->_counter : $key] = $val; - $this->_counter++; - } - - /** - * Runs the actual Map-Reduce algorithm. This is iterate the original data - * and call the mapper function for each , then for each intermediate - * bucket created during the Map phase call the reduce function. - * - * @return void - * @throws \LogicException if emitIntermediate was called but no reducer function - * was provided - */ - protected function _execute() - { - $mapper = $this->_mapper; - foreach ($this->_data as $key => $val) { - $mapper($val, $key, $this); - } - $this->_data = null; - - if (!empty($this->_intermediate) && empty($this->_reducer)) { - throw new LogicException('No reducer function was provided'); - } - - $reducer = $this->_reducer; - foreach ($this->_intermediate as $key => $list) { - $reducer($list, $key, $this); - } - $this->_intermediate = []; - $this->_executed = true; - } -} diff --git a/vendor/cakephp/cakephp/src/Collection/Iterator/NestIterator.php b/vendor/cakephp/cakephp/src/Collection/Iterator/NestIterator.php deleted file mode 100644 index ac9e6cb..0000000 --- a/vendor/cakephp/cakephp/src/Collection/Iterator/NestIterator.php +++ /dev/null @@ -1,77 +0,0 @@ -_nestKey = $nestKey; - } - - /** - * Returns a traversable containing the children for the current item - * - * @return \Traversable - */ - public function getChildren() - { - $property = $this->_propertyExtractor($this->_nestKey); - - return new static($property($this->current()), $this->_nestKey); - } - - /** - * Returns true if there is an array or a traversable object stored under the - * configured nestKey for the current item - * - * @return bool - */ - public function hasChildren() - { - $property = $this->_propertyExtractor($this->_nestKey); - $children = $property($this->current()); - - if (is_array($children)) { - return !empty($children); - } - - return $children instanceof Traversable; - } -} diff --git a/vendor/cakephp/cakephp/src/Collection/Iterator/NoChildrenIterator.php b/vendor/cakephp/cakephp/src/Collection/Iterator/NoChildrenIterator.php deleted file mode 100644 index aaf1fe6..0000000 --- a/vendor/cakephp/cakephp/src/Collection/Iterator/NoChildrenIterator.php +++ /dev/null @@ -1,47 +0,0 @@ -_callback = $callback; - parent::__construct($items); - $this->_innerIterator = $this->getInnerIterator(); - } - - /** - * Returns the value returned by the callback after passing the current value in - * the iteration - * - * @return mixed - */ - public function current() - { - $callback = $this->_callback; - - return $callback(parent::current(), $this->key(), $this->_innerIterator); - } - - /** - * {@inheritDoc} - * - * We perform here some strictness analysis so that the - * iterator logic is bypassed entirely. - * - * @return \Iterator - */ - public function unwrap() - { - $iterator = $this->_innerIterator; - - if ($iterator instanceof CollectionInterface) { - $iterator = $iterator->unwrap(); - } - - if (get_class($iterator) !== ArrayIterator::class) { - return $this; - } - - // ArrayIterator can be traversed strictly. - // Let's do that for performance gains - - $callback = $this->_callback; - $res = []; - - foreach ($iterator as $k => $v) { - $res[$k] = $callback($v, $k, $iterator); - } - - return new ArrayIterator($res); - } -} diff --git a/vendor/cakephp/cakephp/src/Collection/Iterator/SortIterator.php b/vendor/cakephp/cakephp/src/Collection/Iterator/SortIterator.php deleted file mode 100644 index 82c4b19..0000000 --- a/vendor/cakephp/cakephp/src/Collection/Iterator/SortIterator.php +++ /dev/null @@ -1,93 +0,0 @@ -age; - * }); - * - * // output all user name order by their age in descending order - * foreach ($sorted as $user) { - * echo $user->name; - * } - * ``` - * - * This iterator does not preserve the keys passed in the original elements. - */ -class SortIterator extends Collection -{ - - /** - * Wraps this iterator around the passed items so when iterated they are returned - * in order. - * - * The callback will receive as first argument each of the elements in $items, - * the value returned in the callback will be used as the value for sorting such - * element. Please note that the callback function could be called more than once - * per element. - * - * @param array|\Traversable $items The values to sort - * @param callable|string $callback A function used to return the actual value to - * be compared. It can also be a string representing the path to use to fetch a - * column or property in each element - * @param int $dir either SORT_DESC or SORT_ASC - * @param int $type the type of comparison to perform, either SORT_STRING - * SORT_NUMERIC or SORT_NATURAL - */ - public function __construct($items, $callback, $dir = SORT_DESC, $type = SORT_NUMERIC) - { - if (!is_array($items)) { - $items = iterator_to_array((new Collection($items))->unwrap(), false); - } - - $callback = $this->_propertyExtractor($callback); - $results = []; - foreach ($items as $key => $val) { - $val = $callback($val); - if ($val instanceof DateTimeInterface && $type === SORT_NUMERIC) { - $val = $val->format('U'); - } - $results[$key] = $val; - } - - $dir === SORT_DESC ? arsort($results, $type) : asort($results, $type); - - foreach (array_keys($results) as $key) { - $results[$key] = $items[$key]; - } - parent::__construct($results); - } - - /** - * {@inheritDoc} - * - * @return \Iterator - */ - public function unwrap() - { - return $this->getInnerIterator(); - } -} diff --git a/vendor/cakephp/cakephp/src/Collection/Iterator/StoppableIterator.php b/vendor/cakephp/cakephp/src/Collection/Iterator/StoppableIterator.php deleted file mode 100644 index 7d1882c..0000000 --- a/vendor/cakephp/cakephp/src/Collection/Iterator/StoppableIterator.php +++ /dev/null @@ -1,119 +0,0 @@ -_condition = $condition; - parent::__construct($items); - $this->_innerIterator = $this->getInnerIterator(); - } - - /** - * Evaluates the condition and returns its result, this controls - * whether or not more results will be yielded. - * - * @return bool - */ - public function valid() - { - if (!parent::valid()) { - return false; - } - - $current = $this->current(); - $key = $this->key(); - $condition = $this->_condition; - - return !$condition($current, $key, $this->_innerIterator); - } - - /** - * {@inheritDoc} - * - * We perform here some strictness analysis so that the - * iterator logic is bypassed entirely. - * - * @return \Iterator - */ - public function unwrap() - { - $iterator = $this->_innerIterator; - - if ($iterator instanceof CollectionInterface) { - $iterator = $iterator->unwrap(); - } - - if (get_class($iterator) !== ArrayIterator::class) { - return $this; - } - - // ArrayIterator can be traversed strictly. - // Let's do that for performance gains - - $callback = $this->_condition; - $res = []; - - foreach ($iterator as $k => $v) { - if ($callback($v, $k, $iterator)) { - break; - } - $res[$k] = $v; - } - - return new ArrayIterator($res); - } -} diff --git a/vendor/cakephp/cakephp/src/Collection/Iterator/TreeIterator.php b/vendor/cakephp/cakephp/src/Collection/Iterator/TreeIterator.php deleted file mode 100644 index f4d2251..0000000 --- a/vendor/cakephp/cakephp/src/Collection/Iterator/TreeIterator.php +++ /dev/null @@ -1,105 +0,0 @@ -_mode = $mode; - } - - /** - * Returns another iterator which will return the values ready to be displayed - * to a user. It does so by extracting one property from each of the elements - * and prefixing it with a spacer so that the relative position in the tree - * can be visualized. - * - * Both $valuePath and $keyPath can be a string with a property name to extract - * or a dot separated path of properties that should be followed to get the last - * one in the path. - * - * Alternatively, $valuePath and $keyPath can be callable functions. They will get - * the current element as first parameter, the current iteration key as second - * parameter, and the iterator instance as third argument. - * - * ### Example - * - * ``` - * $printer = (new Collection($treeStructure))->listNested()->printer('name'); - * ``` - * - * Using a closure: - * - * ``` - * $printer = (new Collection($treeStructure)) - * ->listNested() - * ->printer(function ($item, $key, $iterator) { - * return $item->name; - * }); - * ``` - * - * @param string|callable $valuePath The property to extract or a callable to return - * the display value - * @param string|callable|null $keyPath The property to use as iteration key or a - * callable returning the key value. - * @param string $spacer The string to use for prefixing the values according to - * their depth in the tree - * @return \Cake\Collection\Iterator\TreePrinter - */ - public function printer($valuePath, $keyPath = null, $spacer = '__') - { - if (!$keyPath) { - $counter = 0; - $keyPath = function () use (&$counter) { - return $counter++; - }; - } - - return new TreePrinter( - $this->getInnerIterator(), - $valuePath, - $keyPath, - $spacer, - $this->_mode - ); - } -} diff --git a/vendor/cakephp/cakephp/src/Collection/Iterator/TreePrinter.php b/vendor/cakephp/cakephp/src/Collection/Iterator/TreePrinter.php deleted file mode 100644 index fa72d0e..0000000 --- a/vendor/cakephp/cakephp/src/Collection/Iterator/TreePrinter.php +++ /dev/null @@ -1,127 +0,0 @@ -_value = $this->_propertyExtractor($valuePath); - $this->_key = $this->_propertyExtractor($keyPath); - $this->_spacer = $spacer; - } - - /** - * Returns the current iteration key - * - * @return mixed - */ - public function key() - { - $extractor = $this->_key; - - return $extractor($this->_fetchCurrent(), parent::key(), $this); - } - - /** - * Returns the current iteration value - * - * @return string - */ - public function current() - { - $extractor = $this->_value; - $current = $this->_fetchCurrent(); - $spacer = str_repeat($this->_spacer, $this->getDepth()); - - return $spacer . $extractor($current, parent::key(), $this); - } - - /** - * Advances the cursor one position - * - * @return void - */ - public function next() - { - parent::next(); - $this->_current = null; - } - - /** - * Returns the current iteration element and caches its value - * - * @return mixed - */ - protected function _fetchCurrent() - { - if ($this->_current !== null) { - return $this->_current; - } - - return $this->_current = parent::current(); - } -} diff --git a/vendor/cakephp/cakephp/src/Collection/Iterator/UnfoldIterator.php b/vendor/cakephp/cakephp/src/Collection/Iterator/UnfoldIterator.php deleted file mode 100644 index 06a2ca6..0000000 --- a/vendor/cakephp/cakephp/src/Collection/Iterator/UnfoldIterator.php +++ /dev/null @@ -1,86 +0,0 @@ -_unfolder = $unfolder; - parent::__construct($items); - $this->_innerIterator = $this->getInnerIterator(); - } - - /** - * Returns true as each of the elements in the array represent a - * list of items - * - * @return bool - */ - public function hasChildren() - { - return true; - } - - /** - * Returns an iterator containing the items generated by transforming - * the current value with the callable function. - * - * @return \RecursiveIterator - */ - public function getChildren() - { - $current = $this->current(); - $key = $this->key(); - $unfolder = $this->_unfolder; - - return new NoChildrenIterator($unfolder($current, $key, $this->_innerIterator)); - } -} diff --git a/vendor/cakephp/cakephp/src/Collection/Iterator/ZipIterator.php b/vendor/cakephp/cakephp/src/Collection/Iterator/ZipIterator.php deleted file mode 100644 index 9c4adac..0000000 --- a/vendor/cakephp/cakephp/src/Collection/Iterator/ZipIterator.php +++ /dev/null @@ -1,126 +0,0 @@ -toList(); // Returns [[1, 3], [2, 4]] - * ``` - * - * You can also chose a custom function to zip the elements together, such - * as doing a sum by index: - * - * ### Example - * - * ``` - * $iterator = new ZipIterator([[1, 2], [3, 4]], function ($a, $b) { - * return $a + $b; - * }); - * $iterator->toList(); // Returns [4, 6] - * ``` - */ -class ZipIterator extends MultipleIterator implements CollectionInterface, Serializable -{ - - use CollectionTrait; - - /** - * The function to use for zipping items together - * - * @var callable - */ - protected $_callback; - - /** - * Contains the original iterator objects that were attached - * - * @var array - */ - protected $_iterators = []; - - /** - * Creates the iterator to merge together the values by for all the passed - * iterators by their corresponding index. - * - * @param array $sets The list of array or iterators to be zipped. - * @param callable|null $callable The function to use for zipping the elements of each iterator. - */ - public function __construct(array $sets, $callable = null) - { - $sets = array_map(function ($items) { - return (new Collection($items))->unwrap(); - }, $sets); - - $this->_callback = $callable; - parent::__construct(MultipleIterator::MIT_NEED_ALL | MultipleIterator::MIT_KEYS_NUMERIC); - - foreach ($sets as $set) { - $this->_iterators[] = $set; - $this->attachIterator($set); - } - } - - /** - * Returns the value resulting out of zipping all the elements for all the - * iterators with the same positional index. - * - * @return mixed - */ - public function current() - { - if ($this->_callback === null) { - return parent::current(); - } - - return call_user_func_array($this->_callback, parent::current()); - } - - /** - * Returns a string representation of this object that can be used - * to reconstruct it - * - * @return string - */ - public function serialize() - { - return serialize($this->_iterators); - } - - /** - * Unserializes the passed string and rebuilds the ZipIterator instance - * - * @param string $iterators The serialized iterators - * @return void - */ - public function unserialize($iterators) - { - parent::__construct(MultipleIterator::MIT_NEED_ALL | MultipleIterator::MIT_KEYS_NUMERIC); - $this->_iterators = unserialize($iterators); - foreach ($this->_iterators as $it) { - $this->attachIterator($it); - } - } -} diff --git a/vendor/cakephp/cakephp/src/Collection/LICENSE.txt b/vendor/cakephp/cakephp/src/Collection/LICENSE.txt deleted file mode 100644 index 0c4b793..0000000 --- a/vendor/cakephp/cakephp/src/Collection/LICENSE.txt +++ /dev/null @@ -1,22 +0,0 @@ -The MIT License (MIT) - -CakePHP(tm) : The Rapid Development PHP Framework (https://cakephp.org) -Copyright (c) 2005-2016, Cake Software Foundation, Inc. (https://cakefoundation.org) - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. diff --git a/vendor/cakephp/cakephp/src/Collection/README.md b/vendor/cakephp/cakephp/src/Collection/README.md deleted file mode 100644 index 9863913..0000000 --- a/vendor/cakephp/cakephp/src/Collection/README.md +++ /dev/null @@ -1,31 +0,0 @@ -[![Total Downloads](https://img.shields.io/packagist/dt/cakephp/collection.svg?style=flat-square)](https://packagist.org/packages/cakephp/collection) -[![License](https://img.shields.io/badge/license-MIT-blue.svg?style=flat-square)](LICENSE.txt) - -# CakePHP Collection Library - -The collection classes provide a set of tools to manipulate arrays or Traversable objects. -If you have ever used underscore.js, you have an idea of what you can expect from the collection classes. - -## Usage - -Collections can be created using an array or Traversable object. A simple use of a Collection would be: - -```php -use Cake\Collection\Collection; - -$items = ['a' => 1, 'b' => 2, 'c' => 3]; -$collection = new Collection($items); - -// Create a new collection containing elements -// with a value greater than one. -$overOne = $collection->filter(function ($value, $key, $iterator) { - return $value > 1; -}); -``` - -The `Collection\CollectionTrait` allows you to integrate collection-like features into any Traversable object -you have in your application as well. - -## Documentation - -Please make sure you check the [official documentation](https://book.cakephp.org/3.0/en/core-libraries/collections.html) diff --git a/vendor/cakephp/cakephp/src/Collection/composer.json b/vendor/cakephp/cakephp/src/Collection/composer.json deleted file mode 100644 index 47a24c4..0000000 --- a/vendor/cakephp/cakephp/src/Collection/composer.json +++ /dev/null @@ -1,36 +0,0 @@ -{ - "name": "cakephp/collection", - "description": "Work easily with arrays and iterators by having a battery of utility traversal methods", - "type": "library", - "keywords": [ - "cakephp", - "collections", - "iterators", - "arrays" - ], - "homepage": "https://cakephp.org", - "license": "MIT", - "authors": [ - { - "name": "CakePHP Community", - "homepage": "https://github.com/cakephp/collection/graphs/contributors" - } - ], - "support": { - "issues": "https://github.com/cakephp/cakephp/issues", - "forum": "https://stackoverflow.com/tags/cakephp", - "irc": "irc://irc.freenode.org/cakephp", - "source": "https://github.com/cakephp/collection" - }, - "require": { - "php": ">=5.6.0" - }, - "autoload": { - "psr-4": { - "Cake\\Collection\\": "." - }, - "files": [ - "functions.php" - ] - } -} diff --git a/vendor/cakephp/cakephp/src/Collection/functions.php b/vendor/cakephp/cakephp/src/Collection/functions.php deleted file mode 100644 index e1f01b5..0000000 --- a/vendor/cakephp/cakephp/src/Collection/functions.php +++ /dev/null @@ -1,29 +0,0 @@ -_stderr = $options['stderr']; - $this->_options = $options; - } - - /** - * Handle errors in the console environment. Writes errors to stderr, - * and logs messages if Configure::read('debug') is false. - * - * @param \Exception $exception Exception instance. - * @return void - * @throws \Exception When renderer class not found - * @see https://secure.php.net/manual/en/function.set-exception-handler.php - */ - public function handleException(Exception $exception) - { - $this->_displayException($exception); - $this->_logException($exception); - $code = $exception->getCode(); - $code = ($code && is_int($code)) ? $code : 1; - $this->_stop($code); - } - - /** - * Prints an exception to stderr. - * - * @param \Exception $exception The exception to handle - * @return void - */ - protected function _displayException($exception) - { - $errorName = 'Exception:'; - if ($exception instanceof FatalErrorException) { - $errorName = 'Fatal Error:'; - } - - if ($exception instanceof PHP7ErrorException) { - $exception = $exception->getError(); - } - - $message = sprintf( - '%s %s in [%s, line %s]', - $errorName, - $exception->getMessage(), - $exception->getFile(), - $exception->getLine() - ); - $this->_stderr->write($message); - } - - /** - * Prints an error to stderr. - * - * Template method of BaseErrorHandler. - * - * @param array $error An array of error data. - * @param bool $debug Whether or not the app is in debug mode. - * @return void - */ - protected function _displayError($error, $debug) - { - $message = sprintf( - '%s in [%s, line %s]', - $error['description'], - $error['file'], - $error['line'] - ); - $message = sprintf( - "%s Error: %s\n", - $error['error'], - $message - ); - $this->_stderr->write($message); - } - - /** - * Stop the execution and set the exit code for the process. - * - * @param int $code The exit code. - * @return void - */ - protected function _stop($code) - { - exit($code); - } -} diff --git a/vendor/cakephp/cakephp/src/Console/ConsoleInput.php b/vendor/cakephp/cakephp/src/Console/ConsoleInput.php deleted file mode 100644 index 118cc1f..0000000 --- a/vendor/cakephp/cakephp/src/Console/ConsoleInput.php +++ /dev/null @@ -1,84 +0,0 @@ -_canReadline = (extension_loaded('readline') && $handle === 'php://stdin'); - $this->_input = fopen($handle, 'rb'); - } - - /** - * Read a value from the stream - * - * @return mixed The value of the stream - */ - public function read() - { - if ($this->_canReadline) { - $line = readline(''); - if (strlen($line) > 0) { - readline_add_history($line); - } - - return $line; - } - - return fgets($this->_input); - } - - /** - * Check if data is available on stdin - * - * @param int $timeout An optional time to wait for data - * @return bool True for data available, false otherwise - */ - public function dataAvailable($timeout = 0) - { - $readFds = [$this->_input]; - $readyFds = stream_select($readFds, $writeFds, $errorFds, $timeout); - - return ($readyFds > 0); - } -} diff --git a/vendor/cakephp/cakephp/src/Console/ConsoleInputArgument.php b/vendor/cakephp/cakephp/src/Console/ConsoleInputArgument.php deleted file mode 100644 index bc0314d..0000000 --- a/vendor/cakephp/cakephp/src/Console/ConsoleInputArgument.php +++ /dev/null @@ -1,197 +0,0 @@ - $value) { - $this->{'_' . $key} = $value; - } - } else { - $this->_name = $name; - $this->_help = $help; - $this->_required = $required; - $this->_choices = $choices; - } - } - - /** - * Get the value of the name attribute. - * - * @return string Value of this->_name. - */ - public function name() - { - return $this->_name; - } - - /** - * Checks if this argument is equal to another argument. - * - * @param \Cake\Console\ConsoleInputArgument $argument ConsoleInputArgument to compare to. - * @return bool - */ - public function isEqualTo(ConsoleInputArgument $argument) - { - return $this->usage() === $argument->usage(); - } - - /** - * Generate the help for this argument. - * - * @param int $width The width to make the name of the option. - * @return string - */ - public function help($width = 0) - { - $name = $this->_name; - if (strlen($name) < $width) { - $name = str_pad($name, $width, ' '); - } - $optional = ''; - if (!$this->isRequired()) { - $optional = ' (optional)'; - } - if ($this->_choices) { - $optional .= sprintf(' (choices: %s)', implode('|', $this->_choices)); - } - - return sprintf('%s%s%s', $name, $this->_help, $optional); - } - - /** - * Get the usage value for this argument - * - * @return string - */ - public function usage() - { - $name = $this->_name; - if ($this->_choices) { - $name = implode('|', $this->_choices); - } - $name = '<' . $name . '>'; - if (!$this->isRequired()) { - $name = '[' . $name . ']'; - } - - return $name; - } - - /** - * Check if this argument is a required argument - * - * @return bool - */ - public function isRequired() - { - return (bool)$this->_required; - } - - /** - * Check that $value is a valid choice for this argument. - * - * @param string $value The choice to validate. - * @return bool - * @throws \Cake\Console\Exception\ConsoleException - */ - public function validChoice($value) - { - if (empty($this->_choices)) { - return true; - } - if (!in_array($value, $this->_choices)) { - throw new ConsoleException( - sprintf( - '"%s" is not a valid value for %s. Please use one of "%s"', - $value, - $this->_name, - implode(', ', $this->_choices) - ) - ); - } - - return true; - } - - /** - * Append this arguments XML representation to the passed in SimpleXml object. - * - * @param \SimpleXMLElement $parent The parent element. - * @return \SimpleXMLElement The parent with this argument appended. - */ - public function xml(SimpleXMLElement $parent) - { - $option = $parent->addChild('argument'); - $option->addAttribute('name', $this->_name); - $option->addAttribute('help', $this->_help); - $option->addAttribute('required', (int)$this->isRequired()); - $choices = $option->addChild('choices'); - foreach ($this->_choices as $valid) { - $choices->addChild('choice', $valid); - } - - return $parent; - } -} diff --git a/vendor/cakephp/cakephp/src/Console/ConsoleInputOption.php b/vendor/cakephp/cakephp/src/Console/ConsoleInputOption.php deleted file mode 100644 index 87d280a..0000000 --- a/vendor/cakephp/cakephp/src/Console/ConsoleInputOption.php +++ /dev/null @@ -1,265 +0,0 @@ - $value) { - $this->{'_' . $key} = $value; - } - } else { - $this->_name = $name; - $this->_short = $short; - $this->_help = $help; - $this->_boolean = $boolean; - $this->_default = $default; - $this->_choices = $choices; - $this->_multiple = $multiple; - } - if (strlen($this->_short) > 1) { - throw new ConsoleException( - sprintf('Short option "%s" is invalid, short options must be one letter.', $this->_short) - ); - } - } - - /** - * Get the value of the name attribute. - * - * @return string Value of this->_name. - */ - public function name() - { - return $this->_name; - } - - /** - * Get the value of the short attribute. - * - * @return string Value of this->_short. - */ - public function short() - { - return $this->_short; - } - - /** - * Generate the help for this this option. - * - * @param int $width The width to make the name of the option. - * @return string - */ - public function help($width = 0) - { - $default = $short = ''; - if ($this->_default && $this->_default !== true) { - $default = sprintf(' (default: %s)', $this->_default); - } - if ($this->_choices) { - $default .= sprintf(' (choices: %s)', implode('|', $this->_choices)); - } - if (strlen($this->_short) > 0) { - $short = ', -' . $this->_short; - } - $name = sprintf('--%s%s', $this->_name, $short); - if (strlen($name) < $width) { - $name = str_pad($name, $width, ' '); - } - - return sprintf('%s%s%s', $name, $this->_help, $default); - } - - /** - * Get the usage value for this option - * - * @return string - */ - public function usage() - { - $name = (strlen($this->_short) > 0) ? ('-' . $this->_short) : ('--' . $this->_name); - $default = ''; - if (strlen($this->_default) > 0 && $this->_default !== true) { - $default = ' ' . $this->_default; - } - if ($this->_choices) { - $default = ' ' . implode('|', $this->_choices); - } - - return sprintf('[%s%s]', $name, $default); - } - - /** - * Get the default value for this option - * - * @return mixed - */ - public function defaultValue() - { - return $this->_default; - } - - /** - * Check if this option is a boolean option - * - * @return bool - */ - public function isBoolean() - { - return (bool)$this->_boolean; - } - - /** - * Check if this option accepts multiple values. - * - * @return bool - */ - public function acceptsMultiple() - { - return (bool)$this->_multiple; - } - - /** - * Check that a value is a valid choice for this option. - * - * @param string $value The choice to validate. - * @return bool - * @throws \Cake\Console\Exception\ConsoleException - */ - public function validChoice($value) - { - if (empty($this->_choices)) { - return true; - } - if (!in_array($value, $this->_choices)) { - throw new ConsoleException( - sprintf( - '"%s" is not a valid value for --%s. Please use one of "%s"', - $value, - $this->_name, - implode(', ', $this->_choices) - ) - ); - } - - return true; - } - - /** - * Append the option's xml into the parent. - * - * @param \SimpleXMLElement $parent The parent element. - * @return \SimpleXMLElement The parent with this option appended. - */ - public function xml(SimpleXMLElement $parent) - { - $option = $parent->addChild('option'); - $option->addAttribute('name', '--' . $this->_name); - $short = ''; - if (strlen($this->_short) > 0) { - $short = '-' . $this->_short; - } - $option->addAttribute('short', $short); - $option->addAttribute('help', $this->_help); - $option->addAttribute('boolean', (int)$this->_boolean); - $option->addChild('default', $this->_default); - $choices = $option->addChild('choices'); - foreach ($this->_choices as $valid) { - $choices->addChild('choice', $valid); - } - - return $parent; - } -} diff --git a/vendor/cakephp/cakephp/src/Console/ConsoleInputSubcommand.php b/vendor/cakephp/cakephp/src/Console/ConsoleInputSubcommand.php deleted file mode 100644 index 1330098..0000000 --- a/vendor/cakephp/cakephp/src/Console/ConsoleInputSubcommand.php +++ /dev/null @@ -1,140 +0,0 @@ - $value) { - $this->{'_' . $key} = $value; - } - } else { - $this->_name = $name; - $this->_help = $help; - $this->_parser = $parser; - } - if (is_array($this->_parser)) { - $this->_parser['command'] = $this->_name; - $this->_parser = ConsoleOptionParser::buildFromArray($this->_parser); - } - } - - /** - * Get the value of the name attribute. - * - * @return string Value of this->_name. - */ - public function name() - { - return $this->_name; - } - - /** - * Get the raw help string for this command - * - * @return string - */ - public function getRawHelp() - { - return $this->_help; - } - - /** - * Generate the help for this this subcommand. - * - * @param int $width The width to make the name of the subcommand. - * @return string - */ - public function help($width = 0) - { - $name = $this->_name; - if (strlen($name) < $width) { - $name = str_pad($name, $width, ' '); - } - - return $name . $this->_help; - } - - /** - * Get the usage value for this option - * - * @return \Cake\Console\ConsoleOptionParser|bool Either false or a ConsoleOptionParser - */ - public function parser() - { - if ($this->_parser instanceof ConsoleOptionParser) { - return $this->_parser; - } - - return false; - } - - /** - * Append this subcommand to the Parent element - * - * @param \SimpleXMLElement $parent The parent element. - * @return \SimpleXMLElement The parent with this subcommand appended. - */ - public function xml(SimpleXMLElement $parent) - { - $command = $parent->addChild('command'); - $command->addAttribute('name', $this->_name); - $command->addAttribute('help', $this->_help); - - return $parent; - } -} diff --git a/vendor/cakephp/cakephp/src/Console/ConsoleIo.php b/vendor/cakephp/cakephp/src/Console/ConsoleIo.php deleted file mode 100644 index 65c5eab..0000000 --- a/vendor/cakephp/cakephp/src/Console/ConsoleIo.php +++ /dev/null @@ -1,592 +0,0 @@ -_out = $out ?: new ConsoleOutput('php://stdout'); - $this->_err = $err ?: new ConsoleOutput('php://stderr'); - $this->_in = $in ?: new ConsoleInput('php://stdin'); - $this->_helpers = $helpers ?: new HelperRegistry(); - $this->_helpers->setIo($this); - } - - /** - * Get/set the current output level. - * - * @param null|int $level The current output level. - * @return int The current output level. - */ - public function level($level = null) - { - if ($level !== null) { - $this->_level = $level; - } - - return $this->_level; - } - - /** - * Output at the verbose level. - * - * @param string|array $message A string or an array of strings to output - * @param int $newlines Number of newlines to append - * @return int|bool The number of bytes returned from writing to stdout. - */ - public function verbose($message, $newlines = 1) - { - return $this->out($message, $newlines, self::VERBOSE); - } - - /** - * Output at all levels. - * - * @param string|array $message A string or an array of strings to output - * @param int $newlines Number of newlines to append - * @return int|bool The number of bytes returned from writing to stdout. - */ - public function quiet($message, $newlines = 1) - { - return $this->out($message, $newlines, self::QUIET); - } - - /** - * Outputs a single or multiple messages to stdout. If no parameters - * are passed outputs just a newline. - * - * ### Output levels - * - * There are 3 built-in output level. Shell::QUIET, Shell::NORMAL, Shell::VERBOSE. - * The verbose and quiet output levels, map to the `verbose` and `quiet` output switches - * present in most shells. Using Shell::QUIET for a message means it will always display. - * While using Shell::VERBOSE means it will only display when verbose output is toggled. - * - * @param string|array $message A string or an array of strings to output - * @param int $newlines Number of newlines to append - * @param int $level The message's output level, see above. - * @return int|bool The number of bytes returned from writing to stdout. - */ - public function out($message = '', $newlines = 1, $level = ConsoleIo::NORMAL) - { - if ($level <= $this->_level) { - $this->_lastWritten = (int)$this->_out->write($message, $newlines); - - return $this->_lastWritten; - } - - return true; - } - - /** - * Convenience method for out() that wraps message between tag - * - * @param string|array|null $message A string or an array of strings to output - * @param int $newlines Number of newlines to append - * @param int $level The message's output level, see above. - * @return int|bool The number of bytes returned from writing to stdout. - * @see https://book.cakephp.org/3.0/en/console-and-shells.html#Shell::out - */ - public function info($message = null, $newlines = 1, $level = Shell::NORMAL) - { - $messageType = 'info'; - $message = $this->wrapMessageWithType($messageType, $message); - - return $this->out($message, $newlines, $level); - } - - /** - * Convenience method for err() that wraps message between tag - * - * @param string|array|null $message A string or an array of strings to output - * @param int $newlines Number of newlines to append - * @return int|bool The number of bytes returned from writing to stderr. - * @see https://book.cakephp.org/3.0/en/console-and-shells.html#Shell::err - */ - public function warning($message = null, $newlines = 1) - { - $messageType = 'warning'; - $message = $this->wrapMessageWithType($messageType, $message); - - return $this->err($message, $newlines); - } - - /** - * Convenience method for err() that wraps message between tag - * - * @param string|array|null $message A string or an array of strings to output - * @param int $newlines Number of newlines to append - * @return int|bool The number of bytes returned from writing to stderr. - * @see https://book.cakephp.org/3.0/en/console-and-shells.html#Shell::err - */ - public function error($message = null, $newlines = 1) - { - $messageType = 'error'; - $message = $this->wrapMessageWithType($messageType, $message); - - return $this->err($message, $newlines); - } - - /** - * Convenience method for out() that wraps message between tag - * - * @param string|array|null $message A string or an array of strings to output - * @param int $newlines Number of newlines to append - * @param int $level The message's output level, see above. - * @return int|bool The number of bytes returned from writing to stdout. - * @see https://book.cakephp.org/3.0/en/console-and-shells.html#Shell::out - */ - public function success($message = null, $newlines = 1, $level = Shell::NORMAL) - { - $messageType = 'success'; - $message = $this->wrapMessageWithType($messageType, $message); - - return $this->out($message, $newlines, $level); - } - - /** - * Wraps a message with a given message type, e.g. - * - * @param string $messageType The message type, e.g. "warning". - * @param string|array $message The message to wrap. - * @return array|string The message wrapped with the given message type. - */ - protected function wrapMessageWithType($messageType, $message) - { - if (is_array($message)) { - foreach ($message as $k => $v) { - $message[$k] = "<{$messageType}>{$v}"; - } - } else { - $message = "<{$messageType}>{$message}"; - } - - return $message; - } - - /** - * Overwrite some already output text. - * - * Useful for building progress bars, or when you want to replace - * text already output to the screen with new text. - * - * **Warning** You cannot overwrite text that contains newlines. - * - * @param array|string $message The message to output. - * @param int $newlines Number of newlines to append. - * @param int|null $size The number of bytes to overwrite. Defaults to the - * length of the last message output. - * @return void - */ - public function overwrite($message, $newlines = 1, $size = null) - { - $size = $size ?: $this->_lastWritten; - - // Output backspaces. - $this->out(str_repeat("\x08", $size), 0); - - $newBytes = $this->out($message, 0); - - // Fill any remaining bytes with spaces. - $fill = $size - $newBytes; - if ($fill > 0) { - $this->out(str_repeat(' ', $fill), 0); - } - if ($newlines) { - $this->out($this->nl($newlines), 0); - } - - // Store length of content + fill so if the new content - // is shorter than the old content the next overwrite - // will work. - if ($fill > 0) { - $this->_lastWritten = $newBytes + $fill; - } - } - - /** - * Outputs a single or multiple error messages to stderr. If no parameters - * are passed outputs just a newline. - * - * @param string|array $message A string or an array of strings to output - * @param int $newlines Number of newlines to append - * @return int|bool The number of bytes returned from writing to stderr. - */ - public function err($message = '', $newlines = 1) - { - return $this->_err->write($message, $newlines); - } - - /** - * Returns a single or multiple linefeeds sequences. - * - * @param int $multiplier Number of times the linefeed sequence should be repeated - * @return string - */ - public function nl($multiplier = 1) - { - return str_repeat(ConsoleOutput::LF, $multiplier); - } - - /** - * Outputs a series of minus characters to the standard output, acts as a visual separator. - * - * @param int $newlines Number of newlines to pre- and append - * @param int $width Width of the line, defaults to 79 - * @return void - */ - public function hr($newlines = 0, $width = 79) - { - $this->out(null, $newlines); - $this->out(str_repeat('-', $width)); - $this->out(null, $newlines); - } - - /** - * Prompts the user for input, and returns it. - * - * @param string $prompt Prompt text. - * @param string|null $default Default input value. - * @return mixed Either the default value, or the user-provided input. - */ - public function ask($prompt, $default = null) - { - return $this->_getInput($prompt, null, $default); - } - - /** - * Change the output mode of the stdout stream - * - * @param int $mode The output mode. - * @return void - * @see \Cake\Console\ConsoleOutput::setOutputAs() - */ - public function setOutputAs($mode) - { - $this->_out->setOutputAs($mode); - } - - /** - * Change the output mode of the stdout stream - * - * @deprecated 3.5.0 Use setOutputAs() instead. - * @param int $mode The output mode. - * @return void - * @see \Cake\Console\ConsoleOutput::outputAs() - */ - public function outputAs($mode) - { - deprecationWarning('ConsoleIo::outputAs() is deprecated. Use ConsoleIo::setOutputAs() instead.'); - $this->_out->setOutputAs($mode); - } - - /** - * Add a new output style or get defined styles. - * - * @param string|null $style The style to get or create. - * @param array|bool|null $definition The array definition of the style to change or create a style - * or false to remove a style. - * @return mixed If you are getting styles, the style or null will be returned. If you are creating/modifying - * styles true will be returned. - * @see \Cake\Console\ConsoleOutput::styles() - */ - public function styles($style = null, $definition = null) - { - $this->_out->styles($style, $definition); - } - - /** - * Prompts the user for input based on a list of options, and returns it. - * - * @param string $prompt Prompt text. - * @param string|array $options Array or string of options. - * @param string|null $default Default input value. - * @return mixed Either the default value, or the user-provided input. - */ - public function askChoice($prompt, $options, $default = null) - { - if ($options && is_string($options)) { - if (strpos($options, ',')) { - $options = explode(',', $options); - } elseif (strpos($options, '/')) { - $options = explode('/', $options); - } else { - $options = [$options]; - } - } - - $printOptions = '(' . implode('/', $options) . ')'; - $options = array_merge( - array_map('strtolower', $options), - array_map('strtoupper', $options), - $options - ); - $in = ''; - while ($in === '' || !in_array($in, $options)) { - $in = $this->_getInput($prompt, $printOptions, $default); - } - - return $in; - } - - /** - * Prompts the user for input, and returns it. - * - * @param string $prompt Prompt text. - * @param string|null $options String of options. Pass null to omit. - * @param string|null $default Default input value. Pass null to omit. - * @return string Either the default value, or the user-provided input. - */ - protected function _getInput($prompt, $options, $default) - { - $optionsText = ''; - if (isset($options)) { - $optionsText = " $options "; - } - - $defaultText = ''; - if ($default !== null) { - $defaultText = "[$default] "; - } - $this->_out->write('' . $prompt . "$optionsText\n$defaultText> ", 0); - $result = $this->_in->read(); - - $result = trim($result); - if ($default !== null && ($result === '' || $result === null)) { - return $default; - } - - return $result; - } - - /** - * Connects or disconnects the loggers to the console output. - * - * Used to enable or disable logging stream output to stdout and stderr - * If you don't wish all log output in stdout or stderr - * through Cake's Log class, call this function with `$enable=false`. - * - * @param int|bool $enable Use a boolean to enable/toggle all logging. Use - * one of the verbosity constants (self::VERBOSE, self::QUIET, self::NORMAL) - * to control logging levels. VERBOSE enables debug logs, NORMAL does not include debug logs, - * QUIET disables notice, info and debug logs. - * @return void - */ - public function setLoggers($enable) - { - Log::drop('stdout'); - Log::drop('stderr'); - if ($enable === false) { - return; - } - $outLevels = ['notice', 'info']; - if ($enable === static::VERBOSE || $enable === true) { - $outLevels[] = 'debug'; - } - if ($enable !== static::QUIET) { - $stdout = new ConsoleLog([ - 'types' => $outLevels, - 'stream' => $this->_out - ]); - Log::setConfig('stdout', ['engine' => $stdout]); - } - $stderr = new ConsoleLog([ - 'types' => ['emergency', 'alert', 'critical', 'error', 'warning'], - 'stream' => $this->_err, - ]); - Log::setConfig('stderr', ['engine' => $stderr]); - } - - /** - * Render a Console Helper - * - * Create and render the output for a helper object. If the helper - * object has not already been loaded, it will be loaded and constructed. - * - * @param string $name The name of the helper to render - * @param array $settings Configuration data for the helper. - * @return \Cake\Console\Helper The created helper instance. - */ - public function helper($name, array $settings = []) - { - $name = ucfirst($name); - - return $this->_helpers->load($name, $settings); - } - - /** - * Create a file at the given path. - * - * This method will prompt the user if a file will be overwritten. - * Setting `forceOverwrite` to true will suppress this behavior - * and always overwrite the file. - * - * If the user replies `a` subsequent `forceOverwrite` parameters will - * be coerced to true and all files will be overwritten. - * - * @param string $path The path to create the file at. - * @param string $contents The contents to put into the file. - * @param bool $forceOverwrite Whether or not the file should be overwritten. - * If true, no question will be asked about whether or not to overwrite existing files. - * @return bool Success. - * @throws \Cake\Console\Exception\StopException When `q` is given as an answer - * to whether or not a file should be overwritten. - */ - public function createFile($path, $contents, $forceOverwrite = false) - { - $path = str_replace( - DIRECTORY_SEPARATOR . DIRECTORY_SEPARATOR, - DIRECTORY_SEPARATOR, - $path - ); - - $this->out(); - $forceOverwrite = $forceOverwrite || $this->forceOverwrite; - - if (file_exists($path) && $forceOverwrite === false) { - $this->warning("File `{$path}` exists"); - $key = $this->askChoice('Do you want to overwrite?', ['y', 'n', 'a', 'q'], 'n'); - $key = strtolower($key); - - if ($key === 'q') { - $this->error('Quitting.', 2); - throw new StopException('Not creating file. Quitting.'); - } - if ($key === 'a') { - $this->forceOverwrite = true; - $key = 'y'; - } - if ($key !== 'y') { - $this->out("Skip `{$path}`", 2); - - return false; - } - } else { - $this->out("Creating file {$path}"); - } - - try { - $file = new SplFileObject($path, 'w'); - } catch (RuntimeException $e) { - $this->error("Could not write to `{$path}`. Permission denied.", 2); - - return false; - } - - $file->rewind(); - if ($file->fwrite($contents) > 0) { - $this->out("Wrote `{$path}`"); - - return true; - } - $this->error("Could not write to `{$path}`.", 2); - - return false; - } -} diff --git a/vendor/cakephp/cakephp/src/Console/ConsoleOptionParser.php b/vendor/cakephp/cakephp/src/Console/ConsoleOptionParser.php deleted file mode 100644 index 0d9290e..0000000 --- a/vendor/cakephp/cakephp/src/Console/ConsoleOptionParser.php +++ /dev/null @@ -1,1113 +0,0 @@ -addOption()` - * you can define new options. The name of the option is used as its long form, and you - * can supply an additional short form, with the `short` option. Short options should - * only be one letter long. Using more than one letter for a short option will raise an exception. - * - * Calling options can be done using syntax similar to most *nix command line tools. Long options - * cane either include an `=` or leave it out. - * - * `cake myshell command --connection default --name=something` - * - * Short options can be defined singly or in groups. - * - * `cake myshell command -cn` - * - * Short options can be combined into groups as seen above. Each letter in a group - * will be treated as a separate option. The previous example is equivalent to: - * - * `cake myshell command -c -n` - * - * Short options can also accept values: - * - * `cake myshell command -c default` - * - * ### Positional arguments - * - * If no positional arguments are defined, all of them will be parsed. If you define positional - * arguments any arguments greater than those defined will cause exceptions. Additionally you can - * declare arguments as optional, by setting the required param to false. - * - * ``` - * $parser->addArgument('model', ['required' => false]); - * ``` - * - * ### Providing Help text - * - * By providing help text for your positional arguments and named arguments, the ConsoleOptionParser - * can generate a help display for you. You can view the help for shells by using the `--help` or `-h` switch. - */ -class ConsoleOptionParser -{ - - /** - * Description text - displays before options when help is generated - * - * @see \Cake\Console\ConsoleOptionParser::description() - * @var string - */ - protected $_description; - - /** - * Epilog text - displays after options when help is generated - * - * @see \Cake\Console\ConsoleOptionParser::epilog() - * @var string - */ - protected $_epilog; - - /** - * Option definitions. - * - * @see \Cake\Console\ConsoleOptionParser::addOption() - * @var \Cake\Console\ConsoleInputOption[] - */ - protected $_options = []; - - /** - * Map of short -> long options, generated when using addOption() - * - * @var array - */ - protected $_shortOptions = []; - - /** - * Positional argument definitions. - * - * @see \Cake\Console\ConsoleOptionParser::addArgument() - * @var \Cake\Console\ConsoleInputArgument[] - */ - protected $_args = []; - - /** - * Subcommands for this Shell. - * - * @see \Cake\Console\ConsoleOptionParser::addSubcommand() - * @var \Cake\Console\ConsoleInputSubcommand[] - */ - protected $_subcommands = []; - - /** - * Subcommand sorting option - * - * @var bool - */ - protected $_subcommandSort = true; - - /** - * Command name. - * - * @var string - */ - protected $_command = ''; - - /** - * Array of args (argv). - * - * @var array - */ - protected $_tokens = []; - - /** - * Root alias used in help output - * - * @see \Cake\Console\HelpFormatter::setAlias() - * @var string - */ - protected $rootName = 'cake'; - - /** - * Construct an OptionParser so you can define its behavior - * - * @param string|null $command The command name this parser is for. The command name is used for generating help. - * @param bool $defaultOptions Whether you want the verbose and quiet options set. Setting - * this to false will prevent the addition of `--verbose` & `--quiet` options. - */ - public function __construct($command = null, $defaultOptions = true) - { - $this->setCommand($command); - - $this->addOption('help', [ - 'short' => 'h', - 'help' => 'Display this help.', - 'boolean' => true - ]); - - if ($defaultOptions) { - $this->addOption('verbose', [ - 'short' => 'v', - 'help' => 'Enable verbose output.', - 'boolean' => true - ])->addOption('quiet', [ - 'short' => 'q', - 'help' => 'Enable quiet output.', - 'boolean' => true - ]); - } - } - - /** - * Static factory method for creating new OptionParsers so you can chain methods off of them. - * - * @param string|null $command The command name this parser is for. The command name is used for generating help. - * @param bool $defaultOptions Whether you want the verbose and quiet options set. - * @return static - */ - public static function create($command, $defaultOptions = true) - { - return new static($command, $defaultOptions); - } - - /** - * Build a parser from an array. Uses an array like - * - * ``` - * $spec = [ - * 'description' => 'text', - * 'epilog' => 'text', - * 'arguments' => [ - * // list of arguments compatible with addArguments. - * ], - * 'options' => [ - * // list of options compatible with addOptions - * ], - * 'subcommands' => [ - * // list of subcommands to add. - * ] - * ]; - * ``` - * - * @param array $spec The spec to build the OptionParser with. - * @param bool $defaultOptions Whether you want the verbose and quiet options set. - * @return static - */ - public static function buildFromArray($spec, $defaultOptions = true) - { - $parser = new static($spec['command'], $defaultOptions); - if (!empty($spec['arguments'])) { - $parser->addArguments($spec['arguments']); - } - if (!empty($spec['options'])) { - $parser->addOptions($spec['options']); - } - if (!empty($spec['subcommands'])) { - $parser->addSubcommands($spec['subcommands']); - } - if (!empty($spec['description'])) { - $parser->setDescription($spec['description']); - } - if (!empty($spec['epilog'])) { - $parser->setEpilog($spec['epilog']); - } - - return $parser; - } - - /** - * Returns an array representation of this parser. - * - * @return array - */ - public function toArray() - { - $result = [ - 'command' => $this->_command, - 'arguments' => $this->_args, - 'options' => $this->_options, - 'subcommands' => $this->_subcommands, - 'description' => $this->_description, - 'epilog' => $this->_epilog - ]; - - return $result; - } - - /** - * Get or set the command name for shell/task. - * - * @param array|\Cake\Console\ConsoleOptionParser $spec ConsoleOptionParser or spec to merge with. - * @return $this - */ - public function merge($spec) - { - if ($spec instanceof ConsoleOptionParser) { - $spec = $spec->toArray(); - } - if (!empty($spec['arguments'])) { - $this->addArguments($spec['arguments']); - } - if (!empty($spec['options'])) { - $this->addOptions($spec['options']); - } - if (!empty($spec['subcommands'])) { - $this->addSubcommands($spec['subcommands']); - } - if (!empty($spec['description'])) { - $this->setDescription($spec['description']); - } - if (!empty($spec['epilog'])) { - $this->setEpilog($spec['epilog']); - } - - return $this; - } - - /** - * Sets the command name for shell/task. - * - * @param string $text The text to set. - * @return $this - */ - public function setCommand($text) - { - $this->_command = Inflector::underscore($text); - - return $this; - } - - /** - * Gets the command name for shell/task. - * - * @return string The value of the command. - */ - public function getCommand() - { - return $this->_command; - } - - /** - * Gets or sets the command name for shell/task. - * - * @deprecated 3.4.0 Use setCommand()/getCommand() instead. - * @param string|null $text The text to set, or null if you want to read - * @return string|$this If reading, the value of the command. If setting $this will be returned. - */ - public function command($text = null) - { - deprecationWarning( - 'ConsoleOptionParser::command() is deprecated. ' . - 'Use ConsoleOptionParser::setCommand()/getCommand() instead.' - ); - if ($text !== null) { - return $this->setCommand($text); - } - - return $this->getCommand(); - } - - /** - * Sets the description text for shell/task. - * - * @param string|array $text The text to set. If an array the - * text will be imploded with "\n". - * @return $this - */ - public function setDescription($text) - { - if (is_array($text)) { - $text = implode("\n", $text); - } - $this->_description = $text; - - return $this; - } - - /** - * Gets the description text for shell/task. - * - * @return string The value of the description - */ - public function getDescription() - { - return $this->_description; - } - - /** - * Get or set the description text for shell/task. - * - * @deprecated 3.4.0 Use setDescription()/getDescription() instead. - * @param string|array|null $text The text to set, or null if you want to read. If an array the - * text will be imploded with "\n". - * @return string|$this If reading, the value of the description. If setting $this will be returned. - */ - public function description($text = null) - { - deprecationWarning( - 'ConsoleOptionParser::description() is deprecated. ' . - 'Use ConsoleOptionParser::setDescription()/getDescription() instead.' - ); - if ($text !== null) { - return $this->setDescription($text); - } - - return $this->getDescription(); - } - - /** - * Sets an epilog to the parser. The epilog is added to the end of - * the options and arguments listing when help is generated. - * - * @param string|array $text The text to set. If an array the text will - * be imploded with "\n". - * @return $this - */ - public function setEpilog($text) - { - if (is_array($text)) { - $text = implode("\n", $text); - } - $this->_epilog = $text; - - return $this; - } - - /** - * Gets the epilog. - * - * @return string The value of the epilog. - */ - public function getEpilog() - { - return $this->_epilog; - } - - /** - * Gets or sets an epilog to the parser. The epilog is added to the end of - * the options and arguments listing when help is generated. - * - * @deprecated 3.4.0 Use setEpilog()/getEpilog() instead. - * @param string|array|null $text Text when setting or null when reading. If an array the text will - * be imploded with "\n". - * @return string|$this If reading, the value of the epilog. If setting $this will be returned. - */ - public function epilog($text = null) - { - deprecationWarning( - 'ConsoleOptionParser::epliog() is deprecated. ' . - 'Use ConsoleOptionParser::setEpilog()/getEpilog() instead.' - ); - if ($text !== null) { - return $this->setEpilog($text); - } - - return $this->getEpilog(); - } - - /** - * Enables sorting of subcommands - * - * @param bool $value Whether or not to sort subcommands - * @return $this - */ - public function enableSubcommandSort($value = true) - { - $this->_subcommandSort = (bool)$value; - - return $this; - } - - /** - * Checks whether or not sorting is enabled for subcommands. - * - * @return bool - */ - public function isSubcommandSortEnabled() - { - return $this->_subcommandSort; - } - - /** - * Add an option to the option parser. Options allow you to define optional or required - * parameters for your console application. Options are defined by the parameters they use. - * - * ### Options - * - * - `short` - The single letter variant for this option, leave undefined for none. - * - `help` - Help text for this option. Used when generating help for the option. - * - `default` - The default value for this option. Defaults are added into the parsed params when the - * attached option is not provided or has no value. Using default and boolean together will not work. - * are added into the parsed parameters when the option is undefined. Defaults to null. - * - `boolean` - The option uses no value, it's just a boolean switch. Defaults to false. - * If an option is defined as boolean, it will always be added to the parsed params. If no present - * it will be false, if present it will be true. - * - `multiple` - The option can be provided multiple times. The parsed option - * will be an array of values when this option is enabled. - * - `choices` A list of valid choices for this option. If left empty all values are valid.. - * An exception will be raised when parse() encounters an invalid value. - * - * @param \Cake\Console\ConsoleInputOption|string $name The long name you want to the value to be parsed out as when options are parsed. - * Will also accept an instance of ConsoleInputOption - * @param array $options An array of parameters that define the behavior of the option - * @return $this - */ - public function addOption($name, array $options = []) - { - if ($name instanceof ConsoleInputOption) { - $option = $name; - $name = $option->name(); - } else { - $defaults = [ - 'name' => $name, - 'short' => null, - 'help' => '', - 'default' => null, - 'boolean' => false, - 'choices' => [] - ]; - $options += $defaults; - $option = new ConsoleInputOption($options); - } - $this->_options[$name] = $option; - asort($this->_options); - if ($option->short() !== null) { - $this->_shortOptions[$option->short()] = $name; - asort($this->_shortOptions); - } - - return $this; - } - - /** - * Remove an option from the option parser. - * - * @param string $name The option name to remove. - * @return $this - */ - public function removeOption($name) - { - unset($this->_options[$name]); - - return $this; - } - - /** - * Add a positional argument to the option parser. - * - * ### Params - * - * - `help` The help text to display for this argument. - * - `required` Whether this parameter is required. - * - `index` The index for the arg, if left undefined the argument will be put - * onto the end of the arguments. If you define the same index twice the first - * option will be overwritten. - * - `choices` A list of valid choices for this argument. If left empty all values are valid.. - * An exception will be raised when parse() encounters an invalid value. - * - * @param \Cake\Console\ConsoleInputArgument|string $name The name of the argument. - * Will also accept an instance of ConsoleInputArgument. - * @param array $params Parameters for the argument, see above. - * @return $this - */ - public function addArgument($name, array $params = []) - { - if ($name instanceof ConsoleInputArgument) { - $arg = $name; - $index = count($this->_args); - } else { - $defaults = [ - 'name' => $name, - 'help' => '', - 'index' => count($this->_args), - 'required' => false, - 'choices' => [] - ]; - $options = $params + $defaults; - $index = $options['index']; - unset($options['index']); - $arg = new ConsoleInputArgument($options); - } - foreach ($this->_args as $k => $a) { - if ($a->isEqualTo($arg)) { - return $this; - } - if (!empty($options['required']) && !$a->isRequired()) { - throw new LogicException('A required argument cannot follow an optional one'); - } - } - $this->_args[$index] = $arg; - ksort($this->_args); - - return $this; - } - - /** - * Add multiple arguments at once. Take an array of argument definitions. - * The keys are used as the argument names, and the values as params for the argument. - * - * @param array $args Array of arguments to add. - * @see \Cake\Console\ConsoleOptionParser::addArgument() - * @return $this - */ - public function addArguments(array $args) - { - foreach ($args as $name => $params) { - if ($params instanceof ConsoleInputArgument) { - $name = $params; - $params = []; - } - $this->addArgument($name, $params); - } - - return $this; - } - - /** - * Add multiple options at once. Takes an array of option definitions. - * The keys are used as option names, and the values as params for the option. - * - * @param array $options Array of options to add. - * @see \Cake\Console\ConsoleOptionParser::addOption() - * @return $this - */ - public function addOptions(array $options) - { - foreach ($options as $name => $params) { - if ($params instanceof ConsoleInputOption) { - $name = $params; - $params = []; - } - $this->addOption($name, $params); - } - - return $this; - } - - /** - * Append a subcommand to the subcommand list. - * Subcommands are usually methods on your Shell, but can also be used to document Tasks. - * - * ### Options - * - * - `help` - Help text for the subcommand. - * - `parser` - A ConsoleOptionParser for the subcommand. This allows you to create method - * specific option parsers. When help is generated for a subcommand, if a parser is present - * it will be used. - * - * @param \Cake\Console\ConsoleInputSubcommand|string $name Name of the subcommand. Will also accept an instance of ConsoleInputSubcommand - * @param array $options Array of params, see above. - * @return $this - */ - public function addSubcommand($name, array $options = []) - { - if ($name instanceof ConsoleInputSubcommand) { - $command = $name; - $name = $command->name(); - } else { - $name = Inflector::underscore($name); - $defaults = [ - 'name' => $name, - 'help' => '', - 'parser' => null - ]; - $options += $defaults; - - $command = new ConsoleInputSubcommand($options); - } - $this->_subcommands[$name] = $command; - if ($this->_subcommandSort) { - asort($this->_subcommands); - } - - return $this; - } - - /** - * Remove a subcommand from the option parser. - * - * @param string $name The subcommand name to remove. - * @return $this - */ - public function removeSubcommand($name) - { - unset($this->_subcommands[$name]); - - return $this; - } - - /** - * Add multiple subcommands at once. - * - * @param array $commands Array of subcommands. - * @return $this - */ - public function addSubcommands(array $commands) - { - foreach ($commands as $name => $params) { - if ($params instanceof ConsoleInputSubcommand) { - $name = $params; - $params = []; - } - $this->addSubcommand($name, $params); - } - - return $this; - } - - /** - * Gets the arguments defined in the parser. - * - * @return \Cake\Console\ConsoleInputArgument[] - */ - public function arguments() - { - return $this->_args; - } - - /** - * Get the list of argument names. - * - * @return string[] - */ - public function argumentNames() - { - $out = []; - foreach ($this->_args as $arg) { - $out[] = $arg->name(); - } - - return $out; - } - - /** - * Get the defined options in the parser. - * - * @return \Cake\Console\ConsoleInputOption[] - */ - public function options() - { - return $this->_options; - } - - /** - * Get the array of defined subcommands - * - * @return \Cake\Console\ConsoleInputSubcommand[] - */ - public function subcommands() - { - return $this->_subcommands; - } - - /** - * Parse the argv array into a set of params and args. If $command is not null - * and $command is equal to a subcommand that has a parser, that parser will be used - * to parse the $argv - * - * @param array $argv Array of args (argv) to parse. - * @return array [$params, $args] - * @throws \Cake\Console\Exception\ConsoleException When an invalid parameter is encountered. - */ - public function parse($argv) - { - $command = isset($argv[0]) ? Inflector::underscore($argv[0]) : null; - if (isset($this->_subcommands[$command])) { - array_shift($argv); - } - if (isset($this->_subcommands[$command]) && $this->_subcommands[$command]->parser()) { - return $this->_subcommands[$command]->parser()->parse($argv); - } - $params = $args = []; - $this->_tokens = $argv; - while (($token = array_shift($this->_tokens)) !== null) { - if (isset($this->_subcommands[$token])) { - continue; - } - if (substr($token, 0, 2) === '--') { - $params = $this->_parseLongOption($token, $params); - } elseif (substr($token, 0, 1) === '-') { - $params = $this->_parseShortOption($token, $params); - } else { - $args = $this->_parseArg($token, $args); - } - } - foreach ($this->_args as $i => $arg) { - if ($arg->isRequired() && !isset($args[$i]) && empty($params['help'])) { - throw new ConsoleException( - sprintf('Missing required arguments. %s is required.', $arg->name()) - ); - } - } - foreach ($this->_options as $option) { - $name = $option->name(); - $isBoolean = $option->isBoolean(); - $default = $option->defaultValue(); - - if ($default !== null && !isset($params[$name]) && !$isBoolean) { - $params[$name] = $default; - } - if ($isBoolean && !isset($params[$name])) { - $params[$name] = false; - } - } - - return [$params, $args]; - } - - /** - * Gets formatted help for this parser object. - * - * Generates help text based on the description, options, arguments, subcommands and epilog - * in the parser. - * - * @param string|null $subcommand If present and a valid subcommand that has a linked parser. - * That subcommands help will be shown instead. - * @param string $format Define the output format, can be text or xml - * @param int $width The width to format user content to. Defaults to 72 - * @return string Generated help. - */ - public function help($subcommand = null, $format = 'text', $width = 72) - { - if ($subcommand === null) { - $formatter = new HelpFormatter($this); - $formatter->setAlias($this->rootName); - - if ($format === 'text') { - return $formatter->text($width); - } - if ($format === 'xml') { - return (string)$formatter->xml(); - } - } - - if (isset($this->_subcommands[$subcommand])) { - $command = $this->_subcommands[$subcommand]; - $subparser = $command->parser(); - if (!($subparser instanceof self)) { - $subparser = clone $this; - } - if (strlen($subparser->getDescription()) === 0) { - $subparser->setDescription($command->getRawHelp()); - } - $subparser->setCommand($this->getCommand() . ' ' . $subcommand); - $subparser->setRootName($this->rootName); - - return $subparser->help(null, $format, $width); - } - - return $this->getCommandError($subcommand); - } - - /** - * Set the alias used in the HelpFormatter - * - * @param string $alias The alias - * @return void - * @deprecated 3.5.0 Use setRootName() instead. - */ - public function setHelpAlias($alias) - { - deprecationWarning( - 'ConsoleOptionParser::setHelpAlias() is deprecated. ' . - 'Use ConsoleOptionParser::setRootName() instead.' - ); - $this->rootName = $alias; - } - - /** - * Set the root name used in the HelpFormatter - * - * @param string $name The root command name - * @return $this - */ - public function setRootName($name) - { - $this->rootName = (string)$name; - - return $this; - } - - /** - * Get the message output in the console stating that the command can not be found and tries to guess what the user - * wanted to say. Output a list of available subcommands as well. - * - * @param string $command Unknown command name trying to be dispatched. - * @return string The message to be displayed in the console. - */ - protected function getCommandError($command) - { - $rootCommand = $this->getCommand(); - $subcommands = array_keys((array)$this->subcommands()); - $bestGuess = $this->findClosestItem($command, $subcommands); - - $out = [ - sprintf( - 'Unable to find the `%s %s` subcommand. See `bin/%s %s --help`.', - $rootCommand, - $command, - $this->rootName, - $rootCommand - ), - '' - ]; - - if ($bestGuess !== null) { - $out[] = sprintf('Did you mean : `%s %s` ?', $rootCommand, $bestGuess); - $out[] = ''; - } - $out[] = sprintf('Available subcommands for the `%s` command are : ', $rootCommand); - $out[] = ''; - foreach ($subcommands as $subcommand) { - $out[] = ' - ' . $subcommand; - } - - return implode("\n", $out); - } - - /** - * Get the message output in the console stating that the option can not be found and tries to guess what the user - * wanted to say. Output a list of available options as well. - * - * @param string $option Unknown option name trying to be used. - * @return string The message to be displayed in the console. - */ - protected function getOptionError($option) - { - $availableOptions = array_keys($this->_options); - $bestGuess = $this->findClosestItem($option, $availableOptions); - $out = [ - sprintf('Unknown option `%s`.', $option), - '' - ]; - - if ($bestGuess !== null) { - $out[] = sprintf('Did you mean `%s` ?', $bestGuess); - $out[] = ''; - } - - $out[] = 'Available options are :'; - $out[] = ''; - foreach ($availableOptions as $availableOption) { - $out[] = ' - ' . $availableOption; - } - - return implode("\n", $out); - } - - /** - * Get the message output in the console stating that the short option can not be found. Output a list of available - * short options and what option they refer to as well. - * - * @param string $option Unknown short option name trying to be used. - * @return string The message to be displayed in the console. - */ - protected function getShortOptionError($option) - { - $out = [sprintf('Unknown short option `%s`', $option)]; - $out[] = ''; - $out[] = 'Available short options are :'; - $out[] = ''; - - foreach ($this->_shortOptions as $short => $long) { - $out[] = sprintf(' - `%s` (short for `--%s`)', $short, $long); - } - - return implode("\n", $out); - } - - /** - * Tries to guess the item name the user originally wanted using the some regex pattern and the levenshtein - * algorithm. - * - * @param string $needle Unknown item (either a subcommand name or an option for instance) trying to be used. - * @param array $haystack List of items available for the type $needle belongs to. - * @return string|null The closest name to the item submitted by the user. - */ - protected function findClosestItem($needle, $haystack) - { - $bestGuess = null; - foreach ($haystack as $item) { - if (preg_match('/^' . $needle . '/', $item)) { - return $item; - } - } - - foreach ($haystack as $item) { - if (preg_match('/' . $needle . '/', $item)) { - return $item; - } - - $score = levenshtein($needle, $item); - - if (!isset($bestScore) || $score < $bestScore) { - $bestScore = $score; - $bestGuess = $item; - } - } - - return $bestGuess; - } - - /** - * Parse the value for a long option out of $this->_tokens. Will handle - * options with an `=` in them. - * - * @param string $option The option to parse. - * @param array $params The params to append the parsed value into - * @return array Params with $option added in. - */ - protected function _parseLongOption($option, $params) - { - $name = substr($option, 2); - if (strpos($name, '=') !== false) { - list($name, $value) = explode('=', $name, 2); - array_unshift($this->_tokens, $value); - } - - return $this->_parseOption($name, $params); - } - - /** - * Parse the value for a short option out of $this->_tokens - * If the $option is a combination of multiple shortcuts like -otf - * they will be shifted onto the token stack and parsed individually. - * - * @param string $option The option to parse. - * @param array $params The params to append the parsed value into - * @return array Params with $option added in. - * @throws \Cake\Console\Exception\ConsoleException When unknown short options are encountered. - */ - protected function _parseShortOption($option, $params) - { - $key = substr($option, 1); - if (strlen($key) > 1) { - $flags = str_split($key); - $key = $flags[0]; - for ($i = 1, $len = count($flags); $i < $len; $i++) { - array_unshift($this->_tokens, '-' . $flags[$i]); - } - } - if (!isset($this->_shortOptions[$key])) { - throw new ConsoleException($this->getShortOptionError($key)); - } - $name = $this->_shortOptions[$key]; - - return $this->_parseOption($name, $params); - } - - /** - * Parse an option by its name index. - * - * @param string $name The name to parse. - * @param array $params The params to append the parsed value into - * @return array Params with $option added in. - * @throws \Cake\Console\Exception\ConsoleException - */ - protected function _parseOption($name, $params) - { - if (!isset($this->_options[$name])) { - throw new ConsoleException($this->getOptionError($name)); - } - $option = $this->_options[$name]; - $isBoolean = $option->isBoolean(); - $nextValue = $this->_nextToken(); - $emptyNextValue = (empty($nextValue) && $nextValue !== '0'); - if (!$isBoolean && !$emptyNextValue && !$this->_optionExists($nextValue)) { - array_shift($this->_tokens); - $value = $nextValue; - } elseif ($isBoolean) { - $value = true; - } else { - $value = $option->defaultValue(); - } - if ($option->validChoice($value)) { - if ($option->acceptsMultiple()) { - $params[$name][] = $value; - } else { - $params[$name] = $value; - } - - return $params; - } - - return []; - } - - /** - * Check to see if $name has an option (short/long) defined for it. - * - * @param string $name The name of the option. - * @return bool - */ - protected function _optionExists($name) - { - if (substr($name, 0, 2) === '--') { - return isset($this->_options[substr($name, 2)]); - } - if ($name{0} === '-' && $name{1} !== '-') { - return isset($this->_shortOptions[$name{1}]); - } - - return false; - } - - /** - * Parse an argument, and ensure that the argument doesn't exceed the number of arguments - * and that the argument is a valid choice. - * - * @param string $argument The argument to append - * @param array $args The array of parsed args to append to. - * @return array Args - * @throws \Cake\Console\Exception\ConsoleException - */ - protected function _parseArg($argument, $args) - { - if (empty($this->_args)) { - $args[] = $argument; - - return $args; - } - $next = count($args); - if (!isset($this->_args[$next])) { - throw new ConsoleException('Too many arguments.'); - } - - if ($this->_args[$next]->validChoice($argument)) { - $args[] = $argument; - - return $args; - } - } - - /** - * Find the next token in the argv set. - * - * @return string next token or '' - */ - protected function _nextToken() - { - return isset($this->_tokens[0]) ? $this->_tokens[0] : ''; - } -} diff --git a/vendor/cakephp/cakephp/src/Console/ConsoleOutput.php b/vendor/cakephp/cakephp/src/Console/ConsoleOutput.php deleted file mode 100644 index d16ba80..0000000 --- a/vendor/cakephp/cakephp/src/Console/ConsoleOutput.php +++ /dev/null @@ -1,361 +0,0 @@ -out('Overwrite: foo.php was overwritten.'); - * ``` - * - * This would create orange 'Overwrite:' text, while the rest of the text would remain the normal color. - * See ConsoleOutput::styles() to learn more about defining your own styles. Nested styles are not supported - * at this time. - */ -class ConsoleOutput -{ - - /** - * Raw output constant - no modification of output text. - * - * @var int - */ - const RAW = 0; - - /** - * Plain output - tags will be stripped. - * - * @var int - */ - const PLAIN = 1; - - /** - * Color output - Convert known tags in to ANSI color escape codes. - * - * @var int - */ - const COLOR = 2; - - /** - * Constant for a newline. - * - * @var string - */ - const LF = PHP_EOL; - - /** - * File handle for output. - * - * @var resource - */ - protected $_output; - - /** - * The current output type. Manipulated with ConsoleOutput::outputAs(); - * - * @var int - */ - protected $_outputAs = self::COLOR; - - /** - * text colors used in colored output. - * - * @var array - */ - protected static $_foregroundColors = [ - 'black' => 30, - 'red' => 31, - 'green' => 32, - 'yellow' => 33, - 'blue' => 34, - 'magenta' => 35, - 'cyan' => 36, - 'white' => 37 - ]; - - /** - * background colors used in colored output. - * - * @var array - */ - protected static $_backgroundColors = [ - 'black' => 40, - 'red' => 41, - 'green' => 42, - 'yellow' => 43, - 'blue' => 44, - 'magenta' => 45, - 'cyan' => 46, - 'white' => 47 - ]; - - /** - * Formatting options for colored output. - * - * @var array - */ - protected static $_options = [ - 'bold' => 1, - 'underline' => 4, - 'blink' => 5, - 'reverse' => 7, - ]; - - /** - * Styles that are available as tags in console output. - * You can modify these styles with ConsoleOutput::styles() - * - * @var array - */ - protected static $_styles = [ - 'emergency' => ['text' => 'red'], - 'alert' => ['text' => 'red'], - 'critical' => ['text' => 'red'], - 'error' => ['text' => 'red'], - 'warning' => ['text' => 'yellow'], - 'info' => ['text' => 'cyan'], - 'debug' => ['text' => 'yellow'], - 'success' => ['text' => 'green'], - 'comment' => ['text' => 'blue'], - 'question' => ['text' => 'magenta'], - 'notice' => ['text' => 'cyan'] - ]; - - /** - * Construct the output object. - * - * Checks for a pretty console environment. Ansicon and ConEmu allows - * pretty consoles on windows, and is supported. - * - * @param string $stream The identifier of the stream to write output to. - */ - public function __construct($stream = 'php://stdout') - { - $this->_output = fopen($stream, 'wb'); - - if ((DIRECTORY_SEPARATOR === '\\' && !(bool)env('ANSICON') && env('ConEmuANSI') !== 'ON') || - (function_exists('posix_isatty') && !posix_isatty($this->_output)) - ) { - $this->_outputAs = self::PLAIN; - } - } - - /** - * Outputs a single or multiple messages to stdout or stderr. If no parameters - * are passed, outputs just a newline. - * - * @param string|array $message A string or an array of strings to output - * @param int $newlines Number of newlines to append - * @return int|bool The number of bytes returned from writing to output. - */ - public function write($message, $newlines = 1) - { - if (is_array($message)) { - $message = implode(static::LF, $message); - } - - return $this->_write($this->styleText($message . str_repeat(static::LF, $newlines))); - } - - /** - * Apply styling to text. - * - * @param string $text Text with styling tags. - * @return string String with color codes added. - */ - public function styleText($text) - { - if ($this->_outputAs == static::RAW) { - return $text; - } - if ($this->_outputAs == static::PLAIN) { - $tags = implode('|', array_keys(static::$_styles)); - - return preg_replace('##', '', $text); - } - - return preg_replace_callback( - '/<(?P[a-z0-9-_]+)>(?P.*?)<\/(\1)>/ims', - [$this, '_replaceTags'], - $text - ); - } - - /** - * Replace tags with color codes. - * - * @param array $matches An array of matches to replace. - * @return string - */ - protected function _replaceTags($matches) - { - $style = $this->styles($matches['tag']); - if (empty($style)) { - return '<' . $matches['tag'] . '>' . $matches['text'] . ''; - } - - $styleInfo = []; - if (!empty($style['text']) && isset(static::$_foregroundColors[$style['text']])) { - $styleInfo[] = static::$_foregroundColors[$style['text']]; - } - if (!empty($style['background']) && isset(static::$_backgroundColors[$style['background']])) { - $styleInfo[] = static::$_backgroundColors[$style['background']]; - } - unset($style['text'], $style['background']); - foreach ($style as $option => $value) { - if ($value) { - $styleInfo[] = static::$_options[$option]; - } - } - - return "\033[" . implode($styleInfo, ';') . 'm' . $matches['text'] . "\033[0m"; - } - - /** - * Writes a message to the output stream. - * - * @param string $message Message to write. - * @return int|bool The number of bytes returned from writing to output. - */ - protected function _write($message) - { - return fwrite($this->_output, $message); - } - - /** - * Get the current styles offered, or append new ones in. - * - * ### Get a style definition - * - * ``` - * $output->styles('error'); - * ``` - * - * ### Get all the style definitions - * - * ``` - * $output->styles(); - * ``` - * - * ### Create or modify an existing style - * - * ``` - * $output->styles('annoy', ['text' => 'purple', 'background' => 'yellow', 'blink' => true]); - * ``` - * - * ### Remove a style - * - * ``` - * $this->output->styles('annoy', false); - * ``` - * - * @param string|null $style The style to get or create. - * @param array|bool|null $definition The array definition of the style to change or create a style - * or false to remove a style. - * @return mixed If you are getting styles, the style or null will be returned. If you are creating/modifying - * styles true will be returned. - */ - public function styles($style = null, $definition = null) - { - if ($style === null && $definition === null) { - return static::$_styles; - } - if (is_string($style) && $definition === null) { - return isset(static::$_styles[$style]) ? static::$_styles[$style] : null; - } - if ($definition === false) { - unset(static::$_styles[$style]); - - return true; - } - static::$_styles[$style] = $definition; - - return true; - } - - /** - * Get the output type on how formatting tags are treated. - * - * @return int - */ - public function getOutputAs() - { - return $this->_outputAs; - } - - /** - * Set the output type on how formatting tags are treated. - * - * @param int $type The output type to use. Should be one of the class constants. - * @return void - * @throws \InvalidArgumentException in case of a not supported output type. - */ - public function setOutputAs($type) - { - if (!in_array($type, [self::RAW, self::PLAIN, self::COLOR], true)) { - throw new InvalidArgumentException(sprintf('Invalid output type "%s".', $type)); - } - - $this->_outputAs = $type; - } - - /** - * Get/Set the output type to use. The output type how formatting tags are treated. - * - * @deprecated 3.5.0 Use getOutputAs()/setOutputAs() instead. - * @param int|null $type The output type to use. Should be one of the class constants. - * @return int|null Either null or the value if getting. - */ - public function outputAs($type = null) - { - deprecationWarning( - 'ConsoleOutput::outputAs() is deprecated. ' . - 'Use ConsoleOutput::setOutputAs()/getOutputAs() instead.' - ); - if ($type === null) { - return $this->_outputAs; - } - $this->_outputAs = $type; - } - - /** - * Clean up and close handles - */ - public function __destruct() - { - if (is_resource($this->_output)) { - fclose($this->_output); - } - } -} diff --git a/vendor/cakephp/cakephp/src/Console/Exception/ConsoleException.php b/vendor/cakephp/cakephp/src/Console/Exception/ConsoleException.php deleted file mode 100644 index 445af8d..0000000 --- a/vendor/cakephp/cakephp/src/Console/Exception/ConsoleException.php +++ /dev/null @@ -1,24 +0,0 @@ -help($command, 'xml'); is usually - * how you would access help. Or via the `--help=xml` option on the command line. - * - * Xml output is useful for integration with other tools like IDE's or other build tools. - */ -class HelpFormatter -{ - - /** - * The maximum number of arguments shown when generating usage. - * - * @var int - */ - protected $_maxArgs = 6; - - /** - * The maximum number of options shown when generating usage. - * - * @var int - */ - protected $_maxOptions = 6; - - /** - * Option parser. - * - * @var \Cake\Console\ConsoleOptionParser - */ - protected $_parser; - - /** - * Alias to display in the output. - * - * @var string - */ - protected $_alias = 'cake'; - - /** - * Build the help formatter for an OptionParser - * - * @param \Cake\Console\ConsoleOptionParser $parser The option parser help is being generated for. - */ - public function __construct(ConsoleOptionParser $parser) - { - $this->_parser = $parser; - } - - /** - * Set the alias - * - * @param string $alias The alias - * @return void - * @throws \Cake\Console\Exception\ConsoleException When alias is not a string. - */ - public function setAlias($alias) - { - if (is_string($alias)) { - $this->_alias = $alias; - } else { - throw new ConsoleException('Alias must be of type string.'); - } - } - - /** - * Get the help as formatted text suitable for output on the command line. - * - * @param int $width The width of the help output. - * @return string - */ - public function text($width = 72) - { - $parser = $this->_parser; - $out = []; - $description = $parser->getDescription(); - if (!empty($description)) { - $out[] = Text::wrap($description, $width); - $out[] = ''; - } - $out[] = 'Usage:'; - $out[] = $this->_generateUsage(); - $out[] = ''; - $subcommands = $parser->subcommands(); - if (!empty($subcommands)) { - $out[] = 'Subcommands:'; - $out[] = ''; - $max = $this->_getMaxLength($subcommands) + 2; - foreach ($subcommands as $command) { - $out[] = Text::wrapBlock($command->help($max), [ - 'width' => $width, - 'indent' => str_repeat(' ', $max), - 'indentAt' => 1 - ]); - } - $out[] = ''; - $out[] = sprintf('To see help on a subcommand use `' . $this->_alias . ' %s [subcommand] --help`', $parser->getCommand()); - $out[] = ''; - } - - $options = $parser->options(); - if (!empty($options)) { - $max = $this->_getMaxLength($options) + 8; - $out[] = 'Options:'; - $out[] = ''; - foreach ($options as $option) { - $out[] = Text::wrapBlock($option->help($max), [ - 'width' => $width, - 'indent' => str_repeat(' ', $max), - 'indentAt' => 1 - ]); - } - $out[] = ''; - } - - $arguments = $parser->arguments(); - if (!empty($arguments)) { - $max = $this->_getMaxLength($arguments) + 2; - $out[] = 'Arguments:'; - $out[] = ''; - foreach ($arguments as $argument) { - $out[] = Text::wrapBlock($argument->help($max), [ - 'width' => $width, - 'indent' => str_repeat(' ', $max), - 'indentAt' => 1 - ]); - } - $out[] = ''; - } - $epilog = $parser->getEpilog(); - if (!empty($epilog)) { - $out[] = Text::wrap($epilog, $width); - $out[] = ''; - } - - return implode("\n", $out); - } - - /** - * Generate the usage for a shell based on its arguments and options. - * Usage strings favor short options over the long ones. and optional args will - * be indicated with [] - * - * @return string - */ - protected function _generateUsage() - { - $usage = [$this->_alias . ' ' . $this->_parser->getCommand()]; - $subcommands = $this->_parser->subcommands(); - if (!empty($subcommands)) { - $usage[] = '[subcommand]'; - } - $options = []; - foreach ($this->_parser->options() as $option) { - $options[] = $option->usage(); - } - if (count($options) > $this->_maxOptions) { - $options = ['[options]']; - } - $usage = array_merge($usage, $options); - $args = []; - foreach ($this->_parser->arguments() as $argument) { - $args[] = $argument->usage(); - } - if (count($args) > $this->_maxArgs) { - $args = ['[arguments]']; - } - $usage = array_merge($usage, $args); - - return implode(' ', $usage); - } - - /** - * Iterate over a collection and find the longest named thing. - * - * @param array $collection The collection to find a max length of. - * @return int - */ - protected function _getMaxLength($collection) - { - $max = 0; - foreach ($collection as $item) { - $max = (strlen($item->name()) > $max) ? strlen($item->name()) : $max; - } - - return $max; - } - - /** - * Get the help as an xml string. - * - * @param bool $string Return the SimpleXml object or a string. Defaults to true. - * @return string|\SimpleXMLElement See $string - */ - public function xml($string = true) - { - $parser = $this->_parser; - $xml = new SimpleXMLElement(''); - $xml->addChild('command', $parser->getCommand()); - $xml->addChild('description', $parser->getDescription()); - - $subcommands = $xml->addChild('subcommands'); - foreach ($parser->subcommands() as $command) { - $command->xml($subcommands); - } - $options = $xml->addChild('options'); - foreach ($parser->options() as $option) { - $option->xml($options); - } - $arguments = $xml->addChild('arguments'); - foreach ($parser->arguments() as $argument) { - $argument->xml($arguments); - } - $xml->addChild('epilog', $parser->getEpilog()); - - return $string ? $xml->asXML() : $xml; - } -} diff --git a/vendor/cakephp/cakephp/src/Console/Helper.php b/vendor/cakephp/cakephp/src/Console/Helper.php deleted file mode 100644 index e498f3a..0000000 --- a/vendor/cakephp/cakephp/src/Console/Helper.php +++ /dev/null @@ -1,63 +0,0 @@ -_io = $io; - $this->setConfig($config); - } - - /** - * This method should output content using `$this->_io`. - * - * @param array $args The arguments for the helper. - * @return void - */ - abstract public function output($args); -} diff --git a/vendor/cakephp/cakephp/src/Console/HelperRegistry.php b/vendor/cakephp/cakephp/src/Console/HelperRegistry.php deleted file mode 100644 index c832d8a..0000000 --- a/vendor/cakephp/cakephp/src/Console/HelperRegistry.php +++ /dev/null @@ -1,100 +0,0 @@ -_io = $io; - } - - /** - * Resolve a helper classname. - * - * Will prefer helpers defined in Command\Helper over those - * defined in Shell\Helper. - * - * Part of the template method for Cake\Core\ObjectRegistry::load() - * - * @param string $class Partial classname to resolve. - * @return string|false Either the correct classname or false. - */ - protected function _resolveClassName($class) - { - $name = App::className($class, 'Command/Helper', 'Helper'); - if ($name) { - return $name; - } - - return App::className($class, 'Shell/Helper', 'Helper'); - } - - /** - * Throws an exception when a helper is missing. - * - * Part of the template method for Cake\Core\ObjectRegistry::load() - * and Cake\Core\ObjectRegistry::unload() - * - * @param string $class The classname that is missing. - * @param string $plugin The plugin the helper is missing in. - * @return void - * @throws \Cake\Console\Exception\MissingHelperException - */ - protected function _throwMissingClassError($class, $plugin) - { - throw new MissingHelperException([ - 'class' => $class, - 'plugin' => $plugin - ]); - } - - /** - * Create the helper instance. - * - * Part of the template method for Cake\Core\ObjectRegistry::load() - * - * @param string $class The classname to create. - * @param string $alias The alias of the helper. - * @param array $settings An array of settings to use for the helper. - * @return \Cake\Console\Helper The constructed helper class. - */ - protected function _create($class, $alias, $settings) - { - return new $class($this->_io, $settings); - } -} diff --git a/vendor/cakephp/cakephp/src/Console/Shell.php b/vendor/cakephp/cakephp/src/Console/Shell.php deleted file mode 100644 index b07b9ca..0000000 --- a/vendor/cakephp/cakephp/src/Console/Shell.php +++ /dev/null @@ -1,1011 +0,0 @@ -name) { - list(, $class) = namespaceSplit(get_class($this)); - $this->name = str_replace(['Shell', 'Task'], '', $class); - } - $this->_io = $io ?: new ConsoleIo(); - $this->_tableLocator = $locator; - - $this->modelFactory('Table', [$this->getTableLocator(), 'get']); - $this->Tasks = new TaskRegistry($this); - - $this->_mergeVars( - ['tasks'], - ['associative' => ['tasks']] - ); - - if (isset($this->modelClass)) { - $this->loadModel(); - } - } - - /** - * Set the root command name for help output. - * - * @param string $name The name of the root command. - * @return $this - */ - public function setRootName($name) - { - $this->rootName = (string)$name; - - return $this; - } - - /** - * Get the io object for this shell. - * - * @return \Cake\Console\ConsoleIo The current ConsoleIo object. - */ - public function getIo() - { - return $this->_io; - } - - /** - * Set the io object for this shell. - * - * @param \Cake\Console\ConsoleIo $io The ConsoleIo object to use. - * @return void - */ - public function setIo(ConsoleIo $io) - { - $this->_io = $io; - } - - /** - * Get/Set the io object for this shell. - * - * @deprecated 3.5.0 Use getIo()/setIo() instead. - * @param \Cake\Console\ConsoleIo|null $io The ConsoleIo object to use. - * @return \Cake\Console\ConsoleIo The current ConsoleIo object. - */ - public function io(ConsoleIo $io = null) - { - deprecationWarning( - 'Shell::io() is deprecated. ' . - 'Use Shell::setIo()/getIo() instead.' - ); - if ($io !== null) { - $this->_io = $io; - } - - return $this->_io; - } - - /** - * Initializes the Shell - * acts as constructor for subclasses - * allows configuration of tasks prior to shell execution - * - * @return void - * @link https://book.cakephp.org/3.0/en/console-and-shells.html#Cake\Console\ConsoleOptionParser::initialize - */ - public function initialize() - { - $this->loadTasks(); - } - - /** - * Starts up the Shell and displays the welcome message. - * Allows for checking and configuring prior to command or main execution - * - * Override this method if you want to remove the welcome information, - * or otherwise modify the pre-command flow. - * - * @return void - * @link https://book.cakephp.org/3.0/en/console-and-shells.html#Cake\Console\ConsoleOptionParser::startup - */ - public function startup() - { - if (!$this->param('requested')) { - $this->_welcome(); - } - } - - /** - * Displays a header for the shell - * - * @return void - */ - protected function _welcome() - { - } - - /** - * Loads tasks defined in public $tasks - * - * @return bool - */ - public function loadTasks() - { - if ($this->tasks === true || empty($this->tasks) || empty($this->Tasks)) { - return true; - } - $this->_taskMap = $this->Tasks->normalizeArray((array)$this->tasks); - $this->taskNames = array_merge($this->taskNames, array_keys($this->_taskMap)); - - $this->_validateTasks(); - - return true; - } - - /** - * Checks that the tasks in the task map are actually available - * - * @throws \RuntimeException - * @return void - */ - protected function _validateTasks() - { - foreach ($this->_taskMap as $taskName => $task) { - $class = App::className($task['class'], 'Shell/Task', 'Task'); - if (!class_exists($class)) { - throw new RuntimeException(sprintf( - 'Task `%s` not found. Maybe you made a typo or a plugin is missing or not loaded?', - $taskName - )); - } - } - } - - /** - * Check to see if this shell has a task with the provided name. - * - * @param string $task The task name to check. - * @return bool Success - * @link https://book.cakephp.org/3.0/en/console-and-shells.html#shell-tasks - */ - public function hasTask($task) - { - return isset($this->_taskMap[Inflector::camelize($task)]); - } - - /** - * Check to see if this shell has a callable method by the given name. - * - * @param string $name The method name to check. - * @return bool - * @link https://book.cakephp.org/3.0/en/console-and-shells.html#shell-tasks - */ - public function hasMethod($name) - { - try { - $method = new ReflectionMethod($this, $name); - if (!$method->isPublic()) { - return false; - } - - return $method->getDeclaringClass()->name !== 'Cake\Console\Shell'; - } catch (ReflectionException $e) { - return false; - } - } - - /** - * Dispatch a command to another Shell. Similar to Object::requestAction() - * but intended for running shells from other shells. - * - * ### Usage: - * - * With a string command: - * - * ``` - * return $this->dispatchShell('schema create DbAcl'); - * ``` - * - * Avoid using this form if you have string arguments, with spaces in them. - * The dispatched will be invoked incorrectly. Only use this form for simple - * command dispatching. - * - * With an array command: - * - * ``` - * return $this->dispatchShell('schema', 'create', 'i18n', '--dry'); - * ``` - * - * With an array having two key / value pairs: - * - `command` can accept either a string or an array. Represents the command to dispatch - * - `extra` can accept an array of extra parameters to pass on to the dispatcher. This - * parameters will be available in the `param` property of the called `Shell` - * - * `return $this->dispatchShell([ - * 'command' => 'schema create DbAcl', - * 'extra' => ['param' => 'value'] - * ]);` - * - * or - * - * `return $this->dispatchShell([ - * 'command' => ['schema', 'create', 'DbAcl'], - * 'extra' => ['param' => 'value'] - * ]);` - * - * @return int The cli command exit code. 0 is success. - * @link https://book.cakephp.org/3.0/en/console-and-shells.html#invoking-other-shells-from-your-shell - */ - public function dispatchShell() - { - list($args, $extra) = $this->parseDispatchArguments(func_get_args()); - - if (!isset($extra['requested'])) { - $extra['requested'] = true; - } - - $dispatcher = new ShellDispatcher($args, false); - - return $dispatcher->dispatch($extra); - } - - /** - * Parses the arguments for the dispatchShell() method. - * - * @param array $args Arguments fetch from the dispatchShell() method with - * func_get_args() - * @return array First value has to be an array of the command arguments. - * Second value has to be an array of extra parameter to pass on to the dispatcher - */ - public function parseDispatchArguments($args) - { - $extra = []; - - if (is_string($args[0]) && count($args) === 1) { - $args = explode(' ', $args[0]); - - return [$args, $extra]; - } - - if (is_array($args[0]) && !empty($args[0]['command'])) { - $command = $args[0]['command']; - if (is_string($command)) { - $command = explode(' ', $command); - } - - if (!empty($args[0]['extra'])) { - $extra = $args[0]['extra']; - } - - return [$command, $extra]; - } - - return [$args, $extra]; - } - - /** - * Runs the Shell with the provided argv. - * - * Delegates calls to Tasks and resolves methods inside the class. Commands are looked - * up with the following order: - * - * - Method on the shell. - * - Matching task name. - * - `main()` method. - * - * If a shell implements a `main()` method, all missing method calls will be sent to - * `main()` with the original method name in the argv. - * - * For tasks to be invoked they *must* be exposed as subcommands. If you define any subcommands, - * you must define all the subcommands your shell needs, whether they be methods on this class - * or methods on tasks. - * - * @param array $argv Array of arguments to run the shell with. This array should be missing the shell name. - * @param bool $autoMethod Set to true to allow any public method to be called even if it - * was not defined as a subcommand. This is used by ShellDispatcher to make building simple shells easy. - * @param array $extra Extra parameters that you can manually pass to the Shell - * to be dispatched. - * Built-in extra parameter is : - * - `requested` : if used, will prevent the Shell welcome message to be displayed - * @return int|bool|null - * @link https://book.cakephp.org/3.0/en/console-and-shells.html#the-cakephp-console - */ - public function runCommand($argv, $autoMethod = false, $extra = []) - { - $command = isset($argv[0]) ? Inflector::underscore($argv[0]) : null; - $this->OptionParser = $this->getOptionParser(); - try { - list($this->params, $this->args) = $this->OptionParser->parse($argv); - } catch (ConsoleException $e) { - $this->err('Error: ' . $e->getMessage()); - - return false; - } - - if (!empty($extra) && is_array($extra)) { - $this->params = array_merge($this->params, $extra); - } - $this->_setOutputLevel(); - $this->command = $command; - if (!empty($this->params['help'])) { - return $this->_displayHelp($command); - } - - $subcommands = $this->OptionParser->subcommands(); - $method = Inflector::camelize($command); - $isMethod = $this->hasMethod($method); - - if ($isMethod && $autoMethod && count($subcommands) === 0) { - array_shift($this->args); - $this->startup(); - - return $this->$method(...$this->args); - } - - if ($isMethod && isset($subcommands[$command])) { - $this->startup(); - - return $this->$method(...$this->args); - } - - if ($this->hasTask($command) && isset($subcommands[$command])) { - $this->startup(); - array_shift($argv); - - return $this->{$method}->runCommand($argv, false, ['requested' => true]); - } - - if ($this->hasMethod('main')) { - $this->command = 'main'; - $this->startup(); - - return $this->main(...$this->args); - } - - $this->err('No subcommand provided. Choose one of the available subcommands.', 2); - $this->_io->err($this->OptionParser->help($command)); - - return false; - } - - /** - * Set the output level based on the parameters. - * - * This reconfigures both the output level for out() - * and the configured stdout/stderr logging - * - * @return void - */ - protected function _setOutputLevel() - { - $this->_io->setLoggers(ConsoleIo::NORMAL); - if (!empty($this->params['quiet'])) { - $this->_io->level(ConsoleIo::QUIET); - $this->_io->setLoggers(ConsoleIo::QUIET); - } - if (!empty($this->params['verbose'])) { - $this->_io->level(ConsoleIo::VERBOSE); - $this->_io->setLoggers(ConsoleIo::VERBOSE); - } - } - - /** - * Display the help in the correct format - * - * @param string $command The command to get help for. - * @return int|bool The number of bytes returned from writing to stdout. - */ - protected function _displayHelp($command) - { - $format = 'text'; - if (!empty($this->args[0]) && $this->args[0] === 'xml') { - $format = 'xml'; - $this->_io->setOutputAs(ConsoleOutput::RAW); - } else { - $this->_welcome(); - } - - $subcommands = $this->OptionParser->subcommands(); - $command = isset($subcommands[$command]) ? $command : null; - - return $this->out($this->OptionParser->help($command, $format)); - } - - /** - * Gets the option parser instance and configures it. - * - * By overriding this method you can configure the ConsoleOptionParser before returning it. - * - * @return \Cake\Console\ConsoleOptionParser - * @link https://book.cakephp.org/3.0/en/console-and-shells.html#configuring-options-and-generating-help - */ - public function getOptionParser() - { - $name = ($this->plugin ? $this->plugin . '.' : '') . $this->name; - $parser = new ConsoleOptionParser($name); - $parser->setRootName($this->rootName); - - return $parser; - } - - /** - * Overload get for lazy building of tasks - * - * @param string $name The task to get. - * @return \Cake\Console\Shell Object of Task - */ - public function __get($name) - { - if (empty($this->{$name}) && in_array($name, $this->taskNames)) { - $properties = $this->_taskMap[$name]; - $this->{$name} = $this->Tasks->load($properties['class'], $properties['config']); - $this->{$name}->args =& $this->args; - $this->{$name}->params =& $this->params; - $this->{$name}->initialize(); - $this->{$name}->loadTasks(); - } - - return $this->{$name}; - } - - /** - * Safely access the values in $this->params. - * - * @param string $name The name of the parameter to get. - * @return string|bool|null Value. Will return null if it doesn't exist. - */ - public function param($name) - { - if (!isset($this->params[$name])) { - return null; - } - - return $this->params[$name]; - } - - /** - * Prompts the user for input, and returns it. - * - * @param string $prompt Prompt text. - * @param string|array|null $options Array or string of options. - * @param string|null $default Default input value. - * @return mixed Either the default value, or the user-provided input. - * @link https://book.cakephp.org/3.0/en/console-and-shells.html#Shell::in - */ - public function in($prompt, $options = null, $default = null) - { - if (!$this->interactive) { - return $default; - } - if ($options) { - return $this->_io->askChoice($prompt, $options, $default); - } - - return $this->_io->ask($prompt, $default); - } - - /** - * Wrap a block of text. - * Allows you to set the width, and indenting on a block of text. - * - * ### Options - * - * - `width` The width to wrap to. Defaults to 72 - * - `wordWrap` Only wrap on words breaks (spaces) Defaults to true. - * - `indent` Indent the text with the string provided. Defaults to null. - * - * @param string $text Text the text to format. - * @param int|array $options Array of options to use, or an integer to wrap the text to. - * @return string Wrapped / indented text - * @see \Cake\Utility\Text::wrap() - * @link https://book.cakephp.org/3.0/en/console-and-shells.html#Shell::wrapText - */ - public function wrapText($text, $options = []) - { - return Text::wrap($text, $options); - } - - /** - * Output at the verbose level. - * - * @param string|array $message A string or an array of strings to output - * @param int $newlines Number of newlines to append - * @return int|bool The number of bytes returned from writing to stdout. - */ - public function verbose($message, $newlines = 1) - { - return $this->_io->verbose($message, $newlines); - } - - /** - * Output at all levels. - * - * @param string|array $message A string or an array of strings to output - * @param int $newlines Number of newlines to append - * @return int|bool The number of bytes returned from writing to stdout. - */ - public function quiet($message, $newlines = 1) - { - return $this->_io->quiet($message, $newlines); - } - - /** - * Outputs a single or multiple messages to stdout. If no parameters - * are passed outputs just a newline. - * - * ### Output levels - * - * There are 3 built-in output level. Shell::QUIET, Shell::NORMAL, Shell::VERBOSE. - * The verbose and quiet output levels, map to the `verbose` and `quiet` output switches - * present in most shells. Using Shell::QUIET for a message means it will always display. - * While using Shell::VERBOSE means it will only display when verbose output is toggled. - * - * @param string|array|null $message A string or an array of strings to output - * @param int $newlines Number of newlines to append - * @param int $level The message's output level, see above. - * @return int|bool The number of bytes returned from writing to stdout. - * @link https://book.cakephp.org/3.0/en/console-and-shells.html#Shell::out - */ - public function out($message = null, $newlines = 1, $level = Shell::NORMAL) - { - return $this->_io->out($message, $newlines, $level); - } - - /** - * Outputs a single or multiple error messages to stderr. If no parameters - * are passed outputs just a newline. - * - * @param string|array|null $message A string or an array of strings to output - * @param int $newlines Number of newlines to append - * @return int|bool The number of bytes returned from writing to stderr. - */ - public function err($message = null, $newlines = 1) - { - return $this->_io->error($message, $newlines); - } - - /** - * Convenience method for out() that wraps message between tag - * - * @param string|array|null $message A string or an array of strings to output - * @param int $newlines Number of newlines to append - * @param int $level The message's output level, see above. - * @return int|bool The number of bytes returned from writing to stdout. - * @see https://book.cakephp.org/3.0/en/console-and-shells.html#Shell::out - */ - public function info($message = null, $newlines = 1, $level = Shell::NORMAL) - { - return $this->_io->info($message, $newlines, $level); - } - - /** - * Convenience method for err() that wraps message between tag - * - * @param string|array|null $message A string or an array of strings to output - * @param int $newlines Number of newlines to append - * @return int|bool The number of bytes returned from writing to stderr. - * @see https://book.cakephp.org/3.0/en/console-and-shells.html#Shell::err - */ - public function warn($message = null, $newlines = 1) - { - return $this->_io->warning($message, $newlines); - } - - /** - * Convenience method for out() that wraps message between tag - * - * @param string|array|null $message A string or an array of strings to output - * @param int $newlines Number of newlines to append - * @param int $level The message's output level, see above. - * @return int|bool The number of bytes returned from writing to stdout. - * @see https://book.cakephp.org/3.0/en/console-and-shells.html#Shell::out - */ - public function success($message = null, $newlines = 1, $level = Shell::NORMAL) - { - return $this->_io->success($message, $newlines, $level); - } - - /** - * Wraps a message with a given message type, e.g. - * - * @param string $messageType The message type, e.g. "warning". - * @param string|array $message The message to wrap. - * @return array|string The message wrapped with the given message type. - * @deprecated 3.6.0 Will be removed in 4.0.0 as it is no longer in use. - */ - protected function wrapMessageWithType($messageType, $message) - { - deprecationWarning( - 'Shell::wrapMessageWithType() is deprecated. ' . - 'Use output methods on ConsoleIo instead.' - ); - if (is_array($message)) { - foreach ($message as $k => $v) { - $message[$k] = "<$messageType>" . $v . ""; - } - } else { - $message = "<$messageType>" . $message . ""; - } - - return $message; - } - - /** - * Returns a single or multiple linefeeds sequences. - * - * @param int $multiplier Number of times the linefeed sequence should be repeated - * @return string - * @link https://book.cakephp.org/3.0/en/console-and-shells.html#Shell::nl - */ - public function nl($multiplier = 1) - { - return $this->_io->nl($multiplier); - } - - /** - * Outputs a series of minus characters to the standard output, acts as a visual separator. - * - * @param int $newlines Number of newlines to pre- and append - * @param int $width Width of the line, defaults to 63 - * @return void - * @link https://book.cakephp.org/3.0/en/console-and-shells.html#Shell::hr - */ - public function hr($newlines = 0, $width = 63) - { - $this->_io->hr($newlines, $width); - } - - /** - * Displays a formatted error message - * and exits the application with status code 1 - * - * @param string $message The error message - * @param int $exitCode The exit code for the shell task. - * @throws \Cake\Console\Exception\StopException - * @return void - * @link https://book.cakephp.org/3.0/en/console-and-shells.html#styling-output - */ - public function abort($message, $exitCode = self::CODE_ERROR) - { - $this->_io->err('' . $message . ''); - throw new StopException($message, $exitCode); - } - - /** - * Displays a formatted error message - * and exits the application with status code 1 - * - * @param string $title Title of the error - * @param string|null $message An optional error message - * @param int $exitCode The exit code for the shell task. - * @throws \Cake\Console\Exception\StopException - * @return int Error code - * @link https://book.cakephp.org/3.0/en/console-and-shells.html#styling-output - * @deprecated 3.2.0 Use Shell::abort() instead. - */ - public function error($title, $message = null, $exitCode = self::CODE_ERROR) - { - deprecationWarning('Shell::error() is deprecated. `Use Shell::abort() instead.'); - $this->_io->err(sprintf('Error: %s', $title)); - - if (!empty($message)) { - $this->_io->err($message); - } - - $this->_stop($exitCode); - - return $exitCode; - } - - /** - * Clear the console - * - * @return void - * @link https://book.cakephp.org/3.0/en/console-and-shells.html#console-output - */ - public function clear() - { - if (empty($this->params['noclear'])) { - if (DIRECTORY_SEPARATOR === '/') { - passthru('clear'); - } else { - passthru('cls'); - } - } - } - - /** - * Creates a file at given path - * - * @param string $path Where to put the file. - * @param string $contents Content to put in the file. - * @return bool Success - * @link https://book.cakephp.org/3.0/en/console-and-shells.html#creating-files - */ - public function createFile($path, $contents) - { - $path = str_replace(DIRECTORY_SEPARATOR . DIRECTORY_SEPARATOR, DIRECTORY_SEPARATOR, $path); - - $this->_io->out(); - - $fileExists = is_file($path); - if ($fileExists && empty($this->params['force']) && !$this->interactive) { - $this->_io->out('File exists, skipping.'); - - return false; - } - - if ($fileExists && $this->interactive && empty($this->params['force'])) { - $this->_io->out(sprintf('File `%s` exists', $path)); - $key = $this->_io->askChoice('Do you want to overwrite?', ['y', 'n', 'a', 'q'], 'n'); - - if (strtolower($key) === 'q') { - $this->_io->out('Quitting.', 2); - $this->_stop(); - - return false; - } - if (strtolower($key) === 'a') { - $this->params['force'] = true; - $key = 'y'; - } - if (strtolower($key) !== 'y') { - $this->_io->out(sprintf('Skip `%s`', $path), 2); - - return false; - } - } else { - $this->out(sprintf('Creating file %s', $path)); - } - - $File = new File($path, true); - - try { - if ($File->exists() && $File->writable()) { - $File->write($contents); - $this->_io->out(sprintf('Wrote `%s`', $path)); - - return true; - } - - $this->_io->err(sprintf('Could not write to `%s`.', $path), 2); - - return false; - } finally { - $File->close(); - } - } - - /** - * Makes absolute file path easier to read - * - * @param string $file Absolute file path - * @return string short path - * @link https://book.cakephp.org/3.0/en/console-and-shells.html#Shell::shortPath - */ - public function shortPath($file) - { - $shortPath = str_replace(ROOT, null, $file); - $shortPath = str_replace('..' . DIRECTORY_SEPARATOR, '', $shortPath); - $shortPath = str_replace(DIRECTORY_SEPARATOR, '/', $shortPath); - - return str_replace('//', DIRECTORY_SEPARATOR, $shortPath); - } - - /** - * Render a Console Helper - * - * Create and render the output for a helper object. If the helper - * object has not already been loaded, it will be loaded and constructed. - * - * @param string $name The name of the helper to render - * @param array $settings Configuration data for the helper. - * @return \Cake\Console\Helper The created helper instance. - */ - public function helper($name, array $settings = []) - { - return $this->_io->helper($name, $settings); - } - - /** - * Stop execution of the current script. - * Raises a StopException to try and halt the execution. - * - * @param int|string $status see https://secure.php.net/exit for values - * @throws \Cake\Console\Exception\StopException - * @return void - */ - protected function _stop($status = self::CODE_SUCCESS) - { - throw new StopException('Halting error reached', $status); - } - - /** - * Returns an array that can be used to describe the internal state of this - * object. - * - * @return array - */ - public function __debugInfo() - { - return [ - 'name' => $this->name, - 'plugin' => $this->plugin, - 'command' => $this->command, - 'tasks' => $this->tasks, - 'params' => $this->params, - 'args' => $this->args, - 'interactive' => $this->interactive, - ]; - } -} diff --git a/vendor/cakephp/cakephp/src/Console/ShellDispatcher.php b/vendor/cakephp/cakephp/src/Console/ShellDispatcher.php deleted file mode 100644 index 03399ca..0000000 --- a/vendor/cakephp/cakephp/src/Console/ShellDispatcher.php +++ /dev/null @@ -1,416 +0,0 @@ -args = (array)$args; - - $this->addShortPluginAliases(); - - if ($bootstrap) { - $this->_initEnvironment(); - } - } - - /** - * Add an alias for a shell command. - * - * Aliases allow you to call shells by alternate names. This is most - * useful when dealing with plugin shells that you want to have shorter - * names for. - * - * If you re-use an alias the last alias set will be the one available. - * - * ### Usage - * - * Aliasing a shell named ClassName: - * - * ``` - * $this->alias('alias', 'ClassName'); - * ``` - * - * Getting the original name for a given alias: - * - * ``` - * $this->alias('alias'); - * ``` - * - * @param string $short The new short name for the shell. - * @param string|null $original The original full name for the shell. - * @return string|false The aliased class name, or false if the alias does not exist - */ - public static function alias($short, $original = null) - { - $short = Inflector::camelize($short); - if ($original) { - static::$_aliases[$short] = $original; - } - - return isset(static::$_aliases[$short]) ? static::$_aliases[$short] : false; - } - - /** - * Clear any aliases that have been set. - * - * @return void - */ - public static function resetAliases() - { - static::$_aliases = []; - } - - /** - * Run the dispatcher - * - * @param array $argv The argv from PHP - * @param array $extra Extra parameters - * @return int The exit code of the shell process. - */ - public static function run($argv, $extra = []) - { - $dispatcher = new ShellDispatcher($argv); - - return $dispatcher->dispatch($extra); - } - - /** - * Defines current working environment. - * - * @return void - * @throws \Cake\Core\Exception\Exception - */ - protected function _initEnvironment() - { - if (!$this->_bootstrap()) { - $message = "Unable to load CakePHP core.\nMake sure Cake exists in " . CAKE_CORE_INCLUDE_PATH; - throw new Exception($message); - } - - if (function_exists('ini_set')) { - ini_set('html_errors', '0'); - ini_set('implicit_flush', '1'); - ini_set('max_execution_time', '0'); - } - - $this->shiftArgs(); - } - - /** - * Initializes the environment and loads the CakePHP core. - * - * @return bool Success. - */ - protected function _bootstrap() - { - if (!Configure::read('App.fullBaseUrl')) { - Configure::write('App.fullBaseUrl', 'http://localhost'); - } - - return true; - } - - /** - * Dispatches a CLI request - * - * Converts a shell command result into an exit code. Null/True - * are treated as success. All other return values are an error. - * - * @param array $extra Extra parameters that you can manually pass to the Shell - * to be dispatched. - * Built-in extra parameter is : - * - `requested` : if used, will prevent the Shell welcome message to be displayed - * @return int The cli command exit code. 0 is success. - */ - public function dispatch($extra = []) - { - try { - $result = $this->_dispatch($extra); - } catch (StopException $e) { - return $e->getCode(); - } - if ($result === null || $result === true) { - return Shell::CODE_SUCCESS; - } - if (is_int($result)) { - return $result; - } - - return Shell::CODE_ERROR; - } - - /** - * Dispatch a request. - * - * @param array $extra Extra parameters that you can manually pass to the Shell - * to be dispatched. - * Built-in extra parameter is : - * - `requested` : if used, will prevent the Shell welcome message to be displayed - * @return bool|int|null - * @throws \Cake\Console\Exception\MissingShellMethodException - */ - protected function _dispatch($extra = []) - { - $shell = $this->shiftArgs(); - - if (!$shell) { - $this->help(); - - return false; - } - if (in_array($shell, ['help', '--help', '-h'])) { - $this->help(); - - return true; - } - if (in_array($shell, ['version', '--version'])) { - $this->version(); - - return true; - } - - $Shell = $this->findShell($shell); - - $Shell->initialize(); - - return $Shell->runCommand($this->args, true, $extra); - } - - /** - * For all loaded plugins, add a short alias - * - * This permits a plugin which implements a shell of the same name to be accessed - * Using the shell name alone - * - * @return array the resultant list of aliases - */ - public function addShortPluginAliases() - { - $plugins = Plugin::loaded(); - - $io = new ConsoleIo(); - $task = new CommandTask($io); - $io->setLoggers(false); - $list = $task->getShellList() + ['app' => []]; - $fixed = array_flip($list['app']) + array_flip($list['CORE']); - $aliases = $others = []; - - foreach ($plugins as $plugin) { - if (!isset($list[$plugin])) { - continue; - } - - foreach ($list[$plugin] as $shell) { - $aliases += [$shell => $plugin]; - if (!isset($others[$shell])) { - $others[$shell] = [$plugin]; - } else { - $others[$shell] = array_merge($others[$shell], [$plugin]); - } - } - } - - foreach ($aliases as $shell => $plugin) { - if (isset($fixed[$shell])) { - Log::write( - 'debug', - "command '$shell' in plugin '$plugin' was not aliased, conflicts with another shell", - ['shell-dispatcher'] - ); - continue; - } - - $other = static::alias($shell); - if ($other) { - $other = $aliases[$shell]; - if ($other !== $plugin) { - Log::write( - 'debug', - "command '$shell' in plugin '$plugin' was not aliased, conflicts with '$other'", - ['shell-dispatcher'] - ); - } - continue; - } - - if (isset($others[$shell])) { - $conflicts = array_diff($others[$shell], [$plugin]); - if (count($conflicts) > 0) { - $conflictList = implode("', '", $conflicts); - Log::write( - 'debug', - "command '$shell' in plugin '$plugin' was not aliased, conflicts with '$conflictList'", - ['shell-dispatcher'] - ); - } - } - - static::alias($shell, "$plugin.$shell"); - } - - return static::$_aliases; - } - - /** - * Get shell to use, either plugin shell or application shell - * - * All paths in the loaded shell paths are searched, handles alias - * dereferencing - * - * @param string $shell Optionally the name of a plugin - * @return \Cake\Console\Shell A shell instance. - * @throws \Cake\Console\Exception\MissingShellException when errors are encountered. - */ - public function findShell($shell) - { - $className = $this->_shellExists($shell); - if (!$className) { - $shell = $this->_handleAlias($shell); - $className = $this->_shellExists($shell); - } - - if (!$className) { - throw new MissingShellException([ - 'class' => $shell, - ]); - } - - return $this->_createShell($className, $shell); - } - - /** - * If the input matches an alias, return the aliased shell name - * - * @param string $shell Optionally the name of a plugin or alias - * @return string Shell name with plugin prefix - */ - protected function _handleAlias($shell) - { - $aliased = static::alias($shell); - if ($aliased) { - $shell = $aliased; - } - - $class = array_map('Cake\Utility\Inflector::camelize', explode('.', $shell)); - - return implode('.', $class); - } - - /** - * Check if a shell class exists for the given name. - * - * @param string $shell The shell name to look for. - * @return string|bool Either the classname or false. - */ - protected function _shellExists($shell) - { - $class = App::className($shell, 'Shell', 'Shell'); - if (class_exists($class)) { - return $class; - } - - return false; - } - - /** - * Create the given shell name, and set the plugin property - * - * @param string $className The class name to instantiate - * @param string $shortName The plugin-prefixed shell name - * @return \Cake\Console\Shell A shell instance. - */ - protected function _createShell($className, $shortName) - { - list($plugin) = pluginSplit($shortName); - $instance = new $className(); - $instance->plugin = trim($plugin, '.'); - - return $instance; - } - - /** - * Removes first argument and shifts other arguments up - * - * @return mixed Null if there are no arguments otherwise the shifted argument - */ - public function shiftArgs() - { - return array_shift($this->args); - } - - /** - * Shows console help. Performs an internal dispatch to the CommandList Shell - * - * @return void - */ - public function help() - { - $this->args = array_merge(['command_list'], $this->args); - $this->dispatch(); - } - - /** - * Prints the currently installed version of CakePHP. Performs an internal dispatch to the CommandList Shell - * - * @return void - */ - public function version() - { - $this->args = array_merge(['command_list', '--version'], $this->args); - $this->dispatch(); - } -} diff --git a/vendor/cakephp/cakephp/src/Console/TaskRegistry.php b/vendor/cakephp/cakephp/src/Console/TaskRegistry.php deleted file mode 100644 index 1655d98..0000000 --- a/vendor/cakephp/cakephp/src/Console/TaskRegistry.php +++ /dev/null @@ -1,91 +0,0 @@ -_Shell = $Shell; - } - - /** - * Resolve a task classname. - * - * Part of the template method for Cake\Core\ObjectRegistry::load() - * - * @param string $class Partial classname to resolve. - * @return string|false Either the correct classname or false. - */ - protected function _resolveClassName($class) - { - return App::className($class, 'Shell/Task', 'Task'); - } - - /** - * Throws an exception when a task is missing. - * - * Part of the template method for Cake\Core\ObjectRegistry::load() - * and Cake\Core\ObjectRegistry::unload() - * - * @param string $class The classname that is missing. - * @param string $plugin The plugin the task is missing in. - * @return void - * @throws \Cake\Console\Exception\MissingTaskException - */ - protected function _throwMissingClassError($class, $plugin) - { - throw new MissingTaskException([ - 'class' => $class, - 'plugin' => $plugin - ]); - } - - /** - * Create the task instance. - * - * Part of the template method for Cake\Core\ObjectRegistry::load() - * - * @param string $class The classname to create. - * @param string $alias The alias of the task. - * @param array $settings An array of settings to use for the task. - * @return \Cake\Console\Shell The constructed task class. - */ - protected function _create($class, $alias, $settings) - { - return new $class($this->_Shell->getIo()); - } -} diff --git a/vendor/cakephp/cakephp/src/Controller/Component.php b/vendor/cakephp/cakephp/src/Controller/Component.php deleted file mode 100644 index 408d18c..0000000 --- a/vendor/cakephp/cakephp/src/Controller/Component.php +++ /dev/null @@ -1,224 +0,0 @@ -getSubject() to access the controller & request instead. - */ - public $request; - - /** - * Response object - * - * @var \Cake\Http\Response - * @deprecated 3.4.0 Storing references to the response is deprecated. Use Component::getController() - * or callback $event->getSubject() to access the controller & response instead. - */ - public $response; - - /** - * Component registry class used to lazy load components. - * - * @var \Cake\Controller\ComponentRegistry - */ - protected $_registry; - - /** - * Other Components this component uses. - * - * @var array - */ - public $components = []; - - /** - * Default config - * - * These are merged with user-provided config when the component is used. - * - * @var array - */ - protected $_defaultConfig = []; - - /** - * A component lookup table used to lazy load component objects. - * - * @var array - */ - protected $_componentMap = []; - - /** - * Constructor - * - * @param \Cake\Controller\ComponentRegistry $registry A ComponentRegistry this component can use to lazy load its components - * @param array $config Array of configuration settings. - */ - public function __construct(ComponentRegistry $registry, array $config = []) - { - $this->_registry = $registry; - $controller = $registry->getController(); - if ($controller) { - $this->request =& $controller->request; - $this->response =& $controller->response; - } - - $this->setConfig($config); - - if ($this->components) { - $this->_componentMap = $registry->normalizeArray($this->components); - } - $this->initialize($config); - } - - /** - * Get the controller this component is bound to. - * - * @return \Cake\Controller\Controller The bound controller. - */ - public function getController() - { - return $this->_registry->getController(); - } - - /** - * Constructor hook method. - * - * Implement this method to avoid having to overwrite - * the constructor and call parent. - * - * @param array $config The configuration settings provided to this component. - * @return void - */ - public function initialize(array $config) - { - } - - /** - * Magic method for lazy loading $components. - * - * @param string $name Name of component to get. - * @return mixed A Component object or null. - */ - public function __get($name) - { - if (isset($this->_componentMap[$name]) && !isset($this->{$name})) { - $config = (array)$this->_componentMap[$name]['config'] + ['enabled' => false]; - $this->{$name} = $this->_registry->load($this->_componentMap[$name]['class'], $config); - } - if (!isset($this->{$name})) { - return null; - } - - return $this->{$name}; - } - - /** - * Get the Controller callbacks this Component is interested in. - * - * Uses Conventions to map controller events to standard component - * callback method names. By defining one of the callback methods a - * component is assumed to be interested in the related event. - * - * Override this method if you need to add non-conventional event listeners. - * Or if you want components to listen to non-standard events. - * - * @return array - */ - public function implementedEvents() - { - $eventMap = [ - 'Controller.initialize' => 'beforeFilter', - 'Controller.startup' => 'startup', - 'Controller.beforeRender' => 'beforeRender', - 'Controller.beforeRedirect' => 'beforeRedirect', - 'Controller.shutdown' => 'shutdown', - ]; - $events = []; - foreach ($eventMap as $event => $method) { - if (method_exists($this, $method)) { - $events[$event] = $method; - } - } - - return $events; - } - - /** - * Returns an array that can be used to describe the internal state of this - * object. - * - * @return array - */ - public function __debugInfo() - { - return [ - 'components' => $this->components, - 'implementedEvents' => $this->implementedEvents(), - '_config' => $this->getConfig(), - ]; - } -} diff --git a/vendor/cakephp/cakephp/src/Controller/Component/AuthComponent.php b/vendor/cakephp/cakephp/src/Controller/Component/AuthComponent.php deleted file mode 100644 index 19806db..0000000 --- a/vendor/cakephp/cakephp/src/Controller/Component/AuthComponent.php +++ /dev/null @@ -1,1030 +0,0 @@ -Auth->setConfig('authenticate', [ - * 'Form' => [ - * 'userModel' => 'Users.Users' - * ] - * ]); - * ``` - * - * Using the class name without 'Authenticate' as the key, you can pass in an - * array of config for each authentication object. Additionally you can define - * config that should be set to all authentications objects using the 'all' key: - * - * ``` - * $this->Auth->setConfig('authenticate', [ - * AuthComponent::ALL => [ - * 'userModel' => 'Users.Users', - * 'scope' => ['Users.active' => 1] - * ], - * 'Form', - * 'Basic' - * ]); - * ``` - * - * - `authorize` - An array of authorization objects to use for authorizing users. - * You can configure multiple adapters and they will be checked sequentially - * when authorization checks are done. - * - * ``` - * $this->Auth->setConfig('authorize', [ - * 'Crud' => [ - * 'actionPath' => 'controllers/' - * ] - * ]); - * ``` - * - * Using the class name without 'Authorize' as the key, you can pass in an array - * of config for each authorization object. Additionally you can define config - * that should be set to all authorization objects using the AuthComponent::ALL key: - * - * ``` - * $this->Auth->setConfig('authorize', [ - * AuthComponent::ALL => [ - * 'actionPath' => 'controllers/' - * ], - * 'Crud', - * 'CustomAuth' - * ]); - * ``` - * - * - ~~`ajaxLogin`~~ - The name of an optional view element to render when an Ajax - * request is made with an invalid or expired session. - * **This option is deprecated since 3.3.6.** Your client side code should - * instead check for 403 status code and show appropriate login form. - * - * - `flash` - Settings to use when Auth needs to do a flash message with - * FlashComponent::set(). Available keys are: - * - * - `key` - The message domain to use for flashes generated by this component, - * defaults to 'auth'. - * - `element` - Flash element to use, defaults to 'default'. - * - `params` - The array of additional params to use, defaults to ['class' => 'error'] - * - * - `loginAction` - A URL (defined as a string or array) to the controller action - * that handles logins. Defaults to `/users/login`. - * - * - `loginRedirect` - Normally, if a user is redirected to the `loginAction` page, - * the location they were redirected from will be stored in the session so that - * they can be redirected back after a successful login. If this session value - * is not set, redirectUrl() method will return the URL specified in `loginRedirect`. - * - * - `logoutRedirect` - The default action to redirect to after the user is logged out. - * While AuthComponent does not handle post-logout redirection, a redirect URL - * will be returned from `AuthComponent::logout()`. Defaults to `loginAction`. - * - * - `authError` - Error to display when user attempts to access an object or - * action to which they do not have access. - * - * - `unauthorizedRedirect` - Controls handling of unauthorized access. - * - * - For default value `true` unauthorized user is redirected to the referrer URL - * or `$loginRedirect` or '/'. - * - If set to a string or array the value is used as a URL to redirect to. - * - If set to false a `ForbiddenException` exception is thrown instead of redirecting. - * - * - `storage` - Storage class to use for persisting user record. When using - * stateless authenticator you should set this to 'Memory'. Defaults to 'Session'. - * - * - `checkAuthIn` - Name of event for which initial auth checks should be done. - * Defaults to 'Controller.startup'. You can set it to 'Controller.initialize' - * if you want the check to be done before controller's beforeFilter() is run. - * - * @var array - */ - protected $_defaultConfig = [ - 'authenticate' => null, - 'authorize' => null, - 'ajaxLogin' => null, - 'flash' => null, - 'loginAction' => null, - 'loginRedirect' => null, - 'logoutRedirect' => null, - 'authError' => null, - 'unauthorizedRedirect' => true, - 'storage' => 'Session', - 'checkAuthIn' => 'Controller.startup' - ]; - - /** - * Other components utilized by AuthComponent - * - * @var array - */ - public $components = ['RequestHandler', 'Flash']; - - /** - * Objects that will be used for authentication checks. - * - * @var \Cake\Auth\BaseAuthenticate[] - */ - protected $_authenticateObjects = []; - - /** - * Objects that will be used for authorization checks. - * - * @var \Cake\Auth\BaseAuthorize[] - */ - protected $_authorizeObjects = []; - - /** - * Storage object. - * - * @var \Cake\Auth\Storage\StorageInterface|null - */ - protected $_storage; - - /** - * Controller actions for which user validation is not required. - * - * @var array - * @see \Cake\Controller\Component\AuthComponent::allow() - */ - public $allowedActions = []; - - /** - * Request object - * - * @var \Cake\Http\ServerRequest - */ - public $request; - - /** - * Response object - * - * @var \Cake\Http\Response - */ - public $response; - - /** - * Instance of the Session object - * - * @var \Cake\Http\Session - * @deprecated 3.1.0 Will be removed in 4.0 - */ - public $session; - - /** - * The instance of the Authenticate provider that was used for - * successfully logging in the current user after calling `login()` - * in the same request - * - * @var \Cake\Auth\BaseAuthenticate - */ - protected $_authenticationProvider; - - /** - * The instance of the Authorize provider that was used to grant - * access to the current user to the URL they are requesting. - * - * @var \Cake\Auth\BaseAuthorize - */ - protected $_authorizationProvider; - - /** - * Initialize properties. - * - * @param array $config The config data. - * @return void - */ - public function initialize(array $config) - { - $controller = $this->_registry->getController(); - $this->setEventManager($controller->getEventManager()); - $this->response =& $controller->response; - $this->session = $controller->request->getSession(); - - if ($this->getConfig('ajaxLogin')) { - deprecationWarning( - 'The `ajaxLogin` option is deprecated. Your client-side ' . - 'code should instead check for 403 status code and show ' . - 'appropriate login form.' - ); - } - } - - /** - * Callback for Controller.startup event. - * - * @param \Cake\Event\Event $event Event instance. - * @return \Cake\Http\Response|null - */ - public function startup(Event $event) - { - return $this->authCheck($event); - } - - /** - * Main execution method, handles initial authentication check and redirection - * of invalid users. - * - * The auth check is done when event name is same as the one configured in - * `checkAuthIn` config. - * - * @param \Cake\Event\Event $event Event instance. - * @return \Cake\Http\Response|null - */ - public function authCheck(Event $event) - { - if ($this->_config['checkAuthIn'] !== $event->getName()) { - return null; - } - - /** @var \Cake\Controller\Controller $controller */ - $controller = $event->getSubject(); - - $action = strtolower($controller->request->getParam('action')); - if (!$controller->isAction($action)) { - return null; - } - - $this->_setDefaults(); - - if ($this->_isAllowed($controller)) { - return null; - } - - $isLoginAction = $this->_isLoginAction($controller); - - if (!$this->_getUser()) { - if ($isLoginAction) { - return null; - } - $result = $this->_unauthenticated($controller); - if ($result instanceof Response) { - $event->stopPropagation(); - } - - return $result; - } - - if ($isLoginAction || - empty($this->_config['authorize']) || - $this->isAuthorized($this->user()) - ) { - return null; - } - - $event->stopPropagation(); - - return $this->_unauthorized($controller); - } - - /** - * Events supported by this component. - * - * @return array - */ - public function implementedEvents() - { - return [ - 'Controller.initialize' => 'authCheck', - 'Controller.startup' => 'startup', - ]; - } - - /** - * Checks whether current action is accessible without authentication. - * - * @param \Cake\Controller\Controller $controller A reference to the instantiating - * controller object - * @return bool True if action is accessible without authentication else false - */ - protected function _isAllowed(Controller $controller) - { - $action = strtolower($controller->request->getParam('action')); - - return in_array($action, array_map('strtolower', $this->allowedActions)); - } - - /** - * Handles unauthenticated access attempt. First the `unauthenticated()` method - * of the last authenticator in the chain will be called. The authenticator can - * handle sending response or redirection as appropriate and return `true` to - * indicate no further action is necessary. If authenticator returns null this - * method redirects user to login action. If it's an AJAX request and config - * `ajaxLogin` is specified that element is rendered else a 403 HTTP status code - * is returned. - * - * @param \Cake\Controller\Controller $controller A reference to the controller object. - * @return \Cake\Http\Response|null Null if current action is login action - * else response object returned by authenticate object or Controller::redirect(). - * @throws \Cake\Core\Exception\Exception - */ - protected function _unauthenticated(Controller $controller) - { - if (empty($this->_authenticateObjects)) { - $this->constructAuthenticate(); - } - $response = $this->response; - $auth = end($this->_authenticateObjects); - if ($auth === false) { - throw new Exception('At least one authenticate object must be available.'); - } - $result = $auth->unauthenticated($controller->request, $response); - if ($result !== null) { - return $result; - } - - if (!$controller->request->is('ajax')) { - $this->flash($this->_config['authError']); - - return $controller->redirect($this->_loginActionRedirectUrl()); - } - - if (!empty($this->_config['ajaxLogin'])) { - $controller->viewBuilder()->setTemplatePath('Element'); - $response = $controller->render( - $this->_config['ajaxLogin'], - $this->RequestHandler->ajaxLayout - ); - } - - return $response->withStatus(403); - } - - /** - * Returns the URL of the login action to redirect to. - * - * This includes the redirect query string if applicable. - * - * @return array|string - */ - protected function _loginActionRedirectUrl() - { - $urlToRedirectBackTo = $this->_getUrlToRedirectBackTo(); - - $loginAction = $this->_config['loginAction']; - if ($urlToRedirectBackTo === '/') { - return $loginAction; - } - - if (is_array($loginAction)) { - $loginAction['?'][static::QUERY_STRING_REDIRECT] = $urlToRedirectBackTo; - } else { - $char = strpos($loginAction, '?') === false ? '?' : '&'; - $loginAction .= $char . static::QUERY_STRING_REDIRECT . '=' . urlencode($urlToRedirectBackTo); - } - - return $loginAction; - } - - /** - * Normalizes config `loginAction` and checks if current request URL is same as login action. - * - * @param \Cake\Controller\Controller $controller A reference to the controller object. - * @return bool True if current action is login action else false. - */ - protected function _isLoginAction(Controller $controller) - { - $uri = $controller->request->getUri(); - $url = Router::normalize($uri->getPath()); - $loginAction = Router::normalize($this->_config['loginAction']); - - return $loginAction === $url; - } - - /** - * Handle unauthorized access attempt - * - * @param \Cake\Controller\Controller $controller A reference to the controller object - * @return \Cake\Http\Response - * @throws \Cake\Http\Exception\ForbiddenException - */ - protected function _unauthorized(Controller $controller) - { - if ($this->_config['unauthorizedRedirect'] === false) { - throw new ForbiddenException($this->_config['authError']); - } - - $this->flash($this->_config['authError']); - if ($this->_config['unauthorizedRedirect'] === true) { - $default = '/'; - if (!empty($this->_config['loginRedirect'])) { - $default = $this->_config['loginRedirect']; - } - if (is_array($default)) { - $default['_base'] = false; - } - $url = $controller->referer($default, true); - } else { - $url = $this->_config['unauthorizedRedirect']; - } - - return $controller->redirect($url); - } - - /** - * Sets defaults for configs. - * - * @return void - */ - protected function _setDefaults() - { - $defaults = [ - 'authenticate' => ['Form'], - 'flash' => [ - 'element' => 'error', - 'key' => 'flash', - 'params' => ['class' => 'error'] - ], - 'loginAction' => [ - 'controller' => 'Users', - 'action' => 'login', - 'plugin' => null - ], - 'logoutRedirect' => $this->_config['loginAction'], - 'authError' => __d('cake', 'You are not authorized to access that location.') - ]; - - $config = $this->getConfig(); - foreach ($config as $key => $value) { - if ($value !== null) { - unset($defaults[$key]); - } - } - $this->setConfig($defaults); - } - - /** - * Check if the provided user is authorized for the request. - * - * Uses the configured Authorization adapters to check whether or not a user is authorized. - * Each adapter will be checked in sequence, if any of them return true, then the user will - * be authorized for the request. - * - * @param array|\ArrayAccess|null $user The user to check the authorization of. - * If empty the user fetched from storage will be used. - * @param \Cake\Http\ServerRequest|null $request The request to authenticate for. - * If empty, the current request will be used. - * @return bool True if $user is authorized, otherwise false - */ - public function isAuthorized($user = null, ServerRequest $request = null) - { - if (empty($user) && !$this->user()) { - return false; - } - if (empty($user)) { - $user = $this->user(); - } - if (empty($request)) { - $request = $this->getController()->getRequest(); - } - if (empty($this->_authorizeObjects)) { - $this->constructAuthorize(); - } - foreach ($this->_authorizeObjects as $authorizer) { - if ($authorizer->authorize($user, $request) === true) { - $this->_authorizationProvider = $authorizer; - - return true; - } - } - - return false; - } - - /** - * Loads the authorization objects configured. - * - * @return array|null The loaded authorization objects, or null when authorize is empty. - * @throws \Cake\Core\Exception\Exception - */ - public function constructAuthorize() - { - if (empty($this->_config['authorize'])) { - return null; - } - $this->_authorizeObjects = []; - $authorize = Hash::normalize((array)$this->_config['authorize']); - $global = []; - if (isset($authorize[AuthComponent::ALL])) { - $global = $authorize[AuthComponent::ALL]; - unset($authorize[AuthComponent::ALL]); - } - foreach ($authorize as $alias => $config) { - if (!empty($config['className'])) { - $class = $config['className']; - unset($config['className']); - } else { - $class = $alias; - } - $className = App::className($class, 'Auth', 'Authorize'); - if (!class_exists($className)) { - throw new Exception(sprintf('Authorization adapter "%s" was not found.', $class)); - } - if (!method_exists($className, 'authorize')) { - throw new Exception('Authorization objects must implement an authorize() method.'); - } - $config = (array)$config + $global; - $this->_authorizeObjects[$alias] = new $className($this->_registry, $config); - } - - return $this->_authorizeObjects; - } - - /** - * Getter for authorize objects. Will return a particular authorize object. - * - * @param string $alias Alias for the authorize object - * @return \Cake\Auth\BaseAuthorize|null - */ - public function getAuthorize($alias) - { - if (empty($this->_authorizeObjects)) { - $this->constructAuthorize(); - } - - return isset($this->_authorizeObjects[$alias]) ? $this->_authorizeObjects[$alias] : null; - } - - /** - * Takes a list of actions in the current controller for which authentication is not required, or - * no parameters to allow all actions. - * - * You can use allow with either an array or a simple string. - * - * ``` - * $this->Auth->allow('view'); - * $this->Auth->allow(['edit', 'add']); - * ``` - * or to allow all actions - * ``` - * $this->Auth->allow(); - * ``` - * - * @param string|array|null $actions Controller action name or array of actions - * @return void - * @link https://book.cakephp.org/3.0/en/controllers/components/authentication.html#making-actions-public - */ - public function allow($actions = null) - { - if ($actions === null) { - $controller = $this->_registry->getController(); - $this->allowedActions = get_class_methods($controller); - - return; - } - $this->allowedActions = array_merge($this->allowedActions, (array)$actions); - } - - /** - * Removes items from the list of allowed/no authentication required actions. - * - * You can use deny with either an array or a simple string. - * - * ``` - * $this->Auth->deny('view'); - * $this->Auth->deny(['edit', 'add']); - * ``` - * or - * ``` - * $this->Auth->deny(); - * ``` - * to remove all items from the allowed list - * - * @param string|array|null $actions Controller action name or array of actions - * @return void - * @see \Cake\Controller\Component\AuthComponent::allow() - * @link https://book.cakephp.org/3.0/en/controllers/components/authentication.html#making-actions-require-authorization - */ - public function deny($actions = null) - { - if ($actions === null) { - $this->allowedActions = []; - - return; - } - foreach ((array)$actions as $action) { - $i = array_search($action, $this->allowedActions); - if (is_int($i)) { - unset($this->allowedActions[$i]); - } - } - $this->allowedActions = array_values($this->allowedActions); - } - - /** - * Set provided user info to storage as logged in user. - * - * The storage class is configured using `storage` config key or passing - * instance to AuthComponent::storage(). - * - * @param array|\ArrayAccess $user User data. - * @return void - * @link https://book.cakephp.org/3.0/en/controllers/components/authentication.html#identifying-users-and-logging-them-in - */ - public function setUser($user) - { - $this->storage()->write($user); - } - - /** - * Log a user out. - * - * Returns the logout action to redirect to. Triggers the `Auth.logout` event - * which the authenticate classes can listen for and perform custom logout logic. - * - * @return string Normalized config `logoutRedirect` - * @link https://book.cakephp.org/3.0/en/controllers/components/authentication.html#logging-users-out - */ - public function logout() - { - $this->_setDefaults(); - if (empty($this->_authenticateObjects)) { - $this->constructAuthenticate(); - } - $user = (array)$this->user(); - $this->dispatchEvent('Auth.logout', [$user]); - $this->storage()->delete(); - - return Router::normalize($this->_config['logoutRedirect']); - } - - /** - * Get the current user from storage. - * - * @param string|null $key Field to retrieve. Leave null to get entire User record. - * @return mixed|null Either User record or null if no user is logged in, or retrieved field if key is specified. - * @link https://book.cakephp.org/3.0/en/controllers/components/authentication.html#accessing-the-logged-in-user - */ - public function user($key = null) - { - $user = $this->storage()->read(); - if (!$user) { - return null; - } - - if ($key === null) { - return $user; - } - - return Hash::get($user, $key); - } - - /** - * Similar to AuthComponent::user() except if user is not found in - * configured storage, connected authentication objects will have their - * getUser() methods called. - * - * This lets stateless authentication methods function correctly. - * - * @return bool true If a user can be found, false if one cannot. - */ - protected function _getUser() - { - $user = $this->user(); - if ($user) { - return true; - } - - if (empty($this->_authenticateObjects)) { - $this->constructAuthenticate(); - } - foreach ($this->_authenticateObjects as $auth) { - $result = $auth->getUser($this->getController()->getRequest()); - if (!empty($result) && is_array($result)) { - $this->_authenticationProvider = $auth; - $event = $this->dispatchEvent('Auth.afterIdentify', [$result, $auth]); - if ($event->getResult() !== null) { - $result = $event->getResult(); - } - $this->storage()->write($result); - - return true; - } - } - - return false; - } - - /** - * Get the URL a user should be redirected to upon login. - * - * Pass a URL in to set the destination a user should be redirected to upon - * logging in. - * - * If no parameter is passed, gets the authentication redirect URL. The URL - * returned is as per following rules: - * - * - Returns the normalized redirect URL from storage if it is - * present and for the same domain the current app is running on. - * - If there is no URL returned from storage and there is a config - * `loginRedirect`, the `loginRedirect` value is returned. - * - If there is no session and no `loginRedirect`, / is returned. - * - * @param string|array|null $url Optional URL to write as the login redirect URL. - * @return string Redirect URL - */ - public function redirectUrl($url = null) - { - $redirectUrl = $this->getController()->getRequest()->getQuery(static::QUERY_STRING_REDIRECT); - if ($redirectUrl && (substr($redirectUrl, 0, 1) !== '/' || substr($redirectUrl, 0, 2) === '//')) { - $redirectUrl = null; - } - - if ($url !== null) { - $redirectUrl = $url; - } elseif ($redirectUrl) { - if (Router::normalize($redirectUrl) === Router::normalize($this->_config['loginAction'])) { - $redirectUrl = $this->_config['loginRedirect']; - } - } elseif ($this->_config['loginRedirect']) { - $redirectUrl = $this->_config['loginRedirect']; - } else { - $redirectUrl = '/'; - } - if (is_array($redirectUrl)) { - return Router::url($redirectUrl + ['_base' => false]); - } - - return $redirectUrl; - } - - /** - * Use the configured authentication adapters, and attempt to identify the user - * by credentials contained in $request. - * - * Triggers `Auth.afterIdentify` event which the authenticate classes can listen - * to. - * - * @return array|bool User record data, or false, if the user could not be identified. - */ - public function identify() - { - $this->_setDefaults(); - - if (empty($this->_authenticateObjects)) { - $this->constructAuthenticate(); - } - foreach ($this->_authenticateObjects as $auth) { - $result = $auth->authenticate($this->getController()->getRequest(), $this->response); - if (!empty($result)) { - $this->_authenticationProvider = $auth; - $event = $this->dispatchEvent('Auth.afterIdentify', [$result, $auth]); - if ($event->getResult() !== null) { - return $event->getResult(); - } - - return $result; - } - } - - return false; - } - - /** - * Loads the configured authentication objects. - * - * @return array|null The loaded authorization objects, or null on empty authenticate value. - * @throws \Cake\Core\Exception\Exception - */ - public function constructAuthenticate() - { - if (empty($this->_config['authenticate'])) { - return null; - } - $this->_authenticateObjects = []; - $authenticate = Hash::normalize((array)$this->_config['authenticate']); - $global = []; - if (isset($authenticate[AuthComponent::ALL])) { - $global = $authenticate[AuthComponent::ALL]; - unset($authenticate[AuthComponent::ALL]); - } - foreach ($authenticate as $alias => $config) { - if (!empty($config['className'])) { - $class = $config['className']; - unset($config['className']); - } else { - $class = $alias; - } - $className = App::className($class, 'Auth', 'Authenticate'); - if (!class_exists($className)) { - throw new Exception(sprintf('Authentication adapter "%s" was not found.', $class)); - } - if (!method_exists($className, 'authenticate')) { - throw new Exception('Authentication objects must implement an authenticate() method.'); - } - $config = array_merge($global, (array)$config); - $this->_authenticateObjects[$alias] = new $className($this->_registry, $config); - $this->getEventManager()->on($this->_authenticateObjects[$alias]); - } - - return $this->_authenticateObjects; - } - - /** - * Get/set user record storage object. - * - * @param \Cake\Auth\Storage\StorageInterface|null $storage Sets provided - * object as storage or if null returns configured storage object. - * @return \Cake\Auth\Storage\StorageInterface|\Cake\Core\InstanceConfigTrait|null - */ - public function storage(StorageInterface $storage = null) - { - if ($storage !== null) { - $this->_storage = $storage; - - return null; - } - - if ($this->_storage) { - return $this->_storage; - } - - $config = $this->_config['storage']; - if (is_string($config)) { - $class = $config; - $config = []; - } else { - $class = $config['className']; - unset($config['className']); - } - $className = App::className($class, 'Auth/Storage', 'Storage'); - if (!class_exists($className)) { - throw new Exception(sprintf('Auth storage adapter "%s" was not found.', $class)); - } - $request = $this->getController()->getRequest(); - $response = $this->getController()->getResponse(); - $this->_storage = new $className($request, $response, $config); - - return $this->_storage; - } - - /** - * Magic accessor for backward compatibility for property `$sessionKey`. - * - * @param string $name Property name - * @return mixed - */ - public function __get($name) - { - if ($name === 'sessionKey') { - return $this->storage()->getConfig('key'); - } - - return parent::__get($name); - } - - /** - * Magic setter for backward compatibility for property `$sessionKey`. - * - * @param string $name Property name. - * @param mixed $value Value to set. - * @return void - */ - public function __set($name, $value) - { - if ($name === 'sessionKey') { - $this->_storage = null; - - if ($value === false) { - $this->setConfig('storage', 'Memory'); - - return; - } - - $this->setConfig('storage', 'Session'); - $this->storage()->setConfig('key', $value); - - return; - } - - $this->{$name} = $value; - } - - /** - * Getter for authenticate objects. Will return a particular authenticate object. - * - * @param string $alias Alias for the authenticate object - * - * @return \Cake\Auth\BaseAuthenticate|null - */ - public function getAuthenticate($alias) - { - if (empty($this->_authenticateObjects)) { - $this->constructAuthenticate(); - } - - return isset($this->_authenticateObjects[$alias]) ? $this->_authenticateObjects[$alias] : null; - } - - /** - * Set a flash message. Uses the Flash component with values from `flash` config. - * - * @param string $message The message to set. - * @return void - */ - public function flash($message) - { - if ($message === false) { - return; - } - - $this->Flash->set($message, $this->_config['flash']); - } - - /** - * If login was called during this request and the user was successfully - * authenticated, this function will return the instance of the authentication - * object that was used for logging the user in. - * - * @return \Cake\Auth\BaseAuthenticate|null - */ - public function authenticationProvider() - { - return $this->_authenticationProvider; - } - - /** - * If there was any authorization processing for the current request, this function - * will return the instance of the Authorization object that granted access to the - * user to the current address. - * - * @return \Cake\Auth\BaseAuthorize|null - */ - public function authorizationProvider() - { - return $this->_authorizationProvider; - } - - /** - * Returns the URL to redirect back to or / if not possible. - * - * This method takes the referrer into account if the - * request is not of type GET. - * - * @return string - */ - protected function _getUrlToRedirectBackTo() - { - $urlToRedirectBackTo = $this->request->getRequestTarget(); - if (!$this->request->is('get')) { - $urlToRedirectBackTo = $this->request->referer(true); - } - - return $urlToRedirectBackTo; - } -} diff --git a/vendor/cakephp/cakephp/src/Controller/Component/CookieComponent.php b/vendor/cakephp/cakephp/src/Controller/Component/CookieComponent.php deleted file mode 100644 index 07909d8..0000000 --- a/vendor/cakephp/cakephp/src/Controller/Component/CookieComponent.php +++ /dev/null @@ -1,357 +0,0 @@ - null, - 'domain' => '', - 'secure' => false, - 'key' => null, - 'httpOnly' => false, - 'encryption' => 'aes', - 'expires' => '+1 month', - ]; - - /** - * Config specific to a given top level key name. - * - * The values in this array are merged with the general config - * to generate the configuration for a given top level cookie name. - * - * @var array - */ - protected $_keyConfig = []; - - /** - * Values stored in the cookie. - * - * Accessed in the controller using $this->Cookie->read('Name.key'); - * - * @var array - */ - protected $_values = []; - - /** - * A map of keys that have been loaded. - * - * Since CookieComponent lazily reads cookie data, - * we need to track which cookies have been read to account for - * read, delete, read patterns. - * - * @var array - */ - protected $_loaded = []; - - /** - * A reference to the Controller's Cake\Http\Response object. - * Currently unused. - * - * @var \Cake\Http\Response|null - * @deprecated 3.4.0 Will be removed in 4.0.0 - */ - protected $_response; - - /** - * Initialize config data and properties. - * - * @param array $config The config data. - * @return void - */ - public function initialize(array $config) - { - if (!$this->_config['key']) { - $this->setConfig('key', Security::getSalt()); - } - - $controller = $this->_registry->getController(); - - if ($controller === null) { - $this->request = ServerRequestFactory::fromGlobals(); - } - - if (empty($this->_config['path'])) { - $this->setConfig('path', $this->request->getAttribute('webroot')); - } - } - - /** - * Set the configuration for a specific top level key. - * - * ### Examples: - * - * Set a single config option for a key: - * - * ``` - * $this->Cookie->configKey('User', 'expires', '+3 months'); - * ``` - * - * Set multiple options: - * - * ``` - * $this->Cookie->configKey('User', [ - * 'expires', '+3 months', - * 'httpOnly' => true, - * ]); - * ``` - * - * @param string $keyname The top level keyname to configure. - * @param null|string|array $option Either the option name to set, or an array of options to set, - * or null to read config options for a given key. - * @param string|null $value Either the value to set, or empty when $option is an array. - * @return array|null - */ - public function configKey($keyname, $option = null, $value = null) - { - if ($option === null) { - $default = $this->_config; - $local = isset($this->_keyConfig[$keyname]) ? $this->_keyConfig[$keyname] : []; - - return $local + $default; - } - if (!is_array($option)) { - $option = [$option => $value]; - } - $this->_keyConfig[$keyname] = $option; - - return null; - } - - /** - * Events supported by this component. - * - * @return array - */ - public function implementedEvents() - { - return []; - } - - /** - * Write a value to the response cookies. - * - * You must use this method before any output is sent to the browser. - * Failure to do so will result in header already sent errors. - * - * @param string|array $key Key for the value - * @param mixed $value Value - * @return void - */ - public function write($key, $value = null) - { - if (!is_array($key)) { - $key = [$key => $value]; - } - - $keys = []; - foreach ($key as $name => $value) { - $this->_load($name); - - $this->_values = Hash::insert($this->_values, $name, $value); - $parts = explode('.', $name); - $keys[] = $parts[0]; - } - - foreach ($keys as $name) { - $this->_write($name, $this->_values[$name]); - } - } - - /** - * Read the value of key path from request cookies. - * - * This method will also allow you to read cookies that have been written in this - * request, but not yet sent to the client. - * - * @param string|null $key Key of the value to be obtained. - * @return string or null, value for specified key - */ - public function read($key = null) - { - $this->_load($key); - - return Hash::get($this->_values, $key); - } - - /** - * Load the cookie data from the request and response objects. - * - * Based on the configuration data, cookies will be decrypted. When cookies - * contain array data, that data will be expanded. - * - * @param string|array $key The key to load. - * @return void - */ - protected function _load($key) - { - $parts = explode('.', $key); - $first = array_shift($parts); - if (isset($this->_loaded[$first])) { - return; - } - $cookie = $this->request->getCookie($first); - if ($cookie === null) { - return; - } - $config = $this->configKey($first); - $this->_loaded[$first] = true; - $this->_values[$first] = $this->_decrypt($cookie, $config['encryption'], $config['key']); - } - - /** - * Returns true if given key is set in the cookie. - * - * @param string|null $key Key to check for - * @return bool True if the key exists - */ - public function check($key = null) - { - if (empty($key)) { - return false; - } - - return $this->read($key) !== null; - } - - /** - * Delete a cookie value - * - * You must use this method before any output is sent to the browser. - * Failure to do so will result in header already sent errors. - * - * Deleting a top level key will delete all keys nested within that key. - * For example deleting the `User` key, will also delete `User.email`. - * - * @param string $key Key of the value to be deleted - * @return void - */ - public function delete($key) - { - $this->_load($key); - - $this->_values = Hash::remove($this->_values, $key); - $parts = explode('.', $key); - $top = $parts[0]; - - if (isset($this->_values[$top])) { - $this->_write($top, $this->_values[$top]); - } else { - $this->_delete($top); - } - } - - /** - * Set cookie - * - * @param string $name Name for cookie - * @param string $value Value for cookie - * @return void - */ - protected function _write($name, $value) - { - $config = $this->configKey($name); - $expires = new Time($config['expires']); - - $controller = $this->getController(); - $controller->response = $controller->response->withCookie($name, [ - 'value' => $this->_encrypt($value, $config['encryption'], $config['key']), - 'expire' => $expires->format('U'), - 'path' => $config['path'], - 'domain' => $config['domain'], - 'secure' => (bool)$config['secure'], - 'httpOnly' => (bool)$config['httpOnly'] - ]); - } - - /** - * Sets a cookie expire time to remove cookie value. - * - * This is only done once all values in a cookie key have been - * removed with delete. - * - * @param string $name Name of cookie - * @return void - */ - protected function _delete($name) - { - $config = $this->configKey($name); - $expires = new Time('now'); - $controller = $this->getController(); - - $controller->response = $controller->response->withCookie($name, [ - 'value' => '', - 'expire' => $expires->format('U') - 42000, - 'path' => $config['path'], - 'domain' => $config['domain'], - 'secure' => $config['secure'], - 'httpOnly' => $config['httpOnly'] - ]); - } - - /** - * Returns the encryption key to be used. - * - * @return string - */ - protected function _getCookieEncryptionKey() - { - return $this->_config['key']; - } -} diff --git a/vendor/cakephp/cakephp/src/Controller/Component/CsrfComponent.php b/vendor/cakephp/cakephp/src/Controller/Component/CsrfComponent.php deleted file mode 100644 index afb376a..0000000 --- a/vendor/cakephp/cakephp/src/Controller/Component/CsrfComponent.php +++ /dev/null @@ -1,169 +0,0 @@ -Form->create(...)` is used in a view. - * - * @deprecated 3.5.0 Use Cake\Http\Middleware\CsrfProtectionMiddleware instead. - */ -class CsrfComponent extends Component -{ - - /** - * Default config for the CSRF handling. - * - * - cookieName = The name of the cookie to send. - * - expiry = How long the CSRF token should last. Defaults to browser session. - * - secure = Whether or not the cookie will be set with the Secure flag. Defaults to false. - * - httpOnly = Whether or not the cookie will be set with the HttpOnly flag. Defaults to false. - * - field = The form field to check. Changing this will also require configuring - * FormHelper. - * - * @var array - */ - protected $_defaultConfig = [ - 'cookieName' => 'csrfToken', - 'expiry' => 0, - 'secure' => false, - 'httpOnly' => false, - 'field' => '_csrfToken', - ]; - - /** - * Startup callback. - * - * Validates the CSRF token for POST data. If - * the request is a GET request, and the cookie value is absent a cookie will be set. - * - * Once a cookie is set it will be copied into request->getParam('_csrfToken') - * so that application and framework code can easily access the csrf token. - * - * RequestAction requests do not get checked, nor will - * they set a cookie should it be missing. - * - * @param \Cake\Event\Event $event Event instance. - * @return void - */ - public function startup(Event $event) - { - /** @var \Cake\Controller\Controller $controller */ - $controller = $event->getSubject(); - $request = $controller->request; - $response = $controller->response; - $cookieName = $this->_config['cookieName']; - - $cookieData = $request->getCookie($cookieName); - if ($cookieData) { - $request = $request->withParam('_csrfToken', $cookieData); - } - - if ($request->is('requested')) { - $controller->request = $request; - - return; - } - - if ($request->is('get') && $cookieData === null) { - list($request, $response) = $this->_setCookie($request, $response); - $controller->response = $response; - } - if ($request->is(['put', 'post', 'delete', 'patch']) || $request->getData()) { - $this->_validateToken($request); - $request = $request->withoutData($this->_config['field']); - } - $controller->request = $request; - } - - /** - * Events supported by this component. - * - * @return array - */ - public function implementedEvents() - { - return [ - 'Controller.startup' => 'startup', - ]; - } - - /** - * Set the cookie in the response. - * - * Also sets the request->params['_csrfToken'] so the newly minted - * token is available in the request data. - * - * @param \Cake\Http\ServerRequest $request The request object. - * @param \Cake\Http\Response $response The response object. - * @return array An array of the modified request, response. - */ - protected function _setCookie(ServerRequest $request, Response $response) - { - $expiry = new Time($this->_config['expiry']); - $value = hash('sha512', Security::randomBytes(16), false); - - $request = $request->withParam('_csrfToken', $value); - $response = $response->withCookie($this->_config['cookieName'], [ - 'value' => $value, - 'expire' => $expiry->format('U'), - 'path' => $request->getAttribute('webroot'), - 'secure' => $this->_config['secure'], - 'httpOnly' => $this->_config['httpOnly'], - ]); - - return [$request, $response]; - } - - /** - * Validate the request data against the cookie token. - * - * @param \Cake\Http\ServerRequest $request The request to validate against. - * @throws \Cake\Http\Exception\InvalidCsrfTokenException when the CSRF token is invalid or missing. - * @return void - */ - protected function _validateToken(ServerRequest $request) - { - $cookie = $request->getCookie($this->_config['cookieName']); - $post = $request->getData($this->_config['field']); - $header = $request->getHeaderLine('X-CSRF-Token'); - - if (!$cookie) { - throw new InvalidCsrfTokenException(__d('cake', 'Missing CSRF token cookie')); - } - - if (!Security::constantEquals($post, $cookie) && !Security::constantEquals($header, $cookie)) { - throw new InvalidCsrfTokenException(__d('cake', 'CSRF token mismatch.')); - } - } -} diff --git a/vendor/cakephp/cakephp/src/Controller/Component/FlashComponent.php b/vendor/cakephp/cakephp/src/Controller/Component/FlashComponent.php deleted file mode 100644 index 9a8ae72..0000000 --- a/vendor/cakephp/cakephp/src/Controller/Component/FlashComponent.php +++ /dev/null @@ -1,175 +0,0 @@ - 'flash', - 'element' => 'default', - 'params' => [], - 'clear' => false, - 'duplicate' => true - ]; - - /** - * Constructor - * - * @param \Cake\Controller\ComponentRegistry $registry A ComponentRegistry for this component - * @param array $config Array of config. - */ - public function __construct(ComponentRegistry $registry, array $config = []) - { - parent::__construct($registry, $config); - $this->_session = $registry->getController()->request->getSession(); - } - - /** - * Used to set a session variable that can be used to output messages in the view. - * If you make consecutive calls to this method, the messages will stack (if they are - * set with the same flash key) - * - * In your controller: $this->Flash->set('This has been saved'); - * - * ### Options: - * - * - `key` The key to set under the session's Flash key - * - `element` The element used to render the flash message. Default to 'default'. - * - `params` An array of variables to make available when using an element - * - `clear` A bool stating if the current stack should be cleared to start a new one - * - `escape` Set to false to allow templates to print out HTML content - * - * @param string|\Exception $message Message to be flashed. If an instance - * of \Exception the exception message will be used and code will be set - * in params. - * @param array $options An array of options - * @return void - */ - public function set($message, array $options = []) - { - $options += $this->getConfig(); - - if ($message instanceof Exception) { - if (!isset($options['params']['code'])) { - $options['params']['code'] = $message->getCode(); - } - $message = $message->getMessage(); - } - - if (isset($options['escape']) && !isset($options['params']['escape'])) { - $options['params']['escape'] = $options['escape']; - } - - list($plugin, $element) = pluginSplit($options['element']); - - if ($plugin) { - $options['element'] = $plugin . '.Flash/' . $element; - } else { - $options['element'] = 'Flash/' . $element; - } - - $messages = []; - if (!$options['clear']) { - $messages = (array)$this->_session->read('Flash.' . $options['key']); - } - - if (!$options['duplicate']) { - foreach ($messages as $existingMessage) { - if ($existingMessage['message'] === $message) { - return; - } - } - } - - $messages[] = [ - 'message' => $message, - 'key' => $options['key'], - 'element' => $options['element'], - 'params' => $options['params'] - ]; - - $this->_session->write('Flash.' . $options['key'], $messages); - } - - /** - * Magic method for verbose flash methods based on element names. - * - * For example: $this->Flash->success('My message') would use the - * success.ctp element under `src/Template/Element/Flash` for rendering the - * flash message. - * - * If you make consecutive calls to this method, the messages will stack (if they are - * set with the same flash key) - * - * Note that the parameter `element` will be always overridden. In order to call a - * specific element from a plugin, you should set the `plugin` option in $args. - * - * For example: `$this->Flash->warning('My message', ['plugin' => 'PluginName'])` would - * use the warning.ctp element under `plugins/PluginName/src/Template/Element/Flash` for - * rendering the flash message. - * - * @param string $name Element name to use. - * @param array $args Parameters to pass when calling `FlashComponent::set()`. - * @return void - * @throws \Cake\Http\Exception\InternalErrorException If missing the flash message. - */ - public function __call($name, $args) - { - $element = Inflector::underscore($name); - - if (count($args) < 1) { - throw new InternalErrorException('Flash message missing.'); - } - - $options = ['element' => $element]; - - if (!empty($args[1])) { - if (!empty($args[1]['plugin'])) { - $options = ['element' => $args[1]['plugin'] . '.' . $element]; - unset($args[1]['plugin']); - } - $options += (array)$args[1]; - } - - $this->set($args[0], $options); - } -} diff --git a/vendor/cakephp/cakephp/src/Controller/Component/PaginatorComponent.php b/vendor/cakephp/cakephp/src/Controller/Component/PaginatorComponent.php deleted file mode 100644 index 472bc2b..0000000 --- a/vendor/cakephp/cakephp/src/Controller/Component/PaginatorComponent.php +++ /dev/null @@ -1,348 +0,0 @@ - 1, - 'limit' => 20, - 'maxLimit' => 100, - 'whitelist' => ['limit', 'sort', 'page', 'direction'] - ]; - - /** - * Datasource paginator instance. - * - * @var \Cake\Datasource\Paginator - */ - protected $_paginator; - - /** - * {@inheritDoc} - */ - public function __construct(ComponentRegistry $registry, array $config = []) - { - if (isset($config['paginator'])) { - if (!$config['paginator'] instanceof Paginator) { - throw new InvalidArgumentException('Paginator must be an instance of ' . Paginator::class); - } - $this->_paginator = $config['paginator']; - unset($config['paginator']); - } else { - $this->_paginator = new Paginator(); - } - - parent::__construct($registry, $config); - } - - /** - * Events supported by this component. - * - * @return array - */ - public function implementedEvents() - { - return []; - } - - /** - * Handles automatic pagination of model records. - * - * ### Configuring pagination - * - * When calling `paginate()` you can use the $settings parameter to pass in pagination settings. - * These settings are used to build the queries made and control other pagination settings. - * - * If your settings contain a key with the current table's alias. The data inside that key will be used. - * Otherwise the top level configuration will be used. - * - * ``` - * $settings = [ - * 'limit' => 20, - * 'maxLimit' => 100 - * ]; - * $results = $paginator->paginate($table, $settings); - * ``` - * - * The above settings will be used to paginate any Table. You can configure Table specific settings by - * keying the settings with the Table alias. - * - * ``` - * $settings = [ - * 'Articles' => [ - * 'limit' => 20, - * 'maxLimit' => 100 - * ], - * 'Comments' => [ ... ] - * ]; - * $results = $paginator->paginate($table, $settings); - * ``` - * - * This would allow you to have different pagination settings for `Articles` and `Comments` tables. - * - * ### Controlling sort fields - * - * By default CakePHP will automatically allow sorting on any column on the table object being - * paginated. Often times you will want to allow sorting on either associated columns or calculated - * fields. In these cases you will need to define a whitelist of all the columns you wish to allow - * sorting on. You can define the whitelist in the `$settings` parameter: - * - * ``` - * $settings = [ - * 'Articles' => [ - * 'finder' => 'custom', - * 'sortWhitelist' => ['title', 'author_id', 'comment_count'], - * ] - * ]; - * ``` - * - * Passing an empty array as whitelist disallows sorting altogether. - * - * ### Paginating with custom finders - * - * You can paginate with any find type defined on your table using the `finder` option. - * - * ``` - * $settings = [ - * 'Articles' => [ - * 'finder' => 'popular' - * ] - * ]; - * $results = $paginator->paginate($table, $settings); - * ``` - * - * Would paginate using the `find('popular')` method. - * - * You can also pass an already created instance of a query to this method: - * - * ``` - * $query = $this->Articles->find('popular')->matching('Tags', function ($q) { - * return $q->where(['name' => 'CakePHP']) - * }); - * $results = $paginator->paginate($query); - * ``` - * - * ### Scoping Request parameters - * - * By using request parameter scopes you can paginate multiple queries in the same controller action: - * - * ``` - * $articles = $paginator->paginate($articlesQuery, ['scope' => 'articles']); - * $tags = $paginator->paginate($tagsQuery, ['scope' => 'tags']); - * ``` - * - * Each of the above queries will use different query string parameter sets - * for pagination data. An example URL paginating both results would be: - * - * ``` - * /dashboard?articles[page]=1&tags[page]=2 - * ``` - * - * @param \Cake\Datasource\RepositoryInterface|\Cake\Datasource\QueryInterface $object The table or query to paginate. - * @param array $settings The settings/configuration used for pagination. - * @return \Cake\Datasource\ResultSetInterface Query results - * @throws \Cake\Http\Exception\NotFoundException - */ - public function paginate($object, array $settings = []) - { - $request = $this->_registry->getController()->request; - - try { - $results = $this->_paginator->paginate( - $object, - $request->getQueryParams(), - $settings - ); - - $this->_setPagingParams(); - } catch (PageOutOfBoundsException $e) { - $this->_setPagingParams(); - - throw new NotFoundException(null, null, $e); - } - - return $results; - } - - /** - * Merges the various options that Pagination uses. - * Pulls settings together from the following places: - * - * - General pagination settings - * - Model specific settings. - * - Request parameters - * - * The result of this method is the aggregate of all the option sets combined together. You can change - * config value `whitelist` to modify which options/values can be set using request parameters. - * - * @param string $alias Model alias being paginated, if the general settings has a key with this value - * that key's settings will be used for pagination instead of the general ones. - * @param array $settings The settings to merge with the request data. - * @return array Array of merged options. - */ - public function mergeOptions($alias, $settings) - { - $request = $this->_registry->getController()->request; - - return $this->_paginator->mergeOptions( - $request->getQueryParams(), - $this->_paginator->getDefaults($alias, $settings) - ); - } - - /** - * Set paginator instance. - * - * @param \Cake\Datasource\Paginator $paginator Paginator instance. - * @return self - */ - public function setPaginator(Paginator $paginator) - { - $this->_paginator = $paginator; - - return $this; - } - - /** - * Get paginator instance. - * - * @return \Cake\Datasource\Paginator - */ - public function getPaginator() - { - return $this->_paginator; - } - - /** - * Set paging params to request instance. - * - * @return void - */ - protected function _setPagingParams() - { - $controller = $this->getController(); - $request = $controller->getRequest(); - $paging = $this->_paginator->getPagingParams() + (array)$request->getParam('paging', []); - - $controller->setRequest($request->withParam('paging', $paging)); - } - - /** - * Proxy getting/setting config options to Paginator. - * - * @deprecated 3.5.0 use setConfig()/getConfig() instead. - * @param string|array|null $key The key to get/set, or a complete array of configs. - * @param mixed|null $value The value to set. - * @param bool $merge Whether to recursively merge or overwrite existing config, defaults to true. - * @return mixed Config value being read, or the object itself on write operations. - */ - public function config($key = null, $value = null, $merge = true) - { - deprecationWarning('PaginatorComponent::config() is deprecated. Use getConfig()/setConfig() instead.'); - $return = $this->_paginator->config($key, $value, $merge); - if ($return instanceof Paginator) { - $return = $this; - } - - return $return; - } - - /** - * Proxy setting config options to Paginator. - * - * @param string|array $key The key to set, or a complete array of configs. - * @param mixed|null $value The value to set. - * @param bool $merge Whether to recursively merge or overwrite existing config, defaults to true. - * @return $this - */ - public function setConfig($key, $value = null, $merge = true) - { - $this->_paginator->setConfig($key, $value, $merge); - - return $this; - } - - /** - * Proxy getting config options to Paginator. - * - * @param string|null $key The key to get or null for the whole config. - * @param mixed $default The return value when the key does not exist. - * @return mixed Config value being read. - */ - public function getConfig($key = null, $default = null) - { - return $this->_paginator->getConfig($key, $default); - } - - /** - * Proxy setting config options to Paginator. - * - * @param string|array $key The key to set, or a complete array of configs. - * @param mixed|null $value The value to set. - * @return $this - */ - public function configShallow($key, $value = null) - { - $this->_paginator->configShallow($key, $value = null); - - return $this; - } - - /** - * Proxy method calls to Paginator. - * - * @param string $method Method name. - * @param array $args Method arguments. - * @return mixed - */ - public function __call($method, $args) - { - return call_user_func_array([$this->_paginator, $method], $args); - } -} diff --git a/vendor/cakephp/cakephp/src/Controller/Component/RequestHandlerComponent.php b/vendor/cakephp/cakephp/src/Controller/Component/RequestHandlerComponent.php deleted file mode 100644 index 22980f4..0000000 --- a/vendor/cakephp/cakephp/src/Controller/Component/RequestHandlerComponent.php +++ /dev/null @@ -1,763 +0,0 @@ - true, - 'viewClassMap' => [], - 'inputTypeMap' => [], - 'enableBeforeRedirect' => true - ]; - - /** - * Set the layout to be used when rendering the AuthComponent's ajaxLogin element. - * - * @var string - * @deprecated 3.3.11 This feature property is not supported and will - * be removed in 4.0.0 - */ - public $ajaxLayout; - - /** - * Constructor. Parses the accepted content types accepted by the client using HTTP_ACCEPT - * - * @param \Cake\Controller\ComponentRegistry $registry ComponentRegistry object. - * @param array $config Array of config. - */ - public function __construct(ComponentRegistry $registry, array $config = []) - { - $config += [ - 'viewClassMap' => [ - 'json' => 'Json', - 'xml' => 'Xml', - 'ajax' => 'Ajax' - ], - 'inputTypeMap' => [ - 'json' => ['json_decode', true], - 'xml' => [[$this, 'convertXml']], - ] - ]; - parent::__construct($registry, $config); - } - - /** - * Events supported by this component. - * - * @return array - */ - public function implementedEvents() - { - return [ - 'Controller.startup' => 'startup', - 'Controller.beforeRender' => 'beforeRender', - 'Controller.beforeRedirect' => 'beforeRedirect', - ]; - } - - /** - * @param array $config The config data. - * @return void - * @deprecated 3.4.0 Unused. To be removed in 4.0.0 - */ - public function initialize(array $config) - { - } - - /** - * Set the extension based on the accept headers. - * Compares the accepted types and configured extensions. - * If there is one common type, that is assigned as the ext/content type for the response. - * The type with the highest weight will be set. If the highest weight has more - * than one type matching the extensions, the order in which extensions are specified - * determines which type will be set. - * - * If html is one of the preferred types, no content type will be set, this - * is to avoid issues with browsers that prefer HTML and several other content types. - * - * @param \Cake\Http\ServerRequest $request The request instance. - * @param \Cake\Http\Response $response The response instance. - * @return void - */ - protected function _setExtension($request, $response) - { - $accept = $request->parseAccept(); - if (empty($accept) || current($accept)[0] === 'text/html') { - return; - } - - $accepts = $response->mapType($accept); - $preferredTypes = current($accepts); - if (array_intersect($preferredTypes, ['html', 'xhtml'])) { - return; - } - - $extensions = array_unique( - array_merge(Router::extensions(), array_keys($this->getConfig('viewClassMap'))) - ); - foreach ($accepts as $types) { - $ext = array_intersect($extensions, $types); - if ($ext) { - $this->ext = current($ext); - break; - } - } - } - - /** - * The startup method of the RequestHandler enables several automatic behaviors - * related to the detection of certain properties of the HTTP request, including: - * - * If the XML data is POSTed, the data is parsed into an XML object, which is assigned - * to the $data property of the controller, which can then be saved to a model object. - * - * @param \Cake\Event\Event $event The startup event that was fired. - * @return void - */ - public function startup(Event $event) - { - /** @var \Cake\Controller\Controller $controller */ - $controller = $event->getSubject(); - $request = $controller->request; - $response = $controller->response; - - if ($request->getParam('_ext')) { - $this->ext = $request->getParam('_ext'); - } - if (!$this->ext || in_array($this->ext, ['html', 'htm'])) { - $this->_setExtension($request, $response); - } - - $isAjax = $request->is('ajax'); - $controller->request = $request->withParam('isAjax', $isAjax); - - if (!$this->ext && $isAjax) { - $this->ext = 'ajax'; - } - - if ($request->is(['get', 'head', 'options'])) { - return; - } - - if ($request->getParsedBody() !== []) { - return; - } - foreach ($this->getConfig('inputTypeMap') as $type => $handler) { - if (!is_callable($handler[0])) { - throw new RuntimeException(sprintf("Invalid callable for '%s' type.", $type)); - } - if ($this->requestedWith($type)) { - $input = $request->input(...$handler); - $controller->request = $request->withParsedBody((array)$input); - } - } - } - - /** - * Helper method to parse xml input data, due to lack of anonymous functions - * this lives here. - * - * @param string $xml XML string. - * @return array Xml array data - */ - public function convertXml($xml) - { - try { - $xml = Xml::build($xml, ['return' => 'domdocument', 'readFile' => false]); - // We might not get child nodes if there are nested inline entities. - if ($xml->childNodes->length > 0) { - return Xml::toArray($xml); - } - - return []; - } catch (XmlException $e) { - return []; - } - } - - /** - * Handles (fakes) redirects for AJAX requests using requestAction() - * - * @param \Cake\Event\Event $event The Controller.beforeRedirect event. - * @param string|array $url A string or array containing the redirect location - * @param \Cake\Http\Response $response The response object. - * @return \Cake\Http\Response|null The response object if the redirect is caught. - * @deprecated 3.3.5 This functionality will be removed in 4.0.0. You can disable this function - * now by setting the `enableBeforeRedirect` config option to false. - */ - public function beforeRedirect(Event $event, $url, Response $response) - { - if (!$this->getConfig('enableBeforeRedirect')) { - return null; - } - deprecationWarning( - 'RequestHandlerComponent::beforeRedirect() is deprecated. ' . - 'This functionality will be removed in 4.0.0. Set the `enableBeforeRedirect` ' . - 'option to `false` to disable this warning.' - ); - $request = $this->request; - if (!$request->is('ajax')) { - return null; - } - if (empty($url)) { - return null; - } - if (is_array($url)) { - $url = Router::url($url + ['_base' => false]); - } - $query = []; - if (strpos($url, '?') !== false) { - list($url, $querystr) = explode('?', $url, 2); - parse_str($querystr, $query); - } - /** @var \Cake\Controller\Controller $controller */ - $controller = $event->getSubject(); - $response->body($controller->requestAction($url, [ - 'return', - 'bare' => false, - 'environment' => [ - 'REQUEST_METHOD' => 'GET' - ], - 'query' => $query, - 'cookies' => $request->getCookieParams() - ])); - - return $response->withStatus(200); - } - - /** - * Checks if the response can be considered different according to the request - * headers, and the caching response headers. If it was not modified, then the - * render process is skipped. And the client will get a blank response with a - * "304 Not Modified" header. - * - * - If Router::extensions() is enabled, the layout and template type are - * switched based on the parsed extension or `Accept` header. For example, - * if `controller/action.xml` is requested, the view path becomes - * `app/View/Controller/xml/action.ctp`. Also if `controller/action` is - * requested with `Accept: application/xml` in the headers the view - * path will become `app/View/Controller/xml/action.ctp`. Layout and template - * types will only switch to mime-types recognized by Cake\Http\Response. - * If you need to declare additional mime-types, you can do so using - * Cake\Http\Response::type() in your controller's beforeFilter() method. - * - If a helper with the same name as the extension exists, it is added to - * the controller. - * - If the extension is of a type that RequestHandler understands, it will - * set that Content-type in the response header. - * - * @param \Cake\Event\Event $event The Controller.beforeRender event. - * @return bool false if the render process should be aborted - */ - public function beforeRender(Event $event) - { - /** @var \Cake\Controller\Controller $controller */ - $controller = $event->getSubject(); - $response = $controller->response; - $request = $controller->request; - - $isRecognized = ( - !in_array($this->ext, ['html', 'htm']) && - $response->getMimeType($this->ext) - ); - - if ($this->ext && $isRecognized) { - $this->renderAs($controller, $this->ext); - $response = $controller->response; - } else { - $response = $response->withCharset(Configure::read('App.encoding')); - } - - if ($this->_config['checkHttpCache'] && - $response->checkNotModified($request) - ) { - $controller->response = $response; - - return false; - } - $controller->response = $response; - } - - /** - * Returns true if the current call accepts an XML response, false otherwise - * - * @return bool True if client accepts an XML response - */ - public function isXml() - { - return $this->prefers('xml'); - } - - /** - * Returns true if the current call accepts an RSS response, false otherwise - * - * @return bool True if client accepts an RSS response - */ - public function isRss() - { - return $this->prefers('rss'); - } - - /** - * Returns true if the current call accepts an Atom response, false otherwise - * - * @return bool True if client accepts an RSS response - */ - public function isAtom() - { - return $this->prefers('atom'); - } - - /** - * Returns true if user agent string matches a mobile web browser, or if the - * client accepts WAP content. - * - * @return bool True if user agent is a mobile web browser - */ - public function isMobile() - { - $request = $this->request; - - return $request->is('mobile') || $this->accepts('wap'); - } - - /** - * Returns true if the client accepts WAP content - * - * @return bool - */ - public function isWap() - { - return $this->prefers('wap'); - } - - /** - * Determines which content types the client accepts. Acceptance is based on - * the file extension parsed by the Router (if present), and by the HTTP_ACCEPT - * header. Unlike Cake\Http\ServerRequest::accepts() this method deals entirely with mapped content types. - * - * Usage: - * - * ``` - * $this->RequestHandler->accepts(['xml', 'html', 'json']); - * ``` - * - * Returns true if the client accepts any of the supplied types. - * - * ``` - * $this->RequestHandler->accepts('xml'); - * ``` - * - * Returns true if the client accepts xml. - * - * @param string|array|null $type Can be null (or no parameter), a string type name, or an - * array of types - * @return mixed If null or no parameter is passed, returns an array of content - * types the client accepts. If a string is passed, returns true - * if the client accepts it. If an array is passed, returns true - * if the client accepts one or more elements in the array. - */ - public function accepts($type = null) - { - $controller = $this->getController(); - $request = $controller->request; - $response = $controller->response; - $accepted = $request->accepts(); - - if (!$type) { - return $response->mapType($accepted); - } - if (is_array($type)) { - foreach ($type as $t) { - $t = $this->mapAlias($t); - if (in_array($t, $accepted)) { - return true; - } - } - - return false; - } - if (is_string($type)) { - return in_array($this->mapAlias($type), $accepted); - } - - return false; - } - - /** - * Determines the content type of the data the client has sent (i.e. in a POST request) - * - * @param string|array|null $type Can be null (or no parameter), a string type name, or an array of types - * @return mixed If a single type is supplied a boolean will be returned. If no type is provided - * The mapped value of CONTENT_TYPE will be returned. If an array is supplied the first type - * in the request content type will be returned. - */ - public function requestedWith($type = null) - { - $controller = $this->getController(); - $request = $controller->request; - $response = $controller->response; - - if (!$request->is('post') && - !$request->is('put') && - !$request->is('patch') && - !$request->is('delete') - ) { - return null; - } - if (is_array($type)) { - foreach ($type as $t) { - if ($this->requestedWith($t)) { - return $t; - } - } - - return false; - } - - list($contentType) = explode(';', $request->contentType()); - if ($type === null) { - return $response->mapType($contentType); - } - if (is_string($type)) { - return ($type === $response->mapType($contentType)); - } - } - - /** - * Determines which content-types the client prefers. If no parameters are given, - * the single content-type that the client most likely prefers is returned. If $type is - * an array, the first item in the array that the client accepts is returned. - * Preference is determined primarily by the file extension parsed by the Router - * if provided, and secondarily by the list of content-types provided in - * HTTP_ACCEPT. - * - * @param string|array|null $type An optional array of 'friendly' content-type names, i.e. - * 'html', 'xml', 'js', etc. - * @return mixed If $type is null or not provided, the first content-type in the - * list, based on preference, is returned. If a single type is provided - * a boolean will be returned if that type is preferred. - * If an array of types are provided then the first preferred type is returned. - * If no type is provided the first preferred type is returned. - */ - public function prefers($type = null) - { - $controller = $this->getController(); - $request = $controller->request; - $response = $controller->response; - $acceptRaw = $request->parseAccept(); - - if (empty($acceptRaw)) { - return $type ? $type === $this->ext : $this->ext; - } - $accepts = $response->mapType(array_shift($acceptRaw)); - - if (!$type) { - if (empty($this->ext) && !empty($accepts)) { - return $accepts[0]; - } - - return $this->ext; - } - - $types = (array)$type; - - if (count($types) === 1) { - if ($this->ext) { - return in_array($this->ext, $types); - } - - return in_array($types[0], $accepts); - } - - $intersect = array_values(array_intersect($accepts, $types)); - if (!$intersect) { - return false; - } - - return $intersect[0]; - } - - /** - * Sets either the view class if one exists or the layout and template path of the view. - * The names of these are derived from the $type input parameter. - * - * ### Usage: - * - * Render the response as an 'ajax' response. - * - * ``` - * $this->RequestHandler->renderAs($this, 'ajax'); - * ``` - * - * Render the response as an xml file and force the result as a file download. - * - * ``` - * $this->RequestHandler->renderAs($this, 'xml', ['attachment' => 'myfile.xml']; - * ``` - * - * @param \Cake\Controller\Controller $controller A reference to a controller object - * @param string $type Type of response to send (e.g: 'ajax') - * @param array $options Array of options to use - * @return void - * @see \Cake\Controller\Component\RequestHandlerComponent::respondAs() - */ - public function renderAs(Controller $controller, $type, array $options = []) - { - $defaults = ['charset' => 'UTF-8']; - $viewClassMap = $this->getConfig('viewClassMap'); - - if (Configure::read('App.encoding') !== null) { - $defaults['charset'] = Configure::read('App.encoding'); - } - $options += $defaults; - - $builder = $controller->viewBuilder(); - if (array_key_exists($type, $viewClassMap)) { - $view = $viewClassMap[$type]; - } else { - $view = Inflector::classify($type); - } - - $viewClass = null; - if ($builder->getClassName() === null) { - $viewClass = App::className($view, 'View', 'View'); - } - - if ($viewClass) { - $controller->viewClass = $viewClass; - $builder->setClassName($viewClass); - } else { - if (!$this->_renderType) { - $builder->setTemplatePath($builder->getTemplatePath() . DIRECTORY_SEPARATOR . $type); - } else { - $builder->setTemplatePath(preg_replace( - "/([\/\\\\]{$this->_renderType})$/", - DIRECTORY_SEPARATOR . $type, - $builder->getTemplatePath() - )); - } - - $this->_renderType = $type; - $builder->setLayoutPath($type); - } - - $response = $controller->response; - if ($response->getMimeType($type)) { - $this->respondAs($type, $options); - } - } - - /** - * Sets the response header based on type map index name. This wraps several methods - * available on Cake\Http\Response. It also allows you to use Content-Type aliases. - * - * @param string|array $type Friendly type name, i.e. 'html' or 'xml', or a full content-type, - * like 'application/x-shockwave'. - * @param array $options If $type is a friendly type name that is associated with - * more than one type of content, $index is used to select which content-type to use. - * @return bool Returns false if the friendly type name given in $type does - * not exist in the type map, or if the Content-type header has - * already been set by this method. - */ - public function respondAs($type, array $options = []) - { - $defaults = ['index' => null, 'charset' => null, 'attachment' => false]; - $options += $defaults; - - $cType = $type; - $controller = $this->getController(); - $response = $controller->response; - $request = $controller->request; - - if (strpos($type, '/') === false) { - $cType = $response->getMimeType($type); - } - if (is_array($cType)) { - if (isset($cType[$options['index']])) { - $cType = $cType[$options['index']]; - } - - if ($this->prefers($cType)) { - $cType = $this->prefers($cType); - } else { - $cType = $cType[0]; - } - } - - if (!$type) { - return false; - } - if (!$request->getParam('requested')) { - $response = $response->withType($cType); - } - if (!empty($options['charset'])) { - $response = $response->withCharset($options['charset']); - } - if (!empty($options['attachment'])) { - $response = $response->withDownload($options['attachment']); - } - $controller->response = $response; - - return true; - } - - /** - * Returns the current response type (Content-type header), or null if not alias exists - * - * @return mixed A string content type alias, or raw content type if no alias map exists, - * otherwise null - */ - public function responseType() - { - $response = $this->getController()->response; - - return $response->mapType($response->getType()); - } - - /** - * Maps a content type alias back to its mime-type(s) - * - * @param string|array $alias String alias to convert back into a content type. Or an array of aliases to map. - * @return string|null|array Null on an undefined alias. String value of the mapped alias type. If an - * alias maps to more than one content type, the first one will be returned. If an array is provided - * for $alias, an array of mapped types will be returned. - */ - public function mapAlias($alias) - { - if (is_array($alias)) { - return array_map([$this, 'mapAlias'], $alias); - } - $response = $this->getController()->response; - $type = $response->getMimeType($alias); - if ($type) { - if (is_array($type)) { - return $type[0]; - } - - return $type; - } - - return null; - } - - /** - * Add a new mapped input type. Mapped input types are automatically - * converted by RequestHandlerComponent during the startup() callback. - * - * @param string $type The type alias being converted, ie. json - * @param array $handler The handler array for the type. The first index should - * be the handling callback, all other arguments should be additional parameters - * for the handler. - * @return void - * @throws \Cake\Core\Exception\Exception - * @deprecated 3.1.0 Use setConfig('addInputType', ...) instead. - */ - public function addInputType($type, $handler) - { - deprecationWarning( - 'RequestHandlerComponent::addInputType() is deprecated. Use setConfig("inputTypeMap", ...) instead.' - ); - if (!is_array($handler) || !isset($handler[0]) || !is_callable($handler[0])) { - throw new Exception('You must give a handler callback.'); - } - $this->setConfig('inputTypeMap.' . $type, $handler); - } - - /** - * Getter/setter for viewClassMap - * - * @param array|string|null $type The type string or array with format `['type' => 'viewClass']` to map one or more - * @param array|null $viewClass The viewClass to be used for the type without `View` appended - * @return array|string Returns viewClass when only string $type is set, else array with viewClassMap - * @deprecated 3.1.0 Use setConfig('viewClassMap', ...) instead. - */ - public function viewClassMap($type = null, $viewClass = null) - { - deprecationWarning( - 'RequestHandlerComponent::viewClassMap() is deprecated. Use setConfig("viewClassMap", ...) instead.' - ); - if (!$viewClass && is_string($type)) { - return $this->getConfig('viewClassMap.' . $type); - } - if (is_string($type)) { - $this->setConfig('viewClassMap.' . $type, $viewClass); - } elseif (is_array($type)) { - $this->setConfig('viewClassMap', $type, true); - } - - return $this->getConfig('viewClassMap'); - } -} diff --git a/vendor/cakephp/cakephp/src/Controller/Component/SecurityComponent.php b/vendor/cakephp/cakephp/src/Controller/Component/SecurityComponent.php deleted file mode 100644 index db83f24..0000000 --- a/vendor/cakephp/cakephp/src/Controller/Component/SecurityComponent.php +++ /dev/null @@ -1,668 +0,0 @@ - null, - 'requireSecure' => [], - 'requireAuth' => [], - 'allowedControllers' => [], - 'allowedActions' => [], - 'unlockedFields' => [], - 'unlockedActions' => [], - 'validatePost' => true - ]; - - /** - * Holds the current action of the controller - * - * @var string - */ - protected $_action; - - /** - * The Session object - * - * @var \Cake\Http\Session - */ - public $session; - - /** - * Component startup. All security checking happens here. - * - * @param \Cake\Event\Event $event An Event instance - * @return mixed - */ - public function startup(Event $event) - { - /** @var \Cake\Controller\Controller $controller */ - $controller = $event->getSubject(); - $request = $controller->request; - $this->session = $request->getSession(); - $this->_action = $request->getParam('action'); - $hasData = ($request->getData() || $request->is(['put', 'post', 'delete', 'patch'])); - try { - $this->_secureRequired($controller); - $this->_authRequired($controller); - - $isNotRequestAction = !$request->getParam('requested'); - - if ($this->_action === $this->_config['blackHoleCallback']) { - throw new AuthSecurityException(sprintf('Action %s is defined as the blackhole callback.', $this->_action)); - } - - if (!in_array($this->_action, (array)$this->_config['unlockedActions']) && - $hasData && - $isNotRequestAction && - $this->_config['validatePost'] - ) { - $this->_validatePost($controller); - } - } catch (SecurityException $se) { - $this->blackHole($controller, $se->getType(), $se); - } - - $request = $this->generateToken($request); - if ($hasData && is_array($controller->request->getData())) { - $request = $request->withoutData('_Token'); - } - $controller->request = $request; - } - - /** - * Events supported by this component. - * - * @return array - */ - public function implementedEvents() - { - return [ - 'Controller.startup' => 'startup', - ]; - } - - /** - * Sets the actions that require a request that is SSL-secured, or empty for all actions - * - * @param string|array|null $actions Actions list - * @return void - */ - public function requireSecure($actions = null) - { - $this->_requireMethod('Secure', (array)$actions); - } - - /** - * Sets the actions that require whitelisted form submissions. - * - * Adding actions with this method will enforce the restrictions - * set in SecurityComponent::$allowedControllers and - * SecurityComponent::$allowedActions. - * - * @param string|array $actions Actions list - * @return void - * @deprecated 3.2.2 This feature is confusing and not useful. - */ - public function requireAuth($actions) - { - deprecationWarning('SecurityComponent::requireAuth() will be removed in 4.0.0.'); - $this->_requireMethod('Auth', (array)$actions); - } - - /** - * Black-hole an invalid request with a 400 error or custom callback. If SecurityComponent::$blackHoleCallback - * is specified, it will use this callback by executing the method indicated in $error - * - * @param \Cake\Controller\Controller $controller Instantiating controller - * @param string $error Error method - * @param \Cake\Controller\Exception\SecurityException|null $exception Additional debug info describing the cause - * @return mixed If specified, controller blackHoleCallback's response, or no return otherwise - * @see \Cake\Controller\Component\SecurityComponent::$blackHoleCallback - * @link https://book.cakephp.org/3.0/en/controllers/components/security.html#handling-blackhole-callbacks - * @throws \Cake\Http\Exception\BadRequestException - */ - public function blackHole(Controller $controller, $error = '', SecurityException $exception = null) - { - if (!$this->_config['blackHoleCallback']) { - $this->_throwException($exception); - } - - return $this->_callback($controller, $this->_config['blackHoleCallback'], [$error, $exception]); - } - - /** - * Check debug status and throw an Exception based on the existing one - * - * @param \Cake\Controller\Exception\SecurityException|null $exception Additional debug info describing the cause - * @throws \Cake\Http\Exception\BadRequestException - * @return void - */ - protected function _throwException($exception = null) - { - if ($exception !== null) { - if (!Configure::read('debug') && $exception instanceof SecurityException) { - $exception->setReason($exception->getMessage()); - $exception->setMessage(self::DEFAULT_EXCEPTION_MESSAGE); - } - throw $exception; - } - throw new BadRequestException(self::DEFAULT_EXCEPTION_MESSAGE); - } - - /** - * Sets the actions that require a $method HTTP request, or empty for all actions - * - * @param string $method The HTTP method to assign controller actions to - * @param array $actions Controller actions to set the required HTTP method to. - * @return void - */ - protected function _requireMethod($method, $actions = []) - { - if (isset($actions[0]) && is_array($actions[0])) { - $actions = $actions[0]; - } - $this->setConfig('require' . $method, empty($actions) ? ['*'] : $actions); - } - - /** - * Check if access requires secure connection - * - * @param \Cake\Controller\Controller $controller Instantiating controller - * @return bool true if secure connection required - */ - protected function _secureRequired(Controller $controller) - { - if (is_array($this->_config['requireSecure']) && - !empty($this->_config['requireSecure']) - ) { - $requireSecure = $this->_config['requireSecure']; - - if (in_array($this->_action, $requireSecure) || $requireSecure === ['*']) { - if (!$this->request->is('ssl')) { - throw new SecurityException( - 'Request is not SSL and the action is required to be secure' - ); - } - } - } - - return true; - } - - /** - * Check if authentication is required - * - * @param \Cake\Controller\Controller $controller Instantiating controller - * @return bool true if authentication required - * @deprecated 3.2.2 This feature is confusing and not useful. - */ - protected function _authRequired(Controller $controller) - { - $request = $controller->request; - if (is_array($this->_config['requireAuth']) && - !empty($this->_config['requireAuth']) && - $request->getData() - ) { - deprecationWarning('SecurityComponent::requireAuth() will be removed in 4.0.0.'); - $requireAuth = $this->_config['requireAuth']; - - if (in_array($request->getParam('action'), $requireAuth) || $requireAuth == ['*']) { - if ($request->getData('_Token') === null) { - throw new AuthSecurityException('\'_Token\' was not found in request data.'); - } - - if ($this->session->check('_Token')) { - $tData = $this->session->read('_Token'); - - if (!empty($tData['allowedControllers']) && - !in_array($request->getParam('controller'), $tData['allowedControllers'])) { - throw new AuthSecurityException( - sprintf( - 'Controller \'%s\' was not found in allowed controllers: \'%s\'.', - $request->getParam('controller'), - implode(', ', (array)$tData['allowedControllers']) - ) - ); - } - if (!empty($tData['allowedActions']) && - !in_array($request->getParam('action'), $tData['allowedActions']) - ) { - throw new AuthSecurityException( - sprintf( - 'Action \'%s::%s\' was not found in allowed actions: \'%s\'.', - $request->getParam('controller'), - $request->getParam('action'), - implode(', ', (array)$tData['allowedActions']) - ) - ); - } - } else { - throw new AuthSecurityException('\'_Token\' was not found in session.'); - } - } - } - - return true; - } - - /** - * Validate submitted form - * - * @param \Cake\Controller\Controller $controller Instantiating controller - * @throws \Cake\Controller\Exception\AuthSecurityException - * @return bool true if submitted form is valid - */ - protected function _validatePost(Controller $controller) - { - $token = $this->_validToken($controller); - $hashParts = $this->_hashParts($controller); - $check = hash_hmac('sha1', implode('', $hashParts), Security::getSalt()); - - if (hash_equals($check, $token)) { - return true; - } - - $msg = self::DEFAULT_EXCEPTION_MESSAGE; - if (Configure::read('debug')) { - $msg = $this->_debugPostTokenNotMatching($controller, $hashParts); - } - - throw new AuthSecurityException($msg); - } - - /** - * Check if token is valid - * - * @param \Cake\Controller\Controller $controller Instantiating controller - * @throws \Cake\Controller\Exception\SecurityException - * @return string fields token - */ - protected function _validToken(Controller $controller) - { - $check = $controller->request->getData(); - - $message = '\'%s\' was not found in request data.'; - if (!isset($check['_Token'])) { - throw new AuthSecurityException(sprintf($message, '_Token')); - } - if (!isset($check['_Token']['fields'])) { - throw new AuthSecurityException(sprintf($message, '_Token.fields')); - } - if (!isset($check['_Token']['unlocked'])) { - throw new AuthSecurityException(sprintf($message, '_Token.unlocked')); - } - if (Configure::read('debug') && !isset($check['_Token']['debug'])) { - throw new SecurityException(sprintf($message, '_Token.debug')); - } - if (!Configure::read('debug') && isset($check['_Token']['debug'])) { - throw new SecurityException('Unexpected \'_Token.debug\' found in request data'); - } - - $token = urldecode($check['_Token']['fields']); - if (strpos($token, ':')) { - list($token, ) = explode(':', $token, 2); - } - - return $token; - } - - /** - * Return hash parts for the Token generation - * - * @param \Cake\Controller\Controller $controller Instantiating controller - * @return array - */ - protected function _hashParts(Controller $controller) - { - $request = $controller->getRequest(); - - // Start the session to ensure we get the correct session id. - $session = $request->getSession(); - $session->start(); - - $data = $request->getData(); - $fieldList = $this->_fieldsList($data); - $unlocked = $this->_sortedUnlocked($data); - - return [ - Router::url($request->getRequestTarget()), - serialize($fieldList), - $unlocked, - $session->id() - ]; - } - - /** - * Return the fields list for the hash calculation - * - * @param array $check Data array - * @return array - */ - protected function _fieldsList(array $check) - { - $locked = ''; - $token = urldecode($check['_Token']['fields']); - $unlocked = $this->_unlocked($check); - - if (strpos($token, ':')) { - list($token, $locked) = explode(':', $token, 2); - } - unset($check['_Token'], $check['_csrfToken']); - - $locked = explode('|', $locked); - $unlocked = explode('|', $unlocked); - - $fields = Hash::flatten($check); - $fieldList = array_keys($fields); - $multi = $lockedFields = []; - $isUnlocked = false; - - foreach ($fieldList as $i => $key) { - if (preg_match('/(\.\d+){1,10}$/', $key)) { - $multi[$i] = preg_replace('/(\.\d+){1,10}$/', '', $key); - unset($fieldList[$i]); - } else { - $fieldList[$i] = (string)$key; - } - } - if (!empty($multi)) { - $fieldList += array_unique($multi); - } - - $unlockedFields = array_unique( - array_merge((array)$this->getConfig('disabledFields'), (array)$this->_config['unlockedFields'], $unlocked) - ); - - foreach ($fieldList as $i => $key) { - $isLocked = (is_array($locked) && in_array($key, $locked)); - - if (!empty($unlockedFields)) { - foreach ($unlockedFields as $off) { - $off = explode('.', $off); - $field = array_values(array_intersect(explode('.', $key), $off)); - $isUnlocked = ($field === $off); - if ($isUnlocked) { - break; - } - } - } - - if ($isUnlocked || $isLocked) { - unset($fieldList[$i]); - if ($isLocked) { - $lockedFields[$key] = $fields[$key]; - } - } - } - sort($fieldList, SORT_STRING); - ksort($lockedFields, SORT_STRING); - $fieldList += $lockedFields; - - return $fieldList; - } - - /** - * Get the unlocked string - * - * @param array $data Data array - * @return string - */ - protected function _unlocked(array $data) - { - return urldecode($data['_Token']['unlocked']); - } - - /** - * Get the sorted unlocked string - * - * @param array $data Data array - * @return string - */ - protected function _sortedUnlocked($data) - { - $unlocked = $this->_unlocked($data); - $unlocked = explode('|', $unlocked); - sort($unlocked, SORT_STRING); - - return implode('|', $unlocked); - } - - /** - * Create a message for humans to understand why Security token is not matching - * - * @param \Cake\Controller\Controller $controller Instantiating controller - * @param array $hashParts Elements used to generate the Token hash - * @return string Message explaining why the tokens are not matching - */ - protected function _debugPostTokenNotMatching(Controller $controller, $hashParts) - { - $messages = []; - $expectedParts = json_decode(urldecode($controller->request->getData('_Token.debug')), true); - if (!is_array($expectedParts) || count($expectedParts) !== 3) { - return 'Invalid security debug token.'; - } - $expectedUrl = Hash::get($expectedParts, 0); - $url = Hash::get($hashParts, 0); - if ($expectedUrl !== $url) { - $messages[] = sprintf('URL mismatch in POST data (expected \'%s\' but found \'%s\')', $expectedUrl, $url); - } - $expectedFields = Hash::get($expectedParts, 1); - $dataFields = Hash::get($hashParts, 1); - if ($dataFields) { - $dataFields = unserialize($dataFields); - } - $fieldsMessages = $this->_debugCheckFields( - $dataFields, - $expectedFields, - 'Unexpected field \'%s\' in POST data', - 'Tampered field \'%s\' in POST data (expected value \'%s\' but found \'%s\')', - 'Missing field \'%s\' in POST data' - ); - $expectedUnlockedFields = Hash::get($expectedParts, 2); - $dataUnlockedFields = Hash::get($hashParts, 2) ?: null; - if ($dataUnlockedFields) { - $dataUnlockedFields = explode('|', $dataUnlockedFields); - } - $unlockFieldsMessages = $this->_debugCheckFields( - (array)$dataUnlockedFields, - $expectedUnlockedFields, - 'Unexpected unlocked field \'%s\' in POST data', - null, - 'Missing unlocked field: \'%s\'' - ); - - $messages = array_merge($messages, $fieldsMessages, $unlockFieldsMessages); - - return implode(', ', $messages); - } - - /** - * Iterates data array to check against expected - * - * @param array $dataFields Fields array, containing the POST data fields - * @param array $expectedFields Fields array, containing the expected fields we should have in POST - * @param string $intKeyMessage Message string if unexpected found in data fields indexed by int (not protected) - * @param string $stringKeyMessage Message string if tampered found in data fields indexed by string (protected) - * @param string $missingMessage Message string if missing field - * @return array Messages - */ - protected function _debugCheckFields($dataFields, $expectedFields = [], $intKeyMessage = '', $stringKeyMessage = '', $missingMessage = '') - { - $messages = $this->_matchExistingFields($dataFields, $expectedFields, $intKeyMessage, $stringKeyMessage); - $expectedFieldsMessage = $this->_debugExpectedFields($expectedFields, $missingMessage); - if ($expectedFieldsMessage !== null) { - $messages[] = $expectedFieldsMessage; - } - - return $messages; - } - - /** - * Manually add form tampering prevention token information into the provided - * request object. - * - * @param \Cake\Http\ServerRequest $request The request object to add into. - * @return \Cake\Http\ServerRequest The modified request. - */ - public function generateToken(ServerRequest $request) - { - if ($request->is('requested')) { - if ($this->session->check('_Token')) { - $request = $request->withParam('_Token', $this->session->read('_Token')); - } - - return $request; - } - $token = [ - 'allowedControllers' => $this->_config['allowedControllers'], - 'allowedActions' => $this->_config['allowedActions'], - 'unlockedFields' => $this->_config['unlockedFields'], - ]; - - $this->session->write('_Token', $token); - - return $request->withParam('_Token', [ - 'unlockedFields' => $token['unlockedFields'] - ]); - } - - /** - * Calls a controller callback method - * - * @param \Cake\Controller\Controller $controller Instantiating controller - * @param string $method Method to execute - * @param array $params Parameters to send to method - * @return mixed Controller callback method's response - * @throws \Cake\Http\Exception\BadRequestException When a the blackholeCallback is not callable. - */ - protected function _callback(Controller $controller, $method, $params = []) - { - if (!is_callable([$controller, $method])) { - throw new BadRequestException('The request has been black-holed'); - } - - return call_user_func_array([&$controller, $method], empty($params) ? null : $params); - } - - /** - * Generate array of messages for the existing fields in POST data, matching dataFields in $expectedFields - * will be unset - * - * @param array $dataFields Fields array, containing the POST data fields - * @param array $expectedFields Fields array, containing the expected fields we should have in POST - * @param string $intKeyMessage Message string if unexpected found in data fields indexed by int (not protected) - * @param string $stringKeyMessage Message string if tampered found in data fields indexed by string (protected) - * @return array Error messages - */ - protected function _matchExistingFields($dataFields, &$expectedFields, $intKeyMessage, $stringKeyMessage) - { - $messages = []; - foreach ((array)$dataFields as $key => $value) { - if (is_int($key)) { - $foundKey = array_search($value, (array)$expectedFields); - if ($foundKey === false) { - $messages[] = sprintf($intKeyMessage, $value); - } else { - unset($expectedFields[$foundKey]); - } - } elseif (is_string($key)) { - if (isset($expectedFields[$key]) && $value !== $expectedFields[$key]) { - $messages[] = sprintf($stringKeyMessage, $key, $expectedFields[$key], $value); - } - unset($expectedFields[$key]); - } - } - - return $messages; - } - - /** - * Generate debug message for the expected fields - * - * @param array $expectedFields Expected fields - * @param string $missingMessage Message template - * @return string|null Error message about expected fields - */ - protected function _debugExpectedFields($expectedFields = [], $missingMessage = '') - { - if (count($expectedFields) === 0) { - return null; - } - - $expectedFieldNames = []; - foreach ((array)$expectedFields as $key => $expectedField) { - if (is_int($key)) { - $expectedFieldNames[] = $expectedField; - } else { - $expectedFieldNames[] = $key; - } - } - - return sprintf($missingMessage, implode(', ', $expectedFieldNames)); - } -} diff --git a/vendor/cakephp/cakephp/src/Controller/ComponentRegistry.php b/vendor/cakephp/cakephp/src/Controller/ComponentRegistry.php deleted file mode 100644 index f395c8c..0000000 --- a/vendor/cakephp/cakephp/src/Controller/ComponentRegistry.php +++ /dev/null @@ -1,127 +0,0 @@ -setController($controller); - } - } - - /** - * Get the controller associated with the collection. - * - * @return \Cake\Controller\Controller Controller instance - */ - public function getController() - { - return $this->_Controller; - } - - /** - * Set the controller associated with the collection. - * - * @param \Cake\Controller\Controller $controller Controller instance. - * @return void - */ - public function setController(Controller $controller) - { - $this->_Controller = $controller; - $this->setEventManager($controller->getEventManager()); - } - - /** - * Resolve a component classname. - * - * Part of the template method for Cake\Core\ObjectRegistry::load() - * - * @param string $class Partial classname to resolve. - * @return string|false Either the correct classname or false. - */ - protected function _resolveClassName($class) - { - return App::className($class, 'Controller/Component', 'Component'); - } - - /** - * Throws an exception when a component is missing. - * - * Part of the template method for Cake\Core\ObjectRegistry::load() - * and Cake\Core\ObjectRegistry::unload() - * - * @param string $class The classname that is missing. - * @param string $plugin The plugin the component is missing in. - * @return void - * @throws \Cake\Controller\Exception\MissingComponentException - */ - protected function _throwMissingClassError($class, $plugin) - { - throw new MissingComponentException([ - 'class' => $class . 'Component', - 'plugin' => $plugin - ]); - } - - /** - * Create the component instance. - * - * Part of the template method for Cake\Core\ObjectRegistry::load() - * Enabled components will be registered with the event manager. - * - * @param string $class The classname to create. - * @param string $alias The alias of the component. - * @param array $config An array of config to use for the component. - * @return \Cake\Controller\Component The constructed component class. - */ - protected function _create($class, $alias, $config) - { - $instance = new $class($this, $config); - $enable = isset($config['enabled']) ? $config['enabled'] : true; - if ($enable) { - $this->getEventManager()->on($instance); - } - - return $instance; - } -} diff --git a/vendor/cakephp/cakephp/src/Controller/Controller.php b/vendor/cakephp/cakephp/src/Controller/Controller.php deleted file mode 100644 index 8b5b299..0000000 --- a/vendor/cakephp/cakephp/src/Controller/Controller.php +++ /dev/null @@ -1,958 +0,0 @@ -request`. The request object - * contains all the POST, GET and FILES that were part of the request. - * - * After performing the required action, controllers are responsible for - * creating a response. This usually takes the form of a generated `View`, or - * possibly a redirection to another URL. In either case `$this->response` - * allows you to manipulate all aspects of the response. - * - * Controllers are created by `Dispatcher` based on request parameters and - * routing. By default controllers and actions use conventional names. - * For example `/posts/index` maps to `PostsController::index()`. You can re-map - * URLs using Router::connect() or RouterBuilder::connect(). - * - * ### Life cycle callbacks - * - * CakePHP fires a number of life cycle callbacks during each request. - * By implementing a method you can receive the related events. The available - * callbacks are: - * - * - `beforeFilter(Event $event)` - * Called before each action. This is a good place to do general logic that - * applies to all actions. - * - `beforeRender(Event $event)` - * Called before the view is rendered. - * - `beforeRedirect(Event $event, $url, Response $response)` - * Called before a redirect is done. - * - `afterFilter(Event $event)` - * Called after each action is complete and after the view is rendered. - * - * @property \Cake\Controller\Component\AuthComponent $Auth - * @property \Cake\Controller\Component\CookieComponent $Cookie - * @property \Cake\Controller\Component\CsrfComponent $Csrf - * @property \Cake\Controller\Component\FlashComponent $Flash - * @property \Cake\Controller\Component\PaginatorComponent $Paginator - * @property \Cake\Controller\Component\RequestHandlerComponent $RequestHandler - * @property \Cake\Controller\Component\SecurityComponent $Security - * @method bool isAuthorized($user) - * @link https://book.cakephp.org/3.0/en/controllers.html - */ -class Controller implements EventListenerInterface, EventDispatcherInterface -{ - - use EventDispatcherTrait; - use LocatorAwareTrait; - use LogTrait; - use MergeVariablesTrait; - use ModelAwareTrait; - use RequestActionTrait; - use ViewVarsTrait; - - /** - * The name of this controller. Controller names are plural, named after the model they manipulate. - * - * Set automatically using conventions in Controller::__construct(). - * - * @var string - */ - protected $name; - - /** - * An array containing the names of helpers this controller uses. The array elements should - * not contain the "Helper" part of the class name. - * - * Example: - * ``` - * public $helpers = ['Form', 'Html', 'Time']; - * ``` - * - * @var array - * @link https://book.cakephp.org/3.0/en/controllers.html#configuring-helpers-to-load - * - * @deprecated 3.0.0 You should configure helpers in your AppView::initialize() method. - */ - public $helpers = []; - - /** - * An instance of a \Cake\Http\ServerRequest object that contains information about the current request. - * This object contains all the information about a request and several methods for reading - * additional information about the request. - * - * @var \Cake\Http\ServerRequest|null - * @link https://book.cakephp.org/3.0/en/controllers/request-response.html#request - * @deprecated 3.6.0 The property will become protected in 4.0.0. Use getRequest()/setRequest instead. - */ - public $request; - - /** - * An instance of a Response object that contains information about the impending response - * - * @var \Cake\Http\Response|null - * @link https://book.cakephp.org/3.0/en/controllers/request-response.html#response - * @deprecated 3.6.0 The property will become protected in 4.0.0. Use getResponse()/setResponse instead. - */ - public $response; - - /** - * The class name to use for creating the response object. - * - * @var string - */ - protected $_responseClass = 'Cake\Http\Response'; - - /** - * Settings for pagination. - * - * Used to pre-configure pagination preferences for the various - * tables your controller will be paginating. - * - * @var array - * @see \Cake\Controller\Component\PaginatorComponent - */ - public $paginate = []; - - /** - * Set to true to automatically render the view - * after action logic. - * - * @var bool - */ - protected $autoRender = true; - - /** - * Instance of ComponentRegistry used to create Components - * - * @var \Cake\Controller\ComponentRegistry - */ - protected $_components; - - /** - * Array containing the names of components this controller uses. Component names - * should not contain the "Component" portion of the class name. - * - * Example: - * ``` - * public $components = ['RequestHandler', 'Acl']; - * ``` - * - * @var array - * @link https://book.cakephp.org/3.0/en/controllers/components.html - * - * @deprecated 3.0.0 You should configure components in your Controller::initialize() method. - */ - public $components = []; - - /** - * Instance of the View created during rendering. Won't be set until after - * Controller::render() is called. - * - * @var \Cake\View\View - * @deprecated 3.1.0 Use viewBuilder() instead. - */ - public $View; - - /** - * These Controller properties will be passed from the Controller to the View as options. - * - * @var array - * @see \Cake\View\View - */ - protected $_validViewOptions = [ - 'passedArgs' - ]; - - /** - * Automatically set to the name of a plugin. - * - * @var string|null - */ - protected $plugin; - - /** - * Holds all passed params. - * - * @var array - * @deprecated 3.1.0 Use `$this->request->getParam('pass')` instead. - */ - public $passedArgs = []; - - /** - * Constructor. - * - * Sets a number of properties based on conventions if they are empty. To override the - * conventions CakePHP uses you can define properties in your class declaration. - * - * @param \Cake\Http\ServerRequest|null $request Request object for this controller. Can be null for testing, - * but expect that features that use the request parameters will not work. - * @param \Cake\Http\Response|null $response Response object for this controller. - * @param string|null $name Override the name useful in testing when using mocks. - * @param \Cake\Event\EventManager|null $eventManager The event manager. Defaults to a new instance. - * @param \Cake\Controller\ComponentRegistry|null $components The component registry. Defaults to a new instance. - */ - public function __construct(ServerRequest $request = null, Response $response = null, $name = null, $eventManager = null, $components = null) - { - if ($name !== null) { - $this->name = $name; - } - - if ($this->name === null && $request && $request->getParam('controller')) { - $this->name = $request->getParam('controller'); - } - - if ($this->name === null) { - list(, $name) = namespaceSplit(get_class($this)); - $this->name = substr($name, 0, -10); - } - - $this->setRequest($request ?: new ServerRequest()); - $this->setResponse($response ?: new Response()); - - if ($eventManager !== null) { - $this->setEventManager($eventManager); - } - - $this->modelFactory('Table', [$this->getTableLocator(), 'get']); - $plugin = $this->request->getParam('plugin'); - $modelClass = ($plugin ? $plugin . '.' : '') . $this->name; - $this->_setModelClass($modelClass); - - if ($components !== null) { - $this->components($components); - } - - $this->initialize(); - - $this->_mergeControllerVars(); - $this->_loadComponents(); - $this->getEventManager()->on($this); - } - - /** - * Initialization hook method. - * - * Implement this method to avoid having to overwrite - * the constructor and call parent. - * - * @return void - */ - public function initialize() - { - } - - /** - * Get the component registry for this controller. - * - * If called with the first parameter, it will be set as the controller $this->_components property - * - * @param \Cake\Controller\ComponentRegistry|null $components Component registry. - * - * @return \Cake\Controller\ComponentRegistry - */ - public function components($components = null) - { - if ($components === null && $this->_components === null) { - $this->_components = new ComponentRegistry($this); - } - if ($components !== null) { - $components->setController($this); - $this->_components = $components; - } - - return $this->_components; - } - - /** - * Add a component to the controller's registry. - * - * This method will also set the component to a property. - * For example: - * - * ``` - * $this->loadComponent('Acl.Acl'); - * ``` - * - * Will result in a `Toolbar` property being set. - * - * @param string $name The name of the component to load. - * @param array $config The config for the component. - * @return \Cake\Controller\Component - */ - public function loadComponent($name, array $config = []) - { - list(, $prop) = pluginSplit($name); - - return $this->{$prop} = $this->components()->load($name, $config); - } - - /** - * Magic accessor for model autoloading. - * - * @param string $name Property name - * @return bool|object The model instance or false - */ - public function __get($name) - { - $deprecated = [ - 'name' => 'getName', - 'plugin' => 'getPlugin', - 'autoRender' => 'isAutoRenderEnabled', - ]; - if (isset($deprecated[$name])) { - $method = $deprecated[$name]; - deprecationWarning(sprintf('Controller::$%s is deprecated. Use $this->%s() instead.', $name, $method)); - - return $this->{$method}(); - } - - $deprecated = [ - 'layout' => 'getLayout', - 'view' => 'getTemplate', - 'theme' => 'getTheme', - 'autoLayout' => 'isAutoLayoutEnabled', - 'viewPath' => 'getTemplatePath', - 'layoutPath' => 'getLayoutPath', - ]; - if (isset($deprecated[$name])) { - $method = $deprecated[$name]; - deprecationWarning(sprintf('Controller::$%s is deprecated. Use $this->viewBuilder()->%s() instead.', $name, $method)); - - return $this->viewBuilder()->{$method}(); - } - - list($plugin, $class) = pluginSplit($this->modelClass, true); - if ($class !== $name) { - return false; - } - - return $this->loadModel($plugin . $class); - } - - /** - * Magic setter for removed properties. - * - * @param string $name Property name. - * @param mixed $value Value to set. - * @return void - */ - public function __set($name, $value) - { - $deprecated = [ - 'name' => 'setName', - 'plugin' => 'setPlugin' - ]; - if (isset($deprecated[$name])) { - $method = $deprecated[$name]; - deprecationWarning(sprintf('Controller::$%s is deprecated. Use $this->%s() instead.', $name, $method)); - $this->{$method}($value); - - return; - } - if ($name === 'autoRender') { - $value ? $this->enableAutoRender() : $this->disableAutoRender(); - deprecationWarning(sprintf('Controller::$%s is deprecated. Use $this->enableAutoRender/disableAutoRender() instead.', $name)); - - return; - } - $deprecated = [ - 'layout' => 'setLayout', - 'view' => 'setTemplate', - 'theme' => 'setTheme', - 'autoLayout' => 'enableAutoLayout', - 'viewPath' => 'setTemplatePath', - 'layoutPath' => 'setLayoutPath', - ]; - if (isset($deprecated[$name])) { - $method = $deprecated[$name]; - deprecationWarning(sprintf('Controller::$%s is deprecated. Use $this->viewBuilder()->%s() instead.', $name, $method)); - - $this->viewBuilder()->{$method}($value); - - return; - } - - $this->{$name} = $value; - } - - /** - * Returns the controller name. - * - * @return string - * @since 3.6.0 - */ - public function getName() - { - return $this->name; - } - - /** - * Sets the controller name. - * - * @param string $name Controller name. - * @return $this - * @since 3.6.0 - */ - public function setName($name) - { - $this->name = $name; - - return $this; - } - - /** - * Returns the plugin name. - * - * @return string|null - * @since 3.6.0 - */ - public function getPlugin() - { - return $this->plugin; - } - - /** - * Sets the plugin name. - * - * @param string $name Plugin name. - * @return $this - * @since 3.6.0 - */ - public function setPlugin($name) - { - $this->plugin = $name; - - return $this; - } - - /** - * Returns true if an action should be rendered automatically. - * - * @return bool - * @since 3.6.0 - */ - public function isAutoRenderEnabled() - { - return $this->autoRender; - } - - /** - * Enable automatic action rendering. - * - * @return $this - * @since 3.6.0 - */ - public function enableAutoRender() - { - $this->autoRender = true; - - return $this; - } - - /** - * Disbale automatic action rendering. - * - * @return $this - * @since 3.6.0 - */ - public function disableAutoRender() - { - $this->autoRender = false; - - return $this; - } - - /** - * Gets the request instance. - * - * @return \Cake\Http\ServerRequest - * @since 3.6.0 - */ - public function getRequest() - { - return $this->request; - } - - /** - * Sets the request objects and configures a number of controller properties - * based on the contents of the request. Controller acts as a proxy for certain View variables - * which must also be updated here. The properties that get set are: - * - * - $this->request - To the $request parameter - * - $this->passedArgs - Same as $request->params['pass] - * - * @param \Cake\Http\ServerRequest $request Request instance. - * @return $this - */ - public function setRequest(ServerRequest $request) - { - $this->request = $request; - $this->plugin = $request->getParam('plugin') ?: null; - - if ($request->getParam('pass')) { - $this->passedArgs = $request->getParam('pass'); - } - - return $this; - } - - /** - * Gets the response instance. - * - * @return \Cake\Http\Response - * @since 3.6.0 - */ - public function getResponse() - { - return $this->response; - } - - /** - * Sets the response instance. - * - * @param \Cake\Http\Response $response Response instance. - * @return $this - * @since 3.6.0 - */ - public function setResponse(Response $response) - { - $this->response = $response; - - return $this; - } - - /** - * Dispatches the controller action. Checks that the action - * exists and isn't private. - * - * @return mixed The resulting response. - * @throws \LogicException When request is not set. - * @throws \Cake\Controller\Exception\MissingActionException When actions are not defined or inaccessible. - */ - public function invokeAction() - { - $request = $this->request; - if (!isset($request)) { - throw new LogicException('No Request object configured. Cannot invoke action'); - } - if (!$this->isAction($request->getParam('action'))) { - throw new MissingActionException([ - 'controller' => $this->name . 'Controller', - 'action' => $request->getParam('action'), - 'prefix' => $request->getParam('prefix') ?: '', - 'plugin' => $request->getParam('plugin'), - ]); - } - /* @var callable $callable */ - $callable = [$this, $request->getParam('action')]; - - return $callable(...array_values($request->getParam('pass'))); - } - - /** - * Merge components, helpers vars from - * parent classes. - * - * @return void - */ - protected function _mergeControllerVars() - { - $this->_mergeVars( - ['components', 'helpers'], - ['associative' => ['components', 'helpers']] - ); - } - - /** - * Returns a list of all events that will fire in the controller during its lifecycle. - * You can override this function to add your own listener callbacks - * - * @return array - */ - public function implementedEvents() - { - return [ - 'Controller.initialize' => 'beforeFilter', - 'Controller.beforeRender' => 'beforeRender', - 'Controller.beforeRedirect' => 'beforeRedirect', - 'Controller.shutdown' => 'afterFilter', - ]; - } - - /** - * Loads the defined components using the Component factory. - * - * @return void - */ - protected function _loadComponents() - { - if (empty($this->components)) { - return; - } - $registry = $this->components(); - $components = $registry->normalizeArray($this->components); - foreach ($components as $properties) { - $this->loadComponent($properties['class'], $properties['config']); - } - } - - /** - * Perform the startup process for this controller. - * Fire the Components and Controller callbacks in the correct order. - * - * - Initializes components, which fires their `initialize` callback - * - Calls the controller `beforeFilter`. - * - triggers Component `startup` methods. - * - * @return \Cake\Http\Response|null - */ - public function startupProcess() - { - $event = $this->dispatchEvent('Controller.initialize'); - if ($event->getResult() instanceof Response) { - return $event->getResult(); - } - $event = $this->dispatchEvent('Controller.startup'); - if ($event->getResult() instanceof Response) { - return $event->getResult(); - } - - return null; - } - - /** - * Perform the various shutdown processes for this controller. - * Fire the Components and Controller callbacks in the correct order. - * - * - triggers the component `shutdown` callback. - * - calls the Controller's `afterFilter` method. - * - * @return \Cake\Http\Response|null - */ - public function shutdownProcess() - { - $event = $this->dispatchEvent('Controller.shutdown'); - if ($event->getResult() instanceof Response) { - return $event->getResult(); - } - - return null; - } - - /** - * Redirects to given $url, after turning off $this->autoRender. - * - * @param string|array $url A string or array-based URL pointing to another location within the app, - * or an absolute URL - * @param int $status HTTP status code (eg: 301) - * @return \Cake\Http\Response|null - * @link https://book.cakephp.org/3.0/en/controllers.html#Controller::redirect - */ - public function redirect($url, $status = 302) - { - $this->autoRender = false; - - if ($status) { - $this->response = $this->response->withStatus($status); - } - - $event = $this->dispatchEvent('Controller.beforeRedirect', [$url, $this->response]); - if ($event->getResult() instanceof Response) { - return $this->response = $event->getResult(); - } - if ($event->isStopped()) { - return null; - } - $response = $this->response; - - if (!$response->getHeaderLine('Location')) { - $response = $response->withLocation(Router::url($url, true)); - } - - return $this->response = $response; - } - - /** - * Internally redirects one action to another. Does not perform another HTTP request unlike Controller::redirect() - * - * Examples: - * - * ``` - * setAction('another_action'); - * setAction('action_with_parameters', $parameter1); - * ``` - * - * @param string $action The new action to be 'redirected' to. - * Any other parameters passed to this method will be passed as parameters to the new action. - * @param array ...$args Arguments passed to the action - * @return mixed Returns the return value of the called action - */ - public function setAction($action, ...$args) - { - $this->request = $this->request->withParam('action', $action); - - return $this->$action(...$args); - } - - /** - * Instantiates the correct view class, hands it its data, and uses it to render the view output. - * - * @param string|null $view View to use for rendering - * @param string|null $layout Layout to use - * @return \Cake\Http\Response A response object containing the rendered view. - * @link https://book.cakephp.org/3.0/en/controllers.html#rendering-a-view - */ - public function render($view = null, $layout = null) - { - $builder = $this->viewBuilder(); - if (!$builder->getTemplatePath()) { - $builder->setTemplatePath($this->_viewPath()); - } - - if ($this->request->getParam('bare')) { - $builder->enableAutoLayout(false); - } - $builder->getClassName($this->viewClass); - - $this->autoRender = false; - - $event = $this->dispatchEvent('Controller.beforeRender'); - if ($event->getResult() instanceof Response) { - return $event->getResult(); - } - if ($event->isStopped()) { - return $this->response; - } - - if ($builder->getTemplate() === null && $this->request->getParam('action')) { - $builder->setTemplate($this->request->getParam('action')); - } - - $this->View = $this->createView(); - $contents = $this->View->render($view, $layout); - $this->response = $this->View->response->withStringBody($contents); - - return $this->response; - } - - /** - * Get the viewPath based on controller name and request prefix. - * - * @return string - */ - protected function _viewPath() - { - $viewPath = $this->name; - if ($this->request->getParam('prefix')) { - $prefixes = array_map( - 'Cake\Utility\Inflector::camelize', - explode('/', $this->request->getParam('prefix')) - ); - $viewPath = implode(DIRECTORY_SEPARATOR, $prefixes) . DIRECTORY_SEPARATOR . $viewPath; - } - - return $viewPath; - } - - /** - * Returns the referring URL for this request. - * - * @param string|array|null $default Default URL to use if HTTP_REFERER cannot be read from headers - * @param bool $local If true, restrict referring URLs to local server - * @return string Referring URL - */ - public function referer($default = null, $local = false) - { - if (!$this->request) { - return Router::url($default, !$local); - } - - $referer = $this->request->referer($local); - if ($referer === '/' && $default && $default !== $referer) { - $url = Router::url($default, !$local); - $base = $this->request->getAttribute('base'); - if ($local && $base && strpos($url, $base) === 0) { - $url = substr($url, strlen($base)); - if ($url[0] !== '/') { - $url = '/' . $url; - } - - return $url; - } - - return $url; - } - - return $referer; - } - - /** - * Handles pagination of records in Table objects. - * - * Will load the referenced Table object, and have the PaginatorComponent - * paginate the query using the request date and settings defined in `$this->paginate`. - * - * This method will also make the PaginatorHelper available in the view. - * - * @param \Cake\ORM\Table|string|\Cake\ORM\Query|null $object Table to paginate - * (e.g: Table instance, 'TableName' or a Query object) - * @param array $settings The settings/configuration used for pagination. - * @return \Cake\ORM\ResultSet|\Cake\Datasource\ResultSetInterface Query results - * @link https://book.cakephp.org/3.0/en/controllers.html#paginating-a-model - * @throws \RuntimeException When no compatible table object can be found. - */ - public function paginate($object = null, array $settings = []) - { - if (is_object($object)) { - $table = $object; - } - - if (is_string($object) || $object === null) { - $try = [$object, $this->modelClass]; - foreach ($try as $tableName) { - if (empty($tableName)) { - continue; - } - $table = $this->loadModel($tableName); - break; - } - } - - $this->loadComponent('Paginator'); - if (empty($table)) { - throw new RuntimeException('Unable to locate an object compatible with paginate.'); - } - $settings += $this->paginate; - - return $this->Paginator->paginate($table, $settings); - } - - /** - * Method to check that an action is accessible from a URL. - * - * Override this method to change which controller methods can be reached. - * The default implementation disallows access to all methods defined on Cake\Controller\Controller, - * and allows all public methods on all subclasses of this class. - * - * @param string $action The action to check. - * @return bool Whether or not the method is accessible from a URL. - */ - public function isAction($action) - { - $baseClass = new ReflectionClass('Cake\Controller\Controller'); - if ($baseClass->hasMethod($action)) { - return false; - } - try { - $method = new ReflectionMethod($this, $action); - } catch (ReflectionException $e) { - return false; - } - - return $method->isPublic(); - } - - /** - * Called before the controller action. You can use this method to configure and customize components - * or perform logic that needs to happen before each controller action. - * - * @param \Cake\Event\Event $event An Event instance - * @return \Cake\Http\Response|null - * @link https://book.cakephp.org/3.0/en/controllers.html#request-life-cycle-callbacks - */ - public function beforeFilter(Event $event) - { - return null; - } - - /** - * Called after the controller action is run, but before the view is rendered. You can use this method - * to perform logic or set view variables that are required on every request. - * - * @param \Cake\Event\Event $event An Event instance - * @return \Cake\Http\Response|null - * @link https://book.cakephp.org/3.0/en/controllers.html#request-life-cycle-callbacks - */ - public function beforeRender(Event $event) - { - return null; - } - - /** - * The beforeRedirect method is invoked when the controller's redirect method is called but before any - * further action. - * - * If the event is stopped the controller will not continue on to redirect the request. - * The $url and $status variables have same meaning as for the controller's method. - * You can set the event result to response instance or modify the redirect location - * using controller's response instance. - * - * @param \Cake\Event\Event $event An Event instance - * @param string|array $url A string or array-based URL pointing to another location within the app, - * or an absolute URL - * @param \Cake\Http\Response $response The response object. - * @return \Cake\Http\Response|null - * @link https://book.cakephp.org/3.0/en/controllers.html#request-life-cycle-callbacks - */ - public function beforeRedirect(Event $event, $url, Response $response) - { - return null; - } - - /** - * Called after the controller action is run and rendered. - * - * @param \Cake\Event\Event $event An Event instance - * @return \Cake\Http\Response|null - * @link https://book.cakephp.org/3.0/en/controllers.html#request-life-cycle-callbacks - */ - public function afterFilter(Event $event) - { - return null; - } -} diff --git a/vendor/cakephp/cakephp/src/Controller/ErrorController.php b/vendor/cakephp/cakephp/src/Controller/ErrorController.php deleted file mode 100644 index 51b5295..0000000 --- a/vendor/cakephp/cakephp/src/Controller/ErrorController.php +++ /dev/null @@ -1,47 +0,0 @@ -loadComponent('RequestHandler'); - } - - /** - * beforeRender callback. - * - * @param \Cake\Event\Event $event Event. - * @return void - */ - public function beforeRender(Event $event) - { - $this->viewBuilder()->setTemplatePath('Error'); - } -} diff --git a/vendor/cakephp/cakephp/src/Controller/Exception/AuthSecurityException.php b/vendor/cakephp/cakephp/src/Controller/Exception/AuthSecurityException.php deleted file mode 100644 index f902d54..0000000 --- a/vendor/cakephp/cakephp/src/Controller/Exception/AuthSecurityException.php +++ /dev/null @@ -1,25 +0,0 @@ -_type; - } - - /** - * Set Message - * - * @param string $message Exception message - * @return void - */ - public function setMessage($message) - { - $this->message = $message; - } - - /** - * Set Reason - * - * @param string|null $reason Reason details - * @return void - */ - public function setReason($reason = null) - { - $this->_reason = $reason; - } - - /** - * Get Reason - * - * @return string - */ - public function getReason() - { - return $this->_reason; - } -} diff --git a/vendor/cakephp/cakephp/src/Core/App.php b/vendor/cakephp/cakephp/src/Core/App.php deleted file mode 100644 index b18d09c..0000000 --- a/vendor/cakephp/cakephp/src/Core/App.php +++ /dev/null @@ -1,214 +0,0 @@ -_prefixes[$prefix])) { - $this->_prefixes[$prefix] = []; - } - - if ($prepend) { - array_unshift($this->_prefixes[$prefix], $baseDir); - } else { - $this->_prefixes[$prefix][] = $baseDir; - } - } - - /** - * Loads the class file for a given class name. - * - * @param string $class The fully-qualified class name. - * @return string|false The mapped file name on success, or boolean false on - * failure. - */ - public function loadClass($class) - { - $prefix = $class; - - while (($pos = strrpos($prefix, '\\')) !== false) { - $prefix = substr($class, 0, $pos + 1); - $relativeClass = substr($class, $pos + 1); - - $mappedFile = $this->_loadMappedFile($prefix, $relativeClass); - if ($mappedFile) { - return $mappedFile; - } - - $prefix = rtrim($prefix, '\\'); - } - - return false; - } - - /** - * Load the mapped file for a namespace prefix and relative class. - * - * @param string $prefix The namespace prefix. - * @param string $relativeClass The relative class name. - * @return mixed Boolean false if no mapped file can be loaded, or the - * name of the mapped file that was loaded. - */ - protected function _loadMappedFile($prefix, $relativeClass) - { - if (!isset($this->_prefixes[$prefix])) { - return false; - } - - foreach ($this->_prefixes[$prefix] as $baseDir) { - $file = $baseDir . str_replace('\\', DIRECTORY_SEPARATOR, $relativeClass) . '.php'; - - if ($this->_requireFile($file)) { - return $file; - } - } - - return false; - } - - /** - * If a file exists, require it from the file system. - * - * @param string $file The file to require. - * @return bool True if the file exists, false if not. - */ - protected function _requireFile($file) - { - if (file_exists($file)) { - require $file; - - return true; - } - - return false; - } -} diff --git a/vendor/cakephp/cakephp/src/Core/Configure.php b/vendor/cakephp/cakephp/src/Core/Configure.php deleted file mode 100644 index cb65453..0000000 --- a/vendor/cakephp/cakephp/src/Core/Configure.php +++ /dev/null @@ -1,463 +0,0 @@ - false - ]; - - /** - * Configured engine classes, used to load config files from resources - * - * @see \Cake\Core\Configure::load() - * @var \Cake\Core\Configure\ConfigEngineInterface[] - */ - protected static $_engines = []; - - /** - * Flag to track whether or not ini_set exists. - * - * @var bool|null - */ - protected static $_hasIniSet; - - /** - * Used to store a dynamic variable in Configure. - * - * Usage: - * ``` - * Configure::write('One.key1', 'value of the Configure::One[key1]'); - * Configure::write(['One.key1' => 'value of the Configure::One[key1]']); - * Configure::write('One', [ - * 'key1' => 'value of the Configure::One[key1]', - * 'key2' => 'value of the Configure::One[key2]' - * ]); - * - * Configure::write([ - * 'One.key1' => 'value of the Configure::One[key1]', - * 'One.key2' => 'value of the Configure::One[key2]' - * ]); - * ``` - * - * @param string|array $config The key to write, can be a dot notation value. - * Alternatively can be an array containing key(s) and value(s). - * @param mixed $value Value to set for var - * @return bool True if write was successful - * @link https://book.cakephp.org/3.0/en/development/configuration.html#writing-configuration-data - */ - public static function write($config, $value = null) - { - if (!is_array($config)) { - $config = [$config => $value]; - } - - foreach ($config as $name => $value) { - static::$_values = Hash::insert(static::$_values, $name, $value); - } - - if (isset($config['debug'])) { - if (static::$_hasIniSet === null) { - static::$_hasIniSet = function_exists('ini_set'); - } - if (static::$_hasIniSet) { - ini_set('display_errors', $config['debug'] ? '1' : '0'); - } - } - - return true; - } - - /** - * Used to read information stored in Configure. It's not - * possible to store `null` values in Configure. - * - * Usage: - * ``` - * Configure::read('Name'); will return all values for Name - * Configure::read('Name.key'); will return only the value of Configure::Name[key] - * ``` - * - * @param string|null $var Variable to obtain. Use '.' to access array elements. - * @param mixed $default The return value when the configure does not exist - * @return mixed Value stored in configure, or null. - * @link https://book.cakephp.org/3.0/en/development/configuration.html#reading-configuration-data - */ - public static function read($var = null, $default = null) - { - if ($var === null) { - return static::$_values; - } - - return Hash::get(static::$_values, $var, $default); - } - - /** - * Returns true if given variable is set in Configure. - * - * @param string $var Variable name to check for - * @return bool True if variable is there - */ - public static function check($var) - { - if (empty($var)) { - return false; - } - - return static::read($var) !== null; - } - - /** - * Used to get information stored in Configure. It's not - * possible to store `null` values in Configure. - * - * Acts as a wrapper around Configure::read() and Configure::check(). - * The configure key/value pair fetched via this method is expected to exist. - * In case it does not an exception will be thrown. - * - * Usage: - * ``` - * Configure::readOrFail('Name'); will return all values for Name - * Configure::readOrFail('Name.key'); will return only the value of Configure::Name[key] - * ``` - * - * @param string $var Variable to obtain. Use '.' to access array elements. - * @return mixed Value stored in configure. - * @throws \RuntimeException if the requested configuration is not set. - * @link https://book.cakephp.org/3.0/en/development/configuration.html#reading-configuration-data - */ - public static function readOrFail($var) - { - if (static::check($var) === false) { - throw new RuntimeException(sprintf('Expected configuration key "%s" not found.', $var)); - } - - return static::read($var); - } - - /** - * Used to delete a variable from Configure. - * - * Usage: - * ``` - * Configure::delete('Name'); will delete the entire Configure::Name - * Configure::delete('Name.key'); will delete only the Configure::Name[key] - * ``` - * - * @param string $var the var to be deleted - * @return void - * @link https://book.cakephp.org/3.0/en/development/configuration.html#deleting-configuration-data - */ - public static function delete($var) - { - static::$_values = Hash::remove(static::$_values, $var); - } - - /** - * Used to consume information stored in Configure. It's not - * possible to store `null` values in Configure. - * - * Acts as a wrapper around Configure::consume() and Configure::check(). - * The configure key/value pair consumed via this method is expected to exist. - * In case it does not an exception will be thrown. - * - * @param string $var Variable to consume. Use '.' to access array elements. - * @return mixed Value stored in configure. - * @throws \RuntimeException if the requested configuration is not set. - * @since 3.6.0 - */ - public static function consumeOrFail($var) - { - if (static::check($var) === false) { - throw new RuntimeException(sprintf('Expected configuration key "%s" not found.', $var)); - } - - return static::consume($var); - } - - /** - * Used to read and delete a variable from Configure. - * - * This is primarily used during bootstrapping to move configuration data - * out of configure into the various other classes in CakePHP. - * - * @param string $var The key to read and remove. - * @return array|string|null - */ - public static function consume($var) - { - if (strpos($var, '.') === false) { - if (!isset(static::$_values[$var])) { - return null; - } - $value = static::$_values[$var]; - unset(static::$_values[$var]); - - return $value; - } - $value = Hash::get(static::$_values, $var); - static::delete($var); - - return $value; - } - - /** - * Add a new engine to Configure. Engines allow you to read configuration - * files in various formats/storage locations. CakePHP comes with two built-in engines - * PhpConfig and IniConfig. You can also implement your own engine classes in your application. - * - * To add a new engine to Configure: - * - * ``` - * Configure::config('ini', new IniConfig()); - * ``` - * - * @param string $name The name of the engine being configured. This alias is used later to - * read values from a specific engine. - * @param \Cake\Core\Configure\ConfigEngineInterface $engine The engine to append. - * @return void - */ - public static function config($name, ConfigEngineInterface $engine) - { - static::$_engines[$name] = $engine; - } - - /** - * Gets the names of the configured Engine objects. - * - * @param string|null $name Engine name. - * @return array|bool Array of the configured Engine objects, bool for specific name. - */ - public static function configured($name = null) - { - if ($name !== null) { - return isset(static::$_engines[$name]); - } - - return array_keys(static::$_engines); - } - - /** - * Remove a configured engine. This will unset the engine - * and make any future attempts to use it cause an Exception. - * - * @param string $name Name of the engine to drop. - * @return bool Success - */ - public static function drop($name) - { - if (!isset(static::$_engines[$name])) { - return false; - } - unset(static::$_engines[$name]); - - return true; - } - - /** - * Loads stored configuration information from a resource. You can add - * config file resource engines with `Configure::config()`. - * - * Loaded configuration information will be merged with the current - * runtime configuration. You can load configuration files from plugins - * by preceding the filename with the plugin name. - * - * `Configure::load('Users.user', 'default')` - * - * Would load the 'user' config file using the default config engine. You can load - * app config files by giving the name of the resource you want loaded. - * - * ``` - * Configure::load('setup', 'default'); - * ``` - * - * If using `default` config and no engine has been configured for it yet, - * one will be automatically created using PhpConfig - * - * @param string $key name of configuration resource to load. - * @param string $config Name of the configured engine to use to read the resource identified by $key. - * @param bool $merge if config files should be merged instead of simply overridden - * @return bool False if file not found, true if load successful. - * @link https://book.cakephp.org/3.0/en/development/configuration.html#reading-and-writing-configuration-files - */ - public static function load($key, $config = 'default', $merge = true) - { - $engine = static::_getEngine($config); - if (!$engine) { - return false; - } - $values = $engine->read($key); - - if ($merge) { - $values = Hash::merge(static::$_values, $values); - } - - return static::write($values); - } - - /** - * Dump data currently in Configure into $key. The serialization format - * is decided by the config engine attached as $config. For example, if the - * 'default' adapter is a PhpConfig, the generated file will be a PHP - * configuration file loadable by the PhpConfig. - * - * ### Usage - * - * Given that the 'default' engine is an instance of PhpConfig. - * Save all data in Configure to the file `my_config.php`: - * - * ``` - * Configure::dump('my_config', 'default'); - * ``` - * - * Save only the error handling configuration: - * - * ``` - * Configure::dump('error', 'default', ['Error', 'Exception']; - * ``` - * - * @param string $key The identifier to create in the config adapter. - * This could be a filename or a cache key depending on the adapter being used. - * @param string $config The name of the configured adapter to dump data with. - * @param array $keys The name of the top-level keys you want to dump. - * This allows you save only some data stored in Configure. - * @return bool Success - * @throws \Cake\Core\Exception\Exception if the adapter does not implement a `dump` method. - */ - public static function dump($key, $config = 'default', $keys = []) - { - $engine = static::_getEngine($config); - if (!$engine) { - throw new Exception(sprintf('There is no "%s" config engine.', $config)); - } - $values = static::$_values; - if (!empty($keys) && is_array($keys)) { - $values = array_intersect_key($values, array_flip($keys)); - } - - return (bool)$engine->dump($key, $values); - } - - /** - * Get the configured engine. Internally used by `Configure::load()` and `Configure::dump()` - * Will create new PhpConfig for default if not configured yet. - * - * @param string $config The name of the configured adapter - * @return \Cake\Core\Configure\ConfigEngineInterface|false Engine instance or false - */ - protected static function _getEngine($config) - { - if (!isset(static::$_engines[$config])) { - if ($config !== 'default') { - return false; - } - static::config($config, new PhpConfig()); - } - - return static::$_engines[$config]; - } - - /** - * Used to determine the current version of CakePHP. - * - * Usage - * ``` - * Configure::version(); - * ``` - * - * @return string Current version of CakePHP - */ - public static function version() - { - if (!isset(static::$_values['Cake']['version'])) { - $config = require CORE_PATH . 'config/config.php'; - static::write($config); - } - - return static::$_values['Cake']['version']; - } - - /** - * Used to write runtime configuration into Cache. Stored runtime configuration can be - * restored using `Configure::restore()`. These methods can be used to enable configuration managers - * frontends, or other GUI type interfaces for configuration. - * - * @param string $name The storage name for the saved configuration. - * @param string $cacheConfig The cache configuration to save into. Defaults to 'default' - * @param array|null $data Either an array of data to store, or leave empty to store all values. - * @return bool Success - */ - public static function store($name, $cacheConfig = 'default', $data = null) - { - if ($data === null) { - $data = static::$_values; - } - - return Cache::write($name, $data, $cacheConfig); - } - - /** - * Restores configuration data stored in the Cache into configure. Restored - * values will overwrite existing ones. - * - * @param string $name Name of the stored config file to load. - * @param string $cacheConfig Name of the Cache configuration to read from. - * @return bool Success. - */ - public static function restore($name, $cacheConfig = 'default') - { - $values = Cache::read($name, $cacheConfig); - if ($values) { - return static::write($values); - } - - return false; - } - - /** - * Clear all values stored in Configure. - * - * @return bool success. - */ - public static function clear() - { - static::$_values = []; - - return true; - } -} diff --git a/vendor/cakephp/cakephp/src/Core/Configure/ConfigEngineInterface.php b/vendor/cakephp/cakephp/src/Core/Configure/ConfigEngineInterface.php deleted file mode 100644 index 188c0b9..0000000 --- a/vendor/cakephp/cakephp/src/Core/Configure/ConfigEngineInterface.php +++ /dev/null @@ -1,43 +0,0 @@ - ['password' => 'secret']]` - * - * You can nest properties as deeply as needed using `.`'s. In addition to using `.` you - * can use standard ini section notation to create nested structures: - * - * ``` - * [section] - * key = value - * ``` - * - * Once loaded into Configure, the above would be accessed using: - * - * `Configure::read('section.key'); - * - * You can also use `.` separated values in section names to create more deeply - * nested structures. - * - * IniConfig also manipulates how the special ini values of - * 'yes', 'no', 'on', 'off', 'null' are handled. These values will be - * converted to their boolean equivalents. - * - * @see https://secure.php.net/parse_ini_file - */ -class IniConfig implements ConfigEngineInterface -{ - - use FileConfigTrait; - - /** - * File extension. - * - * @var string - */ - protected $_extension = '.ini'; - - /** - * The section to read, if null all sections will be read. - * - * @var string|null - */ - protected $_section; - - /** - * Build and construct a new ini file parser. The parser can be used to read - * ini files that are on the filesystem. - * - * @param string|null $path Path to load ini config files from. Defaults to CONFIG. - * @param string|null $section Only get one section, leave null to parse and fetch - * all sections in the ini file. - */ - public function __construct($path = null, $section = null) - { - if ($path === null) { - $path = CONFIG; - } - $this->_path = $path; - $this->_section = $section; - } - - /** - * Read an ini file and return the results as an array. - * - * @param string $key The identifier to read from. If the key has a . it will be treated - * as a plugin prefix. The chosen file must be on the engine's path. - * @return array Parsed configuration values. - * @throws \Cake\Core\Exception\Exception when files don't exist. - * Or when files contain '..' as this could lead to abusive reads. - */ - public function read($key) - { - $file = $this->_getFilePath($key, true); - - $contents = parse_ini_file($file, true); - if ($this->_section && isset($contents[$this->_section])) { - $values = $this->_parseNestedValues($contents[$this->_section]); - } else { - $values = []; - foreach ($contents as $section => $attribs) { - if (is_array($attribs)) { - $values[$section] = $this->_parseNestedValues($attribs); - } else { - $parse = $this->_parseNestedValues([$attribs]); - $values[$section] = array_shift($parse); - } - } - } - - return $values; - } - - /** - * parses nested values out of keys. - * - * @param array $values Values to be exploded. - * @return array Array of values exploded - */ - protected function _parseNestedValues($values) - { - foreach ($values as $key => $value) { - if ($value === '1') { - $value = true; - } - if ($value === '') { - $value = false; - } - unset($values[$key]); - if (strpos($key, '.') !== false) { - $values = Hash::insert($values, $key, $value); - } else { - $values[$key] = $value; - } - } - - return $values; - } - - /** - * Dumps the state of Configure data into an ini formatted string. - * - * @param string $key The identifier to write to. If the key has a . it will be treated - * as a plugin prefix. - * @param array $data The data to convert to ini file. - * @return bool Success. - */ - public function dump($key, array $data) - { - $result = []; - foreach ($data as $k => $value) { - $isSection = false; - if ($k[0] !== '[') { - $result[] = "[$k]"; - $isSection = true; - } - if (is_array($value)) { - $kValues = Hash::flatten($value, '.'); - foreach ($kValues as $k2 => $v) { - $result[] = "$k2 = " . $this->_value($v); - } - } - if ($isSection) { - $result[] = ''; - } - } - $contents = trim(implode("\n", $result)); - - $filename = $this->_getFilePath($key); - - return file_put_contents($filename, $contents) > 0; - } - - /** - * Converts a value into the ini equivalent - * - * @param mixed $value Value to export. - * @return string String value for ini file. - */ - protected function _value($value) - { - if ($value === null) { - return 'null'; - } - if ($value === true) { - return 'true'; - } - if ($value === false) { - return 'false'; - } - - return (string)$value; - } -} diff --git a/vendor/cakephp/cakephp/src/Core/Configure/Engine/JsonConfig.php b/vendor/cakephp/cakephp/src/Core/Configure/Engine/JsonConfig.php deleted file mode 100644 index b454347..0000000 --- a/vendor/cakephp/cakephp/src/Core/Configure/Engine/JsonConfig.php +++ /dev/null @@ -1,114 +0,0 @@ -_path = $path; - } - - /** - * Read a config file and return its contents. - * - * Files with `.` in the name will be treated as values in plugins. Instead of - * reading from the initialized path, plugin keys will be located using Plugin::path(). - * - * @param string $key The identifier to read from. If the key has a . it will be treated - * as a plugin prefix. - * @return array Parsed configuration values. - * @throws \Cake\Core\Exception\Exception When files don't exist or when - * files contain '..' (as this could lead to abusive reads) or when there - * is an error parsing the JSON string. - */ - public function read($key) - { - $file = $this->_getFilePath($key, true); - - $values = json_decode(file_get_contents($file), true); - if (json_last_error() !== JSON_ERROR_NONE) { - throw new Exception(sprintf( - 'Error parsing JSON string fetched from config file "%s.json": %s', - $key, - json_last_error_msg() - )); - } - if (!is_array($values)) { - throw new Exception(sprintf( - 'Decoding JSON config file "%s.json" did not return an array', - $key - )); - } - - return $values; - } - - /** - * Converts the provided $data into a JSON string that can be used saved - * into a file and loaded later. - * - * @param string $key The identifier to write to. If the key has a . it will - * be treated as a plugin prefix. - * @param array $data Data to dump. - * @return bool Success - */ - public function dump($key, array $data) - { - $filename = $this->_getFilePath($key); - - return file_put_contents($filename, json_encode($data, JSON_PRETTY_PRINT)) > 0; - } -} diff --git a/vendor/cakephp/cakephp/src/Core/Configure/Engine/PhpConfig.php b/vendor/cakephp/cakephp/src/Core/Configure/Engine/PhpConfig.php deleted file mode 100644 index ec572eb..0000000 --- a/vendor/cakephp/cakephp/src/Core/Configure/Engine/PhpConfig.php +++ /dev/null @@ -1,118 +0,0 @@ - 0, - * 'Security' => [ - * 'salt' => 'its-secret' - * ], - * 'App' => [ - * 'namespace' => 'App' - * ] - * ]; - * ``` - * - * @see Cake\Core\Configure::load() for how to load custom configuration files. - */ -class PhpConfig implements ConfigEngineInterface -{ - - use FileConfigTrait; - - /** - * File extension. - * - * @var string - */ - protected $_extension = '.php'; - - /** - * Constructor for PHP Config file reading. - * - * @param string|null $path The path to read config files from. Defaults to CONFIG. - */ - public function __construct($path = null) - { - if ($path === null) { - $path = CONFIG; - } - $this->_path = $path; - } - - /** - * Read a config file and return its contents. - * - * Files with `.` in the name will be treated as values in plugins. Instead of - * reading from the initialized path, plugin keys will be located using Plugin::path(). - * - * Setting a `$config` variable is deprecated. Use `return` instead. - * - * @param string $key The identifier to read from. If the key has a . it will be treated - * as a plugin prefix. - * @return array Parsed configuration values. - * @throws \Cake\Core\Exception\Exception when files don't exist or they don't contain `$config`. - * Or when files contain '..' as this could lead to abusive reads. - */ - public function read($key) - { - $file = $this->_getFilePath($key, true); - - $return = include $file; - if (is_array($return)) { - return $return; - } - - if (!isset($config)) { - throw new Exception(sprintf('Config file "%s" did not return an array', $key . '.php')); - } - deprecationWarning('PHP configuration files should not set `$config. Instead return an array.'); - - return $config; - } - - /** - * Converts the provided $data into a string of PHP code that can - * be used saved into a file and loaded later. - * - * @param string $key The identifier to write to. If the key has a . it will be treated - * as a plugin prefix. - * @param array $data Data to dump. - * @return bool Success - */ - public function dump($key, array $data) - { - $contents = '_getFilePath($key); - - return file_put_contents($filename, $contents) > 0; - } -} diff --git a/vendor/cakephp/cakephp/src/Core/Configure/FileConfigTrait.php b/vendor/cakephp/cakephp/src/Core/Configure/FileConfigTrait.php deleted file mode 100644 index 71a9b4b..0000000 --- a/vendor/cakephp/cakephp/src/Core/Configure/FileConfigTrait.php +++ /dev/null @@ -1,69 +0,0 @@ -_path . $key; - } - - $file .= $this->_extension; - - if (!$checkExists || is_file($file)) { - return $file; - } - - if (is_file(realpath($file))) { - return realpath($file); - } - - throw new Exception(sprintf('Could not load configuration file: %s', $file)); - } -} diff --git a/vendor/cakephp/cakephp/src/Core/ConventionsTrait.php b/vendor/cakephp/cakephp/src/Core/ConventionsTrait.php deleted file mode 100644 index 2845830..0000000 --- a/vendor/cakephp/cakephp/src/Core/ConventionsTrait.php +++ /dev/null @@ -1,155 +0,0 @@ -_defaultCode; - } - - if (is_array($message)) { - $this->_attributes = $message; - $message = vsprintf($this->_messageTemplate, $message); - } - parent::__construct($message, $code, $previous); - } - - /** - * Get the passed in attributes - * - * @return array - */ - public function getAttributes() - { - return $this->_attributes; - } - - /** - * Get/set the response header to be used - * - * See also Cake\Http\Response::withHeader() - * - * @param string|array|null $header An array of header strings or a single header string - * - an associative array of "header name" => "header value" - * - an array of string headers is also accepted (deprecated) - * @param string|null $value The header value. - * @return array - */ - public function responseHeader($header = null, $value = null) - { - if ($header === null) { - return $this->_responseHeaders; - } - if (is_array($header)) { - if (isset($header[0])) { - deprecationWarning( - 'Passing a list string headers to Exception::responseHeader() is deprecated. ' . - 'Use an associative array instead.' - ); - } - - return $this->_responseHeaders = $header; - } - $this->_responseHeaders = [$header => $value]; - } -} diff --git a/vendor/cakephp/cakephp/src/Core/Exception/MissingPluginException.php b/vendor/cakephp/cakephp/src/Core/Exception/MissingPluginException.php deleted file mode 100644 index bb865ac..0000000 --- a/vendor/cakephp/cakephp/src/Core/Exception/MissingPluginException.php +++ /dev/null @@ -1,22 +0,0 @@ -setConfig('key', $value); - * ``` - * - * Setting a nested value: - * - * ``` - * $this->setConfig('some.nested.key', $value); - * ``` - * - * Updating multiple config settings at the same time: - * - * ``` - * $this->setConfig(['one' => 'value', 'another' => 'value']); - * ``` - * - * @param string|array $key The key to set, or a complete array of configs. - * @param mixed|null $value The value to set. - * @param bool $merge Whether to recursively merge or overwrite existing config, defaults to true. - * @return $this - * @throws \Cake\Core\Exception\Exception When trying to set a key that is invalid. - */ - public function setConfig($key, $value = null, $merge = true) - { - if (!$this->_configInitialized) { - $this->_config = $this->_defaultConfig; - $this->_configInitialized = true; - } - - $this->_configWrite($key, $value, $merge); - - return $this; - } - - /** - * Returns the config. - * - * ### Usage - * - * Reading the whole config: - * - * ``` - * $this->getConfig(); - * ``` - * - * Reading a specific value: - * - * ``` - * $this->getConfig('key'); - * ``` - * - * Reading a nested value: - * - * ``` - * $this->getConfig('some.nested.key'); - * ``` - * - * Reading with default value: - * - * ``` - * $this->getConfig('some-key', 'default-value'); - * ``` - * - * @param string|null $key The key to get or null for the whole config. - * @param mixed $default The return value when the key does not exist. - * @return mixed Config value being read. - */ - public function getConfig($key = null, $default = null) - { - if (!$this->_configInitialized) { - $this->_config = $this->_defaultConfig; - $this->_configInitialized = true; - } - - $return = $this->_configRead($key); - - return $return === null ? $default : $return; - } - - /** - * Gets/Sets the config. - * - * ### Usage - * - * Reading the whole config: - * - * ``` - * $this->config(); - * ``` - * - * Reading a specific value: - * - * ``` - * $this->config('key'); - * ``` - * - * Reading a nested value: - * - * ``` - * $this->config('some.nested.key'); - * ``` - * - * Setting a specific value: - * - * ``` - * $this->config('key', $value); - * ``` - * - * Setting a nested value: - * - * ``` - * $this->config('some.nested.key', $value); - * ``` - * - * Updating multiple config settings at the same time: - * - * ``` - * $this->config(['one' => 'value', 'another' => 'value']); - * ``` - * - * @deprecated 3.4.0 use setConfig()/getConfig() instead. - * @param string|array|null $key The key to get/set, or a complete array of configs. - * @param mixed|null $value The value to set. - * @param bool $merge Whether to recursively merge or overwrite existing config, defaults to true. - * @return mixed Config value being read, or the object itself on write operations. - * @throws \Cake\Core\Exception\Exception When trying to set a key that is invalid. - */ - public function config($key = null, $value = null, $merge = true) - { - deprecationWarning( - get_called_class() . '::config() is deprecated. ' . - 'Use setConfig()/getConfig() instead.' - ); - - if (is_array($key) || func_num_args() >= 2) { - return $this->setConfig($key, $value, $merge); - } - - return $this->getConfig($key); - } - - /** - * Merge provided config with existing config. Unlike `config()` which does - * a recursive merge for nested keys, this method does a simple merge. - * - * Setting a specific value: - * - * ``` - * $this->configShallow('key', $value); - * ``` - * - * Setting a nested value: - * - * ``` - * $this->configShallow('some.nested.key', $value); - * ``` - * - * Updating multiple config settings at the same time: - * - * ``` - * $this->configShallow(['one' => 'value', 'another' => 'value']); - * ``` - * - * @param string|array $key The key to set, or a complete array of configs. - * @param mixed|null $value The value to set. - * @return $this - */ - public function configShallow($key, $value = null) - { - if (!$this->_configInitialized) { - $this->_config = $this->_defaultConfig; - $this->_configInitialized = true; - } - - $this->_configWrite($key, $value, 'shallow'); - - return $this; - } - - /** - * Reads a config key. - * - * @param string|null $key Key to read. - * @return mixed - */ - protected function _configRead($key) - { - if ($key === null) { - return $this->_config; - } - - if (strpos($key, '.') === false) { - return isset($this->_config[$key]) ? $this->_config[$key] : null; - } - - $return = $this->_config; - - foreach (explode('.', $key) as $k) { - if (!is_array($return) || !isset($return[$k])) { - $return = null; - break; - } - - $return = $return[$k]; - } - - return $return; - } - - /** - * Writes a config key. - * - * @param string|array $key Key to write to. - * @param mixed $value Value to write. - * @param bool|string $merge True to merge recursively, 'shallow' for simple merge, - * false to overwrite, defaults to false. - * @return void - * @throws \Cake\Core\Exception\Exception if attempting to clobber existing config - */ - protected function _configWrite($key, $value, $merge = false) - { - if (is_string($key) && $value === null) { - $this->_configDelete($key); - - return; - } - - if ($merge) { - $update = is_array($key) ? $key : [$key => $value]; - if ($merge === 'shallow') { - $this->_config = array_merge($this->_config, Hash::expand($update)); - } else { - $this->_config = Hash::merge($this->_config, Hash::expand($update)); - } - - return; - } - - if (is_array($key)) { - foreach ($key as $k => $val) { - $this->_configWrite($k, $val); - } - - return; - } - - if (strpos($key, '.') === false) { - $this->_config[$key] = $value; - - return; - } - - $update =& $this->_config; - $stack = explode('.', $key); - - foreach ($stack as $k) { - if (!is_array($update)) { - throw new Exception(sprintf('Cannot set %s value', $key)); - } - - if (!isset($update[$k])) { - $update[$k] = []; - } - - $update =& $update[$k]; - } - - $update = $value; - } - - /** - * Deletes a single config key. - * - * @param string $key Key to delete. - * @return void - * @throws \Cake\Core\Exception\Exception if attempting to clobber existing config - */ - protected function _configDelete($key) - { - if (strpos($key, '.') === false) { - unset($this->_config[$key]); - - return; - } - - $update =& $this->_config; - $stack = explode('.', $key); - $length = count($stack); - - foreach ($stack as $i => $k) { - if (!is_array($update)) { - throw new Exception(sprintf('Cannot unset %s value', $key)); - } - - if (!isset($update[$k])) { - break; - } - - if ($i === $length - 1) { - unset($update[$k]); - break; - } - - $update =& $update[$k]; - } - } -} diff --git a/vendor/cakephp/cakephp/src/Core/LICENSE.txt b/vendor/cakephp/cakephp/src/Core/LICENSE.txt deleted file mode 100644 index 0c4b793..0000000 --- a/vendor/cakephp/cakephp/src/Core/LICENSE.txt +++ /dev/null @@ -1,22 +0,0 @@ -The MIT License (MIT) - -CakePHP(tm) : The Rapid Development PHP Framework (https://cakephp.org) -Copyright (c) 2005-2016, Cake Software Foundation, Inc. (https://cakefoundation.org) - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. diff --git a/vendor/cakephp/cakephp/src/Core/ObjectRegistry.php b/vendor/cakephp/cakephp/src/Core/ObjectRegistry.php deleted file mode 100644 index ba21ce6..0000000 --- a/vendor/cakephp/cakephp/src/Core/ObjectRegistry.php +++ /dev/null @@ -1,391 +0,0 @@ - [ - * 'className' => '\App\Controller\Component\AliasedEmailComponent' - * ]; - * ]; - * ``` - * - * All calls to the `Email` component would use `AliasedEmail` instead. - * - * @param string $objectName The name/class of the object to load. - * @param array $config Additional settings to use when loading the object. - * @return mixed - */ - public function load($objectName, $config = []) - { - if (is_array($config) && isset($config['className'])) { - $name = $objectName; - $objectName = $config['className']; - } else { - list(, $name) = pluginSplit($objectName); - } - - $loaded = isset($this->_loaded[$name]); - if ($loaded && !empty($config)) { - $this->_checkDuplicate($name, $config); - } - if ($loaded) { - return $this->_loaded[$name]; - } - - $className = $this->_resolveClassName($objectName); - if (!$className || (is_string($className) && !class_exists($className))) { - list($plugin, $objectName) = pluginSplit($objectName); - $this->_throwMissingClassError($objectName, $plugin); - } - $instance = $this->_create($className, $name, $config); - $this->_loaded[$name] = $instance; - - return $instance; - } - - /** - * Check for duplicate object loading. - * - * If a duplicate is being loaded and has different configuration, that is - * bad and an exception will be raised. - * - * An exception is raised, as replacing the object will not update any - * references other objects may have. Additionally, simply updating the runtime - * configuration is not a good option as we may be missing important constructor - * logic dependent on the configuration. - * - * @param string $name The name of the alias in the registry. - * @param array $config The config data for the new instance. - * @return void - * @throws \RuntimeException When a duplicate is found. - */ - protected function _checkDuplicate($name, $config) - { - /** @var \Cake\Core\InstanceConfigTrait $existing */ - $existing = $this->_loaded[$name]; - $msg = sprintf('The "%s" alias has already been loaded', $name); - $hasConfig = method_exists($existing, 'config'); - if (!$hasConfig) { - throw new RuntimeException($msg); - } - if (empty($config)) { - return; - } - $existingConfig = $existing->getConfig(); - unset($config['enabled'], $existingConfig['enabled']); - - $fail = false; - foreach ($config as $key => $value) { - if (!array_key_exists($key, $existingConfig)) { - $fail = true; - break; - } - if (isset($existingConfig[$key]) && $existingConfig[$key] !== $value) { - $fail = true; - break; - } - } - if ($fail) { - $msg .= ' with the following config: '; - $msg .= var_export($existingConfig, true); - $msg .= ' which differs from ' . var_export($config, true); - throw new RuntimeException($msg); - } - } - - /** - * Should resolve the classname for a given object type. - * - * @param string $class The class to resolve. - * @return string|bool The resolved name or false for failure. - */ - abstract protected function _resolveClassName($class); - - /** - * Throw an exception when the requested object name is missing. - * - * @param string $class The class that is missing. - * @param string $plugin The plugin $class is missing from. - * @return void - * @throws \Exception - */ - abstract protected function _throwMissingClassError($class, $plugin); - - /** - * Create an instance of a given classname. - * - * This method should construct and do any other initialization logic - * required. - * - * @param string $class The class to build. - * @param string $alias The alias of the object. - * @param array $config The Configuration settings for construction - * @return mixed - */ - abstract protected function _create($class, $alias, $config); - - /** - * Get the list of loaded objects. - * - * @return array List of object names. - */ - public function loaded() - { - return array_keys($this->_loaded); - } - - /** - * Check whether or not a given object is loaded. - * - * @param string $name The object name to check for. - * @return bool True is object is loaded else false. - */ - public function has($name) - { - return isset($this->_loaded[$name]); - } - - /** - * Get loaded object instance. - * - * @param string $name Name of object. - * @return object|null Object instance if loaded else null. - */ - public function get($name) - { - if (isset($this->_loaded[$name])) { - return $this->_loaded[$name]; - } - - return null; - } - - /** - * Provide public read access to the loaded objects - * - * @param string $name Name of property to read - * @return mixed - */ - public function __get($name) - { - return $this->get($name); - } - - /** - * Provide isset access to _loaded - * - * @param string $name Name of object being checked. - * @return bool - */ - public function __isset($name) - { - return isset($this->_loaded[$name]); - } - - /** - * Sets an object. - * - * @param string $name Name of a property to set. - * @param mixed $object Object to set. - * @return void - */ - public function __set($name, $object) - { - $this->set($name, $object); - } - - /** - * Unsets an object. - * - * @param string $name Name of a property to unset. - * @return void - */ - public function __unset($name) - { - $this->unload($name); - } - - /** - * Normalizes an object array, creates an array that makes lazy loading - * easier - * - * @param array $objects Array of child objects to normalize. - * @return array Array of normalized objects. - */ - public function normalizeArray($objects) - { - $normal = []; - foreach ($objects as $i => $objectName) { - $config = []; - if (!is_int($i)) { - $config = (array)$objectName; - $objectName = $i; - } - list(, $name) = pluginSplit($objectName); - if (isset($config['class'])) { - $normal[$name] = $config; - } else { - $normal[$name] = ['class' => $objectName, 'config' => $config]; - } - } - - return $normal; - } - - /** - * Clear loaded instances in the registry. - * - * If the registry subclass has an event manager, the objects will be detached from events as well. - * - * @return $this - */ - public function reset() - { - foreach (array_keys($this->_loaded) as $name) { - $this->unload($name); - } - - return $this; - } - - /** - * Set an object directly into the registry by name. - * - * If this collection implements events, the passed object will - * be attached into the event manager - * - * @param string $objectName The name of the object to set in the registry. - * @param object $object instance to store in the registry - * @return $this - */ - public function set($objectName, $object) - { - list(, $name) = pluginSplit($objectName); - - // Just call unload if the object was loaded before - if (array_key_exists($objectName, $this->_loaded)) { - $this->unload($objectName); - } - if ($this instanceof EventDispatcherInterface && $object instanceof EventListenerInterface) { - $this->getEventManager()->on($object); - } - $this->_loaded[$name] = $object; - - return $this; - } - - /** - * Remove an object from the registry. - * - * If this registry has an event manager, the object will be detached from any events as well. - * - * @param string $objectName The name of the object to remove from the registry. - * @return $this - */ - public function unload($objectName) - { - if (empty($this->_loaded[$objectName])) { - list($plugin, $objectName) = pluginSplit($objectName); - $this->_throwMissingClassError($objectName, $plugin); - } - - $object = $this->_loaded[$objectName]; - if ($this instanceof EventDispatcherInterface && $object instanceof EventListenerInterface) { - $this->getEventManager()->off($object); - } - unset($this->_loaded[$objectName]); - - return $this; - } - - /** - * Returns an array iterator. - * - * @return \ArrayIterator - */ - public function getIterator() - { - return new ArrayIterator($this->_loaded); - } - - /** - * Returns the number of loaded objects. - * - * @return int - */ - public function count() - { - return count($this->_loaded); - } - - /** - * Debug friendly object properties. - * - * @return array - */ - public function __debugInfo() - { - $properties = get_object_vars($this); - if (isset($properties['_loaded'])) { - $properties['_loaded'] = array_keys($properties['_loaded']); - } - - return $properties; - } -} diff --git a/vendor/cakephp/cakephp/src/Core/Plugin.php b/vendor/cakephp/cakephp/src/Core/Plugin.php deleted file mode 100644 index e76fc40..0000000 --- a/vendor/cakephp/cakephp/src/Core/Plugin.php +++ /dev/null @@ -1,423 +0,0 @@ - true, 'routes' => true])` - * - * Will load the bootstrap.php and routes.php files. - * - * `Plugin::load('DebugKit', ['bootstrap' => false, 'routes' => true])` - * - * Will load routes.php file but not bootstrap.php - * - * `Plugin::load('FOC/Authenticate')` - * - * Will load plugin from `plugins/FOC/Authenticate`. - * - * It is also possible to load multiple plugins at once. Examples: - * - * `Plugin::load(['DebugKit', 'ApiGenerator'])` - * - * Will load the DebugKit and ApiGenerator plugins. - * - * `Plugin::load(['DebugKit', 'ApiGenerator'], ['bootstrap' => true])` - * - * Will load bootstrap file for both plugins - * - * ``` - * Plugin::load([ - * 'DebugKit' => ['routes' => true], - * 'ApiGenerator' - * ], - * ['bootstrap' => true]) - * ``` - * - * Will only load the bootstrap for ApiGenerator and only the routes for DebugKit - * - * ### Configuration options - * - * - `bootstrap` - array - Whether or not you want the $plugin/config/bootstrap.php file loaded. - * - `routes` - boolean - Whether or not you want to load the $plugin/config/routes.php file. - * - `ignoreMissing` - boolean - Set to true to ignore missing bootstrap/routes files. - * - `path` - string - The path the plugin can be found on. If empty the default plugin path (App.pluginPaths) will be used. - * - `classBase` - The path relative to `path` which contains the folders with class files. - * Defaults to "src". - * - `autoload` - boolean - Whether or not you want an autoloader registered. This defaults to false. The framework - * assumes you have configured autoloaders using composer. However, if your application source tree is made up of - * plugins, this can be a useful option. - * - * @param string|array $plugin name of the plugin to be loaded in CamelCase format or array or plugins to load - * @param array $config configuration options for the plugin - * @throws \Cake\Core\Exception\MissingPluginException if the folder for the plugin to be loaded is not found - * @return void - */ - public static function load($plugin, array $config = []) - { - if (is_array($plugin)) { - foreach ($plugin as $name => $conf) { - list($name, $conf) = is_numeric($name) ? [$conf, $config] : [$name, $conf]; - static::load($name, $conf); - } - - return; - } - - static::_loadConfig(); - - $config += [ - 'autoload' => false, - 'bootstrap' => false, - 'routes' => false, - 'console' => true, - 'classBase' => 'src', - 'ignoreMissing' => false, - 'name' => $plugin - ]; - - if (!isset($config['path'])) { - $config['path'] = Configure::read('plugins.' . $plugin); - } - - if (empty($config['path'])) { - $paths = App::path('Plugin'); - $pluginPath = str_replace('/', DIRECTORY_SEPARATOR, $plugin); - foreach ($paths as $path) { - if (is_dir($path . $pluginPath)) { - $config['path'] = $path . $pluginPath . DIRECTORY_SEPARATOR; - break; - } - } - } - - if (empty($config['path'])) { - throw new MissingPluginException(['plugin' => $plugin]); - } - - $config['classPath'] = $config['path'] . $config['classBase'] . DIRECTORY_SEPARATOR; - if (!isset($config['configPath'])) { - $config['configPath'] = $config['path'] . 'config' . DIRECTORY_SEPARATOR; - } - - // Use stub plugins as this method will be removed long term. - static::getCollection()->add(new BasePlugin($config)); - - if ($config['autoload'] === true) { - if (empty(static::$_loader)) { - static::$_loader = new ClassLoader(); - static::$_loader->register(); - } - static::$_loader->addNamespace( - str_replace('/', '\\', $plugin), - $config['path'] . $config['classBase'] . DIRECTORY_SEPARATOR - ); - static::$_loader->addNamespace( - str_replace('/', '\\', $plugin) . '\Test', - $config['path'] . 'tests' . DIRECTORY_SEPARATOR - ); - } - - if ($config['bootstrap'] === true) { - static::bootstrap($plugin); - } - } - - /** - * Load the plugin path configuration file. - * - * @return void - */ - protected static function _loadConfig() - { - if (Configure::check('plugins')) { - return; - } - $vendorFile = dirname(dirname(__DIR__)) . DIRECTORY_SEPARATOR . 'cakephp-plugins.php'; - if (!file_exists($vendorFile)) { - $vendorFile = dirname(dirname(dirname(dirname(__DIR__)))) . DIRECTORY_SEPARATOR . 'cakephp-plugins.php'; - if (!file_exists($vendorFile)) { - Configure::write(['plugins' => []]); - - return; - } - } - - $config = require $vendorFile; - Configure::write($config); - } - - /** - * Will load all the plugins located in the default plugin folder. - * - * If passed an options array, it will be used as a common default for all plugins to be loaded - * It is possible to set specific defaults for each plugins in the options array. Examples: - * - * ``` - * Plugin::loadAll([ - * ['bootstrap' => true], - * 'DebugKit' => ['routes' => true], - * ]); - * ``` - * - * The above example will load the bootstrap file for all plugins, but for DebugKit it will only load the routes file - * and will not look for any bootstrap script. - * - * If a plugin has been loaded already, it will not be reloaded by loadAll(). - * - * @param array $options Options. - * @return void - * @throws \Cake\Core\Exception\MissingPluginException - */ - public static function loadAll(array $options = []) - { - static::_loadConfig(); - $plugins = []; - foreach (App::path('Plugin') as $path) { - if (!is_dir($path)) { - continue; - } - $dir = new DirectoryIterator($path); - foreach ($dir as $dirPath) { - if ($dirPath->isDir() && !$dirPath->isDot()) { - $plugins[] = $dirPath->getBasename(); - } - } - } - if (Configure::check('plugins')) { - $plugins = array_merge($plugins, array_keys(Configure::read('plugins'))); - $plugins = array_unique($plugins); - } - - $collection = static::getCollection(); - foreach ($plugins as $p) { - $opts = isset($options[$p]) ? $options[$p] : null; - if ($opts === null && isset($options[0])) { - $opts = $options[0]; - } - if ($collection->has($p)) { - continue; - } - static::load($p, (array)$opts); - } - } - - /** - * Returns the filesystem path for a plugin - * - * @param string $name name of the plugin in CamelCase format - * @return string path to the plugin folder - * @throws \Cake\Core\Exception\MissingPluginException if the folder for plugin was not found or plugin has not been loaded - */ - public static function path($name) - { - $plugin = static::getCollection()->get($name); - - return $plugin->getPath(); - } - - /** - * Returns the filesystem path for plugin's folder containing class folders. - * - * @param string $name name of the plugin in CamelCase format. - * @return string Path to the plugin folder container class folders. - * @throws \Cake\Core\Exception\MissingPluginException If plugin has not been loaded. - */ - public static function classPath($name) - { - $plugin = static::getCollection()->get($name); - - return $plugin->getClassPath(); - } - - /** - * Returns the filesystem path for plugin's folder containing config files. - * - * @param string $name name of the plugin in CamelCase format. - * @return string Path to the plugin folder container config files. - * @throws \Cake\Core\Exception\MissingPluginException If plugin has not been loaded. - */ - public static function configPath($name) - { - $plugin = static::getCollection()->get($name); - - return $plugin->getConfigPath(); - } - - /** - * Loads the bootstrapping files for a plugin, or calls the initialization setup in the configuration - * - * @param string $name name of the plugin - * @return mixed - * @see \Cake\Core\Plugin::load() for examples of bootstrap configuration - */ - public static function bootstrap($name) - { - $plugin = static::getCollection()->get($name); - if (!$plugin->isEnabled('bootstrap')) { - return false; - } - // Disable bootstrapping for this plugin as it will have - // been bootstrapped. - $plugin->disable('bootstrap'); - - return static::_includeFile( - $plugin->getConfigPath() . 'bootstrap.php', - true - ); - } - - /** - * Loads the routes file for a plugin, or all plugins configured to load their respective routes file. - * - * If you need fine grained control over how routes are loaded for plugins, you - * can use {@see Cake\Routing\RouteBuilder::loadPlugin()} - * - * @param string|null $name name of the plugin, if null will operate on all - * plugins having enabled the loading of routes files. - * @return bool - */ - public static function routes($name = null) - { - if ($name === null) { - foreach (static::loaded() as $p) { - static::routes($p); - } - - return true; - } - $plugin = static::getCollection()->get($name); - if (!$plugin->isEnabled('routes')) { - return false; - } - - return (bool)static::_includeFile( - $plugin->getConfigPath() . 'routes.php', - true - ); - } - - /** - * Returns true if the plugin $plugin is already loaded - * If plugin is null, it will return a list of all loaded plugins - * - * @param string|null $plugin Plugin name. - * @return bool|array Boolean true if $plugin is already loaded. - * If $plugin is null, returns a list of plugins that have been loaded - */ - public static function loaded($plugin = null) - { - if ($plugin !== null) { - return static::getCollection()->has($plugin); - } - $names = []; - foreach (static::getCollection() as $plugin) { - $names[] = $plugin->getName(); - } - sort($names); - - return $names; - } - - /** - * Forgets a loaded plugin or all of them if first parameter is null - * - * @param string|null $plugin name of the plugin to forget - * @return void - */ - public static function unload($plugin = null) - { - if ($plugin === null) { - static::$plugins = null; - } else { - static::getCollection()->remove($plugin); - } - } - - /** - * Include file, ignoring include error if needed if file is missing - * - * @param string $file File to include - * @param bool $ignoreMissing Whether to ignore include error for missing files - * @return mixed - */ - protected static function _includeFile($file, $ignoreMissing = false) - { - if ($ignoreMissing && !is_file($file)) { - return false; - } - - return include $file; - } - - /** - * Get the shared plugin collection. - * - * @internal - * @return \Cake\Core\PluginCollection - */ - public static function getCollection() - { - if (!isset(static::$plugins)) { - static::$plugins = new PluginCollection(); - } - - return static::$plugins; - } -} diff --git a/vendor/cakephp/cakephp/src/Core/README.md b/vendor/cakephp/cakephp/src/Core/README.md deleted file mode 100644 index ca10e4f..0000000 --- a/vendor/cakephp/cakephp/src/Core/README.md +++ /dev/null @@ -1,37 +0,0 @@ -[![Total Downloads](https://img.shields.io/packagist/dt/cakephp/core.svg?style=flat-square)](https://packagist.org/packages/cakephp/core) -[![License](https://img.shields.io/badge/license-MIT-blue.svg?style=flat-square)](LICENSE.txt) - -# CakePHP Core Classes - -A set of classes used for configuration files reading and storing. -This repository contains the classes that are used as glue for creating the CakePHP framework. - -## Usage - -You can use the `Configure` class to store arbitrary configuration data: - -```php -use Cake\Core\Configure; -use Cake\Core\Configure\Engine\PhpConfig; - -Configure::write('Company.name','Pizza, Inc.'); -Configure::read('Company.name'); // Returns: 'Pizza, Inc.' -``` - -It also possible to load configuration from external files: - -```php -Configure::config('default', new PhpConfig('/path/to/config/folder')); -Configure::load('app', 'default', false); -Configure::load('other_config', 'default'); -``` - -And Write the configuration back into files: - -```php -Configure::dump('my_config', 'default'); -``` - -## Documentation - -Please make sure you check the [official documentation](https://book.cakephp.org/3.0/en/development/configuration.html) diff --git a/vendor/cakephp/cakephp/src/Core/StaticConfigTrait.php b/vendor/cakephp/cakephp/src/Core/StaticConfigTrait.php deleted file mode 100644 index feb4996..0000000 --- a/vendor/cakephp/cakephp/src/Core/StaticConfigTrait.php +++ /dev/null @@ -1,381 +0,0 @@ - configuration data for adapter. - * @throws \BadMethodCallException When trying to modify an existing config. - * @throws \LogicException When trying to store an invalid structured config array. - * @return void - */ - public static function setConfig($key, $config = null) - { - if ($config === null) { - if (!is_array($key)) { - throw new LogicException('If config is null, key must be an array.'); - } - foreach ($key as $name => $settings) { - static::setConfig($name, $settings); - } - - return; - } - - if (isset(static::$_config[$key])) { - throw new BadMethodCallException(sprintf('Cannot reconfigure existing key "%s"', $key)); - } - - if (is_object($config)) { - $config = ['className' => $config]; - } - - if (isset($config['url'])) { - $parsed = static::parseDsn($config['url']); - unset($config['url']); - $config = $parsed + $config; - } - - if (isset($config['engine']) && empty($config['className'])) { - $config['className'] = $config['engine']; - unset($config['engine']); - } - static::$_config[$key] = $config; - } - - /** - * Reads existing configuration. - * - * @param string $key The name of the configuration. - * @return array|null Array of configuration data. - */ - public static function getConfig($key) - { - return isset(static::$_config[$key]) ? static::$_config[$key] : null; - } - - /** - * This method can be used to define configuration adapters for an application - * or read existing configuration. - * - * To change an adapter's configuration at runtime, first drop the adapter and then - * reconfigure it. - * - * Adapters will not be constructed until the first operation is done. - * - * ### Usage - * - * Assuming that the class' name is `Cache` the following scenarios - * are supported: - * - * Reading config data back: - * - * ``` - * Cache::config('default'); - * ``` - * - * Setting a cache engine up. - * - * ``` - * Cache::config('default', $settings); - * ``` - * - * Injecting a constructed adapter in: - * - * ``` - * Cache::config('default', $instance); - * ``` - * - * Configure multiple adapters at once: - * - * ``` - * Cache::config($arrayOfConfig); - * ``` - * - * @deprecated 3.4.0 Use setConfig()/getConfig() instead. - * @param string|array $key The name of the configuration, or an array of multiple configs. - * @param array|null $config An array of name => configuration data for adapter. - * @return array|null Null when adding configuration or an array of configuration data when reading. - * @throws \BadMethodCallException When trying to modify an existing config. - */ - public static function config($key, $config = null) - { - deprecationWarning( - get_called_class() . '::config() is deprecated. ' . - 'Use setConfig()/getConfig() instead.' - ); - - if ($config !== null || is_array($key)) { - static::setConfig($key, $config); - - return null; - } - - return static::getConfig($key); - } - - /** - * Drops a constructed adapter. - * - * If you wish to modify an existing configuration, you should drop it, - * change configuration and then re-add it. - * - * If the implementing objects supports a `$_registry` object the named configuration - * will also be unloaded from the registry. - * - * @param string $config An existing configuration you wish to remove. - * @return bool Success of the removal, returns false when the config does not exist. - */ - public static function drop($config) - { - if (!isset(static::$_config[$config])) { - return false; - } - if (isset(static::$_registry)) { - static::$_registry->unload($config); - } - unset(static::$_config[$config]); - - return true; - } - - /** - * Returns an array containing the named configurations - * - * @return array Array of configurations. - */ - public static function configured() - { - return array_keys(static::$_config); - } - - /** - * Parses a DSN into a valid connection configuration - * - * This method allows setting a DSN using formatting similar to that used by PEAR::DB. - * The following is an example of its usage: - * - * ``` - * $dsn = 'mysql://user:pass@localhost/database?'; - * $config = ConnectionManager::parseDsn($dsn); - * - * $dsn = 'Cake\Log\Engine\FileLog://?types=notice,info,debug&file=debug&path=LOGS'; - * $config = Log::parseDsn($dsn); - * - * $dsn = 'smtp://user:secret@localhost:25?timeout=30&client=null&tls=null'; - * $config = Email::parseDsn($dsn); - * - * $dsn = 'file:///?className=\My\Cache\Engine\FileEngine'; - * $config = Cache::parseDsn($dsn); - * - * $dsn = 'File://?prefix=myapp_cake_core_&serialize=true&duration=+2 minutes&path=/tmp/persistent/'; - * $config = Cache::parseDsn($dsn); - * ``` - * - * For all classes, the value of `scheme` is set as the value of both the `className` - * unless they have been otherwise specified. - * - * Note that querystring arguments are also parsed and set as values in the returned configuration. - * - * @param string $dsn The DSN string to convert to a configuration array - * @return array The configuration array to be stored after parsing the DSN - * @throws \InvalidArgumentException If not passed a string, or passed an invalid string - */ - public static function parseDsn($dsn) - { - if (empty($dsn)) { - return []; - } - - if (!is_string($dsn)) { - throw new InvalidArgumentException('Only strings can be passed to parseDsn'); - } - - $pattern = <<<'REGEXP' -{ - ^ - (?P<_scheme> - (?P[\w\\\\]+):// - ) - (?P<_username> - (?P.*?) - (?P<_password> - :(?P.*?) - )? - @ - )? - (?P<_host> - (?P[^?#/:@]+) - (?P<_port> - :(?P\d+) - )? - )? - (?P<_path> - (?P/[^?#]*) - )? - (?P<_query> - \?(?P[^#]*) - )? - (?P<_fragment> - \#(?P.*) - )? - $ -}x -REGEXP; - - preg_match($pattern, $dsn, $parsed); - - if (!$parsed) { - throw new InvalidArgumentException("The DSN string '{$dsn}' could not be parsed."); - } - - $exists = []; - foreach ($parsed as $k => $v) { - if (is_int($k)) { - unset($parsed[$k]); - } elseif (strpos($k, '_') === 0) { - $exists[substr($k, 1)] = ($v !== ''); - unset($parsed[$k]); - } elseif ($v === '' && !$exists[$k]) { - unset($parsed[$k]); - } - } - - $query = ''; - - if (isset($parsed['query'])) { - $query = $parsed['query']; - unset($parsed['query']); - } - - parse_str($query, $queryArgs); - - foreach ($queryArgs as $key => $value) { - if ($value === 'true') { - $queryArgs[$key] = true; - } elseif ($value === 'false') { - $queryArgs[$key] = false; - } elseif ($value === 'null') { - $queryArgs[$key] = null; - } - } - - $parsed = $queryArgs + $parsed; - - if (empty($parsed['className'])) { - $classMap = static::getDsnClassMap(); - - $parsed['className'] = $parsed['scheme']; - if (isset($classMap[$parsed['scheme']])) { - $parsed['className'] = $classMap[$parsed['scheme']]; - } - } - - return $parsed; - } - - /** - * Updates the DSN class map for this class. - * - * @param array $map Additions/edits to the class map to apply. - * @return void - */ - public static function setDsnClassMap(array $map) - { - static::$_dsnClassMap = $map + static::$_dsnClassMap; - } - - /** - * Returns the DSN class map for this class. - * - * @return array - */ - public static function getDsnClassMap() - { - return static::$_dsnClassMap; - } - - /** - * Returns or updates the DSN class map for this class. - * - * @deprecated 3.4.0 Use setDsnClassMap()/getDsnClassMap() instead. - * @param array|null $map Additions/edits to the class map to apply. - * @return array - */ - public static function dsnClassMap(array $map = null) - { - deprecationWarning( - get_called_class() . '::setDsnClassMap() is deprecated. ' . - 'Use setDsnClassMap()/getDsnClassMap() instead.' - ); - - if ($map !== null) { - static::setDsnClassMap($map); - } - - return static::getDsnClassMap(); - } -} diff --git a/vendor/cakephp/cakephp/src/Core/composer.json b/vendor/cakephp/cakephp/src/Core/composer.json deleted file mode 100644 index 3a48585..0000000 --- a/vendor/cakephp/cakephp/src/Core/composer.json +++ /dev/null @@ -1,39 +0,0 @@ -{ - "name": "cakephp/core", - "description": "CakePHP Framework Core classes", - "type": "library", - "keywords": [ - "cakephp", - "framework", - "core" - ], - "homepage": "https://cakephp.org", - "license": "MIT", - "authors": [ - { - "name": "CakePHP Community", - "homepage": "https://github.com/cakephp/core/graphs/contributors" - } - ], - "support": { - "issues": "https://github.com/cakephp/cakephp/issues", - "forum": "https://stackoverflow.com/tags/cakephp", - "irc": "irc://irc.freenode.org/cakephp", - "source": "https://github.com/cakephp/core" - }, - "require": { - "php": ">=5.6.0", - "cakephp/utility": "^3.6.0" - }, - "suggest": { - "cakephp/event": "To use PluginApplicationInterface or plugin applications." - }, - "autoload": { - "psr-4": { - "Cake\\Core\\": "." - }, - "files": [ - "functions.php" - ] - } -} diff --git a/vendor/cakephp/cakephp/src/Core/functions.php b/vendor/cakephp/cakephp/src/Core/functions.php deleted file mode 100644 index d73eb06..0000000 --- a/vendor/cakephp/cakephp/src/Core/functions.php +++ /dev/null @@ -1,322 +0,0 @@ - $t) { - $texts[$k] = h($t, $double, $charset); - } - - return $texts; - } elseif (is_object($text)) { - if (method_exists($text, '__toString')) { - $text = (string)$text; - } else { - $text = '(object)' . get_class($text); - } - } elseif (is_bool($text) || is_null($text) || is_int($text)) { - return $text; - } - - static $defaultCharset = false; - if ($defaultCharset === false) { - $defaultCharset = mb_internal_encoding(); - if ($defaultCharset === null) { - $defaultCharset = 'UTF-8'; - } - } - if (is_string($double)) { - $charset = $double; - } - - return htmlspecialchars($text, ENT_QUOTES | ENT_SUBSTITUTE, $charset ?: $defaultCharset, $double); - } - -} - -if (!function_exists('pluginSplit')) { - /** - * Splits a dot syntax plugin name into its plugin and class name. - * If $name does not have a dot, then index 0 will be null. - * - * Commonly used like - * ``` - * list($plugin, $name) = pluginSplit($name); - * ``` - * - * @param string $name The name you want to plugin split. - * @param bool $dotAppend Set to true if you want the plugin to have a '.' appended to it. - * @param string|null $plugin Optional default plugin to use if no plugin is found. Defaults to null. - * @return array Array with 2 indexes. 0 => plugin name, 1 => class name. - * @link https://book.cakephp.org/3.0/en/core-libraries/global-constants-and-functions.html#pluginSplit - */ - function pluginSplit($name, $dotAppend = false, $plugin = null) - { - if (strpos($name, '.') !== false) { - $parts = explode('.', $name, 2); - if ($dotAppend) { - $parts[0] .= '.'; - } - - return $parts; - } - - return [$plugin, $name]; - } - -} - -if (!function_exists('namespaceSplit')) { - /** - * Split the namespace from the classname. - * - * Commonly used like `list($namespace, $className) = namespaceSplit($class);`. - * - * @param string $class The full class name, ie `Cake\Core\App`. - * @return array Array with 2 indexes. 0 => namespace, 1 => classname. - */ - function namespaceSplit($class) - { - $pos = strrpos($class, '\\'); - if ($pos === false) { - return ['', $class]; - } - - return [substr($class, 0, $pos), substr($class, $pos + 1)]; - } - -} - -if (!function_exists('pr')) { - /** - * print_r() convenience function. - * - * In terminals this will act similar to using print_r() directly, when not run on cli - * print_r() will also wrap
 tags around the output of given variable. Similar to debug().
-     *
-     * This function returns the same variable that was passed.
-     *
-     * @param mixed $var Variable to print out.
-     * @return mixed the same $var that was passed to this function
-     * @link https://book.cakephp.org/3.0/en/core-libraries/global-constants-and-functions.html#pr
-     * @see debug()
-     */
-    function pr($var)
-    {
-        if (!Configure::read('debug')) {
-            return $var;
-        }
-
-        $template = (PHP_SAPI !== 'cli' && PHP_SAPI !== 'phpdbg') ? '
%s
' : "\n%s\n\n"; - printf($template, trim(print_r($var, true))); - - return $var; - } - -} - -if (!function_exists('pj')) { - /** - * json pretty print convenience function. - * - * In terminals this will act similar to using json_encode() with JSON_PRETTY_PRINT directly, when not run on cli - * will also wrap
 tags around the output of given variable. Similar to pr().
-     *
-     * This function returns the same variable that was passed.
-     *
-     * @param mixed $var Variable to print out.
-     * @return mixed the same $var that was passed to this function
-     * @see pr()
-     * @link https://book.cakephp.org/3.0/en/core-libraries/global-constants-and-functions.html#pj
-     */
-    function pj($var)
-    {
-        if (!Configure::read('debug')) {
-            return $var;
-        }
-
-        $template = (PHP_SAPI !== 'cli' && PHP_SAPI !== 'phpdbg') ? '
%s
' : "\n%s\n\n"; - printf($template, trim(json_encode($var, JSON_PRETTY_PRINT))); - - return $var; - } - -} - -if (!function_exists('env')) { - /** - * Gets an environment variable from available sources, and provides emulation - * for unsupported or inconsistent environment variables (i.e. DOCUMENT_ROOT on - * IIS, or SCRIPT_NAME in CGI mode). Also exposes some additional custom - * environment information. - * - * @param string $key Environment variable name. - * @param string|null $default Specify a default value in case the environment variable is not defined. - * @return string|bool|null Environment variable setting. - * @link https://book.cakephp.org/3.0/en/core-libraries/global-constants-and-functions.html#env - */ - function env($key, $default = null) - { - if ($key === 'HTTPS') { - if (isset($_SERVER['HTTPS'])) { - return (!empty($_SERVER['HTTPS']) && $_SERVER['HTTPS'] !== 'off'); - } - - return (strpos((string)env('SCRIPT_URI'), 'https://') === 0); - } - - if ($key === 'SCRIPT_NAME') { - if (env('CGI_MODE') && isset($_ENV['SCRIPT_URL'])) { - $key = 'SCRIPT_URL'; - } - } - - $val = null; - if (isset($_SERVER[$key])) { - $val = $_SERVER[$key]; - } elseif (isset($_ENV[$key])) { - $val = $_ENV[$key]; - } elseif (getenv($key) !== false) { - $val = getenv($key); - } - - if ($key === 'REMOTE_ADDR' && $val === env('SERVER_ADDR')) { - $addr = env('HTTP_PC_REMOTE_ADDR'); - if ($addr !== null) { - $val = $addr; - } - } - - if ($val !== null) { - return $val; - } - - switch ($key) { - case 'DOCUMENT_ROOT': - $name = env('SCRIPT_NAME'); - $filename = env('SCRIPT_FILENAME'); - $offset = 0; - if (!strpos($name, '.php')) { - $offset = 4; - } - - return substr($filename, 0, -(strlen($name) + $offset)); - case 'PHP_SELF': - return str_replace(env('DOCUMENT_ROOT'), '', env('SCRIPT_FILENAME')); - case 'CGI_MODE': - return (PHP_SAPI === 'cgi'); - } - - return $default; - } - -} - -if (!function_exists('triggerWarning')) { - /** - * Triggers an E_USER_WARNING. - * - * @param string $message The warning message. - * @return void - */ - function triggerWarning($message) - { - $stackFrame = 1; - $trace = debug_backtrace(); - if (isset($trace[$stackFrame])) { - $frame = $trace[$stackFrame]; - $frame += ['file' => '[internal]', 'line' => '??']; - $message = sprintf( - '%s - %s, line: %s', - $message, - $frame['file'], - $frame['line'] - ); - } - trigger_error($message, E_USER_WARNING); - } -} - -if (!function_exists('deprecationWarning')) { - /** - * Helper method for outputting deprecation warnings - * - * @param string $message The message to output as a deprecation warning. - * @param int $stackFrame The stack frame to include in the error. Defaults to 1 - * as that should point to application/plugin code. - * @return void - */ - function deprecationWarning($message, $stackFrame = 1) - { - if (!(error_reporting() & E_USER_DEPRECATED)) { - return; - } - - $trace = debug_backtrace(); - if (isset($trace[$stackFrame])) { - $frame = $trace[$stackFrame]; - $frame += ['file' => '[internal]', 'line' => '??']; - - $message = sprintf( - '%s - %s, line: %s' . "\n" . - ' You can disable deprecation warnings by setting `Error.errorLevel` to' . - ' `E_ALL & ~E_USER_DEPRECATED` in your config/app.php.', - $message, - $frame['file'], - $frame['line'] - ); - } - - trigger_error($message, E_USER_DEPRECATED); - } -} - -if (!function_exists('getTypeName')) { - /** - * Returns the objects class or var type of it's not an object - * - * @param mixed $var Variable to check - * @return string Returns the class name or variable type - */ - function getTypeName($var) - { - return is_object($var) ? get_class($var) : gettype($var); - } -} diff --git a/vendor/cakephp/cakephp/src/Database/Connection.php b/vendor/cakephp/cakephp/src/Database/Connection.php deleted file mode 100644 index 62a7411..0000000 --- a/vendor/cakephp/cakephp/src/Database/Connection.php +++ /dev/null @@ -1,960 +0,0 @@ -_config = $config; - - $driver = ''; - if (!empty($config['driver'])) { - $driver = $config['driver']; - } - $this->setDriver($driver, $config); - - if (!empty($config['log'])) { - $this->logQueries($config['log']); - } - } - - /** - * Destructor - * - * Disconnects the driver to release the connection. - */ - public function __destruct() - { - if ($this->_transactionStarted && class_exists('Cake\Log\Log')) { - Log::warning('The connection is going to be closed but there is an active transaction.'); - } - } - - /** - * {@inheritDoc} - */ - public function config() - { - return $this->_config; - } - - /** - * {@inheritDoc} - */ - public function configName() - { - if (empty($this->_config['name'])) { - return ''; - } - - return $this->_config['name']; - } - - /** - * Sets the driver instance. If a string is passed it will be treated - * as a class name and will be instantiated. - * - * @param \Cake\Database\Driver|string $driver The driver instance to use. - * @param array $config Config for a new driver. - * @throws \Cake\Database\Exception\MissingDriverException When a driver class is missing. - * @throws \Cake\Database\Exception\MissingExtensionException When a driver's PHP extension is missing. - * @return $this - */ - public function setDriver($driver, $config = []) - { - if (is_string($driver)) { - $className = App::className($driver, 'Database/Driver'); - if (!$className || !class_exists($className)) { - throw new MissingDriverException(['driver' => $driver]); - } - $driver = new $className($config); - } - if (!$driver->enabled()) { - throw new MissingExtensionException(['driver' => get_class($driver)]); - } - - $this->_driver = $driver; - - return $this; - } - - /** - * Get the retry wrapper object that is allows recovery from server disconnects - * while performing certain database actions, such as executing a query. - * - * @return \Cake\Core\Retry\CommandRetry The retry wrapper - */ - public function getDisconnectRetry() - { - return new CommandRetry(new ReconnectStrategy($this)); - } - - /** - * Gets the driver instance. - * - * @return \Cake\Database\Driver - */ - public function getDriver() - { - return $this->_driver; - } - - /** - * Sets the driver instance. If a string is passed it will be treated - * as a class name and will be instantiated. - * - * If no params are passed it will return the current driver instance. - * - * @deprecated 3.4.0 Use setDriver()/getDriver() instead. - * @param \Cake\Database\Driver|string|null $driver The driver instance to use. - * @param array $config Either config for a new driver or null. - * @throws \Cake\Database\Exception\MissingDriverException When a driver class is missing. - * @throws \Cake\Database\Exception\MissingExtensionException When a driver's PHP extension is missing. - * @return \Cake\Database\Driver - */ - public function driver($driver = null, $config = []) - { - deprecationWarning('Connection::driver() is deprecated. Use Connection::setDriver()/getDriver() instead.'); - if ($driver !== null) { - $this->setDriver($driver, $config); - } - - return $this->getDriver(); - } - - /** - * Connects to the configured database. - * - * @throws \Cake\Database\Exception\MissingConnectionException if credentials are invalid. - * @return bool true, if the connection was already established or the attempt was successful. - */ - public function connect() - { - try { - return $this->_driver->connect(); - } catch (Exception $e) { - throw new MissingConnectionException(['reason' => $e->getMessage()], null, $e); - } - } - - /** - * Disconnects from database server. - * - * @return void - */ - public function disconnect() - { - $this->_driver->disconnect(); - } - - /** - * Returns whether connection to database server was already established. - * - * @return bool - */ - public function isConnected() - { - return $this->_driver->isConnected(); - } - - /** - * Prepares a SQL statement to be executed. - * - * @param string|\Cake\Database\Query $sql The SQL to convert into a prepared statement. - * @return \Cake\Database\StatementInterface - */ - public function prepare($sql) - { - return $this->getDisconnectRetry()->run(function () use ($sql) { - $statement = $this->_driver->prepare($sql); - - if ($this->_logQueries) { - $statement = $this->_newLogger($statement); - } - - return $statement; - }); - } - - /** - * Executes a query using $params for interpolating values and $types as a hint for each - * those params. - * - * @param string $query SQL to be executed and interpolated with $params - * @param array $params list or associative array of params to be interpolated in $query as values - * @param array $types list or associative array of types to be used for casting values in query - * @return \Cake\Database\StatementInterface executed statement - */ - public function execute($query, array $params = [], array $types = []) - { - return $this->getDisconnectRetry()->run(function () use ($query, $params, $types) { - if (!empty($params)) { - $statement = $this->prepare($query); - $statement->bind($params, $types); - $statement->execute(); - } else { - $statement = $this->query($query); - } - - return $statement; - }); - } - - /** - * Compiles a Query object into a SQL string according to the dialect for this - * connection's driver - * - * @param \Cake\Database\Query $query The query to be compiled - * @param \Cake\Database\ValueBinder $generator The placeholder generator to use - * @return string - */ - public function compileQuery(Query $query, ValueBinder $generator) - { - return $this->getDriver()->compileQuery($query, $generator)[1]; - } - - /** - * Executes the provided query after compiling it for the specific driver - * dialect and returns the executed Statement object. - * - * @param \Cake\Database\Query $query The query to be executed - * @return \Cake\Database\StatementInterface executed statement - */ - public function run(Query $query) - { - return $this->getDisconnectRetry()->run(function () use ($query) { - $statement = $this->prepare($query); - $query->getValueBinder()->attachTo($statement); - $statement->execute(); - - return $statement; - }); - } - - /** - * Executes a SQL statement and returns the Statement object as result. - * - * @param string $sql The SQL query to execute. - * @return \Cake\Database\StatementInterface - */ - public function query($sql) - { - return $this->getDisconnectRetry()->run(function () use ($sql) { - $statement = $this->prepare($sql); - $statement->execute(); - - return $statement; - }); - } - - /** - * Create a new Query instance for this connection. - * - * @return \Cake\Database\Query - */ - public function newQuery() - { - return new Query($this); - } - - /** - * Sets a Schema\Collection object for this connection. - * - * @param \Cake\Database\Schema\Collection $collection The schema collection object - * @return $this - */ - public function setSchemaCollection(SchemaCollection $collection) - { - $this->_schemaCollection = $collection; - - return $this; - } - - /** - * Gets a Schema\Collection object for this connection. - * - * @return \Cake\Database\Schema\Collection - */ - public function getSchemaCollection() - { - if ($this->_schemaCollection !== null) { - return $this->_schemaCollection; - } - - if (!empty($this->_config['cacheMetadata'])) { - return $this->_schemaCollection = new CachedCollection($this, $this->_config['cacheMetadata']); - } - - return $this->_schemaCollection = new SchemaCollection($this); - } - - /** - * Gets or sets a Schema\Collection object for this connection. - * - * @deprecated 3.4.0 Use setSchemaCollection()/getSchemaCollection() - * @param \Cake\Database\Schema\Collection|null $collection The schema collection object - * @return \Cake\Database\Schema\Collection - */ - public function schemaCollection(SchemaCollection $collection = null) - { - deprecationWarning( - 'Connection::schemaCollection() is deprecated. ' . - 'Use Connection::setSchemaCollection()/getSchemaCollection() instead.' - ); - if ($collection !== null) { - $this->setSchemaCollection($collection); - } - - return $this->getSchemaCollection(); - } - - /** - * Executes an INSERT query on the specified table. - * - * @param string $table the table to insert values in - * @param array $data values to be inserted - * @param array $types list of associative array containing the types to be used for casting - * @return \Cake\Database\StatementInterface - */ - public function insert($table, array $data, array $types = []) - { - return $this->getDisconnectRetry()->run(function () use ($table, $data, $types) { - $columns = array_keys($data); - - return $this->newQuery()->insert($columns, $types) - ->into($table) - ->values($data) - ->execute(); - }); - } - - /** - * Executes an UPDATE statement on the specified table. - * - * @param string $table the table to update rows from - * @param array $data values to be updated - * @param array $conditions conditions to be set for update statement - * @param array $types list of associative array containing the types to be used for casting - * @return \Cake\Database\StatementInterface - */ - public function update($table, array $data, array $conditions = [], $types = []) - { - return $this->getDisconnectRetry()->run(function () use ($table, $data, $conditions, $types) { - return $this->newQuery()->update($table) - ->set($data, $types) - ->where($conditions, $types) - ->execute(); - }); - } - - /** - * Executes a DELETE statement on the specified table. - * - * @param string $table the table to delete rows from - * @param array $conditions conditions to be set for delete statement - * @param array $types list of associative array containing the types to be used for casting - * @return \Cake\Database\StatementInterface - */ - public function delete($table, $conditions = [], $types = []) - { - return $this->getDisconnectRetry()->run(function () use ($table, $conditions, $types) { - return $this->newQuery()->delete($table) - ->where($conditions, $types) - ->execute(); - }); - } - - /** - * Starts a new transaction. - * - * @return void - */ - public function begin() - { - if (!$this->_transactionStarted) { - if ($this->_logQueries) { - $this->log('BEGIN'); - } - - $this->getDisconnectRetry()->run(function () { - $this->_driver->beginTransaction(); - }); - - $this->_transactionLevel = 0; - $this->_transactionStarted = true; - $this->nestedTransactionRollbackException = null; - - return; - } - - $this->_transactionLevel++; - if ($this->isSavePointsEnabled()) { - $this->createSavePoint((string)$this->_transactionLevel); - } - } - - /** - * Commits current transaction. - * - * @return bool true on success, false otherwise - */ - public function commit() - { - if (!$this->_transactionStarted) { - return false; - } - - if ($this->_transactionLevel === 0) { - if ($this->wasNestedTransactionRolledback()) { - $e = $this->nestedTransactionRollbackException; - $this->nestedTransactionRollbackException = null; - throw $e; - } - - $this->_transactionStarted = false; - $this->nestedTransactionRollbackException = null; - if ($this->_logQueries) { - $this->log('COMMIT'); - } - - return $this->_driver->commitTransaction(); - } - if ($this->isSavePointsEnabled()) { - $this->releaseSavePoint((string)$this->_transactionLevel); - } - - $this->_transactionLevel--; - - return true; - } - - /** - * Rollback current transaction. - * - * @param bool|null $toBeginning Whether or not the transaction should be rolled back to the - * beginning of it. Defaults to false if using savepoints, or true if not. - * @return bool - */ - public function rollback($toBeginning = null) - { - if (!$this->_transactionStarted) { - return false; - } - - $useSavePoint = $this->isSavePointsEnabled(); - if ($toBeginning === null) { - $toBeginning = !$useSavePoint; - } - if ($this->_transactionLevel === 0 || $toBeginning) { - $this->_transactionLevel = 0; - $this->_transactionStarted = false; - $this->nestedTransactionRollbackException = null; - if ($this->_logQueries) { - $this->log('ROLLBACK'); - } - $this->_driver->rollbackTransaction(); - - return true; - } - - $savePoint = $this->_transactionLevel--; - if ($useSavePoint) { - $this->rollbackSavepoint($savePoint); - } elseif ($this->nestedTransactionRollbackException === null) { - $this->nestedTransactionRollbackException = new NestedTransactionRollbackException(); - } - - return true; - } - - /** - * Enables/disables the usage of savepoints, enables only if driver the allows it. - * - * If you are trying to enable this feature, make sure you check the return value of this - * function to verify it was enabled successfully. - * - * ### Example: - * - * `$connection->enableSavePoints(true)` Returns true if drivers supports save points, false otherwise - * `$connection->enableSavePoints(false)` Disables usage of savepoints and returns false - * - * @param bool $enable Whether or not save points should be used. - * @return $this - */ - public function enableSavePoints($enable) - { - if ($enable === false) { - $this->_useSavePoints = false; - } else { - $this->_useSavePoints = $this->_driver->supportsSavePoints(); - } - - return $this; - } - - /** - * Returns whether this connection is using savepoints for nested transactions - * - * @return bool true if enabled, false otherwise - */ - public function isSavePointsEnabled() - { - return $this->_useSavePoints; - } - - /** - * Returns whether this connection is using savepoints for nested transactions - * If a boolean is passed as argument it will enable/disable the usage of savepoints - * only if driver the allows it. - * - * If you are trying to enable this feature, make sure you check the return value of this - * function to verify it was enabled successfully. - * - * ### Example: - * - * `$connection->useSavePoints(true)` Returns true if drivers supports save points, false otherwise - * `$connection->useSavePoints(false)` Disables usage of savepoints and returns false - * `$connection->useSavePoints()` Returns current status - * - * @deprecated 3.4.0 Use enableSavePoints()/isSavePointsEnabled() instead. - * @param bool|null $enable Whether or not save points should be used. - * @return bool true if enabled, false otherwise - */ - public function useSavePoints($enable = null) - { - deprecationWarning( - 'Connection::useSavePoints() is deprecated. ' . - 'Use Connection::enableSavePoints()/isSavePointsEnabled() instead.' - ); - if ($enable !== null) { - $this->enableSavePoints($enable); - } - - return $this->isSavePointsEnabled(); - } - - /** - * Creates a new save point for nested transactions. - * - * @param string $name The save point name. - * @return void - */ - public function createSavePoint($name) - { - $this->execute($this->_driver->savePointSQL($name))->closeCursor(); - } - - /** - * Releases a save point by its name. - * - * @param string $name The save point name. - * @return void - */ - public function releaseSavePoint($name) - { - $this->execute($this->_driver->releaseSavePointSQL($name))->closeCursor(); - } - - /** - * Rollback a save point by its name. - * - * @param string $name The save point name. - * @return void - */ - public function rollbackSavepoint($name) - { - $this->execute($this->_driver->rollbackSavePointSQL($name))->closeCursor(); - } - - /** - * Run driver specific SQL to disable foreign key checks. - * - * @return void - */ - public function disableForeignKeys() - { - $this->getDisconnectRetry()->run(function () { - $this->execute($this->_driver->disableForeignKeySQL())->closeCursor(); - }); - } - - /** - * Run driver specific SQL to enable foreign key checks. - * - * @return void - */ - public function enableForeignKeys() - { - $this->getDisconnectRetry()->run(function () { - $this->execute($this->_driver->enableForeignKeySQL())->closeCursor(); - }); - } - - /** - * Returns whether the driver supports adding or dropping constraints - * to already created tables. - * - * @return bool true if driver supports dynamic constraints - */ - public function supportsDynamicConstraints() - { - return $this->_driver->supportsDynamicConstraints(); - } - - /** - * {@inheritDoc} - * - * ### Example: - * - * ``` - * $connection->transactional(function ($connection) { - * $connection->newQuery()->delete('users')->execute(); - * }); - * ``` - */ - public function transactional(callable $callback) - { - $this->begin(); - - try { - $result = $callback($this); - } catch (Exception $e) { - $this->rollback(false); - throw $e; - } - - if ($result === false) { - $this->rollback(false); - - return false; - } - - try { - $this->commit(); - } catch (NestedTransactionRollbackException $e) { - $this->rollback(false); - throw $e; - } - - return $result; - } - - /** - * Returns whether some nested transaction has been already rolled back. - * - * @return bool - */ - protected function wasNestedTransactionRolledback() - { - return $this->nestedTransactionRollbackException instanceof NestedTransactionRollbackException; - } - - /** - * {@inheritDoc} - * - * ### Example: - * - * ``` - * $connection->disableConstraints(function ($connection) { - * $connection->newQuery()->delete('users')->execute(); - * }); - * ``` - */ - public function disableConstraints(callable $callback) - { - return $this->getDisconnectRetry()->run(function () use ($callback) { - $this->disableForeignKeys(); - - try { - $result = $callback($this); - } catch (Exception $e) { - $this->enableForeignKeys(); - throw $e; - } - - $this->enableForeignKeys(); - - return $result; - }); - } - - /** - * Checks if a transaction is running. - * - * @return bool True if a transaction is running else false. - */ - public function inTransaction() - { - return $this->_transactionStarted; - } - - /** - * Quotes value to be used safely in database query. - * - * @param mixed $value The value to quote. - * @param string|null $type Type to be used for determining kind of quoting to perform - * @return string Quoted value - */ - public function quote($value, $type = null) - { - list($value, $type) = $this->cast($value, $type); - - return $this->_driver->quote($value, $type); - } - - /** - * Checks if the driver supports quoting. - * - * @return bool - */ - public function supportsQuoting() - { - return $this->_driver->supportsQuoting(); - } - - /** - * Quotes a database identifier (a column name, table name, etc..) to - * be used safely in queries without the risk of using reserved words. - * - * @param string $identifier The identifier to quote. - * @return string - */ - public function quoteIdentifier($identifier) - { - return $this->_driver->quoteIdentifier($identifier); - } - - /** - * Enables or disables metadata caching for this connection - * - * Changing this setting will not modify existing schema collections objects. - * - * @param bool|string $cache Either boolean false to disable metadata caching, or - * true to use `_cake_model_` or the name of the cache config to use. - * @return void - */ - public function cacheMetadata($cache) - { - $this->_schemaCollection = null; - $this->_config['cacheMetadata'] = $cache; - } - - /** - * {@inheritDoc} - */ - public function logQueries($enable = null) - { - if ($enable === null) { - return $this->_logQueries; - } - $this->_logQueries = $enable; - } - - /** - * {@inheritDoc} - * - * @deprecated 3.5.0 Use getLogger() and setLogger() instead. - */ - public function logger($instance = null) - { - deprecationWarning( - 'Connection::logger() is deprecated. ' . - 'Use Connection::setLogger()/getLogger() instead.' - ); - if ($instance === null) { - return $this->getLogger(); - } - - $this->setLogger($instance); - } - - /** - * Sets a logger - * - * @param \Cake\Database\Log\QueryLogger $logger Logger object - * @return $this - */ - public function setLogger($logger) - { - $this->_logger = $logger; - - return $this; - } - - /** - * Gets the logger object - * - * @return \Cake\Database\Log\QueryLogger logger instance - */ - public function getLogger() - { - if ($this->_logger === null) { - $this->_logger = new QueryLogger(); - } - - return $this->_logger; - } - - /** - * Logs a Query string using the configured logger object. - * - * @param string $sql string to be logged - * @return void - */ - public function log($sql) - { - $query = new LoggedQuery(); - $query->query = $sql; - $this->getLogger()->log($query); - } - - /** - * Returns a new statement object that will log the activity - * for the passed original statement instance. - * - * @param \Cake\Database\StatementInterface $statement the instance to be decorated - * @return \Cake\Database\Log\LoggingStatement - */ - protected function _newLogger(StatementInterface $statement) - { - $log = new LoggingStatement($statement, $this->_driver); - $log->setLogger($this->getLogger()); - - return $log; - } - - /** - * Returns an array that can be used to describe the internal state of this - * object. - * - * @return array - */ - public function __debugInfo() - { - $secrets = [ - 'password' => '*****', - 'username' => '*****', - 'host' => '*****', - 'database' => '*****', - 'port' => '*****' - ]; - $replace = array_intersect_key($secrets, $this->_config); - $config = $replace + $this->_config; - - return [ - 'config' => $config, - 'driver' => $this->_driver, - 'transactionLevel' => $this->_transactionLevel, - 'transactionStarted' => $this->_transactionStarted, - 'useSavePoints' => $this->_useSavePoints, - 'logQueries' => $this->_logQueries, - 'logger' => $this->_logger - ]; - } -} diff --git a/vendor/cakephp/cakephp/src/Database/Dialect/MysqlDialectTrait.php b/vendor/cakephp/cakephp/src/Database/Dialect/MysqlDialectTrait.php deleted file mode 100644 index a696690..0000000 --- a/vendor/cakephp/cakephp/src/Database/Dialect/MysqlDialectTrait.php +++ /dev/null @@ -1,84 +0,0 @@ -_schemaDialect) { - $this->_schemaDialect = new MysqlSchema($this); - } - - return $this->_schemaDialect; - } - - /** - * {@inheritDoc} - */ - public function disableForeignKeySQL() - { - return 'SET foreign_key_checks = 0'; - } - - /** - * {@inheritDoc} - */ - public function enableForeignKeySQL() - { - return 'SET foreign_key_checks = 1'; - } -} diff --git a/vendor/cakephp/cakephp/src/Database/Dialect/PostgresDialectTrait.php b/vendor/cakephp/cakephp/src/Database/Dialect/PostgresDialectTrait.php deleted file mode 100644 index 3f3e5f4..0000000 --- a/vendor/cakephp/cakephp/src/Database/Dialect/PostgresDialectTrait.php +++ /dev/null @@ -1,189 +0,0 @@ -clause('epilog')) { - $query->epilog('RETURNING *'); - } - - return $query; - } - - /** - * Returns a dictionary of expressions to be transformed when compiling a Query - * to SQL. Array keys are method names to be called in this class - * - * @return array - */ - protected function _expressionTranslators() - { - $namespace = 'Cake\Database\Expression'; - - return [ - $namespace . '\FunctionExpression' => '_transformFunctionExpression' - ]; - } - - /** - * Receives a FunctionExpression and changes it so that it conforms to this - * SQL dialect. - * - * @param \Cake\Database\Expression\FunctionExpression $expression The function expression to convert - * to postgres SQL. - * @return void - */ - protected function _transformFunctionExpression(FunctionExpression $expression) - { - switch ($expression->getName()) { - case 'CONCAT': - // CONCAT function is expressed as exp1 || exp2 - $expression->setName('')->setConjunction(' ||'); - break; - case 'DATEDIFF': - $expression - ->setName('') - ->setConjunction('-') - ->iterateParts(function ($p) { - if (is_string($p)) { - $p = ['value' => [$p => 'literal'], 'type' => null]; - } else { - $p['value'] = [$p['value']]; - } - - return new FunctionExpression('DATE', $p['value'], [$p['type']]); - }); - break; - case 'CURRENT_DATE': - $time = new FunctionExpression('LOCALTIMESTAMP', [' 0 ' => 'literal']); - $expression->setName('CAST')->setConjunction(' AS ')->add([$time, 'date' => 'literal']); - break; - case 'CURRENT_TIME': - $time = new FunctionExpression('LOCALTIMESTAMP', [' 0 ' => 'literal']); - $expression->setName('CAST')->setConjunction(' AS ')->add([$time, 'time' => 'literal']); - break; - case 'NOW': - $expression->setName('LOCALTIMESTAMP')->add([' 0 ' => 'literal']); - break; - case 'DATE_ADD': - $expression - ->setName('') - ->setConjunction(' + INTERVAL') - ->iterateParts(function ($p, $key) { - if ($key === 1) { - $p = sprintf("'%s'", $p); - } - - return $p; - }); - break; - case 'DAYOFWEEK': - $expression - ->setName('EXTRACT') - ->setConjunction(' ') - ->add(['DOW FROM' => 'literal'], [], true) - ->add([') + (1' => 'literal']); // Postgres starts on index 0 but Sunday should be 1 - break; - } - } - - /** - * Get the schema dialect. - * - * Used by Cake\Database\Schema package to reflect schema and - * generate schema. - * - * @return \Cake\Database\Schema\PostgresSchema - */ - public function schemaDialect() - { - if (!$this->_schemaDialect) { - $this->_schemaDialect = new PostgresSchema($this); - } - - return $this->_schemaDialect; - } - - /** - * {@inheritDoc} - */ - public function disableForeignKeySQL() - { - return 'SET CONSTRAINTS ALL DEFERRED'; - } - - /** - * {@inheritDoc} - */ - public function enableForeignKeySQL() - { - return 'SET CONSTRAINTS ALL IMMEDIATE'; - } -} diff --git a/vendor/cakephp/cakephp/src/Database/Dialect/SqliteDialectTrait.php b/vendor/cakephp/cakephp/src/Database/Dialect/SqliteDialectTrait.php deleted file mode 100644 index 2455090..0000000 --- a/vendor/cakephp/cakephp/src/Database/Dialect/SqliteDialectTrait.php +++ /dev/null @@ -1,196 +0,0 @@ - 'd', - 'hour' => 'H', - 'month' => 'm', - 'minute' => 'M', - 'second' => 'S', - 'week' => 'W', - 'year' => 'Y' - ]; - - /** - * Returns a dictionary of expressions to be transformed when compiling a Query - * to SQL. Array keys are method names to be called in this class - * - * @return array - */ - protected function _expressionTranslators() - { - $namespace = 'Cake\Database\Expression'; - - return [ - $namespace . '\FunctionExpression' => '_transformFunctionExpression', - $namespace . '\TupleComparison' => '_transformTupleComparison' - ]; - } - - /** - * Receives a FunctionExpression and changes it so that it conforms to this - * SQL dialect. - * - * @param \Cake\Database\Expression\FunctionExpression $expression The function expression - * to translate for SQLite. - * @return void - */ - protected function _transformFunctionExpression(FunctionExpression $expression) - { - switch ($expression->getName()) { - case 'CONCAT': - // CONCAT function is expressed as exp1 || exp2 - $expression->setName('')->setConjunction(' ||'); - break; - case 'DATEDIFF': - $expression - ->setName('ROUND') - ->setConjunction('-') - ->iterateParts(function ($p) { - return new FunctionExpression('JULIANDAY', [$p['value']], [$p['type']]); - }); - break; - case 'NOW': - $expression->setName('DATETIME')->add(["'now'" => 'literal']); - break; - case 'CURRENT_DATE': - $expression->setName('DATE')->add(["'now'" => 'literal']); - break; - case 'CURRENT_TIME': - $expression->setName('TIME')->add(["'now'" => 'literal']); - break; - case 'EXTRACT': - $expression - ->setName('STRFTIME') - ->setConjunction(' ,') - ->iterateParts(function ($p, $key) { - if ($key === 0) { - $value = rtrim(strtolower($p), 's'); - if (isset($this->_dateParts[$value])) { - $p = ['value' => '%' . $this->_dateParts[$value], 'type' => null]; - } - } - - return $p; - }); - break; - case 'DATE_ADD': - $expression - ->setName('DATE') - ->setConjunction(',') - ->iterateParts(function ($p, $key) { - if ($key === 1) { - $p = ['value' => $p, 'type' => null]; - } - - return $p; - }); - break; - case 'DAYOFWEEK': - $expression - ->setName('STRFTIME') - ->setConjunction(' ') - ->add(["'%w', " => 'literal'], [], true) - ->add([') + (1' => 'literal']); // Sqlite starts on index 0 but Sunday should be 1 - break; - } - } - - /** - * Get the schema dialect. - * - * Used by Cake\Database\Schema package to reflect schema and - * generate schema. - * - * @return \Cake\Database\Schema\SqliteSchema - */ - public function schemaDialect() - { - if (!$this->_schemaDialect) { - $this->_schemaDialect = new SqliteSchema($this); - } - - return $this->_schemaDialect; - } - - /** - * {@inheritDoc} - */ - public function disableForeignKeySQL() - { - return 'PRAGMA foreign_keys = OFF'; - } - - /** - * {@inheritDoc} - */ - public function enableForeignKeySQL() - { - return 'PRAGMA foreign_keys = ON'; - } - - /** - * {@inheritDoc} - * - * @return \Cake\Database\SqliteCompiler - */ - public function newCompiler() - { - return new SqliteCompiler(); - } -} diff --git a/vendor/cakephp/cakephp/src/Database/Dialect/SqlserverDialectTrait.php b/vendor/cakephp/cakephp/src/Database/Dialect/SqlserverDialectTrait.php deleted file mode 100644 index a58161c..0000000 --- a/vendor/cakephp/cakephp/src/Database/Dialect/SqlserverDialectTrait.php +++ /dev/null @@ -1,393 +0,0 @@ -clause('limit'); - $offset = $query->clause('offset'); - - if ($limit && $offset === null) { - $query->modifier(['_auto_top_' => sprintf('TOP %d', $limit)]); - } - - if ($offset !== null && !$query->clause('order')) { - $query->order($query->newExpr()->add('(SELECT NULL)')); - } - - if ($this->_version() < 11 && $offset !== null) { - return $this->_pagingSubquery($query, $limit, $offset); - } - - return $this->_transformDistinct($query); - } - - /** - * Get the version of SQLserver we are connected to. - * - * @return int - */ - // @codingStandardsIgnoreLine - public function _version() - { - $this->connect(); - - return $this->_connection->getAttribute(PDO::ATTR_SERVER_VERSION); - } - - /** - * Generate a paging subquery for older versions of SQLserver. - * - * Prior to SQLServer 2012 there was no equivalent to LIMIT OFFSET, so a subquery must - * be used. - * - * @param \Cake\Database\Query $original The query to wrap in a subquery. - * @param int $limit The number of rows to fetch. - * @param int $offset The number of rows to offset. - * @return \Cake\Database\Query Modified query object. - */ - protected function _pagingSubquery($original, $limit, $offset) - { - $field = '_cake_paging_._cake_page_rownum_'; - - if ($original->clause('order')) { - // SQL server does not support column aliases in OVER clauses. But - // the only practical way to specify the use of calculated columns - // is with their alias. So substitute the select SQL in place of - // any column aliases for those entries in the order clause. - $select = $original->clause('select'); - $order = new OrderByExpression(); - $original - ->clause('order') - ->iterateParts(function ($direction, $orderBy) use ($select, $order) { - $key = $orderBy; - if (isset($select[$orderBy]) && - $select[$orderBy] instanceof ExpressionInterface - ) { - $key = $select[$orderBy]->sql(new ValueBinder()); - } - $order->add([$key => $direction]); - - // Leave original order clause unchanged. - return $orderBy; - }); - } else { - $order = new OrderByExpression('(SELECT NULL)'); - } - - $query = clone $original; - $query->select([ - '_cake_page_rownum_' => new UnaryExpression('ROW_NUMBER() OVER', $order) - ])->limit(null) - ->offset(null) - ->order([], true); - - $outer = new Query($query->getConnection()); - $outer->select('*') - ->from(['_cake_paging_' => $query]); - - if ($offset) { - $outer->where(["$field > " . (int)$offset]); - } - if ($limit) { - $value = (int)$offset + (int)$limit; - $outer->where(["$field <= $value"]); - } - - // Decorate the original query as that is what the - // end developer will be calling execute() on originally. - $original->decorateResults(function ($row) { - if (isset($row['_cake_page_rownum_'])) { - unset($row['_cake_page_rownum_']); - } - - return $row; - }); - - return $outer; - } - - /** - * Returns the passed query after rewriting the DISTINCT clause, so that drivers - * that do not support the "ON" part can provide the actual way it should be done - * - * @param \Cake\Database\Query $original The query to be transformed - * @return \Cake\Database\Query - */ - protected function _transformDistinct($original) - { - if (!is_array($original->clause('distinct'))) { - return $original; - } - - $query = clone $original; - $distinct = $query->clause('distinct'); - $query->distinct(false); - - $order = new OrderByExpression($distinct); - $query - ->select(function ($q) use ($distinct, $order) { - $over = $q->newExpr('ROW_NUMBER() OVER') - ->add('(PARTITION BY') - ->add($q->newExpr()->add($distinct)->setConjunction(',')) - ->add($order) - ->add(')') - ->setConjunction(' '); - - return [ - '_cake_distinct_pivot_' => $over - ]; - }) - ->limit(null) - ->offset(null) - ->order([], true); - - $outer = new Query($query->getConnection()); - $outer->select('*') - ->from(['_cake_distinct_' => $query]) - ->where(['_cake_distinct_pivot_' => 1]); - - // Decorate the original query as that is what the - // end developer will be calling execute() on originally. - $original->decorateResults(function ($row) { - if (isset($row['_cake_distinct_pivot_'])) { - unset($row['_cake_distinct_pivot_']); - } - - return $row; - }); - - return $outer; - } - - /** - * Returns a dictionary of expressions to be transformed when compiling a Query - * to SQL. Array keys are method names to be called in this class - * - * @return array - */ - protected function _expressionTranslators() - { - $namespace = 'Cake\Database\Expression'; - - return [ - $namespace . '\FunctionExpression' => '_transformFunctionExpression', - $namespace . '\TupleComparison' => '_transformTupleComparison' - ]; - } - - /** - * Receives a FunctionExpression and changes it so that it conforms to this - * SQL dialect. - * - * @param \Cake\Database\Expression\FunctionExpression $expression The function expression to convert to TSQL. - * @return void - */ - protected function _transformFunctionExpression(FunctionExpression $expression) - { - switch ($expression->getName()) { - case 'CONCAT': - // CONCAT function is expressed as exp1 + exp2 - $expression->setName('')->setConjunction(' +'); - break; - case 'DATEDIFF': - $hasDay = false; - $visitor = function ($value) use (&$hasDay) { - if ($value === 'day') { - $hasDay = true; - } - - return $value; - }; - $expression->iterateParts($visitor); - - if (!$hasDay) { - $expression->add(['day' => 'literal'], [], true); - } - break; - case 'CURRENT_DATE': - $time = new FunctionExpression('GETUTCDATE'); - $expression->setName('CONVERT')->add(['date' => 'literal', $time]); - break; - case 'CURRENT_TIME': - $time = new FunctionExpression('GETUTCDATE'); - $expression->setName('CONVERT')->add(['time' => 'literal', $time]); - break; - case 'NOW': - $expression->setName('GETUTCDATE'); - break; - case 'EXTRACT': - $expression->setName('DATEPART')->setConjunction(' ,'); - break; - case 'DATE_ADD': - $params = []; - $visitor = function ($p, $key) use (&$params) { - if ($key === 0) { - $params[2] = $p; - } else { - $valueUnit = explode(' ', $p); - $params[0] = rtrim($valueUnit[1], 's'); - $params[1] = $valueUnit[0]; - } - - return $p; - }; - $manipulator = function ($p, $key) use (&$params) { - return $params[$key]; - }; - - $expression - ->setName('DATEADD') - ->setConjunction(',') - ->iterateParts($visitor) - ->iterateParts($manipulator) - ->add([$params[2] => 'literal']); - break; - case 'DAYOFWEEK': - $expression - ->setName('DATEPART') - ->setConjunction(' ') - ->add(['weekday, ' => 'literal'], [], true); - break; - case 'SUBSTR': - $expression->setName('SUBSTRING'); - if (count($expression) < 4) { - $params = []; - $expression - ->iterateParts(function ($p) use (&$params) { - return $params[] = $p; - }) - ->add([new FunctionExpression('LEN', [$params[0]]), ['string']]); - } - - break; - } - } - - /** - * Get the schema dialect. - * - * Used by Cake\Schema package to reflect schema and - * generate schema. - * - * @return \Cake\Database\Schema\SqlserverSchema - */ - public function schemaDialect() - { - return new SqlserverSchema($this); - } - - /** - * Returns a SQL snippet for creating a new transaction savepoint - * - * @param string $name save point name - * @return string - */ - public function savePointSQL($name) - { - return 'SAVE TRANSACTION t' . $name; - } - - /** - * Returns a SQL snippet for releasing a previously created save point - * - * @param string $name save point name - * @return string - */ - public function releaseSavePointSQL($name) - { - return 'COMMIT TRANSACTION t' . $name; - } - - /** - * Returns a SQL snippet for rollbacking a previously created save point - * - * @param string $name save point name - * @return string - */ - public function rollbackSavePointSQL($name) - { - return 'ROLLBACK TRANSACTION t' . $name; - } - - /** - * {@inheritDoc} - * - * @return \Cake\Database\SqlserverCompiler - */ - public function newCompiler() - { - return new SqlserverCompiler(); - } - - /** - * {@inheritDoc} - */ - public function disableForeignKeySQL() - { - return 'EXEC sp_msforeachtable "ALTER TABLE ? NOCHECK CONSTRAINT all"'; - } - - /** - * {@inheritDoc} - */ - public function enableForeignKeySQL() - { - return 'EXEC sp_msforeachtable "ALTER TABLE ? WITH CHECK CHECK CONSTRAINT all"'; - } -} diff --git a/vendor/cakephp/cakephp/src/Database/Dialect/TupleComparisonTranslatorTrait.php b/vendor/cakephp/cakephp/src/Database/Dialect/TupleComparisonTranslatorTrait.php deleted file mode 100644 index a9627b3..0000000 --- a/vendor/cakephp/cakephp/src/Database/Dialect/TupleComparisonTranslatorTrait.php +++ /dev/null @@ -1,95 +0,0 @@ -getField(); - - if (!is_array($fields)) { - return; - } - - $value = $expression->getValue(); - $op = $expression->getOperator(); - $true = new QueryExpression('1'); - - if ($value instanceof Query) { - $selected = array_values($value->clause('select')); - foreach ($fields as $i => $field) { - $value->andWhere([$field . " $op" => new IdentifierExpression($selected[$i])]); - } - $value->select($true, true); - $expression->setField($true); - $expression->setOperator('='); - - return; - } - - $surrogate = $query->getConnection() - ->newQuery() - ->select($true); - - if (!is_array(current($value))) { - $value = [$value]; - } - - $conditions = ['OR' => []]; - foreach ($value as $tuple) { - $item = []; - foreach (array_values($tuple) as $i => $value) { - $item[] = [$fields[$i] => $value]; - } - $conditions['OR'][] = $item; - } - $surrogate->where($conditions); - - $expression->setField($true); - $expression->setValue($surrogate); - $expression->setOperator('='); - } -} diff --git a/vendor/cakephp/cakephp/src/Database/Driver.php b/vendor/cakephp/cakephp/src/Database/Driver.php deleted file mode 100644 index 3cc0bb6..0000000 --- a/vendor/cakephp/cakephp/src/Database/Driver.php +++ /dev/null @@ -1,437 +0,0 @@ -_baseConfig; - $this->_config = $config; - if (!empty($config['quoteIdentifiers'])) { - $this->enableAutoQuoting(); - } - } - - /** - * Establishes a connection to the database server - * - * @param string $dsn A Driver-specific PDO-DSN - * @param array $config configuration to be used for creating connection - * @return bool true on success - */ - protected function _connect($dsn, array $config) - { - $connection = new PDO( - $dsn, - $config['username'], - $config['password'], - $config['flags'] - ); - $this->setConnection($connection); - - return true; - } - - /** - * {@inheritDoc} - */ - abstract public function connect(); - - /** - * {@inheritDoc} - */ - public function disconnect() - { - $this->_connection = null; - } - - /** - * Returns correct connection resource or object that is internally used - * If first argument is passed, it will set internal connection object or - * result to the value passed. - * - * @param mixed $connection The PDO connection instance. - * @return mixed Connection object used internally. - * @deprecated 3.6.0 Use getConnection()/setConnection() instead. - */ - public function connection($connection = null) - { - deprecationWarning( - get_called_class() . '::connection() is deprecated. ' . - 'Use setConnection()/getConnection() instead.' - ); - if ($connection !== null) { - $this->_connection = $connection; - } - - return $this->_connection; - } - - /** - * Get the internal PDO connection instance. - * - * @return \PDO - */ - public function getConnection() - { - return $this->_connection; - } - - /** - * Set the internal PDO connection instance. - * - * @param \PDO $connection PDO instance. - * @return $this - */ - public function setConnection($connection) - { - $this->_connection = $connection; - - return $this; - } - - /** - * {@inheritDoc} - */ - abstract public function enabled(); - - /** - * {@inheritDoc} - */ - public function prepare($query) - { - $this->connect(); - $isObject = $query instanceof Query; - $statement = $this->_connection->prepare($isObject ? $query->sql() : $query); - - return new PDOStatement($statement, $this); - } - - /** - * {@inheritDoc} - */ - public function beginTransaction() - { - $this->connect(); - if ($this->_connection->inTransaction()) { - return true; - } - - return $this->_connection->beginTransaction(); - } - - /** - * {@inheritDoc} - */ - public function commitTransaction() - { - $this->connect(); - if (!$this->_connection->inTransaction()) { - return false; - } - - return $this->_connection->commit(); - } - - /** - * {@inheritDoc} - */ - public function rollbackTransaction() - { - $this->connect(); - if (!$this->_connection->inTransaction()) { - return false; - } - - return $this->_connection->rollBack(); - } - - /** - * {@inheritDoc} - */ - abstract public function releaseSavePointSQL($name); - - /** - * {@inheritDoc} - */ - abstract public function savePointSQL($name); - - /** - * {@inheritDoc} - */ - abstract public function rollbackSavePointSQL($name); - - /** - * {@inheritDoc} - */ - abstract public function disableForeignKeySQL(); - - /** - * {@inheritDoc} - */ - abstract public function enableForeignKeySQL(); - - /** - * {@inheritDoc} - */ - abstract public function supportsDynamicConstraints(); - - /** - * {@inheritDoc} - */ - public function supportsSavePoints() - { - return true; - } - - /** - * {@inheritDoc} - */ - public function quote($value, $type) - { - $this->connect(); - - return $this->_connection->quote($value, $type); - } - - /** - * Checks if the driver supports quoting, as PDO_ODBC does not support it. - * - * @return bool - */ - public function supportsQuoting() - { - $this->connect(); - - return $this->_connection->getAttribute(PDO::ATTR_DRIVER_NAME) !== 'odbc'; - } - - /** - * {@inheritDoc} - */ - abstract public function queryTranslator($type); - - /** - * {@inheritDoc} - */ - abstract public function schemaDialect(); - - /** - * {@inheritDoc} - */ - abstract public function quoteIdentifier($identifier); - - /** - * {@inheritDoc} - */ - public function schemaValue($value) - { - if ($value === null) { - return 'NULL'; - } - if ($value === false) { - return 'FALSE'; - } - if ($value === true) { - return 'TRUE'; - } - if (is_float($value)) { - return str_replace(',', '.', (string)$value); - } - if ((is_int($value) || $value === '0') || ( - is_numeric($value) && strpos($value, ',') === false && - $value[0] !== '0' && strpos($value, 'e') === false) - ) { - return (string)$value; - } - - return $this->_connection->quote($value, PDO::PARAM_STR); - } - - /** - * {@inheritDoc} - */ - public function schema() - { - return $this->_config['schema']; - } - - /** - * {@inheritDoc} - */ - public function lastInsertId($table = null, $column = null) - { - $this->connect(); - - if ($this->_connection instanceof PDO) { - return $this->_connection->lastInsertId($table); - } - - return $this->_connection->lastInsertId($table, $column); - } - - /** - * {@inheritDoc} - */ - public function isConnected() - { - if ($this->_connection === null) { - $connected = false; - } else { - try { - $connected = $this->_connection->query('SELECT 1'); - } catch (PDOException $e) { - $connected = false; - } - } - - return (bool)$connected; - } - - /** - * {@inheritDoc} - */ - public function enableAutoQuoting($enable = true) - { - $this->_autoQuoting = (bool)$enable; - - return $this; - } - - /** - * {@inheritDoc} - */ - public function isAutoQuotingEnabled() - { - return $this->_autoQuoting; - } - - /** - * Returns whether or not this driver should automatically quote identifiers - * in queries - * - * If called with a boolean argument, it will toggle the auto quoting setting - * to the passed value - * - * @deprecated 3.4.0 use enableAutoQuoting()/isAutoQuotingEnabled() instead. - * @param bool|null $enable Whether to enable auto quoting - * @return bool - */ - public function autoQuoting($enable = null) - { - deprecationWarning( - 'Driver::autoQuoting() is deprecated. ' . - 'Use Driver::enableAutoQuoting()/isAutoQuotingEnabled() instead.' - ); - if ($enable !== null) { - $this->enableAutoQuoting($enable); - } - - return $this->isAutoQuotingEnabled(); - } - - /** - * {@inheritDoc} - */ - public function compileQuery(Query $query, ValueBinder $generator) - { - $processor = $this->newCompiler(); - $translator = $this->queryTranslator($query->type()); - $query = $translator($query); - - return [$query, $processor->compile($query, $generator)]; - } - - /** - * {@inheritDoc} - */ - public function newCompiler() - { - return new QueryCompiler(); - } - - /** - * Destructor - */ - public function __destruct() - { - $this->_connection = null; - } - - /** - * Returns an array that can be used to describe the internal state of this - * object. - * - * @return array - */ - public function __debugInfo() - { - return [ - 'connected' => $this->_connection !== null - ]; - } -} diff --git a/vendor/cakephp/cakephp/src/Database/Driver/Mysql.php b/vendor/cakephp/cakephp/src/Database/Driver/Mysql.php deleted file mode 100644 index 0ae3656..0000000 --- a/vendor/cakephp/cakephp/src/Database/Driver/Mysql.php +++ /dev/null @@ -1,177 +0,0 @@ - true, - 'host' => 'localhost', - 'username' => 'root', - 'password' => '', - 'database' => 'cake', - 'port' => '3306', - 'flags' => [], - 'encoding' => 'utf8mb4', - 'timezone' => null, - 'init' => [], - ]; - - /** - * The server version - * - * @var string - */ - protected $_version; - - /** - * Whether or not the server supports native JSON - * - * @var bool - */ - protected $_supportsNativeJson; - - /** - * Establishes a connection to the database server - * - * @return bool true on success - */ - public function connect() - { - if ($this->_connection) { - return true; - } - $config = $this->_config; - - if ($config['timezone'] === 'UTC') { - $config['timezone'] = '+0:00'; - } - - if (!empty($config['timezone'])) { - $config['init'][] = sprintf("SET time_zone = '%s'", $config['timezone']); - } - if (!empty($config['encoding'])) { - $config['init'][] = sprintf('SET NAMES %s', $config['encoding']); - } - - $config['flags'] += [ - PDO::ATTR_PERSISTENT => $config['persistent'], - PDO::MYSQL_ATTR_USE_BUFFERED_QUERY => true, - PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION, - ]; - - if (!empty($config['ssl_key']) && !empty($config['ssl_cert'])) { - $config['flags'][PDO::MYSQL_ATTR_SSL_KEY] = $config['ssl_key']; - $config['flags'][PDO::MYSQL_ATTR_SSL_CERT] = $config['ssl_cert']; - } - if (!empty($config['ssl_ca'])) { - $config['flags'][PDO::MYSQL_ATTR_SSL_CA] = $config['ssl_ca']; - } - - if (empty($config['unix_socket'])) { - $dsn = "mysql:host={$config['host']};port={$config['port']};dbname={$config['database']};charset={$config['encoding']}"; - } else { - $dsn = "mysql:unix_socket={$config['unix_socket']};dbname={$config['database']}"; - } - - $this->_connect($dsn, $config); - - if (!empty($config['init'])) { - $connection = $this->getConnection(); - foreach ((array)$config['init'] as $command) { - $connection->exec($command); - } - } - - return true; - } - - /** - * Returns whether php is able to use this driver for connecting to database - * - * @return bool true if it is valid to use this driver - */ - public function enabled() - { - return in_array('mysql', PDO::getAvailableDrivers()); - } - - /** - * Prepares a sql statement to be executed - * - * @param string|\Cake\Database\Query $query The query to prepare. - * @return \Cake\Database\StatementInterface - */ - public function prepare($query) - { - $this->connect(); - $isObject = $query instanceof Query; - $statement = $this->_connection->prepare($isObject ? $query->sql() : $query); - $result = new MysqlStatement($statement, $this); - if ($isObject && $query->isBufferedResultsEnabled() === false) { - $result->bufferResults(false); - } - - return $result; - } - - /** - * {@inheritDoc} - */ - public function schema() - { - return $this->_config['database']; - } - - /** - * {@inheritDoc} - */ - public function supportsDynamicConstraints() - { - return true; - } - - /** - * Returns true if the server supports native JSON columns - * - * @return bool - */ - public function supportsNativeJson() - { - if ($this->_supportsNativeJson !== null) { - return $this->_supportsNativeJson; - } - - if ($this->_version === null) { - $this->_version = $this->_connection->getAttribute(PDO::ATTR_SERVER_VERSION); - } - - return $this->_supportsNativeJson = version_compare($this->_version, '5.7.0', '>='); - } -} diff --git a/vendor/cakephp/cakephp/src/Database/Driver/PDODriverTrait.php b/vendor/cakephp/cakephp/src/Database/Driver/PDODriverTrait.php deleted file mode 100644 index b115646..0000000 --- a/vendor/cakephp/cakephp/src/Database/Driver/PDODriverTrait.php +++ /dev/null @@ -1,203 +0,0 @@ -connection($connection); - - return true; - } - - /** - * Returns correct connection resource or object that is internally used - * If first argument is passed, it will set internal connection object or - * result to the value passed - * - * @param null|\PDO $connection The PDO connection instance. - * @return \PDO connection object used internally - */ - public function connection($connection = null) - { - if ($connection !== null) { - $this->_connection = $connection; - } - - return $this->_connection; - } - - /** - * Disconnects from database server - * - * @return void - */ - public function disconnect() - { - $this->_connection = null; - } - - /** - * Checks whether or not the driver is connected. - * - * @return bool - */ - public function isConnected() - { - if ($this->_connection === null) { - $connected = false; - } else { - try { - $connected = $this->_connection->query('SELECT 1'); - } catch (PDOException $e) { - $connected = false; - } - } - - return (bool)$connected; - } - - /** - * Prepares a sql statement to be executed - * - * @param string|\Cake\Database\Query $query The query to turn into a prepared statement. - * @return \Cake\Database\StatementInterface - */ - public function prepare($query) - { - $this->connect(); - $isObject = $query instanceof Query; - $statement = $this->_connection->prepare($isObject ? $query->sql() : $query); - - return new PDOStatement($statement, $this); - } - - /** - * Starts a transaction - * - * @return bool true on success, false otherwise - */ - public function beginTransaction() - { - $this->connect(); - if ($this->_connection->inTransaction()) { - return true; - } - - return $this->_connection->beginTransaction(); - } - - /** - * Commits a transaction - * - * @return bool true on success, false otherwise - */ - public function commitTransaction() - { - $this->connect(); - if (!$this->_connection->inTransaction()) { - return false; - } - - return $this->_connection->commit(); - } - - /** - * Rollback a transaction - * - * @return bool true on success, false otherwise - */ - public function rollbackTransaction() - { - $this->connect(); - if (!$this->_connection->inTransaction()) { - return false; - } - - return $this->_connection->rollback(); - } - - /** - * Returns a value in a safe representation to be used in a query string - * - * @param mixed $value The value to quote. - * @param string $type Type to be used for determining kind of quoting to perform - * @return string - */ - public function quote($value, $type) - { - $this->connect(); - - return $this->_connection->quote($value, $type); - } - - /** - * Returns last id generated for a table or sequence in database - * - * @param string|null $table table name or sequence to get last insert value from - * @param string|null $column the name of the column representing the primary key - * @return string|int - */ - public function lastInsertId($table = null, $column = null) - { - $this->connect(); - - return $this->_connection->lastInsertId($table); - } - - /** - * Checks if the driver supports quoting, as PDO_ODBC does not support it. - * - * @return bool - */ - public function supportsQuoting() - { - $this->connect(); - - return $this->_connection->getAttribute(PDO::ATTR_DRIVER_NAME) !== 'odbc'; - } -} diff --git a/vendor/cakephp/cakephp/src/Database/Driver/Postgres.php b/vendor/cakephp/cakephp/src/Database/Driver/Postgres.php deleted file mode 100644 index 8f19af6..0000000 --- a/vendor/cakephp/cakephp/src/Database/Driver/Postgres.php +++ /dev/null @@ -1,130 +0,0 @@ - true, - 'host' => 'localhost', - 'username' => 'root', - 'password' => '', - 'database' => 'cake', - 'schema' => 'public', - 'port' => 5432, - 'encoding' => 'utf8', - 'timezone' => null, - 'flags' => [], - 'init' => [], - ]; - - /** - * Establishes a connection to the database server - * - * @return bool true on success - */ - public function connect() - { - if ($this->_connection) { - return true; - } - $config = $this->_config; - $config['flags'] += [ - PDO::ATTR_PERSISTENT => $config['persistent'], - PDO::ATTR_EMULATE_PREPARES => false, - PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION - ]; - if (empty($config['unix_socket'])) { - $dsn = "pgsql:host={$config['host']};port={$config['port']};dbname={$config['database']}"; - } else { - $dsn = "pgsql:dbname={$config['database']}"; - } - - $this->_connect($dsn, $config); - $this->_connection = $connection = $this->getConnection(); - if (!empty($config['encoding'])) { - $this->setEncoding($config['encoding']); - } - - if (!empty($config['schema'])) { - $this->setSchema($config['schema']); - } - - if (!empty($config['timezone'])) { - $config['init'][] = sprintf('SET timezone = %s', $connection->quote($config['timezone'])); - } - - foreach ($config['init'] as $command) { - $connection->exec($command); - } - - return true; - } - - /** - * Returns whether php is able to use this driver for connecting to database - * - * @return bool true if it is valid to use this driver - */ - public function enabled() - { - return in_array('pgsql', PDO::getAvailableDrivers()); - } - - /** - * Sets connection encoding - * - * @param string $encoding The encoding to use. - * @return void - */ - public function setEncoding($encoding) - { - $this->connect(); - $this->_connection->exec('SET NAMES ' . $this->_connection->quote($encoding)); - } - - /** - * Sets connection default schema, if any relation defined in a query is not fully qualified - * postgres will fallback to looking the relation into defined default schema - * - * @param string $schema The schema names to set `search_path` to. - * @return void - */ - public function setSchema($schema) - { - $this->connect(); - $this->_connection->exec('SET search_path TO ' . $this->_connection->quote($schema)); - } - - /** - * {@inheritDoc} - */ - public function supportsDynamicConstraints() - { - return true; - } -} diff --git a/vendor/cakephp/cakephp/src/Database/Driver/Sqlite.php b/vendor/cakephp/cakephp/src/Database/Driver/Sqlite.php deleted file mode 100644 index 8e2e8fc..0000000 --- a/vendor/cakephp/cakephp/src/Database/Driver/Sqlite.php +++ /dev/null @@ -1,120 +0,0 @@ - false, - 'username' => null, - 'password' => null, - 'database' => ':memory:', - 'encoding' => 'utf8', - 'mask' => 0644, - 'flags' => [], - 'init' => [], - ]; - - /** - * Establishes a connection to the database server - * - * @return bool true on success - */ - public function connect() - { - if ($this->_connection) { - return true; - } - $config = $this->_config; - $config['flags'] += [ - PDO::ATTR_PERSISTENT => $config['persistent'], - PDO::ATTR_EMULATE_PREPARES => false, - PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION - ]; - - $databaseExists = file_exists($config['database']); - - $dsn = "sqlite:{$config['database']}"; - $this->_connect($dsn, $config); - - if (!$databaseExists && $config['database'] != ':memory:') { - //@codingStandardsIgnoreStart - @chmod($config['database'], $config['mask']); - //@codingStandardsIgnoreEnd - } - - if (!empty($config['init'])) { - foreach ((array)$config['init'] as $command) { - $this->getConnection()->exec($command); - } - } - - return true; - } - - /** - * Returns whether php is able to use this driver for connecting to database - * - * @return bool true if it is valid to use this driver - */ - public function enabled() - { - return in_array('sqlite', PDO::getAvailableDrivers()); - } - - /** - * Prepares a sql statement to be executed - * - * @param string|\Cake\Database\Query $query The query to prepare. - * @return \Cake\Database\StatementInterface - */ - public function prepare($query) - { - $this->connect(); - $isObject = $query instanceof Query; - $statement = $this->_connection->prepare($isObject ? $query->sql() : $query); - $result = new SqliteStatement(new PDOStatement($statement, $this), $this); - if ($isObject && $query->isBufferedResultsEnabled() === false) { - $result->bufferResults(false); - } - - return $result; - } - - /** - * {@inheritDoc} - */ - public function supportsDynamicConstraints() - { - return false; - } -} diff --git a/vendor/cakephp/cakephp/src/Database/Driver/Sqlserver.php b/vendor/cakephp/cakephp/src/Database/Driver/Sqlserver.php deleted file mode 100644 index 74d72fc..0000000 --- a/vendor/cakephp/cakephp/src/Database/Driver/Sqlserver.php +++ /dev/null @@ -1,164 +0,0 @@ - 'localhost\SQLEXPRESS', - 'username' => '', - 'password' => '', - 'database' => 'cake', - 'port' => '', - // PDO::SQLSRV_ENCODING_UTF8 - 'encoding' => 65001, - 'flags' => [], - 'init' => [], - 'settings' => [], - 'attributes' => [], - 'app' => null, - 'connectionPooling' => null, - 'failoverPartner' => null, - 'loginTimeout' => null, - 'multiSubnetFailover' => null, - ]; - - /** - * Establishes a connection to the database server. - * - * Please note that the PDO::ATTR_PERSISTENT attribute is not supported by - * the SQL Server PHP PDO drivers. As a result you cannot use the - * persistent config option when connecting to a SQL Server (for more - * information see: https://github.com/Microsoft/msphpsql/issues/65). - * - * @throws \InvalidArgumentException if an unsupported setting is in the driver config - * @return bool true on success - */ - public function connect() - { - if ($this->_connection) { - return true; - } - $config = $this->_config; - - if (isset($config['persistent']) && $config['persistent']) { - throw new \InvalidArgumentException('Config setting "persistent" cannot be set to true, as the Sqlserver PDO driver does not support PDO::ATTR_PERSISTENT'); - } - - $config['flags'] += [ - PDO::ATTR_EMULATE_PREPARES => false, - PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION - ]; - - if (!empty($config['encoding'])) { - $config['flags'][PDO::SQLSRV_ATTR_ENCODING] = $config['encoding']; - } - $port = ''; - if (strlen($config['port'])) { - $port = ',' . $config['port']; - } - - $dsn = "sqlsrv:Server={$config['host']}{$port};Database={$config['database']};MultipleActiveResultSets=false"; - if ($config['app'] !== null) { - $dsn .= ";APP={$config['app']}"; - } - if ($config['connectionPooling'] !== null) { - $dsn .= ";ConnectionPooling={$config['connectionPooling']}"; - } - if ($config['failoverPartner'] !== null) { - $dsn .= ";Failover_Partner={$config['failoverPartner']}"; - } - if ($config['loginTimeout'] !== null) { - $dsn .= ";LoginTimeout={$config['loginTimeout']}"; - } - if ($config['multiSubnetFailover'] !== null) { - $dsn .= ";MultiSubnetFailover={$config['multiSubnetFailover']}"; - } - $this->_connect($dsn, $config); - - $connection = $this->getConnection(); - if (!empty($config['init'])) { - foreach ((array)$config['init'] as $command) { - $connection->exec($command); - } - } - if (!empty($config['settings']) && is_array($config['settings'])) { - foreach ($config['settings'] as $key => $value) { - $connection->exec("SET {$key} {$value}"); - } - } - if (!empty($config['attributes']) && is_array($config['attributes'])) { - foreach ($config['attributes'] as $key => $value) { - $connection->setAttribute($key, $value); - } - } - - return true; - } - - /** - * Returns whether PHP is able to use this driver for connecting to database - * - * @return bool true if it is valid to use this driver - */ - public function enabled() - { - return in_array('sqlsrv', PDO::getAvailableDrivers()); - } - - /** - * Prepares a sql statement to be executed - * - * @param string|\Cake\Database\Query $query The query to prepare. - * @return \Cake\Database\StatementInterface - */ - public function prepare($query) - { - $this->connect(); - $options = [PDO::ATTR_CURSOR => PDO::CURSOR_SCROLL]; - $isObject = $query instanceof Query; - if ($isObject && $query->isBufferedResultsEnabled() === false) { - $options = []; - } - $statement = $this->_connection->prepare($isObject ? $query->sql() : $query, $options); - - return new SqlserverStatement($statement, $this); - } - - /** - * {@inheritDoc} - */ - public function supportsDynamicConstraints() - { - return true; - } -} diff --git a/vendor/cakephp/cakephp/src/Database/Exception.php b/vendor/cakephp/cakephp/src/Database/Exception.php deleted file mode 100644 index c61d87d..0000000 --- a/vendor/cakephp/cakephp/src/Database/Exception.php +++ /dev/null @@ -1,25 +0,0 @@ -_castToExpression($from, $type); - $to = $this->_castToExpression($to, $type); - } - - $this->_field = $field; - $this->_from = $from; - $this->_to = $to; - $this->_type = $type; - } - - /** - * Converts the expression to its string representation - * - * @param \Cake\Database\ValueBinder $generator Placeholder generator object - * @return string - */ - public function sql(ValueBinder $generator) - { - $parts = [ - 'from' => $this->_from, - 'to' => $this->_to - ]; - - $field = $this->_field; - if ($field instanceof ExpressionInterface) { - $field = $field->sql($generator); - } - - foreach ($parts as $name => $part) { - if ($part instanceof ExpressionInterface) { - $parts[$name] = $part->sql($generator); - continue; - } - $parts[$name] = $this->_bindValue($part, $generator, $this->_type); - } - - return sprintf('%s BETWEEN %s AND %s', $field, $parts['from'], $parts['to']); - } - - /** - * {@inheritDoc} - * - */ - public function traverse(callable $callable) - { - foreach ([$this->_field, $this->_from, $this->_to] as $part) { - if ($part instanceof ExpressionInterface) { - $callable($part); - } - } - } - - /** - * Registers a value in the placeholder generator and returns the generated placeholder - * - * @param mixed $value The value to bind - * @param \Cake\Database\ValueBinder $generator The value binder to use - * @param string $type The type of $value - * @return string generated placeholder - */ - protected function _bindValue($value, $generator, $type) - { - $placeholder = $generator->placeholder('c'); - $generator->bind($placeholder, $value, $type); - - return $placeholder; - } - - /** - * Do a deep clone of this expression. - * - * @return void - */ - public function __clone() - { - foreach (['_field', '_from', '_to'] as $part) { - if ($this->{$part} instanceof ExpressionInterface) { - $this->{$part} = clone $this->{$part}; - } - } - } -} diff --git a/vendor/cakephp/cakephp/src/Database/Expression/CaseExpression.php b/vendor/cakephp/cakephp/src/Database/Expression/CaseExpression.php deleted file mode 100644 index b826c18..0000000 --- a/vendor/cakephp/cakephp/src/Database/Expression/CaseExpression.php +++ /dev/null @@ -1,249 +0,0 @@ - :value" - * - * @var array - */ - protected $_conditions = []; - - /** - * Values that are associated with the conditions in the $_conditions array. - * Each value represents the 'true' value for the condition with the corresponding key. - * - * @var array - */ - protected $_values = []; - - /** - * The `ELSE` value for the case statement. If null then no `ELSE` will be included. - * - * @var string|\Cake\Database\ExpressionInterface|array|null - */ - protected $_elseValue; - - /** - * Constructs the case expression - * - * @param array|\Cake\Database\ExpressionInterface $conditions The conditions to test. Must be a ExpressionInterface - * instance, or an array of ExpressionInterface instances. - * @param array|\Cake\Database\ExpressionInterface $values associative array of values to be associated with the conditions - * passed in $conditions. If there are more $values than $conditions, the last $value is used as the `ELSE` value - * @param array $types associative array of types to be associated with the values - * passed in $values - */ - public function __construct($conditions = [], $values = [], $types = []) - { - if (!empty($conditions)) { - $this->add($conditions, $values, $types); - } - - if (is_array($conditions) && is_array($values) && count($values) > count($conditions)) { - end($values); - $key = key($values); - $this->elseValue($values[$key], isset($types[$key]) ? $types[$key] : null); - } - } - - /** - * Adds one or more conditions and their respective true values to the case object. - * Conditions must be a one dimensional array or a QueryExpression. - * The trueValues must be a similar structure, but may contain a string value. - * - * @param array|\Cake\Database\ExpressionInterface $conditions Must be a ExpressionInterface instance, or an array of ExpressionInterface instances. - * @param array|\Cake\Database\ExpressionInterface $values associative array of values of each condition - * @param array $types associative array of types to be associated with the values - * - * @return $this - */ - public function add($conditions = [], $values = [], $types = []) - { - if (!is_array($conditions)) { - $conditions = [$conditions]; - } - if (!is_array($values)) { - $values = [$values]; - } - if (!is_array($types)) { - $types = [$types]; - } - - $this->_addExpressions($conditions, $values, $types); - - return $this; - } - - /** - * Iterates over the passed in conditions and ensures that there is a matching true value for each. - * If no matching true value, then it is defaulted to '1'. - * - * @param array|\Cake\Database\ExpressionInterface $conditions Must be a ExpressionInterface instance, or an array of ExpressionInterface instances. - * @param array|\Cake\Database\ExpressionInterface $values associative array of values of each condition - * @param array $types associative array of types to be associated with the values - * - * @return void - */ - protected function _addExpressions($conditions, $values, $types) - { - $rawValues = array_values($values); - $keyValues = array_keys($values); - - foreach ($conditions as $k => $c) { - $numericKey = is_numeric($k); - - if ($numericKey && empty($c)) { - continue; - } - - if (!$c instanceof ExpressionInterface) { - continue; - } - - $this->_conditions[] = $c; - $value = isset($rawValues[$k]) ? $rawValues[$k] : 1; - - if ($value === 'literal') { - $value = $keyValues[$k]; - $this->_values[] = $value; - continue; - } - - if ($value === 'identifier') { - $value = new IdentifierExpression($keyValues[$k]); - $this->_values[] = $value; - continue; - } - - $type = isset($types[$k]) ? $types[$k] : null; - - if ($type !== null && !$value instanceof ExpressionInterface) { - $value = $this->_castToExpression($value, $type); - } - - if ($value instanceof ExpressionInterface) { - $this->_values[] = $value; - continue; - } - - $this->_values[] = ['value' => $value, 'type' => $type]; - } - } - - /** - * Sets the default value - * - * @param \Cake\Database\ExpressionInterface|string|array|null $value Value to set - * @param string|null $type Type of value - * - * @return void - */ - public function elseValue($value = null, $type = null) - { - if (is_array($value)) { - end($value); - $value = key($value); - } - - if ($value !== null && !$value instanceof ExpressionInterface) { - $value = $this->_castToExpression($value, $type); - } - - if (!$value instanceof ExpressionInterface) { - $value = ['value' => $value, 'type' => $type]; - } - - $this->_elseValue = $value; - } - - /** - * Compiles the relevant parts into sql - * - * @param array|string|\Cake\Database\ExpressionInterface $part The part to compile - * @param \Cake\Database\ValueBinder $generator Sql generator - * - * @return string - */ - protected function _compile($part, ValueBinder $generator) - { - if ($part instanceof ExpressionInterface) { - $part = $part->sql($generator); - } elseif (is_array($part)) { - $placeholder = $generator->placeholder('param'); - $generator->bind($placeholder, $part['value'], $part['type']); - $part = $placeholder; - } - - return $part; - } - - /** - * Converts the Node into a SQL string fragment. - * - * @param \Cake\Database\ValueBinder $generator Placeholder generator object - * - * @return string - */ - public function sql(ValueBinder $generator) - { - $parts = []; - $parts[] = 'CASE'; - foreach ($this->_conditions as $k => $part) { - $value = $this->_values[$k]; - $parts[] = 'WHEN ' . $this->_compile($part, $generator) . ' THEN ' . $this->_compile($value, $generator); - } - if ($this->_elseValue !== null) { - $parts[] = 'ELSE'; - $parts[] = $this->_compile($this->_elseValue, $generator); - } - $parts[] = 'END'; - - return implode(' ', $parts); - } - - /** - * {@inheritDoc} - * - */ - public function traverse(callable $visitor) - { - foreach (['_conditions', '_values'] as $part) { - foreach ($this->{$part} as $c) { - if ($c instanceof ExpressionInterface) { - $visitor($c); - $c->traverse($visitor); - } - } - } - if ($this->_elseValue instanceof ExpressionInterface) { - $visitor($this->_elseValue); - $this->_elseValue->traverse($visitor); - } - } -} diff --git a/vendor/cakephp/cakephp/src/Database/Expression/Comparison.php b/vendor/cakephp/cakephp/src/Database/Expression/Comparison.php deleted file mode 100644 index 25147e3..0000000 --- a/vendor/cakephp/cakephp/src/Database/Expression/Comparison.php +++ /dev/null @@ -1,313 +0,0 @@ -_type = $type; - } - - $this->setField($field); - $this->setValue($value); - $this->_operator = $operator; - } - - /** - * Sets the value - * - * @param mixed $value The value to compare - * @return void - */ - public function setValue($value) - { - $hasType = isset($this->_type) && is_string($this->_type); - $isMultiple = $hasType && strpos($this->_type, '[]') !== false; - - if ($hasType) { - $value = $this->_castToExpression($value, $this->_type); - } - - if ($isMultiple) { - list($value, $this->_valueExpressions) = $this->_collectExpressions($value); - } - - $this->_isMultiple = $isMultiple; - $this->_value = $value; - } - - /** - * Returns the value used for comparison - * - * @return mixed - */ - public function getValue() - { - return $this->_value; - } - - /** - * Sets the operator to use for the comparison - * - * @param string $operator The operator to be used for the comparison. - * @return void - */ - public function setOperator($operator) - { - $this->_operator = $operator; - } - - /** - * Returns the operator used for comparison - * - * @return string - */ - public function getOperator() - { - return $this->_operator; - } - - /** - * Convert the expression into a SQL fragment. - * - * @param \Cake\Database\ValueBinder $generator Placeholder generator object - * @return string - */ - public function sql(ValueBinder $generator) - { - $field = $this->_field; - - if ($field instanceof ExpressionInterface) { - $field = $field->sql($generator); - } - - if ($this->_value instanceof ExpressionInterface) { - $template = '%s %s (%s)'; - $value = $this->_value->sql($generator); - } else { - list($template, $value) = $this->_stringExpression($generator); - } - - return sprintf($template, $field, $this->_operator, $value); - } - - /** - * {@inheritDoc} - * - */ - public function traverse(callable $callable) - { - if ($this->_field instanceof ExpressionInterface) { - $callable($this->_field); - $this->_field->traverse($callable); - } - - if ($this->_value instanceof ExpressionInterface) { - $callable($this->_value); - $this->_value->traverse($callable); - } - - foreach ($this->_valueExpressions as $v) { - $callable($v); - $v->traverse($callable); - } - } - - /** - * Create a deep clone. - * - * Clones the field and value if they are expression objects. - * - * @return void - */ - public function __clone() - { - foreach (['_value', '_field'] as $prop) { - if ($prop instanceof ExpressionInterface) { - $this->{$prop} = clone $this->{$prop}; - } - } - } - - /** - * Returns a template and a placeholder for the value after registering it - * with the placeholder $generator - * - * @param \Cake\Database\ValueBinder $generator The value binder to use. - * @return array First position containing the template and the second a placeholder - */ - protected function _stringExpression($generator) - { - $template = '%s '; - - if ($this->_field instanceof ExpressionInterface) { - $template = '(%s) '; - } - - if ($this->_isMultiple) { - $template .= '%s (%s)'; - $type = str_replace('[]', '', $this->_type); - $value = $this->_flattenValue($this->_value, $generator, $type); - - // To avoid SQL errors when comparing a field to a list of empty values, - // better just throw an exception here - if ($value === '') { - $field = $this->_field instanceof ExpressionInterface ? $this->_field->sql($generator) : $this->_field; - throw new DatabaseException( - "Impossible to generate condition with empty list of values for field ($field)" - ); - } - } else { - $template .= '%s %s'; - $value = $this->_bindValue($this->_value, $generator, $this->_type); - } - - return [$template, $value]; - } - - /** - * Registers a value in the placeholder generator and returns the generated placeholder - * - * @param mixed $value The value to bind - * @param \Cake\Database\ValueBinder $generator The value binder to use - * @param string $type The type of $value - * @return string generated placeholder - */ - protected function _bindValue($value, $generator, $type) - { - $placeholder = $generator->placeholder('c'); - $generator->bind($placeholder, $value, $type); - - return $placeholder; - } - - /** - * Converts a traversable value into a set of placeholders generated by - * $generator and separated by `,` - * - * @param array|\Traversable $value the value to flatten - * @param \Cake\Database\ValueBinder $generator The value binder to use - * @param string|array|null $type the type to cast values to - * @return string - */ - protected function _flattenValue($value, $generator, $type = 'string') - { - $parts = []; - foreach ($this->_valueExpressions as $k => $v) { - $parts[$k] = $v->sql($generator); - unset($value[$k]); - } - - if (!empty($value)) { - $parts += $generator->generateManyNamed($value, $type); - } - - return implode(',', $parts); - } - - /** - * Returns an array with the original $values in the first position - * and all ExpressionInterface objects that could be found in the second - * position. - * - * @param array|\Traversable $values The rows to insert - * @return array - */ - protected function _collectExpressions($values) - { - if ($values instanceof ExpressionInterface) { - return [$values, []]; - } - - $expressions = $result = []; - $isArray = is_array($values); - - if ($isArray) { - $result = $values; - } - - foreach ($values as $k => $v) { - if ($v instanceof ExpressionInterface) { - $expressions[$k] = $v; - } - - if ($isArray) { - $result[$k] = $v; - } - } - - return [$result, $expressions]; - } -} diff --git a/vendor/cakephp/cakephp/src/Database/Expression/FieldInterface.php b/vendor/cakephp/cakephp/src/Database/Expression/FieldInterface.php deleted file mode 100644 index 36f753d..0000000 --- a/vendor/cakephp/cakephp/src/Database/Expression/FieldInterface.php +++ /dev/null @@ -1,38 +0,0 @@ -_field = $field; - } - - /** - * Returns the field name - * - * @return string|\Cake\Database\ExpressionInterface - */ - public function getField() - { - return $this->_field; - } -} diff --git a/vendor/cakephp/cakephp/src/Database/Expression/FunctionExpression.php b/vendor/cakephp/cakephp/src/Database/Expression/FunctionExpression.php deleted file mode 100644 index 258b368..0000000 --- a/vendor/cakephp/cakephp/src/Database/Expression/FunctionExpression.php +++ /dev/null @@ -1,200 +0,0 @@ - 'literal', ' rules']);` - * - * Will produce `CONCAT(name, ' rules')` - * - * @param string $name the name of the function to be constructed - * @param array $params list of arguments to be passed to the function - * If associative the key would be used as argument when value is 'literal' - * @param array $types associative array of types to be associated with the - * passed arguments - * @param string $returnType The return type of this expression - */ - public function __construct($name, $params = [], $types = [], $returnType = 'string') - { - $this->_name = $name; - $this->_returnType = $returnType; - parent::__construct($params, $types, ','); - } - - /** - * Sets the name of the SQL function to be invoke in this expression. - * - * @param string $name The name of the function - * @return $this - */ - public function setName($name) - { - $this->_name = $name; - - return $this; - } - - /** - * Gets the name of the SQL function to be invoke in this expression. - * - * @return string - */ - public function getName() - { - return $this->_name; - } - - /** - * Sets the name of the SQL function to be invoke in this expression, - * if no value is passed it will return current name - * - * @deprecated 3.4.0 Use setName()/getName() instead. - * @param string|null $name The name of the function - * @return string|$this - */ - public function name($name = null) - { - deprecationWarning( - 'FunctionExpression::name() is deprecated. ' . - 'Use FunctionExpression::setName()/getName() instead.' - ); - if ($name !== null) { - return $this->setName($name); - } - - return $this->getName(); - } - - /** - * Adds one or more arguments for the function call. - * - * @param array $params list of arguments to be passed to the function - * If associative the key would be used as argument when value is 'literal' - * @param array $types associative array of types to be associated with the - * passed arguments - * @param bool $prepend Whether to prepend or append to the list of arguments - * @see \Cake\Database\Expression\FunctionExpression::__construct() for more details. - * @return $this - */ - public function add($params, $types = [], $prepend = false) - { - $put = $prepend ? 'array_unshift' : 'array_push'; - $typeMap = $this->getTypeMap()->setTypes($types); - foreach ($params as $k => $p) { - if ($p === 'literal') { - $put($this->_conditions, $k); - continue; - } - - if ($p === 'identifier') { - $put($this->_conditions, new IdentifierExpression($k)); - continue; - } - - $type = $typeMap->type($k); - - if ($type !== null && !$p instanceof ExpressionInterface) { - $p = $this->_castToExpression($p, $type); - } - - if ($p instanceof ExpressionInterface) { - $put($this->_conditions, $p); - continue; - } - - $put($this->_conditions, ['value' => $p, 'type' => $type]); - } - - return $this; - } - - /** - * Returns the string representation of this object so that it can be used in a - * SQL query. Note that values condition values are not included in the string, - * in their place placeholders are put and can be replaced by the quoted values - * accordingly. - * - * @param \Cake\Database\ValueBinder $generator Placeholder generator object - * @return string - */ - public function sql(ValueBinder $generator) - { - $parts = []; - foreach ($this->_conditions as $condition) { - if ($condition instanceof ExpressionInterface) { - $condition = sprintf('%s', $condition->sql($generator)); - } elseif (is_array($condition)) { - $p = $generator->placeholder('param'); - $generator->bind($p, $condition['value'], $condition['type']); - $condition = $p; - } - $parts[] = $condition; - } - - return $this->_name . sprintf('(%s)', implode( - $this->_conjunction . ' ', - $parts - )); - } - - /** - * The name of the function is in itself an expression to generate, thus - * always adding 1 to the amount of expressions stored in this object. - * - * @return int - */ - public function count() - { - return 1 + count($this->_conditions); - } -} diff --git a/vendor/cakephp/cakephp/src/Database/Expression/IdentifierExpression.php b/vendor/cakephp/cakephp/src/Database/Expression/IdentifierExpression.php deleted file mode 100644 index 8aa9a20..0000000 --- a/vendor/cakephp/cakephp/src/Database/Expression/IdentifierExpression.php +++ /dev/null @@ -1,90 +0,0 @@ -_identifier = $identifier; - } - - /** - * Sets the identifier this expression represents - * - * @param string $identifier The identifier - * @return void - */ - public function setIdentifier($identifier) - { - $this->_identifier = $identifier; - } - - /** - * Returns the identifier this expression represents - * - * @return string - */ - public function getIdentifier() - { - return $this->_identifier; - } - - /** - * Converts the expression to its string representation - * - * @param \Cake\Database\ValueBinder $generator Placeholder generator object - * @return string - */ - public function sql(ValueBinder $generator) - { - return $this->_identifier; - } - - /** - * This method is a no-op, this is a leaf type of expression, - * hence there is nothing to traverse - * - * @param callable $callable The callable to traverse with. - * @return void - */ - public function traverse(callable $callable) - { - } -} diff --git a/vendor/cakephp/cakephp/src/Database/Expression/OrderByExpression.php b/vendor/cakephp/cakephp/src/Database/Expression/OrderByExpression.php deleted file mode 100644 index 41a01cc..0000000 --- a/vendor/cakephp/cakephp/src/Database/Expression/OrderByExpression.php +++ /dev/null @@ -1,79 +0,0 @@ -_conditions as $k => $direction) { - if ($direction instanceof ExpressionInterface) { - $direction = $direction->sql($generator); - } - $order[] = is_numeric($k) ? $direction : sprintf('%s %s', $k, $direction); - } - - return sprintf('ORDER BY %s', implode(', ', $order)); - } - - /** - * Auxiliary function used for decomposing a nested array of conditions and - * building a tree structure inside this object to represent the full SQL expression. - * - * New order by expressions are merged to existing ones - * - * @param array $orders list of order by expressions - * @param array $types list of types associated on fields referenced in $conditions - * @return void - */ - protected function _addConditions(array $orders, array $types) - { - foreach ($orders as $key => $val) { - if (is_string($key) && is_string($val) && !in_array(strtoupper($val), ['ASC', 'DESC'], true)) { - deprecationWarning( - 'Passing extra sort expressions by associative array is deprecated. ' . - 'Use QueryExpression or numeric array instead.' - ); - } - } - $this->_conditions = array_merge($this->_conditions, $orders); - } -} diff --git a/vendor/cakephp/cakephp/src/Database/Expression/OrderClauseExpression.php b/vendor/cakephp/cakephp/src/Database/Expression/OrderClauseExpression.php deleted file mode 100644 index 11f04de..0000000 --- a/vendor/cakephp/cakephp/src/Database/Expression/OrderClauseExpression.php +++ /dev/null @@ -1,81 +0,0 @@ -_field = $field; - $this->_direction = strtolower($direction) === 'asc' ? 'ASC' : 'DESC'; - } - - /** - * {@inheritDoc} - */ - public function sql(ValueBinder $generator) - { - $field = $this->_field; - if ($field instanceof ExpressionInterface) { - $field = $field->sql($generator); - } - - return sprintf('%s %s', $field, $this->_direction); - } - - /** - * {@inheritDoc} - */ - public function traverse(callable $visitor) - { - if ($this->_field instanceof ExpressionInterface) { - $visitor($this->_field); - $this->_field->traverse($visitor); - } - } - - /** - * Create a deep clone of the order clause. - * - * @return void - */ - public function __clone() - { - if ($this->_field instanceof ExpressionInterface) { - $this->_field = clone $this->_field; - } - } -} diff --git a/vendor/cakephp/cakephp/src/Database/Expression/QueryExpression.php b/vendor/cakephp/cakephp/src/Database/Expression/QueryExpression.php deleted file mode 100644 index 37d8dde..0000000 --- a/vendor/cakephp/cakephp/src/Database/Expression/QueryExpression.php +++ /dev/null @@ -1,823 +0,0 @@ - :value" - * - * @var array - */ - protected $_conditions = []; - - /** - * Constructor. A new expression object can be created without any params and - * be built dynamically. Otherwise it is possible to pass an array of conditions - * containing either a tree-like array structure to be parsed and/or other - * expression objects. Optionally, you can set the conjunction keyword to be used - * for joining each part of this level of the expression tree. - * - * @param string|array|\Cake\Database\ExpressionInterface $conditions tree-like array structure containing all the conditions - * to be added or nested inside this expression object. - * @param array|\Cake\Database\TypeMap $types associative array of types to be associated with the values - * passed in $conditions. - * @param string $conjunction the glue that will join all the string conditions at this - * level of the expression tree. For example "AND", "OR", "XOR"... - * @see \Cake\Database\Expression\QueryExpression::add() for more details on $conditions and $types - */ - public function __construct($conditions = [], $types = [], $conjunction = 'AND') - { - $this->setTypeMap($types); - $this->setConjunction(strtoupper($conjunction)); - if (!empty($conditions)) { - $this->add($conditions, $this->getTypeMap()->getTypes()); - } - } - - /** - * Changes the conjunction for the conditions at this level of the expression tree. - * - * @param string $conjunction Value to be used for joining conditions - * @return $this - */ - public function setConjunction($conjunction) - { - $this->_conjunction = strtoupper($conjunction); - - return $this; - } - - /** - * Gets the currently configured conjunction for the conditions at this level of the expression tree. - * - * @return string - */ - public function getConjunction() - { - return $this->_conjunction; - } - - /** - * Changes the conjunction for the conditions at this level of the expression tree. - * If called with no arguments it will return the currently configured value. - * - * @deprecated 3.4.0 Use setConjunction()/getConjunction() instead. - * @param string|null $conjunction value to be used for joining conditions. If null it - * will not set any value, but return the currently stored one - * @return string|$this - */ - public function tieWith($conjunction = null) - { - deprecationWarning( - 'QueryExpression::tieWith() is deprecated. ' . - 'Use QueryExpression::setConjunction()/getConjunction() instead.' - ); - if ($conjunction !== null) { - return $this->setConjunction($conjunction); - } - - return $this->getConjunction(); - } - - /** - * Backwards compatible wrapper for tieWith() - * - * @param string|null $conjunction value to be used for joining conditions. If null it - * will not set any value, but return the currently stored one - * @return string|$this - * @deprecated 3.2.0 Use setConjunction()/getConjunction() instead - */ - public function type($conjunction = null) - { - deprecationWarning( - 'QueryExpression::type() is deprecated. ' . - 'Use QueryExpression::setConjunction()/getConjunction() instead.' - ); - - return $this->tieWith($conjunction); - } - - /** - * Adds one or more conditions to this expression object. Conditions can be - * expressed in a one dimensional array, that will cause all conditions to - * be added directly at this level of the tree or they can be nested arbitrarily - * making it create more expression objects that will be nested inside and - * configured to use the specified conjunction. - * - * If the type passed for any of the fields is expressed "type[]" (note braces) - * then it will cause the placeholder to be re-written dynamically so if the - * value is an array, it will create as many placeholders as values are in it. - * - * @param string|array|\Cake\Database\ExpressionInterface $conditions single or multiple conditions to - * be added. When using an array and the key is 'OR' or 'AND' a new expression - * object will be created with that conjunction and internal array value passed - * as conditions. - * @param array $types associative array of fields pointing to the type of the - * values that are being passed. Used for correctly binding values to statements. - * @see \Cake\Database\Query::where() for examples on conditions - * @return $this - */ - public function add($conditions, $types = []) - { - if (is_string($conditions)) { - $this->_conditions[] = $conditions; - - return $this; - } - - if ($conditions instanceof ExpressionInterface) { - $this->_conditions[] = $conditions; - - return $this; - } - - $this->_addConditions($conditions, $types); - - return $this; - } - - /** - * Adds a new condition to the expression object in the form "field = value". - * - * @param string|\Cake\Database\ExpressionInterface $field Database field to be compared against value - * @param mixed $value The value to be bound to $field for comparison - * @param string|null $type the type name for $value as configured using the Type map. - * If it is suffixed with "[]" and the value is an array then multiple placeholders - * will be created, one per each value in the array. - * @return $this - */ - public function eq($field, $value, $type = null) - { - if ($type === null) { - $type = $this->_calculateType($field); - } - - return $this->add(new Comparison($field, $value, $type, '=')); - } - - /** - * Adds a new condition to the expression object in the form "field != value". - * - * @param string|\Cake\Database\ExpressionInterface $field Database field to be compared against value - * @param mixed $value The value to be bound to $field for comparison - * @param string|null $type the type name for $value as configured using the Type map. - * If it is suffixed with "[]" and the value is an array then multiple placeholders - * will be created, one per each value in the array. - * @return $this - */ - public function notEq($field, $value, $type = null) - { - if ($type === null) { - $type = $this->_calculateType($field); - } - - return $this->add(new Comparison($field, $value, $type, '!=')); - } - - /** - * Adds a new condition to the expression object in the form "field > value". - * - * @param string|\Cake\Database\ExpressionInterface $field Database field to be compared against value - * @param mixed $value The value to be bound to $field for comparison - * @param string|null $type the type name for $value as configured using the Type map. - * @return $this - */ - public function gt($field, $value, $type = null) - { - if ($type === null) { - $type = $this->_calculateType($field); - } - - return $this->add(new Comparison($field, $value, $type, '>')); - } - - /** - * Adds a new condition to the expression object in the form "field < value". - * - * @param string|\Cake\Database\ExpressionInterface $field Database field to be compared against value - * @param mixed $value The value to be bound to $field for comparison - * @param string|null $type the type name for $value as configured using the Type map. - * @return $this - */ - public function lt($field, $value, $type = null) - { - if ($type === null) { - $type = $this->_calculateType($field); - } - - return $this->add(new Comparison($field, $value, $type, '<')); - } - - /** - * Adds a new condition to the expression object in the form "field >= value". - * - * @param string|\Cake\Database\ExpressionInterface $field Database field to be compared against value - * @param mixed $value The value to be bound to $field for comparison - * @param string|null $type the type name for $value as configured using the Type map. - * @return $this - */ - public function gte($field, $value, $type = null) - { - if ($type === null) { - $type = $this->_calculateType($field); - } - - return $this->add(new Comparison($field, $value, $type, '>=')); - } - - /** - * Adds a new condition to the expression object in the form "field <= value". - * - * @param string|\Cake\Database\ExpressionInterface $field Database field to be compared against value - * @param mixed $value The value to be bound to $field for comparison - * @param string|null $type the type name for $value as configured using the Type map. - * @return $this - */ - public function lte($field, $value, $type = null) - { - if ($type === null) { - $type = $this->_calculateType($field); - } - - return $this->add(new Comparison($field, $value, $type, '<=')); - } - - /** - * Adds a new condition to the expression object in the form "field IS NULL". - * - * @param string|\Cake\Database\ExpressionInterface $field database field to be - * tested for null - * @return $this - */ - public function isNull($field) - { - if (!($field instanceof ExpressionInterface)) { - $field = new IdentifierExpression($field); - } - - return $this->add(new UnaryExpression('IS NULL', $field, UnaryExpression::POSTFIX)); - } - - /** - * Adds a new condition to the expression object in the form "field IS NOT NULL". - * - * @param string|\Cake\Database\ExpressionInterface $field database field to be - * tested for not null - * @return $this - */ - public function isNotNull($field) - { - if (!($field instanceof ExpressionInterface)) { - $field = new IdentifierExpression($field); - } - - return $this->add(new UnaryExpression('IS NOT NULL', $field, UnaryExpression::POSTFIX)); - } - - /** - * Adds a new condition to the expression object in the form "field LIKE value". - * - * @param string|\Cake\Database\ExpressionInterface $field Database field to be compared against value - * @param mixed $value The value to be bound to $field for comparison - * @param string|null $type the type name for $value as configured using the Type map. - * @return $this - */ - public function like($field, $value, $type = null) - { - if ($type === null) { - $type = $this->_calculateType($field); - } - - return $this->add(new Comparison($field, $value, $type, 'LIKE')); - } - - /** - * Adds a new condition to the expression object in the form "field NOT LIKE value". - * - * @param string|\Cake\Database\ExpressionInterface $field Database field to be compared against value - * @param mixed $value The value to be bound to $field for comparison - * @param string|null $type the type name for $value as configured using the Type map. - * @return $this - */ - public function notLike($field, $value, $type = null) - { - if ($type === null) { - $type = $this->_calculateType($field); - } - - return $this->add(new Comparison($field, $value, $type, 'NOT LIKE')); - } - - /** - * Adds a new condition to the expression object in the form - * "field IN (value1, value2)". - * - * @param string|\Cake\Database\ExpressionInterface $field Database field to be compared against value - * @param string|array $values the value to be bound to $field for comparison - * @param string|null $type the type name for $value as configured using the Type map. - * @return $this - */ - public function in($field, $values, $type = null) - { - if ($type === null) { - $type = $this->_calculateType($field); - } - $type = $type ?: 'string'; - $type .= '[]'; - $values = $values instanceof ExpressionInterface ? $values : (array)$values; - - return $this->add(new Comparison($field, $values, $type, 'IN')); - } - - /** - * Adds a new case expression to the expression object - * - * @param array|\Cake\Database\ExpressionInterface $conditions The conditions to test. Must be a ExpressionInterface - * instance, or an array of ExpressionInterface instances. - * @param array|\Cake\Database\ExpressionInterface $values associative array of values to be associated with the conditions - * passed in $conditions. If there are more $values than $conditions, the last $value is used as the `ELSE` value - * @param array $types associative array of types to be associated with the values - * passed in $values - * @return $this - */ - public function addCase($conditions, $values = [], $types = []) - { - return $this->add(new CaseExpression($conditions, $values, $types)); - } - - /** - * Adds a new condition to the expression object in the form - * "field NOT IN (value1, value2)". - * - * @param string|\Cake\Database\ExpressionInterface $field Database field to be compared against value - * @param array $values the value to be bound to $field for comparison - * @param string|null $type the type name for $value as configured using the Type map. - * @return $this - */ - public function notIn($field, $values, $type = null) - { - if ($type === null) { - $type = $this->_calculateType($field); - } - $type = $type ?: 'string'; - $type .= '[]'; - $values = $values instanceof ExpressionInterface ? $values : (array)$values; - - return $this->add(new Comparison($field, $values, $type, 'NOT IN')); - } - - /** - * Adds a new condition to the expression object in the form "EXISTS (...)". - * - * @param \Cake\Database\ExpressionInterface $query the inner query - * @return $this - */ - public function exists(ExpressionInterface $query) - { - return $this->add(new UnaryExpression('EXISTS', $query, UnaryExpression::PREFIX)); - } - - /** - * Adds a new condition to the expression object in the form "NOT EXISTS (...)". - * - * @param \Cake\Database\ExpressionInterface $query the inner query - * @return $this - */ - public function notExists(ExpressionInterface $query) - { - return $this->add(new UnaryExpression('NOT EXISTS', $query, UnaryExpression::PREFIX)); - } - - /** - * Adds a new condition to the expression object in the form - * "field BETWEEN from AND to". - * - * @param string|\Cake\Database\ExpressionInterface $field The field name to compare for values in between the range. - * @param mixed $from The initial value of the range. - * @param mixed $to The ending value in the comparison range. - * @param string|null $type the type name for $value as configured using the Type map. - * @return $this - */ - public function between($field, $from, $to, $type = null) - { - if ($type === null) { - $type = $this->_calculateType($field); - } - - return $this->add(new BetweenExpression($field, $from, $to, $type)); - } - -// @codingStandardsIgnoreStart - /** - * Returns a new QueryExpression object containing all the conditions passed - * and set up the conjunction to be "AND" - * - * @param string|array|\Cake\Database\ExpressionInterface $conditions to be joined with AND - * @param array $types associative array of fields pointing to the type of the - * values that are being passed. Used for correctly binding values to statements. - * @return \Cake\Database\Expression\QueryExpression - */ - public function and_($conditions, $types = []) - { - if ($this->isCallable($conditions)) { - return $conditions(new static([], $this->getTypeMap()->setTypes($types))); - } - - return new static($conditions, $this->getTypeMap()->setTypes($types)); - } - - /** - * Returns a new QueryExpression object containing all the conditions passed - * and set up the conjunction to be "OR" - * - * @param string|array|\Cake\Database\ExpressionInterface $conditions to be joined with OR - * @param array $types associative array of fields pointing to the type of the - * values that are being passed. Used for correctly binding values to statements. - * @return \Cake\Database\Expression\QueryExpression - */ - public function or_($conditions, $types = []) - { - if ($this->isCallable($conditions)) { - return $conditions(new static([], $this->getTypeMap()->setTypes($types), 'OR')); - } - - return new static($conditions, $this->getTypeMap()->setTypes($types), 'OR'); - } -// @codingStandardsIgnoreEnd - - /** - * Adds a new set of conditions to this level of the tree and negates - * the final result by prepending a NOT, it will look like - * "NOT ( (condition1) AND (conditions2) )" conjunction depends on the one - * currently configured for this object. - * - * @param string|array|\Cake\Database\ExpressionInterface $conditions to be added and negated - * @param array $types associative array of fields pointing to the type of the - * values that are being passed. Used for correctly binding values to statements. - * @return $this - */ - public function not($conditions, $types = []) - { - return $this->add(['NOT' => $conditions], $types); - } - - /** - * Returns the number of internal conditions that are stored in this expression. - * Useful to determine if this expression object is void or it will generate - * a non-empty string when compiled - * - * @return int - */ - public function count() - { - return count($this->_conditions); - } - - /** - * Builds equal condition or assignment with identifier wrapping. - * - * @param string $left Left join condition field name. - * @param string $right Right join condition field name. - * @return $this - */ - public function equalFields($left, $right) - { - $wrapIdentifier = function ($field) { - if ($field instanceof ExpressionInterface) { - return $field; - } - - return new IdentifierExpression($field); - }; - - return $this->eq($wrapIdentifier($left), $wrapIdentifier($right)); - } - - /** - * Returns the string representation of this object so that it can be used in a - * SQL query. Note that values condition values are not included in the string, - * in their place placeholders are put and can be replaced by the quoted values - * accordingly. - * - * @param \Cake\Database\ValueBinder $generator Placeholder generator object - * @return string - */ - public function sql(ValueBinder $generator) - { - $len = $this->count(); - if ($len === 0) { - return ''; - } - $conjunction = $this->_conjunction; - $template = ($len === 1) ? '%s' : '(%s)'; - $parts = []; - foreach ($this->_conditions as $part) { - if ($part instanceof Query) { - $part = '(' . $part->sql($generator) . ')'; - } elseif ($part instanceof ExpressionInterface) { - $part = $part->sql($generator); - } - if (strlen($part)) { - $parts[] = $part; - } - } - - return sprintf($template, implode(" $conjunction ", $parts)); - } - - /** - * Traverses the tree structure of this query expression by executing a callback - * function for each of the conditions that are included in this object. - * Useful for compiling the final expression, or doing - * introspection in the structure. - * - * Callback function receives as only argument an instance of ExpressionInterface - * - * @param callable $callable The callable to apply to all sub-expressions. - * @return void - */ - public function traverse(callable $callable) - { - foreach ($this->_conditions as $c) { - if ($c instanceof ExpressionInterface) { - $callable($c); - $c->traverse($callable); - } - } - } - - /** - * Executes a callable function for each of the parts that form this expression. - * - * The callable function is required to return a value with which the currently - * visited part will be replaced. If the callable function returns null then - * the part will be discarded completely from this expression. - * - * The callback function will receive each of the conditions as first param and - * the key as second param. It is possible to declare the second parameter as - * passed by reference, this will enable you to change the key under which the - * modified part is stored. - * - * @param callable $callable The callable to apply to each part. - * @return $this - */ - public function iterateParts(callable $callable) - { - $parts = []; - foreach ($this->_conditions as $k => $c) { - $key =& $k; - $part = $callable($c, $key); - if ($part !== null) { - $parts[$key] = $part; - } - } - $this->_conditions = $parts; - - return $this; - } - - /** - * Helps calling the `and()` and `or()` methods transparently. - * - * @param string $method The method name. - * @param array $args The arguments to pass to the method. - * @return \Cake\Database\Expression\QueryExpression - * @throws \BadMethodCallException - */ - public function __call($method, $args) - { - if (in_array($method, ['and', 'or'])) { - return call_user_func_array([$this, $method . '_'], $args); - } - throw new BadMethodCallException(sprintf('Method %s does not exist', $method)); - } - - /** - * Check whether or not a callable is acceptable. - * - * We don't accept ['class', 'method'] style callbacks, - * as they often contain user input and arrays of strings - * are easy to sneak in. - * - * @param callable $c The callable to check. - * @return bool Valid callable. - */ - public function isCallable($c) - { - if (is_string($c)) { - return false; - } - if (is_object($c) && is_callable($c)) { - return true; - } - - return is_array($c) && isset($c[0]) && is_object($c[0]) && is_callable($c); - } - - /** - * Returns true if this expression contains any other nested - * ExpressionInterface objects - * - * @return bool - */ - public function hasNestedExpression() - { - foreach ($this->_conditions as $c) { - if ($c instanceof ExpressionInterface) { - return true; - } - } - - return false; - } - - /** - * Auxiliary function used for decomposing a nested array of conditions and build - * a tree structure inside this object to represent the full SQL expression. - * String conditions are stored directly in the conditions, while any other - * representation is wrapped around an adequate instance or of this class. - * - * @param array $conditions list of conditions to be stored in this object - * @param array $types list of types associated on fields referenced in $conditions - * @return void - */ - protected function _addConditions(array $conditions, array $types) - { - $operators = ['and', 'or', 'xor']; - - $typeMap = $this->getTypeMap()->setTypes($types); - - foreach ($conditions as $k => $c) { - $numericKey = is_numeric($k); - - if ($numericKey && empty($c)) { - continue; - } - - if ($this->isCallable($c)) { - $expr = new static([], $typeMap); - $c = $c($expr, $this); - } - - if ($numericKey && is_string($c)) { - $this->_conditions[] = $c; - continue; - } - - if ($numericKey && is_array($c) || in_array(strtolower($k), $operators)) { - $this->_conditions[] = new static($c, $typeMap, $numericKey ? 'AND' : $k); - continue; - } - - if (strtolower($k) === 'not') { - $this->_conditions[] = new UnaryExpression('NOT', new static($c, $typeMap)); - continue; - } - - if ($c instanceof self && count($c) === 0) { - continue; - } - - if ($numericKey && $c instanceof ExpressionInterface) { - $this->_conditions[] = $c; - continue; - } - - if (!$numericKey) { - $this->_conditions[] = $this->_parseCondition($k, $c); - } - } - } - - /** - * Parses a string conditions by trying to extract the operator inside it if any - * and finally returning either an adequate QueryExpression object or a plain - * string representation of the condition. This function is responsible for - * generating the placeholders and replacing the values by them, while storing - * the value elsewhere for future binding. - * - * @param string $field The value from with the actual field and operator will - * be extracted. - * @param mixed $value The value to be bound to a placeholder for the field - * @return string|\Cake\Database\ExpressionInterface - */ - protected function _parseCondition($field, $value) - { - $operator = '='; - $expression = $field; - $parts = explode(' ', trim($field), 2); - - if (count($parts) > 1) { - list($expression, $operator) = $parts; - } - - $type = $this->getTypeMap()->type($expression); - $operator = strtolower(trim($operator)); - - $typeMultiple = strpos($type, '[]') !== false; - if (in_array($operator, ['in', 'not in']) || $typeMultiple) { - $type = $type ?: 'string'; - $type .= $typeMultiple ? null : '[]'; - $operator = $operator === '=' ? 'IN' : $operator; - $operator = $operator === '!=' ? 'NOT IN' : $operator; - $typeMultiple = true; - } - - if ($typeMultiple) { - $value = $value instanceof ExpressionInterface ? $value : (array)$value; - } - - if ($operator === 'is' && $value === null) { - return new UnaryExpression( - 'IS NULL', - new IdentifierExpression($expression), - UnaryExpression::POSTFIX - ); - } - - if ($operator === 'is not' && $value === null) { - return new UnaryExpression( - 'IS NOT NULL', - new IdentifierExpression($expression), - UnaryExpression::POSTFIX - ); - } - - if ($operator === 'is' && $value !== null) { - $operator = '='; - } - - if ($operator === 'is not' && $value !== null) { - $operator = '!='; - } - - return new Comparison($expression, $value, $type, $operator); - } - - /** - * Returns the type name for the passed field if it was stored in the typeMap - * - * @param string|\Cake\Database\Expression\IdentifierExpression $field The field name to get a type for. - * @return string|null The computed type or null, if the type is unknown. - */ - protected function _calculateType($field) - { - $field = $field instanceof IdentifierExpression ? $field->getIdentifier() : $field; - if (is_string($field)) { - return $this->getTypeMap()->type($field); - } - - return null; - } - - /** - * Clone this object and its subtree of expressions. - * - * @return void - */ - public function __clone() - { - foreach ($this->_conditions as $i => $condition) { - if ($condition instanceof ExpressionInterface) { - $this->_conditions[$i] = clone $condition; - } - } - } -} diff --git a/vendor/cakephp/cakephp/src/Database/Expression/TupleComparison.php b/vendor/cakephp/cakephp/src/Database/Expression/TupleComparison.php deleted file mode 100644 index 40ea664..0000000 --- a/vendor/cakephp/cakephp/src/Database/Expression/TupleComparison.php +++ /dev/null @@ -1,192 +0,0 @@ -_type = (array)$types; - } - - /** - * Convert the expression into a SQL fragment. - * - * @param \Cake\Database\ValueBinder $generator Placeholder generator object - * @return string - */ - public function sql(ValueBinder $generator) - { - $template = '(%s) %s (%s)'; - $fields = []; - $originalFields = $this->getField(); - - if (!is_array($originalFields)) { - $originalFields = [$originalFields]; - } - - foreach ($originalFields as $field) { - $fields[] = $field instanceof ExpressionInterface ? $field->sql($generator) : $field; - } - - $values = $this->_stringifyValues($generator); - - $field = implode(', ', $fields); - - return sprintf($template, $field, $this->_operator, $values); - } - - /** - * Returns a string with the values as placeholders in a string to be used - * for the SQL version of this expression - * - * @param \Cake\Database\ValueBinder $generator The value binder to convert expressions with. - * @return string - */ - protected function _stringifyValues($generator) - { - $values = []; - $parts = $this->getValue(); - - if ($parts instanceof ExpressionInterface) { - return $parts->sql($generator); - } - - foreach ($parts as $i => $value) { - if ($value instanceof ExpressionInterface) { - $values[] = $value->sql($generator); - continue; - } - - $type = $this->_type; - $multiType = is_array($type); - $isMulti = $this->isMulti(); - $type = $multiType ? $type : str_replace('[]', '', $type); - $type = $type ?: null; - - if ($isMulti) { - $bound = []; - foreach ($value as $k => $val) { - $valType = $multiType ? $type[$k] : $type; - $bound[] = $this->_bindValue($generator, $val, $valType); - } - - $values[] = sprintf('(%s)', implode(',', $bound)); - continue; - } - - $valType = $multiType && isset($type[$i]) ? $type[$i] : $type; - $values[] = $this->_bindValue($generator, $value, $valType); - } - - return implode(', ', $values); - } - - /** - * Registers a value in the placeholder generator and returns the generated - * placeholder - * - * @param \Cake\Database\ValueBinder $generator The value binder - * @param mixed $value The value to bind - * @param string $type The type to use - * @return string generated placeholder - */ - protected function _bindValue($generator, $value, $type) - { - $placeholder = $generator->placeholder('tuple'); - $generator->bind($placeholder, $value, $type); - - return $placeholder; - } - - /** - * Traverses the tree of expressions stored in this object, visiting first - * expressions in the left hand side and then the rest. - * - * Callback function receives as its only argument an instance of an ExpressionInterface - * - * @param callable $callable The callable to apply to sub-expressions - * @return void - */ - public function traverse(callable $callable) - { - foreach ($this->getField() as $field) { - $this->_traverseValue($field, $callable); - } - - $value = $this->getValue(); - if ($value instanceof ExpressionInterface) { - $callable($value); - $value->traverse($callable); - - return; - } - - foreach ($value as $i => $val) { - if ($this->isMulti()) { - foreach ($val as $v) { - $this->_traverseValue($v, $callable); - } - } else { - $this->_traverseValue($val, $callable); - } - } - } - - /** - * Conditionally executes the callback for the passed value if - * it is an ExpressionInterface - * - * @param mixed $value The value to traverse - * @param callable $callable The callable to use when traversing - * @return void - */ - protected function _traverseValue($value, $callable) - { - if ($value instanceof ExpressionInterface) { - $callable($value); - $value->traverse($callable); - } - } - - /** - * Determines if each of the values in this expressions is a tuple in - * itself - * - * @return bool - */ - public function isMulti() - { - return in_array(strtolower($this->_operator), ['in', 'not in']); - } -} diff --git a/vendor/cakephp/cakephp/src/Database/Expression/UnaryExpression.php b/vendor/cakephp/cakephp/src/Database/Expression/UnaryExpression.php deleted file mode 100644 index f58fd67..0000000 --- a/vendor/cakephp/cakephp/src/Database/Expression/UnaryExpression.php +++ /dev/null @@ -1,116 +0,0 @@ -_operator = $operator; - $this->_value = $value; - $this->_mode = $mode; - } - - /** - * Converts the expression to its string representation - * - * @param \Cake\Database\ValueBinder $generator Placeholder generator object - * @return string - */ - public function sql(ValueBinder $generator) - { - $operand = $this->_value; - if ($operand instanceof ExpressionInterface) { - $operand = $operand->sql($generator); - } - - if ($this->_mode === self::POSTFIX) { - return '(' . $operand . ') ' . $this->_operator; - } - - return $this->_operator . ' (' . $operand . ')'; - } - - /** - * {@inheritDoc} - * - */ - public function traverse(callable $callable) - { - if ($this->_value instanceof ExpressionInterface) { - $callable($this->_value); - $this->_value->traverse($callable); - } - } - - /** - * Perform a deep clone of the inner expression. - * - * @return void - */ - public function __clone() - { - if ($this->_value instanceof ExpressionInterface) { - $this->_value = clone $this->_value; - } - } -} diff --git a/vendor/cakephp/cakephp/src/Database/Expression/ValuesExpression.php b/vendor/cakephp/cakephp/src/Database/Expression/ValuesExpression.php deleted file mode 100644 index 261e512..0000000 --- a/vendor/cakephp/cakephp/src/Database/Expression/ValuesExpression.php +++ /dev/null @@ -1,385 +0,0 @@ - type names - */ - public function __construct(array $columns, $typeMap) - { - $this->_columns = $columns; - $this->setTypeMap($typeMap); - } - - /** - * Add a row of data to be inserted. - * - * @param array|\Cake\Database\Query $data Array of data to append into the insert, or - * a query for doing INSERT INTO .. SELECT style commands - * @return void - * @throws \Cake\Database\Exception When mixing array + Query data types. - */ - public function add($data) - { - if ((count($this->_values) && $data instanceof Query) || - ($this->_query && is_array($data)) - ) { - throw new Exception( - 'You cannot mix subqueries and array data in inserts.' - ); - } - if ($data instanceof Query) { - $this->setQuery($data); - - return; - } - $this->_values[] = $data; - $this->_castedExpressions = false; - } - - /** - * Sets the columns to be inserted. - * - * @param array $cols Array with columns to be inserted. - * @return $this - */ - public function setColumns($cols) - { - $this->_columns = $cols; - $this->_castedExpressions = false; - - return $this; - } - - /** - * Gets the columns to be inserted. - * - * @return array - */ - public function getColumns() - { - return $this->_columns; - } - - /** - * Sets the columns to be inserted. If no params are passed, then it returns - * the currently stored columns. - * - * @deprecated 3.4.0 Use setColumns()/getColumns() instead. - * @param array|null $cols Array with columns to be inserted. - * @return array|$this - */ - public function columns($cols = null) - { - deprecationWarning( - 'ValuesExpression::columns() is deprecated. ' . - 'Use ValuesExpression::setColumns()/getColumns() instead.' - ); - if ($cols !== null) { - return $this->setColumns($cols); - } - - return $this->getColumns(); - } - - /** - * Get the bare column names. - * - * Because column names could be identifier quoted, we - * need to strip the identifiers off of the columns. - * - * @return array - */ - protected function _columnNames() - { - $columns = []; - foreach ($this->_columns as $col) { - if (is_string($col)) { - $col = trim($col, '`[]"'); - } - $columns[] = $col; - } - - return $columns; - } - - /** - * Sets the values to be inserted. - * - * @param array $values Array with values to be inserted. - * @return $this - */ - public function setValues($values) - { - $this->_values = $values; - $this->_castedExpressions = false; - - return $this; - } - - /** - * Gets the values to be inserted. - * - * @return array - */ - public function getValues() - { - if (!$this->_castedExpressions) { - $this->_processExpressions(); - } - - return $this->_values; - } - - /** - * Sets the values to be inserted. If no params are passed, then it returns - * the currently stored values - * - * @deprecated 3.4.0 Use setValues()/getValues() instead. - * @param array|null $values Array with values to be inserted. - * @return array|$this - */ - public function values($values = null) - { - deprecationWarning( - 'ValuesExpression::values() is deprecated. ' . - 'Use ValuesExpression::setValues()/getValues() instead.' - ); - if ($values !== null) { - return $this->setValues($values); - } - - return $this->getValues(); - } - - /** - * Sets the query object to be used as the values expression to be evaluated - * to insert records in the table. - * - * @param \Cake\Database\Query $query The query to set - * @return $this - */ - public function setQuery(Query $query) - { - $this->_query = $query; - - return $this; - } - - /** - * Gets the query object to be used as the values expression to be evaluated - * to insert records in the table. - * - * @return \Cake\Database\Query|null - */ - public function getQuery() - { - return $this->_query; - } - - /** - * Sets the query object to be used as the values expression to be evaluated - * to insert records in the table. If no params are passed, then it returns - * the currently stored query - * - * @deprecated 3.4.0 Use setQuery()/getQuery() instead. - * @param \Cake\Database\Query|null $query The query to set - * @return \Cake\Database\Query|null|$this - */ - public function query(Query $query = null) - { - deprecationWarning( - 'ValuesExpression::query() is deprecated. ' . - 'Use ValuesExpression::setQuery()/getQuery() instead.' - ); - if ($query !== null) { - return $this->setQuery($query); - } - - return $this->getQuery(); - } - - /** - * Convert the values into a SQL string with placeholders. - * - * @param \Cake\Database\ValueBinder $generator Placeholder generator object - * @return string - */ - public function sql(ValueBinder $generator) - { - if (empty($this->_values) && empty($this->_query)) { - return ''; - } - - if (!$this->_castedExpressions) { - $this->_processExpressions(); - } - - $columns = $this->_columnNames(); - $defaults = array_fill_keys($columns, null); - $placeholders = []; - - $types = []; - $typeMap = $this->getTypeMap(); - foreach ($defaults as $col => $v) { - $types[$col] = $typeMap->type($col); - } - - foreach ($this->_values as $row) { - $row += $defaults; - $rowPlaceholders = []; - - foreach ($columns as $column) { - $value = $row[$column]; - - if ($value instanceof ExpressionInterface) { - $rowPlaceholders[] = '(' . $value->sql($generator) . ')'; - continue; - } - - $placeholder = $generator->placeholder('c'); - $rowPlaceholders[] = $placeholder; - $generator->bind($placeholder, $value, $types[$column]); - } - - $placeholders[] = implode(', ', $rowPlaceholders); - } - - if ($this->getQuery()) { - return ' ' . $this->getQuery()->sql($generator); - } - - return sprintf(' VALUES (%s)', implode('), (', $placeholders)); - } - - /** - * Traverse the values expression. - * - * This method will also traverse any queries that are to be used in the INSERT - * values. - * - * @param callable $visitor The visitor to traverse the expression with. - * @return void - */ - public function traverse(callable $visitor) - { - if ($this->_query) { - return; - } - - if (!$this->_castedExpressions) { - $this->_processExpressions(); - } - - foreach ($this->_values as $v) { - if ($v instanceof ExpressionInterface) { - $v->traverse($visitor); - } - if (!is_array($v)) { - continue; - } - foreach ($v as $column => $field) { - if ($field instanceof ExpressionInterface) { - $visitor($field); - $field->traverse($visitor); - } - } - } - } - - /** - * Converts values that need to be casted to expressions - * - * @return void - */ - protected function _processExpressions() - { - $types = []; - $typeMap = $this->getTypeMap(); - - $columns = $this->_columnNames(); - foreach ($columns as $c) { - if (!is_scalar($c)) { - continue; - } - $types[$c] = $typeMap->type($c); - } - - $types = $this->_requiresToExpressionCasting($types); - - if (empty($types)) { - return; - } - - foreach ($this->_values as $row => $values) { - foreach ($types as $col => $type) { - /* @var \Cake\Database\Type\ExpressionTypeInterface $type */ - $this->_values[$row][$col] = $type->toExpression($values[$col]); - } - } - $this->_castedExpressions = true; - } -} diff --git a/vendor/cakephp/cakephp/src/Database/ExpressionInterface.php b/vendor/cakephp/cakephp/src/Database/ExpressionInterface.php deleted file mode 100644 index 57b6667..0000000 --- a/vendor/cakephp/cakephp/src/Database/ExpressionInterface.php +++ /dev/null @@ -1,41 +0,0 @@ -_driver = $driver; - $map = $typeMap->toArray(); - $types = Type::buildAll(); - - $simpleMap = $batchingMap = []; - $simpleResult = $batchingResult = []; - - foreach ($types as $k => $type) { - if ($type instanceof OptionalConvertInterface && !$type->requiresToPhpCast()) { - continue; - } - - // Because of backwards compatibility reasons, we won't allow classes - // inheriting Type in userland code to be batchable, even if they implement - // the interface. Users can implement the TypeInterface instead to have - // access to this feature. - $batchingType = $type instanceof BatchCastingInterface && - !($type instanceof Type && - strpos(get_class($type), 'Cake\Database\Type') === false); - - if ($batchingType) { - $batchingMap[$k] = $type; - continue; - } - - $simpleMap[$k] = $type; - } - - foreach ($map as $field => $type) { - if (isset($simpleMap[$type])) { - $simpleResult[$field] = $simpleMap[$type]; - continue; - } - if (isset($batchingMap[$type])) { - $batchingResult[$type][] = $field; - } - } - - // Using batching when there is only a couple for the type is actually slower, - // so, let's check for that case here. - foreach ($batchingResult as $type => $fields) { - if (count($fields) > 2) { - continue; - } - - foreach ($fields as $f) { - $simpleResult[$f] = $batchingMap[$type]; - } - unset($batchingResult[$type]); - } - - $this->types = $types; - $this->_typeMap = $simpleResult; - $this->batchingTypeMap = $batchingResult; - } - - /** - * Converts each of the fields in the array that are present in the type map - * using the corresponding Type class. - * - * @param array $row The array with the fields to be casted - * @return array - */ - public function __invoke($row) - { - if (!empty($this->_typeMap)) { - foreach ($this->_typeMap as $field => $type) { - $row[$field] = $type->toPHP($row[$field], $this->_driver); - } - } - - if (!empty($this->batchingTypeMap)) { - foreach ($this->batchingTypeMap as $t => $fields) { - $row = $this->types[$t]->manyToPHP($row, $fields, $this->_driver); - } - } - - return $row; - } -} diff --git a/vendor/cakephp/cakephp/src/Database/FunctionsBuilder.php b/vendor/cakephp/cakephp/src/Database/FunctionsBuilder.php deleted file mode 100644 index 0bab11d..0000000 --- a/vendor/cakephp/cakephp/src/Database/FunctionsBuilder.php +++ /dev/null @@ -1,284 +0,0 @@ - 'literal']; - } - - return $this->_build($name, $expression, $types, $return); - } - - /** - * Returns a FunctionExpression representing a call to SQL SUM function. - * - * @param mixed $expression the function argument - * @param array $types list of types to bind to the arguments - * @return \Cake\Database\Expression\FunctionExpression - */ - public function sum($expression, $types = []) - { - $returnType = 'float'; - if (current($types) === 'integer') { - $returnType = 'integer'; - } - - return $this->_literalArgumentFunction('SUM', $expression, $types, $returnType); - } - - /** - * Returns a FunctionExpression representing a call to SQL AVG function. - * - * @param mixed $expression the function argument - * @param array $types list of types to bind to the arguments - * @return \Cake\Database\Expression\FunctionExpression - */ - public function avg($expression, $types = []) - { - return $this->_literalArgumentFunction('AVG', $expression, $types, 'float'); - } - - /** - * Returns a FunctionExpression representing a call to SQL MAX function. - * - * @param mixed $expression the function argument - * @param array $types list of types to bind to the arguments - * @return \Cake\Database\Expression\FunctionExpression - */ - public function max($expression, $types = []) - { - return $this->_literalArgumentFunction('MAX', $expression, $types, current($types) ?: 'string'); - } - - /** - * Returns a FunctionExpression representing a call to SQL MIN function. - * - * @param mixed $expression the function argument - * @param array $types list of types to bind to the arguments - * @return \Cake\Database\Expression\FunctionExpression - */ - public function min($expression, $types = []) - { - return $this->_literalArgumentFunction('MIN', $expression, $types, current($types) ?: 'string'); - } - - /** - * Returns a FunctionExpression representing a call to SQL COUNT function. - * - * @param mixed $expression the function argument - * @param array $types list of types to bind to the arguments - * @return \Cake\Database\Expression\FunctionExpression - */ - public function count($expression, $types = []) - { - return $this->_literalArgumentFunction('COUNT', $expression, $types, 'integer'); - } - - /** - * Returns a FunctionExpression representing a string concatenation - * - * @param array $args List of strings or expressions to concatenate - * @param array $types list of types to bind to the arguments - * @return \Cake\Database\Expression\FunctionExpression - */ - public function concat($args, $types = []) - { - return $this->_build('CONCAT', $args, $types, 'string'); - } - - /** - * Returns a FunctionExpression representing a call to SQL COALESCE function. - * - * @param array $args List of expressions to evaluate as function parameters - * @param array $types list of types to bind to the arguments - * @return \Cake\Database\Expression\FunctionExpression - */ - public function coalesce($args, $types = []) - { - return $this->_build('COALESCE', $args, $types, current($types) ?: 'string'); - } - - /** - * Returns a FunctionExpression representing the difference in days between - * two dates. - * - * @param array $args List of expressions to obtain the difference in days. - * @param array $types list of types to bind to the arguments - * @return \Cake\Database\Expression\FunctionExpression - */ - public function dateDiff($args, $types = []) - { - return $this->_build('DATEDIFF', $args, $types, 'integer'); - } - - /** - * Returns the specified date part from the SQL expression. - * - * @param string $part Part of the date to return. - * @param string $expression Expression to obtain the date part from. - * @param array $types list of types to bind to the arguments - * @return \Cake\Database\Expression\FunctionExpression - */ - public function datePart($part, $expression, $types = []) - { - return $this->extract($part, $expression); - } - - /** - * Returns the specified date part from the SQL expression. - * - * @param string $part Part of the date to return. - * @param string $expression Expression to obtain the date part from. - * @param array $types list of types to bind to the arguments - * @return \Cake\Database\Expression\FunctionExpression - */ - public function extract($part, $expression, $types = []) - { - $expression = $this->_literalArgumentFunction('EXTRACT', $expression, $types, 'integer'); - $expression->setConjunction(' FROM')->add([$part => 'literal'], [], true); - - return $expression; - } - - /** - * Add the time unit to the date expression - * - * @param string $expression Expression to obtain the date part from. - * @param string $value Value to be added. Use negative to substract. - * @param string $unit Unit of the value e.g. hour or day. - * @param array $types list of types to bind to the arguments - * @return \Cake\Database\Expression\FunctionExpression - */ - public function dateAdd($expression, $value, $unit, $types = []) - { - if (!is_numeric($value)) { - $value = 0; - } - $interval = $value . ' ' . $unit; - $expression = $this->_literalArgumentFunction('DATE_ADD', $expression, $types, 'datetime'); - $expression->setConjunction(', INTERVAL')->add([$interval => 'literal']); - - return $expression; - } - - /** - * Returns a FunctionExpression representing a call to SQL WEEKDAY function. - * 1 - Sunday, 2 - Monday, 3 - Tuesday... - * - * @param mixed $expression the function argument - * @param array $types list of types to bind to the arguments - * @return \Cake\Database\Expression\FunctionExpression - */ - public function dayOfWeek($expression, $types = []) - { - return $this->_literalArgumentFunction('DAYOFWEEK', $expression, $types, 'integer'); - } - - /** - * Returns a FunctionExpression representing a call to SQL WEEKDAY function. - * 1 - Sunday, 2 - Monday, 3 - Tuesday... - * - * @param mixed $expression the function argument - * @param array $types list of types to bind to the arguments - * @return \Cake\Database\Expression\FunctionExpression - */ - public function weekday($expression, $types = []) - { - return $this->dayOfWeek($expression, $types); - } - - /** - * Returns a FunctionExpression representing a call that will return the current - * date and time. By default it returns both date and time, but you can also - * make it generate only the date or only the time. - * - * @param string $type (datetime|date|time) - * @return \Cake\Database\Expression\FunctionExpression - */ - public function now($type = 'datetime') - { - if ($type === 'datetime') { - return $this->_build('NOW')->setReturnType('datetime'); - } - if ($type === 'date') { - return $this->_build('CURRENT_DATE')->setReturnType('date'); - } - if ($type === 'time') { - return $this->_build('CURRENT_TIME')->setReturnType('time'); - } - } - - /** - * Magic method dispatcher to create custom SQL function calls - * - * @param string $name the SQL function name to construct - * @param array $args list with up to 3 arguments, first one being an array with - * parameters for the SQL function, the second one a list of types to bind to those - * params, and the third one the return type of the function - * @return \Cake\Database\Expression\FunctionExpression - */ - public function __call($name, $args) - { - switch (count($args)) { - case 0: - return $this->_build($name); - case 1: - return $this->_build($name, $args[0]); - case 2: - return $this->_build($name, $args[0], $args[1]); - default: - return $this->_build($name, $args[0], $args[1], $args[2]); - } - } -} diff --git a/vendor/cakephp/cakephp/src/Database/IdentifierQuoter.php b/vendor/cakephp/cakephp/src/Database/IdentifierQuoter.php deleted file mode 100644 index f5866e8..0000000 --- a/vendor/cakephp/cakephp/src/Database/IdentifierQuoter.php +++ /dev/null @@ -1,264 +0,0 @@ -_driver = $driver; - } - - /** - * Iterates over each of the clauses in a query looking for identifiers and - * quotes them - * - * @param \Cake\Database\Query $query The query to have its identifiers quoted - * @return \Cake\Database\Query - */ - public function quote(Query $query) - { - $binder = $query->getValueBinder(); - $query->setValueBinder(false); - - if ($query->type() === 'insert') { - $this->_quoteInsert($query); - } elseif ($query->type() === 'update') { - $this->_quoteUpdate($query); - } else { - $this->_quoteParts($query); - } - - $query->traverseExpressions([$this, 'quoteExpression']); - $query->setValueBinder($binder); - - return $query; - } - - /** - * Quotes identifiers inside expression objects - * - * @param \Cake\Database\ExpressionInterface $expression The expression object to walk and quote. - * @return void - */ - public function quoteExpression($expression) - { - if ($expression instanceof FieldInterface) { - $this->_quoteComparison($expression); - - return; - } - - if ($expression instanceof OrderByExpression) { - $this->_quoteOrderBy($expression); - - return; - } - - if ($expression instanceof IdentifierExpression) { - $this->_quoteIdentifierExpression($expression); - - return; - } - } - - /** - * Quotes all identifiers in each of the clauses of a query - * - * @param \Cake\Database\Query $query The query to quote. - * @return void - */ - protected function _quoteParts($query) - { - foreach (['distinct', 'select', 'from', 'group'] as $part) { - $contents = $query->clause($part); - - if (!is_array($contents)) { - continue; - } - - $result = $this->_basicQuoter($contents); - if (!empty($result)) { - $query->{$part}($result, true); - } - } - - $joins = $query->clause('join'); - if ($joins) { - $joins = $this->_quoteJoins($joins); - $query->join($joins, [], true); - } - } - - /** - * A generic identifier quoting function used for various parts of the query - * - * @param array $part the part of the query to quote - * @return array - */ - protected function _basicQuoter($part) - { - $result = []; - foreach ((array)$part as $alias => $value) { - $value = !is_string($value) ? $value : $this->_driver->quoteIdentifier($value); - $alias = is_numeric($alias) ? $alias : $this->_driver->quoteIdentifier($alias); - $result[$alias] = $value; - } - - return $result; - } - - /** - * Quotes both the table and alias for an array of joins as stored in a Query - * object - * - * @param array $joins The joins to quote. - * @return array - */ - protected function _quoteJoins($joins) - { - $result = []; - foreach ($joins as $value) { - $alias = null; - if (!empty($value['alias'])) { - $alias = $this->_driver->quoteIdentifier($value['alias']); - $value['alias'] = $alias; - } - - if (is_string($value['table'])) { - $value['table'] = $this->_driver->quoteIdentifier($value['table']); - } - - $result[$alias] = $value; - } - - return $result; - } - - /** - * Quotes the table name and columns for an insert query - * - * @param \Cake\Database\Query $query The insert query to quote. - * @return void - */ - protected function _quoteInsert($query) - { - list($table, $columns) = $query->clause('insert'); - $table = $this->_driver->quoteIdentifier($table); - foreach ($columns as &$column) { - if (is_scalar($column)) { - $column = $this->_driver->quoteIdentifier($column); - } - } - $query->insert($columns)->into($table); - } - - /** - * Quotes the table name for an update query - * - * @param \Cake\Database\Query $query The update query to quote. - * @return void - */ - protected function _quoteUpdate($query) - { - $table = $query->clause('update')[0]; - - if (is_string($table)) { - $query->update($this->_driver->quoteIdentifier($table)); - } - } - - /** - * Quotes identifiers in expression objects implementing the field interface - * - * @param \Cake\Database\Expression\FieldInterface $expression The expression to quote. - * @return void - */ - protected function _quoteComparison(FieldInterface $expression) - { - $field = $expression->getField(); - if (is_string($field)) { - $expression->setField($this->_driver->quoteIdentifier($field)); - } elseif (is_array($field)) { - $quoted = []; - foreach ($field as $f) { - $quoted[] = $this->_driver->quoteIdentifier($f); - } - $expression->setField($quoted); - } elseif ($field instanceof ExpressionInterface) { - $this->quoteExpression($field); - } - } - - /** - * Quotes identifiers in "order by" expression objects - * - * Strings with spaces are treated as literal expressions - * and will not have identifiers quoted. - * - * @param \Cake\Database\Expression\OrderByExpression $expression The expression to quote. - * @return void - */ - protected function _quoteOrderBy(OrderByExpression $expression) - { - $expression->iterateParts(function ($part, &$field) { - if (is_string($field)) { - $field = $this->_driver->quoteIdentifier($field); - - return $part; - } - if (is_string($part) && strpos($part, ' ') === false) { - return $this->_driver->quoteIdentifier($part); - } - - return $part; - }); - } - - /** - * Quotes identifiers in "order by" expression objects - * - * @param \Cake\Database\Expression\IdentifierExpression $expression The identifiers to quote. - * @return void - */ - protected function _quoteIdentifierExpression(IdentifierExpression $expression) - { - $expression->setIdentifier( - $this->_driver->quoteIdentifier($expression->getIdentifier()) - ); - } -} diff --git a/vendor/cakephp/cakephp/src/Database/LICENSE.txt b/vendor/cakephp/cakephp/src/Database/LICENSE.txt deleted file mode 100644 index 0c4b793..0000000 --- a/vendor/cakephp/cakephp/src/Database/LICENSE.txt +++ /dev/null @@ -1,22 +0,0 @@ -The MIT License (MIT) - -CakePHP(tm) : The Rapid Development PHP Framework (https://cakephp.org) -Copyright (c) 2005-2016, Cake Software Foundation, Inc. (https://cakefoundation.org) - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. diff --git a/vendor/cakephp/cakephp/src/Database/Log/LoggedQuery.php b/vendor/cakephp/cakephp/src/Database/Log/LoggedQuery.php deleted file mode 100644 index 90c1b10..0000000 --- a/vendor/cakephp/cakephp/src/Database/Log/LoggedQuery.php +++ /dev/null @@ -1,70 +0,0 @@ -took} rows={$this->numRows} {$this->query}"; - } -} diff --git a/vendor/cakephp/cakephp/src/Database/Log/LoggingStatement.php b/vendor/cakephp/cakephp/src/Database/Log/LoggingStatement.php deleted file mode 100644 index 525eb48..0000000 --- a/vendor/cakephp/cakephp/src/Database/Log/LoggingStatement.php +++ /dev/null @@ -1,149 +0,0 @@ -queryString = $this->queryString; - $query->error = $e; - $this->_log($query, $params, $t); - throw $e; - } - - $query->numRows = $this->rowCount(); - $this->_log($query, $params, $t); - - return $result; - } - - /** - * Copies the logging data to the passed LoggedQuery and sends it - * to the logging system. - * - * @param \Cake\Database\Log\LoggedQuery $query The query to log. - * @param array $params List of values to be bound to query. - * @param float $startTime The microtime when the query was executed. - * @return void - */ - protected function _log($query, $params, $startTime) - { - $query->took = round((microtime(true) - $startTime) * 1000, 0); - $query->params = $params ?: $this->_compiledParams; - $query->query = $this->queryString; - $this->getLogger()->log($query); - } - - /** - * Wrapper for bindValue function to gather each parameter to be later used - * in the logger function. - * - * @param string|int $column Name or param position to be bound - * @param mixed $value The value to bind to variable in query - * @param string|int|null $type PDO type or name of configured Type class - * @return void - */ - public function bindValue($column, $value, $type = 'string') - { - parent::bindValue($column, $value, $type); - if ($type === null) { - $type = 'string'; - } - if (!ctype_digit($type)) { - $value = $this->cast($value, $type)[0]; - } - $this->_compiledParams[$column] = $value; - } - - /** - * Sets the logger object instance. When called with no arguments - * it returns the currently setup logger instance - * - * @deprecated 3.5.0 Use getLogger() and setLogger() instead. - * @param \Cake\Database\Log\QueryLogger|null $instance Logger object instance. - * @return \Cake\Database\Log\QueryLogger|null Logger instance - */ - public function logger($instance = null) - { - deprecationWarning( - 'LoggingStatement::logger() is deprecated. ' . - 'Use LoggingStatement::setLogger()/getLogger() instead.' - ); - if ($instance === null) { - return $this->getLogger(); - } - - return $this->_logger = $instance; - } - - /** - * Sets a logger - * - * @param \Cake\Database\Log\QueryLogger $logger Logger object - * @return void - */ - public function setLogger($logger) - { - $this->_logger = $logger; - } - - /** - * Gets the logger object - * - * @return \Cake\Database\Log\QueryLogger logger instance - */ - public function getLogger() - { - return $this->_logger; - } -} diff --git a/vendor/cakephp/cakephp/src/Database/Log/QueryLogger.php b/vendor/cakephp/cakephp/src/Database/Log/QueryLogger.php deleted file mode 100644 index c80669e..0000000 --- a/vendor/cakephp/cakephp/src/Database/Log/QueryLogger.php +++ /dev/null @@ -1,94 +0,0 @@ -params)) { - $query->query = $this->_interpolate($query); - } - $this->_log($query); - } - - /** - * Wrapper function for the logger object, useful for unit testing - * or for overriding in subclasses. - * - * @param \Cake\Database\Log\LoggedQuery $query to be written in log - * @return void - */ - protected function _log($query) - { - Log::write('debug', $query, ['queriesLog']); - } - - /** - * Helper function used to replace query placeholders by the real - * params used to execute the query - * - * @param \Cake\Database\Log\LoggedQuery $query The query to log - * @return string - */ - protected function _interpolate($query) - { - $params = array_map(function ($p) { - if ($p === null) { - return 'NULL'; - } - if (is_bool($p)) { - return $p ? '1' : '0'; - } - - if (is_string($p)) { - $replacements = [ - '$' => '\\$', - '\\' => '\\\\\\\\', - "'" => "''", - ]; - - $p = strtr($p, $replacements); - - return "'$p'"; - } - - return $p; - }, $query->params); - - $keys = []; - $limit = is_int(key($params)) ? 1 : -1; - foreach ($params as $key => $param) { - $keys[] = is_string($key) ? "/:$key\b/" : '/[?]/'; - } - - return preg_replace($keys, $params, $query->query, $limit); - } -} diff --git a/vendor/cakephp/cakephp/src/Database/Query.php b/vendor/cakephp/cakephp/src/Database/Query.php deleted file mode 100644 index b7fb3b9..0000000 --- a/vendor/cakephp/cakephp/src/Database/Query.php +++ /dev/null @@ -1,2330 +0,0 @@ - true, - 'update' => [], - 'set' => [], - 'insert' => [], - 'values' => [], - 'select' => [], - 'distinct' => false, - 'modifier' => [], - 'from' => [], - 'join' => [], - 'where' => null, - 'group' => [], - 'having' => null, - 'order' => null, - 'limit' => null, - 'offset' => null, - 'union' => [], - 'epilog' => null - ]; - - /** - * Indicates whether internal state of this query was changed, this is used to - * discard internal cached objects such as the transformed query or the reference - * to the executed statement. - * - * @var bool - */ - protected $_dirty = false; - - /** - * A list of callback functions to be called to alter each row from resulting - * statement upon retrieval. Each one of the callback function will receive - * the row array as first argument. - * - * @var array - */ - protected $_resultDecorators = []; - - /** - * Statement object resulting from executing this query. - * - * @var \Cake\Database\StatementInterface|null - */ - protected $_iterator; - - /** - * The object responsible for generating query placeholders and temporarily store values - * associated to each of those. - * - * @var \Cake\Database\ValueBinder|null - */ - protected $_valueBinder; - - /** - * Instance of functions builder object used for generating arbitrary SQL functions. - * - * @var \Cake\Database\FunctionsBuilder|null - */ - protected $_functionsBuilder; - - /** - * Boolean for tracking whether or not buffered results - * are enabled. - * - * @var bool - */ - protected $_useBufferedResults = true; - - /** - * The Type map for fields in the select clause - * - * @var \Cake\Database\TypeMap - */ - protected $_selectTypeMap; - - /** - * Tracking flag to disable casting - * - * @var bool - */ - protected $typeCastEnabled = true; - - /** - * Constructor. - * - * @param \Cake\Database\Connection $connection The connection - * object to be used for transforming and executing this query - */ - public function __construct($connection) - { - $this->setConnection($connection); - } - - /** - * Sets the connection instance to be used for executing and transforming this query. - * - * @param \Cake\Database\Connection $connection Connection instance - * @return $this - */ - public function setConnection($connection) - { - $this->_dirty(); - $this->_connection = $connection; - - return $this; - } - - /** - * Gets the connection instance to be used for executing and transforming this query. - * - * @return \Cake\Database\Connection - */ - public function getConnection() - { - return $this->_connection; - } - - /** - * Sets the connection instance to be used for executing and transforming this query - * When called with a null argument, it will return the current connection instance. - * - * @deprecated 3.4.0 Use setConnection()/getConnection() instead. - * @param \Cake\Database\Connection|null $connection Connection instance - * @return $this|\Cake\Database\Connection - */ - public function connection($connection = null) - { - deprecationWarning( - 'Query::connection() is deprecated. ' . - 'Use Query::setConnection()/getConnection() instead.' - ); - if ($connection !== null) { - return $this->setConnection($connection); - } - - return $this->getConnection(); - } - - /** - * Compiles the SQL representation of this query and executes it using the - * configured connection object. Returns the resulting statement object. - * - * Executing a query internally executes several steps, the first one is - * letting the connection transform this object to fit its particular dialect, - * this might result in generating a different Query object that will be the one - * to actually be executed. Immediately after, literal values are passed to the - * connection so they are bound to the query in a safe way. Finally, the resulting - * statement is decorated with custom objects to execute callbacks for each row - * retrieved if necessary. - * - * Resulting statement is traversable, so it can be used in any loop as you would - * with an array. - * - * This method can be overridden in query subclasses to decorate behavior - * around query execution. - * - * @return \Cake\Database\StatementInterface - */ - public function execute() - { - $statement = $this->_connection->run($this); - $this->_iterator = $this->_decorateStatement($statement); - $this->_dirty = false; - - return $this->_iterator; - } - - /** - * Executes the SQL of this query and immediately closes the statement before returning the row count of records - * changed. - * - * This method can be used with UPDATE and DELETE queries, but is not recommended for SELECT queries and is not - * used to count records. - * - * ## Example - * - * ``` - * $rowCount = $query->update('articles') - * ->set(['published'=>true]) - * ->where(['published'=>false]) - * ->rowCountAndClose(); - * ``` - * - * The above example will change the published column to true for all false records, and return the number of - * records that were updated. - * - * @return int - */ - public function rowCountAndClose() - { - $statement = $this->execute(); - try { - return $statement->rowCount(); - } finally { - $statement->closeCursor(); - } - } - - /** - * Returns the SQL representation of this object. - * - * This function will compile this query to make it compatible - * with the SQL dialect that is used by the connection, This process might - * add, remove or alter any query part or internal expression to make it - * executable in the target platform. - * - * The resulting query may have placeholders that will be replaced with the actual - * values when the query is executed, hence it is most suitable to use with - * prepared statements. - * - * @param \Cake\Database\ValueBinder|null $generator A placeholder object that will hold - * associated values for expressions - * @return string - */ - public function sql(ValueBinder $generator = null) - { - if (!$generator) { - $generator = $this->getValueBinder(); - $generator->resetCount(); - } - - return $this->getConnection()->compileQuery($this, $generator); - } - - /** - * Will iterate over every specified part. Traversing functions can aggregate - * results using variables in the closure or instance variables. This function - * is commonly used as a way for traversing all query parts that - * are going to be used for constructing a query. - * - * The callback will receive 2 parameters, the first one is the value of the query - * part that is being iterated and the second the name of such part. - * - * ### Example: - * ``` - * $query->select(['title'])->from('articles')->traverse(function ($value, $clause) { - * if ($clause === 'select') { - * var_dump($value); - * } - * }, ['select', 'from']); - * ``` - * - * @param callable $visitor A function or callable to be executed for each part - * @param array $parts The query clauses to traverse - * @return $this - */ - public function traverse(callable $visitor, array $parts = []) - { - $parts = $parts ?: array_keys($this->_parts); - foreach ($parts as $name) { - $visitor($this->_parts[$name], $name); - } - - return $this; - } - - /** - * Adds new fields to be returned by a `SELECT` statement when this query is - * executed. Fields can be passed as an array of strings, array of expression - * objects, a single expression or a single string. - * - * If an array is passed, keys will be used to alias fields using the value as the - * real field to be aliased. It is possible to alias strings, Expression objects or - * even other Query objects. - * - * If a callable function is passed, the returning array of the function will - * be used as the list of fields. - * - * By default this function will append any passed argument to the list of fields - * to be selected, unless the second argument is set to true. - * - * ### Examples: - * - * ``` - * $query->select(['id', 'title']); // Produces SELECT id, title - * $query->select(['author' => 'author_id']); // Appends author: SELECT id, title, author_id as author - * $query->select('id', true); // Resets the list: SELECT id - * $query->select(['total' => $countQuery]); // SELECT id, (SELECT ...) AS total - * $query->select(function ($query) { - * return ['article_id', 'total' => $query->count('*')]; - * }) - * ``` - * - * By default no fields are selected, if you have an instance of `Cake\ORM\Query` and try to append - * fields you should also call `Cake\ORM\Query::enableAutoFields()` to select the default fields - * from the table. - * - * @param array|\Cake\Database\ExpressionInterface|string|callable $fields fields to be added to the list. - * @param bool $overwrite whether to reset fields with passed list or not - * @return $this - */ - public function select($fields = [], $overwrite = false) - { - if (!is_string($fields) && is_callable($fields)) { - $fields = $fields($this); - } - - if (!is_array($fields)) { - $fields = [$fields]; - } - - if ($overwrite) { - $this->_parts['select'] = $fields; - } else { - $this->_parts['select'] = array_merge($this->_parts['select'], $fields); - } - - $this->_dirty(); - $this->_type = 'select'; - - return $this; - } - - /** - * Adds a `DISTINCT` clause to the query to remove duplicates from the result set. - * This clause can only be used for select statements. - * - * If you wish to filter duplicates based of those rows sharing a particular field - * or set of fields, you may pass an array of fields to filter on. Beware that - * this option might not be fully supported in all database systems. - * - * ### Examples: - * - * ``` - * // Filters products with the same name and city - * $query->select(['name', 'city'])->from('products')->distinct(); - * - * // Filters products in the same city - * $query->distinct(['city']); - * $query->distinct('city'); - * - * // Filter products with the same name - * $query->distinct(['name'], true); - * $query->distinct('name', true); - * ``` - * - * @param array|\Cake\Database\ExpressionInterface|string|bool $on Enable/disable distinct class - * or list of fields to be filtered on - * @param bool $overwrite whether to reset fields with passed list or not - * @return $this - */ - public function distinct($on = [], $overwrite = false) - { - if ($on === []) { - $on = true; - } elseif (is_string($on)) { - $on = [$on]; - } - - if (is_array($on)) { - $merge = []; - if (is_array($this->_parts['distinct'])) { - $merge = $this->_parts['distinct']; - } - $on = $overwrite ? array_values($on) : array_merge($merge, array_values($on)); - } - - $this->_parts['distinct'] = $on; - $this->_dirty(); - - return $this; - } - - /** - * Adds a single or multiple `SELECT` modifiers to be used in the `SELECT`. - * - * By default this function will append any passed argument to the list of modifiers - * to be applied, unless the second argument is set to true. - * - * ### Example: - * - * ``` - * // Ignore cache query in MySQL - * $query->select(['name', 'city'])->from('products')->modifier('SQL_NO_CACHE'); - * // It will produce the SQL: SELECT SQL_NO_CACHE name, city FROM products - * - * // Or with multiple modifiers - * $query->select(['name', 'city'])->from('products')->modifier(['HIGH_PRIORITY', 'SQL_NO_CACHE']); - * // It will produce the SQL: SELECT HIGH_PRIORITY SQL_NO_CACHE name, city FROM products - * ``` - * - * @param array|\Cake\Database\ExpressionInterface|string $modifiers modifiers to be applied to the query - * @param bool $overwrite whether to reset order with field list or not - * @return $this - */ - public function modifier($modifiers, $overwrite = false) - { - $this->_dirty(); - if ($overwrite) { - $this->_parts['modifier'] = []; - } - $this->_parts['modifier'] = array_merge($this->_parts['modifier'], (array)$modifiers); - - return $this; - } - - /** - * Adds a single or multiple tables to be used in the FROM clause for this query. - * Tables can be passed as an array of strings, array of expression - * objects, a single expression or a single string. - * - * If an array is passed, keys will be used to alias tables using the value as the - * real field to be aliased. It is possible to alias strings, ExpressionInterface objects or - * even other Query objects. - * - * By default this function will append any passed argument to the list of tables - * to be selected from, unless the second argument is set to true. - * - * This method can be used for select, update and delete statements. - * - * ### Examples: - * - * ``` - * $query->from(['p' => 'posts']); // Produces FROM posts p - * $query->from('authors'); // Appends authors: FROM posts p, authors - * $query->from(['products'], true); // Resets the list: FROM products - * $query->from(['sub' => $countQuery]); // FROM (SELECT ...) sub - * ``` - * - * @param array|string $tables tables to be added to the list. This argument, can be - * passed as an array of strings, array of expression objects, or a single string. See - * the examples above for the valid call types. - * @param bool $overwrite whether to reset tables with passed list or not - * @return $this|array - */ - public function from($tables = [], $overwrite = false) - { - if (empty($tables)) { - return $this->_parts['from']; - } - - $tables = (array)$tables; - - if ($overwrite) { - $this->_parts['from'] = $tables; - } else { - $this->_parts['from'] = array_merge($this->_parts['from'], $tables); - } - - $this->_dirty(); - - return $this; - } - - /** - * Adds a single or multiple tables to be used as JOIN clauses to this query. - * Tables can be passed as an array of strings, an array describing the - * join parts, an array with multiple join descriptions, or a single string. - * - * By default this function will append any passed argument to the list of tables - * to be joined, unless the third argument is set to true. - * - * When no join type is specified an `INNER JOIN` is used by default: - * `$query->join(['authors'])` will produce `INNER JOIN authors ON 1 = 1` - * - * It is also possible to alias joins using the array key: - * `$query->join(['a' => 'authors'])` will produce `INNER JOIN authors a ON 1 = 1` - * - * A join can be fully described and aliased using the array notation: - * - * ``` - * $query->join([ - * 'a' => [ - * 'table' => 'authors', - * 'type' => 'LEFT', - * 'conditions' => 'a.id = b.author_id' - * ] - * ]); - * // Produces LEFT JOIN authors a ON a.id = b.author_id - * ``` - * - * You can even specify multiple joins in an array, including the full description: - * - * ``` - * $query->join([ - * 'a' => [ - * 'table' => 'authors', - * 'type' => 'LEFT', - * 'conditions' => 'a.id = b.author_id' - * ], - * 'p' => [ - * 'table' => 'publishers', - * 'type' => 'INNER', - * 'conditions' => 'p.id = b.publisher_id AND p.name = "Cake Software Foundation"' - * ] - * ]); - * // LEFT JOIN authors a ON a.id = b.author_id - * // INNER JOIN publishers p ON p.id = b.publisher_id AND p.name = "Cake Software Foundation" - * ``` - * - * ### Using conditions and types - * - * Conditions can be expressed, as in the examples above, using a string for comparing - * columns, or string with already quoted literal values. Additionally it is - * possible to use conditions expressed in arrays or expression objects. - * - * When using arrays for expressing conditions, it is often desirable to convert - * the literal values to the correct database representation. This is achieved - * using the second parameter of this function. - * - * ``` - * $query->join(['a' => [ - * 'table' => 'articles', - * 'conditions' => [ - * 'a.posted >=' => new DateTime('-3 days'), - * 'a.published' => true, - * 'a.author_id = authors.id' - * ] - * ]], ['a.posted' => 'datetime', 'a.published' => 'boolean']) - * ``` - * - * ### Overwriting joins - * - * When creating aliased joins using the array notation, you can override - * previous join definitions by using the same alias in consequent - * calls to this function or you can replace all previously defined joins - * with another list if the third parameter for this function is set to true. - * - * ``` - * $query->join(['alias' => 'table']); // joins table with as alias - * $query->join(['alias' => 'another_table']); // joins another_table with as alias - * $query->join(['something' => 'different_table'], [], true); // resets joins list - * ``` - * - * @param array|string|null $tables list of tables to be joined in the query - * @param array $types associative array of type names used to bind values to query - * @param bool $overwrite whether to reset joins with passed list or not - * @see \Cake\Database\Type - * @return $this|array - */ - public function join($tables = null, $types = [], $overwrite = false) - { - if ($tables === null) { - return $this->_parts['join']; - } - - if (is_string($tables) || isset($tables['table'])) { - $tables = [$tables]; - } - - $joins = []; - $i = count($this->_parts['join']); - foreach ($tables as $alias => $t) { - if (!is_array($t)) { - $t = ['table' => $t, 'conditions' => $this->newExpr()]; - } - - if (!is_string($t['conditions']) && is_callable($t['conditions'])) { - $t['conditions'] = $t['conditions']($this->newExpr(), $this); - } - - if (!($t['conditions'] instanceof ExpressionInterface)) { - $t['conditions'] = $this->newExpr()->add($t['conditions'], $types); - } - $alias = is_string($alias) ? $alias : null; - $joins[$alias ?: $i++] = $t + ['type' => QueryInterface::JOIN_TYPE_INNER, 'alias' => $alias]; - } - - if ($overwrite) { - $this->_parts['join'] = $joins; - } else { - $this->_parts['join'] = array_merge($this->_parts['join'], $joins); - } - - $this->_dirty(); - - return $this; - } - - /** - * Remove a join if it has been defined. - * - * Useful when you are redefining joins or want to re-order - * the join clauses. - * - * @param string $name The alias/name of the join to remove. - * @return $this - */ - public function removeJoin($name) - { - unset($this->_parts['join'][$name]); - $this->_dirty(); - - return $this; - } - - /** - * Adds a single `LEFT JOIN` clause to the query. - * - * This is a shorthand method for building joins via `join()`. - * - * The table name can be passed as a string, or as an array in case it needs to - * be aliased: - * - * ``` - * // LEFT JOIN authors ON authors.id = posts.author_id - * $query->leftJoin('authors', 'authors.id = posts.author_id'); - * - * // LEFT JOIN authors a ON a.id = posts.author_id - * $query->leftJoin(['a' => 'authors'], 'a.id = posts.author_id'); - * ``` - * - * Conditions can be passed as strings, arrays, or expression objects. When - * using arrays it is possible to combine them with the `$types` parameter - * in order to define how to convert the values: - * - * ``` - * $query->leftJoin(['a' => 'articles'], [ - * 'a.posted >=' => new DateTime('-3 days'), - * 'a.published' => true, - * 'a.author_id = authors.id' - * ], ['a.posted' => 'datetime', 'a.published' => 'boolean']); - * ``` - * - * See `join()` for further details on conditions and types. - * - * @param string|array $table The table to join with - * @param string|array|\Cake\Database\ExpressionInterface $conditions The conditions - * to use for joining. - * @param array $types a list of types associated to the conditions used for converting - * values to the corresponding database representation. - * @return $this - */ - public function leftJoin($table, $conditions = [], $types = []) - { - return $this->join($this->_makeJoin($table, $conditions, QueryInterface::JOIN_TYPE_LEFT), $types); - } - - /** - * Adds a single `RIGHT JOIN` clause to the query. - * - * This is a shorthand method for building joins via `join()`. - * - * The arguments of this method are identical to the `leftJoin()` shorthand, please refer - * to that methods description for further details. - * - * @param string|array $table The table to join with - * @param string|array|\Cake\Database\ExpressionInterface $conditions The conditions - * to use for joining. - * @param array $types a list of types associated to the conditions used for converting - * values to the corresponding database representation. - * @return $this - */ - public function rightJoin($table, $conditions = [], $types = []) - { - return $this->join($this->_makeJoin($table, $conditions, QueryInterface::JOIN_TYPE_RIGHT), $types); - } - - /** - * Adds a single `INNER JOIN` clause to the query. - * - * This is a shorthand method for building joins via `join()`. - * - * The arguments of this method are identical to the `leftJoin()` shorthand, please refer - * to that methods description for further details. - * - * @param string|array $table The table to join with - * @param string|array|\Cake\Database\ExpressionInterface $conditions The conditions - * to use for joining. - * @param array $types a list of types associated to the conditions used for converting - * values to the corresponding database representation. - * @return $this - */ - public function innerJoin($table, $conditions = [], $types = []) - { - return $this->join($this->_makeJoin($table, $conditions, QueryInterface::JOIN_TYPE_INNER), $types); - } - - /** - * Returns an array that can be passed to the join method describing a single join clause - * - * @param string|array $table The table to join with - * @param string|array|\Cake\Database\ExpressionInterface $conditions The conditions - * to use for joining. - * @param string $type the join type to use - * @return array - */ - protected function _makeJoin($table, $conditions, $type) - { - $alias = $table; - - if (is_array($table)) { - $alias = key($table); - $table = current($table); - } - - return [ - $alias => [ - 'table' => $table, - 'conditions' => $conditions, - 'type' => $type - ] - ]; - } - - /** - * Adds a condition or set of conditions to be used in the WHERE clause for this - * query. Conditions can be expressed as an array of fields as keys with - * comparison operators in it, the values for the array will be used for comparing - * the field to such literal. Finally, conditions can be expressed as a single - * string or an array of strings. - * - * When using arrays, each entry will be joined to the rest of the conditions using - * an `AND` operator. Consecutive calls to this function will also join the new - * conditions specified using the AND operator. Additionally, values can be - * expressed using expression objects which can include other query objects. - * - * Any conditions created with this methods can be used with any `SELECT`, `UPDATE` - * and `DELETE` type of queries. - * - * ### Conditions using operators: - * - * ``` - * $query->where([ - * 'posted >=' => new DateTime('3 days ago'), - * 'title LIKE' => 'Hello W%', - * 'author_id' => 1, - * ], ['posted' => 'datetime']); - * ``` - * - * The previous example produces: - * - * `WHERE posted >= 2012-01-27 AND title LIKE 'Hello W%' AND author_id = 1` - * - * Second parameter is used to specify what type is expected for each passed - * key. Valid types can be used from the mapped with Database\Type class. - * - * ### Nesting conditions with conjunctions: - * - * ``` - * $query->where([ - * 'author_id !=' => 1, - * 'OR' => ['published' => true, 'posted <' => new DateTime('now')], - * 'NOT' => ['title' => 'Hello'] - * ], ['published' => boolean, 'posted' => 'datetime'] - * ``` - * - * The previous example produces: - * - * `WHERE author_id = 1 AND (published = 1 OR posted < '2012-02-01') AND NOT (title = 'Hello')` - * - * You can nest conditions using conjunctions as much as you like. Sometimes, you - * may want to define 2 different options for the same key, in that case, you can - * wrap each condition inside a new array: - * - * `$query->where(['OR' => [['published' => false], ['published' => true]])` - * - * Would result in: - * - * `WHERE (published = false) OR (published = true)` - * - * Keep in mind that every time you call where() with the third param set to false - * (default), it will join the passed conditions to the previous stored list using - * the `AND` operator. Also, using the same array key twice in consecutive calls to - * this method will not override the previous value. - * - * ### Using expressions objects: - * - * ``` - * $exp = $query->newExpr()->add(['id !=' => 100, 'author_id' != 1])->tieWith('OR'); - * $query->where(['published' => true], ['published' => 'boolean'])->where($exp); - * ``` - * - * The previous example produces: - * - * `WHERE (id != 100 OR author_id != 1) AND published = 1` - * - * Other Query objects that be used as conditions for any field. - * - * ### Adding conditions in multiple steps: - * - * You can use callable functions to construct complex expressions, functions - * receive as first argument a new QueryExpression object and this query instance - * as second argument. Functions must return an expression object, that will be - * added the list of conditions for the query using the `AND` operator. - * - * ``` - * $query - * ->where(['title !=' => 'Hello World']) - * ->where(function ($exp, $query) { - * $or = $exp->or_(['id' => 1]); - * $and = $exp->and_(['id >' => 2, 'id <' => 10]); - * return $or->add($and); - * }); - * ``` - * - * * The previous example produces: - * - * `WHERE title != 'Hello World' AND (id = 1 OR (id > 2 AND id < 10))` - * - * ### Conditions as strings: - * - * ``` - * $query->where(['articles.author_id = authors.id', 'modified IS NULL']); - * ``` - * - * The previous example produces: - * - * `WHERE articles.author_id = authors.id AND modified IS NULL` - * - * Please note that when using the array notation or the expression objects, all - * *values* will be correctly quoted and transformed to the correspondent database - * data type automatically for you, thus securing your application from SQL injections. - * The keys however, are not treated as unsafe input, and should be sanitized/whitelisted. - * - * If you use string conditions make sure that your values are correctly quoted. - * The safest thing you can do is to never use string conditions. - * - * @param string|array|\Cake\Database\ExpressionInterface|callable|null $conditions The conditions to filter on. - * @param array $types associative array of type names used to bind values to query - * @param bool $overwrite whether to reset conditions with passed list or not - * @see \Cake\Database\Type - * @see \Cake\Database\Expression\QueryExpression - * @return $this - */ - public function where($conditions = null, $types = [], $overwrite = false) - { - if ($overwrite) { - $this->_parts['where'] = $this->newExpr(); - } - $this->_conjugate('where', $conditions, 'AND', $types); - - return $this; - } - - /** - * Convenience method that adds a NOT NULL condition to the query - * - * @param array|string|\Cake\Database\ExpressionInterface $fields A single field or expressions or a list of them that should be not null - * @return $this - */ - public function whereNotNull($fields) - { - if (!is_array($fields)) { - $fields = [$fields]; - } - - $exp = $this->newExpr(); - - foreach ($fields as $field) { - $exp->isNotNull($field); - } - - return $this->where($exp); - } - - /** - * Convenience method that adds a IS NULL condition to the query - * - * @param array|string|\Cake\Database\ExpressionInterface $fields A single field or expressions or a list of them that should be null - * @return $this - */ - public function whereNull($fields) - { - if (!is_array($fields)) { - $fields = [$fields]; - } - - $exp = $this->newExpr(); - - foreach ($fields as $field) { - $exp->isNull($field); - } - - return $this->where($exp); - } - - /** - * Adds an IN condition or set of conditions to be used in the WHERE clause for this - * query. - * - * This method does allow empty inputs in contrast to where() if you set - * 'allowEmpty' to true. - * Be careful about using it without proper sanity checks. - * - * Options: - * - `types` - Associative array of type names used to bind values to query - * - `allowEmpty` - Allow empty array. - * - * @param string $field Field - * @param array $values Array of values - * @param array $options Options - * @return $this - */ - public function whereInList($field, array $values, array $options = []) - { - $options += [ - 'types' => [], - 'allowEmpty' => false, - ]; - - if ($options['allowEmpty'] && !$values) { - return $this->where('1=0'); - } - - return $this->where([$field . ' IN' => $values], $options['types']); - } - - /** - * Adds a NOT IN condition or set of conditions to be used in the WHERE clause for this - * query. - * - * This method does allow empty inputs in contrast to where() if you set - * 'allowEmpty' to true. - * Be careful about using it without proper sanity checks. - * - * @param string $field Field - * @param array $values Array of values - * @param array $options Options - * @return $this - */ - public function whereNotInList($field, array $values, array $options = []) - { - $options += [ - 'types' => [], - 'allowEmpty' => false, - ]; - - if ($options['allowEmpty'] && !$values) { - return $this->where([$field . ' IS NOT' => null]); - } - - return $this->where([$field . ' NOT IN' => $values], $options['types']); - } - - /** - * Connects any previously defined set of conditions to the provided list - * using the AND operator. This function accepts the conditions list in the same - * format as the method `where` does, hence you can use arrays, expression objects - * callback functions or strings. - * - * It is important to notice that when calling this function, any previous set - * of conditions defined for this query will be treated as a single argument for - * the AND operator. This function will not only operate the most recently defined - * condition, but all the conditions as a whole. - * - * When using an array for defining conditions, creating constraints form each - * array entry will use the same logic as with the `where()` function. This means - * that each array entry will be joined to the other using the AND operator, unless - * you nest the conditions in the array using other operator. - * - * ### Examples: - * - * ``` - * $query->where(['title' => 'Hello World')->andWhere(['author_id' => 1]); - * ``` - * - * Will produce: - * - * `WHERE title = 'Hello World' AND author_id = 1` - * - * ``` - * $query - * ->where(['OR' => ['published' => false, 'published is NULL']]) - * ->andWhere(['author_id' => 1, 'comments_count >' => 10]) - * ``` - * - * Produces: - * - * `WHERE (published = 0 OR published IS NULL) AND author_id = 1 AND comments_count > 10` - * - * ``` - * $query - * ->where(['title' => 'Foo']) - * ->andWhere(function ($exp, $query) { - * return $exp - * ->or_(['author_id' => 1]) - * ->add(['author_id' => 2]); - * }); - * ``` - * - * Generates the following conditions: - * - * `WHERE (title = 'Foo') AND (author_id = 1 OR author_id = 2)` - * - * @param string|array|\Cake\Database\ExpressionInterface|callable $conditions The conditions to add with AND. - * @param array $types associative array of type names used to bind values to query - * @see \Cake\Database\Query::where() - * @see \Cake\Database\Type - * @return $this - */ - public function andWhere($conditions, $types = []) - { - $this->_conjugate('where', $conditions, 'AND', $types); - - return $this; - } - - /** - * Connects any previously defined set of conditions to the provided list - * using the OR operator. This function accepts the conditions list in the same - * format as the method `where` does, hence you can use arrays, expression objects - * callback functions or strings. - * - * It is important to notice that when calling this function, any previous set - * of conditions defined for this query will be treated as a single argument for - * the OR operator. This function will not only operate the most recently defined - * condition, but all the conditions as a whole. - * - * When using an array for defining conditions, creating constraints form each - * array entry will use the same logic as with the `where()` function. This means - * that each array entry will be joined to the other using the OR operator, unless - * you nest the conditions in the array using other operator. - * - * ### Examples: - * - * ``` - * $query->where(['title' => 'Hello World')->orWhere(['title' => 'Foo']); - * ``` - * - * Will produce: - * - * `WHERE title = 'Hello World' OR title = 'Foo'` - * - * ``` - * $query - * ->where(['OR' => ['published' => false, 'published is NULL']]) - * ->orWhere(['author_id' => 1, 'comments_count >' => 10]) - * ``` - * - * Produces: - * - * `WHERE (published = 0 OR published IS NULL) OR (author_id = 1 AND comments_count > 10)` - * - * ``` - * $query - * ->where(['title' => 'Foo']) - * ->orWhere(function ($exp, $query) { - * return $exp - * ->or_(['author_id' => 1]) - * ->add(['author_id' => 2]); - * }); - * ``` - * - * Generates the following conditions: - * - * `WHERE (title = 'Foo') OR (author_id = 1 OR author_id = 2)` - * - * @param string|array|\Cake\Database\ExpressionInterface|callable $conditions The conditions to add with OR. - * @param array $types associative array of type names used to bind values to query - * @see \Cake\Database\Query::where() - * @see \Cake\Database\Type - * @return $this - * @deprecated 3.5.0 This method creates hard to predict SQL based on the current query state. - * Use `Query::where()` instead as it has more predicatable and easier to understand behavior. - */ - public function orWhere($conditions, $types = []) - { - deprecationWarning( - 'Query::orWhere() is deprecated as it creates hard to predict SQL based on the ' . - 'current query state. Use `Query::where()` instead.' - ); - $this->_conjugate('where', $conditions, 'OR', $types); - - return $this; - } - - /** - * Adds a single or multiple fields to be used in the ORDER clause for this query. - * Fields can be passed as an array of strings, array of expression - * objects, a single expression or a single string. - * - * If an array is passed, keys will be used as the field itself and the value will - * represent the order in which such field should be ordered. When called multiple - * times with the same fields as key, the last order definition will prevail over - * the others. - * - * By default this function will append any passed argument to the list of fields - * to be selected, unless the second argument is set to true. - * - * ### Examples: - * - * ``` - * $query->order(['title' => 'DESC', 'author_id' => 'ASC']); - * ``` - * - * Produces: - * - * `ORDER BY title DESC, author_id ASC` - * - * ``` - * $query->order(['title' => 'DESC NULLS FIRST'])->order('author_id'); - * ``` - * - * Will generate: - * - * `ORDER BY title DESC NULLS FIRST, author_id` - * - * ``` - * $expression = $query->newExpr()->add(['id % 2 = 0']); - * $query->order($expression)->order(['title' => 'ASC']); - * ``` - * - * Will become: - * - * `ORDER BY (id %2 = 0), title ASC` - * - * Order fields/directions are not sanitized by the query builder. - * You should use a whitelist of fields/directions when passing - * in user-supplied data to `order()`. - * - * If you need to set complex expressions as order conditions, you - * should use `orderAsc()` or `orderDesc()`. - * - * @param array|\Cake\Database\ExpressionInterface|string $fields fields to be added to the list - * @param bool $overwrite whether to reset order with field list or not - * @return $this - */ - public function order($fields, $overwrite = false) - { - if ($overwrite) { - $this->_parts['order'] = null; - } - - if (!$fields) { - return $this; - } - - if (!$this->_parts['order']) { - $this->_parts['order'] = new OrderByExpression(); - } - $this->_conjugate('order', $fields, '', []); - - return $this; - } - - /** - * Add an ORDER BY clause with an ASC direction. - * - * This method allows you to set complex expressions - * as order conditions unlike order() - * - * Order fields are not suitable for use with user supplied data as they are - * not sanitized by the query builder. - * - * @param string|\Cake\Database\Expression\QueryExpression $field The field to order on. - * @param bool $overwrite Whether or not to reset the order clauses. - * @return $this - */ - public function orderAsc($field, $overwrite = false) - { - if ($overwrite) { - $this->_parts['order'] = null; - } - if (!$field) { - return $this; - } - - if (!$this->_parts['order']) { - $this->_parts['order'] = new OrderByExpression(); - } - $this->_parts['order']->add(new OrderClauseExpression($field, 'ASC')); - - return $this; - } - - /** - * Add an ORDER BY clause with a DESC direction. - * - * This method allows you to set complex expressions - * as order conditions unlike order() - * - * Order fields are not suitable for use with user supplied data as they are - * not sanitized by the query builder. - * - * @param string|\Cake\Database\Expression\QueryExpression $field The field to order on. - * @param bool $overwrite Whether or not to reset the order clauses. - * @return $this - */ - public function orderDesc($field, $overwrite = false) - { - if ($overwrite) { - $this->_parts['order'] = null; - } - if (!$field) { - return $this; - } - - if (!$this->_parts['order']) { - $this->_parts['order'] = new OrderByExpression(); - } - $this->_parts['order']->add(new OrderClauseExpression($field, 'DESC')); - - return $this; - } - - /** - * Adds a single or multiple fields to be used in the GROUP BY clause for this query. - * Fields can be passed as an array of strings, array of expression - * objects, a single expression or a single string. - * - * By default this function will append any passed argument to the list of fields - * to be grouped, unless the second argument is set to true. - * - * ### Examples: - * - * ``` - * // Produces GROUP BY id, title - * $query->group(['id', 'title']); - * - * // Produces GROUP BY title - * $query->group('title'); - * ``` - * - * Group fields are not suitable for use with user supplied data as they are - * not sanitized by the query builder. - * - * @param array|\Cake\Database\ExpressionInterface|string $fields fields to be added to the list - * @param bool $overwrite whether to reset fields with passed list or not - * @return $this - */ - public function group($fields, $overwrite = false) - { - if ($overwrite) { - $this->_parts['group'] = []; - } - - if (!is_array($fields)) { - $fields = [$fields]; - } - - $this->_parts['group'] = array_merge($this->_parts['group'], array_values($fields)); - $this->_dirty(); - - return $this; - } - - /** - * Adds a condition or set of conditions to be used in the `HAVING` clause for this - * query. This method operates in exactly the same way as the method `where()` - * does. Please refer to its documentation for an insight on how to using each - * parameter. - * - * Having fields are not suitable for use with user supplied data as they are - * not sanitized by the query builder. - * - * @param string|array|\Cake\Database\ExpressionInterface|callable|null $conditions The having conditions. - * @param array $types associative array of type names used to bind values to query - * @param bool $overwrite whether to reset conditions with passed list or not - * @see \Cake\Database\Query::where() - * @return $this - */ - public function having($conditions = null, $types = [], $overwrite = false) - { - if ($overwrite) { - $this->_parts['having'] = $this->newExpr(); - } - $this->_conjugate('having', $conditions, 'AND', $types); - - return $this; - } - - /** - * Connects any previously defined set of conditions to the provided list - * using the AND operator in the HAVING clause. This method operates in exactly - * the same way as the method `andWhere()` does. Please refer to its - * documentation for an insight on how to using each parameter. - * - * Having fields are not suitable for use with user supplied data as they are - * not sanitized by the query builder. - * - * @param string|array|\Cake\Database\ExpressionInterface|callable $conditions The AND conditions for HAVING. - * @param array $types associative array of type names used to bind values to query - * @see \Cake\Database\Query::andWhere() - * @return $this - */ - public function andHaving($conditions, $types = []) - { - $this->_conjugate('having', $conditions, 'AND', $types); - - return $this; - } - - /** - * Connects any previously defined set of conditions to the provided list - * using the OR operator in the HAVING clause. This method operates in exactly - * the same way as the method `orWhere()` does. Please refer to its - * documentation for an insight on how to using each parameter. - * - * Having fields are not suitable for use with user supplied data as they are - * not sanitized by the query builder. - * - * @param string|array|\Cake\Database\ExpressionInterface|callable $conditions The OR conditions for HAVING. - * @param array $types associative array of type names used to bind values to query. - * @see \Cake\Database\Query::orWhere() - * @return $this - * @deprecated 3.5.0 This method creates hard to predict SQL based on the current query state. - * Use `Query::having()` instead as it has more predicatable and easier to understand behavior. - */ - public function orHaving($conditions, $types = []) - { - deprecationWarning('Query::orHaving() is deprecated. Use Query::having() instead.'); - $this->_conjugate('having', $conditions, 'OR', $types); - - return $this; - } - - /** - * Set the page of results you want. - * - * This method provides an easier to use interface to set the limit + offset - * in the record set you want as results. If empty the limit will default to - * the existing limit clause, and if that too is empty, then `25` will be used. - * - * Pages must start at 1. - * - * @param int $num The page number you want. - * @param int|null $limit The number of rows you want in the page. If null - * the current limit clause will be used. - * @return $this - * @throws \InvalidArgumentException If page number < 1. - */ - public function page($num, $limit = null) - { - if ($num < 1) { - throw new InvalidArgumentException('Pages must start at 1.'); - } - if ($limit !== null) { - $this->limit($limit); - } - $limit = $this->clause('limit'); - if ($limit === null) { - $limit = 25; - $this->limit($limit); - } - $offset = ($num - 1) * $limit; - if (PHP_INT_MAX <= $offset) { - $offset = PHP_INT_MAX; - } - $this->offset((int)$offset); - - return $this; - } - - /** - * Sets the number of records that should be retrieved from database, - * accepts an integer or an expression object that evaluates to an integer. - * In some databases, this operation might not be supported or will require - * the query to be transformed in order to limit the result set size. - * - * ### Examples - * - * ``` - * $query->limit(10) // generates LIMIT 10 - * $query->limit($query->newExpr()->add(['1 + 1'])); // LIMIT (1 + 1) - * ``` - * - * @param int|\Cake\Database\ExpressionInterface $num number of records to be returned - * @return $this - */ - public function limit($num) - { - $this->_dirty(); - if ($num !== null && !is_object($num)) { - $num = (int)$num; - } - $this->_parts['limit'] = $num; - - return $this; - } - - /** - * Sets the number of records that should be skipped from the original result set - * This is commonly used for paginating large results. Accepts an integer or an - * expression object that evaluates to an integer. - * - * In some databases, this operation might not be supported or will require - * the query to be transformed in order to limit the result set size. - * - * ### Examples - * - * ``` - * $query->offset(10) // generates OFFSET 10 - * $query->offset($query->newExpr()->add(['1 + 1'])); // OFFSET (1 + 1) - * ``` - * - * @param int|\Cake\Database\ExpressionInterface $num number of records to be skipped - * @return $this - */ - public function offset($num) - { - $this->_dirty(); - if ($num !== null && !is_object($num)) { - $num = (int)$num; - } - $this->_parts['offset'] = $num; - - return $this; - } - - /** - * Adds a complete query to be used in conjunction with an UNION operator with - * this query. This is used to combine the result set of this query with the one - * that will be returned by the passed query. You can add as many queries as you - * required by calling multiple times this method with different queries. - * - * By default, the UNION operator will remove duplicate rows, if you wish to include - * every row for all queries, use unionAll(). - * - * ### Examples - * - * ``` - * $union = (new Query($conn))->select(['id', 'title'])->from(['a' => 'articles']); - * $query->select(['id', 'name'])->from(['d' => 'things'])->union($union); - * ``` - * - * Will produce: - * - * `SELECT id, name FROM things d UNION SELECT id, title FROM articles a` - * - * @param string|\Cake\Database\Query $query full SQL query to be used in UNION operator - * @param bool $overwrite whether to reset the list of queries to be operated or not - * @return $this - */ - public function union($query, $overwrite = false) - { - if ($overwrite) { - $this->_parts['union'] = []; - } - $this->_parts['union'][] = [ - 'all' => false, - 'query' => $query - ]; - $this->_dirty(); - - return $this; - } - - /** - * Adds a complete query to be used in conjunction with the UNION ALL operator with - * this query. This is used to combine the result set of this query with the one - * that will be returned by the passed query. You can add as many queries as you - * required by calling multiple times this method with different queries. - * - * Unlike UNION, UNION ALL will not remove duplicate rows. - * - * ``` - * $union = (new Query($conn))->select(['id', 'title'])->from(['a' => 'articles']); - * $query->select(['id', 'name'])->from(['d' => 'things'])->unionAll($union); - * ``` - * - * Will produce: - * - * `SELECT id, name FROM things d UNION ALL SELECT id, title FROM articles a` - * - * @param string|\Cake\Database\Query $query full SQL query to be used in UNION operator - * @param bool $overwrite whether to reset the list of queries to be operated or not - * @return $this - */ - public function unionAll($query, $overwrite = false) - { - if ($overwrite) { - $this->_parts['union'] = []; - } - $this->_parts['union'][] = [ - 'all' => true, - 'query' => $query - ]; - $this->_dirty(); - - return $this; - } - - /** - * Create an insert query. - * - * Note calling this method will reset any data previously set - * with Query::values(). - * - * @param array $columns The columns to insert into. - * @param array $types A map between columns & their datatypes. - * @return $this - * @throws \RuntimeException When there are 0 columns. - */ - public function insert(array $columns, array $types = []) - { - if (empty($columns)) { - throw new RuntimeException('At least 1 column is required to perform an insert.'); - } - $this->_dirty(); - $this->_type = 'insert'; - $this->_parts['insert'][1] = $columns; - if (!$this->_parts['values']) { - $this->_parts['values'] = new ValuesExpression($columns, $this->getTypeMap()->setTypes($types)); - } else { - $this->_parts['values']->setColumns($columns); - } - - return $this; - } - - /** - * Set the table name for insert queries. - * - * @param string $table The table name to insert into. - * @return $this - */ - public function into($table) - { - $this->_dirty(); - $this->_type = 'insert'; - $this->_parts['insert'][0] = $table; - - return $this; - } - - /** - * Creates an expression that refers to an identifier. Identifiers are used to refer to field names and allow - * the SQL compiler to apply quotes or escape the identifier. - * - * The value is used as is, and you might be required to use aliases or include the table reference in - * the identifier. Do not use this method to inject SQL methods or logical statements. - * - * ### Example - * - * ``` - * $query->newExp()->lte('count', $query->identifier('total')); - * ``` - * - * @param string $identifier The identifier for an expression - * @return \Cake\Database\ExpressionInterface - */ - public function identifier($identifier) - { - return new IdentifierExpression($identifier); - } - - /** - * Set the values for an insert query. - * - * Multi inserts can be performed by calling values() more than one time, - * or by providing an array of value sets. Additionally $data can be a Query - * instance to insert data from another SELECT statement. - * - * @param array|\Cake\Database\Query $data The data to insert. - * @return $this - * @throws \Cake\Database\Exception if you try to set values before declaring columns. - * Or if you try to set values on non-insert queries. - */ - public function values($data) - { - if ($this->_type !== 'insert') { - throw new Exception( - 'You cannot add values before defining columns to use.' - ); - } - if (empty($this->_parts['insert'])) { - throw new Exception( - 'You cannot add values before defining columns to use.' - ); - } - - $this->_dirty(); - if ($data instanceof ValuesExpression) { - $this->_parts['values'] = $data; - - return $this; - } - - $this->_parts['values']->add($data); - - return $this; - } - - /** - * Create an update query. - * - * Can be combined with set() and where() methods to create update queries. - * - * @param string|\Cake\Database\ExpressionInterface $table The table you want to update. - * @return $this - */ - public function update($table) - { - if (!is_string($table) && !($table instanceof ExpressionInterface)) { - $text = 'Table must be of type string or "%s", got "%s"'; - $message = sprintf($text, ExpressionInterface::class, gettype($table)); - throw new InvalidArgumentException($message); - } - - $this->_dirty(); - $this->_type = 'update'; - $this->_parts['update'][0] = $table; - - return $this; - } - - /** - * Set one or many fields to update. - * - * ### Examples - * - * Passing a string: - * - * ``` - * $query->update('articles')->set('title', 'The Title'); - * ``` - * - * Passing an array: - * - * ``` - * $query->update('articles')->set(['title' => 'The Title'], ['title' => 'string']); - * ``` - * - * Passing a callable: - * - * ``` - * $query->update('articles')->set(function ($exp) { - * return $exp->eq('title', 'The title', 'string'); - * }); - * ``` - * - * @param string|array|callable|\Cake\Database\Expression\QueryExpression $key The column name or array of keys - * + values to set. This can also be a QueryExpression containing a SQL fragment. - * It can also be a callable, that is required to return an expression object. - * @param mixed $value The value to update $key to. Can be null if $key is an - * array or QueryExpression. When $key is an array, this parameter will be - * used as $types instead. - * @param array $types The column types to treat data as. - * @return $this - */ - public function set($key, $value = null, $types = []) - { - if (empty($this->_parts['set'])) { - $this->_parts['set'] = $this->newExpr()->setConjunction(','); - } - - if ($this->_parts['set']->isCallable($key)) { - $exp = $this->newExpr()->setConjunction(','); - $this->_parts['set']->add($key($exp)); - - return $this; - } - - if (is_array($key) || $key instanceof ExpressionInterface) { - $types = (array)$value; - $this->_parts['set']->add($key, $types); - - return $this; - } - - if (is_string($types) && is_string($key)) { - $types = [$key => $types]; - } - $this->_parts['set']->eq($key, $value, $types); - - return $this; - } - - /** - * Create a delete query. - * - * Can be combined with from(), where() and other methods to - * create delete queries with specific conditions. - * - * @param string|null $table The table to use when deleting. - * @return $this - */ - public function delete($table = null) - { - $this->_dirty(); - $this->_type = 'delete'; - if ($table !== null) { - $this->from($table); - } - - return $this; - } - - /** - * A string or expression that will be appended to the generated query - * - * ### Examples: - * ``` - * $query->select('id')->where(['author_id' => 1])->epilog('FOR UPDATE'); - * $query - * ->insert('articles', ['title']) - * ->values(['author_id' => 1]) - * ->epilog('RETURNING id'); - * ``` - * - * Epliog content is raw SQL and not suitable for use with user supplied data. - * - * @param string|\Cake\Database\Expression\QueryExpression|null $expression The expression to be appended - * @return $this - */ - public function epilog($expression = null) - { - $this->_dirty(); - $this->_parts['epilog'] = $expression; - - return $this; - } - - /** - * Returns the type of this query (select, insert, update, delete) - * - * @return string - */ - public function type() - { - return $this->_type; - } - - /** - * Returns a new QueryExpression object. This is a handy function when - * building complex queries using a fluent interface. You can also override - * this function in subclasses to use a more specialized QueryExpression class - * if required. - * - * You can optionally pass a single raw SQL string or an array or expressions in - * any format accepted by \Cake\Database\Expression\QueryExpression: - * - * ``` - * $expression = $query->newExpr(); // Returns an empty expression object - * $expression = $query->newExpr('Table.column = Table2.column'); // Return a raw SQL expression - * ``` - * - * @param mixed $rawExpression A string, array or anything you want wrapped in an expression object - * @return \Cake\Database\Expression\QueryExpression - */ - public function newExpr($rawExpression = null) - { - $expression = new QueryExpression([], $this->getTypeMap()); - - if ($rawExpression !== null) { - $expression->add($rawExpression); - } - - return $expression; - } - - /** - * Returns an instance of a functions builder object that can be used for - * generating arbitrary SQL functions. - * - * ### Example: - * - * ``` - * $query->func()->count('*'); - * $query->func()->dateDiff(['2012-01-05', '2012-01-02']) - * ``` - * - * @return \Cake\Database\FunctionsBuilder - */ - public function func() - { - if ($this->_functionsBuilder === null) { - $this->_functionsBuilder = new FunctionsBuilder(); - } - - return $this->_functionsBuilder; - } - - /** - * Executes this query and returns a results iterator. This function is required - * for implementing the IteratorAggregate interface and allows the query to be - * iterated without having to call execute() manually, thus making it look like - * a result set instead of the query itself. - * - * @return \Cake\Database\StatementInterface|null - */ - public function getIterator() - { - if ($this->_iterator === null || $this->_dirty) { - $this->_iterator = $this->execute(); - } - - return $this->_iterator; - } - - /** - * Returns any data that was stored in the specified clause. This is useful for - * modifying any internal part of the query and it is used by the SQL dialects - * to transform the query accordingly before it is executed. The valid clauses that - * can be retrieved are: delete, update, set, insert, values, select, distinct, - * from, join, set, where, group, having, order, limit, offset and union. - * - * The return value for each of those parts may vary. Some clauses use QueryExpression - * to internally store their state, some use arrays and others may use booleans or - * integers. This is summary of the return types for each clause. - * - * - update: string The name of the table to update - * - set: QueryExpression - * - insert: array, will return an array containing the table + columns. - * - values: ValuesExpression - * - select: array, will return empty array when no fields are set - * - distinct: boolean - * - from: array of tables - * - join: array - * - set: array - * - where: QueryExpression, returns null when not set - * - group: array - * - having: QueryExpression, returns null when not set - * - order: OrderByExpression, returns null when not set - * - limit: integer or QueryExpression, null when not set - * - offset: integer or QueryExpression, null when not set - * - union: array - * - * @param string $name name of the clause to be returned - * @return mixed - * @throws InvalidArgumentException When the named clause does not exist. - */ - public function clause($name) - { - if (!array_key_exists($name, $this->_parts)) { - $clauses = implode(', ', array_keys($this->_parts)); - throw new InvalidArgumentException("The '$name' clause is not defined. Valid clauses are: $clauses"); - } - - return $this->_parts[$name]; - } - - /** - * Registers a callback to be executed for each result that is fetched from the - * result set, the callback function will receive as first parameter an array with - * the raw data from the database for every row that is fetched and must return the - * row with any possible modifications. - * - * Callbacks will be executed lazily, if only 3 rows are fetched for database it will - * called 3 times, event though there might be more rows to be fetched in the cursor. - * - * Callbacks are stacked in the order they are registered, if you wish to reset the stack - * the call this function with the second parameter set to true. - * - * If you wish to remove all decorators from the stack, set the first parameter - * to null and the second to true. - * - * ### Example - * - * ``` - * $query->decorateResults(function ($row) { - * $row['order_total'] = $row['subtotal'] + ($row['subtotal'] * $row['tax']); - * return $row; - * }); - * ``` - * - * @param callable|null $callback The callback to invoke when results are fetched. - * @param bool $overwrite Whether or not this should append or replace all existing decorators. - * @return $this - */ - public function decorateResults($callback, $overwrite = false) - { - if ($overwrite) { - $this->_resultDecorators = []; - } - - if ($callback !== null) { - $this->_resultDecorators[] = $callback; - } - - return $this; - } - - /** - * This function works similar to the traverse() function, with the difference - * that it does a full depth traversal of the entire expression tree. This will execute - * the provided callback function for each ExpressionInterface object that is - * stored inside this query at any nesting depth in any part of the query. - * - * Callback will receive as first parameter the currently visited expression. - * - * @param callable $callback the function to be executed for each ExpressionInterface - * found inside this query. - * @return $this|null - */ - public function traverseExpressions(callable $callback) - { - $visitor = function ($expression) use (&$visitor, $callback) { - if (is_array($expression)) { - foreach ($expression as $e) { - $visitor($e); - } - - return null; - } - - if ($expression instanceof ExpressionInterface) { - $expression->traverse($visitor); - - if (!($expression instanceof self)) { - $callback($expression); - } - } - }; - - return $this->traverse($visitor); - } - - /** - * Associates a query placeholder to a value and a type. - * - * If type is expressed as "atype[]" (note braces) then it will cause the - * placeholder to be re-written dynamically so if the value is an array, it - * will create as many placeholders as values are in it. For example: - * - * ``` - * $query->bind(':id', [1, 2, 3], 'int[]'); - * ``` - * - * Will create 3 int placeholders. When using named placeholders, this method - * requires that the placeholders include `:` e.g. `:value`. - * - * @param string|int $param placeholder to be replaced with quoted version - * of $value - * @param mixed $value The value to be bound - * @param string|int $type the mapped type name, used for casting when sending - * to database - * @return $this - */ - public function bind($param, $value, $type = 'string') - { - $this->getValueBinder()->bind($param, $value, $type); - - return $this; - } - - /** - * Returns the currently used ValueBinder instance. - * - * A ValueBinder is responsible for generating query placeholders and temporarily - * associate values to those placeholders so that they can be passed correctly - * to the statement object. - * - * @return \Cake\Database\ValueBinder - */ - public function getValueBinder() - { - if ($this->_valueBinder === null) { - $this->_valueBinder = new ValueBinder(); - } - - return $this->_valueBinder; - } - - /** - * Overwrite the current value binder - * - * A ValueBinder is responsible for generating query placeholders and temporarily - * associate values to those placeholders so that they can be passed correctly - * to the statement object. - * - * @param \Cake\Database\ValueBinder|bool $binder The binder or false to disable binding. - * @return $this - */ - public function setValueBinder($binder) - { - $this->_valueBinder = $binder; - - return $this; - } - - /** - * Returns the currently used ValueBinder instance. If a value is passed, - * it will be set as the new instance to be used. - * - * A ValueBinder is responsible for generating query placeholders and temporarily - * associate values to those placeholders so that they can be passed correctly - * to the statement object. - * - * @deprecated 3.5.0 Use setValueBinder()/getValueBinder() instead. - * @param \Cake\Database\ValueBinder|false|null $binder new instance to be set. If no value is passed the - * default one will be returned - * @return $this|\Cake\Database\ValueBinder - */ - public function valueBinder($binder = null) - { - deprecationWarning('Query::valueBinder() is deprecated. Use Query::getValueBinder()/setValueBinder() instead.'); - if ($binder === null) { - if ($this->_valueBinder === null) { - $this->_valueBinder = new ValueBinder(); - } - - return $this->_valueBinder; - } - $this->_valueBinder = $binder; - - return $this; - } - - /** - * Enables/Disables buffered results. - * - * When enabled the results returned by this Query will be - * buffered. This enables you to iterate a result set multiple times, or - * both cache and iterate it. - * - * When disabled it will consume less memory as fetched results are not - * remembered for future iterations. - * - * @param bool $enable Whether or not to enable buffering - * @return $this - */ - public function enableBufferedResults($enable = true) - { - $this->_dirty(); - $this->_useBufferedResults = (bool)$enable; - - return $this; - } - - /** - * Returns whether buffered results are enabled/disabled. - * - * When enabled the results returned by this Query will be - * buffered. This enables you to iterate a result set multiple times, or - * both cache and iterate it. - * - * When disabled it will consume less memory as fetched results are not - * remembered for future iterations. - * - * @return bool - */ - public function isBufferedResultsEnabled() - { - return $this->_useBufferedResults; - } - - /** - * Enable/Disable buffered results. - * - * When enabled the results returned by this Query will be - * buffered. This enables you to iterate a result set multiple times, or - * both cache and iterate it. - * - * When disabled it will consume less memory as fetched results are not - * remembered for future iterations. - * - * If called with no arguments, it will return whether or not buffering is - * enabled. - * - * @deprecated 3.4.0 Use enableBufferedResults()/isBufferedResultsEnabled() instead. - * @param bool|null $enable Whether or not to enable buffering - * @return bool|$this - */ - public function bufferResults($enable = null) - { - deprecationWarning( - 'Query::bufferResults() is deprecated. ' . - 'Use Query::enableBufferedResults()/isBufferedResultsEnabled() instead.' - ); - if ($enable !== null) { - return $this->enableBufferedResults($enable); - } - - return $this->isBufferedResultsEnabled(); - } - - /** - * Sets the TypeMap class where the types for each of the fields in the - * select clause are stored. - * - * @param \Cake\Database\TypeMap $typeMap The map object to use - * @return $this - */ - public function setSelectTypeMap(TypeMap $typeMap) - { - $this->_selectTypeMap = $typeMap; - $this->_dirty(); - - return $this; - } - - /** - * Gets the TypeMap class where the types for each of the fields in the - * select clause are stored. - * - * @return \Cake\Database\TypeMap - */ - public function getSelectTypeMap() - { - if ($this->_selectTypeMap === null) { - $this->_selectTypeMap = new TypeMap(); - } - - return $this->_selectTypeMap; - } - - /** - * Disables the automatic casting of fields to their corresponding PHP data type - * - * @return $this - */ - public function disableResultsCasting() - { - $this->typeCastEnabled = false; - - return $this; - } - - /** - * Enables the automatic casting of fields to their corresponding type - * - * @return $this - */ - public function enableResultsCasting() - { - $this->typeCastEnabled = true; - - return $this; - } - - /** - * Sets the TypeMap class where the types for each of the fields in the - * select clause are stored. - * - * When called with no arguments, the current TypeMap object is returned. - * - * @deprecated 3.4.0 Use setSelectTypeMap()/getSelectTypeMap() instead. - * @param \Cake\Database\TypeMap|null $typeMap The map object to use - * @return $this|\Cake\Database\TypeMap - */ - public function selectTypeMap(TypeMap $typeMap = null) - { - deprecationWarning( - 'Query::selectTypeMap() is deprecated. ' . - 'Use Query::setSelectTypeMap()/getSelectTypeMap() instead.' - ); - if ($typeMap !== null) { - return $this->setSelectTypeMap($typeMap); - } - - return $this->getSelectTypeMap(); - } - - /** - * Auxiliary function used to wrap the original statement from the driver with - * any registered callbacks. - * - * @param \Cake\Database\StatementInterface $statement to be decorated - * @return \Cake\Database\Statement\CallbackStatement - */ - protected function _decorateStatement($statement) - { - $typeMap = $this->getSelectTypeMap(); - $driver = $this->getConnection()->getDriver(); - - if ($this->typeCastEnabled && $typeMap->toArray()) { - $statement = new CallbackStatement($statement, $driver, new FieldTypeConverter($typeMap, $driver)); - } - - foreach ($this->_resultDecorators as $f) { - $statement = new CallbackStatement($statement, $driver, $f); - } - - return $statement; - } - - /** - * Helper function used to build conditions by composing QueryExpression objects. - * - * @param string $part Name of the query part to append the new part to - * @param string|null|array|\Cake\Database\ExpressionInterface|callable $append Expression or builder function to append. - * @param string $conjunction type of conjunction to be used to operate part - * @param array $types associative array of type names used to bind values to query - * @return void - */ - protected function _conjugate($part, $append, $conjunction, $types) - { - $expression = $this->_parts[$part] ?: $this->newExpr(); - if (empty($append)) { - $this->_parts[$part] = $expression; - - return; - } - - if ($expression->isCallable($append)) { - $append = $append($this->newExpr(), $this); - } - - if ($expression->getConjunction() === $conjunction) { - $expression->add($append, $types); - } else { - $expression = $this->newExpr() - ->setConjunction($conjunction) - ->add([$expression, $append], $types); - } - - $this->_parts[$part] = $expression; - $this->_dirty(); - } - - /** - * Marks a query as dirty, removing any preprocessed information - * from in memory caching. - * - * @return void - */ - protected function _dirty() - { - $this->_dirty = true; - - if ($this->_iterator && $this->_valueBinder) { - $this->getValueBinder()->reset(); - } - } - - /** - * Do a deep clone on this object. - * - * Will clone all of the expression objects used in - * each of the clauses, as well as the valueBinder. - * - * @return void - */ - public function __clone() - { - $this->_iterator = null; - if ($this->_valueBinder !== null) { - $this->_valueBinder = clone $this->_valueBinder; - } - if ($this->_selectTypeMap !== null) { - $this->_selectTypeMap = clone $this->_selectTypeMap; - } - foreach ($this->_parts as $name => $part) { - if (empty($part)) { - continue; - } - if (is_array($part)) { - foreach ($part as $i => $piece) { - if ($piece instanceof ExpressionInterface) { - $this->_parts[$name][$i] = clone $piece; - } - } - } - if ($part instanceof ExpressionInterface) { - $this->_parts[$name] = clone $part; - } - } - } - - /** - * Returns string representation of this query (complete SQL statement). - * - * @return string - */ - public function __toString() - { - return $this->sql(); - } - - /** - * Returns an array that can be used to describe the internal state of this - * object. - * - * @return array - */ - public function __debugInfo() - { - try { - set_error_handler(function ($errno, $errstr) { - throw new RuntimeException($errstr, $errno); - }, E_ALL); - $sql = $this->sql(); - $params = $this->getValueBinder()->bindings(); - } catch (RuntimeException $e) { - $sql = 'SQL could not be generated for this query as it is incomplete.'; - $params = []; - } finally { - restore_error_handler(); - } - - return [ - '(help)' => 'This is a Query object, to get the results execute or iterate it.', - 'sql' => $sql, - 'params' => $params, - 'defaultTypes' => $this->getDefaultTypes(), - 'decorators' => count($this->_resultDecorators), - 'executed' => $this->_iterator ? true : false - ]; - } -} diff --git a/vendor/cakephp/cakephp/src/Database/QueryCompiler.php b/vendor/cakephp/cakephp/src/Database/QueryCompiler.php deleted file mode 100644 index 79f5c67..0000000 --- a/vendor/cakephp/cakephp/src/Database/QueryCompiler.php +++ /dev/null @@ -1,392 +0,0 @@ - 'DELETE', - 'where' => ' WHERE %s', - 'group' => ' GROUP BY %s ', - 'having' => ' HAVING %s ', - 'order' => ' %s', - 'limit' => ' LIMIT %s', - 'offset' => ' OFFSET %s', - 'epilog' => ' %s' - ]; - - /** - * The list of query clauses to traverse for generating a SELECT statement - * - * @var array - */ - protected $_selectParts = [ - 'select', 'from', 'join', 'where', 'group', 'having', 'order', 'limit', - 'offset', 'union', 'epilog' - ]; - - /** - * The list of query clauses to traverse for generating an UPDATE statement - * - * @var array - */ - protected $_updateParts = ['update', 'set', 'where', 'epilog']; - - /** - * The list of query clauses to traverse for generating a DELETE statement - * - * @var array - */ - protected $_deleteParts = ['delete', 'modifier', 'from', 'where', 'epilog']; - - /** - * The list of query clauses to traverse for generating an INSERT statement - * - * @var array - */ - protected $_insertParts = ['insert', 'values', 'epilog']; - - /** - * Indicate whether or not this query dialect supports ordered unions. - * - * Overridden in subclasses. - * - * @var bool - */ - protected $_orderedUnion = true; - - /** - * Returns the SQL representation of the provided query after generating - * the placeholders for the bound values using the provided generator - * - * @param \Cake\Database\Query $query The query that is being compiled - * @param \Cake\Database\ValueBinder $generator the placeholder generator to be used in expressions - * @return \Closure - */ - public function compile(Query $query, ValueBinder $generator) - { - $sql = ''; - $type = $query->type(); - $query->traverse( - $this->_sqlCompiler($sql, $query, $generator), - $this->{'_' . $type . 'Parts'} - ); - - // Propagate bound parameters from sub-queries if the - // placeholders can be found in the SQL statement. - if ($query->getValueBinder() !== $generator) { - foreach ($query->getValueBinder()->bindings() as $binding) { - $placeholder = ':' . $binding['placeholder']; - if (preg_match('/' . $placeholder . '(?:\W|$)/', $sql) > 0) { - $generator->bind($placeholder, $binding['value'], $binding['type']); - } - } - } - - return $sql; - } - - /** - * Returns a callable object that can be used to compile a SQL string representation - * of this query. - * - * @param string $sql initial sql string to append to - * @param \Cake\Database\Query $query The query that is being compiled - * @param \Cake\Database\ValueBinder $generator The placeholder and value binder object - * @return \Closure - */ - protected function _sqlCompiler(&$sql, $query, $generator) - { - return function ($parts, $name) use (&$sql, $query, $generator) { - if (!isset($parts) || - ((is_array($parts) || $parts instanceof \Countable) && !count($parts)) - ) { - return; - } - if ($parts instanceof ExpressionInterface) { - $parts = [$parts->sql($generator)]; - } - if (isset($this->_templates[$name])) { - $parts = $this->_stringifyExpressions((array)$parts, $generator); - - return $sql .= sprintf($this->_templates[$name], implode(', ', $parts)); - } - - return $sql .= $this->{'_build' . ucfirst($name) . 'Part'}($parts, $query, $generator); - }; - } - - /** - * Helper function used to build the string representation of a SELECT clause, - * it constructs the field list taking care of aliasing and - * converting expression objects to string. This function also constructs the - * DISTINCT clause for the query. - * - * @param array $parts list of fields to be transformed to string - * @param \Cake\Database\Query $query The query that is being compiled - * @param \Cake\Database\ValueBinder $generator the placeholder generator to be used in expressions - * @return string - */ - protected function _buildSelectPart($parts, $query, $generator) - { - $driver = $query->getConnection()->getDriver(); - $select = 'SELECT%s %s%s'; - if ($this->_orderedUnion && $query->clause('union')) { - $select = '(SELECT%s %s%s'; - } - $distinct = $query->clause('distinct'); - $modifiers = $this->_buildModifierPart($query->clause('modifier'), $query, $generator); - - $normalized = []; - $parts = $this->_stringifyExpressions($parts, $generator); - foreach ($parts as $k => $p) { - if (!is_numeric($k)) { - $p = $p . ' AS ' . $driver->quoteIdentifier($k); - } - $normalized[] = $p; - } - - if ($distinct === true) { - $distinct = 'DISTINCT '; - } - - if (is_array($distinct)) { - $distinct = $this->_stringifyExpressions($distinct, $generator); - $distinct = sprintf('DISTINCT ON (%s) ', implode(', ', $distinct)); - } - - return sprintf($select, $modifiers, $distinct, implode(', ', $normalized)); - } - - /** - * Helper function used to build the string representation of a FROM clause, - * it constructs the tables list taking care of aliasing and - * converting expression objects to string. - * - * @param array $parts list of tables to be transformed to string - * @param \Cake\Database\Query $query The query that is being compiled - * @param \Cake\Database\ValueBinder $generator the placeholder generator to be used in expressions - * @return string - */ - protected function _buildFromPart($parts, $query, $generator) - { - $select = ' FROM %s'; - $normalized = []; - $parts = $this->_stringifyExpressions($parts, $generator); - foreach ($parts as $k => $p) { - if (!is_numeric($k)) { - $p = $p . ' ' . $k; - } - $normalized[] = $p; - } - - return sprintf($select, implode(', ', $normalized)); - } - - /** - * Helper function used to build the string representation of multiple JOIN clauses, - * it constructs the joins list taking care of aliasing and converting - * expression objects to string in both the table to be joined and the conditions - * to be used. - * - * @param array $parts list of joins to be transformed to string - * @param \Cake\Database\Query $query The query that is being compiled - * @param \Cake\Database\ValueBinder $generator the placeholder generator to be used in expressions - * @return string - */ - protected function _buildJoinPart($parts, $query, $generator) - { - $joins = ''; - foreach ($parts as $join) { - $subquery = $join['table'] instanceof Query || $join['table'] instanceof QueryExpression; - if ($join['table'] instanceof ExpressionInterface) { - $join['table'] = $join['table']->sql($generator); - } - - if ($subquery) { - $join['table'] = '(' . $join['table'] . ')'; - } - - $joins .= sprintf(' %s JOIN %s %s', $join['type'], $join['table'], $join['alias']); - - $condition = ''; - if (isset($join['conditions']) && $join['conditions'] instanceof ExpressionInterface) { - $condition = $join['conditions']->sql($generator); - } - if (strlen($condition)) { - $joins .= " ON {$condition}"; - } else { - $joins .= ' ON 1 = 1'; - } - } - - return $joins; - } - - /** - * Helper function to generate SQL for SET expressions. - * - * @param array $parts List of keys & values to set. - * @param \Cake\Database\Query $query The query that is being compiled - * @param \Cake\Database\ValueBinder $generator the placeholder generator to be used in expressions - * @return string - */ - protected function _buildSetPart($parts, $query, $generator) - { - $set = []; - foreach ($parts as $part) { - if ($part instanceof ExpressionInterface) { - $part = $part->sql($generator); - } - if ($part[0] === '(') { - $part = substr($part, 1, -1); - } - $set[] = $part; - } - - return ' SET ' . implode('', $set); - } - - /** - * Builds the SQL string for all the UNION clauses in this query, when dealing - * with query objects it will also transform them using their configured SQL - * dialect. - * - * @param array $parts list of queries to be operated with UNION - * @param \Cake\Database\Query $query The query that is being compiled - * @param \Cake\Database\ValueBinder $generator the placeholder generator to be used in expressions - * @return string - */ - protected function _buildUnionPart($parts, $query, $generator) - { - $parts = array_map(function ($p) use ($generator) { - $p['query'] = $p['query']->sql($generator); - $p['query'] = $p['query'][0] === '(' ? trim($p['query'], '()') : $p['query']; - $prefix = $p['all'] ? 'ALL ' : ''; - if ($this->_orderedUnion) { - return "{$prefix}({$p['query']})"; - } - - return $prefix . $p['query']; - }, $parts); - - if ($this->_orderedUnion) { - return sprintf(")\nUNION %s", implode("\nUNION ", $parts)); - } - - return sprintf("\nUNION %s", implode("\nUNION ", $parts)); - } - - /** - * Builds the SQL fragment for INSERT INTO. - * - * @param array $parts The insert parts. - * @param \Cake\Database\Query $query The query that is being compiled - * @param \Cake\Database\ValueBinder $generator the placeholder generator to be used in expressions - * @return string SQL fragment. - */ - protected function _buildInsertPart($parts, $query, $generator) - { - $table = $parts[0]; - $columns = $this->_stringifyExpressions($parts[1], $generator); - $modifiers = $this->_buildModifierPart($query->clause('modifier'), $query, $generator); - - return sprintf('INSERT%s INTO %s (%s)', $modifiers, $table, implode(', ', $columns)); - } - - /** - * Builds the SQL fragment for INSERT INTO. - * - * @param array $parts The values parts. - * @param \Cake\Database\Query $query The query that is being compiled - * @param \Cake\Database\ValueBinder $generator the placeholder generator to be used in expressions - * @return string SQL fragment. - */ - protected function _buildValuesPart($parts, $query, $generator) - { - return implode('', $this->_stringifyExpressions($parts, $generator)); - } - - /** - * Builds the SQL fragment for UPDATE. - * - * @param array $parts The update parts. - * @param \Cake\Database\Query $query The query that is being compiled - * @param \Cake\Database\ValueBinder $generator the placeholder generator to be used in expressions - * @return string SQL fragment. - */ - protected function _buildUpdatePart($parts, $query, $generator) - { - $table = $this->_stringifyExpressions($parts, $generator); - $modifiers = $this->_buildModifierPart($query->clause('modifier'), $query, $generator); - - return sprintf('UPDATE%s %s', $modifiers, implode(',', $table)); - } - - /** - * Builds the SQL modifier fragment - * - * @param array $parts The query modifier parts - * @param \Cake\Database\Query $query The query that is being compiled - * @param \Cake\Database\ValueBinder $generator the placeholder generator to be used in expressions - * @return string SQL fragment. - */ - protected function _buildModifierPart($parts, $query, $generator) - { - if ($parts === []) { - return ''; - } - - return ' ' . implode(' ', $this->_stringifyExpressions($parts, $generator, false)); - } - - /** - * Helper function used to covert ExpressionInterface objects inside an array - * into their string representation. - * - * @param array $expressions list of strings and ExpressionInterface objects - * @param \Cake\Database\ValueBinder $generator the placeholder generator to be used in expressions - * @param bool $wrap Whether to wrap each expression object with parenthesis - * @return array - */ - protected function _stringifyExpressions($expressions, $generator, $wrap = true) - { - $result = []; - foreach ($expressions as $k => $expression) { - if ($expression instanceof ExpressionInterface) { - $value = $expression->sql($generator); - $expression = $wrap ? '(' . $value . ')' : $value; - } - $result[$k] = $expression; - } - - return $result; - } -} diff --git a/vendor/cakephp/cakephp/src/Database/README.md b/vendor/cakephp/cakephp/src/Database/README.md deleted file mode 100644 index c545e31..0000000 --- a/vendor/cakephp/cakephp/src/Database/README.md +++ /dev/null @@ -1,364 +0,0 @@ -[![Total Downloads](https://img.shields.io/packagist/dt/cakephp/database.svg?style=flat-square)](https://packagist.org/packages/cakephp/database) -[![License](https://img.shields.io/badge/license-MIT-blue.svg?style=flat-square)](LICENSE.txt) - -# A flexible and lightweight Database Library for PHP - -This library abstracts and provides help with most aspects of dealing with relational -databases such as keeping connections to the server, building queries, -preventing SQL injections, inspecting and altering schemas, and with debugging and -profiling queries sent to the database. - -It adopts the API from the native PDO extension in PHP for familiarity, but solves many of the -inconsistencies PDO has, while also providing several features that extend PDO's capabilities. - -A distinguishing factor of this library when compared to similar database connection packages, -is that it takes the concept of "data types" to its core. It lets you work with complex PHP objects -or structures that can be passed as query conditions or to be inserted in the database. - -The typing system will intelligently convert the PHP structures when passing them to the database, and -convert them back when retrieving. - - -## Connecting to the database - -This library is able to work with the following databases: - -* MySQL -* Postgres -* SQLite -* Microsoft SQL Server (2008 and above) - -The first thing you need to do when using this library is create a connection object. -Before performing any operations with the connection, you need to specify a driver -to use: - -```php -use Cake\Database\Connection; -use Cake\Database\Driver\Mysql; - -$driver = new Mysql([ - 'database' => 'test', - 'username' => 'root', - 'password' => 'secret' -]); -$connection = new Connection([ - 'driver' => $driver -]); -``` - -Drivers are classes responsible for actually executing the commands to the database and -correctly building the SQL according to the database specific dialect. Drivers can also -be specified by passing a class name. In that case, include all the connection details -directly in the options array: - -```php -use Cake\Database\Connection; - -$connection = new Connection([ - 'driver' => 'Cake\Database\Driver\Sqlite', - 'database' => '/path/to/file.db' -]); -``` - -### Connection options - -This is a list of possible options that can be passed when creating a connection: - -* `persistent`: Creates a persistent connection -* `host`: The server host -* `database`: The database name -* `username`: Login credential -* `password`: Connection secret -* `encoding`: The connection encoding (or charset) -* `timezone`: The connection timezone or time offset - -## Using connections - -After creating a connection, you can immediately interact with the database. You can choose -either to use the shorthand methods `execute()`, `insert()`, `update()`, `delete()` or use the -`newQuery()` for using a query builder. - -The easiest way of executing queries is by using the `execute()` method, it will return a -`Cake\Database\StatementInterface` that you can use to get the data back: - -```php -$statement = $connection->execute('SELECT * FROM articles'); - -while($row = $statement->fetch('assoc')) { - echo $row['title'] . PHP_EOL; -} -``` -Binding values to parametrized arguments is also possible with the execute function: - -```php -$statement = $connection->execute('SELECT * FROM articles WHERE id = :id', ['id' => 1], ['id' => 'integer']); -$results = $statement->fetch('assoc'); -``` - -The third parameter is the types the passed values should be converted to when passed to the database. If -no types are passed, all arguments will be interpreted as a string. - -Alternatively you can construct a statement manually and then fetch rows from it: - -```php -$statement = $connection->prepare('SELECT * from articles WHERE id != :id'); -$statement->bind(['id' => 1], ['id' => 'integer']); -$results = $statement->fetchAll('assoc'); -``` - -The default types that are understood by this library and can be passed to the `bind()` function or to `execute()` -are: - -* biginteger -* binary -* date -* float -* decimal -* integer -* time -* datetime -* timestamp -* uuid - -More types can be added dynamically in a bit. - -Statements can be reused by binding new values to the parameters in the query: - -```php -$statement = $connection->prepare('SELECT * from articles WHERE id = :id'); -$statement->bind(['id' => 1], ['id' => 'integer']); -$results = $statement->fetchAll('assoc'); - -$statement->bind(['id' => 1], ['id' => 'integer']); -$results = $statement->fetchAll('assoc'); -``` - -### Updating Rows - -Updating can be done using the `update()` function in the connection object. In the following -example we will update the title of the article with id = 1: - -```php -$connection->update('articles', ['title' => 'New title'], ['id' => 1]); -``` - -The concept of data types is central to this library, so you can use the last parameter of the function -to specify what types should be used: - -```php -$connection->update( - 'articles', - ['title' => 'New title'], - ['created >=' => new DateTime('-3 day'), 'created <' => new DateTime('now')], - ['created' => 'datetime'] -); -``` - -The example above will execute the following SQL: - -```sql -UPDATE articles SET title = 'New Title' WHERE created >= '2014-10-10 00:00:00' AND created < '2014-10-13 00:00:00'; -``` - -More on creating complex where conditions or more complex update queries later. - -### Deleting Rows - -Similarly, the `delete()` method is used to delete rows from the database: - -```php -$connection->delete('articles', ['created <' => DateTime('now')], ['created' => 'date']); -``` - -Will generate the following SQL - -```sql -DELETE FROM articles where created < '2014-10-10' -``` - -### Inserting Rows - -Rows can be inserted using the `insert()` method: - -```php -$connection->insert( - 'articles', - ['title' => 'My Title', 'body' => 'Some paragraph', 'created' => new DateTime()], - ['created' => 'datetime'] -); -``` - -More complex updates, deletes and insert queries can be generated using the `Query` class. - -## Query Builder - -One of the goals of this library is to allow the generation of both simple and complex queries with -ease. The query builder can be accessed by getting a new instance of a query: - -```php -$query = $connection->newQuery(); -``` - -### Selecting Fields - -Adding fields to the `SELECT` clause: - -```php -$query->select(['id', 'title', 'body']); - -// Results in SELECT id AS pk, title AS aliased_title, body ... -$query->select(['pk' => 'id', 'aliased_title' => 'title', 'body']); - -// Use a closure -$query->select(function ($query) { - return ['id', 'title', 'body']; -}); -``` - -### Where Conditions - -Generating conditions: - -```php -// WHERE id = 1 -$query->where(['id' => 1]); - -// WHERE id > 2 -$query->where(['id >' => 1]); -``` - -As you can see you can use any operator by placing it with a space after the field name. -Adding multiple conditions is easy as well: - -```php -$query->where(['id >' => 1])->andWhere(['title' => 'My Title']); - -// Equivalent to -$query->where(['id >' => 1, 'title' => 'My title']); -``` - -It is possible to generate `OR` conditions as well - -```php -$query->where(['OR' => ['id >' => 1, 'title' => 'My title']]); -``` - -For even more complex conditions you can use closures and expression objects: - -```php -$query->where(function ($exp) { - return $exp - ->eq('author_id', 2) - ->eq('published', true) - ->notEq('spam', true) - ->gt('view_count', 10); - }); -``` - -Which results in: - -```sql -SELECT * FROM articles -WHERE - author_id = 2 - AND published = 1 - AND spam != 1 - AND view_count > 10 -``` - -Combining expressions is also possible: - -```php -$query->where(function ($exp) { - $orConditions = $exp->or_(['author_id' => 2]) - ->eq('author_id', 5); - return $exp - ->not($orConditions) - ->lte('view_count', 10); - }); -``` - -That generates: - -```sql -SELECT * -FROM articles -WHERE - NOT (author_id = 2 OR author_id = 5) - AND view_count <= 10 -``` - -When using the expression objects you can use the following methods to create conditions: - -* `eq()` Creates an equality condition. -* `notEq()` Create an inequality condition -* `like()` Create a condition using the LIKE operator. -* `notLike()` Create a negated LIKE condition. -* `in()` Create a condition using IN. -* `notIn()` Create a negated condition using IN. -* `gt()` Create a > condition. -* `gte()` Create a >= condition. -* `lt()` Create a < condition. -* `lte()` Create a <= condition. -* `isNull()` Create an IS NULL condition. -* `isNotNull()` Create a negated IS NULL condition. - -### Aggregates and SQL Functions - -```php -// Results in SELECT COUNT(*) count FROM ... -$query->select(['count' => $query->func()->count('*')]); -``` - -A number of commonly used functions can be created with the func() method: - -* `sum()` Calculate a sum. The arguments will be treated as literal values. -* `avg()` Calculate an average. The arguments will be treated as literal values. -* `min()` Calculate the min of a column. The arguments will be treated as literal values. -* `max()` Calculate the max of a column. The arguments will be treated as literal values. -* `count()` Calculate the count. The arguments will be treated as literal values. -* `concat()` Concatenate two values together. The arguments are treated as bound parameters unless marked as literal. -* `coalesce()` Coalesce values. The arguments are treated as bound parameters unless marked as literal. -* `dateDiff()` Get the difference between two dates/times. The arguments are treated as bound parameters unless marked as literal. -* `now()` Take either 'time' or 'date' as an argument allowing you to get either the current time, or current date. - -When providing arguments for SQL functions, there are two kinds of parameters you can use, literal arguments and bound parameters. Literal -parameters allow you to reference columns or other SQL literals. Bound parameters can be used to safely add user data to SQL functions. -For example: - -```php -$concat = $query->func()->concat([ - 'title' => 'literal', - ' NEW' -]); -$query->select(['title' => $concat]); -``` - -The above generates: - -```sql -SELECT CONCAT(title, :c0) ...; -``` - -### Other SQL Clauses - -Read of all other SQL clauses that the builder is capable of generating in the [official API docs](https://api.cakephp.org/3.x/class-Cake.Database.Query.html) - -### Getting Results out of a Query - -Once you’ve made your query, you’ll want to retrieve rows from it. There are a few ways of doing this: - -```php -// Iterate the query -foreach ($query as $row) { - // Do stuff. -} - -// Get the statement and fetch all results -$results = $query->execute()->fetchAll('assoc'); -``` - -## Official API - -You can read the official [official API docs](https://api.cakephp.org/3.x/namespace-Cake.Database.html) to learn more of what this library -has to offer. diff --git a/vendor/cakephp/cakephp/src/Database/Schema/BaseSchema.php b/vendor/cakephp/cakephp/src/Database/Schema/BaseSchema.php deleted file mode 100644 index 281c220..0000000 --- a/vendor/cakephp/cakephp/src/Database/Schema/BaseSchema.php +++ /dev/null @@ -1,276 +0,0 @@ -connect(); - $this->_driver = $driver; - } - - /** - * Generate an ON clause for a foreign key. - * - * @param string|null $on The on clause - * @return string - */ - protected function _foreignOnClause($on) - { - if ($on === TableSchema::ACTION_SET_NULL) { - return 'SET NULL'; - } - if ($on === TableSchema::ACTION_SET_DEFAULT) { - return 'SET DEFAULT'; - } - if ($on === TableSchema::ACTION_CASCADE) { - return 'CASCADE'; - } - if ($on === TableSchema::ACTION_RESTRICT) { - return 'RESTRICT'; - } - if ($on === TableSchema::ACTION_NO_ACTION) { - return 'NO ACTION'; - } - } - - /** - * Convert string on clauses to the abstract ones. - * - * @param string $clause The on clause to convert. - * @return string|null - */ - protected function _convertOnClause($clause) - { - if ($clause === 'CASCADE' || $clause === 'RESTRICT') { - return strtolower($clause); - } - if ($clause === 'NO ACTION') { - return TableSchema::ACTION_NO_ACTION; - } - - return TableSchema::ACTION_SET_NULL; - } - - /** - * Convert foreign key constraints references to a valid - * stringified list - * - * @param string|array $references The referenced columns of a foreign key constraint statement - * @return string - */ - protected function _convertConstraintColumns($references) - { - if (is_string($references)) { - return $this->_driver->quoteIdentifier($references); - } - - return implode(', ', array_map( - [$this->_driver, 'quoteIdentifier'], - $references - )); - } - - /** - * Generate the SQL to drop a table. - * - * @param \Cake\Database\Schema\TableSchema $schema Schema instance - * @return array SQL statements to drop a table. - */ - public function dropTableSql(TableSchema $schema) - { - $sql = sprintf( - 'DROP TABLE %s', - $this->_driver->quoteIdentifier($schema->name()) - ); - - return [$sql]; - } - - /** - * Generate the SQL to list the tables. - * - * @param array $config The connection configuration to use for - * getting tables from. - * @return array An array of (sql, params) to execute. - */ - abstract public function listTablesSql($config); - - /** - * Generate the SQL to describe a table. - * - * @param string $tableName The table name to get information on. - * @param array $config The connection configuration. - * @return array An array of (sql, params) to execute. - */ - abstract public function describeColumnSql($tableName, $config); - - /** - * Generate the SQL to describe the indexes in a table. - * - * @param string $tableName The table name to get information on. - * @param array $config The connection configuration. - * @return array An array of (sql, params) to execute. - */ - abstract public function describeIndexSql($tableName, $config); - - /** - * Generate the SQL to describe the foreign keys in a table. - * - * @param string $tableName The table name to get information on. - * @param array $config The connection configuration. - * @return array An array of (sql, params) to execute. - */ - abstract public function describeForeignKeySql($tableName, $config); - - /** - * Generate the SQL to describe table options - * - * @param string $tableName Table name. - * @param array $config The connection configuration. - * @return array SQL statements to get options for a table. - */ - public function describeOptionsSql($tableName, $config) - { - return ['', '']; - } - - /** - * Convert field description results into abstract schema fields. - * - * @param \Cake\Database\Schema\TableSchema $schema The table object to append fields to. - * @param array $row The row data from `describeColumnSql`. - * @return void - */ - abstract public function convertColumnDescription(TableSchema $schema, $row); - - /** - * Convert an index description results into abstract schema indexes or constraints. - * - * @param \Cake\Database\Schema\TableSchema $schema The table object to append - * an index or constraint to. - * @param array $row The row data from `describeIndexSql`. - * @return void - */ - abstract public function convertIndexDescription(TableSchema $schema, $row); - - /** - * Convert a foreign key description into constraints on the Table object. - * - * @param \Cake\Database\Schema\TableSchema $schema The table object to append - * a constraint to. - * @param array $row The row data from `describeForeignKeySql`. - * @return void - */ - abstract public function convertForeignKeyDescription(TableSchema $schema, $row); - - /** - * Convert options data into table options. - * - * @param \Cake\Database\Schema\TableSchema $schema Table instance. - * @param array $row The row of data. - * @return void - */ - public function convertOptionsDescription(TableSchema $schema, $row) - { - } - - /** - * Generate the SQL to create a table. - * - * @param \Cake\Database\Schema\TableSchema $schema Table instance. - * @param array $columns The columns to go inside the table. - * @param array $constraints The constraints for the table. - * @param array $indexes The indexes for the table. - * @return array SQL statements to create a table. - */ - abstract public function createTableSql(TableSchema $schema, $columns, $constraints, $indexes); - - /** - * Generate the SQL fragment for a single column in a table. - * - * @param \Cake\Database\Schema\TableSchema $schema The table instance the column is in. - * @param string $name The name of the column. - * @return string SQL fragment. - */ - abstract public function columnSql(TableSchema $schema, $name); - - /** - * Generate the SQL queries needed to add foreign key constraints to the table - * - * @param \Cake\Database\Schema\TableSchema $schema The table instance the foreign key constraints are. - * @return array SQL fragment. - */ - abstract public function addConstraintSql(TableSchema $schema); - - /** - * Generate the SQL queries needed to drop foreign key constraints from the table - * - * @param \Cake\Database\Schema\TableSchema $schema The table instance the foreign key constraints are. - * @return array SQL fragment. - */ - abstract public function dropConstraintSql(TableSchema $schema); - - /** - * Generate the SQL fragments for defining table constraints. - * - * @param \Cake\Database\Schema\TableSchema $schema The table instance the column is in. - * @param string $name The name of the column. - * @return string SQL fragment. - */ - abstract public function constraintSql(TableSchema $schema, $name); - - /** - * Generate the SQL fragment for a single index in a table. - * - * @param \Cake\Database\Schema\TableSchema $schema The table object the column is in. - * @param string $name The name of the column. - * @return string SQL fragment. - */ - abstract public function indexSql(TableSchema $schema, $name); - - /** - * Generate the SQL to truncate a table. - * - * @param \Cake\Database\Schema\TableSchema $schema Table instance. - * @return array SQL statements to truncate a table. - */ - abstract public function truncateTableSql(TableSchema $schema); -} diff --git a/vendor/cakephp/cakephp/src/Database/Schema/CachedCollection.php b/vendor/cakephp/cakephp/src/Database/Schema/CachedCollection.php deleted file mode 100644 index 8ec484f..0000000 --- a/vendor/cakephp/cakephp/src/Database/Schema/CachedCollection.php +++ /dev/null @@ -1,132 +0,0 @@ -setCacheMetadata($cacheKey); - } - - /** - * {@inheritDoc} - * - */ - public function describe($name, array $options = []) - { - $options += ['forceRefresh' => false]; - $cacheConfig = $this->getCacheMetadata(); - $cacheKey = $this->cacheKey($name); - - if (!empty($cacheConfig) && !$options['forceRefresh']) { - $cached = Cache::read($cacheKey, $cacheConfig); - if ($cached !== false) { - return $cached; - } - } - - $table = parent::describe($name, $options); - - if (!empty($cacheConfig)) { - Cache::write($cacheKey, $table, $cacheConfig); - } - - return $table; - } - - /** - * Get the cache key for a given name. - * - * @param string $name The name to get a cache key for. - * @return string The cache key. - */ - public function cacheKey($name) - { - return $this->_connection->configName() . '_' . $name; - } - - /** - * Sets the cache config name to use for caching table metadata, or - * disables it if false is passed. - * - * @param bool $enable Whether or not to enable caching - * @return $this - */ - public function setCacheMetadata($enable) - { - if ($enable === true) { - $enable = '_cake_model_'; - } - - $this->_cache = $enable; - - return $this; - } - - /** - * Gets the cache config name to use for caching table metadata, false means disabled. - * - * @return string|bool - */ - public function getCacheMetadata() - { - return $this->_cache; - } - - /** - * Sets the cache config name to use for caching table metadata, or - * disables it if false is passed. - * If called with no arguments it returns the current configuration name. - * - * @deprecated 3.4.0 Use setCacheMetadata()/getCacheMetadata() - * @param bool|null $enable Whether or not to enable caching - * @return string|bool - */ - public function cacheMetadata($enable = null) - { - deprecationWarning( - 'CachedCollection::cacheMetadata() is deprecated. ' . - 'Use CachedCollection::setCacheMetadata()/getCacheMetadata() instead.' - ); - if ($enable !== null) { - $this->setCacheMetadata($enable); - } - - return $this->getCacheMetadata(); - } -} diff --git a/vendor/cakephp/cakephp/src/Database/Schema/Collection.php b/vendor/cakephp/cakephp/src/Database/Schema/Collection.php deleted file mode 100644 index 483bc9a..0000000 --- a/vendor/cakephp/cakephp/src/Database/Schema/Collection.php +++ /dev/null @@ -1,138 +0,0 @@ -_connection = $connection; - $this->_dialect = $connection->getDriver()->schemaDialect(); - } - - /** - * Get the list of tables available in the current connection. - * - * @return array The list of tables in the connected database/schema. - */ - public function listTables() - { - list($sql, $params) = $this->_dialect->listTablesSql($this->_connection->config()); - $result = []; - $statement = $this->_connection->execute($sql, $params); - while ($row = $statement->fetch()) { - $result[] = $row[0]; - } - $statement->closeCursor(); - - return $result; - } - - /** - * Get the column metadata for a table. - * - * Caching will be applied if `cacheMetadata` key is present in the Connection - * configuration options. Defaults to _cake_model_ when true. - * - * ### Options - * - * - `forceRefresh` - Set to true to force rebuilding the cached metadata. - * Defaults to false. - * - * @param string $name The name of the table to describe. - * @param array $options The options to use, see above. - * @return \Cake\Database\Schema\TableSchema Object with column metadata. - * @throws \Cake\Database\Exception when table cannot be described. - */ - public function describe($name, array $options = []) - { - $config = $this->_connection->config(); - if (strpos($name, '.')) { - list($config['schema'], $name) = explode('.', $name); - } - $table = new TableSchema($name); - - $this->_reflect('Column', $name, $config, $table); - if (count($table->columns()) === 0) { - throw new Exception(sprintf('Cannot describe %s. It has 0 columns.', $name)); - } - - $this->_reflect('Index', $name, $config, $table); - $this->_reflect('ForeignKey', $name, $config, $table); - $this->_reflect('Options', $name, $config, $table); - - return $table; - } - - /** - * Helper method for running each step of the reflection process. - * - * @param string $stage The stage name. - * @param string $name The table name. - * @param array $config The config data. - * @param \Cake\Database\Schema\TableSchema $schema The table instance - * @return void - * @throws \Cake\Database\Exception on query failure. - */ - protected function _reflect($stage, $name, $config, $schema) - { - $describeMethod = "describe{$stage}Sql"; - $convertMethod = "convert{$stage}Description"; - - list($sql, $params) = $this->_dialect->{$describeMethod}($name, $config); - if (empty($sql)) { - return; - } - try { - $statement = $this->_connection->execute($sql, $params); - } catch (PDOException $e) { - throw new Exception($e->getMessage(), 500, $e); - } - foreach ($statement->fetchAll('assoc') as $row) { - $this->_dialect->{$convertMethod}($schema, $row); - } - $statement->closeCursor(); - } -} diff --git a/vendor/cakephp/cakephp/src/Database/Schema/MysqlSchema.php b/vendor/cakephp/cakephp/src/Database/Schema/MysqlSchema.php deleted file mode 100644 index 5ca25bf..0000000 --- a/vendor/cakephp/cakephp/src/Database/Schema/MysqlSchema.php +++ /dev/null @@ -1,564 +0,0 @@ -_driver->quoteIdentifier($config['database']), []]; - } - - /** - * {@inheritDoc} - */ - public function describeColumnSql($tableName, $config) - { - return ['SHOW FULL COLUMNS FROM ' . $this->_driver->quoteIdentifier($tableName), []]; - } - - /** - * {@inheritDoc} - */ - public function describeIndexSql($tableName, $config) - { - return ['SHOW INDEXES FROM ' . $this->_driver->quoteIdentifier($tableName), []]; - } - - /** - * {@inheritDoc} - */ - public function describeOptionsSql($tableName, $config) - { - return ['SHOW TABLE STATUS WHERE Name = ?', [$tableName]]; - } - - /** - * {@inheritDoc} - */ - public function convertOptionsDescription(TableSchema $schema, $row) - { - $schema->setOptions([ - 'engine' => $row['Engine'], - 'collation' => $row['Collation'], - ]); - } - - /** - * Convert a MySQL column type into an abstract type. - * - * The returned type will be a type that Cake\Database\Type can handle. - * - * @param string $column The column type + length - * @return array Array of column information. - * @throws \Cake\Database\Exception When column type cannot be parsed. - */ - protected function _convertColumn($column) - { - preg_match('/([a-z]+)(?:\(([0-9,]+)\))?\s*([a-z]+)?/i', $column, $matches); - if (empty($matches)) { - throw new Exception(sprintf('Unable to parse column type from "%s"', $column)); - } - - $col = strtolower($matches[1]); - $length = $precision = null; - if (isset($matches[2])) { - $length = $matches[2]; - if (strpos($matches[2], ',') !== false) { - list($length, $precision) = explode(',', $length); - } - $length = (int)$length; - $precision = (int)$precision; - } - - if (in_array($col, ['date', 'time', 'datetime', 'timestamp'])) { - return ['type' => $col, 'length' => null]; - } - if (($col === 'tinyint' && $length === 1) || $col === 'boolean') { - return ['type' => TableSchema::TYPE_BOOLEAN, 'length' => null]; - } - - $unsigned = (isset($matches[3]) && strtolower($matches[3]) === 'unsigned'); - if (strpos($col, 'bigint') !== false || $col === 'bigint') { - return ['type' => TableSchema::TYPE_BIGINTEGER, 'length' => $length, 'unsigned' => $unsigned]; - } - if ($col === 'tinyint') { - return ['type' => TableSchema::TYPE_TINYINTEGER, 'length' => $length, 'unsigned' => $unsigned]; - } - if ($col === 'smallint') { - return ['type' => TableSchema::TYPE_SMALLINTEGER, 'length' => $length, 'unsigned' => $unsigned]; - } - if (in_array($col, ['int', 'integer', 'mediumint'])) { - return ['type' => TableSchema::TYPE_INTEGER, 'length' => $length, 'unsigned' => $unsigned]; - } - if ($col === 'char' && $length === 36) { - return ['type' => TableSchema::TYPE_UUID, 'length' => null]; - } - if ($col === 'char') { - return ['type' => TableSchema::TYPE_STRING, 'fixed' => true, 'length' => $length]; - } - if (strpos($col, 'char') !== false) { - return ['type' => TableSchema::TYPE_STRING, 'length' => $length]; - } - if (strpos($col, 'text') !== false) { - $lengthName = substr($col, 0, -4); - $length = isset(TableSchema::$columnLengths[$lengthName]) ? TableSchema::$columnLengths[$lengthName] : null; - - return ['type' => TableSchema::TYPE_TEXT, 'length' => $length]; - } - if ($col === 'binary' && $length === 16) { - return ['type' => TableSchema::TYPE_BINARY_UUID, 'length' => null]; - } - if (strpos($col, 'blob') !== false || $col === 'binary') { - $lengthName = substr($col, 0, -4); - $length = isset(TableSchema::$columnLengths[$lengthName]) ? TableSchema::$columnLengths[$lengthName] : null; - - return ['type' => TableSchema::TYPE_BINARY, 'length' => $length]; - } - if (strpos($col, 'float') !== false || strpos($col, 'double') !== false) { - return [ - 'type' => TableSchema::TYPE_FLOAT, - 'length' => $length, - 'precision' => $precision, - 'unsigned' => $unsigned - ]; - } - if (strpos($col, 'decimal') !== false) { - return [ - 'type' => TableSchema::TYPE_DECIMAL, - 'length' => $length, - 'precision' => $precision, - 'unsigned' => $unsigned - ]; - } - - if (strpos($col, 'json') !== false) { - return ['type' => TableSchema::TYPE_JSON, 'length' => null]; - } - - return ['type' => TableSchema::TYPE_STRING, 'length' => null]; - } - - /** - * {@inheritDoc} - */ - public function convertColumnDescription(TableSchema $schema, $row) - { - $field = $this->_convertColumn($row['Type']); - $field += [ - 'null' => $row['Null'] === 'YES', - 'default' => $row['Default'], - 'collate' => $row['Collation'], - 'comment' => $row['Comment'], - ]; - if (isset($row['Extra']) && $row['Extra'] === 'auto_increment') { - $field['autoIncrement'] = true; - } - $schema->addColumn($row['Field'], $field); - } - - /** - * {@inheritDoc} - */ - public function convertIndexDescription(TableSchema $schema, $row) - { - $type = null; - $columns = $length = []; - - $name = $row['Key_name']; - if ($name === 'PRIMARY') { - $name = $type = TableSchema::CONSTRAINT_PRIMARY; - } - - $columns[] = $row['Column_name']; - - if ($row['Index_type'] === 'FULLTEXT') { - $type = TableSchema::INDEX_FULLTEXT; - } elseif ($row['Non_unique'] == 0 && $type !== 'primary') { - $type = TableSchema::CONSTRAINT_UNIQUE; - } elseif ($type !== 'primary') { - $type = TableSchema::INDEX_INDEX; - } - - if (!empty($row['Sub_part'])) { - $length[$row['Column_name']] = $row['Sub_part']; - } - $isIndex = ( - $type === TableSchema::INDEX_INDEX || - $type === TableSchema::INDEX_FULLTEXT - ); - if ($isIndex) { - $existing = $schema->getIndex($name); - } else { - $existing = $schema->getConstraint($name); - } - - // MySQL multi column indexes come back as multiple rows. - if (!empty($existing)) { - $columns = array_merge($existing['columns'], $columns); - $length = array_merge($existing['length'], $length); - } - if ($isIndex) { - $schema->addIndex($name, [ - 'type' => $type, - 'columns' => $columns, - 'length' => $length - ]); - } else { - $schema->addConstraint($name, [ - 'type' => $type, - 'columns' => $columns, - 'length' => $length - ]); - } - } - - /** - * {@inheritDoc} - */ - public function describeForeignKeySql($tableName, $config) - { - $sql = 'SELECT * FROM information_schema.key_column_usage AS kcu - INNER JOIN information_schema.referential_constraints AS rc - ON ( - kcu.CONSTRAINT_NAME = rc.CONSTRAINT_NAME - AND kcu.CONSTRAINT_SCHEMA = rc.CONSTRAINT_SCHEMA - ) - WHERE kcu.TABLE_SCHEMA = ? AND kcu.TABLE_NAME = ? AND rc.TABLE_NAME = ?'; - - return [$sql, [$config['database'], $tableName, $tableName]]; - } - - /** - * {@inheritDoc} - */ - public function convertForeignKeyDescription(TableSchema $schema, $row) - { - $data = [ - 'type' => TableSchema::CONSTRAINT_FOREIGN, - 'columns' => [$row['COLUMN_NAME']], - 'references' => [$row['REFERENCED_TABLE_NAME'], $row['REFERENCED_COLUMN_NAME']], - 'update' => $this->_convertOnClause($row['UPDATE_RULE']), - 'delete' => $this->_convertOnClause($row['DELETE_RULE']), - ]; - $name = $row['CONSTRAINT_NAME']; - $schema->addConstraint($name, $data); - } - - /** - * {@inheritDoc} - */ - public function truncateTableSql(TableSchema $schema) - { - return [sprintf('TRUNCATE TABLE `%s`', $schema->name())]; - } - - /** - * {@inheritDoc} - */ - public function createTableSql(TableSchema $schema, $columns, $constraints, $indexes) - { - $content = implode(",\n", array_merge($columns, $constraints, $indexes)); - $temporary = $schema->isTemporary() ? ' TEMPORARY ' : ' '; - $content = sprintf("CREATE%sTABLE `%s` (\n%s\n)", $temporary, $schema->name(), $content); - $options = $schema->getOptions(); - if (isset($options['engine'])) { - $content .= sprintf(' ENGINE=%s', $options['engine']); - } - if (isset($options['charset'])) { - $content .= sprintf(' DEFAULT CHARSET=%s', $options['charset']); - } - if (isset($options['collate'])) { - $content .= sprintf(' COLLATE=%s', $options['collate']); - } - - return [$content]; - } - - /** - * {@inheritDoc} - */ - public function columnSql(TableSchema $schema, $name) - { - $data = $schema->getColumn($name); - $out = $this->_driver->quoteIdentifier($name); - $nativeJson = $this->_driver->supportsNativeJson(); - - $typeMap = [ - TableSchema::TYPE_TINYINTEGER => ' TINYINT', - TableSchema::TYPE_SMALLINTEGER => ' SMALLINT', - TableSchema::TYPE_INTEGER => ' INTEGER', - TableSchema::TYPE_BIGINTEGER => ' BIGINT', - TableSchema::TYPE_BINARY_UUID => ' BINARY(16)', - TableSchema::TYPE_BOOLEAN => ' BOOLEAN', - TableSchema::TYPE_FLOAT => ' FLOAT', - TableSchema::TYPE_DECIMAL => ' DECIMAL', - TableSchema::TYPE_DATE => ' DATE', - TableSchema::TYPE_TIME => ' TIME', - TableSchema::TYPE_DATETIME => ' DATETIME', - TableSchema::TYPE_TIMESTAMP => ' TIMESTAMP', - TableSchema::TYPE_UUID => ' CHAR(36)', - TableSchema::TYPE_JSON => $nativeJson ? ' JSON' : ' LONGTEXT' - ]; - $specialMap = [ - 'string' => true, - 'text' => true, - 'binary' => true, - ]; - if (isset($typeMap[$data['type']])) { - $out .= $typeMap[$data['type']]; - } - if (isset($specialMap[$data['type']])) { - switch ($data['type']) { - case TableSchema::TYPE_STRING: - $out .= !empty($data['fixed']) ? ' CHAR' : ' VARCHAR'; - if (!isset($data['length'])) { - $data['length'] = 255; - } - break; - case TableSchema::TYPE_TEXT: - $isKnownLength = in_array($data['length'], TableSchema::$columnLengths); - if (empty($data['length']) || !$isKnownLength) { - $out .= ' TEXT'; - break; - } - - if ($isKnownLength) { - $length = array_search($data['length'], TableSchema::$columnLengths); - $out .= ' ' . strtoupper($length) . 'TEXT'; - } - - break; - case TableSchema::TYPE_BINARY: - $isKnownLength = in_array($data['length'], TableSchema::$columnLengths); - if (empty($data['length']) || !$isKnownLength) { - $out .= ' BLOB'; - break; - } - - if ($isKnownLength) { - $length = array_search($data['length'], TableSchema::$columnLengths); - $out .= ' ' . strtoupper($length) . 'BLOB'; - } - - break; - } - } - $hasLength = [ - TableSchema::TYPE_INTEGER, - TableSchema::TYPE_SMALLINTEGER, - TableSchema::TYPE_TINYINTEGER, - TableSchema::TYPE_STRING - ]; - if (in_array($data['type'], $hasLength, true) && isset($data['length'])) { - $out .= '(' . (int)$data['length'] . ')'; - } - - $hasPrecision = [TableSchema::TYPE_FLOAT, TableSchema::TYPE_DECIMAL]; - if (in_array($data['type'], $hasPrecision, true) && - (isset($data['length']) || isset($data['precision'])) - ) { - $out .= '(' . (int)$data['length'] . ',' . (int)$data['precision'] . ')'; - } - - $hasUnsigned = [ - TableSchema::TYPE_TINYINTEGER, - TableSchema::TYPE_SMALLINTEGER, - TableSchema::TYPE_INTEGER, - TableSchema::TYPE_BIGINTEGER, - TableSchema::TYPE_FLOAT, - TableSchema::TYPE_DECIMAL - ]; - if (in_array($data['type'], $hasUnsigned, true) && - isset($data['unsigned']) && $data['unsigned'] === true - ) { - $out .= ' UNSIGNED'; - } - - $hasCollate = [ - TableSchema::TYPE_TEXT, - TableSchema::TYPE_STRING, - ]; - if (in_array($data['type'], $hasCollate, true) && isset($data['collate']) && $data['collate'] !== '') { - $out .= ' COLLATE ' . $data['collate']; - } - - if (isset($data['null']) && $data['null'] === false) { - $out .= ' NOT NULL'; - } - $addAutoIncrement = ( - [$name] == (array)$schema->primaryKey() && - !$schema->hasAutoincrement() && - !isset($data['autoIncrement']) - ); - if (in_array($data['type'], [TableSchema::TYPE_INTEGER, TableSchema::TYPE_BIGINTEGER]) && - ($data['autoIncrement'] === true || $addAutoIncrement) - ) { - $out .= ' AUTO_INCREMENT'; - } - if (isset($data['null']) && $data['null'] === true && $data['type'] === TableSchema::TYPE_TIMESTAMP) { - $out .= ' NULL'; - unset($data['default']); - } - if (isset($data['default']) && - in_array($data['type'], [TableSchema::TYPE_TIMESTAMP, TableSchema::TYPE_DATETIME]) && - in_array(strtolower($data['default']), ['current_timestamp', 'current_timestamp()']) - ) { - $out .= ' DEFAULT CURRENT_TIMESTAMP'; - unset($data['default']); - } - if (isset($data['default'])) { - $out .= ' DEFAULT ' . $this->_driver->schemaValue($data['default']); - unset($data['default']); - } - if (isset($data['comment']) && $data['comment'] !== '') { - $out .= ' COMMENT ' . $this->_driver->schemaValue($data['comment']); - } - - return $out; - } - - /** - * {@inheritDoc} - */ - public function constraintSql(TableSchema $schema, $name) - { - $data = $schema->getConstraint($name); - if ($data['type'] === TableSchema::CONSTRAINT_PRIMARY) { - $columns = array_map( - [$this->_driver, 'quoteIdentifier'], - $data['columns'] - ); - - return sprintf('PRIMARY KEY (%s)', implode(', ', $columns)); - } - - $out = ''; - if ($data['type'] === TableSchema::CONSTRAINT_UNIQUE) { - $out = 'UNIQUE KEY '; - } - if ($data['type'] === TableSchema::CONSTRAINT_FOREIGN) { - $out = 'CONSTRAINT '; - } - $out .= $this->_driver->quoteIdentifier($name); - - return $this->_keySql($out, $data); - } - - /** - * {@inheritDoc} - */ - public function addConstraintSql(TableSchema $schema) - { - $sqlPattern = 'ALTER TABLE %s ADD %s;'; - $sql = []; - - foreach ($schema->constraints() as $name) { - $constraint = $schema->getConstraint($name); - if ($constraint['type'] === TableSchema::CONSTRAINT_FOREIGN) { - $tableName = $this->_driver->quoteIdentifier($schema->name()); - $sql[] = sprintf($sqlPattern, $tableName, $this->constraintSql($schema, $name)); - } - } - - return $sql; - } - - /** - * {@inheritDoc} - */ - public function dropConstraintSql(TableSchema $schema) - { - $sqlPattern = 'ALTER TABLE %s DROP FOREIGN KEY %s;'; - $sql = []; - - foreach ($schema->constraints() as $name) { - $constraint = $schema->getConstraint($name); - if ($constraint['type'] === TableSchema::CONSTRAINT_FOREIGN) { - $tableName = $this->_driver->quoteIdentifier($schema->name()); - $constraintName = $this->_driver->quoteIdentifier($name); - $sql[] = sprintf($sqlPattern, $tableName, $constraintName); - } - } - - return $sql; - } - - /** - * {@inheritDoc} - */ - public function indexSql(TableSchema $schema, $name) - { - $data = $schema->getIndex($name); - $out = ''; - if ($data['type'] === TableSchema::INDEX_INDEX) { - $out = 'KEY '; - } - if ($data['type'] === TableSchema::INDEX_FULLTEXT) { - $out = 'FULLTEXT KEY '; - } - $out .= $this->_driver->quoteIdentifier($name); - - return $this->_keySql($out, $data); - } - - /** - * Helper method for generating key SQL snippets. - * - * @param string $prefix The key prefix - * @param array $data Key data. - * @return string - */ - protected function _keySql($prefix, $data) - { - $columns = array_map( - [$this->_driver, 'quoteIdentifier'], - $data['columns'] - ); - foreach ($data['columns'] as $i => $column) { - if (isset($data['length'][$column])) { - $columns[$i] .= sprintf('(%d)', $data['length'][$column]); - } - } - if ($data['type'] === TableSchema::CONSTRAINT_FOREIGN) { - return $prefix . sprintf( - ' FOREIGN KEY (%s) REFERENCES %s (%s) ON UPDATE %s ON DELETE %s', - implode(', ', $columns), - $this->_driver->quoteIdentifier($data['references'][0]), - $this->_convertConstraintColumns($data['references'][1]), - $this->_foreignOnClause($data['update']), - $this->_foreignOnClause($data['delete']) - ); - } - - return $prefix . ' (' . implode(', ', $columns) . ')'; - } -} diff --git a/vendor/cakephp/cakephp/src/Database/Schema/PostgresSchema.php b/vendor/cakephp/cakephp/src/Database/Schema/PostgresSchema.php deleted file mode 100644 index 0a5a274..0000000 --- a/vendor/cakephp/cakephp/src/Database/Schema/PostgresSchema.php +++ /dev/null @@ -1,600 +0,0 @@ - $col, 'length' => null]; - } - if (strpos($col, 'timestamp') !== false) { - return ['type' => TableSchema::TYPE_TIMESTAMP, 'length' => null]; - } - if (strpos($col, 'time') !== false) { - return ['type' => TableSchema::TYPE_TIME, 'length' => null]; - } - if ($col === 'serial' || $col === 'integer') { - return ['type' => TableSchema::TYPE_INTEGER, 'length' => 10]; - } - if ($col === 'bigserial' || $col === 'bigint') { - return ['type' => TableSchema::TYPE_BIGINTEGER, 'length' => 20]; - } - if ($col === 'smallint') { - return ['type' => TableSchema::TYPE_SMALLINTEGER, 'length' => 5]; - } - if ($col === 'inet') { - return ['type' => TableSchema::TYPE_STRING, 'length' => 39]; - } - if ($col === 'uuid') { - return ['type' => TableSchema::TYPE_UUID, 'length' => null]; - } - if ($col === 'char' || $col === 'character') { - return ['type' => TableSchema::TYPE_STRING, 'fixed' => true, 'length' => $length]; - } - // money is 'string' as it includes arbitrary text content - // before the number value. - if (strpos($col, 'char') !== false || - strpos($col, 'money') !== false - ) { - return ['type' => TableSchema::TYPE_STRING, 'length' => $length]; - } - if (strpos($col, 'text') !== false) { - return ['type' => TableSchema::TYPE_TEXT, 'length' => null]; - } - if ($col === 'bytea') { - return ['type' => TableSchema::TYPE_BINARY, 'length' => null]; - } - if ($col === 'real' || strpos($col, 'double') !== false) { - return ['type' => TableSchema::TYPE_FLOAT, 'length' => null]; - } - if (strpos($col, 'numeric') !== false || - strpos($col, 'decimal') !== false - ) { - return ['type' => TableSchema::TYPE_DECIMAL, 'length' => null]; - } - - if (strpos($col, 'json') !== false) { - return ['type' => TableSchema::TYPE_JSON, 'length' => null]; - } - - return ['type' => TableSchema::TYPE_STRING, 'length' => null]; - } - - /** - * {@inheritDoc} - */ - public function convertColumnDescription(TableSchema $schema, $row) - { - $field = $this->_convertColumn($row['type']); - - if ($field['type'] === TableSchema::TYPE_BOOLEAN) { - if ($row['default'] === 'true') { - $row['default'] = 1; - } - if ($row['default'] === 'false') { - $row['default'] = 0; - } - } - if (!empty($row['has_serial'])) { - $field['autoIncrement'] = true; - } - - $field += [ - 'default' => $this->_defaultValue($row['default']), - 'null' => $row['null'] === 'YES', - 'collate' => $row['collation_name'], - 'comment' => $row['comment'] - ]; - $field['length'] = $row['char_length'] ?: $field['length']; - - if ($field['type'] === 'numeric' || $field['type'] === 'decimal') { - $field['length'] = $row['column_precision']; - $field['precision'] = $row['column_scale'] ?: null; - } - $schema->addColumn($row['name'], $field); - } - - /** - * Manipulate the default value. - * - * Postgres includes sequence data and casting information in default values. - * We need to remove those. - * - * @param string|null $default The default value. - * @return string|null - */ - protected function _defaultValue($default) - { - if (is_numeric($default) || $default === null) { - return $default; - } - // Sequences - if (strpos($default, 'nextval') === 0) { - return null; - } - - if (strpos($default, 'NULL::') === 0) { - return null; - } - - // Remove quotes and postgres casts - return preg_replace( - "/^'(.*)'(?:::.*)$/", - '$1', - $default - ); - } - - /** - * {@inheritDoc} - */ - public function describeIndexSql($tableName, $config) - { - $sql = 'SELECT - c2.relname, - a.attname, - i.indisprimary, - i.indisunique - FROM pg_catalog.pg_namespace n - INNER JOIN pg_catalog.pg_class c ON (n.oid = c.relnamespace) - INNER JOIN pg_catalog.pg_index i ON (c.oid = i.indrelid) - INNER JOIN pg_catalog.pg_class c2 ON (c2.oid = i.indexrelid) - INNER JOIN pg_catalog.pg_attribute a ON (a.attrelid = c.oid AND i.indrelid::regclass = a.attrelid::regclass) - WHERE n.nspname = ? - AND a.attnum = ANY(i.indkey) - AND c.relname = ? - ORDER BY i.indisprimary DESC, i.indisunique DESC, c.relname, a.attnum'; - - $schema = 'public'; - if (!empty($config['schema'])) { - $schema = $config['schema']; - } - - return [$sql, [$schema, $tableName]]; - } - - /** - * {@inheritDoc} - */ - public function convertIndexDescription(TableSchema $schema, $row) - { - $type = TableSchema::INDEX_INDEX; - $name = $row['relname']; - if ($row['indisprimary']) { - $name = $type = TableSchema::CONSTRAINT_PRIMARY; - } - if ($row['indisunique'] && $type === TableSchema::INDEX_INDEX) { - $type = TableSchema::CONSTRAINT_UNIQUE; - } - if ($type === TableSchema::CONSTRAINT_PRIMARY || $type === TableSchema::CONSTRAINT_UNIQUE) { - $this->_convertConstraint($schema, $name, $type, $row); - - return; - } - $index = $schema->getIndex($name); - if (!$index) { - $index = [ - 'type' => $type, - 'columns' => [] - ]; - } - $index['columns'][] = $row['attname']; - $schema->addIndex($name, $index); - } - - /** - * Add/update a constraint into the schema object. - * - * @param \Cake\Database\Schema\TableSchema $schema The table to update. - * @param string $name The index name. - * @param string $type The index type. - * @param array $row The metadata record to update with. - * @return void - */ - protected function _convertConstraint($schema, $name, $type, $row) - { - $constraint = $schema->getConstraint($name); - if (!$constraint) { - $constraint = [ - 'type' => $type, - 'columns' => [] - ]; - } - $constraint['columns'][] = $row['attname']; - $schema->addConstraint($name, $constraint); - } - - /** - * {@inheritDoc} - */ - public function describeForeignKeySql($tableName, $config) - { - $sql = 'SELECT - c.conname AS name, - c.contype AS type, - a.attname AS column_name, - c.confmatchtype AS match_type, - c.confupdtype AS on_update, - c.confdeltype AS on_delete, - c.confrelid::regclass AS references_table, - ab.attname AS references_field - FROM pg_catalog.pg_namespace n - INNER JOIN pg_catalog.pg_class cl ON (n.oid = cl.relnamespace) - INNER JOIN pg_catalog.pg_constraint c ON (n.oid = c.connamespace) - INNER JOIN pg_catalog.pg_attribute a ON (a.attrelid = cl.oid AND c.conrelid = a.attrelid AND a.attnum = ANY(c.conkey)) - INNER JOIN pg_catalog.pg_attribute ab ON (a.attrelid = cl.oid AND c.confrelid = ab.attrelid AND ab.attnum = ANY(c.confkey)) - WHERE n.nspname = ? - AND cl.relname = ? - ORDER BY name, a.attnum, ab.attnum DESC'; - - $schema = empty($config['schema']) ? 'public' : $config['schema']; - - return [$sql, [$schema, $tableName]]; - } - - /** - * {@inheritDoc} - */ - public function convertForeignKeyDescription(TableSchema $schema, $row) - { - $data = [ - 'type' => TableSchema::CONSTRAINT_FOREIGN, - 'columns' => $row['column_name'], - 'references' => [$row['references_table'], $row['references_field']], - 'update' => $this->_convertOnClause($row['on_update']), - 'delete' => $this->_convertOnClause($row['on_delete']), - ]; - $schema->addConstraint($row['name'], $data); - } - - /** - * {@inheritDoc} - */ - protected function _convertOnClause($clause) - { - if ($clause === 'r') { - return TableSchema::ACTION_RESTRICT; - } - if ($clause === 'a') { - return TableSchema::ACTION_NO_ACTION; - } - if ($clause === 'c') { - return TableSchema::ACTION_CASCADE; - } - - return TableSchema::ACTION_SET_NULL; - } - - /** - * {@inheritDoc} - */ - public function columnSql(TableSchema $schema, $name) - { - $data = $schema->getColumn($name); - $out = $this->_driver->quoteIdentifier($name); - $typeMap = [ - TableSchema::TYPE_TINYINTEGER => ' SMALLINT', - TableSchema::TYPE_SMALLINTEGER => ' SMALLINT', - TableSchema::TYPE_BINARY_UUID => ' UUID', - TableSchema::TYPE_BINARY => ' BYTEA', - TableSchema::TYPE_BOOLEAN => ' BOOLEAN', - TableSchema::TYPE_FLOAT => ' FLOAT', - TableSchema::TYPE_DECIMAL => ' DECIMAL', - TableSchema::TYPE_DATE => ' DATE', - TableSchema::TYPE_TIME => ' TIME', - TableSchema::TYPE_DATETIME => ' TIMESTAMP', - TableSchema::TYPE_TIMESTAMP => ' TIMESTAMP', - TableSchema::TYPE_UUID => ' UUID', - TableSchema::TYPE_JSON => ' JSONB' - ]; - - if (isset($typeMap[$data['type']])) { - $out .= $typeMap[$data['type']]; - } - - if ($data['type'] === TableSchema::TYPE_INTEGER || $data['type'] === TableSchema::TYPE_BIGINTEGER) { - $type = $data['type'] === TableSchema::TYPE_INTEGER ? ' INTEGER' : ' BIGINT'; - if ([$name] === $schema->primaryKey() || $data['autoIncrement'] === true) { - $type = $data['type'] === TableSchema::TYPE_INTEGER ? ' SERIAL' : ' BIGSERIAL'; - unset($data['null'], $data['default']); - } - $out .= $type; - } - - if ($data['type'] === TableSchema::TYPE_TEXT && $data['length'] !== TableSchema::LENGTH_TINY) { - $out .= ' TEXT'; - } - - if ($data['type'] === TableSchema::TYPE_STRING || - ($data['type'] === TableSchema::TYPE_TEXT && $data['length'] === TableSchema::LENGTH_TINY) - ) { - $isFixed = !empty($data['fixed']); - $type = ' VARCHAR'; - if ($isFixed) { - $type = ' CHAR'; - } - $out .= $type; - if (isset($data['length']) && $data['length'] != 36) { - $out .= '(' . (int)$data['length'] . ')'; - } - } - - $hasCollate = [TableSchema::TYPE_TEXT, TableSchema::TYPE_STRING]; - if (in_array($data['type'], $hasCollate, true) && isset($data['collate']) && $data['collate'] !== '') { - $out .= ' COLLATE "' . $data['collate'] . '"'; - } - - if ($data['type'] === TableSchema::TYPE_FLOAT && isset($data['precision'])) { - $out .= '(' . (int)$data['precision'] . ')'; - } - - if ($data['type'] === TableSchema::TYPE_DECIMAL && - (isset($data['length']) || isset($data['precision'])) - ) { - $out .= '(' . (int)$data['length'] . ',' . (int)$data['precision'] . ')'; - } - - if (isset($data['null']) && $data['null'] === false) { - $out .= ' NOT NULL'; - } - - if (isset($data['default']) && - in_array($data['type'], [TableSchema::TYPE_TIMESTAMP, TableSchema::TYPE_DATETIME]) && - strtolower($data['default']) === 'current_timestamp' - ) { - $out .= ' DEFAULT CURRENT_TIMESTAMP'; - } elseif (isset($data['default'])) { - $defaultValue = $data['default']; - if ($data['type'] === 'boolean') { - $defaultValue = (bool)$defaultValue; - } - $out .= ' DEFAULT ' . $this->_driver->schemaValue($defaultValue); - } elseif (isset($data['null']) && $data['null'] !== false) { - $out .= ' DEFAULT NULL'; - } - - return $out; - } - - /** - * {@inheritDoc} - */ - public function addConstraintSql(TableSchema $schema) - { - $sqlPattern = 'ALTER TABLE %s ADD %s;'; - $sql = []; - - foreach ($schema->constraints() as $name) { - $constraint = $schema->getConstraint($name); - if ($constraint['type'] === TableSchema::CONSTRAINT_FOREIGN) { - $tableName = $this->_driver->quoteIdentifier($schema->name()); - $sql[] = sprintf($sqlPattern, $tableName, $this->constraintSql($schema, $name)); - } - } - - return $sql; - } - - /** - * {@inheritDoc} - */ - public function dropConstraintSql(TableSchema $schema) - { - $sqlPattern = 'ALTER TABLE %s DROP CONSTRAINT %s;'; - $sql = []; - - foreach ($schema->constraints() as $name) { - $constraint = $schema->getConstraint($name); - if ($constraint['type'] === TableSchema::CONSTRAINT_FOREIGN) { - $tableName = $this->_driver->quoteIdentifier($schema->name()); - $constraintName = $this->_driver->quoteIdentifier($name); - $sql[] = sprintf($sqlPattern, $tableName, $constraintName); - } - } - - return $sql; - } - - /** - * {@inheritDoc} - */ - public function indexSql(TableSchema $schema, $name) - { - $data = $schema->getIndex($name); - $columns = array_map( - [$this->_driver, 'quoteIdentifier'], - $data['columns'] - ); - - return sprintf( - 'CREATE INDEX %s ON %s (%s)', - $this->_driver->quoteIdentifier($name), - $this->_driver->quoteIdentifier($schema->name()), - implode(', ', $columns) - ); - } - - /** - * {@inheritDoc} - */ - public function constraintSql(TableSchema $schema, $name) - { - $data = $schema->getConstraint($name); - $out = 'CONSTRAINT ' . $this->_driver->quoteIdentifier($name); - if ($data['type'] === TableSchema::CONSTRAINT_PRIMARY) { - $out = 'PRIMARY KEY'; - } - if ($data['type'] === TableSchema::CONSTRAINT_UNIQUE) { - $out .= ' UNIQUE'; - } - - return $this->_keySql($out, $data); - } - - /** - * Helper method for generating key SQL snippets. - * - * @param string $prefix The key prefix - * @param array $data Key data. - * @return string - */ - protected function _keySql($prefix, $data) - { - $columns = array_map( - [$this->_driver, 'quoteIdentifier'], - $data['columns'] - ); - if ($data['type'] === TableSchema::CONSTRAINT_FOREIGN) { - return $prefix . sprintf( - ' FOREIGN KEY (%s) REFERENCES %s (%s) ON UPDATE %s ON DELETE %s DEFERRABLE INITIALLY IMMEDIATE', - implode(', ', $columns), - $this->_driver->quoteIdentifier($data['references'][0]), - $this->_convertConstraintColumns($data['references'][1]), - $this->_foreignOnClause($data['update']), - $this->_foreignOnClause($data['delete']) - ); - } - - return $prefix . ' (' . implode(', ', $columns) . ')'; - } - - /** - * {@inheritDoc} - */ - public function createTableSql(TableSchema $schema, $columns, $constraints, $indexes) - { - $content = array_merge($columns, $constraints); - $content = implode(",\n", array_filter($content)); - $tableName = $this->_driver->quoteIdentifier($schema->name()); - $temporary = $schema->isTemporary() ? ' TEMPORARY ' : ' '; - $out = []; - $out[] = sprintf("CREATE%sTABLE %s (\n%s\n)", $temporary, $tableName, $content); - foreach ($indexes as $index) { - $out[] = $index; - } - foreach ($schema->columns() as $column) { - $columnData = $schema->getColumn($column); - if (isset($columnData['comment'])) { - $out[] = sprintf( - 'COMMENT ON COLUMN %s.%s IS %s', - $tableName, - $this->_driver->quoteIdentifier($column), - $this->_driver->schemaValue($columnData['comment']) - ); - } - } - - return $out; - } - - /** - * {@inheritDoc} - */ - public function truncateTableSql(TableSchema $schema) - { - $name = $this->_driver->quoteIdentifier($schema->name()); - - return [ - sprintf('TRUNCATE %s RESTART IDENTITY CASCADE', $name) - ]; - } - - /** - * Generate the SQL to drop a table. - * - * @param \Cake\Database\Schema\TableSchema $schema Table instance - * @return array SQL statements to drop a table. - */ - public function dropTableSql(TableSchema $schema) - { - $sql = sprintf( - 'DROP TABLE %s CASCADE', - $this->_driver->quoteIdentifier($schema->name()) - ); - - return [$sql]; - } -} diff --git a/vendor/cakephp/cakephp/src/Database/Schema/SqliteSchema.php b/vendor/cakephp/cakephp/src/Database/Schema/SqliteSchema.php deleted file mode 100644 index 1642e18..0000000 --- a/vendor/cakephp/cakephp/src/Database/Schema/SqliteSchema.php +++ /dev/null @@ -1,518 +0,0 @@ - TableSchema::TYPE_BIGINTEGER, 'length' => $length, 'unsigned' => $unsigned]; - } - if ($col == 'smallint') { - return ['type' => TableSchema::TYPE_SMALLINTEGER, 'length' => $length, 'unsigned' => $unsigned]; - } - if ($col == 'tinyint') { - return ['type' => TableSchema::TYPE_TINYINTEGER, 'length' => $length, 'unsigned' => $unsigned]; - } - if (strpos($col, 'int') !== false) { - return ['type' => TableSchema::TYPE_INTEGER, 'length' => $length, 'unsigned' => $unsigned]; - } - if (strpos($col, 'decimal') !== false) { - return ['type' => TableSchema::TYPE_DECIMAL, 'length' => null, 'unsigned' => $unsigned]; - } - if (in_array($col, ['float', 'real', 'double'])) { - return ['type' => TableSchema::TYPE_FLOAT, 'length' => null, 'unsigned' => $unsigned]; - } - - if (strpos($col, 'boolean') !== false) { - return ['type' => TableSchema::TYPE_BOOLEAN, 'length' => null]; - } - - if ($col === 'char' && $length === 36) { - return ['type' => TableSchema::TYPE_UUID, 'length' => null]; - } - if ($col === 'char') { - return ['type' => TableSchema::TYPE_STRING, 'fixed' => true, 'length' => $length]; - } - if (strpos($col, 'char') !== false) { - return ['type' => TableSchema::TYPE_STRING, 'length' => $length]; - } - - if ($col === 'binary' && $length === 16) { - return ['type' => TableSchema::TYPE_BINARY_UUID, 'length' => null]; - } - if (in_array($col, ['blob', 'clob'])) { - return ['type' => TableSchema::TYPE_BINARY, 'length' => null]; - } - if (in_array($col, ['date', 'time', 'timestamp', 'datetime'])) { - return ['type' => $col, 'length' => null]; - } - - return ['type' => TableSchema::TYPE_TEXT, 'length' => null]; - } - - /** - * {@inheritDoc} - */ - public function listTablesSql($config) - { - return [ - 'SELECT name FROM sqlite_master WHERE type="table" ' . - 'AND name != "sqlite_sequence" ORDER BY name', - [] - ]; - } - - /** - * {@inheritDoc} - */ - public function describeColumnSql($tableName, $config) - { - $sql = sprintf( - 'PRAGMA table_info(%s)', - $this->_driver->quoteIdentifier($tableName) - ); - - return [$sql, []]; - } - - /** - * {@inheritDoc} - */ - public function convertColumnDescription(TableSchema $schema, $row) - { - $field = $this->_convertColumn($row['type']); - $field += [ - 'null' => !$row['notnull'], - 'default' => $this->_defaultValue($row['dflt_value']), - ]; - $primary = $schema->getConstraint('primary'); - - if ($row['pk'] && empty($primary)) { - $field['null'] = false; - $field['autoIncrement'] = true; - } - - // SQLite does not support autoincrement on composite keys. - if ($row['pk'] && !empty($primary)) { - $existingColumn = $primary['columns'][0]; - $schema->addColumn($existingColumn, ['autoIncrement' => null] + $schema->getColumn($existingColumn)); - } - - $schema->addColumn($row['name'], $field); - if ($row['pk']) { - $constraint = (array)$schema->getConstraint('primary') + [ - 'type' => TableSchema::CONSTRAINT_PRIMARY, - 'columns' => [] - ]; - $constraint['columns'] = array_merge($constraint['columns'], [$row['name']]); - $schema->addConstraint('primary', $constraint); - } - } - - /** - * Manipulate the default value. - * - * Sqlite includes quotes and bared NULLs in default values. - * We need to remove those. - * - * @param string|null $default The default value. - * @return string|null - */ - protected function _defaultValue($default) - { - if ($default === 'NULL') { - return null; - } - - // Remove quotes - if (preg_match("/^'(.*)'$/", $default, $matches)) { - return str_replace("''", "'", $matches[1]); - } - - return $default; - } - - /** - * {@inheritDoc} - */ - public function describeIndexSql($tableName, $config) - { - $sql = sprintf( - 'PRAGMA index_list(%s)', - $this->_driver->quoteIdentifier($tableName) - ); - - return [$sql, []]; - } - - /** - * {@inheritDoc} - * - * Since SQLite does not have a way to get metadata about all indexes at once, - * additional queries are done here. Sqlite constraint names are not - * stable, and the names for constraints will not match those used to create - * the table. This is a limitation in Sqlite's metadata features. - * - */ - public function convertIndexDescription(TableSchema $schema, $row) - { - $sql = sprintf( - 'PRAGMA index_info(%s)', - $this->_driver->quoteIdentifier($row['name']) - ); - $statement = $this->_driver->prepare($sql); - $statement->execute(); - $columns = []; - foreach ($statement->fetchAll('assoc') as $column) { - $columns[] = $column['name']; - } - $statement->closeCursor(); - if ($row['unique']) { - $schema->addConstraint($row['name'], [ - 'type' => TableSchema::CONSTRAINT_UNIQUE, - 'columns' => $columns - ]); - } else { - $schema->addIndex($row['name'], [ - 'type' => TableSchema::INDEX_INDEX, - 'columns' => $columns - ]); - } - } - - /** - * {@inheritDoc} - */ - public function describeForeignKeySql($tableName, $config) - { - $sql = sprintf('PRAGMA foreign_key_list(%s)', $this->_driver->quoteIdentifier($tableName)); - - return [$sql, []]; - } - - /** - * {@inheritDoc} - */ - public function convertForeignKeyDescription(TableSchema $schema, $row) - { - $name = $row['from'] . '_fk'; - - $update = isset($row['on_update']) ? $row['on_update'] : ''; - $delete = isset($row['on_delete']) ? $row['on_delete'] : ''; - $data = [ - 'type' => TableSchema::CONSTRAINT_FOREIGN, - 'columns' => [$row['from']], - 'references' => [$row['table'], $row['to']], - 'update' => $this->_convertOnClause($update), - 'delete' => $this->_convertOnClause($delete), - ]; - - if (isset($this->_constraintsIdMap[$schema->name()][$row['id']])) { - $name = $this->_constraintsIdMap[$schema->name()][$row['id']]; - } else { - $this->_constraintsIdMap[$schema->name()][$row['id']] = $name; - } - - $schema->addConstraint($name, $data); - } - - /** - * {@inheritDoc} - * - * @throws \Cake\Database\Exception when the column type is unknown - */ - public function columnSql(TableSchema $schema, $name) - { - $data = $schema->getColumn($name); - $typeMap = [ - TableSchema::TYPE_BINARY_UUID => ' BINARY(16)', - TableSchema::TYPE_UUID => ' CHAR(36)', - TableSchema::TYPE_TINYINTEGER => ' TINYINT', - TableSchema::TYPE_SMALLINTEGER => ' SMALLINT', - TableSchema::TYPE_INTEGER => ' INTEGER', - TableSchema::TYPE_BIGINTEGER => ' BIGINT', - TableSchema::TYPE_BOOLEAN => ' BOOLEAN', - TableSchema::TYPE_BINARY => ' BLOB', - TableSchema::TYPE_FLOAT => ' FLOAT', - TableSchema::TYPE_DECIMAL => ' DECIMAL', - TableSchema::TYPE_DATE => ' DATE', - TableSchema::TYPE_TIME => ' TIME', - TableSchema::TYPE_DATETIME => ' DATETIME', - TableSchema::TYPE_TIMESTAMP => ' TIMESTAMP', - TableSchema::TYPE_JSON => ' TEXT' - ]; - - $out = $this->_driver->quoteIdentifier($name); - $hasUnsigned = [ - TableSchema::TYPE_TINYINTEGER, - TableSchema::TYPE_SMALLINTEGER, - TableSchema::TYPE_INTEGER, - TableSchema::TYPE_BIGINTEGER, - TableSchema::TYPE_FLOAT, - TableSchema::TYPE_DECIMAL - ]; - - if (in_array($data['type'], $hasUnsigned, true) && - isset($data['unsigned']) && $data['unsigned'] === true - ) { - if ($data['type'] !== TableSchema::TYPE_INTEGER || [$name] !== (array)$schema->primaryKey()) { - $out .= ' UNSIGNED'; - } - } - - if (isset($typeMap[$data['type']])) { - $out .= $typeMap[$data['type']]; - } - - if ($data['type'] === TableSchema::TYPE_TEXT && $data['length'] !== TableSchema::LENGTH_TINY) { - $out .= ' TEXT'; - } - - if ($data['type'] === TableSchema::TYPE_STRING || - ($data['type'] === TableSchema::TYPE_TEXT && $data['length'] === TableSchema::LENGTH_TINY) - ) { - $out .= ' VARCHAR'; - - if (isset($data['length'])) { - $out .= '(' . (int)$data['length'] . ')'; - } - } - - $integerTypes = [ - TableSchema::TYPE_TINYINTEGER, - TableSchema::TYPE_SMALLINTEGER, - TableSchema::TYPE_INTEGER, - ]; - if (in_array($data['type'], $integerTypes, true) && - isset($data['length']) && [$name] !== (array)$schema->primaryKey() - ) { - $out .= '(' . (int)$data['length'] . ')'; - } - - $hasPrecision = [TableSchema::TYPE_FLOAT, TableSchema::TYPE_DECIMAL]; - if (in_array($data['type'], $hasPrecision, true) && - (isset($data['length']) || isset($data['precision'])) - ) { - $out .= '(' . (int)$data['length'] . ',' . (int)$data['precision'] . ')'; - } - - if (isset($data['null']) && $data['null'] === false) { - $out .= ' NOT NULL'; - } - - if ($data['type'] === TableSchema::TYPE_INTEGER && [$name] === (array)$schema->primaryKey()) { - $out .= ' PRIMARY KEY AUTOINCREMENT'; - } - - if (isset($data['null']) && $data['null'] === true && $data['type'] === TableSchema::TYPE_TIMESTAMP) { - $out .= ' DEFAULT NULL'; - } - if (isset($data['default'])) { - $out .= ' DEFAULT ' . $this->_driver->schemaValue($data['default']); - } - - return $out; - } - - /** - * {@inheritDoc} - * - * Note integer primary keys will return ''. This is intentional as Sqlite requires - * that integer primary keys be defined in the column definition. - * - */ - public function constraintSql(TableSchema $schema, $name) - { - $data = $schema->getConstraint($name); - if ($data['type'] === TableSchema::CONSTRAINT_PRIMARY && - count($data['columns']) === 1 && - $schema->getColumn($data['columns'][0])['type'] === TableSchema::TYPE_INTEGER - ) { - return ''; - } - $clause = ''; - $type = ''; - if ($data['type'] === TableSchema::CONSTRAINT_PRIMARY) { - $type = 'PRIMARY KEY'; - } - if ($data['type'] === TableSchema::CONSTRAINT_UNIQUE) { - $type = 'UNIQUE'; - } - if ($data['type'] === TableSchema::CONSTRAINT_FOREIGN) { - $type = 'FOREIGN KEY'; - - $clause = sprintf( - ' REFERENCES %s (%s) ON UPDATE %s ON DELETE %s', - $this->_driver->quoteIdentifier($data['references'][0]), - $this->_convertConstraintColumns($data['references'][1]), - $this->_foreignOnClause($data['update']), - $this->_foreignOnClause($data['delete']) - ); - } - $columns = array_map( - [$this->_driver, 'quoteIdentifier'], - $data['columns'] - ); - - return sprintf( - 'CONSTRAINT %s %s (%s)%s', - $this->_driver->quoteIdentifier($name), - $type, - implode(', ', $columns), - $clause - ); - } - - /** - * {@inheritDoc} - * - * SQLite can not properly handle adding a constraint to an existing table. - * This method is no-op - */ - public function addConstraintSql(TableSchema $schema) - { - return []; - } - - /** - * {@inheritDoc} - * - * SQLite can not properly handle dropping a constraint to an existing table. - * This method is no-op - */ - public function dropConstraintSql(TableSchema $schema) - { - return []; - } - - /** - * {@inheritDoc} - */ - public function indexSql(TableSchema $schema, $name) - { - $data = $schema->getIndex($name); - $columns = array_map( - [$this->_driver, 'quoteIdentifier'], - $data['columns'] - ); - - return sprintf( - 'CREATE INDEX %s ON %s (%s)', - $this->_driver->quoteIdentifier($name), - $this->_driver->quoteIdentifier($schema->name()), - implode(', ', $columns) - ); - } - - /** - * {@inheritDoc} - */ - public function createTableSql(TableSchema $schema, $columns, $constraints, $indexes) - { - $lines = array_merge($columns, $constraints); - $content = implode(",\n", array_filter($lines)); - $temporary = $schema->isTemporary() ? ' TEMPORARY ' : ' '; - $table = sprintf("CREATE%sTABLE \"%s\" (\n%s\n)", $temporary, $schema->name(), $content); - $out = [$table]; - foreach ($indexes as $index) { - $out[] = $index; - } - - return $out; - } - - /** - * {@inheritDoc} - */ - public function truncateTableSql(TableSchema $schema) - { - $name = $schema->name(); - $sql = []; - if ($this->hasSequences()) { - $sql[] = sprintf('DELETE FROM sqlite_sequence WHERE name="%s"', $name); - } - - $sql[] = sprintf('DELETE FROM "%s"', $name); - - return $sql; - } - - /** - * Returns whether there is any table in this connection to SQLite containing - * sequences - * - * @return bool - */ - public function hasSequences() - { - $result = $this->_driver - ->prepare('SELECT 1 FROM sqlite_master WHERE name = "sqlite_sequence"'); - $result->execute(); - $this->_hasSequences = (bool)$result->rowCount(); - $result->closeCursor(); - - return $this->_hasSequences; - } -} diff --git a/vendor/cakephp/cakephp/src/Database/Schema/SqlserverSchema.php b/vendor/cakephp/cakephp/src/Database/Schema/SqlserverSchema.php deleted file mode 100644 index 7088a75..0000000 --- a/vendor/cakephp/cakephp/src/Database/Schema/SqlserverSchema.php +++ /dev/null @@ -1,576 +0,0 @@ - $col, 'length' => null]; - } - if (strpos($col, 'datetime') !== false) { - return ['type' => TableSchema::TYPE_TIMESTAMP, 'length' => null]; - } - - if ($col === 'tinyint') { - return ['type' => TableSchema::TYPE_TINYINTEGER, 'length' => $precision ?: 3]; - } - if ($col === 'smallint') { - return ['type' => TableSchema::TYPE_SMALLINTEGER, 'length' => $precision ?: 5]; - } - if ($col === 'int' || $col === 'integer') { - return ['type' => TableSchema::TYPE_INTEGER, 'length' => $precision ?: 10]; - } - if ($col === 'bigint') { - return ['type' => TableSchema::TYPE_BIGINTEGER, 'length' => $precision ?: 20]; - } - if ($col === 'bit') { - return ['type' => TableSchema::TYPE_BOOLEAN, 'length' => null]; - } - if (strpos($col, 'numeric') !== false || - strpos($col, 'money') !== false || - strpos($col, 'decimal') !== false - ) { - return ['type' => TableSchema::TYPE_DECIMAL, 'length' => $precision, 'precision' => $scale]; - } - - if ($col === 'real' || $col === 'float') { - return ['type' => TableSchema::TYPE_FLOAT, 'length' => null]; - } - // SqlServer schema reflection returns double length for unicode - // columns because internally it uses UTF16/UCS2 - if ($col === 'nvarchar' || $col === 'nchar' || $col === 'ntext') { - $length = $length / 2; - } - if (strpos($col, 'varchar') !== false && $length < 0) { - return ['type' => TableSchema::TYPE_TEXT, 'length' => null]; - } - - if (strpos($col, 'varchar') !== false) { - return ['type' => TableSchema::TYPE_STRING, 'length' => $length ?: 255]; - } - - if (strpos($col, 'char') !== false) { - return ['type' => TableSchema::TYPE_STRING, 'fixed' => true, 'length' => $length]; - } - - if (strpos($col, 'text') !== false) { - return ['type' => TableSchema::TYPE_TEXT, 'length' => null]; - } - - if ($col === 'image' || strpos($col, 'binary')) { - return ['type' => TableSchema::TYPE_BINARY, 'length' => null]; - } - - if ($col === 'uniqueidentifier') { - return ['type' => TableSchema::TYPE_UUID]; - } - - return ['type' => TableSchema::TYPE_STRING, 'length' => null]; - } - - /** - * {@inheritDoc} - */ - public function convertColumnDescription(TableSchema $schema, $row) - { - $field = $this->_convertColumn( - $row['type'], - $row['char_length'], - $row['precision'], - $row['scale'] - ); - if (!empty($row['default'])) { - $row['default'] = trim($row['default'], '()'); - } - if (!empty($row['autoincrement'])) { - $field['autoIncrement'] = true; - } - if ($field['type'] === TableSchema::TYPE_BOOLEAN) { - $row['default'] = (int)$row['default']; - } - - $field += [ - 'null' => $row['null'] === '1', - 'default' => $this->_defaultValue($row['default']), - 'collate' => $row['collation_name'], - ]; - $schema->addColumn($row['name'], $field); - } - - /** - * Manipulate the default value. - * - * Sqlite includes quotes and bared NULLs in default values. - * We need to remove those. - * - * @param string|null $default The default value. - * @return string|null - */ - protected function _defaultValue($default) - { - if ($default === 'NULL') { - return null; - } - - // Remove quotes - if (preg_match("/^N?'(.*)'/", $default, $matches)) { - return str_replace("''", "'", $matches[1]); - } - - return $default; - } - - /** - * {@inheritDoc} - */ - public function describeIndexSql($tableName, $config) - { - $sql = "SELECT - I.[name] AS [index_name], - IC.[index_column_id] AS [index_order], - AC.[name] AS [column_name], - I.[is_unique], I.[is_primary_key], - I.[is_unique_constraint] - FROM sys.[tables] AS T - INNER JOIN sys.[schemas] S ON S.[schema_id] = T.[schema_id] - INNER JOIN sys.[indexes] I ON T.[object_id] = I.[object_id] - INNER JOIN sys.[index_columns] IC ON I.[object_id] = IC.[object_id] AND I.[index_id] = IC.[index_id] - INNER JOIN sys.[all_columns] AC ON T.[object_id] = AC.[object_id] AND IC.[column_id] = AC.[column_id] - WHERE T.[is_ms_shipped] = 0 AND I.[type_desc] <> 'HEAP' AND T.[name] = ? AND S.[name] = ? - ORDER BY I.[index_id], IC.[index_column_id]"; - - $schema = empty($config['schema']) ? static::DEFAULT_SCHEMA_NAME : $config['schema']; - - return [$sql, [$tableName, $schema]]; - } - - /** - * {@inheritDoc} - */ - public function convertIndexDescription(TableSchema $schema, $row) - { - $type = TableSchema::INDEX_INDEX; - $name = $row['index_name']; - if ($row['is_primary_key']) { - $name = $type = TableSchema::CONSTRAINT_PRIMARY; - } - if ($row['is_unique_constraint'] && $type === TableSchema::INDEX_INDEX) { - $type = TableSchema::CONSTRAINT_UNIQUE; - } - - if ($type === TableSchema::INDEX_INDEX) { - $existing = $schema->getIndex($name); - } else { - $existing = $schema->getConstraint($name); - } - - $columns = [$row['column_name']]; - if (!empty($existing)) { - $columns = array_merge($existing['columns'], $columns); - } - - if ($type === TableSchema::CONSTRAINT_PRIMARY || $type === TableSchema::CONSTRAINT_UNIQUE) { - $schema->addConstraint($name, [ - 'type' => $type, - 'columns' => $columns - ]); - - return; - } - $schema->addIndex($name, [ - 'type' => $type, - 'columns' => $columns - ]); - } - - /** - * {@inheritDoc} - */ - public function describeForeignKeySql($tableName, $config) - { - $sql = 'SELECT FK.[name] AS [foreign_key_name], FK.[delete_referential_action_desc] AS [delete_type], - FK.[update_referential_action_desc] AS [update_type], C.name AS [column], RT.name AS [reference_table], - RC.name AS [reference_column] - FROM sys.foreign_keys FK - INNER JOIN sys.foreign_key_columns FKC ON FKC.constraint_object_id = FK.object_id - INNER JOIN sys.tables T ON T.object_id = FKC.parent_object_id - INNER JOIN sys.tables RT ON RT.object_id = FKC.referenced_object_id - INNER JOIN sys.schemas S ON S.schema_id = T.schema_id AND S.schema_id = RT.schema_id - INNER JOIN sys.columns C ON C.column_id = FKC.parent_column_id AND C.object_id = FKC.parent_object_id - INNER JOIN sys.columns RC ON RC.column_id = FKC.referenced_column_id AND RC.object_id = FKC.referenced_object_id - WHERE FK.is_ms_shipped = 0 AND T.name = ? AND S.name = ?'; - - $schema = empty($config['schema']) ? static::DEFAULT_SCHEMA_NAME : $config['schema']; - - return [$sql, [$tableName, $schema]]; - } - - /** - * {@inheritDoc} - */ - public function convertForeignKeyDescription(TableSchema $schema, $row) - { - $data = [ - 'type' => TableSchema::CONSTRAINT_FOREIGN, - 'columns' => [$row['column']], - 'references' => [$row['reference_table'], $row['reference_column']], - 'update' => $this->_convertOnClause($row['update_type']), - 'delete' => $this->_convertOnClause($row['delete_type']), - ]; - $name = $row['foreign_key_name']; - $schema->addConstraint($name, $data); - } - - /** - * {@inheritDoc} - */ - protected function _foreignOnClause($on) - { - $parent = parent::_foreignOnClause($on); - - return $parent === 'RESTRICT' ? parent::_foreignOnClause(TableSchema::ACTION_SET_NULL) : $parent; - } - - /** - * {@inheritDoc} - */ - protected function _convertOnClause($clause) - { - switch ($clause) { - case 'NO_ACTION': - return TableSchema::ACTION_NO_ACTION; - case 'CASCADE': - return TableSchema::ACTION_CASCADE; - case 'SET_NULL': - return TableSchema::ACTION_SET_NULL; - case 'SET_DEFAULT': - return TableSchema::ACTION_SET_DEFAULT; - } - - return TableSchema::ACTION_SET_NULL; - } - - /** - * {@inheritDoc} - */ - public function columnSql(TableSchema $schema, $name) - { - $data = $schema->getColumn($name); - $out = $this->_driver->quoteIdentifier($name); - $typeMap = [ - TableSchema::TYPE_TINYINTEGER => ' TINYINT', - TableSchema::TYPE_SMALLINTEGER => ' SMALLINT', - TableSchema::TYPE_INTEGER => ' INTEGER', - TableSchema::TYPE_BIGINTEGER => ' BIGINT', - TableSchema::TYPE_BINARY_UUID => ' UNIQUEIDENTIFIER', - TableSchema::TYPE_BOOLEAN => ' BIT', - TableSchema::TYPE_FLOAT => ' FLOAT', - TableSchema::TYPE_DECIMAL => ' DECIMAL', - TableSchema::TYPE_DATE => ' DATE', - TableSchema::TYPE_TIME => ' TIME', - TableSchema::TYPE_DATETIME => ' DATETIME', - TableSchema::TYPE_TIMESTAMP => ' DATETIME', - TableSchema::TYPE_UUID => ' UNIQUEIDENTIFIER', - TableSchema::TYPE_JSON => ' NVARCHAR(MAX)', - ]; - - if (isset($typeMap[$data['type']])) { - $out .= $typeMap[$data['type']]; - } - - if ($data['type'] === TableSchema::TYPE_INTEGER || $data['type'] === TableSchema::TYPE_BIGINTEGER) { - if ([$name] === $schema->primaryKey() || $data['autoIncrement'] === true) { - unset($data['null'], $data['default']); - $out .= ' IDENTITY(1, 1)'; - } - } - - if ($data['type'] === TableSchema::TYPE_TEXT && $data['length'] !== TableSchema::LENGTH_TINY) { - $out .= ' NVARCHAR(MAX)'; - } - - if ($data['type'] === TableSchema::TYPE_BINARY) { - $out .= ' VARBINARY'; - - if ($data['length'] !== TableSchema::LENGTH_TINY) { - $out .= '(MAX)'; - } else { - $out .= sprintf('(%s)', TableSchema::LENGTH_TINY); - } - } - - if ($data['type'] === TableSchema::TYPE_STRING || - ($data['type'] === TableSchema::TYPE_TEXT && $data['length'] === TableSchema::LENGTH_TINY) - ) { - $type = ' NVARCHAR'; - - if (!empty($data['fixed'])) { - $type = ' NCHAR'; - } - - if (!isset($data['length'])) { - $data['length'] = 255; - } - - $out .= sprintf('%s(%d)', $type, $data['length']); - } - - $hasCollate = [TableSchema::TYPE_TEXT, TableSchema::TYPE_STRING]; - if (in_array($data['type'], $hasCollate, true) && isset($data['collate']) && $data['collate'] !== '') { - $out .= ' COLLATE ' . $data['collate']; - } - - if ($data['type'] === TableSchema::TYPE_FLOAT && isset($data['precision'])) { - $out .= '(' . (int)$data['precision'] . ')'; - } - - if ($data['type'] === TableSchema::TYPE_DECIMAL && - (isset($data['length']) || isset($data['precision'])) - ) { - $out .= '(' . (int)$data['length'] . ',' . (int)$data['precision'] . ')'; - } - - if (isset($data['null']) && $data['null'] === false) { - $out .= ' NOT NULL'; - } - - if (isset($data['default']) && - in_array($data['type'], [TableSchema::TYPE_TIMESTAMP, TableSchema::TYPE_DATETIME]) && - strtolower($data['default']) === 'current_timestamp' - ) { - $out .= ' DEFAULT CURRENT_TIMESTAMP'; - } elseif (isset($data['default'])) { - $default = is_bool($data['default']) ? (int)$data['default'] : $this->_driver->schemaValue($data['default']); - $out .= ' DEFAULT ' . $default; - } elseif (isset($data['null']) && $data['null'] !== false) { - $out .= ' DEFAULT NULL'; - } - - return $out; - } - - /** - * {@inheritDoc} - */ - public function addConstraintSql(TableSchema $schema) - { - $sqlPattern = 'ALTER TABLE %s ADD %s;'; - $sql = []; - - foreach ($schema->constraints() as $name) { - $constraint = $schema->getConstraint($name); - if ($constraint['type'] === TableSchema::CONSTRAINT_FOREIGN) { - $tableName = $this->_driver->quoteIdentifier($schema->name()); - $sql[] = sprintf($sqlPattern, $tableName, $this->constraintSql($schema, $name)); - } - } - - return $sql; - } - - /** - * {@inheritDoc} - */ - public function dropConstraintSql(TableSchema $schema) - { - $sqlPattern = 'ALTER TABLE %s DROP CONSTRAINT %s;'; - $sql = []; - - foreach ($schema->constraints() as $name) { - $constraint = $schema->getConstraint($name); - if ($constraint['type'] === TableSchema::CONSTRAINT_FOREIGN) { - $tableName = $this->_driver->quoteIdentifier($schema->name()); - $constraintName = $this->_driver->quoteIdentifier($name); - $sql[] = sprintf($sqlPattern, $tableName, $constraintName); - } - } - - return $sql; - } - - /** - * {@inheritDoc} - */ - public function indexSql(TableSchema $schema, $name) - { - $data = $schema->getIndex($name); - $columns = array_map( - [$this->_driver, 'quoteIdentifier'], - $data['columns'] - ); - - return sprintf( - 'CREATE INDEX %s ON %s (%s)', - $this->_driver->quoteIdentifier($name), - $this->_driver->quoteIdentifier($schema->name()), - implode(', ', $columns) - ); - } - - /** - * {@inheritDoc} - */ - public function constraintSql(TableSchema $schema, $name) - { - $data = $schema->getConstraint($name); - $out = 'CONSTRAINT ' . $this->_driver->quoteIdentifier($name); - if ($data['type'] === TableSchema::CONSTRAINT_PRIMARY) { - $out = 'PRIMARY KEY'; - } - if ($data['type'] === TableSchema::CONSTRAINT_UNIQUE) { - $out .= ' UNIQUE'; - } - - return $this->_keySql($out, $data); - } - - /** - * Helper method for generating key SQL snippets. - * - * @param string $prefix The key prefix - * @param array $data Key data. - * @return string - */ - protected function _keySql($prefix, $data) - { - $columns = array_map( - [$this->_driver, 'quoteIdentifier'], - $data['columns'] - ); - if ($data['type'] === TableSchema::CONSTRAINT_FOREIGN) { - return $prefix . sprintf( - ' FOREIGN KEY (%s) REFERENCES %s (%s) ON UPDATE %s ON DELETE %s', - implode(', ', $columns), - $this->_driver->quoteIdentifier($data['references'][0]), - $this->_convertConstraintColumns($data['references'][1]), - $this->_foreignOnClause($data['update']), - $this->_foreignOnClause($data['delete']) - ); - } - - return $prefix . ' (' . implode(', ', $columns) . ')'; - } - - /** - * {@inheritDoc} - */ - public function createTableSql(TableSchema $schema, $columns, $constraints, $indexes) - { - $content = array_merge($columns, $constraints); - $content = implode(",\n", array_filter($content)); - $tableName = $this->_driver->quoteIdentifier($schema->name()); - $out = []; - $out[] = sprintf("CREATE TABLE %s (\n%s\n)", $tableName, $content); - foreach ($indexes as $index) { - $out[] = $index; - } - - return $out; - } - - /** - * {@inheritDoc} - */ - public function truncateTableSql(TableSchema $schema) - { - $name = $this->_driver->quoteIdentifier($schema->name()); - $queries = [ - sprintf('DELETE FROM %s', $name) - ]; - - // Restart identity sequences - $pk = $schema->primaryKey(); - if (count($pk) === 1) { - $column = $schema->getColumn($pk[0]); - if (in_array($column['type'], ['integer', 'biginteger'])) { - $queries[] = sprintf( - "DBCC CHECKIDENT('%s', RESEED, 0)", - $schema->name() - ); - } - } - - return $queries; - } -} diff --git a/vendor/cakephp/cakephp/src/Database/Schema/Table.php b/vendor/cakephp/cakephp/src/Database/Schema/Table.php deleted file mode 100644 index 86d3f0f..0000000 --- a/vendor/cakephp/cakephp/src/Database/Schema/Table.php +++ /dev/null @@ -1,4 +0,0 @@ -_startQuote . $identifier . $this->_endQuote; - } - - if (preg_match('/^[\w-]+\.[^ \*]*$/', $identifier)) { -// string.string - $items = explode('.', $identifier); - - return $this->_startQuote . implode($this->_endQuote . '.' . $this->_startQuote, $items) . $this->_endQuote; - } - - if (preg_match('/^[\w-]+\.\*$/', $identifier)) { -// string.* - return $this->_startQuote . str_replace('.*', $this->_endQuote . '.*', $identifier); - } - - if (preg_match('/^([\w-]+)\((.*)\)$/', $identifier, $matches)) { -// Functions - return $matches[1] . '(' . $this->quoteIdentifier($matches[2]) . ')'; - } - - // Alias.field AS thing - if (preg_match('/^([\w-]+(\.[\w-]+|\(.*\))*)\s+AS\s*([\w-]+)$/i', $identifier, $matches)) { - return $this->quoteIdentifier($matches[1]) . ' AS ' . $this->quoteIdentifier($matches[3]); - } - - if (preg_match('/^[\w-_\s]*[\w-_]+/', $identifier)) { - return $this->_startQuote . $identifier . $this->_endQuote; - } - - return $identifier; - } - - /** - * Returns a callable function that will be used to transform a passed Query object. - * This function, in turn, will return an instance of a Query object that has been - * transformed to accommodate any specificities of the SQL dialect in use. - * - * @param string $type the type of query to be transformed - * (select, insert, update, delete) - * @return callable - */ - public function queryTranslator($type) - { - return function ($query) use ($type) { - if ($this->isAutoQuotingEnabled()) { - $query = (new IdentifierQuoter($this))->quote($query); - } - - /** @var \Cake\ORM\Query $query */ - $query = $this->{'_' . $type . 'QueryTranslator'}($query); - $translators = $this->_expressionTranslators(); - if (!$translators) { - return $query; - } - - $query->traverseExpressions(function ($expression) use ($translators, $query) { - foreach ($translators as $class => $method) { - if ($expression instanceof $class) { - $this->{$method}($expression, $query); - } - } - }); - - return $query; - }; - } - - /** - * Returns an associative array of methods that will transform Expression - * objects to conform with the specific SQL dialect. Keys are class names - * and values a method in this class. - * - * @return array - */ - protected function _expressionTranslators() - { - return []; - } - - /** - * Apply translation steps to select queries. - * - * @param \Cake\Database\Query $query The query to translate - * @return \Cake\Database\Query The modified query - */ - protected function _selectQueryTranslator($query) - { - return $this->_transformDistinct($query); - } - - /** - * Returns the passed query after rewriting the DISTINCT clause, so that drivers - * that do not support the "ON" part can provide the actual way it should be done - * - * @param \Cake\Database\Query $query The query to be transformed - * @return \Cake\Database\Query - */ - protected function _transformDistinct($query) - { - if (is_array($query->clause('distinct'))) { - $query->group($query->clause('distinct'), true); - $query->distinct(false); - } - - return $query; - } - - /** - * Apply translation steps to delete queries. - * - * Chops out aliases on delete query conditions as most database dialects do not - * support aliases in delete queries. This also removes aliases - * in table names as they frequently don't work either. - * - * We are intentionally not supporting deletes with joins as they have even poorer support. - * - * @param \Cake\Database\Query $query The query to translate - * @return \Cake\Database\Query The modified query - */ - protected function _deleteQueryTranslator($query) - { - $hadAlias = false; - $tables = []; - foreach ($query->clause('from') as $alias => $table) { - if (is_string($alias)) { - $hadAlias = true; - } - $tables[] = $table; - } - if ($hadAlias) { - $query->from($tables, true); - } - - if (!$hadAlias) { - return $query; - } - - return $this->_removeAliasesFromConditions($query); - } - - /** - * Apply translation steps to update queries. - * - * Chops out aliases on update query conditions as not all database dialects do support - * aliases in update queries. - * - * Just like for delete queries, joins are currently not supported for update queries. - * - * @param \Cake\Database\Query $query The query to translate - * @return \Cake\Database\Query The modified query - */ - protected function _updateQueryTranslator($query) - { - return $this->_removeAliasesFromConditions($query); - } - - /** - * Removes aliases from the `WHERE` clause of a query. - * - * @param \Cake\Database\Query $query The query to process. - * @return \Cake\Database\Query The modified query. - * @throws \RuntimeException In case the processed query contains any joins, as removing - * aliases from the conditions can break references to the joined tables. - */ - protected function _removeAliasesFromConditions($query) - { - if ($query->clause('join')) { - throw new \RuntimeException( - 'Aliases are being removed from conditions for UPDATE/DELETE queries, ' . - 'this can break references to joined tables.' - ); - } - - $conditions = $query->clause('where'); - if ($conditions) { - $conditions->traverse(function ($condition) { - if (!($condition instanceof Comparison)) { - return $condition; - } - - $field = $condition->getField(); - if ($field instanceof ExpressionInterface || strpos($field, '.') === false) { - return $condition; - } - - list(, $field) = explode('.', $field); - $condition->setField($field); - - return $condition; - }); - } - - return $query; - } - - /** - * Apply translation steps to insert queries. - * - * @param \Cake\Database\Query $query The query to translate - * @return \Cake\Database\Query The modified query - */ - protected function _insertQueryTranslator($query) - { - return $query; - } - - /** - * Returns a SQL snippet for creating a new transaction savepoint - * - * @param string $name save point name - * @return string - */ - public function savePointSQL($name) - { - return 'SAVEPOINT LEVEL' . $name; - } - - /** - * Returns a SQL snippet for releasing a previously created save point - * - * @param string $name save point name - * @return string - */ - public function releaseSavePointSQL($name) - { - return 'RELEASE SAVEPOINT LEVEL' . $name; - } - - /** - * Returns a SQL snippet for rollbacking a previously created save point - * - * @param string $name save point name - * @return string - */ - public function rollbackSavePointSQL($name) - { - return 'ROLLBACK TO SAVEPOINT LEVEL' . $name; - } -} diff --git a/vendor/cakephp/cakephp/src/Database/SqliteCompiler.php b/vendor/cakephp/cakephp/src/Database/SqliteCompiler.php deleted file mode 100644 index 5a9e547..0000000 --- a/vendor/cakephp/cakephp/src/Database/SqliteCompiler.php +++ /dev/null @@ -1,32 +0,0 @@ - 'DELETE', - 'where' => ' WHERE %s', - 'group' => ' GROUP BY %s ', - 'having' => ' HAVING %s ', - 'order' => ' %s', - 'offset' => ' OFFSET %s ROWS', - 'epilog' => ' %s' - ]; - - /** - * {@inheritDoc} - */ - protected $_selectParts = [ - 'select', 'from', 'join', 'where', 'group', 'having', 'order', 'offset', - 'limit', 'union', 'epilog' - ]; - - /** - * Generates the INSERT part of a SQL query - * - * To better handle concurrency and low transaction isolation levels, - * we also include an OUTPUT clause so we can ensure we get the inserted - * row's data back. - * - * @param array $parts The parts to build - * @param \Cake\Database\Query $query The query that is being compiled - * @param \Cake\Database\ValueBinder $generator the placeholder generator to be used in expressions - * @return string - */ - protected function _buildInsertPart($parts, $query, $generator) - { - $table = $parts[0]; - $columns = $this->_stringifyExpressions($parts[1], $generator); - $modifiers = $this->_buildModifierPart($query->clause('modifier'), $query, $generator); - - return sprintf( - 'INSERT%s INTO %s (%s) OUTPUT INSERTED.*', - $modifiers, - $table, - implode(', ', $columns) - ); - } - - /** - * Generates the LIMIT part of a SQL query - * - * @param int $limit the limit clause - * @param \Cake\Database\Query $query The query that is being compiled - * @return string - */ - protected function _buildLimitPart($limit, $query) - { - if ($limit === null || $query->clause('offset') === null) { - return ''; - } - - return sprintf(' FETCH FIRST %d ROWS ONLY', $limit); - } -} diff --git a/vendor/cakephp/cakephp/src/Database/Statement/BufferResultsTrait.php b/vendor/cakephp/cakephp/src/Database/Statement/BufferResultsTrait.php deleted file mode 100644 index 0ad4c79..0000000 --- a/vendor/cakephp/cakephp/src/Database/Statement/BufferResultsTrait.php +++ /dev/null @@ -1,44 +0,0 @@ -_bufferResults = (bool)$buffer; - - return $this; - } -} diff --git a/vendor/cakephp/cakephp/src/Database/Statement/BufferedStatement.php b/vendor/cakephp/cakephp/src/Database/Statement/BufferedStatement.php deleted file mode 100644 index c435c03..0000000 --- a/vendor/cakephp/cakephp/src/Database/Statement/BufferedStatement.php +++ /dev/null @@ -1,173 +0,0 @@ -_reset(); - } - - /** - * Execute the statement and return the results. - * - * @param array|null $params list of values to be bound to query - * @return bool true on success, false otherwise - */ - public function execute($params = null) - { - $this->_reset(); - - return parent::execute($params); - } - - /** - * {@inheritDoc} - * - * @param string $type The type to fetch. - * @return array|false - */ - public function fetch($type = parent::FETCH_TYPE_NUM) - { - if ($this->_allFetched) { - $row = ($this->_counter < $this->_count) ? $this->_records[$this->_counter++] : false; - $row = ($row && $type === static::FETCH_TYPE_NUM) ? array_values($row) : $row; - - return $row; - } - - $record = parent::fetch($type); - - if ($record === false) { - $this->_allFetched = true; - $this->_counter = $this->_count + 1; - $this->_statement->closeCursor(); - - return false; - } - - $this->_count++; - - return $this->_records[] = $record; - } - - /** - * {@inheritdoc} - */ - public function fetchAssoc() - { - return $this->fetch(static::FETCH_TYPE_ASSOC); - } - - /** - * {@inheritDoc} - * - * @param string $type The type to fetch. - * @return array - */ - public function fetchAll($type = parent::FETCH_TYPE_NUM) - { - if ($this->_allFetched) { - return $this->_records; - } - - $this->_records = parent::fetchAll($type); - $this->_count = count($this->_records); - $this->_allFetched = true; - $this->_statement->closeCursor(); - - return $this->_records; - } - - /** - * {@inheritDoc} - */ - public function rowCount() - { - if (!$this->_allFetched) { - $counter = $this->_counter; - while ($this->fetch(static::FETCH_TYPE_ASSOC)) { - } - $this->_counter = $counter; - } - - return $this->_count; - } - - /** - * Rewind the _counter property - * - * @return void - */ - public function rewind() - { - $this->_counter = 0; - } - - /** - * Reset all properties - * - * @return void - */ - protected function _reset() - { - $this->_count = $this->_counter = 0; - $this->_records = []; - $this->_allFetched = false; - } -} diff --git a/vendor/cakephp/cakephp/src/Database/Statement/CallbackStatement.php b/vendor/cakephp/cakephp/src/Database/Statement/CallbackStatement.php deleted file mode 100644 index b7035ff..0000000 --- a/vendor/cakephp/cakephp/src/Database/Statement/CallbackStatement.php +++ /dev/null @@ -1,74 +0,0 @@ -_callback = $callback; - } - - /** - * Fetch a row from the statement. - * - * The result will be processed by the callback when it is not `false`. - * - * @param string $type Either 'num' or 'assoc' to indicate the result format you would like. - * @return array|false - */ - public function fetch($type = parent::FETCH_TYPE_NUM) - { - $callback = $this->_callback; - $row = $this->_statement->fetch($type); - - return $row === false ? $row : $callback($row); - } - - /** - * Fetch all rows from the statement. - * - * Each row in the result will be processed by the callback when it is not `false. - * - * @param string $type Either 'num' or 'assoc' to indicate the result format you would like. - * @return array - */ - public function fetchAll($type = parent::FETCH_TYPE_NUM) - { - return array_map($this->_callback, $this->_statement->fetchAll($type)); - } -} diff --git a/vendor/cakephp/cakephp/src/Database/Statement/MysqlStatement.php b/vendor/cakephp/cakephp/src/Database/Statement/MysqlStatement.php deleted file mode 100644 index 0f75194..0000000 --- a/vendor/cakephp/cakephp/src/Database/Statement/MysqlStatement.php +++ /dev/null @@ -1,46 +0,0 @@ -_driver->getConnection(); - - try { - $connection->setAttribute(PDO::MYSQL_ATTR_USE_BUFFERED_QUERY, $this->_bufferResults); - $result = $this->_statement->execute($params); - } finally { - $connection->setAttribute(PDO::MYSQL_ATTR_USE_BUFFERED_QUERY, true); - } - - return $result; - } -} diff --git a/vendor/cakephp/cakephp/src/Database/Statement/PDOStatement.php b/vendor/cakephp/cakephp/src/Database/Statement/PDOStatement.php deleted file mode 100644 index 055ea25..0000000 --- a/vendor/cakephp/cakephp/src/Database/Statement/PDOStatement.php +++ /dev/null @@ -1,134 +0,0 @@ -bindValue(1, 'a title'); - * $statement->bindValue(2, 5, PDO::INT); - * $statement->bindValue('active', true, 'boolean'); - * $statement->bindValue(5, new \DateTime(), 'date'); - * ``` - * - * @param string|int $column name or param position to be bound - * @param mixed $value The value to bind to variable in query - * @param string|int $type PDO type or name of configured Type class - * @return void - */ - public function bindValue($column, $value, $type = 'string') - { - if ($type === null) { - $type = 'string'; - } - if (!ctype_digit($type)) { - list($value, $type) = $this->cast($value, $type); - } - $this->_statement->bindValue($column, $value, $type); - } - - /** - * Returns the next row for the result set after executing this statement. - * Rows can be fetched to contain columns as names or positions. If no - * rows are left in result set, this method will return false - * - * ### Example: - * - * ``` - * $statement = $connection->prepare('SELECT id, title from articles'); - * $statement->execute(); - * print_r($statement->fetch('assoc')); // will show ['id' => 1, 'title' => 'a title'] - * ``` - * - * @param string $type 'num' for positional columns, assoc for named columns - * @return array|false Result array containing columns and values or false if no results - * are left - */ - public function fetch($type = parent::FETCH_TYPE_NUM) - { - if ($type === static::FETCH_TYPE_NUM) { - return $this->_statement->fetch(PDO::FETCH_NUM); - } - if ($type === static::FETCH_TYPE_ASSOC) { - return $this->_statement->fetch(PDO::FETCH_ASSOC); - } - if ($type === static::FETCH_TYPE_OBJ) { - return $this->_statement->fetch(PDO::FETCH_OBJ); - } - - return $this->_statement->fetch($type); - } - - /** - * Returns an array with all rows resulting from executing this statement - * - * ### Example: - * - * ``` - * $statement = $connection->prepare('SELECT id, title from articles'); - * $statement->execute(); - * print_r($statement->fetchAll('assoc')); // will show [0 => ['id' => 1, 'title' => 'a title']] - * ``` - * - * @param string $type num for fetching columns as positional keys or assoc for column names as keys - * @return array list of all results from database for this statement - */ - public function fetchAll($type = parent::FETCH_TYPE_NUM) - { - if ($type === static::FETCH_TYPE_NUM) { - return $this->_statement->fetchAll(PDO::FETCH_NUM); - } - if ($type === static::FETCH_TYPE_ASSOC) { - return $this->_statement->fetchAll(PDO::FETCH_ASSOC); - } - if ($type === static::FETCH_TYPE_OBJ) { - return $this->_statement->fetch(PDO::FETCH_OBJ); - } - - return $this->_statement->fetchAll($type); - } -} diff --git a/vendor/cakephp/cakephp/src/Database/Statement/SqliteStatement.php b/vendor/cakephp/cakephp/src/Database/Statement/SqliteStatement.php deleted file mode 100644 index 08e0b55..0000000 --- a/vendor/cakephp/cakephp/src/Database/Statement/SqliteStatement.php +++ /dev/null @@ -1,62 +0,0 @@ -_statement instanceof BufferedStatement) { - $this->_statement = $this->_statement->getInnerStatement(); - } - - if ($this->_bufferResults) { - $this->_statement = new BufferedStatement($this->_statement, $this->_driver); - } - - return $this->_statement->execute($params); - } - - /** - * Returns the number of rows returned of affected by last execution - * - * @return int - */ - public function rowCount() - { - if (preg_match('/^(?:DELETE|UPDATE|INSERT)/i', $this->_statement->queryString)) { - $changes = $this->_driver->prepare('SELECT CHANGES()'); - $changes->execute(); - $count = $changes->fetch()[0]; - $changes->closeCursor(); - - return (int)$count; - } - - return parent::rowCount(); - } -} diff --git a/vendor/cakephp/cakephp/src/Database/Statement/SqlserverStatement.php b/vendor/cakephp/cakephp/src/Database/Statement/SqlserverStatement.php deleted file mode 100644 index 5b1eb53..0000000 --- a/vendor/cakephp/cakephp/src/Database/Statement/SqlserverStatement.php +++ /dev/null @@ -1,47 +0,0 @@ -cast($value, $type); - } - if ($type == PDO::PARAM_LOB) { - $this->_statement->bindParam($column, $value, $type, 0, PDO::SQLSRV_ENCODING_BINARY); - } else { - $this->_statement->bindValue($column, $value, $type); - } - } -} diff --git a/vendor/cakephp/cakephp/src/Database/Statement/StatementDecorator.php b/vendor/cakephp/cakephp/src/Database/Statement/StatementDecorator.php deleted file mode 100644 index 7a26ed3..0000000 --- a/vendor/cakephp/cakephp/src/Database/Statement/StatementDecorator.php +++ /dev/null @@ -1,375 +0,0 @@ -_statement = $statement; - $this->_driver = $driver; - } - - /** - * Magic getter to return $queryString as read-only. - * - * @param string $property internal property to get - * @return mixed - */ - public function __get($property) - { - if ($property === 'queryString') { - return $this->_statement->queryString; - } - } - - /** - * Assign a value to a positional or named variable in prepared query. If using - * positional variables you need to start with index one, if using named params then - * just use the name in any order. - * - * It is not allowed to combine positional and named variables in the same statement. - * - * ### Examples: - * - * ``` - * $statement->bindValue(1, 'a title'); - * $statement->bindValue('active', true, 'boolean'); - * $statement->bindValue(5, new \DateTime(), 'date'); - * ``` - * - * @param string|int $column name or param position to be bound - * @param mixed $value The value to bind to variable in query - * @param string $type name of configured Type class - * @return void - */ - public function bindValue($column, $value, $type = 'string') - { - $this->_statement->bindValue($column, $value, $type); - } - - /** - * Closes a cursor in the database, freeing up any resources and memory - * allocated to it. In most cases you don't need to call this method, as it is - * automatically called after fetching all results from the result set. - * - * @return void - */ - public function closeCursor() - { - $this->_statement->closeCursor(); - } - - /** - * Returns the number of columns this statement's results will contain. - * - * ### Example: - * - * ``` - * $statement = $connection->prepare('SELECT id, title from articles'); - * $statement->execute(); - * echo $statement->columnCount(); // outputs 2 - * ``` - * - * @return int - */ - public function columnCount() - { - return $this->_statement->columnCount(); - } - - /** - * Returns the error code for the last error that occurred when executing this statement. - * - * @return int|string - */ - public function errorCode() - { - return $this->_statement->errorCode(); - } - - /** - * Returns the error information for the last error that occurred when executing - * this statement. - * - * @return array - */ - public function errorInfo() - { - return $this->_statement->errorInfo(); - } - - /** - * Executes the statement by sending the SQL query to the database. It can optionally - * take an array or arguments to be bound to the query variables. Please note - * that binding parameters from this method will not perform any custom type conversion - * as it would normally happen when calling `bindValue`. - * - * @param array|null $params list of values to be bound to query - * @return bool true on success, false otherwise - */ - public function execute($params = null) - { - $this->_hasExecuted = true; - - return $this->_statement->execute($params); - } - - /** - * Returns the next row for the result set after executing this statement. - * Rows can be fetched to contain columns as names or positions. If no - * rows are left in result set, this method will return false. - * - * ### Example: - * - * ``` - * $statement = $connection->prepare('SELECT id, title from articles'); - * $statement->execute(); - * print_r($statement->fetch('assoc')); // will show ['id' => 1, 'title' => 'a title'] - * ``` - * - * @param string $type 'num' for positional columns, assoc for named columns - * @return array|false Result array containing columns and values or false if no results - * are left - */ - public function fetch($type = self::FETCH_TYPE_NUM) - { - return $this->_statement->fetch($type); - } - - /** - * Returns the next row in a result set as an associative array. Calling this function is the same as calling - * $statement->fetch(StatementDecorator::FETCH_TYPE_ASSOC). If no results are found false is returned. - * - * @return array|false Result array containing columns and values an an associative array or false if no results - */ - public function fetchAssoc() - { - return $this->fetch(static::FETCH_TYPE_ASSOC); - } - - /** - * Returns the value of the result at position. - * - * @param int $position The numeric position of the column to retrieve in the result - * @return mixed|false Returns the specific value of the column designated at $position - */ - public function fetchColumn($position) - { - $result = $this->fetch(static::FETCH_TYPE_NUM); - if (isset($result[$position])) { - return $result[$position]; - }; - - return false; - } - - /** - * Returns an array with all rows resulting from executing this statement. - * - * ### Example: - * - * ``` - * $statement = $connection->prepare('SELECT id, title from articles'); - * $statement->execute(); - * print_r($statement->fetchAll('assoc')); // will show [0 => ['id' => 1, 'title' => 'a title']] - * ``` - * - * @param string $type num for fetching columns as positional keys or assoc for column names as keys - * @return array List of all results from database for this statement - */ - public function fetchAll($type = self::FETCH_TYPE_NUM) - { - return $this->_statement->fetchAll($type); - } - - /** - * Returns the number of rows affected by this SQL statement. - * - * ### Example: - * - * ``` - * $statement = $connection->prepare('SELECT id, title from articles'); - * $statement->execute(); - * print_r($statement->rowCount()); // will show 1 - * ``` - * - * @return int - */ - public function rowCount() - { - return $this->_statement->rowCount(); - } - - /** - * Statements are iterable as arrays, this method will return - * the iterator object for traversing all items in the result. - * - * ### Example: - * - * ``` - * $statement = $connection->prepare('SELECT id, title from articles'); - * foreach ($statement as $row) { - * //do stuff - * } - * ``` - * - * @return \Cake\Database\StatementInterface|\PDOStatement - */ - public function getIterator() - { - if (!$this->_hasExecuted) { - $this->execute(); - } - - return $this->_statement; - } - - /** - * Statements can be passed as argument for count() to return the number - * for affected rows from last execution. - * - * @return int - */ - public function count() - { - return $this->rowCount(); - } - - /** - * Binds a set of values to statement object with corresponding type. - * - * @param array $params list of values to be bound - * @param array $types list of types to be used, keys should match those in $params - * @return void - */ - public function bind($params, $types) - { - if (empty($params)) { - return; - } - - $anonymousParams = is_int(key($params)) ? true : false; - $offset = 1; - foreach ($params as $index => $value) { - $type = null; - if (isset($types[$index])) { - $type = $types[$index]; - } - if ($anonymousParams) { - $index += $offset; - } - $this->bindValue($index, $value, $type); - } - } - - /** - * Returns the latest primary inserted using this statement. - * - * @param string|null $table table name or sequence to get last insert value from - * @param string|null $column the name of the column representing the primary key - * @return string|int - */ - public function lastInsertId($table = null, $column = null) - { - $row = null; - if ($column && $this->columnCount()) { - $row = $this->fetch(static::FETCH_TYPE_ASSOC); - } - if (isset($row[$column])) { - return $row[$column]; - } - - return $this->_driver->lastInsertId($table, $column); - } - - /** - * Returns the statement object that was decorated by this class. - * - * @return \Cake\Database\StatementInterface|\PDOStatement - */ - public function getInnerStatement() - { - return $this->_statement; - } -} diff --git a/vendor/cakephp/cakephp/src/Database/StatementInterface.php b/vendor/cakephp/cakephp/src/Database/StatementInterface.php deleted file mode 100644 index f88ef22..0000000 --- a/vendor/cakephp/cakephp/src/Database/StatementInterface.php +++ /dev/null @@ -1,171 +0,0 @@ -bindValue(1, 'a title'); - * $statement->bindValue('active', true, 'boolean'); - * $statement->bindValue(5, new \DateTime(), 'date'); - * ``` - * - * @param string|int $column name or param position to be bound - * @param mixed $value The value to bind to variable in query - * @param string $type name of configured Type class - * @return void - */ - public function bindValue($column, $value, $type = 'string'); - - /** - * Closes a cursor in the database, freeing up any resources and memory - * allocated to it. In most cases you don't need to call this method, as it is - * automatically called after fetching all results from the result set. - * - * @return void - */ - public function closeCursor(); - - /** - * Returns the number of columns this statement's results will contain - * - * ### Example: - * - * ``` - * $statement = $connection->prepare('SELECT id, title from articles'); - * $statement->execute(); - * echo $statement->columnCount(); // outputs 2 - * ``` - * - * @return int - */ - public function columnCount(); - - /** - * Returns the error code for the last error that occurred when executing this statement - * - * @return int|string - */ - public function errorCode(); - - /** - * Returns the error information for the last error that occurred when executing - * this statement - * - * @return array - */ - public function errorInfo(); - - /** - * Executes the statement by sending the SQL query to the database. It can optionally - * take an array or arguments to be bound to the query variables. Please note - * that binding parameters from this method will not perform any custom type conversion - * as it would normally happen when calling `bindValue` - * - * @param array|null $params list of values to be bound to query - * @return bool true on success, false otherwise - */ - public function execute($params = null); - - /** - * Returns the next row for the result set after executing this statement. - * Rows can be fetched to contain columns as names or positions. If no - * rows are left in result set, this method will return false - * - * ### Example: - * - * ``` - * $statement = $connection->prepare('SELECT id, title from articles'); - * $statement->execute(); - * print_r($statement->fetch('assoc')); // will show ['id' => 1, 'title' => 'a title'] - * ``` - * - * @param string $type 'num' for positional columns, assoc for named columns - * @return array|false Result array containing columns and values or false if no results - * are left - */ - public function fetch($type = 'num'); - - /** - * Returns an array with all rows resulting from executing this statement - * - * ### Example: - * - * ``` - * $statement = $connection->prepare('SELECT id, title from articles'); - * $statement->execute(); - * print_r($statement->fetchAll('assoc')); // will show [0 => ['id' => 1, 'title' => 'a title']] - * ``` - * - * @param string $type num for fetching columns as positional keys or assoc for column names as keys - * @return array list of all results from database for this statement - */ - public function fetchAll($type = 'num'); - - /** - * Returns the number of rows affected by this SQL statement - * - * ### Example: - * - * ``` - * $statement = $connection->prepare('SELECT id, title from articles'); - * $statement->execute(); - * print_r($statement->rowCount()); // will show 1 - * ``` - * - * @return int - */ - public function rowCount(); - - /** - * Statements can be passed as argument for count() - * to return the number for affected rows from last execution - * - * @return int - */ - public function count(); - - /** - * Binds a set of values to statement object with corresponding type - * - * @param array $params list of values to be bound - * @param array $types list of types to be used, keys should match those in $params - * @return void - */ - public function bind($params, $types); - - /** - * Returns the latest primary inserted using this statement - * - * @param string|null $table table name or sequence to get last insert value from - * @param string|null $column the name of the column representing the primary key - * @return string - */ - public function lastInsertId($table = null, $column = null); -} diff --git a/vendor/cakephp/cakephp/src/Database/Type.php b/vendor/cakephp/cakephp/src/Database/Type.php deleted file mode 100644 index 6730584..0000000 --- a/vendor/cakephp/cakephp/src/Database/Type.php +++ /dev/null @@ -1,378 +0,0 @@ - 'Cake\Database\Type\IntegerType', - 'smallinteger' => 'Cake\Database\Type\IntegerType', - 'integer' => 'Cake\Database\Type\IntegerType', - 'biginteger' => 'Cake\Database\Type\IntegerType', - 'binary' => 'Cake\Database\Type\BinaryType', - 'binaryuuid' => 'Cake\Database\Type\BinaryUuidType', - 'boolean' => 'Cake\Database\Type\BoolType', - 'date' => 'Cake\Database\Type\DateType', - 'datetime' => 'Cake\Database\Type\DateTimeType', - 'decimal' => 'Cake\Database\Type\DecimalType', - 'float' => 'Cake\Database\Type\FloatType', - 'json' => 'Cake\Database\Type\JsonType', - 'string' => 'Cake\Database\Type\StringType', - 'text' => 'Cake\Database\Type\StringType', - 'time' => 'Cake\Database\Type\TimeType', - 'timestamp' => 'Cake\Database\Type\DateTimeType', - 'uuid' => 'Cake\Database\Type\UuidType', - ]; - - /** - * List of basic type mappings, used to avoid having to instantiate a class - * for doing conversion on these. - * - * @var array - * @deprecated 3.1 All types will now use a specific class - */ - protected static $_basicTypes = [ - 'string' => ['callback' => [Type::class, 'strval']], - 'text' => ['callback' => [Type::class, 'strval']], - 'boolean' => [ - 'callback' => [Type::class, 'boolval'], - 'pdo' => PDO::PARAM_BOOL - ], - ]; - - /** - * Contains a map of type object instances to be reused if needed. - * - * @var \Cake\Database\Type[] - */ - protected static $_builtTypes = []; - - /** - * Identifier name for this type - * - * @var string|null - */ - protected $_name; - - /** - * Constructor - * - * @param string|null $name The name identifying this type - */ - public function __construct($name = null) - { - $this->_name = $name; - } - - /** - * Returns a Type object capable of converting a type identified by name. - * - * @param string $name type identifier - * @throws \InvalidArgumentException If type identifier is unknown - * @return \Cake\Database\Type - */ - public static function build($name) - { - if (isset(static::$_builtTypes[$name])) { - return static::$_builtTypes[$name]; - } - if (!isset(static::$_types[$name])) { - throw new InvalidArgumentException(sprintf('Unknown type "%s"', $name)); - } - if (is_string(static::$_types[$name])) { - return static::$_builtTypes[$name] = new static::$_types[$name]($name); - } - - return static::$_builtTypes[$name] = static::$_types[$name]; - } - - /** - * Returns an arrays with all the mapped type objects, indexed by name. - * - * @return array - */ - public static function buildAll() - { - $result = []; - foreach (static::$_types as $name => $type) { - $result[$name] = isset(static::$_builtTypes[$name]) ? static::$_builtTypes[$name] : static::build($name); - } - - return $result; - } - - /** - * Returns a Type object capable of converting a type identified by $name - * - * @param string $name The type identifier you want to set. - * @param \Cake\Database\Type $instance The type instance you want to set. - * @return void - */ - public static function set($name, Type $instance) - { - static::$_builtTypes[$name] = $instance; - } - - /** - * Registers a new type identifier and maps it to a fully namespaced classname, - * If called with no arguments it will return current types map array - * If $className is omitted it will return mapped class for $type - * - * Deprecated 3.6.2: - * - The usage of $type as string[]|\Cake\Database\Type[] is deprecated. - * Use Type::setMap() with string[] instead. - * - Passing $className as \Cake\Database\Type instance is deprecated, use - * class name string only. - * - Using this method as getter is deprecated. Use Type::getMap() instead. - * - * @param string|string[]|\Cake\Database\Type[]|null $type If string name of type to map, if array list of arrays to be mapped - * @param string|\Cake\Database\Type|null $className The classname or object instance of it to register. - * @return array|string|null If $type is null then array with current map, if $className is null string - * configured class name for give $type, null otherwise - */ - public static function map($type = null, $className = null) - { - if ($type === null) { - deprecationWarning( - 'Using `Type::map()` as getter is deprecated. ' . - 'Use `Type::getMap()` instead.' - ); - - return static::$_types; - } - if (is_array($type)) { - deprecationWarning( - 'Using `Type::map()` to set complete types map is deprecated. ' . - 'Use `Type::setMap()` instead.' - ); - - static::$_types = $type; - - return null; - } - if ($className === null) { - deprecationWarning( - 'Using `Type::map()` as getter is deprecated. ' . - 'Use `Type::getMap()` instead.' - ); - - return isset(static::$_types[$type]) ? static::$_types[$type] : null; - } - - if (!is_string($className)) { - deprecationWarning( - 'Passing $className as object to Type::map() is deprecated. ' . - 'Use Type::set() instead.' - ); - } - - static::$_types[$type] = $className; - unset(static::$_builtTypes[$type]); - } - - /** - * Set type to classname mapping. - * - * @param string[] $map List of types to be mapped. - * @return void - * @since 3.6.2 - */ - public static function setMap(array $map) - { - static::$_types = $map; - static::$_builtTypes = []; - } - - /** - * Get mapped class name or instance for type(s). - * - * @param string|null $type Type name to get mapped class for or null to get map array. - * @return array|string|\Cake\Database\TypeInterface|null Configured class name or instance for give $type or map array. - * @since 3.6.2 - */ - public static function getMap($type = null) - { - if ($type === null) { - return static::$_types; - } - - return isset(static::$_types[$type]) ? static::$_types[$type] : null; - } - - /** - * Clears out all created instances and mapped types classes, useful for testing - * - * @return void - */ - public static function clear() - { - static::$_types = []; - static::$_builtTypes = []; - } - - /** - * {@inheritDoc} - */ - public function getName() - { - return $this->_name; - } - - /** - * {@inheritDoc} - */ - public function getBaseType() - { - return $this->_name; - } - - /** - * {@inheritDoc} - */ - public function toDatabase($value, Driver $driver) - { - return $this->_basicTypeCast($value); - } - - /** - * Casts given value from a database type to PHP equivalent - * - * @param mixed $value Value to be converted to PHP equivalent - * @param \Cake\Database\Driver $driver Object from which database preferences and configuration will be extracted - * @return mixed - */ - public function toPHP($value, Driver $driver) - { - return $this->_basicTypeCast($value); - } - - /** - * Checks whether this type is a basic one and can be converted using a callback - * If it is, returns converted value - * - * @param mixed $value Value to be converted to PHP equivalent - * @return mixed - * @deprecated 3.1 All types should now be a specific class - */ - protected function _basicTypeCast($value) - { - deprecationWarning('Type::_basicTypeCast() is deprecated.'); - if ($value === null) { - return null; - } - if (!empty(static::$_basicTypes[$this->_name])) { - $typeInfo = static::$_basicTypes[$this->_name]; - if (isset($typeInfo['callback'])) { - return $typeInfo['callback']($value); - } - } - - return $value; - } - - /** - * {@inheritDoc} - */ - public function toStatement($value, Driver $driver) - { - if ($value === null) { - return PDO::PARAM_NULL; - } - - return PDO::PARAM_STR; - } - - /** - * Type converter for boolean values. - * - * Will convert string true/false into booleans. - * - * @param mixed $value The value to convert to a boolean. - * @return bool - * @deprecated 3.1.8 This method is now unused. - */ - public static function boolval($value) - { - deprecationWarning('Type::boolval() is deprecated.'); - if (is_string($value) && !is_numeric($value)) { - return strtolower($value) === 'true'; - } - - return !empty($value); - } - - /** - * Type converter for string values. - * - * Will convert values into strings - * - * @param mixed $value The value to convert to a string. - * @return string - * @deprecated 3.1.8 This method is now unused. - */ - public static function strval($value) - { - deprecationWarning('Type::strval() is deprecated.'); - if (is_array($value)) { - $value = ''; - } - - return (string)$value; - } - - /** - * {@inheritDoc} - */ - public function newId() - { - return null; - } - - /** - * {@inheritDoc} - */ - public function marshal($value) - { - return $this->_basicTypeCast($value); - } - - /** - * Returns an array that can be used to describe the internal state of this - * object. - * - * @return array - */ - public function __debugInfo() - { - return [ - 'name' => $this->_name, - ]; - } -} diff --git a/vendor/cakephp/cakephp/src/Database/Type/BinaryType.php b/vendor/cakephp/cakephp/src/Database/Type/BinaryType.php deleted file mode 100644 index dc75d30..0000000 --- a/vendor/cakephp/cakephp/src/Database/Type/BinaryType.php +++ /dev/null @@ -1,120 +0,0 @@ -_name = $name; - } - - /** - * Convert binary data into the database format. - * - * Binary data is not altered before being inserted into the database. - * As PDO will handle reading file handles. - * - * @param string|resource $value The value to convert. - * @param \Cake\Database\Driver $driver The driver instance to convert with. - * @return string|resource - */ - public function toDatabase($value, Driver $driver) - { - return $value; - } - - /** - * Convert binary into resource handles - * - * @param null|string|resource $value The value to convert. - * @param \Cake\Database\Driver $driver The driver instance to convert with. - * @return resource|null - * @throws \Cake\Core\Exception\Exception - */ - public function toPHP($value, Driver $driver) - { - if ($value === null) { - return null; - } - if (is_string($value) && $driver instanceof Sqlserver) { - $value = pack('H*', $value); - } - if (is_string($value)) { - return fopen('data:text/plain;base64,' . base64_encode($value), 'rb'); - } - if (is_resource($value)) { - return $value; - } - throw new Exception(sprintf('Unable to convert %s into binary.', gettype($value))); - } - - /** - * Get the correct PDO binding type for Binary data. - * - * @param mixed $value The value being bound. - * @param \Cake\Database\Driver $driver The driver. - * @return int - */ - public function toStatement($value, Driver $driver) - { - return PDO::PARAM_LOB; - } - - /** - * Marshalls flat data into PHP objects. - * - * Most useful for converting request data into PHP objects - * that make sense for the rest of the ORM/Database layers. - * - * @param mixed $value The value to convert. - * - * @return mixed Converted value. - */ - public function marshal($value) - { - return $value; - } -} diff --git a/vendor/cakephp/cakephp/src/Database/Type/BoolType.php b/vendor/cakephp/cakephp/src/Database/Type/BoolType.php deleted file mode 100644 index 8c95c5f..0000000 --- a/vendor/cakephp/cakephp/src/Database/Type/BoolType.php +++ /dev/null @@ -1,167 +0,0 @@ -_name = $name; - } - - /** - * Convert bool data into the database format. - * - * @param mixed $value The value to convert. - * @param \Cake\Database\Driver $driver The driver instance to convert with. - * @return bool|null - */ - public function toDatabase($value, Driver $driver) - { - if ($value === true || $value === false || $value === null) { - return $value; - } - - if (in_array($value, [1, 0, '1', '0'], true)) { - return (bool)$value; - } - - throw new InvalidArgumentException(sprintf( - 'Cannot convert value of type `%s` to bool', - getTypeName($value) - )); - } - - /** - * Convert bool values to PHP booleans - * - * @param mixed $value The value to convert. - * @param \Cake\Database\Driver $driver The driver instance to convert with. - * @return bool|null - */ - public function toPHP($value, Driver $driver) - { - if ($value === null || $value === true || $value === false) { - return $value; - } - - if (!is_numeric($value)) { - return strtolower($value) === 'true'; - } - - return !empty($value); - } - - /** - * {@inheritDoc} - * - * @return array - */ - public function manyToPHP(array $values, array $fields, Driver $driver) - { - foreach ($fields as $field) { - if (!isset($values[$field]) || $values[$field] === true || $values[$field] === false) { - continue; - } - - if ($values[$field] === '1') { - $values[$field] = true; - continue; - } - - if ($values[$field] === '0') { - $values[$field] = false; - continue; - } - - $value = $values[$field]; - if (!is_numeric($value)) { - $values[$field] = strtolower($value) === 'true'; - continue; - } - - $values[$field] = !empty($value); - } - - return $values; - } - - /** - * Get the correct PDO binding type for bool data. - * - * @param mixed $value The value being bound. - * @param \Cake\Database\Driver $driver The driver. - * @return int - */ - public function toStatement($value, Driver $driver) - { - if ($value === null) { - return PDO::PARAM_NULL; - } - - return PDO::PARAM_BOOL; - } - - /** - * Marshalls request data into PHP booleans. - * - * @param mixed $value The value to convert. - * @return bool|null Converted value. - */ - public function marshal($value) - { - if ($value === null) { - return null; - } - if ($value === 'true') { - return true; - } - if ($value === 'false') { - return false; - } - - return !empty($value); - } -} diff --git a/vendor/cakephp/cakephp/src/Database/Type/DateTimeType.php b/vendor/cakephp/cakephp/src/Database/Type/DateTimeType.php deleted file mode 100644 index 949fefa..0000000 --- a/vendor/cakephp/cakephp/src/Database/Type/DateTimeType.php +++ /dev/null @@ -1,427 +0,0 @@ -_name = $name; - - $this->_setClassName(static::$dateTimeClass, 'DateTime'); - } - - /** - * Convert DateTime instance into strings. - * - * @param string|int|\DateTime|\DateTimeImmutable $value The value to convert. - * @param \Cake\Database\Driver $driver The driver instance to convert with. - * @return string|null - */ - public function toDatabase($value, Driver $driver) - { - if ($value === null || is_string($value)) { - return $value; - } - if (is_int($value)) { - $class = $this->_className; - $value = new $class('@' . $value); - } - - $format = (array)$this->_format; - - if ($this->dbTimezone !== null - && $this->dbTimezone->getName() !== $value->getTimezone()->getName() - ) { - if (!$value instanceof DateTimeImmutable) { - $value = clone $value; - } - $value = $value->setTimezone($this->dbTimezone); - } - - return $value->format(array_shift($format)); - } - - /** - * Set database timezone. - * - * Specified timezone will be set for DateTime objects before generating - * datetime string for saving to database. If `null` no timezone conversion - * will be done. - * - * @param string|\DateTimeZone|null $timezone Database timezone. - * @return $this - */ - public function setTimezone($timezone) - { - if (is_string($timezone)) { - $timezone = new DateTimeZone($timezone); - } - $this->dbTimezone = $timezone; - - return $this; - } - - /** - * Convert strings into DateTime instances. - * - * @param string $value The value to convert. - * @param \Cake\Database\Driver $driver The driver instance to convert with. - * @return \Cake\I18n\Time|\DateTime|null - */ - public function toPHP($value, Driver $driver) - { - if ($value === null || strpos($value, '0000-00-00') === 0) { - return null; - } - - $instance = clone $this->_datetimeInstance; - $instance = $instance->modify($value); - - if ($this->setToDateStart) { - $instance = $instance->setTime(0, 0, 0); - } - - return $instance; - } - - /** - * {@inheritDoc} - * - * @return array - */ - public function manyToPHP(array $values, array $fields, Driver $driver) - { - foreach ($fields as $field) { - if (!isset($values[$field])) { - continue; - } - - if (strpos($values[$field], '0000-00-00') === 0) { - $values[$field] = null; - continue; - } - - $instance = clone $this->_datetimeInstance; - $instance = $instance->modify($values[$field]); - - if ($this->setToDateStart) { - $instance = $instance->setTime(0, 0, 0); - } - - $values[$field] = $instance; - } - - return $values; - } - - /** - * Convert request data into a datetime object. - * - * @param mixed $value Request data - * @return \DateTimeInterface|null - */ - public function marshal($value) - { - if ($value instanceof DateTimeInterface) { - return $value; - } - - $class = $this->_className; - try { - $compare = $date = false; - if ($value === '' || $value === null || $value === false || $value === true) { - return null; - } - $isString = is_string($value); - if (ctype_digit($value)) { - $date = new $class('@' . $value); - } elseif ($isString && $this->_useLocaleParser) { - return $this->_parseValue($value); - } elseif ($isString) { - $date = new $class($value); - $compare = true; - } - if ($compare && $date && !$this->_compare($date, $value)) { - return $value; - } - if ($date) { - return $date; - } - } catch (Exception $e) { - return $value; - } - - if (is_array($value) && implode('', $value) === '') { - return null; - } - $value += ['hour' => 0, 'minute' => 0, 'second' => 0]; - - $format = ''; - if (isset($value['year'], $value['month'], $value['day']) && - (is_numeric($value['year']) && is_numeric($value['month']) && is_numeric($value['day'])) - ) { - $format .= sprintf('%d-%02d-%02d', $value['year'], $value['month'], $value['day']); - } - - if (isset($value['meridian']) && (int)$value['hour'] === 12) { - $value['hour'] = 0; - } - if (isset($value['meridian'])) { - $value['hour'] = strtolower($value['meridian']) === 'am' ? $value['hour'] : $value['hour'] + 12; - } - $format .= sprintf( - '%s%02d:%02d:%02d', - empty($format) ? '' : ' ', - $value['hour'], - $value['minute'], - $value['second'] - ); - $tz = isset($value['timezone']) ? $value['timezone'] : null; - - return new $class($format, $tz); - } - - /** - * @param \Cake\I18n\Time|\DateTime $date DateTime object - * @param mixed $value Request data - * @return bool - */ - protected function _compare($date, $value) - { - foreach ((array)$this->_format as $format) { - if ($date->format($format) === $value) { - return true; - } - } - - return false; - } - - /** - * Sets whether or not to parse dates passed to the marshal() function - * by using a locale aware parser. - * - * @param bool $enable Whether or not to enable - * @return $this - */ - public function useLocaleParser($enable = true) - { - if ($enable === false) { - $this->_useLocaleParser = $enable; - - return $this; - } - if (method_exists($this->_className, 'parseDateTime')) { - $this->_useLocaleParser = $enable; - - return $this; - } - throw new RuntimeException( - sprintf('Cannot use locale parsing with the %s class', $this->_className) - ); - } - - /** - * Sets the format string to use for parsing dates in this class. The formats - * that are accepted are documented in the `Cake\I18n\Time::parseDateTime()` - * function. - * - * @param string|array $format The format in which the string are passed. - * @see \Cake\I18n\Time::parseDateTime() - * @return $this - */ - public function setLocaleFormat($format) - { - $this->_localeFormat = $format; - - return $this; - } - - /** - * Change the preferred class name to the FrozenTime implementation. - * - * @return $this - */ - public function useImmutable() - { - $this->_setClassName('Cake\I18n\FrozenTime', 'DateTimeImmutable'); - - return $this; - } - - /** - * Set the classname to use when building objects. - * - * @param string $class The classname to use. - * @param string $fallback The classname to use when the preferred class does not exist. - * @return void - */ - protected function _setClassName($class, $fallback) - { - if (!class_exists($class)) { - $class = $fallback; - } - $this->_className = $class; - $this->_datetimeInstance = new $this->_className; - } - - /** - * Get the classname used for building objects. - * - * @return string - */ - public function getDateTimeClassName() - { - return $this->_className; - } - - /** - * Change the preferred class name to the mutable Time implementation. - * - * @return $this - */ - public function useMutable() - { - $this->_setClassName('Cake\I18n\Time', 'DateTime'); - - return $this; - } - - /** - * Converts a string into a DateTime object after parsing it using the locale - * aware parser with the specified format. - * - * @param string $value The value to parse and convert to an object. - * @return \Cake\I18n\Time|null - */ - protected function _parseValue($value) - { - /* @var \Cake\I18n\Time $class */ - $class = $this->_className; - - return $class::parseDateTime($value, $this->_localeFormat); - } - - /** - * Casts given value to Statement equivalent - * - * @param mixed $value value to be converted to PDO statement - * @param \Cake\Database\Driver $driver object from which database preferences and configuration will be extracted - * - * @return mixed - */ - public function toStatement($value, Driver $driver) - { - return PDO::PARAM_STR; - } -} diff --git a/vendor/cakephp/cakephp/src/Database/Type/DateType.php b/vendor/cakephp/cakephp/src/Database/Type/DateType.php deleted file mode 100644 index a6ca9c3..0000000 --- a/vendor/cakephp/cakephp/src/Database/Type/DateType.php +++ /dev/null @@ -1,99 +0,0 @@ -_setClassName('Cake\I18n\FrozenDate', 'DateTimeImmutable'); - - return $this; - } - - /** - * Change the preferred class name to the mutable Date implementation. - * - * @return $this - */ - public function useMutable() - { - $this->_setClassName('Cake\I18n\Date', 'DateTime'); - - return $this; - } - - /** - * Convert request data into a datetime object. - * - * @param mixed $value Request data - * @return \DateTimeInterface - */ - public function marshal($value) - { - $date = parent::marshal($value); - if ($date instanceof DateTime) { - $date->setTime(0, 0, 0); - } - - return $date; - } - - /** - * {@inheritDoc} - */ - protected function _parseValue($value) - { - /* @var \Cake\I18n\Time $class */ - $class = $this->_className; - - return $class::parseDate($value, $this->_localeFormat); - } -} diff --git a/vendor/cakephp/cakephp/src/Database/Type/DecimalType.php b/vendor/cakephp/cakephp/src/Database/Type/DecimalType.php deleted file mode 100644 index c4e48d1..0000000 --- a/vendor/cakephp/cakephp/src/Database/Type/DecimalType.php +++ /dev/null @@ -1,207 +0,0 @@ -_name = $name; - } - - /** - * The class to use for representing number objects - * - * @var string - */ - public static $numberClass = 'Cake\I18n\Number'; - - /** - * Whether numbers should be parsed using a locale aware parser - * when marshalling string inputs. - * - * @var bool - */ - protected $_useLocaleParser = false; - - /** - * Convert integer data into the database format. - * - * @param string|int|float $value The value to convert. - * @param \Cake\Database\Driver $driver The driver instance to convert with. - * @return string|null - * @throws \InvalidArgumentException - */ - public function toDatabase($value, Driver $driver) - { - if ($value === null || $value === '') { - return null; - } - if (!is_scalar($value)) { - throw new InvalidArgumentException(sprintf( - 'Cannot convert value of type `%s` to a decimal', - getTypeName($value) - )); - } - if (is_string($value) && is_numeric($value)) { - return $value; - } - - return sprintf('%F', $value); - } - - /** - * Convert float values to PHP floats - * - * @param null|string|resource $value The value to convert. - * @param \Cake\Database\Driver $driver The driver instance to convert with. - * @return float|null - * @throws \Cake\Core\Exception\Exception - */ - public function toPHP($value, Driver $driver) - { - if ($value === null) { - return $value; - } - - return (float)$value; - } - - /** - * {@inheritDoc} - * - * @return array - */ - public function manyToPHP(array $values, array $fields, Driver $driver) - { - foreach ($fields as $field) { - if (!isset($values[$field])) { - continue; - } - - $values[$field] = (float)$values[$field]; - } - - return $values; - } - - /** - * Get the correct PDO binding type for integer data. - * - * @param mixed $value The value being bound. - * @param \Cake\Database\Driver $driver The driver. - * @return int - */ - public function toStatement($value, Driver $driver) - { - return PDO::PARAM_STR; - } - - /** - * Marshalls request data into PHP floats. - * - * @param mixed $value The value to convert. - * @return mixed Converted value. - */ - public function marshal($value) - { - if ($value === null || $value === '') { - return null; - } - if (is_string($value) && $this->_useLocaleParser) { - return $this->_parseValue($value); - } - if (is_numeric($value)) { - return (float)$value; - } - if (is_array($value)) { - return 1; - } - - return $value; - } - - /** - * Sets whether or not to parse numbers passed to the marshal() function - * by using a locale aware parser. - * - * @param bool $enable Whether or not to enable - * @return $this - */ - public function useLocaleParser($enable = true) - { - if ($enable === false) { - $this->_useLocaleParser = $enable; - - return $this; - } - if (static::$numberClass === 'Cake\I18n\Number' || - is_subclass_of(static::$numberClass, 'Cake\I18n\Number') - ) { - $this->_useLocaleParser = $enable; - - return $this; - } - throw new RuntimeException( - sprintf('Cannot use locale parsing with the %s class', static::$numberClass) - ); - } - - /** - * Converts a string into a float point after parsing it using the locale - * aware parser. - * - * @param string $value The value to parse and convert to an float. - * @return float - */ - protected function _parseValue($value) - { - /* @var \Cake\I18n\Number $class */ - $class = static::$numberClass; - - return $class::parseFloat($value); - } -} diff --git a/vendor/cakephp/cakephp/src/Database/Type/ExpressionTypeCasterTrait.php b/vendor/cakephp/cakephp/src/Database/Type/ExpressionTypeCasterTrait.php deleted file mode 100644 index 51c6247..0000000 --- a/vendor/cakephp/cakephp/src/Database/Type/ExpressionTypeCasterTrait.php +++ /dev/null @@ -1,79 +0,0 @@ -toExpression($value); - } - - /** - * Returns an array with the types that require values to - * be casted to expressions, out of the list of type names - * passed as parameter. - * - * @param array $types List of type names - * @return array - */ - protected function _requiresToExpressionCasting($types) - { - $result = []; - $types = array_filter($types); - foreach ($types as $k => $type) { - $object = Type::build($type); - if ($object instanceof ExpressionTypeInterface) { - $result[$k] = $object; - } - } - - return $result; - } -} diff --git a/vendor/cakephp/cakephp/src/Database/Type/ExpressionTypeInterface.php b/vendor/cakephp/cakephp/src/Database/Type/ExpressionTypeInterface.php deleted file mode 100644 index d2f931e..0000000 --- a/vendor/cakephp/cakephp/src/Database/Type/ExpressionTypeInterface.php +++ /dev/null @@ -1,33 +0,0 @@ -_name = $name; - } - - /** - * The class to use for representing number objects - * - * @var string - */ - public static $numberClass = 'Cake\I18n\Number'; - - /** - * Whether numbers should be parsed using a locale aware parser - * when marshalling string inputs. - * - * @var bool - */ - protected $_useLocaleParser = false; - - /** - * Convert integer data into the database format. - * - * @param string|resource $value The value to convert. - * @param \Cake\Database\Driver $driver The driver instance to convert with. - * @return float|null - */ - public function toDatabase($value, Driver $driver) - { - if ($value === null || $value === '') { - return null; - } - - return (float)$value; - } - - /** - * Convert float values to PHP integers - * - * @param null|string|resource $value The value to convert. - * @param \Cake\Database\Driver $driver The driver instance to convert with. - * @return float|null - * @throws \Cake\Core\Exception\Exception - */ - public function toPHP($value, Driver $driver) - { - if ($value === null) { - return null; - } - - return (float)$value; - } - - /** - * {@inheritDoc} - * - * @return array - */ - public function manyToPHP(array $values, array $fields, Driver $driver) - { - foreach ($fields as $field) { - if (!isset($values[$field])) { - continue; - } - - $values[$field] = (float)$values[$field]; - } - - return $values; - } - - /** - * Get the correct PDO binding type for integer data. - * - * @param mixed $value The value being bound. - * @param \Cake\Database\Driver $driver The driver. - * @return int - */ - public function toStatement($value, Driver $driver) - { - return PDO::PARAM_STR; - } - - /** - * Marshalls request data into PHP floats. - * - * @param mixed $value The value to convert. - * @return float|null Converted value. - */ - public function marshal($value) - { - if ($value === null || $value === '') { - return null; - } - if (is_numeric($value)) { - return (float)$value; - } - if (is_string($value) && $this->_useLocaleParser) { - return $this->_parseValue($value); - } - if (is_array($value)) { - return 1.0; - } - - return $value; - } - - /** - * Sets whether or not to parse numbers passed to the marshal() function - * by using a locale aware parser. - * - * @param bool $enable Whether or not to enable - * @return $this - */ - public function useLocaleParser($enable = true) - { - if ($enable === false) { - $this->_useLocaleParser = $enable; - - return $this; - } - if (static::$numberClass === 'Cake\I18n\Number' || - is_subclass_of(static::$numberClass, 'Cake\I18n\Number') - ) { - $this->_useLocaleParser = $enable; - - return $this; - } - throw new RuntimeException( - sprintf('Cannot use locale parsing with the %s class', static::$numberClass) - ); - } - - /** - * Converts a string into a float point after parsing it using the locale - * aware parser. - * - * @param string $value The value to parse and convert to an float. - * @return float - */ - protected function _parseValue($value) - { - $class = static::$numberClass; - - return $class::parseFloat($value); - } -} diff --git a/vendor/cakephp/cakephp/src/Database/Type/IntegerType.php b/vendor/cakephp/cakephp/src/Database/Type/IntegerType.php deleted file mode 100644 index b8903ea..0000000 --- a/vendor/cakephp/cakephp/src/Database/Type/IntegerType.php +++ /dev/null @@ -1,142 +0,0 @@ -_name = $name; - } - - /** - * Convert integer data into the database format. - * - * @param mixed $value The value to convert. - * @param \Cake\Database\Driver $driver The driver instance to convert with. - * @return int|null - */ - public function toDatabase($value, Driver $driver) - { - if ($value === null || $value === '') { - return null; - } - - if (!is_scalar($value)) { - throw new InvalidArgumentException(sprintf( - 'Cannot convert value of type `%s` to integer', - getTypeName($value) - )); - } - - return (int)$value; - } - - /** - * Convert integer values to PHP integers - * - * @param mixed $value The value to convert. - * @param \Cake\Database\Driver $driver The driver instance to convert with. - * @return int|null - */ - public function toPHP($value, Driver $driver) - { - if ($value === null) { - return $value; - } - - return (int)$value; - } - - /** - * {@inheritDoc} - * - * @return array - */ - public function manyToPHP(array $values, array $fields, Driver $driver) - { - foreach ($fields as $field) { - if (!isset($values[$field])) { - continue; - } - $values[$field] = (int)$values[$field]; - } - - return $values; - } - - /** - * Get the correct PDO binding type for integer data. - * - * @param mixed $value The value being bound. - * @param \Cake\Database\Driver $driver The driver. - * @return int - */ - public function toStatement($value, Driver $driver) - { - return PDO::PARAM_INT; - } - - /** - * Marshalls request data into PHP floats. - * - * @param mixed $value The value to convert. - * @return int|null Converted value. - */ - public function marshal($value) - { - if ($value === null || $value === '') { - return null; - } - if (is_numeric($value) || ctype_digit($value)) { - return (int)$value; - } - if (is_array($value)) { - return 1; - } - - return null; - } -} diff --git a/vendor/cakephp/cakephp/src/Database/Type/JsonType.php b/vendor/cakephp/cakephp/src/Database/Type/JsonType.php deleted file mode 100644 index 2c48dbb..0000000 --- a/vendor/cakephp/cakephp/src/Database/Type/JsonType.php +++ /dev/null @@ -1,122 +0,0 @@ -_name = $name; - } - - /** - * Convert a value data into a JSON string - * - * @param mixed $value The value to convert. - * @param \Cake\Database\Driver $driver The driver instance to convert with. - * @return string|null - */ - public function toDatabase($value, Driver $driver) - { - if (is_resource($value)) { - throw new InvalidArgumentException('Cannot convert a resource value to JSON'); - } - - return json_encode($value); - } - - /** - * Convert string values to PHP arrays. - * - * @param mixed $value The value to convert. - * @param \Cake\Database\Driver $driver The driver instance to convert with. - * @return string|null|array - */ - public function toPHP($value, Driver $driver) - { - return json_decode($value, true); - } - - /** - * {@inheritDoc} - * - * @return array - */ - public function manyToPHP(array $values, array $fields, Driver $driver) - { - foreach ($fields as $field) { - if (!isset($values[$field])) { - continue; - } - - $values[$field] = json_decode($values[$field], true); - } - - return $values; - } - - /** - * Get the correct PDO binding type for string data. - * - * @param mixed $value The value being bound. - * @param \Cake\Database\Driver $driver The driver. - * @return int - */ - public function toStatement($value, Driver $driver) - { - return PDO::PARAM_STR; - } - - /** - * Marshalls request data into a JSON compatible structure. - * - * @param mixed $value The value to convert. - * @return mixed Converted value. - */ - public function marshal($value) - { - return $value; - } -} diff --git a/vendor/cakephp/cakephp/src/Database/Type/OptionalConvertInterface.php b/vendor/cakephp/cakephp/src/Database/Type/OptionalConvertInterface.php deleted file mode 100644 index 8d6c03a..0000000 --- a/vendor/cakephp/cakephp/src/Database/Type/OptionalConvertInterface.php +++ /dev/null @@ -1,31 +0,0 @@ -__toString(); - } - - if (is_scalar($value)) { - return (string)$value; - } - - throw new InvalidArgumentException(sprintf( - 'Cannot convert value of type `%s` to string', - getTypeName($value) - )); - } - - /** - * Convert string values to PHP strings. - * - * @param mixed $value The value to convert. - * @param \Cake\Database\Driver $driver The driver instance to convert with. - * @return string|null - */ - public function toPHP($value, Driver $driver) - { - if ($value === null) { - return null; - } - - return (string)$value; - } - - /** - * Get the correct PDO binding type for string data. - * - * @param mixed $value The value being bound. - * @param \Cake\Database\Driver $driver The driver. - * @return int - */ - public function toStatement($value, Driver $driver) - { - return PDO::PARAM_STR; - } - - /** - * Marshalls request data into PHP strings. - * - * @param mixed $value The value to convert. - * @return string|null Converted value. - */ - public function marshal($value) - { - if ($value === null) { - return null; - } - if (is_array($value)) { - return ''; - } - - return (string)$value; - } - - /** - * {@inheritDoc} - * - * @return boolean False as database results are returned already as strings - */ - public function requiresToPhpCast() - { - return false; - } -} diff --git a/vendor/cakephp/cakephp/src/Database/Type/TimeType.php b/vendor/cakephp/cakephp/src/Database/Type/TimeType.php deleted file mode 100644 index 582a4e2..0000000 --- a/vendor/cakephp/cakephp/src/Database/Type/TimeType.php +++ /dev/null @@ -1,42 +0,0 @@ -_className; - - return $class::parseTime($value, $this->_localeFormat); - } -} diff --git a/vendor/cakephp/cakephp/src/Database/Type/UuidType.php b/vendor/cakephp/cakephp/src/Database/Type/UuidType.php deleted file mode 100644 index ecfdb85..0000000 --- a/vendor/cakephp/cakephp/src/Database/Type/UuidType.php +++ /dev/null @@ -1,66 +0,0 @@ -toDatabase($value, $this->_driver); - $type = $type->toStatement($value, $this->_driver); - } - - return [$value, $type]; - } - - /** - * Matches columns to corresponding types - * - * Both $columns and $types should either be numeric based or string key based at - * the same time. - * - * @param array $columns list or associative array of columns and parameters to be bound with types - * @param array $types list or associative array of types - * @return array - */ - public function matchTypes($columns, $types) - { - if (!is_int(key($types))) { - $positions = array_intersect_key(array_flip($columns), $types); - $types = array_intersect_key($types, $positions); - $types = array_combine($positions, $types); - } - - return $types; - } -} diff --git a/vendor/cakephp/cakephp/src/Database/TypeInterface.php b/vendor/cakephp/cakephp/src/Database/TypeInterface.php deleted file mode 100644 index 82e17f4..0000000 --- a/vendor/cakephp/cakephp/src/Database/TypeInterface.php +++ /dev/null @@ -1,90 +0,0 @@ -setDefaults($defaults); - } - - /** - * Configures a map of default fields and their associated types to be - * used as the default list of types for every function in this class - * with a $types param. Useful to avoid repetition when calling the same - * functions using the same fields and types. - * - * ### Example - * - * ``` - * $query->setDefaults(['created' => 'datetime', 'is_visible' => 'boolean']); - * ``` - * - * This method will replace all the existing type maps with the ones provided. - * - * @param array $defaults Associative array where keys are field names and values - * are the correspondent type. - * @return $this - */ - public function setDefaults(array $defaults) - { - $this->_defaults = $defaults; - - return $this; - } - - /** - * Returns the currently configured types. - * - * @return array - */ - public function getDefaults() - { - return $this->_defaults; - } - - /** - * Configures a map of default fields and their associated types to be - * used as the default list of types for every function in this class - * with a $types param. Useful to avoid repetition when calling the same - * functions using the same fields and types. - * - * If called with no arguments it will return the currently configured types. - * - * ### Example - * - * ``` - * $query->defaults(['created' => 'datetime', 'is_visible' => 'boolean']); - * ``` - * - * This method will replace all the existing type maps with the ones provided. - * - * @deprecated 3.4.0 Use setDefaults()/getDefaults() instead. - * @param array|null $defaults associative array where keys are field names and values - * are the correspondent type. - * @return $this|array - */ - public function defaults(array $defaults = null) - { - deprecationWarning( - 'TypeMap::defaults() is deprecated. ' . - 'Use TypeMap::setDefaults()/getDefaults() instead.' - ); - if ($defaults !== null) { - return $this->setDefaults($defaults); - } - - return $this->getDefaults(); - } - - /** - * Add additional default types into the type map. - * - * If a key already exists it will not be overwritten. - * - * @param array $types The additional types to add. - * @return void - */ - public function addDefaults(array $types) - { - $this->_defaults += $types; - } - - /** - * Sets a map of fields and their associated types for single-use. - * - * ### Example - * - * ``` - * $query->setTypes(['created' => 'time']); - * ``` - * - * This method will replace all the existing type maps with the ones provided. - * - * @param array $types Associative array where keys are field names and values - * are the correspondent type. - * @return $this - */ - public function setTypes(array $types) - { - $this->_types = $types; - - return $this; - } - - /** - * Gets a map of fields and their associated types for single-use. - * - * @return array - */ - public function getTypes() - { - return $this->_types; - } - - /** - * Sets a map of fields and their associated types for single-use. - * - * If called with no arguments it will return the currently configured types. - * - * ### Example - * - * ``` - * $query->types(['created' => 'time']); - * ``` - * - * This method will replace all the existing type maps with the ones provided. - * - * @deprecated 3.4.0 Use setTypes()/getTypes() instead. - * @param array|null $types associative array where keys are field names and values - * are the correspondent type. - * @return $this|array - */ - public function types(array $types = null) - { - deprecationWarning( - 'TypeMap::types() is deprecated. ' . - 'Use TypeMap::setTypes()/getTypes() instead.' - ); - if ($types !== null) { - return $this->setTypes($types); - } - - return $this->getTypes(); - } - - /** - * Returns the type of the given column. If there is no single use type is configured, - * the column type will be looked for inside the default mapping. If neither exist, - * null will be returned. - * - * @param string $column The type for a given column - * @return null|string - */ - public function type($column) - { - if (isset($this->_types[$column])) { - return $this->_types[$column]; - } - if (isset($this->_defaults[$column])) { - return $this->_defaults[$column]; - } - - return null; - } - - /** - * Returns an array of all types mapped types - * - * @return array - */ - public function toArray() - { - return $this->_types + $this->_defaults; - } -} diff --git a/vendor/cakephp/cakephp/src/Database/TypeMapTrait.php b/vendor/cakephp/cakephp/src/Database/TypeMapTrait.php deleted file mode 100644 index 573259d..0000000 --- a/vendor/cakephp/cakephp/src/Database/TypeMapTrait.php +++ /dev/null @@ -1,118 +0,0 @@ -_typeMap = is_array($typeMap) ? new TypeMap($typeMap) : $typeMap; - - return $this; - } - - /** - * Returns the existing type map. - * - * @return \Cake\Database\TypeMap - */ - public function getTypeMap() - { - if ($this->_typeMap === null) { - $this->_typeMap = new TypeMap(); - } - - return $this->_typeMap; - } - - /** - * Creates a new TypeMap if $typeMap is an array, otherwise returns the existing type map - * or exchanges it for the given one. - * - * @deprecated 3.4.0 Use setTypeMap()/getTypeMap() instead. - * @param array|\Cake\Database\TypeMap|null $typeMap Creates a TypeMap if array, otherwise sets the given TypeMap - * @return $this|\Cake\Database\TypeMap - */ - public function typeMap($typeMap = null) - { - deprecationWarning( - 'TypeMapTrait::typeMap() is deprecated. ' . - 'Use TypeMapTrait::setTypeMap()/getTypeMap() instead.' - ); - if ($typeMap !== null) { - return $this->setTypeMap($typeMap); - } - - return $this->getTypeMap(); - } - - /** - * Allows setting default types when chaining query. - * - * @param array $types The array of types to set. - * @return $this - */ - public function setDefaultTypes(array $types) - { - $this->getTypeMap()->setDefaults($types); - - return $this; - } - - /** - * Gets default types of current type map. - * - * @return array - */ - public function getDefaultTypes() - { - return $this->getTypeMap()->getDefaults(); - } - - /** - * Allows setting default types when chaining query - * - * @deprecated 3.4.0 Use setDefaultTypes()/getDefaultTypes() instead. - * @param array|null $types The array of types to set. - * @return $this|array - */ - public function defaultTypes(array $types = null) - { - deprecationWarning( - 'TypeMapTrait::defaultTypes() is deprecated. ' . - 'Use TypeMapTrait::setDefaultTypes()/getDefaultTypes() instead.' - ); - if ($types !== null) { - return $this->setDefaultTypes($types); - } - - return $this->getDefaultTypes(); - } -} diff --git a/vendor/cakephp/cakephp/src/Database/TypedResultInterface.php b/vendor/cakephp/cakephp/src/Database/TypedResultInterface.php deleted file mode 100644 index b77d463..0000000 --- a/vendor/cakephp/cakephp/src/Database/TypedResultInterface.php +++ /dev/null @@ -1,35 +0,0 @@ -_returnType; - } - - /** - * Sets the type of the value this object will generate. - * - * @param string $type The name of the type that is to be returned - * @return $this - */ - public function setReturnType($type) - { - $this->_returnType = $type; - - return $this; - } - - /** - * Sets the type of the value this object will generate. - * If called without arguments, returns the current known type - * - * @deprecated 3.5.0 Use getReturnType()/setReturnType() instead. - * @param string|null $type The name of the type that is to be returned - * @return string|$this - */ - public function returnType($type = null) - { - deprecationWarning( - 'TypedResultTrait::returnType() is deprecated. ' . - 'Use TypedResultTrait::setReturnType()/getReturnType() instead.' - ); - if ($type !== null) { - $this->_returnType = $type; - - return $this; - } - - return $this->_returnType; - } -} diff --git a/vendor/cakephp/cakephp/src/Database/ValueBinder.php b/vendor/cakephp/cakephp/src/Database/ValueBinder.php deleted file mode 100644 index a13838d..0000000 --- a/vendor/cakephp/cakephp/src/Database/ValueBinder.php +++ /dev/null @@ -1,150 +0,0 @@ -_bindings[$param] = compact('value', 'type') + [ - 'placeholder' => is_int($param) ? $param : substr($param, 1) - ]; - } - - /** - * Creates a unique placeholder name if the token provided does not start with ":" - * otherwise, it will return the same string and internally increment the number - * of placeholders generated by this object. - * - * @param string $token string from which the placeholder will be derived from, - * if it starts with a colon, then the same string is returned - * @return string to be used as a placeholder in a query expression - */ - public function placeholder($token) - { - $number = $this->_bindingsCount++; - if ($token[0] !== ':' && $token !== '?') { - $token = sprintf(':%s%s', $token, $number); - } - - return $token; - } - - /** - * Creates unique named placeholders for each of the passed values - * and binds them with the specified type. - * - * @param array|\Traversable $values The list of values to be bound - * @param string $type The type with which all values will be bound - * @return array with the placeholders to insert in the query - */ - public function generateManyNamed($values, $type = 'string') - { - $placeholders = []; - foreach ($values as $k => $value) { - $param = $this->placeholder('c'); - $this->_bindings[$param] = [ - 'value' => $value, - 'type' => $type, - 'placeholder' => substr($param, 1), - ]; - $placeholders[$k] = $param; - } - - return $placeholders; - } - - /** - * Returns all values bound to this expression object at this nesting level. - * Subexpression bound values will not be returned with this function. - * - * @return array - */ - public function bindings() - { - return $this->_bindings; - } - - /** - * Clears any bindings that were previously registered - * - * @return void - */ - public function reset() - { - $this->_bindings = []; - $this->_bindingsCount = 0; - } - - /** - * Resets the bindings count without clearing previously bound values - * - * @return void - */ - public function resetCount() - { - $this->_bindingsCount = 0; - } - - /** - * Binds all the stored values in this object to the passed statement. - * - * @param \Cake\Database\StatementInterface $statement The statement to add parameters to. - * @return void - */ - public function attachTo($statement) - { - $bindings = $this->bindings(); - if (empty($bindings)) { - return; - } - - foreach ($bindings as $b) { - $statement->bindValue($b['placeholder'], $b['value'], $b['type']); - } - } -} diff --git a/vendor/cakephp/cakephp/src/Database/composer.json b/vendor/cakephp/cakephp/src/Database/composer.json deleted file mode 100644 index 3de6513..0000000 --- a/vendor/cakephp/cakephp/src/Database/composer.json +++ /dev/null @@ -1,40 +0,0 @@ -{ - "name": "cakephp/database", - "description": "Flexible and powerful Database abstraction library with a familiar PDO-like API", - "type": "library", - "keywords": [ - "cakephp", - "database", - "abstraction", - "database abstraction", - "pdo" - ], - "homepage": "https://cakephp.org", - "license": "MIT", - "authors": [ - { - "name": "CakePHP Community", - "homepage": "https://github.com/cakephp/database/graphs/contributors" - } - ], - "support": { - "issues": "https://github.com/cakephp/cakephp/issues", - "forum": "https://stackoverflow.com/tags/cakephp", - "irc": "irc://irc.freenode.org/cakephp", - "source": "https://github.com/cakephp/database" - }, - "require": { - "php": ">=5.6.0", - "cakephp/cache": "^3.6.0", - "cakephp/core": "^3.6.0", - "cakephp/datasource": "^3.6.0" - }, - "suggest": { - "cakephp/log": "Require this if you want to use the built-in query logger" - }, - "autoload": { - "psr-4": { - "Cake\\Database\\": "." - } - } -} diff --git a/vendor/cakephp/cakephp/src/Datasource/ConnectionInterface.php b/vendor/cakephp/cakephp/src/Datasource/ConnectionInterface.php deleted file mode 100644 index fbc3b24..0000000 --- a/vendor/cakephp/cakephp/src/Datasource/ConnectionInterface.php +++ /dev/null @@ -1,92 +0,0 @@ - 'Cake\Database\Driver\Mysql', - 'postgres' => 'Cake\Database\Driver\Postgres', - 'sqlite' => 'Cake\Database\Driver\Sqlite', - 'sqlserver' => 'Cake\Database\Driver\Sqlserver', - ]; - - /** - * The ConnectionRegistry used by the manager. - * - * @var \Cake\Datasource\ConnectionRegistry - */ - protected static $_registry; - - /** - * Configure a new connection object. - * - * The connection will not be constructed until it is first used. - * - * @param string|array $key The name of the connection config, or an array of multiple configs. - * @param array|null $config An array of name => config data for adapter. - * @return void - * @throws \Cake\Core\Exception\Exception When trying to modify an existing config. - * @see \Cake\Core\StaticConfigTrait::config() - */ - public static function setConfig($key, $config = null) - { - if (is_array($config)) { - $config['name'] = $key; - } - - static::_setConfig($key, $config); - } - - /** - * Parses a DSN into a valid connection configuration - * - * This method allows setting a DSN using formatting similar to that used by PEAR::DB. - * The following is an example of its usage: - * - * ``` - * $dsn = 'mysql://user:pass@localhost/database'; - * $config = ConnectionManager::parseDsn($dsn); - * - * $dsn = 'Cake\Database\Driver\Mysql://localhost:3306/database?className=Cake\Database\Connection'; - * $config = ConnectionManager::parseDsn($dsn); - * - * $dsn = 'Cake\Database\Connection://localhost:3306/database?driver=Cake\Database\Driver\Mysql'; - * $config = ConnectionManager::parseDsn($dsn); - * ``` - * - * For all classes, the value of `scheme` is set as the value of both the `className` and `driver` - * unless they have been otherwise specified. - * - * Note that query-string arguments are also parsed and set as values in the returned configuration. - * - * @param string|null $config The DSN string to convert to a configuration array - * @return array The configuration array to be stored after parsing the DSN - */ - public static function parseDsn($config = null) - { - $config = static::_parseDsn($config); - - if (isset($config['path']) && empty($config['database'])) { - $config['database'] = substr($config['path'], 1); - } - - if (empty($config['driver'])) { - $config['driver'] = $config['className']; - $config['className'] = 'Cake\Database\Connection'; - } - - unset($config['path']); - - return $config; - } - - /** - * Set one or more connection aliases. - * - * Connection aliases allow you to rename active connections without overwriting - * the aliased connection. This is most useful in the test-suite for replacing - * connections with their test variant. - * - * Defined aliases will take precedence over normal connection names. For example, - * if you alias 'default' to 'test', fetching 'default' will always return the 'test' - * connection as long as the alias is defined. - * - * You can remove aliases with ConnectionManager::dropAlias(). - * - * ### Usage - * - * ``` - * // Make 'things' resolve to 'test_things' connection - * ConnectionManager::alias('test_things', 'things'); - * ``` - * - * @param string $alias The alias to add. Fetching $source will return $alias when loaded with get. - * @param string $source The connection to add an alias to. - * @return void - * @throws \Cake\Datasource\Exception\MissingDatasourceConfigException When aliasing a - * connection that does not exist. - */ - public static function alias($alias, $source) - { - if (empty(static::$_config[$source]) && empty(static::$_config[$alias])) { - throw new MissingDatasourceConfigException( - sprintf('Cannot create alias of "%s" as it does not exist.', $alias) - ); - } - static::$_aliasMap[$source] = $alias; - } - - /** - * Drop an alias. - * - * Removes an alias from ConnectionManager. Fetching the aliased - * connection may fail if there is no other connection with that name. - * - * @param string $name The connection name to remove aliases for. - * @return void - */ - public static function dropAlias($name) - { - unset(static::$_aliasMap[$name]); - } - - /** - * Get a connection. - * - * If the connection has not been constructed an instance will be added - * to the registry. This method will use any aliases that have been - * defined. If you want the original unaliased connections pass `false` - * as second parameter. - * - * @param string $name The connection name. - * @param bool $useAliases Set to false to not use aliased connections. - * @return \Cake\Datasource\ConnectionInterface A connection object. - * @throws \Cake\Datasource\Exception\MissingDatasourceConfigException When config - * data is missing. - */ - public static function get($name, $useAliases = true) - { - if ($useAliases && isset(static::$_aliasMap[$name])) { - $name = static::$_aliasMap[$name]; - } - if (empty(static::$_config[$name])) { - throw new MissingDatasourceConfigException(['name' => $name]); - } - if (empty(static::$_registry)) { - static::$_registry = new ConnectionRegistry(); - } - if (isset(static::$_registry->{$name})) { - return static::$_registry->{$name}; - } - - return static::$_registry->load($name, static::$_config[$name]); - } -} diff --git a/vendor/cakephp/cakephp/src/Datasource/ConnectionRegistry.php b/vendor/cakephp/cakephp/src/Datasource/ConnectionRegistry.php deleted file mode 100644 index ea9d434..0000000 --- a/vendor/cakephp/cakephp/src/Datasource/ConnectionRegistry.php +++ /dev/null @@ -1,102 +0,0 @@ - $class, - 'plugin' => $plugin, - ]); - } - - /** - * Create the connection object with the correct settings. - * - * Part of the template method for Cake\Core\ObjectRegistry::load() - * - * If a callable is passed as first argument, The returned value of this - * function will be the result of the callable. - * - * @param string|object|callable $class The classname or object to make. - * @param string $alias The alias of the object. - * @param array $settings An array of settings to use for the datasource. - * @return object A connection with the correct settings. - */ - protected function _create($class, $alias, $settings) - { - if (is_callable($class)) { - return $class($alias); - } - - if (is_object($class)) { - return $class; - } - - unset($settings['className']); - - return new $class($settings); - } - - /** - * Remove a single adapter from the registry. - * - * @param string $name The adapter name. - * @return void - */ - public function unload($name) - { - unset($this->_loaded[$name]); - } -} diff --git a/vendor/cakephp/cakephp/src/Datasource/EntityInterface.php b/vendor/cakephp/cakephp/src/Datasource/EntityInterface.php deleted file mode 100644 index d10832a..0000000 --- a/vendor/cakephp/cakephp/src/Datasource/EntityInterface.php +++ /dev/null @@ -1,207 +0,0 @@ -accessible('*', true)` means that any property not specified already - * will be accessible by default. - * - * @deprecated 3.4.0 Use setAccess() and isAccessible() instead. - * @param string|array $property Either a single or list of properties to change its accessibility. - * @param bool|null $set true marks the property as accessible, false will - * mark it as protected. - * @return \Cake\Datasource\EntityInterface|bool - */ - public function accessible($property, $set = null); -} diff --git a/vendor/cakephp/cakephp/src/Datasource/EntityTrait.php b/vendor/cakephp/cakephp/src/Datasource/EntityTrait.php deleted file mode 100644 index a13ac48..0000000 --- a/vendor/cakephp/cakephp/src/Datasource/EntityTrait.php +++ /dev/null @@ -1,1402 +0,0 @@ - true` - * means that any property not defined in the map will be accessible by default - * - * @var array - */ - protected $_accessible = ['*' => true]; - - /** - * The alias of the repository this entity came from - * - * @var string - */ - protected $_registryAlias; - - /** - * Magic getter to access properties that have been set in this entity - * - * @param string $property Name of the property to access - * @return mixed - */ - public function &__get($property) - { - return $this->get($property); - } - - /** - * Magic setter to add or edit a property in this entity - * - * @param string $property The name of the property to set - * @param mixed $value The value to set to the property - * @return void - */ - public function __set($property, $value) - { - $this->set($property, $value); - } - - /** - * Returns whether this entity contains a property named $property - * regardless of if it is empty. - * - * @param string $property The property to check. - * @return bool - * @see \Cake\ORM\Entity::has() - */ - public function __isset($property) - { - return $this->has($property); - } - - /** - * Removes a property from this entity - * - * @param string $property The property to unset - * @return void - */ - public function __unset($property) - { - $this->unsetProperty($property); - } - - /** - * Sets a single property inside this entity. - * - * ### Example: - * - * ``` - * $entity->set('name', 'Andrew'); - * ``` - * - * It is also possible to mass-assign multiple properties to this entity - * with one call by passing a hashed array as properties in the form of - * property => value pairs - * - * ### Example: - * - * ``` - * $entity->set(['name' => 'andrew', 'id' => 1]); - * echo $entity->name // prints andrew - * echo $entity->id // prints 1 - * ``` - * - * Some times it is handy to bypass setter functions in this entity when assigning - * properties. You can achieve this by disabling the `setter` option using the - * `$options` parameter: - * - * ``` - * $entity->set('name', 'Andrew', ['setter' => false]); - * $entity->set(['name' => 'Andrew', 'id' => 1], ['setter' => false]); - * ``` - * - * Mass assignment should be treated carefully when accepting user input, by default - * entities will guard all fields when properties are assigned in bulk. You can disable - * the guarding for a single set call with the `guard` option: - * - * ``` - * $entity->set(['name' => 'Andrew', 'id' => 1], ['guard' => true]); - * ``` - * - * You do not need to use the guard option when assigning properties individually: - * - * ``` - * // No need to use the guard option. - * $entity->set('name', 'Andrew'); - * ``` - * - * @param string|array $property the name of property to set or a list of - * properties with their respective values - * @param mixed $value The value to set to the property or an array if the - * first argument is also an array, in which case will be treated as $options - * @param array $options options to be used for setting the property. Allowed option - * keys are `setter` and `guard` - * @return $this - * @throws \InvalidArgumentException - */ - public function set($property, $value = null, array $options = []) - { - if (is_string($property) && $property !== '') { - $guard = false; - $property = [$property => $value]; - } else { - $guard = true; - $options = (array)$value; - } - - if (!is_array($property)) { - throw new InvalidArgumentException('Cannot set an empty property'); - } - $options += ['setter' => true, 'guard' => $guard]; - - foreach ($property as $p => $value) { - if ($options['guard'] === true && !$this->isAccessible($p)) { - continue; - } - - $this->setDirty($p, true); - - if (!array_key_exists($p, $this->_original) && - array_key_exists($p, $this->_properties) && - $this->_properties[$p] !== $value - ) { - $this->_original[$p] = $this->_properties[$p]; - } - - if (!$options['setter']) { - $this->_properties[$p] = $value; - continue; - } - - $setter = static::_accessor($p, 'set'); - if ($setter) { - $value = $this->{$setter}($value); - } - $this->_properties[$p] = $value; - } - - return $this; - } - - /** - * Returns the value of a property by name - * - * @param string $property the name of the property to retrieve - * @return mixed - * @throws \InvalidArgumentException if an empty property name is passed - */ - public function &get($property) - { - if (!strlen((string)$property)) { - throw new InvalidArgumentException('Cannot get an empty property'); - } - - $value = null; - $method = static::_accessor($property, 'get'); - - if (isset($this->_properties[$property])) { - $value =& $this->_properties[$property]; - } - - if ($method) { - $result = $this->{$method}($value); - - return $result; - } - - return $value; - } - - /** - * Returns the value of an original property by name - * - * @param string $property the name of the property for which original value is retrieved. - * @return mixed - * @throws \InvalidArgumentException if an empty property name is passed. - */ - public function getOriginal($property) - { - if (!strlen((string)$property)) { - throw new InvalidArgumentException('Cannot get an empty property'); - } - if (array_key_exists($property, $this->_original)) { - return $this->_original[$property]; - } - - return $this->get($property); - } - - /** - * Gets all original values of the entity. - * - * @return array - */ - public function getOriginalValues() - { - $originals = $this->_original; - $originalKeys = array_keys($originals); - foreach ($this->_properties as $key => $value) { - if (!in_array($key, $originalKeys)) { - $originals[$key] = $value; - } - } - - return $originals; - } - - /** - * Returns whether this entity contains a property named $property - * that contains a non-null value. - * - * ### Example: - * - * ``` - * $entity = new Entity(['id' => 1, 'name' => null]); - * $entity->has('id'); // true - * $entity->has('name'); // false - * $entity->has('last_name'); // false - * ``` - * - * You can check multiple properties by passing an array: - * - * ``` - * $entity->has(['name', 'last_name']); - * ``` - * - * All properties must not be null to get a truthy result. - * - * When checking multiple properties. All properties must not be null - * in order for true to be returned. - * - * @param string|array $property The property or properties to check. - * @return bool - */ - public function has($property) - { - foreach ((array)$property as $prop) { - if ($this->get($prop) === null) { - return false; - } - } - - return true; - } - - /** - * Checks that a property is empty - * - * This is not working like the PHP `empty()` function. The method will - * return true for: - * - * - `''` (empty string) - * - `null` - * - `[]` - * - * and false in all other cases. - * - * @param string $property The property to check. - * @return bool - */ - public function isEmpty($property) - { - $value = $this->get($property); - if ($value === null - || (is_array($value) && empty($value) - || (is_string($value) && empty($value))) - ) { - return true; - } - - return false; - } - - /** - * Checks tha a property has a value. - * - * This method will return true for - * - * - Non-empty strings - * - Non-empty arrays - * - Any object - * - Integer, even `0` - * - Float, even 0.0 - * - * and false in all other cases. - * - * @param string $property The property to check. - * @return bool - */ - public function hasValue($property) - { - return !$this->isEmpty($property); - } - - /** - * Removes a property or list of properties from this entity - * - * ### Examples: - * - * ``` - * $entity->unsetProperty('name'); - * $entity->unsetProperty(['name', 'last_name']); - * ``` - * - * @param string|array $property The property to unset. - * @return $this - */ - public function unsetProperty($property) - { - $property = (array)$property; - foreach ($property as $p) { - unset($this->_properties[$p], $this->_dirty[$p]); - } - - return $this; - } - - /** - * Get/Set the hidden properties on this entity. - * - * If the properties argument is null, the currently hidden properties - * will be returned. Otherwise the hidden properties will be set. - * - * @deprecated 3.4.0 Use EntityTrait::setHidden() and EntityTrait::getHidden() - * @param null|array $properties Either an array of properties to hide or null to get properties - * @return array|$this - */ - public function hiddenProperties($properties = null) - { - deprecationWarning( - get_called_class() . '::hiddenProperties() is deprecated. ' . - 'Use setHidden()/getHidden() instead.' - ); - if ($properties === null) { - return $this->_hidden; - } - $this->_hidden = $properties; - - return $this; - } - - /** - * Sets hidden properties. - * - * @param array $properties An array of properties to hide from array exports. - * @param bool $merge Merge the new properties with the existing. By default false. - * @return $this - */ - public function setHidden(array $properties, $merge = false) - { - if ($merge === false) { - $this->_hidden = $properties; - - return $this; - } - - $properties = array_merge($this->_hidden, $properties); - $this->_hidden = array_unique($properties); - - return $this; - } - - /** - * Gets the hidden properties. - * - * @return array - */ - public function getHidden() - { - return $this->_hidden; - } - - /** - * Get/Set the virtual properties on this entity. - * - * If the properties argument is null, the currently virtual properties - * will be returned. Otherwise the virtual properties will be set. - * - * @deprecated 3.4.0 Use EntityTrait::getVirtual() and EntityTrait::setVirtual() - * @param null|array $properties Either an array of properties to treat as virtual or null to get properties - * @return array|$this - */ - public function virtualProperties($properties = null) - { - deprecationWarning( - get_called_class() . '::virtualProperties() is deprecated. ' . - 'Use setVirtual()/getVirtual() instead.' - ); - if ($properties === null) { - return $this->getVirtual(); - } - - return $this->setVirtual($properties); - } - - /** - * Sets the virtual properties on this entity. - * - * @param array $properties An array of properties to treat as virtual. - * @param bool $merge Merge the new properties with the existing. By default false. - * @return $this - */ - public function setVirtual(array $properties, $merge = false) - { - if ($merge === false) { - $this->_virtual = $properties; - - return $this; - } - - $properties = array_merge($this->_virtual, $properties); - $this->_virtual = array_unique($properties); - - return $this; - } - - /** - * Gets the virtual properties on this entity. - * - * @return array - */ - public function getVirtual() - { - return $this->_virtual; - } - - /** - * Get the list of visible properties. - * - * The list of visible properties is all standard properties - * plus virtual properties minus hidden properties. - * - * @return array A list of properties that are 'visible' in all - * representations. - */ - public function visibleProperties() - { - $properties = array_keys($this->_properties); - $properties = array_merge($properties, $this->_virtual); - - return array_diff($properties, $this->_hidden); - } - - /** - * Returns an array with all the properties that have been set - * to this entity - * - * This method will recursively transform entities assigned to properties - * into arrays as well. - * - * @return array - */ - public function toArray() - { - $result = []; - foreach ($this->visibleProperties() as $property) { - $value = $this->get($property); - if (is_array($value)) { - $result[$property] = []; - foreach ($value as $k => $entity) { - if ($entity instanceof EntityInterface) { - $result[$property][$k] = $entity->toArray(); - } else { - $result[$property][$k] = $entity; - } - } - } elseif ($value instanceof EntityInterface) { - $result[$property] = $value->toArray(); - } else { - $result[$property] = $value; - } - } - - return $result; - } - - /** - * Returns the properties that will be serialized as JSON - * - * @return array - */ - public function jsonSerialize() - { - return $this->extract($this->visibleProperties()); - } - - /** - * Implements isset($entity); - * - * @param mixed $offset The offset to check. - * @return bool Success - */ - public function offsetExists($offset) - { - return $this->has($offset); - } - - /** - * Implements $entity[$offset]; - * - * @param mixed $offset The offset to get. - * @return mixed - */ - public function &offsetGet($offset) - { - return $this->get($offset); - } - - /** - * Implements $entity[$offset] = $value; - * - * @param mixed $offset The offset to set. - * @param mixed $value The value to set. - * @return void - */ - public function offsetSet($offset, $value) - { - $this->set($offset, $value); - } - - /** - * Implements unset($result[$offset]); - * - * @param mixed $offset The offset to remove. - * @return void - */ - public function offsetUnset($offset) - { - $this->unsetProperty($offset); - } - - /** - * Fetch accessor method name - * Accessor methods (available or not) are cached in $_accessors - * - * @param string $property the field name to derive getter name from - * @param string $type the accessor type ('get' or 'set') - * @return string method name or empty string (no method available) - */ - protected static function _accessor($property, $type) - { - $class = static::class; - - if (isset(static::$_accessors[$class][$type][$property])) { - return static::$_accessors[$class][$type][$property]; - } - - if (!empty(static::$_accessors[$class])) { - return static::$_accessors[$class][$type][$property] = ''; - } - - if ($class === 'Cake\ORM\Entity') { - return ''; - } - - foreach (get_class_methods($class) as $method) { - $prefix = substr($method, 1, 3); - if ($method[0] !== '_' || ($prefix !== 'get' && $prefix !== 'set')) { - continue; - } - $field = lcfirst(substr($method, 4)); - $snakeField = Inflector::underscore($field); - $titleField = ucfirst($field); - static::$_accessors[$class][$prefix][$snakeField] = $method; - static::$_accessors[$class][$prefix][$field] = $method; - static::$_accessors[$class][$prefix][$titleField] = $method; - } - - if (!isset(static::$_accessors[$class][$type][$property])) { - static::$_accessors[$class][$type][$property] = ''; - } - - return static::$_accessors[$class][$type][$property]; - } - - /** - * Returns an array with the requested properties - * stored in this entity, indexed by property name - * - * @param array $properties list of properties to be returned - * @param bool $onlyDirty Return the requested property only if it is dirty - * @return array - */ - public function extract(array $properties, $onlyDirty = false) - { - $result = []; - foreach ($properties as $property) { - if (!$onlyDirty || $this->isDirty($property)) { - $result[$property] = $this->get($property); - } - } - - return $result; - } - - /** - * Returns an array with the requested original properties - * stored in this entity, indexed by property name. - * - * Properties that are unchanged from their original value will be included in the - * return of this method. - * - * @param array $properties List of properties to be returned - * @return array - */ - public function extractOriginal(array $properties) - { - $result = []; - foreach ($properties as $property) { - $result[$property] = $this->getOriginal($property); - } - - return $result; - } - - /** - * Returns an array with only the original properties - * stored in this entity, indexed by property name. - * - * This method will only return properties that have been modified since - * the entity was built. Unchanged properties will be omitted. - * - * @param array $properties List of properties to be returned - * @return array - */ - public function extractOriginalChanged(array $properties) - { - $result = []; - foreach ($properties as $property) { - $original = $this->getOriginal($property); - if ($original !== $this->get($property)) { - $result[$property] = $original; - } - } - - return $result; - } - - /** - * Sets the dirty status of a single property. If called with no second - * argument, it will return whether the property was modified or not - * after the object creation. - * - * When called with no arguments it will return whether or not there are any - * dirty property in the entity - * - * @deprecated 3.4.0 Use EntityTrait::setDirty() and EntityTrait::isDirty() - * @param string|null $property the field to set or check status for - * @param null|bool $isDirty true means the property was changed, false means - * it was not changed and null will make the function return current state - * for that property - * @return bool Whether the property was changed or not - */ - public function dirty($property = null, $isDirty = null) - { - deprecationWarning( - get_called_class() . '::dirty() is deprecated. ' . - 'Use setDirty()/isDirty() instead.' - ); - if ($property === null) { - return $this->isDirty(); - } - - if ($isDirty === null) { - return $this->isDirty($property); - } - - $this->setDirty($property, $isDirty); - - return true; - } - - /** - * Sets the dirty status of a single property. - * - * @param string $property the field to set or check status for - * @param bool $isDirty true means the property was changed, false means - * it was not changed - * @return $this - */ - public function setDirty($property, $isDirty) - { - if ($isDirty === false) { - unset($this->_dirty[$property]); - - return $this; - } - - $this->_dirty[$property] = true; - unset($this->_errors[$property], $this->_invalid[$property]); - - return $this; - } - - /** - * Checks if the entity is dirty or if a single property of it is dirty. - * - * @param string|null $property The field to check the status for. Null for the whole entity. - * @return bool Whether the property was changed or not - */ - public function isDirty($property = null) - { - if ($property === null) { - return !empty($this->_dirty); - } - - return isset($this->_dirty[$property]); - } - - /** - * Gets the dirty properties. - * - * @return array - */ - public function getDirty() - { - return array_keys($this->_dirty); - } - - /** - * Sets the entire entity as clean, which means that it will appear as - * no properties being modified or added at all. This is an useful call - * for an initial object hydration - * - * @return void - */ - public function clean() - { - $this->_dirty = []; - $this->_errors = []; - $this->_invalid = []; - $this->_original = []; - } - - /** - * Returns whether or not this entity has already been persisted. - * This method can return null in the case there is no prior information on - * the status of this entity. - * - * If called with a boolean it will set the known status of this instance, - * true means that the instance is not yet persisted in the database, false - * that it already is. - * - * @param bool|null $new true if it is known this instance was not yet persisted - * @return bool Whether or not the entity has been persisted. - */ - public function isNew($new = null) - { - if ($new === null) { - return $this->_new; - } - - $new = (bool)$new; - - if ($new) { - foreach ($this->_properties as $k => $p) { - $this->_dirty[$k] = true; - } - } - - return $this->_new = $new; - } - - /** - * Returns all validation errors. - * - * @return array - */ - public function getErrors() - { - $diff = array_diff_key($this->_properties, $this->_errors); - - return $this->_errors + (new Collection($diff)) - ->filter(function ($value) { - return is_array($value) || $value instanceof EntityInterface; - }) - ->map(function ($value) { - return $this->_readError($value); - }) - ->filter() - ->toArray(); - } - - /** - * Returns validation errors of a field - * - * @param string $field Field name to get the errors from - * @return array - */ - public function getError($field) - { - $errors = isset($this->_errors[$field]) ? $this->_errors[$field] : []; - if ($errors) { - return $errors; - } - - return $this->_nestedErrors($field); - } - - /** - * Sets error messages to the entity - * - * ## Example - * - * ``` - * // Sets the error messages for multiple fields at once - * $entity->errors(['salary' => ['message'], 'name' => ['another message']); - * ``` - * - * @param array $fields The array of errors to set. - * @param bool $overwrite Whether or not to overwrite pre-existing errors for $fields - * @return $this - */ - public function setErrors(array $fields, $overwrite = false) - { - foreach ($fields as $f => $error) { - $this->_errors += [$f => []]; - $this->_errors[$f] = $overwrite ? - (array)$error : - array_merge($this->_errors[$f], (array)$error); - } - - return $this; - } - - /** - * Sets errors for a single field - * - * ### Example - * - * ``` - * // Sets the error messages for a single field - * $entity->errors('salary', ['must be numeric', 'must be a positive number']); - * ``` - * - * @param string $field The field to get errors for, or the array of errors to set. - * @param string|array $errors The errors to be set for $field - * @param bool $overwrite Whether or not to overwrite pre-existing errors for $field - * @return $this - */ - public function setError($field, $errors, $overwrite = false) - { - if (is_string($errors)) { - $errors = [$errors]; - } - - return $this->setErrors([$field => $errors], $overwrite); - } - - /** - * Sets the error messages for a field or a list of fields. When called - * without the second argument it returns the validation - * errors for the specified fields. If called with no arguments it returns - * all the validation error messages stored in this entity and any other nested - * entity. - * - * ### Example - * - * ``` - * // Sets the error messages for a single field - * $entity->errors('salary', ['must be numeric', 'must be a positive number']); - * - * // Returns the error messages for a single field - * $entity->errors('salary'); - * - * // Returns all error messages indexed by field name - * $entity->errors(); - * - * // Sets the error messages for multiple fields at once - * $entity->errors(['salary' => ['message'], 'name' => ['another message']); - * ``` - * - * When used as a setter, this method will return this entity instance for method - * chaining. - * - * @deprecated 3.4.0 Use EntityTrait::setError(), EntityTrait::setErrors(), EntityTrait::getError() and EntityTrait::getErrors() - * @param string|array|null $field The field to get errors for, or the array of errors to set. - * @param string|array|null $errors The errors to be set for $field - * @param bool $overwrite Whether or not to overwrite pre-existing errors for $field - * @return array|$this - */ - public function errors($field = null, $errors = null, $overwrite = false) - { - deprecationWarning( - get_called_class() . '::errors() is deprecated. ' . - 'Use setError()/getError() or setErrors()/getErrors() instead.' - ); - if ($field === null) { - return $this->getErrors(); - } - - if (is_string($field) && $errors === null) { - return $this->getError($field); - } - - if (!is_array($field)) { - $field = [$field => $errors]; - } - - return $this->setErrors($field, $overwrite); - } - - /** - * Auxiliary method for getting errors in nested entities - * - * @param string $field the field in this entity to check for errors - * @return array errors in nested entity if any - */ - protected function _nestedErrors($field) - { - $path = explode('.', $field); - - // Only one path element, check for nested entity with error. - if (count($path) === 1) { - return $this->_readError($this->get($path[0])); - } - - $entity = $this; - $len = count($path); - while ($len) { - $part = array_shift($path); - $len = count($path); - $val = null; - if ($entity instanceof EntityInterface) { - $val = $entity->get($part); - } elseif (is_array($entity)) { - $val = isset($entity[$part]) ? $entity[$part] : false; - } - - if (is_array($val) || - $val instanceof Traversable || - $val instanceof EntityInterface - ) { - $entity = $val; - } else { - $path[] = $part; - break; - } - } - if (count($path) <= 1) { - return $this->_readError($entity, array_pop($path)); - } - - return []; - } - - /** - * Read the error(s) from one or many objects. - * - * @param array|\Cake\Datasource\EntityTrait $object The object to read errors from. - * @param string|null $path The field name for errors. - * @return array - */ - protected function _readError($object, $path = null) - { - if ($path !== null && $object instanceof EntityInterface) { - return $object->getError($path); - } - if ($object instanceof EntityInterface) { - return $object->getErrors(); - } - if (is_array($object)) { - $array = array_map(function ($val) { - if ($val instanceof EntityInterface) { - return $val->getErrors(); - } - }, $object); - - return array_filter($array); - } - - return []; - } - - /** - * Get a list of invalid fields and their data for errors upon validation/patching - * - * @return array - */ - public function getInvalid() - { - return $this->_invalid; - } - - /** - * Get a single value of an invalid field. Returns null if not set. - * - * @param string $field The name of the field. - * @return mixed - */ - public function getInvalidField($field) - { - $value = isset($this->_invalid[$field]) ? $this->_invalid[$field] : null; - - return $value; - } - - /** - * Set fields as invalid and not patchable into the entity. - * - * This is useful for batch operations when one needs to get the original value for an error message after patching. - * This value could not be patched into the entity and is simply copied into the _invalid property for debugging purposes - * or to be able to log it away. - * - * @param array $fields The values to set. - * @param bool $overwrite Whether or not to overwrite pre-existing values for $field. - * @return $this - */ - public function setInvalid(array $fields, $overwrite = false) - { - foreach ($fields as $field => $value) { - if ($overwrite === true) { - $this->_invalid[$field] = $value; - continue; - } - $this->_invalid += [$field => $value]; - } - - return $this; - } - - /** - * Sets a field as invalid and not patchable into the entity. - * - * @param string $field The value to set. - * @param mixed $value The invalid value to be set for $field. - * @return $this - */ - public function setInvalidField($field, $value) - { - $this->_invalid[$field] = $value; - - return $this; - } - - /** - * Sets a field as invalid and not patchable into the entity. - * - * This is useful for batch operations when one needs to get the original value for an error message after patching. - * This value could not be patched into the entity and is simply copied into the _invalid property for debugging purposes - * or to be able to log it away. - * - * @deprecated 3.5 Use getInvalid()/getInvalidField()/setInvalid() instead. - * @param string|array|null $field The field to get invalid value for, or the value to set. - * @param mixed|null $value The invalid value to be set for $field. - * @param bool $overwrite Whether or not to overwrite pre-existing values for $field. - * @return $this|mixed - */ - public function invalid($field = null, $value = null, $overwrite = false) - { - deprecationWarning( - get_called_class() . '::invalid() is deprecated. ' . - 'Use setInvalid()/getInvalid()/getInvalidField() instead.' - ); - if ($field === null) { - return $this->_invalid; - } - - if (is_string($field) && $value === null) { - $value = isset($this->_invalid[$field]) ? $this->_invalid[$field] : null; - - return $value; - } - - if (!is_array($field)) { - $field = [$field => $value]; - } - - foreach ($field as $f => $value) { - if ($overwrite) { - $this->_invalid[$f] = $value; - continue; - } - $this->_invalid += [$f => $value]; - } - - return $this; - } - - /** - * Stores whether or not a property value can be changed or set in this entity. - * The special property `*` can also be marked as accessible or protected, meaning - * that any other property specified before will take its value. For example - * `$entity->accessible('*', true)` means that any property not specified already - * will be accessible by default. - * - * You can also call this method with an array of properties, in which case they - * will each take the accessibility value specified in the second argument. - * - * ### Example: - * - * ``` - * $entity->accessible('id', true); // Mark id as not protected - * $entity->accessible('author_id', false); // Mark author_id as protected - * $entity->accessible(['id', 'user_id'], true); // Mark both properties as accessible - * $entity->accessible('*', false); // Mark all properties as protected - * ``` - * - * When called without the second param it will return whether or not the property - * can be set. - * - * ### Example: - * - * ``` - * $entity->accessible('id'); // Returns whether it can be set or not - * ``` - * - * @deprecated 3.4.0 Use EntityTrait::setAccess() and EntityTrait::isAccessible() - * @param string|array $property single or list of properties to change its accessibility - * @param bool|null $set true marks the property as accessible, false will - * mark it as protected. - * @return $this|bool - */ - public function accessible($property, $set = null) - { - deprecationWarning( - get_called_class() . '::accessible() is deprecated. ' . - 'Use setAccess()/isAccessible() instead.' - ); - if ($set === null) { - return $this->isAccessible($property); - } - - return $this->setAccess($property, $set); - } - - /** - * Stores whether or not a property value can be changed or set in this entity. - * The special property `*` can also be marked as accessible or protected, meaning - * that any other property specified before will take its value. For example - * `$entity->setAccess('*', true)` means that any property not specified already - * will be accessible by default. - * - * You can also call this method with an array of properties, in which case they - * will each take the accessibility value specified in the second argument. - * - * ### Example: - * - * ``` - * $entity->setAccess('id', true); // Mark id as not protected - * $entity->setAccess('author_id', false); // Mark author_id as protected - * $entity->setAccess(['id', 'user_id'], true); // Mark both properties as accessible - * $entity->setAccess('*', false); // Mark all properties as protected - * ``` - * - * @param string|array $property single or list of properties to change its accessibility - * @param bool $set true marks the property as accessible, false will - * mark it as protected. - * @return $this - */ - public function setAccess($property, $set) - { - if ($property === '*') { - $this->_accessible = array_map(function ($p) use ($set) { - return (bool)$set; - }, $this->_accessible); - $this->_accessible['*'] = (bool)$set; - - return $this; - } - - foreach ((array)$property as $prop) { - $this->_accessible[$prop] = (bool)$set; - } - - return $this; - } - - /** - * Checks if a property is accessible - * - * ### Example: - * - * ``` - * $entity->isAccessible('id'); // Returns whether it can be set or not - * ``` - * - * @param string $property Property name to check - * @return bool - */ - public function isAccessible($property) - { - $value = isset($this->_accessible[$property]) ? - $this->_accessible[$property] : - null; - - return ($value === null && !empty($this->_accessible['*'])) || $value; - } - - /** - * Returns the alias of the repository from which this entity came from. - * - * @return string - */ - public function getSource() - { - return $this->_registryAlias; - } - - /** - * Sets the source alias - * - * @param string $alias the alias of the repository - * @return $this - */ - public function setSource($alias) - { - $this->_registryAlias = $alias; - - return $this; - } - - /** - * Returns the alias of the repository from which this entity came from. - * - * If called with no arguments, it returns the alias of the repository - * this entity came from if it is known. - * - * @deprecated 3.4.0 Use EntityTrait::getSource() and EntityTrait::setSource() - * @param string|null $alias the alias of the repository - * @return string|$this - */ - public function source($alias = null) - { - deprecationWarning( - get_called_class() . '::source() is deprecated. ' . - 'Use setSource()/getSource() instead.' - ); - if (is_null($alias)) { - return $this->getSource(); - } - - $this->setSource($alias); - - return $this; - } - - /** - * Returns a string representation of this object in a human readable format. - * - * @return string - */ - public function __toString() - { - return json_encode($this, JSON_PRETTY_PRINT); - } - - /** - * Returns an array that can be used to describe the internal state of this - * object. - * - * @return array - */ - public function __debugInfo() - { - $properties = $this->_properties; - foreach ($this->_virtual as $field) { - $properties[$field] = $this->$field; - } - - return $properties + [ - '[new]' => $this->isNew(), - '[accessible]' => $this->_accessible, - '[dirty]' => $this->_dirty, - '[original]' => $this->_original, - '[virtual]' => $this->_virtual, - '[errors]' => $this->_errors, - '[invalid]' => $this->_invalid, - '[repository]' => $this->_registryAlias - ]; - } -} diff --git a/vendor/cakephp/cakephp/src/Datasource/Exception/InvalidPrimaryKeyException.php b/vendor/cakephp/cakephp/src/Datasource/Exception/InvalidPrimaryKeyException.php deleted file mode 100644 index 9a033a7..0000000 --- a/vendor/cakephp/cakephp/src/Datasource/Exception/InvalidPrimaryKeyException.php +++ /dev/null @@ -1,41 +0,0 @@ -modelClass)) { - $this->modelClass = $name; - } - } - - /** - * Loads and constructs repository objects required by this object - * - * Typically used to load ORM Table objects as required. Can - * also be used to load other types of repository objects your application uses. - * - * If a repository provider does not return an object a MissingModelException will - * be thrown. - * - * @param string|null $modelClass Name of model class to load. Defaults to $this->modelClass - * @param string|null $modelType The type of repository to load. Defaults to the modelType() value. - * @return \Cake\Datasource\RepositoryInterface The model instance created. - * @throws \Cake\Datasource\Exception\MissingModelException If the model class cannot be found. - * @throws \InvalidArgumentException When using a type that has not been registered. - * @throws \UnexpectedValueException If no model type has been defined - */ - public function loadModel($modelClass = null, $modelType = null) - { - if ($modelClass === null) { - $modelClass = $this->modelClass; - } - if ($modelType === null) { - $modelType = $this->getModelType(); - - if ($modelType === null) { - throw new UnexpectedValueException('No model type has been defined'); - } - } - - list(, $alias) = pluginSplit($modelClass, true); - - if (isset($this->{$alias})) { - return $this->{$alias}; - } - - if (isset($this->_modelFactories[$modelType])) { - $factory = $this->_modelFactories[$modelType]; - } - if (!isset($factory)) { - $factory = FactoryLocator::get($modelType); - } - $this->{$alias} = $factory($modelClass); - if (!$this->{$alias}) { - throw new MissingModelException([$modelClass, $modelType]); - } - - return $this->{$alias}; - } - - /** - * Override a existing callable to generate repositories of a given type. - * - * @param string $type The name of the repository type the factory function is for. - * @param callable $factory The factory function used to create instances. - * @return void - */ - public function modelFactory($type, callable $factory) - { - $this->_modelFactories[$type] = $factory; - } - - /** - * Get the model type to be used by this class - * - * @return string - */ - public function getModelType() - { - return $this->_modelType; - } - - /** - * Set the model type to be used by this class - * - * @param string $modelType The model type - * - * @return $this - */ - public function setModelType($modelType) - { - $this->_modelType = $modelType; - - return $this; - } - - /** - * Set or get the model type to be used by this class - * - * @deprecated 3.5.0 Use getModelType()/setModelType() instead. - * @param string|null $modelType The model type or null to retrieve the current - * - * @return string|$this - */ - public function modelType($modelType = null) - { - deprecationWarning( - get_called_class() . '::modelType() is deprecated. ' . - 'Use setModelType()/getModelType() instead.' - ); - if ($modelType === null) { - return $this->_modelType; - } - - $this->_modelType = $modelType; - - return $this; - } -} diff --git a/vendor/cakephp/cakephp/src/Datasource/QueryCacher.php b/vendor/cakephp/cakephp/src/Datasource/QueryCacher.php deleted file mode 100644 index cf33e64..0000000 --- a/vendor/cakephp/cakephp/src/Datasource/QueryCacher.php +++ /dev/null @@ -1,134 +0,0 @@ -_key = $key; - - if (!is_string($config) && !($config instanceof CacheEngine)) { - throw new RuntimeException('Cache configs must be strings or CacheEngine instances.'); - } - $this->_config = $config; - } - - /** - * Load the cached results from the cache or run the query. - * - * @param object $query The query the cache read is for. - * @return \Cake\ORM\ResultSet|null Either the cached results or null. - */ - public function fetch($query) - { - $key = $this->_resolveKey($query); - $storage = $this->_resolveCacher(); - $result = $storage->read($key); - if (empty($result)) { - return null; - } - - return $result; - } - - /** - * Store the result set into the cache. - * - * @param object $query The query the cache read is for. - * @param \Traversable $results The result set to store. - * @return bool True if the data was successfully cached, false on failure - */ - public function store($query, Traversable $results) - { - $key = $this->_resolveKey($query); - $storage = $this->_resolveCacher(); - - return $storage->write($key, $results); - } - - /** - * Get/generate the cache key. - * - * @param object $query The query to generate a key for. - * @return string - * @throws \RuntimeException - */ - protected function _resolveKey($query) - { - if (is_string($this->_key)) { - return $this->_key; - } - $func = $this->_key; - $key = $func($query); - if (!is_string($key)) { - $msg = sprintf('Cache key functions must return a string. Got %s.', var_export($key, true)); - throw new RuntimeException($msg); - } - - return $key; - } - - /** - * Get the cache engine. - * - * @return \Cake\Cache\CacheEngine - */ - protected function _resolveCacher() - { - if (is_string($this->_config)) { - return Cache::engine($this->_config); - } - - return $this->_config; - } -} diff --git a/vendor/cakephp/cakephp/src/Datasource/QueryInterface.php b/vendor/cakephp/cakephp/src/Datasource/QueryInterface.php deleted file mode 100644 index 793258e..0000000 --- a/vendor/cakephp/cakephp/src/Datasource/QueryInterface.php +++ /dev/null @@ -1,382 +0,0 @@ - value array representing a single aliased field - * that can be passed directly to the select() method. - * The key will contain the alias and the value the actual field name. - * - * If the field is already aliased, then it will not be changed. - * If no $alias is passed, the default table for this query will be used. - * - * @param string $field The field to alias - * @param string|null $alias the alias used to prefix the field - * @return string - */ - public function aliasField($field, $alias = null); - - /** - * Runs `aliasField()` for each field in the provided list and returns - * the result under a single array. - * - * @param array $fields The fields to alias - * @param string|null $defaultAlias The default alias - * @return string[] - */ - public function aliasFields($fields, $defaultAlias = null); - - /** - * Fetch the results for this query. - * - * Will return either the results set through setResult(), or execute this query - * and return the ResultSetDecorator object ready for streaming of results. - * - * ResultSetDecorator is a traversable object that implements the methods found - * on Cake\Collection\Collection. - * - * @return \Cake\Datasource\ResultSetInterface - */ - public function all(); - - /** - * Populates or adds parts to current query clauses using an array. - * This is handy for passing all query clauses at once. The option array accepts: - * - * - fields: Maps to the select method - * - conditions: Maps to the where method - * - limit: Maps to the limit method - * - order: Maps to the order method - * - offset: Maps to the offset method - * - group: Maps to the group method - * - having: Maps to the having method - * - contain: Maps to the contain options for eager loading - * - join: Maps to the join method - * - page: Maps to the page method - * - * ### Example: - * - * ``` - * $query->applyOptions([ - * 'fields' => ['id', 'name'], - * 'conditions' => [ - * 'created >=' => '2013-01-01' - * ], - * 'limit' => 10 - * ]); - * ``` - * - * Is equivalent to: - * - * ``` - * $query - * ->select(['id', 'name']) - * ->where(['created >=' => '2013-01-01']) - * ->limit(10) - * ``` - * - * @param array $options list of query clauses to apply new parts to. - * @return $this - */ - public function applyOptions(array $options); - - /** - * Apply custom finds to against an existing query object. - * - * Allows custom find methods to be combined and applied to each other. - * - * ``` - * $repository->find('all')->find('recent'); - * ``` - * - * The above is an example of stacking multiple finder methods onto - * a single query. - * - * @param string $finder The finder method to use. - * @param array $options The options for the finder. - * @return $this Returns a modified query. - */ - public function find($finder, array $options = []); - - /** - * Returns the first result out of executing this query, if the query has not been - * executed before, it will set the limit clause to 1 for performance reasons. - * - * ### Example: - * - * ``` - * $singleUser = $query->select(['id', 'username'])->first(); - * ``` - * - * @return mixed the first result from the ResultSet - */ - public function first(); - - /** - * Returns the total amount of results for the query. - * - * @return int - */ - public function count(); - - /** - * Sets the number of records that should be retrieved from database, - * accepts an integer or an expression object that evaluates to an integer. - * In some databases, this operation might not be supported or will require - * the query to be transformed in order to limit the result set size. - * - * ### Examples - * - * ``` - * $query->limit(10) // generates LIMIT 10 - * $query->limit($query->newExpr()->add(['1 + 1'])); // LIMIT (1 + 1) - * ``` - * - * @param int $num number of records to be returned - * @return $this - */ - public function limit($num); - - /** - * Sets the number of records that should be skipped from the original result set - * This is commonly used for paginating large results. Accepts an integer or an - * expression object that evaluates to an integer. - * - * In some databases, this operation might not be supported or will require - * the query to be transformed in order to limit the result set size. - * - * ### Examples - * - * ``` - * $query->offset(10) // generates OFFSET 10 - * $query->offset($query->newExpr()->add(['1 + 1'])); // OFFSET (1 + 1) - * ``` - * - * @param int $num number of records to be skipped - * @return $this - */ - public function offset($num); - - /** - * Adds a single or multiple fields to be used in the ORDER clause for this query. - * Fields can be passed as an array of strings, array of expression - * objects, a single expression or a single string. - * - * If an array is passed, keys will be used as the field itself and the value will - * represent the order in which such field should be ordered. When called multiple - * times with the same fields as key, the last order definition will prevail over - * the others. - * - * By default this function will append any passed argument to the list of fields - * to be selected, unless the second argument is set to true. - * - * ### Examples: - * - * ``` - * $query->order(['title' => 'DESC', 'author_id' => 'ASC']); - * ``` - * - * Produces: - * - * `ORDER BY title DESC, author_id ASC` - * - * ``` - * $query->order(['title' => 'DESC NULLS FIRST'])->order('author_id'); - * ``` - * - * Will generate: - * - * `ORDER BY title DESC NULLS FIRST, author_id` - * - * ``` - * $expression = $query->newExpr()->add(['id % 2 = 0']); - * $query->order($expression)->order(['title' => 'ASC']); - * ``` - * - * Will become: - * - * `ORDER BY (id %2 = 0), title ASC` - * - * If you need to set complex expressions as order conditions, you - * should use `orderAsc()` or `orderDesc()`. - * - * @param array|string $fields fields to be added to the list - * @param bool $overwrite whether to reset order with field list or not - * @return $this - */ - public function order($fields, $overwrite = false); - - /** - * Set the page of results you want. - * - * This method provides an easier to use interface to set the limit + offset - * in the record set you want as results. If empty the limit will default to - * the existing limit clause, and if that too is empty, then `25` will be used. - * - * Pages must start at 1. - * - * @param int $num The page number you want. - * @param int|null $limit The number of rows you want in the page. If null - * the current limit clause will be used. - * @return $this - * @throws \InvalidArgumentException If page number < 1. - */ - public function page($num, $limit = null); - - /** - * Returns an array representation of the results after executing the query. - * - * @return array - */ - public function toArray(); - - /** - * Returns the default repository object that will be used by this query, - * that is, the repository that will appear in the from clause. - * - * @param \Cake\Datasource\RepositoryInterface|null $repository The default repository object to use - * @return \Cake\Datasource\RepositoryInterface|$this - */ - public function repository(RepositoryInterface $repository = null); - - /** - * Adds a condition or set of conditions to be used in the WHERE clause for this - * query. Conditions can be expressed as an array of fields as keys with - * comparison operators in it, the values for the array will be used for comparing - * the field to such literal. Finally, conditions can be expressed as a single - * string or an array of strings. - * - * When using arrays, each entry will be joined to the rest of the conditions using - * an AND operator. Consecutive calls to this function will also join the new - * conditions specified using the AND operator. Additionally, values can be - * expressed using expression objects which can include other query objects. - * - * Any conditions created with this methods can be used with any SELECT, UPDATE - * and DELETE type of queries. - * - * ### Conditions using operators: - * - * ``` - * $query->where([ - * 'posted >=' => new DateTime('3 days ago'), - * 'title LIKE' => 'Hello W%', - * 'author_id' => 1, - * ], ['posted' => 'datetime']); - * ``` - * - * The previous example produces: - * - * `WHERE posted >= 2012-01-27 AND title LIKE 'Hello W%' AND author_id = 1` - * - * Second parameter is used to specify what type is expected for each passed - * key. Valid types can be used from the mapped with Database\Type class. - * - * ### Nesting conditions with conjunctions: - * - * ``` - * $query->where([ - * 'author_id !=' => 1, - * 'OR' => ['published' => true, 'posted <' => new DateTime('now')], - * 'NOT' => ['title' => 'Hello'] - * ], ['published' => boolean, 'posted' => 'datetime'] - * ``` - * - * The previous example produces: - * - * `WHERE author_id = 1 AND (published = 1 OR posted < '2012-02-01') AND NOT (title = 'Hello')` - * - * You can nest conditions using conjunctions as much as you like. Sometimes, you - * may want to define 2 different options for the same key, in that case, you can - * wrap each condition inside a new array: - * - * `$query->where(['OR' => [['published' => false], ['published' => true]])` - * - * Keep in mind that every time you call where() with the third param set to false - * (default), it will join the passed conditions to the previous stored list using - * the AND operator. Also, using the same array key twice in consecutive calls to - * this method will not override the previous value. - * - * ### Using expressions objects: - * - * ``` - * $exp = $query->newExpr()->add(['id !=' => 100, 'author_id' != 1])->tieWith('OR'); - * $query->where(['published' => true], ['published' => 'boolean'])->where($exp); - * ``` - * - * The previous example produces: - * - * `WHERE (id != 100 OR author_id != 1) AND published = 1` - * - * Other Query objects that be used as conditions for any field. - * - * ### Adding conditions in multiple steps: - * - * You can use callable functions to construct complex expressions, functions - * receive as first argument a new QueryExpression object and this query instance - * as second argument. Functions must return an expression object, that will be - * added the list of conditions for the query using the AND operator. - * - * ``` - * $query - * ->where(['title !=' => 'Hello World']) - * ->where(function ($exp, $query) { - * $or = $exp->or_(['id' => 1]); - * $and = $exp->and_(['id >' => 2, 'id <' => 10]); - * return $or->add($and); - * }); - * ``` - * - * * The previous example produces: - * - * `WHERE title != 'Hello World' AND (id = 1 OR (id > 2 AND id < 10))` - * - * ### Conditions as strings: - * - * ``` - * $query->where(['articles.author_id = authors.id', 'modified IS NULL']); - * ``` - * - * The previous example produces: - * - * `WHERE articles.author_id = authors.id AND modified IS NULL` - * - * Please note that when using the array notation or the expression objects, all - * values will be correctly quoted and transformed to the correspondent database - * data type automatically for you, thus securing your application from SQL injections. - * If you use string conditions make sure that your values are correctly quoted. - * The safest thing you can do is to never use string conditions. - * - * @param string|array|callable|null $conditions The conditions to filter on. - * @param array $types associative array of type names used to bind values to query - * @param bool $overwrite whether to reset conditions with passed list or not - * @return $this - */ - public function where($conditions = null, $types = [], $overwrite = false); -} diff --git a/vendor/cakephp/cakephp/src/Datasource/QueryTrait.php b/vendor/cakephp/cakephp/src/Datasource/QueryTrait.php deleted file mode 100644 index c99e83a..0000000 --- a/vendor/cakephp/cakephp/src/Datasource/QueryTrait.php +++ /dev/null @@ -1,587 +0,0 @@ -getRepository(); - } - - $this->_repository = $table; - - return $this; - } - - /** - * Returns the default table object that will be used by this query, - * that is, the table that will appear in the from clause. - * - * @return \Cake\Datasource\RepositoryInterface|\Cake\ORM\Table - */ - public function getRepository() - { - return $this->_repository; - } - - /** - * Set the result set for a query. - * - * Setting the resultset of a query will make execute() a no-op. Instead - * of executing the SQL query and fetching results, the ResultSet provided to this - * method will be returned. - * - * This method is most useful when combined with results stored in a persistent cache. - * - * @param \Cake\Datasource\ResultSetInterface $results The results this query should return. - * @return $this - */ - public function setResult($results) - { - $this->_results = $results; - - return $this; - } - - /** - * Executes this query and returns a results iterator. This function is required - * for implementing the IteratorAggregate interface and allows the query to be - * iterated without having to call execute() manually, thus making it look like - * a result set instead of the query itself. - * - * @return \Iterator - */ - public function getIterator() - { - return $this->all(); - } - - /** - * Enable result caching for this query. - * - * If a query has caching enabled, it will do the following when executed: - * - * - Check the cache for $key. If there are results no SQL will be executed. - * Instead the cached results will be returned. - * - When the cached data is stale/missing the result set will be cached as the query - * is executed. - * - * ### Usage - * - * ``` - * // Simple string key + config - * $query->cache('my_key', 'db_results'); - * - * // Function to generate key. - * $query->cache(function ($q) { - * $key = serialize($q->clause('select')); - * $key .= serialize($q->clause('where')); - * return md5($key); - * }); - * - * // Using a pre-built cache engine. - * $query->cache('my_key', $engine); - * - * // Disable caching - * $query->cache(false); - * ``` - * - * @param false|string|\Closure $key Either the cache key or a function to generate the cache key. - * When using a function, this query instance will be supplied as an argument. - * @param string|\Cake\Cache\CacheEngine $config Either the name of the cache config to use, or - * a cache config instance. - * @return $this - */ - public function cache($key, $config = 'default') - { - if ($key === false) { - $this->_cache = null; - - return $this; - } - $this->_cache = new QueryCacher($key, $config); - - return $this; - } - - /** - * Returns the current configured query `_eagerLoaded` value - * - * @return bool - */ - public function isEagerLoaded() - { - return $this->_eagerLoaded; - } - - /** - * Sets the query instance to be an eager loaded query. If no argument is - * passed, the current configured query `_eagerLoaded` value is returned. - * - * @deprecated 3.5.0 Use isEagerLoaded() for the getter part instead. - * @param bool|null $value Whether or not to eager load. - * @return $this|\Cake\ORM\Query - */ - public function eagerLoaded($value = null) - { - if ($value === null) { - deprecationWarning( - 'Using ' . get_called_class() . '::eagerLoaded() as a getter is deprecated. ' . - 'Use isEagerLoaded() instead.' - ); - - return $this->_eagerLoaded; - } - $this->_eagerLoaded = $value; - - return $this; - } - - /** - * Returns a key => value array representing a single aliased field - * that can be passed directly to the select() method. - * The key will contain the alias and the value the actual field name. - * - * If the field is already aliased, then it will not be changed. - * If no $alias is passed, the default table for this query will be used. - * - * @param string $field The field to alias - * @param string|null $alias the alias used to prefix the field - * @return array - */ - public function aliasField($field, $alias = null) - { - $namespaced = strpos($field, '.') !== false; - $aliasedField = $field; - - if ($namespaced) { - list($alias, $field) = explode('.', $field); - } - - if (!$alias) { - $alias = $this->getRepository()->getAlias(); - } - - $key = sprintf('%s__%s', $alias, $field); - if (!$namespaced) { - $aliasedField = $alias . '.' . $field; - } - - return [$key => $aliasedField]; - } - - /** - * Runs `aliasField()` for each field in the provided list and returns - * the result under a single array. - * - * @param array $fields The fields to alias - * @param string|null $defaultAlias The default alias - * @return array - */ - public function aliasFields($fields, $defaultAlias = null) - { - $aliased = []; - foreach ($fields as $alias => $field) { - if (is_numeric($alias) && is_string($field)) { - $aliased += $this->aliasField($field, $defaultAlias); - continue; - } - $aliased[$alias] = $field; - } - - return $aliased; - } - - /** - * Fetch the results for this query. - * - * Will return either the results set through setResult(), or execute this query - * and return the ResultSetDecorator object ready for streaming of results. - * - * ResultSetDecorator is a traversable object that implements the methods found - * on Cake\Collection\Collection. - * - * @return \Cake\Datasource\ResultSetInterface - */ - public function all() - { - if ($this->_results !== null) { - return $this->_results; - } - - if ($this->_cache) { - $results = $this->_cache->fetch($this); - } - if (!isset($results)) { - $results = $this->_decorateResults($this->_execute()); - if ($this->_cache) { - $this->_cache->store($this, $results); - } - } - $this->_results = $results; - - return $this->_results; - } - - /** - * Returns an array representation of the results after executing the query. - * - * @return array - */ - public function toArray() - { - return $this->all()->toArray(); - } - - /** - * Register a new MapReduce routine to be executed on top of the database results - * Both the mapper and caller callable should be invokable objects. - * - * The MapReduce routing will only be run when the query is executed and the first - * result is attempted to be fetched. - * - * If the first argument is set to null, it will return the list of previously - * registered map reduce routines. This is deprecated as of 3.6.0 - use getMapReducers() instead. - * - * If the third argument is set to true, it will erase previous map reducers - * and replace it with the arguments passed. - * - * @param callable|null $mapper The mapper callable. - * @param callable|null $reducer The reducing function. - * @param bool $overwrite Set to true to overwrite existing map + reduce functions. - * @return $this|array - * @see \Cake\Collection\Iterator\MapReduce for details on how to use emit data to the map reducer. - */ - public function mapReduce(callable $mapper = null, callable $reducer = null, $overwrite = false) - { - if ($overwrite) { - $this->_mapReduce = []; - } - if ($mapper === null) { - if (!$overwrite) { - deprecationWarning( - 'Using QueryTrait::mapReduce() as a getter is deprecated. ' . - 'Use getMapReducers() instead.' - ); - } - - return $this->_mapReduce; - } - $this->_mapReduce[] = compact('mapper', 'reducer'); - - return $this; - } - - /** - * Returns the list of previously registered map reduce routines. - * - * @return array - */ - public function getMapReducers() - { - return $this->_mapReduce; - } - - /** - * Registers a new formatter callback function that is to be executed when trying - * to fetch the results from the database. - * - * Formatting callbacks will get a first parameter, an object implementing - * `\Cake\Collection\CollectionInterface`, that can be traversed and modified at will. - * - * Callbacks are required to return an iterator object, which will be used as - * the return value for this query's result. Formatter functions are applied - * after all the `MapReduce` routines for this query have been executed. - * - * If the first argument is set to null, it will return the list of previously - * registered format routines. This is deprecated as of 3.6.0 - use getResultFormatters() instead. - * - * If the second argument is set to true, it will erase previous formatters - * and replace them with the passed first argument. - * - * ### Example: - * - * ``` - * // Return all results from the table indexed by id - * $query->select(['id', 'name'])->formatResults(function ($results) { - * return $results->indexBy('id'); - * }); - * - * // Add a new column to the ResultSet - * $query->select(['name', 'birth_date'])->formatResults(function ($results) { - * return $results->map(function ($row) { - * $row['age'] = $row['birth_date']->diff(new DateTime)->y; - * return $row; - * }); - * }); - * ``` - * - * @param callable|null $formatter The formatting callable. - * @param bool|int $mode Whether or not to overwrite, append or prepend the formatter. - * @return $this|array - */ - public function formatResults(callable $formatter = null, $mode = 0) - { - if ($mode === self::OVERWRITE) { - $this->_formatters = []; - } - if ($formatter === null) { - if ($mode !== self::OVERWRITE) { - deprecationWarning( - 'Using QueryTrait::formatResults() as a getter is deprecated. ' . - 'Use getResultFormatters() instead.' - ); - } - - return $this->_formatters; - } - - if ($mode === self::PREPEND) { - array_unshift($this->_formatters, $formatter); - - return $this; - } - - $this->_formatters[] = $formatter; - - return $this; - } - - /** - * Returns the list of previously registered format routines. - * - * @return array - */ - public function getResultFormatters() - { - return $this->_formatters; - } - - /** - * Returns the first result out of executing this query, if the query has not been - * executed before, it will set the limit clause to 1 for performance reasons. - * - * ### Example: - * - * ``` - * $singleUser = $query->select(['id', 'username'])->first(); - * ``` - * - * @return \Cake\Datasource\EntityInterface|array|null The first result from the ResultSet. - */ - public function first() - { - if ($this->_dirty) { - $this->limit(1); - } - - return $this->all()->first(); - } - - /** - * Get the first result from the executing query or raise an exception. - * - * @throws \Cake\Datasource\Exception\RecordNotFoundException When there is no first record. - * @return \Cake\Datasource\EntityInterface|array The first result from the ResultSet. - */ - public function firstOrFail() - { - $entity = $this->first(); - if (!$entity) { - throw new RecordNotFoundException(sprintf( - 'Record not found in table "%s"', - $this->getRepository()->getTable() - )); - } - - return $entity; - } - - /** - * Returns an array with the custom options that were applied to this query - * and that were not already processed by another method in this class. - * - * ### Example: - * - * ``` - * $query->applyOptions(['doABarrelRoll' => true, 'fields' => ['id', 'name']); - * $query->getOptions(); // Returns ['doABarrelRoll' => true] - * ``` - * - * @see \Cake\ORM\Query::applyOptions() to read about the options that will - * be processed by this class and not returned by this function - * @return array - */ - public function getOptions() - { - return $this->_options; - } - - /** - * Enables calling methods from the result set as if they were from this class - * - * @param string $method the method to call - * @param array $arguments list of arguments for the method to call - * @return mixed - * @throws \BadMethodCallException if no such method exists in result set - */ - public function __call($method, $arguments) - { - $resultSetClass = $this->_decoratorClass(); - if (in_array($method, get_class_methods($resultSetClass))) { - $results = $this->all(); - - return $results->$method(...$arguments); - } - throw new BadMethodCallException( - sprintf('Unknown method "%s"', $method) - ); - } - - /** - * Populates or adds parts to current query clauses using an array. - * This is handy for passing all query clauses at once. - * - * @param array $options the options to be applied - * @return $this - */ - abstract public function applyOptions(array $options); - - /** - * Executes this query and returns a traversable object containing the results - * - * @return \Traversable - */ - abstract protected function _execute(); - - /** - * Decorates the results iterator with MapReduce routines and formatters - * - * @param \Traversable $result Original results - * @return \Cake\Datasource\ResultSetInterface - */ - protected function _decorateResults($result) - { - $decorator = $this->_decoratorClass(); - foreach ($this->_mapReduce as $functions) { - $result = new MapReduce($result, $functions['mapper'], $functions['reducer']); - } - - if (!empty($this->_mapReduce)) { - $result = new $decorator($result); - } - - foreach ($this->_formatters as $formatter) { - $result = $formatter($result); - } - - if (!empty($this->_formatters) && !($result instanceof $decorator)) { - $result = new $decorator($result); - } - - return $result; - } - - /** - * Returns the name of the class to be used for decorating results - * - * @return string - */ - protected function _decoratorClass() - { - return ResultSetDecorator::class; - } -} diff --git a/vendor/cakephp/cakephp/src/Datasource/README.md b/vendor/cakephp/cakephp/src/Datasource/README.md deleted file mode 100644 index 9eae4c0..0000000 --- a/vendor/cakephp/cakephp/src/Datasource/README.md +++ /dev/null @@ -1,82 +0,0 @@ -[![Total Downloads](https://img.shields.io/packagist/dt/cakephp/datasource.svg?style=flat-square)](https://packagist.org/packages/cakephp/datasource) -[![License](https://img.shields.io/badge/license-MIT-blue.svg?style=flat-square)](LICENSE.txt) - -# CakePHP Datasource Library - -This library contains interfaces for implementing Repositories and Entities using any data source, -a class for managing connections to datasources and traits to help you quickly implement the -interfaces provided by this package. - -## Repositories - -A repository is a class capable of interfacing with a data source using operations such as -`find`, `save` and `delete` by using intermediate query objects for expressing commands to -the data store and returning Entities as the single result unit of such system. - -In the case of a Relational database, a Repository would be a `Table`, which can be return single -or multiple `Entity` objects by using a `Query`. - -This library exposes the following interfaces for creating a system that implements the -repository pattern and is compatible with the CakePHP framework: - -* `RepositoryInterface` - Describes the methods for a base repository class. -* `EntityInterface` - Describes the methods for a single result object. -* `ResultSetInterface` - Represents the idea of a collection of Entities as a result of a query. - -Additionally, this package provides a few traits and classes you can use in your own implementations: - -* `EntityTrait` - Contains the default implementation for the `EntityInterface`. -* `QueryTrait` - Exposes the methods for creating a query object capable of returning decoratable collections. -* `ResultSetDecorator` - Decorates any traversable object so it complies with `ResultSetInterface`. - - -## Connections - -This library contains a couple of utility classes meant to create and manage -connection objects. Connections are typically used in repositories for -interfacing with the actual data source system. - -The `ConnectionManager` class acts as a registry to access database connections -your application has. It provides a place that other objects can get references -to existing connections. Creating connections with the `ConnectionManager` is -easy: - -```php -use Cake\Datasource\ConnectionManager; - -ConnectionManager::config('master', [ - 'className' => 'MyApp\Connections\CustomConnection', - 'param1' => 'value', - 'param2' => 'another value' -]); - -ConnectionManager::config('slave', [ - 'className' => 'MyApp\Connections\CustomConnection', - 'param1' => 'different value', - 'param2' => 'another value' -]); -``` - -When requested, the `ConnectionManager` will instantiate -`MyApp\Connections\CustomConnection` by passing `param1` and `param2` inside an -array as the first argument of the constructor. - -Once configured connections can be fetched using `ConnectionManager::get()`. -This method will construct and load a connection if it has not been built -before, or return the existing known connection: - -```php -use Cake\Datasource\ConnectionManager; -$conn = ConnectionManager::get('master'); -``` - -It is also possible to store connection objects by passing the instance directly to the manager: - -```php -use Cake\Datasource\ConnectionManager; -$conn = ConnectionManager::config('other', $connectionInstance); -``` - -## Documentation - -Please make sure you check the [official API documentation](https://api.cakephp.org/3.x/namespace-Cake.Datasource.html) diff --git a/vendor/cakephp/cakephp/src/Datasource/RepositoryInterface.php b/vendor/cakephp/cakephp/src/Datasource/RepositoryInterface.php deleted file mode 100644 index 1a15d33..0000000 --- a/vendor/cakephp/cakephp/src/Datasource/RepositoryInterface.php +++ /dev/null @@ -1,227 +0,0 @@ -get($id); - * - * $article = $articles->get($id, ['contain' => ['Comments]]); - * ``` - * - * @param mixed $primaryKey primary key value to find - * @param array|\ArrayAccess $options options accepted by `Table::find()` - * @throws \Cake\Datasource\Exception\RecordNotFoundException if the record with such id - * could not be found - * @return \Cake\Datasource\EntityInterface - * @see \Cake\Datasource\RepositoryInterface::find() - */ - public function get($primaryKey, $options = []); - - /** - * Creates a new Query instance for this repository - * - * @return \Cake\ORM\Query - */ - public function query(); - - /** - * Update all matching records. - * - * Sets the $fields to the provided values based on $conditions. - * This method will *not* trigger beforeSave/afterSave events. If you need those - * first load a collection of records and update them. - * - * @param string|array|callable|\Cake\Database\Expression\QueryExpression $fields A hash of field => new value. - * @param mixed $conditions Conditions to be used, accepts anything Query::where() - * can take. - * @return int Count Returns the affected rows. - */ - public function updateAll($fields, $conditions); - - /** - * Deletes all records matching the provided conditions. - * - * This method will *not* trigger beforeDelete/afterDelete events. If you - * need those first load a collection of records and delete them. - * - * This method will *not* execute on associations' `cascade` attribute. You should - * use database foreign keys + ON CASCADE rules if you need cascading deletes combined - * with this method. - * - * @param mixed $conditions Conditions to be used, accepts anything Query::where() - * can take. - * @return int Returns the number of affected rows. - * @see \Cake\Datasource\RepositoryInterface::delete() - */ - public function deleteAll($conditions); - - /** - * Returns true if there is any record in this repository matching the specified - * conditions. - * - * @param array|\ArrayAccess $conditions list of conditions to pass to the query - * @return bool - */ - public function exists($conditions); - - /** - * Persists an entity based on the fields that are marked as dirty and - * returns the same entity after a successful save or false in case - * of any error. - * - * @param \Cake\Datasource\EntityInterface $entity the entity to be saved - * @param array|\ArrayAccess $options The options to use when saving. - * @return \Cake\Datasource\EntityInterface|false - */ - public function save(EntityInterface $entity, $options = []); - - /** - * Delete a single entity. - * - * Deletes an entity and possibly related associations from the database - * based on the 'dependent' option used when defining the association. - * - * @param \Cake\Datasource\EntityInterface $entity The entity to remove. - * @param array|\ArrayAccess $options The options for the delete. - * @return bool success - */ - public function delete(EntityInterface $entity, $options = []); - - /** - * Create a new entity + associated entities from an array. - * - * This is most useful when hydrating request data back into entities. - * For example, in your controller code: - * - * ``` - * $article = $this->Articles->newEntity($this->request->getData()); - * ``` - * - * The hydrated entity will correctly do an insert/update based - * on the primary key data existing in the database when the entity - * is saved. Until the entity is saved, it will be a detached record. - * - * @param array|null $data The data to build an entity with. - * @param array $options A list of options for the object hydration. - * @return \Cake\Datasource\EntityInterface - */ - public function newEntity($data = null, array $options = []); - - /** - * Create a list of entities + associated entities from an array. - * - * This is most useful when hydrating request data back into entities. - * For example, in your controller code: - * - * ``` - * $articles = $this->Articles->newEntities($this->request->getData()); - * ``` - * - * The hydrated entities can then be iterated and saved. - * - * @param array $data The data to build an entity with. - * @param array $options A list of options for the objects hydration. - * @return \Cake\Datasource\EntityInterface[] An array of hydrated records. - */ - public function newEntities(array $data, array $options = []); - - /** - * Merges the passed `$data` into `$entity` respecting the accessible - * fields configured on the entity. Returns the same entity after being - * altered. - * - * This is most useful when editing an existing entity using request data: - * - * ``` - * $article = $this->Articles->patchEntity($article, $this->request->getData()); - * ``` - * - * @param \Cake\Datasource\EntityInterface $entity the entity that will get the - * data merged in - * @param array $data key value list of fields to be merged into the entity - * @param array $options A list of options for the object hydration. - * @return \Cake\Datasource\EntityInterface - */ - public function patchEntity(EntityInterface $entity, array $data, array $options = []); - - /** - * Merges each of the elements passed in `$data` into the entities - * found in `$entities` respecting the accessible fields configured on the entities. - * Merging is done by matching the primary key in each of the elements in `$data` - * and `$entities`. - * - * This is most useful when editing a list of existing entities using request data: - * - * ``` - * $article = $this->Articles->patchEntities($articles, $this->request->getData()); - * ``` - * - * @param \Cake\Datasource\EntityInterface[]|\Traversable $entities the entities that will get the - * data merged in - * @param array $data list of arrays to be merged into the entities - * @param array $options A list of options for the objects hydration. - * @return \Cake\Datasource\EntityInterface[] - */ - public function patchEntities($entities, array $data, array $options = []); -} diff --git a/vendor/cakephp/cakephp/src/Datasource/ResultSetDecorator.php b/vendor/cakephp/cakephp/src/Datasource/ResultSetDecorator.php deleted file mode 100644 index 6d6f626..0000000 --- a/vendor/cakephp/cakephp/src/Datasource/ResultSetDecorator.php +++ /dev/null @@ -1,44 +0,0 @@ -getInnerIterator() instanceof Countable) { - return $this->getInnerIterator()->count(); - } - - return count($this->toArray()); - } -} diff --git a/vendor/cakephp/cakephp/src/Datasource/ResultSetInterface.php b/vendor/cakephp/cakephp/src/Datasource/ResultSetInterface.php deleted file mode 100644 index f6166e0..0000000 --- a/vendor/cakephp/cakephp/src/Datasource/ResultSetInterface.php +++ /dev/null @@ -1,26 +0,0 @@ -rule = $rule; - $this->name = $name; - $this->options = $options; - } - - /** - * Set options for the rule invocation. - * - * Old options will be merged with the new ones. - * - * @param array $options The options to set. - * @return $this - */ - public function setOptions(array $options) - { - $this->options = $options + $this->options; - - return $this; - } - - /** - * Set the rule name. - * - * Only truthy names will be set. - * - * @param string $name The name to set. - * @return $this - */ - public function setName($name) - { - if ($name) { - $this->name = $name; - } - - return $this; - } - - /** - * Invoke the rule. - * - * @param \Cake\Datasource\EntityInterface $entity The entity the rule - * should apply to. - * @param array $scope The rule's scope/options. - * @return bool Whether or not the rule passed. - */ - public function __invoke($entity, $scope) - { - $rule = $this->rule; - $pass = $rule($entity, $this->options + $scope); - if ($pass === true || empty($this->options['errorField'])) { - return $pass === true; - } - - $message = 'invalid'; - if (isset($this->options['message'])) { - $message = $this->options['message']; - } - if (is_string($pass)) { - $message = $pass; - } - if ($this->name) { - $message = [$this->name => $message]; - } else { - $message = [$message]; - } - $errorField = $this->options['errorField']; - $entity->setError($errorField, $message); - - if ($entity instanceof InvalidPropertyInterface && isset($entity->{$errorField})) { - $invalidValue = $entity->{$errorField}; - $entity->setInvalidField($errorField, $invalidValue); - } - - return $pass === true; - } -} diff --git a/vendor/cakephp/cakephp/src/Datasource/RulesAwareTrait.php b/vendor/cakephp/cakephp/src/Datasource/RulesAwareTrait.php deleted file mode 100644 index 98c161d..0000000 --- a/vendor/cakephp/cakephp/src/Datasource/RulesAwareTrait.php +++ /dev/null @@ -1,117 +0,0 @@ -rulesChecker(); - $options = $options ?: new ArrayObject(); - $options = is_array($options) ? new ArrayObject($options) : $options; - $hasEvents = ($this instanceof EventDispatcherInterface); - - if ($hasEvents) { - $event = $this->dispatchEvent( - 'Model.beforeRules', - compact('entity', 'options', 'operation') - ); - if ($event->isStopped()) { - return $event->getResult(); - } - } - - $result = $rules->check($entity, $operation, $options->getArrayCopy()); - - if ($hasEvents) { - $event = $this->dispatchEvent( - 'Model.afterRules', - compact('entity', 'options', 'result', 'operation') - ); - - if ($event->isStopped()) { - return $event->getResult(); - } - } - - return $result; - } - - /** - * Returns the RulesChecker for this instance. - * - * A RulesChecker object is used to test an entity for validity - * on rules that may involve complex logic or data that - * needs to be fetched from relevant datasources. - * - * @see \Cake\Datasource\RulesChecker - * @return \Cake\Datasource\RulesChecker - */ - public function rulesChecker() - { - if ($this->_rulesChecker !== null) { - return $this->_rulesChecker; - } - $class = defined('static::RULES_CLASS') ? static::RULES_CLASS : 'Cake\Datasource\RulesChecker'; - $this->_rulesChecker = $this->buildRules(new $class(['repository' => $this])); - $this->dispatchEvent('Model.buildRules', ['rules' => $this->_rulesChecker]); - - return $this->_rulesChecker; - } - - /** - * Returns a RulesChecker object after modifying the one that was supplied. - * - * Subclasses should override this method in order to initialize the rules to be applied to - * entities saved by this instance. - * - * @param \Cake\Datasource\RulesChecker $rules The rules object to be modified. - * @return \Cake\Datasource\RulesChecker - */ - public function buildRules(RulesChecker $rules) - { - return $rules; - } -} diff --git a/vendor/cakephp/cakephp/src/Datasource/RulesChecker.php b/vendor/cakephp/cakephp/src/Datasource/RulesChecker.php deleted file mode 100644 index f0bfede..0000000 --- a/vendor/cakephp/cakephp/src/Datasource/RulesChecker.php +++ /dev/null @@ -1,328 +0,0 @@ -_options = $options; - $this->_useI18n = function_exists('__d'); - } - - /** - * Adds a rule that will be applied to the entity both on create and update - * operations. - * - * ### Options - * - * The options array accept the following special keys: - * - * - `errorField`: The name of the entity field that will be marked as invalid - * if the rule does not pass. - * - `message`: The error message to set to `errorField` if the rule does not pass. - * - * @param callable $rule A callable function or object that will return whether - * the entity is valid or not. - * @param string|null $name The alias for a rule. - * @param array $options List of extra options to pass to the rule callable as - * second argument. - * @return $this - */ - public function add(callable $rule, $name = null, array $options = []) - { - $this->_rules[] = $this->_addError($rule, $name, $options); - - return $this; - } - - /** - * Adds a rule that will be applied to the entity on create operations. - * - * ### Options - * - * The options array accept the following special keys: - * - * - `errorField`: The name of the entity field that will be marked as invalid - * if the rule does not pass. - * - `message`: The error message to set to `errorField` if the rule does not pass. - * - * @param callable $rule A callable function or object that will return whether - * the entity is valid or not. - * @param string|null $name The alias for a rule. - * @param array $options List of extra options to pass to the rule callable as - * second argument. - * @return $this - */ - public function addCreate(callable $rule, $name = null, array $options = []) - { - $this->_createRules[] = $this->_addError($rule, $name, $options); - - return $this; - } - - /** - * Adds a rule that will be applied to the entity on update operations. - * - * ### Options - * - * The options array accept the following special keys: - * - * - `errorField`: The name of the entity field that will be marked as invalid - * if the rule does not pass. - * - `message`: The error message to set to `errorField` if the rule does not pass. - * - * @param callable $rule A callable function or object that will return whether - * the entity is valid or not. - * @param string|null $name The alias for a rule. - * @param array $options List of extra options to pass to the rule callable as - * second argument. - * @return $this - */ - public function addUpdate(callable $rule, $name = null, array $options = []) - { - $this->_updateRules[] = $this->_addError($rule, $name, $options); - - return $this; - } - - /** - * Adds a rule that will be applied to the entity on delete operations. - * - * ### Options - * - * The options array accept the following special keys: - * - * - `errorField`: The name of the entity field that will be marked as invalid - * if the rule does not pass. - * - `message`: The error message to set to `errorField` if the rule does not pass. - * - * @param callable $rule A callable function or object that will return whether - * the entity is valid or not. - * @param string|null $name The alias for a rule. - * @param array $options List of extra options to pass to the rule callable as - * second argument. - * @return $this - */ - public function addDelete(callable $rule, $name = null, array $options = []) - { - $this->_deleteRules[] = $this->_addError($rule, $name, $options); - - return $this; - } - - /** - * Runs each of the rules by passing the provided entity and returns true if all - * of them pass. The rules to be applied are depended on the $mode parameter which - * can only be RulesChecker::CREATE, RulesChecker::UPDATE or RulesChecker::DELETE - * - * @param \Cake\Datasource\EntityInterface $entity The entity to check for validity. - * @param string $mode Either 'create, 'update' or 'delete'. - * @param array $options Extra options to pass to checker functions. - * @return bool - * @throws \InvalidArgumentException if an invalid mode is passed. - */ - public function check(EntityInterface $entity, $mode, array $options = []) - { - if ($mode === self::CREATE) { - return $this->checkCreate($entity, $options); - } - - if ($mode === self::UPDATE) { - return $this->checkUpdate($entity, $options); - } - - if ($mode === self::DELETE) { - return $this->checkDelete($entity, $options); - } - - throw new InvalidArgumentException('Wrong checking mode: ' . $mode); - } - - /** - * Runs each of the rules by passing the provided entity and returns true if all - * of them pass. The rules selected will be only those specified to be run on 'create' - * - * @param \Cake\Datasource\EntityInterface $entity The entity to check for validity. - * @param array $options Extra options to pass to checker functions. - * @return bool - */ - public function checkCreate(EntityInterface $entity, array $options = []) - { - return $this->_checkRules($entity, $options, array_merge($this->_rules, $this->_createRules)); - } - - /** - * Runs each of the rules by passing the provided entity and returns true if all - * of them pass. The rules selected will be only those specified to be run on 'update' - * - * @param \Cake\Datasource\EntityInterface $entity The entity to check for validity. - * @param array $options Extra options to pass to checker functions. - * @return bool - */ - public function checkUpdate(EntityInterface $entity, array $options = []) - { - return $this->_checkRules($entity, $options, array_merge($this->_rules, $this->_updateRules)); - } - - /** - * Runs each of the rules by passing the provided entity and returns true if all - * of them pass. The rules selected will be only those specified to be run on 'delete' - * - * @param \Cake\Datasource\EntityInterface $entity The entity to check for validity. - * @param array $options Extra options to pass to checker functions. - * @return bool - */ - public function checkDelete(EntityInterface $entity, array $options = []) - { - return $this->_checkRules($entity, $options, $this->_deleteRules); - } - - /** - * Used by top level functions checkDelete, checkCreate and checkUpdate, this function - * iterates an array containing the rules to be checked and checks them all. - * - * @param \Cake\Datasource\EntityInterface $entity The entity to check for validity. - * @param array $options Extra options to pass to checker functions. - * @param array $rules The list of rules that must be checked. - * @return bool - */ - protected function _checkRules(EntityInterface $entity, array $options = [], array $rules = []) - { - $success = true; - $options += $this->_options; - foreach ($rules as $rule) { - $success = $rule($entity, $options) && $success; - } - - return $success; - } - - /** - * Utility method for decorating any callable so that if it returns false, the correct - * property in the entity is marked as invalid. - * - * @param callable $rule The rule to decorate - * @param string $name The alias for a rule. - * @param array $options The options containing the error message and field. - * @return callable - */ - protected function _addError($rule, $name, $options) - { - if (is_array($name)) { - $options = $name; - $name = null; - } - - if (!($rule instanceof RuleInvoker)) { - $rule = new RuleInvoker($rule, $name, $options); - } else { - $rule->setOptions($options)->setName($name); - } - - return $rule; - } -} diff --git a/vendor/cakephp/cakephp/src/Datasource/TableSchemaInterface.php b/vendor/cakephp/cakephp/src/Datasource/TableSchemaInterface.php deleted file mode 100644 index 90b7817..0000000 --- a/vendor/cakephp/cakephp/src/Datasource/TableSchemaInterface.php +++ /dev/null @@ -1,35 +0,0 @@ -=5.6.0", - "cakephp/core": "^3.6.0" - }, - "suggest": { - "cakephp/utility": "If you decide to use EntityTrait.", - "cakephp/collection": "If you decide to use ResultSetInterface.", - "cakephp/cache": "If you decide to use Query caching." - }, - "autoload": { - "psr-4": { - "Cake\\Datasource\\": "." - } - } -} diff --git a/vendor/cakephp/cakephp/src/Error/BaseErrorHandler.php b/vendor/cakephp/cakephp/src/Error/BaseErrorHandler.php deleted file mode 100644 index c4585e7..0000000 --- a/vendor/cakephp/cakephp/src/Error/BaseErrorHandler.php +++ /dev/null @@ -1,421 +0,0 @@ -_options['errorLevel'])) { - $level = $this->_options['errorLevel']; - } - error_reporting($level); - set_error_handler([$this, 'handleError'], $level); - set_exception_handler([$this, 'wrapAndHandleException']); - register_shutdown_function(function () { - if (PHP_SAPI === 'cli' || PHP_SAPI === 'phpdbg') { - return; - } - $megabytes = Configure::read('Error.extraFatalErrorMemory'); - if ($megabytes === null) { - $megabytes = 4; - } - if ($megabytes > 0) { - $this->increaseMemoryLimit($megabytes * 1024); - } - $error = error_get_last(); - if (!is_array($error)) { - return; - } - $fatals = [ - E_USER_ERROR, - E_ERROR, - E_PARSE, - ]; - if (!in_array($error['type'], $fatals, true)) { - return; - } - $this->handleFatalError( - $error['type'], - $error['message'], - $error['file'], - $error['line'] - ); - }); - } - - /** - * Set as the default error handler by CakePHP. - * - * Use config/error.php to customize or replace this error handler. - * This function will use Debugger to display errors when debug > 0. And - * will log errors to Log, when debug == 0. - * - * You can use the 'errorLevel' option to set what type of errors will be handled. - * Stack traces for errors can be enabled with the 'trace' option. - * - * @param int $code Code of error - * @param string $description Error description - * @param string|null $file File on which error occurred - * @param int|null $line Line that triggered the error - * @param array|null $context Context - * @return bool True if error was handled - */ - public function handleError($code, $description, $file = null, $line = null, $context = null) - { - if (error_reporting() === 0) { - return false; - } - list($error, $log) = static::mapErrorCode($code); - if ($log === LOG_ERR) { - return $this->handleFatalError($code, $description, $file, $line); - } - $data = [ - 'level' => $log, - 'code' => $code, - 'error' => $error, - 'description' => $description, - 'file' => $file, - 'line' => $line, - ]; - - $debug = Configure::read('debug'); - if ($debug) { - $data += [ - 'context' => $context, - 'start' => 3, - 'path' => Debugger::trimPath($file) - ]; - } - $this->_displayError($data, $debug); - $this->_logError($log, $data); - - return true; - } - - /** - * Checks the passed exception type. If it is an instance of `Error` - * then, it wraps the passed object inside another Exception object - * for backwards compatibility purposes. - * - * @param \Exception|\Error $exception The exception to handle - * @return void - */ - public function wrapAndHandleException($exception) - { - if ($exception instanceof Error) { - $exception = new PHP7ErrorException($exception); - } - $this->handleException($exception); - } - - /** - * Handle uncaught exceptions. - * - * Uses a template method provided by subclasses to display errors in an - * environment appropriate way. - * - * @param \Exception $exception Exception instance. - * @return void - * @throws \Exception When renderer class not found - * @see https://secure.php.net/manual/en/function.set-exception-handler.php - */ - public function handleException(Exception $exception) - { - $this->_displayException($exception); - $this->_logException($exception); - $this->_stop($exception->getCode() ?: 1); - } - - /** - * Stop the process. - * - * Implemented in subclasses that need it. - * - * @param int $code Exit code. - * @return void - */ - protected function _stop($code) - { - // Do nothing. - } - - /** - * Display/Log a fatal error. - * - * @param int $code Code of error - * @param string $description Error description - * @param string $file File on which error occurred - * @param int $line Line that triggered the error - * @return bool - */ - public function handleFatalError($code, $description, $file, $line) - { - $data = [ - 'code' => $code, - 'description' => $description, - 'file' => $file, - 'line' => $line, - 'error' => 'Fatal Error', - ]; - $this->_logError(LOG_ERR, $data); - - $this->handleException(new FatalErrorException($description, 500, $file, $line)); - - return true; - } - - /** - * Increases the PHP "memory_limit" ini setting by the specified amount - * in kilobytes - * - * @param int $additionalKb Number in kilobytes - * @return void - */ - public function increaseMemoryLimit($additionalKb) - { - $limit = ini_get('memory_limit'); - if (!strlen($limit) || $limit === '-1') { - return; - } - $limit = trim($limit); - $units = strtoupper(substr($limit, -1)); - $current = (int)substr($limit, 0, strlen($limit) - 1); - if ($units === 'M') { - $current *= 1024; - $units = 'K'; - } - if ($units === 'G') { - $current = $current * 1024 * 1024; - $units = 'K'; - } - - if ($units === 'K') { - ini_set('memory_limit', ceil($current + $additionalKb) . 'K'); - } - } - - /** - * Log an error. - * - * @param string $level The level name of the log. - * @param array $data Array of error data. - * @return bool - */ - protected function _logError($level, $data) - { - $message = sprintf( - '%s (%s): %s in [%s, line %s]', - $data['error'], - $data['code'], - $data['description'], - $data['file'], - $data['line'] - ); - if (!empty($this->_options['trace'])) { - $trace = Debugger::trace([ - 'start' => 1, - 'format' => 'log' - ]); - - $request = Router::getRequest(); - if ($request) { - $message .= $this->_requestContext($request); - } - $message .= "\nTrace:\n" . $trace . "\n"; - } - $message .= "\n\n"; - - return Log::write($level, $message); - } - - /** - * Handles exception logging - * - * @param \Exception $exception Exception instance. - * @return bool - */ - protected function _logException(Exception $exception) - { - $config = $this->_options; - $unwrapped = $exception instanceof PHP7ErrorException ? - $exception->getError() : - $exception; - - if (empty($config['log'])) { - return false; - } - - if (!empty($config['skipLog'])) { - foreach ((array)$config['skipLog'] as $class) { - if ($unwrapped instanceof $class) { - return false; - } - } - } - - return Log::error($this->_getMessage($exception)); - } - - /** - * Get the request context for an error/exception trace. - * - * @param \Cake\Http\ServerRequest $request The request to read from. - * @return string - */ - protected function _requestContext($request) - { - $message = "\nRequest URL: " . $request->getRequestTarget(); - - $referer = $request->getEnv('HTTP_REFERER'); - if ($referer) { - $message .= "\nReferer URL: " . $referer; - } - $clientIp = $request->clientIp(); - if ($clientIp && $clientIp !== '::1') { - $message .= "\nClient IP: " . $clientIp; - } - - return $message; - } - - /** - * Generates a formatted error message - * - * @param \Exception $exception Exception instance - * @return string Formatted message - */ - protected function _getMessage(Exception $exception) - { - $exception = $exception instanceof PHP7ErrorException ? - $exception->getError() : - $exception; - $config = $this->_options; - $message = sprintf( - '[%s] %s in %s on line %s', - get_class($exception), - $exception->getMessage(), - $exception->getFile(), - $exception->getLine() - ); - $debug = Configure::read('debug'); - - if ($debug && method_exists($exception, 'getAttributes')) { - $attributes = $exception->getAttributes(); - if ($attributes) { - $message .= "\nException Attributes: " . var_export($exception->getAttributes(), true); - } - } - - $request = Router::getRequest(); - if ($request) { - $message .= $this->_requestContext($request); - } - - if (!empty($config['trace'])) { - $message .= "\nStack Trace:\n" . $exception->getTraceAsString() . "\n\n"; - } - - return $message; - } - - /** - * Map an error code into an Error word, and log location. - * - * @param int $code Error code to map - * @return array Array of error word, and log location. - */ - public static function mapErrorCode($code) - { - $levelMap = [ - E_PARSE => 'error', - E_ERROR => 'error', - E_CORE_ERROR => 'error', - E_COMPILE_ERROR => 'error', - E_USER_ERROR => 'error', - E_WARNING => 'warning', - E_USER_WARNING => 'warning', - E_COMPILE_WARNING => 'warning', - E_RECOVERABLE_ERROR => 'warning', - E_NOTICE => 'notice', - E_USER_NOTICE => 'notice', - E_STRICT => 'strict', - E_DEPRECATED => 'deprecated', - E_USER_DEPRECATED => 'deprecated', - ]; - $logMap = [ - 'error' => LOG_ERR, - 'warning' => LOG_WARNING, - 'notice' => LOG_NOTICE, - 'strict' => LOG_NOTICE, - 'deprecated' => LOG_NOTICE, - ]; - - $error = $levelMap[$code]; - $log = $logMap[$error]; - - return [ucfirst($error), $log]; - } -} diff --git a/vendor/cakephp/cakephp/src/Error/Debugger.php b/vendor/cakephp/cakephp/src/Error/Debugger.php deleted file mode 100644 index 8819476..0000000 --- a/vendor/cakephp/cakephp/src/Error/Debugger.php +++ /dev/null @@ -1,966 +0,0 @@ - [] - ]; - - /** - * A list of errors generated by the application. - * - * @var array - */ - public $errors = []; - - /** - * The current output format. - * - * @var string - */ - protected $_outputFormat = 'js'; - - /** - * Templates used when generating trace or error strings. Can be global or indexed by the format - * value used in $_outputFormat. - * - * @var array - */ - protected $_templates = [ - 'log' => [ - 'trace' => '{:reference} - {:path}, line {:line}', - 'error' => '{:error} ({:code}): {:description} in [{:file}, line {:line}]' - ], - 'js' => [ - 'error' => '', - 'info' => '', - 'trace' => '
{:trace}
', - 'code' => '', - 'context' => '', - 'links' => [], - 'escapeContext' => true, - ], - 'html' => [ - 'trace' => '
Trace 

{:trace}

', - 'context' => '
Context 

{:context}

', - 'escapeContext' => true, - ], - 'txt' => [ - 'error' => "{:error}: {:code} :: {:description} on line {:line} of {:path}\n{:info}", - 'code' => '', - 'info' => '' - ], - 'base' => [ - 'traceLine' => '{:reference} - {:path}, line {:line}', - 'trace' => "Trace:\n{:trace}\n", - 'context' => "Context:\n{:context}\n", - ] - ]; - - /** - * Holds current output data when outputFormat is false. - * - * @var array - */ - protected $_data = []; - - /** - * Constructor. - * - */ - public function __construct() - { - $docRef = ini_get('docref_root'); - - if (empty($docRef) && function_exists('ini_set')) { - ini_set('docref_root', 'https://secure.php.net/'); - } - if (!defined('E_RECOVERABLE_ERROR')) { - define('E_RECOVERABLE_ERROR', 4096); - } - - $e = '
';
-        $e .= '{:error} ({:code}): {:description} ';
-        $e .= '[{:path}, line {:line}]';
-
-        $e .= '';
-        $e .= '
'; - $this->_templates['js']['error'] = $e; - - $t = ''; - $this->_templates['js']['info'] = $t; - - $links = []; - $link = 'Code'; - $links['code'] = $link; - - $link = 'Context'; - $links['context'] = $link; - - $this->_templates['js']['links'] = $links; - - $this->_templates['js']['context'] = '
_templates['js']['context'] .= 'style="display: none;">{:context}
'; - - $this->_templates['js']['code'] = '
_templates['js']['code'] .= 'style="display: none;">{:code}
'; - - $e = '
{:error} ({:code}) : {:description} ';
-        $e .= '[{:path}, line {:line}]
'; - $this->_templates['html']['error'] = $e; - - $this->_templates['html']['context'] = '
Context ';
-        $this->_templates['html']['context'] .= '

{:context}

'; - } - - /** - * Returns a reference to the Debugger singleton object instance. - * - * @param string|null $class Class name. - * @return \Cake\Error\Debugger - */ - public static function getInstance($class = null) - { - static $instance = []; - if (!empty($class)) { - if (!$instance || strtolower($class) !== strtolower(get_class($instance[0]))) { - $instance[0] = new $class(); - } - } - if (!$instance) { - $instance[0] = new Debugger(); - } - - return $instance[0]; - } - - /** - * Read or write configuration options for the Debugger instance. - * - * @param string|array|null $key The key to get/set, or a complete array of configs. - * @param mixed|null $value The value to set. - * @param bool $merge Whether to recursively merge or overwrite existing config, defaults to true. - * @return mixed Config value being read, or the object itself on write operations. - * @throws \Cake\Core\Exception\Exception When trying to set a key that is invalid. - */ - public static function configInstance($key = null, $value = null, $merge = true) - { - if (is_array($key) || func_num_args() >= 2) { - return static::getInstance()->setConfig($key, $value, $merge); - } - - return static::getInstance()->getConfig($key); - } - - /** - * Reads the current output masking. - * - * @return array - */ - public static function outputMask() - { - return static::configInstance('outputMask'); - } - - /** - * Sets configurable masking of debugger output by property name and array key names. - * - * ### Example - * - * Debugger::setOutputMask(['password' => '[*************]'); - * - * @param array $value An array where keys are replaced by their values in output. - * @param bool $merge Whether to recursively merge or overwrite existing config, defaults to true. - * @return void - */ - public static function setOutputMask(array $value, $merge = true) - { - static::configInstance('outputMask', $value, $merge); - } - - /** - * Recursively formats and outputs the contents of the supplied variable. - * - * @param mixed $var The variable to dump. - * @param int $depth The depth to output to. Defaults to 3. - * @return void - * @see \Cake\Error\Debugger::exportVar() - * @link https://book.cakephp.org/3.0/en/development/debugging.html#outputting-values - */ - public static function dump($var, $depth = 3) - { - pr(static::exportVar($var, $depth)); - } - - /** - * Creates an entry in the log file. The log entry will contain a stack trace from where it was called. - * as well as export the variable using exportVar. By default the log is written to the debug log. - * - * @param mixed $var Variable or content to log. - * @param int|string $level Type of log to use. Defaults to 'debug'. - * @param int $depth The depth to output to. Defaults to 3. - * @return void - */ - public static function log($var, $level = 'debug', $depth = 3) - { - $source = static::trace(['start' => 1]) . "\n"; - Log::write($level, "\n" . $source . static::exportVar($var, $depth)); - } - - /** - * Outputs a stack trace based on the supplied options. - * - * ### Options - * - * - `depth` - The number of stack frames to return. Defaults to 999 - * - `format` - The format you want the return. Defaults to the currently selected format. If - * format is 'array' or 'points' the return will be an array. - * - `args` - Should arguments for functions be shown? If true, the arguments for each method call - * will be displayed. - * - `start` - The stack frame to start generating a trace from. Defaults to 0 - * - * @param array $options Format for outputting stack trace. - * @return mixed Formatted stack trace. - * @link https://book.cakephp.org/3.0/en/development/debugging.html#generating-stack-traces - */ - public static function trace(array $options = []) - { - return Debugger::formatTrace(debug_backtrace(), $options); - } - - /** - * Formats a stack trace based on the supplied options. - * - * ### Options - * - * - `depth` - The number of stack frames to return. Defaults to 999 - * - `format` - The format you want the return. Defaults to the currently selected format. If - * format is 'array' or 'points' the return will be an array. - * - `args` - Should arguments for functions be shown? If true, the arguments for each method call - * will be displayed. - * - `start` - The stack frame to start generating a trace from. Defaults to 0 - * - * @param array|\Exception $backtrace Trace as array or an exception object. - * @param array $options Format for outputting stack trace. - * @return mixed Formatted stack trace. - * @link https://book.cakephp.org/3.0/en/development/debugging.html#generating-stack-traces - */ - public static function formatTrace($backtrace, $options = []) - { - if ($backtrace instanceof Exception) { - $backtrace = $backtrace->getTrace(); - } - $self = Debugger::getInstance(); - $defaults = [ - 'depth' => 999, - 'format' => $self->_outputFormat, - 'args' => false, - 'start' => 0, - 'scope' => null, - 'exclude' => ['call_user_func_array', 'trigger_error'] - ]; - $options = Hash::merge($defaults, $options); - - $count = count($backtrace); - $back = []; - - $_trace = [ - 'line' => '??', - 'file' => '[internal]', - 'class' => null, - 'function' => '[main]' - ]; - - for ($i = $options['start']; $i < $count && $i < $options['depth']; $i++) { - $trace = $backtrace[$i] + ['file' => '[internal]', 'line' => '??']; - $signature = $reference = '[main]'; - - if (isset($backtrace[$i + 1])) { - $next = $backtrace[$i + 1] + $_trace; - $signature = $reference = $next['function']; - - if (!empty($next['class'])) { - $signature = $next['class'] . '::' . $next['function']; - $reference = $signature . '('; - if ($options['args'] && isset($next['args'])) { - $args = []; - foreach ($next['args'] as $arg) { - $args[] = Debugger::exportVar($arg); - } - $reference .= implode(', ', $args); - } - $reference .= ')'; - } - } - if (in_array($signature, $options['exclude'])) { - continue; - } - if ($options['format'] === 'points' && $trace['file'] !== '[internal]') { - $back[] = ['file' => $trace['file'], 'line' => $trace['line']]; - } elseif ($options['format'] === 'array') { - $back[] = $trace; - } else { - if (isset($self->_templates[$options['format']]['traceLine'])) { - $tpl = $self->_templates[$options['format']]['traceLine']; - } else { - $tpl = $self->_templates['base']['traceLine']; - } - $trace['path'] = static::trimPath($trace['file']); - $trace['reference'] = $reference; - unset($trace['object'], $trace['args']); - $back[] = Text::insert($tpl, $trace, ['before' => '{:', 'after' => '}']); - } - } - - if ($options['format'] === 'array' || $options['format'] === 'points') { - return $back; - } - - return implode("\n", $back); - } - - /** - * Shortens file paths by replacing the application base path with 'APP', and the CakePHP core - * path with 'CORE'. - * - * @param string $path Path to shorten. - * @return string Normalized path - */ - public static function trimPath($path) - { - if (defined('APP') && strpos($path, APP) === 0) { - return str_replace(APP, 'APP/', $path); - } - if (defined('CAKE_CORE_INCLUDE_PATH') && strpos($path, CAKE_CORE_INCLUDE_PATH) === 0) { - return str_replace(CAKE_CORE_INCLUDE_PATH, 'CORE', $path); - } - if (defined('ROOT') && strpos($path, ROOT) === 0) { - return str_replace(ROOT, 'ROOT', $path); - } - - return $path; - } - - /** - * Grabs an excerpt from a file and highlights a given line of code. - * - * Usage: - * - * ``` - * Debugger::excerpt('/path/to/file', 100, 4); - * ``` - * - * The above would return an array of 8 items. The 4th item would be the provided line, - * and would be wrapped in ``. All of the lines - * are processed with highlight_string() as well, so they have basic PHP syntax highlighting - * applied. - * - * @param string $file Absolute path to a PHP file. - * @param int $line Line number to highlight. - * @param int $context Number of lines of context to extract above and below $line. - * @return array Set of lines highlighted - * @see https://secure.php.net/highlight_string - * @link https://book.cakephp.org/3.0/en/development/debugging.html#getting-an-excerpt-from-a-file - */ - public static function excerpt($file, $line, $context = 2) - { - $lines = []; - if (!file_exists($file)) { - return []; - } - $data = file_get_contents($file); - if (empty($data)) { - return $lines; - } - if (strpos($data, "\n") !== false) { - $data = explode("\n", $data); - } - $line--; - if (!isset($data[$line])) { - return $lines; - } - for ($i = $line - $context; $i < $line + $context + 1; $i++) { - if (!isset($data[$i])) { - continue; - } - $string = str_replace(["\r\n", "\n"], '', static::_highlight($data[$i])); - if ($i == $line) { - $lines[] = '' . $string . ''; - } else { - $lines[] = $string; - } - } - - return $lines; - } - - /** - * Wraps the highlight_string function in case the server API does not - * implement the function as it is the case of the HipHop interpreter - * - * @param string $str The string to convert. - * @return string - */ - protected static function _highlight($str) - { - if (function_exists('hphp_log') || function_exists('hphp_gettid')) { - return htmlentities($str); - } - $added = false; - if (strpos($str, '', '<?php 
'], - '', - $highlight - ); - } - - return $highlight; - } - - /** - * Converts a variable to a string for debug output. - * - * *Note:* The following keys will have their contents - * replaced with `*****`: - * - * - password - * - login - * - host - * - database - * - port - * - prefix - * - schema - * - * This is done to protect database credentials, which could be accidentally - * shown in an error message if CakePHP is deployed in development mode. - * - * @param string $var Variable to convert. - * @param int $depth The depth to output to. Defaults to 3. - * @return string Variable as a formatted string - */ - public static function exportVar($var, $depth = 3) - { - return static::_export($var, $depth, 0); - } - - /** - * Protected export function used to keep track of indentation and recursion. - * - * @param mixed $var The variable to dump. - * @param int $depth The remaining depth. - * @param int $indent The current indentation level. - * @return string The dumped variable. - */ - protected static function _export($var, $depth, $indent) - { - switch (static::getType($var)) { - case 'boolean': - return $var ? 'true' : 'false'; - case 'integer': - return '(int) ' . $var; - case 'float': - return '(float) ' . $var; - case 'string': - if (trim($var) === '' && ctype_space($var) === false) { - return "''"; - } - - return "'" . $var . "'"; - case 'array': - return static::_array($var, $depth - 1, $indent + 1); - case 'resource': - return strtolower(gettype($var)); - case 'null': - return 'null'; - case 'unknown': - return 'unknown'; - default: - return static::_object($var, $depth - 1, $indent + 1); - } - } - - /** - * Export an array type object. Filters out keys used in datasource configuration. - * - * The following keys are replaced with ***'s - * - * - password - * - login - * - host - * - database - * - port - * - prefix - * - schema - * - * @param array $var The array to export. - * @param int $depth The current depth, used for recursion tracking. - * @param int $indent The current indentation level. - * @return string Exported array. - */ - protected static function _array(array $var, $depth, $indent) - { - $out = '['; - $break = $end = null; - if (!empty($var)) { - $break = "\n" . str_repeat("\t", $indent); - $end = "\n" . str_repeat("\t", $indent - 1); - } - $vars = []; - - if ($depth >= 0) { - $outputMask = (array)static::outputMask(); - foreach ($var as $key => $val) { - // Sniff for globals as !== explodes in < 5.4 - if ($key === 'GLOBALS' && is_array($val) && isset($val['GLOBALS'])) { - $val = '[recursion]'; - } elseif (array_key_exists($key, $outputMask)) { - $val = (string)$outputMask[$key]; - } elseif ($val !== $var) { - $val = static::_export($val, $depth, $indent); - } - $vars[] = $break . static::exportVar($key) . - ' => ' . - $val; - } - } else { - $vars[] = $break . '[maximum depth reached]'; - } - - return $out . implode(',', $vars) . $end . ']'; - } - - /** - * Handles object to string conversion. - * - * @param object $var Object to convert. - * @param int $depth The current depth, used for tracking recursion. - * @param int $indent The current indentation level. - * @return string - * @see \Cake\Error\Debugger::exportVar() - */ - protected static function _object($var, $depth, $indent) - { - $out = ''; - $props = []; - - $className = get_class($var); - $out .= 'object(' . $className . ') {'; - $break = "\n" . str_repeat("\t", $indent); - $end = "\n" . str_repeat("\t", $indent - 1); - - if ($depth > 0 && method_exists($var, '__debugInfo')) { - try { - return $out . "\n" . - substr(static::_array($var->__debugInfo(), $depth - 1, $indent), 1, -1) . - $end . '}'; - } catch (Exception $e) { - $message = $e->getMessage(); - - return $out . "\n(unable to export object: $message)\n }"; - } - } - - if ($depth > 0) { - $outputMask = (array)static::outputMask(); - $objectVars = get_object_vars($var); - foreach ($objectVars as $key => $value) { - $value = array_key_exists($key, $outputMask) ? $outputMask[$key] : static::_export($value, $depth - 1, $indent); - $props[] = "$key => " . $value; - } - - $ref = new ReflectionObject($var); - - $filters = [ - ReflectionProperty::IS_PROTECTED => 'protected', - ReflectionProperty::IS_PRIVATE => 'private', - ]; - foreach ($filters as $filter => $visibility) { - $reflectionProperties = $ref->getProperties($filter); - foreach ($reflectionProperties as $reflectionProperty) { - $reflectionProperty->setAccessible(true); - $property = $reflectionProperty->getValue($var); - - $value = static::_export($property, $depth - 1, $indent); - $key = $reflectionProperty->name; - $props[] = sprintf( - '[%s] %s => %s', - $visibility, - $key, - array_key_exists($key, $outputMask) ? $outputMask[$key] : $value - ); - } - } - - $out .= $break . implode($break, $props) . $end; - } - $out .= '}'; - - return $out; - } - - /** - * Get the output format for Debugger error rendering. - * - * @return string Returns the current format when getting. - */ - public static function getOutputFormat() - { - return Debugger::getInstance()->_outputFormat; - } - - /** - * Set the output format for Debugger error rendering. - * - * @param string $format The format you want errors to be output as. - * @return void - * @throws \InvalidArgumentException When choosing a format that doesn't exist. - */ - public static function setOutputFormat($format) - { - $self = Debugger::getInstance(); - - if (!isset($self->_templates[$format])) { - throw new InvalidArgumentException('Invalid Debugger output format.'); - } - $self->_outputFormat = $format; - } - - /** - * Get/Set the output format for Debugger error rendering. - * - * @deprecated 3.5.0 Use getOutputFormat()/setOutputFormat() instead. - * @param string|null $format The format you want errors to be output as. - * Leave null to get the current format. - * @return string|null Returns null when setting. Returns the current format when getting. - * @throws \InvalidArgumentException When choosing a format that doesn't exist. - */ - public static function outputAs($format = null) - { - deprecationWarning( - 'Debugger::outputAs() is deprecated. Use Debugger::getOutputFormat()/setOutputFormat() instead.' - ); - $self = Debugger::getInstance(); - if ($format === null) { - return $self->_outputFormat; - } - - if (!isset($self->_templates[$format])) { - throw new InvalidArgumentException('Invalid Debugger output format.'); - } - $self->_outputFormat = $format; - - return null; - } - - /** - * Add an output format or update a format in Debugger. - * - * ``` - * Debugger::addFormat('custom', $data); - * ``` - * - * Where $data is an array of strings that use Text::insert() variable - * replacement. The template vars should be in a `{:id}` style. - * An error formatter can have the following keys: - * - * - 'error' - Used for the container for the error message. Gets the following template - * variables: `id`, `error`, `code`, `description`, `path`, `line`, `links`, `info` - * - 'info' - A combination of `code`, `context` and `trace`. Will be set with - * the contents of the other template keys. - * - 'trace' - The container for a stack trace. Gets the following template - * variables: `trace` - * - 'context' - The container element for the context variables. - * Gets the following templates: `id`, `context` - * - 'links' - An array of HTML links that are used for creating links to other resources. - * Typically this is used to create javascript links to open other sections. - * Link keys, are: `code`, `context`, `help`. See the js output format for an - * example. - * - 'traceLine' - Used for creating lines in the stacktrace. Gets the following - * template variables: `reference`, `path`, `line` - * - * Alternatively if you want to use a custom callback to do all the formatting, you can use - * the callback key, and provide a callable: - * - * ``` - * Debugger::addFormat('custom', ['callback' => [$foo, 'outputError']]; - * ``` - * - * The callback can expect two parameters. The first is an array of all - * the error data. The second contains the formatted strings generated using - * the other template strings. Keys like `info`, `links`, `code`, `context` and `trace` - * will be present depending on the other templates in the format type. - * - * @param string $format Format to use, including 'js' for JavaScript-enhanced HTML, 'html' for - * straight HTML output, or 'txt' for unformatted text. - * @param array $strings Template strings, or a callback to be used for the output format. - * @return array The resulting format string set. - */ - public static function addFormat($format, array $strings) - { - $self = Debugger::getInstance(); - if (isset($self->_templates[$format])) { - if (isset($strings['links'])) { - $self->_templates[$format]['links'] = array_merge( - $self->_templates[$format]['links'], - $strings['links'] - ); - unset($strings['links']); - } - $self->_templates[$format] = $strings + $self->_templates[$format]; - } else { - $self->_templates[$format] = $strings; - } - - return $self->_templates[$format]; - } - - /** - * Takes a processed array of data from an error and displays it in the chosen format. - * - * @param array $data Data to output. - * @return void - */ - public function outputError($data) - { - $defaults = [ - 'level' => 0, - 'error' => 0, - 'code' => 0, - 'description' => '', - 'file' => '', - 'line' => 0, - 'context' => [], - 'start' => 2, - ]; - $data += $defaults; - - $files = static::trace(['start' => $data['start'], 'format' => 'points']); - $code = ''; - $file = null; - if (isset($files[0]['file'])) { - $file = $files[0]; - } elseif (isset($files[1]['file'])) { - $file = $files[1]; - } - if ($file) { - $code = static::excerpt($file['file'], $file['line'], 1); - } - $trace = static::trace(['start' => $data['start'], 'depth' => '20']); - $insertOpts = ['before' => '{:', 'after' => '}']; - $context = []; - $links = []; - $info = ''; - - foreach ((array)$data['context'] as $var => $value) { - $context[] = "\${$var} = " . static::exportVar($value, 3); - } - - switch ($this->_outputFormat) { - case false: - $this->_data[] = compact('context', 'trace') + $data; - - return; - case 'log': - static::log(compact('context', 'trace') + $data); - - return; - } - - $data['trace'] = $trace; - $data['id'] = 'cakeErr' . uniqid(); - $tpl = $this->_templates[$this->_outputFormat] + $this->_templates['base']; - - if (isset($tpl['links'])) { - foreach ($tpl['links'] as $key => $val) { - $links[$key] = Text::insert($val, $data, $insertOpts); - } - } - - if (!empty($tpl['escapeContext'])) { - $context = h($context); - $data['description'] = h($data['description']); - } - - $infoData = compact('code', 'context', 'trace'); - foreach ($infoData as $key => $value) { - if (empty($value) || !isset($tpl[$key])) { - continue; - } - if (is_array($value)) { - $value = implode("\n", $value); - } - $info .= Text::insert($tpl[$key], [$key => $value] + $data, $insertOpts); - } - $links = implode(' ', $links); - - if (isset($tpl['callback']) && is_callable($tpl['callback'])) { - call_user_func($tpl['callback'], $data, compact('links', 'info')); - - return; - } - echo Text::insert($tpl['error'], compact('links', 'info') + $data, $insertOpts); - } - - /** - * Get the type of the given variable. Will return the class name - * for objects. - * - * @param mixed $var The variable to get the type of. - * @return string The type of variable. - */ - public static function getType($var) - { - if (is_object($var)) { - return get_class($var); - } - if ($var === null) { - return 'null'; - } - if (is_string($var)) { - return 'string'; - } - if (is_array($var)) { - return 'array'; - } - if (is_int($var)) { - return 'integer'; - } - if (is_bool($var)) { - return 'boolean'; - } - if (is_float($var)) { - return 'float'; - } - if (is_resource($var)) { - return 'resource'; - } - - return 'unknown'; - } - - /** - * Prints out debug information about given variable. - * - * @param mixed $var Variable to show debug information for. - * @param array $location If contains keys "file" and "line" their values will - * be used to show location info. - * @param bool|null $showHtml If set to true, the method prints the debug - * data in a browser-friendly way. - * @return void - */ - public static function printVar($var, $location = [], $showHtml = null) - { - $location += ['file' => null, 'line' => null]; - $file = $location['file']; - $line = $location['line']; - $lineInfo = ''; - if ($file) { - $search = []; - if (defined('ROOT')) { - $search = [ROOT]; - } - if (defined('CAKE_CORE_INCLUDE_PATH')) { - array_unshift($search, CAKE_CORE_INCLUDE_PATH); - } - $file = str_replace($search, '', $file); - } - $html = << -%s -
-%s
-
- -HTML; - $text = <<%s (line %s)', $file, $line); - } - } - printf($template, $lineInfo, $var); - } - - /** - * Verifies that the application's salt and cipher seed value has been changed from the default value. - * - * @return void - */ - public static function checkSecurityKeys() - { - if (Security::getSalt() === '__SALT__') { - trigger_error(sprintf('Please change the value of %s in %s to a salt value specific to your application.', '\'Security.salt\'', 'ROOT/config/app.php'), E_USER_NOTICE); - } - } -} diff --git a/vendor/cakephp/cakephp/src/Error/ErrorHandler.php b/vendor/cakephp/cakephp/src/Error/ErrorHandler.php deleted file mode 100644 index 633b35f..0000000 --- a/vendor/cakephp/cakephp/src/Error/ErrorHandler.php +++ /dev/null @@ -1,200 +0,0 @@ - 1. - * - * ### Uncaught exceptions - * - * When debug < 1 a CakeException will render 404 or 500 errors. If an uncaught exception is thrown - * and it is a type that ErrorHandler does not know about it will be treated as a 500 error. - * - * ### Implementing application specific exception handling - * - * You can implement application specific exception handling in one of a few ways. Each approach - * gives you different amounts of control over the exception handling process. - * - * - Modify config/error.php and setup custom exception handling. - * - Use the `exceptionRenderer` option to inject an Exception renderer. This will - * let you keep the existing handling logic but override the rendering logic. - * - * #### Create your own Exception handler - * - * This gives you full control over the exception handling process. The class you choose should be - * loaded in your config/error.php and registered as the default exception handler. - * - * #### Using a custom renderer with `exceptionRenderer` - * - * If you don't want to take control of the exception handling, but want to change how exceptions are - * rendered you can use `exceptionRenderer` option to choose a class to render exception pages. By default - * `Cake\Error\ExceptionRenderer` is used. Your custom exception renderer class should be placed in src/Error. - * - * Your custom renderer should expect an exception in its constructor, and implement a render method. - * Failing to do so will cause additional errors. - * - * #### Logging exceptions - * - * Using the built-in exception handling, you can log all the exceptions - * that are dealt with by ErrorHandler by setting `log` option to true in your config/error.php. - * Enabling this will log every exception to Log and the configured loggers. - * - * ### PHP errors - * - * Error handler also provides the built in features for handling php errors (trigger_error). - * While in debug mode, errors will be output to the screen using debugger. While in production mode, - * errors will be logged to Log. You can control which errors are logged by setting - * `errorLevel` option in config/error.php. - * - * #### Logging errors - * - * When ErrorHandler is used for handling errors, you can enable error logging by setting the `log` - * option to true. This will log all errors to the configured log handlers. - * - * #### Controlling what errors are logged/displayed - * - * You can control which errors are logged / displayed by ErrorHandler by setting `errorLevel`. Setting this - * to one or a combination of a few of the E_* constants will only enable the specified errors: - * - * ``` - * $options['errorLevel'] = E_ALL & ~E_NOTICE; - * ``` - * - * Would enable handling for all non Notice errors. - * - * @see \Cake\Error\ExceptionRenderer for more information on how to customize exception rendering. - */ -class ErrorHandler extends BaseErrorHandler -{ - /** - * Constructor - * - * @param array $options The options for error handling. - */ - public function __construct($options = []) - { - $defaults = [ - 'log' => true, - 'trace' => false, - 'exceptionRenderer' => ExceptionRenderer::class, - ]; - $this->_options = $options + $defaults; - } - - /** - * Display an error. - * - * Template method of BaseErrorHandler. - * - * @param array $error An array of error data. - * @param bool $debug Whether or not the app is in debug mode. - * @return void - */ - protected function _displayError($error, $debug) - { - if (!$debug) { - return; - } - Debugger::getInstance()->outputError($error); - } - - /** - * Displays an exception response body. - * - * @param \Exception $exception The exception to display. - * @return void - * @throws \Exception When the chosen exception renderer is invalid. - */ - protected function _displayException($exception) - { - $rendererClassName = App::className($this->_options['exceptionRenderer'], 'Error'); - try { - if (!$rendererClassName) { - throw new Exception("$rendererClassName is an invalid class."); - } - /** @var \Cake\Error\ExceptionRendererInterface $renderer */ - $renderer = new $rendererClassName($exception); - $response = $renderer->render(); - $this->_clearOutput(); - $this->_sendResponse($response); - } catch (Throwable $exception) { - $this->_logInternalError($exception); - } catch (Exception $exception) { - $this->_logInternalError($exception); - } - } - - /** - * Clear output buffers so error pages display properly. - * - * Easily stubbed in testing. - * - * @return void - */ - protected function _clearOutput() - { - while (ob_get_level()) { - ob_end_clean(); - } - } - - /** - * Logs both PHP5 and PHP7 errors. - * - * The PHP5 part will be removed with 4.0. - * - * @param \Throwable|\Exception $exception Exception. - * - * @return void - */ - protected function _logInternalError($exception) - { - // Disable trace for internal errors. - $this->_options['trace'] = false; - $message = sprintf( - "[%s] %s\n%s", // Keeping same message format - get_class($exception), - $exception->getMessage(), - $exception->getTraceAsString() - ); - trigger_error($message, E_USER_ERROR); - } - - /** - * Method that can be easily stubbed in testing. - * - * @param string|\Cake\Http\Response $response Either the message or response object. - * @return void - */ - protected function _sendResponse($response) - { - if (is_string($response)) { - echo $response; - - return; - } - - $emitter = new ResponseEmitter(); - $emitter->emit($response); - } -} diff --git a/vendor/cakephp/cakephp/src/Error/ExceptionRenderer.php b/vendor/cakephp/cakephp/src/Error/ExceptionRenderer.php deleted file mode 100644 index b457f72..0000000 --- a/vendor/cakephp/cakephp/src/Error/ExceptionRenderer.php +++ /dev/null @@ -1,398 +0,0 @@ -error = $exception; - $this->controller = $this->_getController(); - } - - /** - * Returns the unwrapped exception object in case we are dealing with - * a PHP 7 Error object - * - * @param \Exception $exception The object to unwrap - * @return \Exception|\Error - */ - protected function _unwrap($exception) - { - return $exception instanceof PHP7ErrorException ? $exception->getError() : $exception; - } - - /** - * Get the controller instance to handle the exception. - * Override this method in subclasses to customize the controller used. - * This method returns the built in `ErrorController` normally, or if an error is repeated - * a bare controller will be used. - * - * @return \Cake\Controller\Controller - * @triggers Controller.startup $controller - */ - protected function _getController() - { - if (!$request = Router::getRequest(true)) { - $request = ServerRequestFactory::fromGlobals(); - } - $response = new Response(); - $controller = null; - - try { - $class = App::className('Error', 'Controller', 'Controller'); - /* @var \Cake\Controller\Controller $controller */ - $controller = new $class($request, $response); - $controller->startupProcess(); - $startup = true; - } catch (Exception $e) { - $startup = false; - } - - // Retry RequestHandler, as another aspect of startupProcess() - // could have failed. Ignore any exceptions out of startup, as - // there could be userland input data parsers. - if ($startup === false && !empty($controller) && isset($controller->RequestHandler)) { - try { - $event = new Event('Controller.startup', $controller); - $controller->RequestHandler->startup($event); - } catch (Exception $e) { - } - } - if (empty($controller)) { - $controller = new Controller($request, $response); - } - - return $controller; - } - - /** - * Renders the response for the exception. - * - * @return \Cake\Http\Response The response to be sent. - */ - public function render() - { - $exception = $this->error; - $code = $this->_code($exception); - $method = $this->_method($exception); - $template = $this->_template($exception, $method, $code); - $unwrapped = $this->_unwrap($exception); - - $isDebug = Configure::read('debug'); - if (($isDebug || $exception instanceof HttpException) && - method_exists($this, $method) - ) { - return $this->_customMethod($method, $unwrapped); - } - - $message = $this->_message($exception, $code); - $url = $this->controller->request->getRequestTarget(); - $response = $this->controller->response; - - if ($exception instanceof CakeException) { - foreach ((array)$exception->responseHeader() as $key => $value) { - $response = $response->withHeader($key, $value); - } - } - $response = $response->withStatus($code); - - $viewVars = [ - 'message' => $message, - 'url' => h($url), - 'error' => $unwrapped, - 'code' => $code, - '_serialize' => ['message', 'url', 'code'] - ]; - if ($isDebug) { - $viewVars['trace'] = Debugger::formatTrace($unwrapped->getTrace(), [ - 'format' => 'array', - 'args' => false - ]); - $viewVars['file'] = $exception->getFile() ?: 'null'; - $viewVars['line'] = $exception->getLine() ?: 'null'; - $viewVars['_serialize'][] = 'file'; - $viewVars['_serialize'][] = 'line'; - } - $this->controller->set($viewVars); - - if ($unwrapped instanceof CakeException && $isDebug) { - $this->controller->set($unwrapped->getAttributes()); - } - $this->controller->response = $response; - - return $this->_outputMessage($template); - } - - /** - * Render a custom error method/template. - * - * @param string $method The method name to invoke. - * @param \Exception $exception The exception to render. - * @return \Cake\Http\Response The response to send. - */ - protected function _customMethod($method, $exception) - { - $result = call_user_func([$this, $method], $exception); - $this->_shutdown(); - if (is_string($result)) { - $result = $this->controller->response->withStringBody($result); - } - - return $result; - } - - /** - * Get method name - * - * @param \Exception $exception Exception instance. - * @return string - */ - protected function _method(Exception $exception) - { - $exception = $this->_unwrap($exception); - list(, $baseClass) = namespaceSplit(get_class($exception)); - - if (substr($baseClass, -9) === 'Exception') { - $baseClass = substr($baseClass, 0, -9); - } - - $method = Inflector::variable($baseClass) ?: 'error500'; - - return $this->method = $method; - } - - /** - * Get error message. - * - * @param \Exception $exception Exception. - * @param int $code Error code. - * @return string Error message - */ - protected function _message(Exception $exception, $code) - { - $exception = $this->_unwrap($exception); - $message = $exception->getMessage(); - - if (!Configure::read('debug') && - !($exception instanceof HttpException) - ) { - if ($code < 500) { - $message = __d('cake', 'Not Found'); - } else { - $message = __d('cake', 'An Internal Error Has Occurred.'); - } - } - - return $message; - } - - /** - * Get template for rendering exception info. - * - * @param \Exception $exception Exception instance. - * @param string $method Method name. - * @param int $code Error code. - * @return string Template name - */ - protected function _template(Exception $exception, $method, $code) - { - $exception = $this->_unwrap($exception); - $isHttpException = $exception instanceof HttpException; - - if (!Configure::read('debug') && !$isHttpException || $isHttpException) { - $template = 'error500'; - if ($code < 500) { - $template = 'error400'; - } - - return $this->template = $template; - } - - $template = $method ?: 'error500'; - - if ($exception instanceof PDOException) { - $template = 'pdo_error'; - } - - return $this->template = $template; - } - - /** - * Get an error code value within range 400 to 506 - * - * @param \Exception $exception Exception. - * @return int Error code value within range 400 to 506 - */ - protected function _code(Exception $exception) - { - $code = 500; - $exception = $this->_unwrap($exception); - $errorCode = $exception->getCode(); - if ($errorCode >= 400 && $errorCode < 506) { - $code = $errorCode; - } - - return $code; - } - - /** - * Generate the response using the controller object. - * - * @param string $template The template to render. - * @return \Cake\Http\Response A response object that can be sent. - */ - protected function _outputMessage($template) - { - try { - $this->controller->render($template); - - return $this->_shutdown(); - } catch (MissingTemplateException $e) { - $attributes = $e->getAttributes(); - if (isset($attributes['file']) && strpos($attributes['file'], 'error500') !== false) { - return $this->_outputMessageSafe('error500'); - } - - return $this->_outputMessage('error500'); - } catch (MissingPluginException $e) { - $attributes = $e->getAttributes(); - if (isset($attributes['plugin']) && $attributes['plugin'] === $this->controller->getPlugin()) { - $this->controller->setPlugin(null); - } - - return $this->_outputMessageSafe('error500'); - } catch (Exception $e) { - return $this->_outputMessageSafe('error500'); - } - } - - /** - * A safer way to render error messages, replaces all helpers, with basics - * and doesn't call component methods. - * - * @param string $template The template to render. - * @return \Cake\Http\Response A response object that can be sent. - */ - protected function _outputMessageSafe($template) - { - $helpers = ['Form', 'Html']; - $this->controller->helpers = $helpers; - $builder = $this->controller->viewBuilder(); - $builder->setHelpers($helpers, false) - ->setLayoutPath('') - ->setTemplatePath('Error'); - $view = $this->controller->createView('View'); - - $this->controller->response = $this->controller->response - ->withType('html') - ->withStringBody($view->render($template, 'error')); - - return $this->controller->response; - } - - /** - * Run the shutdown events. - * - * Triggers the afterFilter and afterDispatch events. - * - * @return \Cake\Http\Response The response to serve. - */ - protected function _shutdown() - { - $this->controller->dispatchEvent('Controller.shutdown'); - $dispatcher = DispatcherFactory::create(); - $eventManager = $dispatcher->getEventManager(); - foreach ($dispatcher->filters() as $filter) { - $eventManager->on($filter); - } - $args = [ - 'request' => $this->controller->request, - 'response' => $this->controller->response - ]; - $result = $dispatcher->dispatchEvent('Dispatcher.afterDispatch', $args); - - return $result->getData('response'); - } -} diff --git a/vendor/cakephp/cakephp/src/Error/FatalErrorException.php b/vendor/cakephp/cakephp/src/Error/FatalErrorException.php deleted file mode 100644 index 4613e8e..0000000 --- a/vendor/cakephp/cakephp/src/Error/FatalErrorException.php +++ /dev/null @@ -1,42 +0,0 @@ -file = $file; - } - if ($line) { - $this->line = $line; - } - } -} diff --git a/vendor/cakephp/cakephp/src/Error/Middleware/ErrorHandlerMiddleware.php b/vendor/cakephp/cakephp/src/Error/Middleware/ErrorHandlerMiddleware.php deleted file mode 100644 index e433a6f..0000000 --- a/vendor/cakephp/cakephp/src/Error/Middleware/ErrorHandlerMiddleware.php +++ /dev/null @@ -1,236 +0,0 @@ - ['Cake\Error\NotFoundException', 'Cake\Error\UnauthorizedException'] - * ``` - * - * - `trace` Should error logs include stack traces? - * - * @var array - */ - protected $_defaultConfig = [ - 'skipLog' => [], - 'log' => true, - 'trace' => false, - ]; - - /** - * Exception render. - * - * @var \Cake\Error\ExceptionRendererInterface|callable|string|null - */ - protected $exceptionRenderer; - - /** - * Constructor - * - * @param string|callable|null $exceptionRenderer The renderer or class name - * to use or a callable factory. If null, Configure::read('Error.exceptionRenderer') - * will be used. - * @param array $config Configuration options to use. If empty, `Configure::read('Error')` - * will be used. - */ - public function __construct($exceptionRenderer = null, array $config = []) - { - if ($exceptionRenderer) { - $this->exceptionRenderer = $exceptionRenderer; - } - - $config = $config ?: Configure::read('Error'); - $this->setConfig($config); - } - - /** - * Wrap the remaining middleware with error handling. - * - * @param \Psr\Http\Message\ServerRequestInterface $request The request. - * @param \Psr\Http\Message\ResponseInterface $response The response. - * @param callable $next Callback to invoke the next middleware. - * @return \Psr\Http\Message\ResponseInterface A response - */ - public function __invoke($request, $response, $next) - { - try { - return $next($request, $response); - } catch (Throwable $exception) { - return $this->handleException($exception, $request, $response); - } catch (Exception $exception) { - return $this->handleException($exception, $request, $response); - } - } - - /** - * Handle an exception and generate an error response - * - * @param \Exception $exception The exception to handle. - * @param \Psr\Http\Message\ServerRequestInterface $request The request. - * @param \Psr\Http\Message\ResponseInterface $response The response. - * @return \Psr\Http\Message\ResponseInterface A response - */ - public function handleException($exception, $request, $response) - { - $renderer = $this->getRenderer($exception); - try { - $res = $renderer->render(); - $this->logException($request, $exception); - - return $res; - } catch (Throwable $exception) { - $this->logException($request, $exception); - $response = $this->handleInternalError($response); - } catch (Exception $exception) { - $this->logException($request, $exception); - $response = $this->handleInternalError($response); - } - - return $response; - } - - /** - * @param \Psr\Http\Message\ResponseInterface $response The response - * - * @return \Psr\Http\Message\ResponseInterface A response - */ - protected function handleInternalError($response) - { - $body = $response->getBody(); - $body->write('An Internal Server Error Occurred'); - - return $response->withStatus(500) - ->withBody($body); - } - - /** - * Get a renderer instance - * - * @param \Exception $exception The exception being rendered. - * @return \Cake\Error\ExceptionRendererInterface The exception renderer. - * @throws \Exception When the renderer class cannot be found. - */ - protected function getRenderer($exception) - { - if (!$this->exceptionRenderer) { - $this->exceptionRenderer = $this->getConfig('exceptionRenderer') ?: ExceptionRenderer::class; - } - - // For PHP5 backwards compatibility - if ($exception instanceof Error) { - $exception = new PHP7ErrorException($exception); - } - - if (is_string($this->exceptionRenderer)) { - $class = App::className($this->exceptionRenderer, 'Error'); - if (!$class) { - throw new Exception(sprintf( - "The '%s' renderer class could not be found.", - $this->exceptionRenderer - )); - } - - return new $class($exception); - } - $factory = $this->exceptionRenderer; - - return $factory($exception); - } - - /** - * Log an error for the exception if applicable. - * - * @param \Psr\Http\Message\ServerRequestInterface $request The current request. - * @param \Exception $exception The exception to log a message for. - * @return void - */ - protected function logException($request, $exception) - { - if (!$this->getConfig('log')) { - return; - } - - foreach ((array)$this->getConfig('skipLog') as $class) { - if ($exception instanceof $class) { - return; - } - } - - Log::error($this->getMessage($request, $exception)); - } - - /** - * Generate the error log message. - * - * @param \Psr\Http\Message\ServerRequestInterface $request The current request. - * @param \Exception $exception The exception to log a message for. - * @return string Error message - */ - protected function getMessage($request, $exception) - { - $message = sprintf( - '[%s] %s', - get_class($exception), - $exception->getMessage() - ); - $debug = Configure::read('debug'); - - if ($debug && $exception instanceof CakeException) { - $attributes = $exception->getAttributes(); - if ($attributes) { - $message .= "\nException Attributes: " . var_export($exception->getAttributes(), true); - } - } - $message .= "\nRequest URL: " . $request->getRequestTarget(); - $referer = $request->getHeaderLine('Referer'); - if ($referer) { - $message .= "\nReferer URL: " . $referer; - } - if ($this->getConfig('trace')) { - $message .= "\nStack Trace:\n" . $exception->getTraceAsString() . "\n\n"; - } - - return $message; - } -} diff --git a/vendor/cakephp/cakephp/src/Error/PHP7ErrorException.php b/vendor/cakephp/cakephp/src/Error/PHP7ErrorException.php deleted file mode 100644 index 165b32b..0000000 --- a/vendor/cakephp/cakephp/src/Error/PHP7ErrorException.php +++ /dev/null @@ -1,63 +0,0 @@ -_error = $error; - $this->message = $error->getMessage(); - $this->code = $error->getCode(); - $this->file = $error->getFile(); - $this->line = $error->getLine(); - $msg = sprintf( - '(%s) - %s in %s on %s', - get_class($error), - $this->message, - $this->file ?: 'null', - $this->line ?: 'null' - ); - parent::__construct($msg, $this->code, $error->getPrevious()); - } - - /** - * Returns the wrapped error object - * - * @return \Error - */ - public function getError() - { - return $this->_error; - } -} diff --git a/vendor/cakephp/cakephp/src/Event/Decorator/AbstractDecorator.php b/vendor/cakephp/cakephp/src/Event/Decorator/AbstractDecorator.php deleted file mode 100644 index e0cb241..0000000 --- a/vendor/cakephp/cakephp/src/Event/Decorator/AbstractDecorator.php +++ /dev/null @@ -1,72 +0,0 @@ -_callable = $callable; - $this->_options = $options; - } - - /** - * Invoke - * - * @link https://secure.php.net/manual/en/language.oop5.magic.php#object.invoke - * @return mixed - */ - public function __invoke() - { - return $this->_call(func_get_args()); - } - - /** - * Calls the decorated callable with the passed arguments. - * - * @param array $args Arguments for the callable. - * @return mixed - */ - protected function _call($args) - { - $callable = $this->_callable; - - return $callable(...$args); - } -} diff --git a/vendor/cakephp/cakephp/src/Event/Decorator/ConditionDecorator.php b/vendor/cakephp/cakephp/src/Event/Decorator/ConditionDecorator.php deleted file mode 100644 index 7db1afb..0000000 --- a/vendor/cakephp/cakephp/src/Event/Decorator/ConditionDecorator.php +++ /dev/null @@ -1,74 +0,0 @@ -canTrigger($args[0])) { - return; - } - - return $this->_call($args); - } - - /** - * Checks if the event is triggered for this listener. - * - * @param \Cake\Event\Event $event Event object. - * @return bool - */ - public function canTrigger(Event $event) - { - $if = $this->_evaluateCondition('if', $event); - $unless = $this->_evaluateCondition('unless', $event); - - return $if && !$unless; - } - - /** - * Evaluates the filter conditions - * - * @param string $condition Condition type - * @param \Cake\Event\Event $event Event object - * @return bool - */ - protected function _evaluateCondition($condition, Event $event) - { - if (!isset($this->_options[$condition])) { - return $condition !== 'unless'; - } - if (!is_callable($this->_options[$condition])) { - throw new RuntimeException(self::class . ' the `' . $condition . '` condition is not a callable!'); - } - - return $this->_options[$condition]($event); - } -} diff --git a/vendor/cakephp/cakephp/src/Event/Decorator/SubjectFilterDecorator.php b/vendor/cakephp/cakephp/src/Event/Decorator/SubjectFilterDecorator.php deleted file mode 100644 index eb32f82..0000000 --- a/vendor/cakephp/cakephp/src/Event/Decorator/SubjectFilterDecorator.php +++ /dev/null @@ -1,63 +0,0 @@ -canTrigger($args[0])) { - return false; - } - - return $this->_call($args); - } - - /** - * Checks if the event is triggered for this listener. - * - * @param \Cake\Event\Event $event Event object. - * @return bool - */ - public function canTrigger(Event $event) - { - $class = get_class($event->getSubject()); - if (!isset($this->_options['allowedSubject'])) { - throw new RuntimeException(self::class . ' Missing subject filter options!'); - } - if (is_string($this->_options['allowedSubject'])) { - $this->_options['allowedSubject'] = [$this->_options['allowedSubject']]; - } - - return in_array($class, $this->_options['allowedSubject']); - } -} diff --git a/vendor/cakephp/cakephp/src/Event/Event.php b/vendor/cakephp/cakephp/src/Event/Event.php deleted file mode 100644 index 42f1880..0000000 --- a/vendor/cakephp/cakephp/src/Event/Event.php +++ /dev/null @@ -1,278 +0,0 @@ - $userData]); - * $event = new Event('User.afterRegister', $UserModel); - * ``` - * - * @param string $name Name of the event - * @param object|null $subject the object that this event applies to (usually the object that is generating the event) - * @param array|\ArrayAccess|null $data any value you wish to be transported with this event to it can be read by listeners - */ - public function __construct($name, $subject = null, $data = null) - { - $this->_name = $name; - $this->_subject = $subject; - $this->_data = (array)$data; - } - - /** - * Provides read-only access for the name and subject properties. - * - * @param string $attribute Attribute name. - * @return mixed - * @deprecated 3.4.0 Public properties will be removed. - */ - public function __get($attribute) - { - if (!in_array($attribute, ['name', 'subject', 'data', 'result'])) { - return $this->{$attribute}; - } - - $method = 'get' . ucfirst($attribute); - deprecationWarning( - "Event::\${$attribute} is deprecated. " . - "Use Event::{$method}() instead." - ); - if ($attribute === 'name' || $attribute === 'subject') { - return $this->{$attribute}(); - } - if ($attribute === 'data') { - return $this->_data; - } - if ($attribute === 'result') { - return $this->result; - } - } - - /** - * Provides backward compatibility for write access to data and result properties. - * - * @param string $attribute Attribute name. - * @param mixed $value The value to set. - * @return void - * @deprecated 3.4.0 Public properties will be removed. - */ - public function __set($attribute, $value) - { - $method = 'set' . ucfirst($attribute); - deprecationWarning( - "Event::\${$attribute} is deprecated. " . - "Use Event::{$method}() instead." - ); - if ($attribute === 'data') { - $this->_data = (array)$value; - } - if ($attribute === 'result') { - $this->result = $value; - } - } - - /** - * Returns the name of this event. This is usually used as the event identifier - * - * @return string - * @deprecated 3.4.0 use getName() instead. - */ - public function name() - { - deprecationWarning('Event::name() is deprecated. Use Event::getName() instead.'); - - return $this->_name; - } - - /** - * Returns the name of this event. This is usually used as the event identifier - * - * @return string - */ - public function getName() - { - return $this->_name; - } - - /** - * Returns the subject of this event - * - * @return object - * @deprecated 3.4.0 use getSubject() instead. - */ - public function subject() - { - deprecationWarning('Event::subject() is deprecated. Use Event::getSubject() instead.'); - - return $this->_subject; - } - - /** - * Returns the subject of this event - * - * @return object - */ - public function getSubject() - { - return $this->_subject; - } - - /** - * Stops the event from being used anymore - * - * @return void - */ - public function stopPropagation() - { - $this->_stopped = true; - } - - /** - * Check if the event is stopped - * - * @return bool True if the event is stopped - */ - public function isStopped() - { - return $this->_stopped; - } - - /** - * The result value of the event listeners - * - * @return mixed - * @deprecated 3.4.0 use getResult() instead. - */ - public function result() - { - deprecationWarning('Event::result() is deprecated. Use Event::getResult() instead.'); - - return $this->result; - } - - /** - * The result value of the event listeners - * - * @return mixed - */ - public function getResult() - { - return $this->result; - } - - /** - * Listeners can attach a result value to the event. - * - * @param mixed $value The value to set. - * @return $this - */ - public function setResult($value = null) - { - $this->result = $value; - - return $this; - } - - /** - * Access the event data/payload. - * - * @param string|null $key The data payload element to return, or null to return all data. - * @return array|mixed|null The data payload if $key is null, or the data value for the given $key. If the $key does not - * exist a null value is returned. - * @deprecated 3.4.0 use getData() instead. - */ - public function data($key = null) - { - return $this->getData($key); - } - - /** - * Access the event data/payload. - * - * @param string|null $key The data payload element to return, or null to return all data. - * @return array|mixed|null The data payload if $key is null, or the data value for the given $key. If the $key does not - * exist a null value is returned. - */ - public function getData($key = null) - { - if ($key !== null) { - return isset($this->_data[$key]) ? $this->_data[$key] : null; - } - - return (array)$this->_data; - } - - /** - * Assigns a value to the data/payload of this event. - * - * @param array|string $key An array will replace all payload data, and a key will set just that array item. - * @param mixed $value The value to set. - * @return $this - */ - public function setData($key, $value = null) - { - if (is_array($key)) { - $this->_data = $key; - } else { - $this->_data[$key] = $value; - } - - return $this; - } -} diff --git a/vendor/cakephp/cakephp/src/Event/EventDispatcherInterface.php b/vendor/cakephp/cakephp/src/Event/EventDispatcherInterface.php deleted file mode 100644 index 9119ad1..0000000 --- a/vendor/cakephp/cakephp/src/Event/EventDispatcherInterface.php +++ /dev/null @@ -1,57 +0,0 @@ -setEventManager($eventManager); - } - - return $this->getEventManager(); - } - - /** - * Returns the Cake\Event\EventManager manager instance for this object. - * - * You can use this instance to register any new listeners or callbacks to the - * object events, or create your own events and trigger them at will. - * - * @return \Cake\Event\EventManager - */ - public function getEventManager() - { - if ($this->_eventManager === null) { - $this->_eventManager = new EventManager(); - } - - return $this->_eventManager; - } - - /** - * Returns the Cake\Event\EventManager manager instance for this object. - * - * You can use this instance to register any new listeners or callbacks to the - * object events, or create your own events and trigger them at will. - * - * @param \Cake\Event\EventManager $eventManager the eventManager to set - * @return $this - */ - public function setEventManager(EventManager $eventManager) - { - $this->_eventManager = $eventManager; - - return $this; - } - - /** - * Wrapper for creating and dispatching events. - * - * Returns a dispatched event. - * - * @param string $name Name of the event. - * @param array|null $data Any value you wish to be transported with this event to - * it can be read by listeners. - * @param object|null $subject The object that this event applies to - * ($this by default). - * - * @return \Cake\Event\Event - */ - public function dispatchEvent($name, $data = null, $subject = null) - { - if ($subject === null) { - $subject = $this; - } - - $event = new $this->_eventClass($name, $subject, $data); - $this->getEventManager()->dispatch($event); - - return $event; - } -} diff --git a/vendor/cakephp/cakephp/src/Event/EventList.php b/vendor/cakephp/cakephp/src/Event/EventList.php deleted file mode 100644 index 112329d..0000000 --- a/vendor/cakephp/cakephp/src/Event/EventList.php +++ /dev/null @@ -1,134 +0,0 @@ -_events = []; - } - - /** - * Adds an event to the list when event listing is enabled. - * - * @param \Cake\Event\Event $event An event to the list of dispatched events. - * @return void - */ - public function add(Event $event) - { - $this->_events[] = $event; - } - - /** - * Whether a offset exists - * - * @link https://secure.php.net/manual/en/arrayaccess.offsetexists.php - * @param mixed $offset An offset to check for. - * @return bool True on success or false on failure. - */ - public function offsetExists($offset) - { - return isset($this->_events[$offset]); - } - - /** - * Offset to retrieve - * - * @link https://secure.php.net/manual/en/arrayaccess.offsetget.php - * @param mixed $offset The offset to retrieve. - * @return mixed Can return all value types. - */ - public function offsetGet($offset) - { - if ($this->offsetExists($offset)) { - return $this->_events[$offset]; - } - - return null; - } - - /** - * Offset to set - * - * @link https://secure.php.net/manual/en/arrayaccess.offsetset.php - * @param mixed $offset The offset to assign the value to. - * @param mixed $value The value to set. - * @return void - */ - public function offsetSet($offset, $value) - { - $this->_events[$offset] = $value; - } - - /** - * Offset to unset - * - * @link https://secure.php.net/manual/en/arrayaccess.offsetunset.php - * @param mixed $offset The offset to unset. - * @return void - */ - public function offsetUnset($offset) - { - unset($this->_events[$offset]); - } - - /** - * Count elements of an object - * - * @link https://secure.php.net/manual/en/countable.count.php - * @return int The custom count as an integer. - */ - public function count() - { - return count($this->_events); - } - - /** - * Checks if an event is in the list. - * - * @param string $name Event name. - * @return bool - */ - public function hasEvent($name) - { - foreach ($this->_events as $event) { - if ($event->getName() === $name) { - return true; - } - } - - return false; - } -} diff --git a/vendor/cakephp/cakephp/src/Event/EventListenerInterface.php b/vendor/cakephp/cakephp/src/Event/EventListenerInterface.php deleted file mode 100644 index 5f7af67..0000000 --- a/vendor/cakephp/cakephp/src/Event/EventListenerInterface.php +++ /dev/null @@ -1,45 +0,0 @@ - 'sendEmail', - * 'Article.afterBuy' => 'decrementInventory', - * 'User.onRegister' => ['callable' => 'logRegistration', 'priority' => 20, 'passParams' => true] - * ]; - * } - * ``` - * - * @return array associative array or event key names pointing to the function - * that should be called in the object when the respective event is fired - */ - public function implementedEvents(); -} diff --git a/vendor/cakephp/cakephp/src/Event/EventManager.php b/vendor/cakephp/cakephp/src/Event/EventManager.php deleted file mode 100644 index 2e5cd7d..0000000 --- a/vendor/cakephp/cakephp/src/Event/EventManager.php +++ /dev/null @@ -1,527 +0,0 @@ -_isGlobal = true; - - return static::$_generalManager; - } - - /** - * Adds a new listener to an event. - * - * @param callable|\Cake\Event\EventListenerInterface $callable PHP valid callback type or instance of Cake\Event\EventListenerInterface to be called - * when the event named with $eventKey is triggered. If a Cake\Event\EventListenerInterface instance is passed, then the `implementedEvents` - * method will be called on the object to register the declared events individually as methods to be managed by this class. - * It is possible to define multiple event handlers per event name. - * - * @param string|null $eventKey The event unique identifier name with which the callback will be associated. If $callable - * is an instance of Cake\Event\EventListenerInterface this argument will be ignored - * - * @param array $options used to set the `priority` flag to the listener. In the future more options may be added. - * Priorities are treated as queues. Lower values are called before higher ones, and multiple attachments - * added to the same priority queue will be treated in the order of insertion. - * - * @return void - * @throws \InvalidArgumentException When event key is missing or callable is not an - * instance of Cake\Event\EventListenerInterface. - * @deprecated 3.0.0 Use on() instead. - */ - public function attach($callable, $eventKey = null, array $options = []) - { - deprecationWarning('EventManager::attach() is deprecated. Use EventManager::on() instead.'); - if ($eventKey === null) { - $this->on($callable); - - return; - } - if ($options) { - $this->on($eventKey, $options, $callable); - - return; - } - $this->on($eventKey, $callable); - } - - /** - * {@inheritDoc} - */ - public function on($eventKey = null, $options = [], $callable = null) - { - if ($eventKey instanceof EventListenerInterface) { - $this->_attachSubscriber($eventKey); - - return $this; - } - $argCount = func_num_args(); - if ($argCount === 2) { - $this->_listeners[$eventKey][static::$defaultPriority][] = [ - 'callable' => $options - ]; - - return $this; - } - if ($argCount === 3) { - $priority = isset($options['priority']) ? $options['priority'] : static::$defaultPriority; - $this->_listeners[$eventKey][$priority][] = [ - 'callable' => $callable - ]; - - return $this; - } - throw new InvalidArgumentException( - 'Invalid arguments for EventManager::on(). ' . - "Expected 1, 2 or 3 arguments. Got {$argCount} arguments." - ); - } - - /** - * Auxiliary function to attach all implemented callbacks of a Cake\Event\EventListenerInterface class instance - * as individual methods on this manager - * - * @param \Cake\Event\EventListenerInterface $subscriber Event listener. - * @return void - */ - protected function _attachSubscriber(EventListenerInterface $subscriber) - { - foreach ((array)$subscriber->implementedEvents() as $eventKey => $function) { - $options = []; - $method = $function; - if (is_array($function) && isset($function['callable'])) { - list($method, $options) = $this->_extractCallable($function, $subscriber); - } elseif (is_array($function) && is_numeric(key($function))) { - foreach ($function as $f) { - list($method, $options) = $this->_extractCallable($f, $subscriber); - $this->on($eventKey, $options, $method); - } - continue; - } - if (is_string($method)) { - $method = [$subscriber, $function]; - } - $this->on($eventKey, $options, $method); - } - } - - /** - * Auxiliary function to extract and return a PHP callback type out of the callable definition - * from the return value of the `implementedEvents` method on a Cake\Event\EventListenerInterface - * - * @param array $function the array taken from a handler definition for an event - * @param \Cake\Event\EventListenerInterface $object The handler object - * @return callable - */ - protected function _extractCallable($function, $object) - { - $method = $function['callable']; - $options = $function; - unset($options['callable']); - if (is_string($method)) { - $method = [$object, $method]; - } - - return [$method, $options]; - } - - /** - * Removes a listener from the active listeners. - * - * @param callable|\Cake\Event\EventListenerInterface $callable any valid PHP callback type or an instance of EventListenerInterface - * @param string|null $eventKey The event unique identifier name with which the callback has been associated - * @return void - * @deprecated 3.0.0 Use off() instead. - */ - public function detach($callable, $eventKey = null) - { - deprecationWarning('EventManager::detach() is deprecated. Use EventManager::off() instead.'); - if ($eventKey === null) { - $this->off($callable); - - return; - } - $this->off($eventKey, $callable); - } - - /** - * {@inheritDoc} - */ - public function off($eventKey, $callable = null) - { - if ($eventKey instanceof EventListenerInterface) { - $this->_detachSubscriber($eventKey); - - return $this; - } - if ($callable instanceof EventListenerInterface) { - $this->_detachSubscriber($callable, $eventKey); - - return $this; - } - if ($callable === null && is_string($eventKey)) { - unset($this->_listeners[$eventKey]); - - return $this; - } - if ($callable === null) { - foreach (array_keys($this->_listeners) as $name) { - $this->off($name, $eventKey); - } - - return $this; - } - if (empty($this->_listeners[$eventKey])) { - return $this; - } - foreach ($this->_listeners[$eventKey] as $priority => $callables) { - foreach ($callables as $k => $callback) { - if ($callback['callable'] === $callable) { - unset($this->_listeners[$eventKey][$priority][$k]); - break; - } - } - } - - return $this; - } - - /** - * Auxiliary function to help detach all listeners provided by an object implementing EventListenerInterface - * - * @param \Cake\Event\EventListenerInterface $subscriber the subscriber to be detached - * @param string|null $eventKey optional event key name to unsubscribe the listener from - * @return void - */ - protected function _detachSubscriber(EventListenerInterface $subscriber, $eventKey = null) - { - $events = (array)$subscriber->implementedEvents(); - if (!empty($eventKey) && empty($events[$eventKey])) { - return; - } - if (!empty($eventKey)) { - $events = [$eventKey => $events[$eventKey]]; - } - foreach ($events as $key => $function) { - if (is_array($function)) { - if (is_numeric(key($function))) { - foreach ($function as $handler) { - $handler = isset($handler['callable']) ? $handler['callable'] : $handler; - $this->off($key, [$subscriber, $handler]); - } - continue; - } - $function = $function['callable']; - } - $this->off($key, [$subscriber, $function]); - } - } - - /** - * {@inheritDoc} - */ - public function dispatch($event) - { - if (is_string($event)) { - $event = new Event($event); - } - - $listeners = $this->listeners($event->getName()); - - if ($this->_trackEvents) { - $this->addEventToList($event); - } - - if (!$this->_isGlobal && static::instance()->isTrackingEvents()) { - static::instance()->addEventToList($event); - } - - if (empty($listeners)) { - return $event; - } - - foreach ($listeners as $listener) { - if ($event->isStopped()) { - break; - } - $result = $this->_callListener($listener['callable'], $event); - if ($result === false) { - $event->stopPropagation(); - } - if ($result !== null) { - $event->setResult($result); - } - } - - return $event; - } - - /** - * Calls a listener. - * - * @param callable $listener The listener to trigger. - * @param \Cake\Event\Event $event Event instance. - * @return mixed The result of the $listener function. - */ - protected function _callListener(callable $listener, Event $event) - { - $data = $event->getData(); - - return $listener($event, ...array_values($data)); - } - - /** - * {@inheritDoc} - */ - public function listeners($eventKey) - { - $localListeners = []; - if (!$this->_isGlobal) { - $localListeners = $this->prioritisedListeners($eventKey); - $localListeners = empty($localListeners) ? [] : $localListeners; - } - $globalListeners = static::instance()->prioritisedListeners($eventKey); - $globalListeners = empty($globalListeners) ? [] : $globalListeners; - - $priorities = array_merge(array_keys($globalListeners), array_keys($localListeners)); - $priorities = array_unique($priorities); - asort($priorities); - - $result = []; - foreach ($priorities as $priority) { - if (isset($globalListeners[$priority])) { - $result = array_merge($result, $globalListeners[$priority]); - } - if (isset($localListeners[$priority])) { - $result = array_merge($result, $localListeners[$priority]); - } - } - - return $result; - } - - /** - * Returns the listeners for the specified event key indexed by priority - * - * @param string $eventKey Event key. - * @return array - */ - public function prioritisedListeners($eventKey) - { - if (empty($this->_listeners[$eventKey])) { - return []; - } - - return $this->_listeners[$eventKey]; - } - - /** - * Returns the listeners matching a specified pattern - * - * @param string $eventKeyPattern Pattern to match. - * @return array - */ - public function matchingListeners($eventKeyPattern) - { - $matchPattern = '/' . preg_quote($eventKeyPattern, '/') . '/'; - $matches = array_intersect_key( - $this->_listeners, - array_flip( - preg_grep($matchPattern, array_keys($this->_listeners), 0) - ) - ); - - return $matches; - } - - /** - * Returns the event list. - * - * @return \Cake\Event\EventList - */ - public function getEventList() - { - return $this->_eventList; - } - - /** - * Adds an event to the list if the event list object is present. - * - * @param \Cake\Event\Event $event An event to add to the list. - * @return $this - */ - public function addEventToList(Event $event) - { - if ($this->_eventList) { - $this->_eventList->add($event); - } - - return $this; - } - - /** - * Enables / disables event tracking at runtime. - * - * @param bool $enabled True or false to enable / disable it. - * @return $this - */ - public function trackEvents($enabled) - { - $this->_trackEvents = (bool)$enabled; - - return $this; - } - - /** - * Returns whether this manager is set up to track events - * - * @return bool - */ - public function isTrackingEvents() - { - return $this->_trackEvents && $this->_eventList; - } - - /** - * Enables the listing of dispatched events. - * - * @param \Cake\Event\EventList $eventList The event list object to use. - * @return $this - */ - public function setEventList(EventList $eventList) - { - $this->_eventList = $eventList; - $this->_trackEvents = true; - - return $this; - } - - /** - * Disables the listing of dispatched events. - * - * @return $this - */ - public function unsetEventList() - { - $this->_eventList = null; - $this->_trackEvents = false; - - return $this; - } - - /** - * Debug friendly object properties. - * - * @return array - */ - public function __debugInfo() - { - $properties = get_object_vars($this); - $properties['_generalManager'] = '(object) EventManager'; - $properties['_listeners'] = []; - foreach ($this->_listeners as $key => $priorities) { - $listenerCount = 0; - foreach ($priorities as $listeners) { - $listenerCount += count($listeners); - } - $properties['_listeners'][$key] = $listenerCount . ' listener(s)'; - } - if ($this->_eventList) { - $count = count($this->_eventList); - for ($i = 0; $i < $count; $i++) { - $event = $this->_eventList[$i]; - $subject = $event->getSubject(); - $properties['_dispatchedEvents'][] = $event->getName() . ' with ' . - (is_object($subject) ? 'subject ' . get_class($subject) : 'no subject'); - } - } else { - $properties['_dispatchedEvents'] = null; - } - unset($properties['_eventList']); - - return $properties; - } -} diff --git a/vendor/cakephp/cakephp/src/Event/EventManagerTrait.php b/vendor/cakephp/cakephp/src/Event/EventManagerTrait.php deleted file mode 100644 index efc0a5a..0000000 --- a/vendor/cakephp/cakephp/src/Event/EventManagerTrait.php +++ /dev/null @@ -1,26 +0,0 @@ -doStuff(); - $event = new Event('Orders.afterPlace', $this, [ - 'order' => $order - ]); - $this->getEventManager()->dispatch($event); - } -} - -$orders = new Orders(); -$orders->getEventManager()->on(function ($event) { - // Do something after the order was placed - ... -}, 'Orders.afterPlace'); - -$orders->placeOrder($order); -``` - -The above code allows you to easily notify the other parts of the application that an order has been created. -You can then do tasks like send email notifications, update stock, log relevant statistics and other tasks -in separate objects that focus on those concerns. - -## Documentation - -Please make sure you check the [official documentation](https://book.cakephp.org/3.0/en/core-libraries/events.html) diff --git a/vendor/cakephp/cakephp/src/Event/composer.json b/vendor/cakephp/cakephp/src/Event/composer.json deleted file mode 100644 index e984d41..0000000 --- a/vendor/cakephp/cakephp/src/Event/composer.json +++ /dev/null @@ -1,34 +0,0 @@ -{ - "name": "cakephp/event", - "description": "CakePHP event dispatcher library that helps implementing the observer pattern", - "type": "library", - "keywords": [ - "cakephp", - "event", - "dispatcher", - "observer pattern" - ], - "homepage": "https://cakephp.org", - "license": "MIT", - "authors": [ - { - "name": "CakePHP Community", - "homepage": "https://github.com/cakephp/event/graphs/contributors" - } - ], - "support": { - "issues": "https://github.com/cakephp/cakephp/issues", - "forum": "https://stackoverflow.com/tags/cakephp", - "irc": "irc://irc.freenode.org/cakephp", - "source": "https://github.com/cakephp/event" - }, - "require": { - "php": ">=5.6.0", - "cakephp/core": "^3.6.0" - }, - "autoload": { - "psr-4": { - "Cake\\Event\\": "." - } - } -} diff --git a/vendor/cakephp/cakephp/src/Filesystem/File.php b/vendor/cakephp/cakephp/src/Filesystem/File.php deleted file mode 100644 index e0ebe95..0000000 --- a/vendor/cakephp/cakephp/src/Filesystem/File.php +++ /dev/null @@ -1,662 +0,0 @@ -Folder = new Folder($splInfo->getPath(), $create, $mode); - if (!is_dir($path)) { - $this->name = ltrim($splInfo->getFilename(), '/\\'); - } - $this->pwd(); - $create && !$this->exists() && $this->safe($path) && $this->create(); - } - - /** - * Closes the current file if it is opened - */ - public function __destruct() - { - $this->close(); - } - - /** - * Creates the file. - * - * @return bool Success - */ - public function create() - { - $dir = $this->Folder->pwd(); - - if (is_dir($dir) && is_writable($dir) && !$this->exists()) { - if (touch($this->path)) { - return true; - } - } - - return false; - } - - /** - * Opens the current file with a given $mode - * - * @param string $mode A valid 'fopen' mode string (r|w|a ...) - * @param bool $force If true then the file will be re-opened even if its already opened, otherwise it won't - * @return bool True on success, false on failure - */ - public function open($mode = 'r', $force = false) - { - if (!$force && is_resource($this->handle)) { - return true; - } - if ($this->exists() === false && $this->create() === false) { - return false; - } - - $this->handle = fopen($this->path, $mode); - - return is_resource($this->handle); - } - - /** - * Return the contents of this file as a string. - * - * @param string|bool $bytes where to start - * @param string $mode A `fread` compatible mode. - * @param bool $force If true then the file will be re-opened even if its already opened, otherwise it won't - * @return string|false string on success, false on failure - */ - public function read($bytes = false, $mode = 'rb', $force = false) - { - if ($bytes === false && $this->lock === null) { - return file_get_contents($this->path); - } - if ($this->open($mode, $force) === false) { - return false; - } - if ($this->lock !== null && flock($this->handle, LOCK_SH) === false) { - return false; - } - if (is_int($bytes)) { - return fread($this->handle, $bytes); - } - - $data = ''; - while (!feof($this->handle)) { - $data .= fgets($this->handle, 4096); - } - - if ($this->lock !== null) { - flock($this->handle, LOCK_UN); - } - if ($bytes === false) { - $this->close(); - } - - return trim($data); - } - - /** - * Sets or gets the offset for the currently opened file. - * - * @param int|bool $offset The $offset in bytes to seek. If set to false then the current offset is returned. - * @param int $seek PHP Constant SEEK_SET | SEEK_CUR | SEEK_END determining what the $offset is relative to - * @return int|bool True on success, false on failure (set mode), false on failure or integer offset on success (get mode) - */ - public function offset($offset = false, $seek = SEEK_SET) - { - if ($offset === false) { - if (is_resource($this->handle)) { - return ftell($this->handle); - } - } elseif ($this->open() === true) { - return fseek($this->handle, $offset, $seek) === 0; - } - - return false; - } - - /** - * Prepares an ASCII string for writing. Converts line endings to the - * correct terminator for the current platform. If Windows, "\r\n" will be used, - * all other platforms will use "\n" - * - * @param string $data Data to prepare for writing. - * @param bool $forceWindows If true forces Windows new line string. - * @return string The with converted line endings. - */ - public static function prepare($data, $forceWindows = false) - { - $lineBreak = "\n"; - if (DIRECTORY_SEPARATOR === '\\' || $forceWindows === true) { - $lineBreak = "\r\n"; - } - - return strtr($data, ["\r\n" => $lineBreak, "\n" => $lineBreak, "\r" => $lineBreak]); - } - - /** - * Write given data to this file. - * - * @param string $data Data to write to this File. - * @param string $mode Mode of writing. {@link https://secure.php.net/fwrite See fwrite()}. - * @param bool $force Force the file to open - * @return bool Success - */ - public function write($data, $mode = 'w', $force = false) - { - $success = false; - if ($this->open($mode, $force) === true) { - if ($this->lock !== null && flock($this->handle, LOCK_EX) === false) { - return false; - } - - if (fwrite($this->handle, $data) !== false) { - $success = true; - } - if ($this->lock !== null) { - flock($this->handle, LOCK_UN); - } - } - - return $success; - } - - /** - * Append given data string to this file. - * - * @param string $data Data to write - * @param bool $force Force the file to open - * @return bool Success - */ - public function append($data, $force = false) - { - return $this->write($data, 'a', $force); - } - - /** - * Closes the current file if it is opened. - * - * @return bool True if closing was successful or file was already closed, otherwise false - */ - public function close() - { - if (!is_resource($this->handle)) { - return true; - } - - return fclose($this->handle); - } - - /** - * Deletes the file. - * - * @return bool Success - */ - public function delete() - { - if (is_resource($this->handle)) { - fclose($this->handle); - $this->handle = null; - } - if ($this->exists()) { - return unlink($this->path); - } - - return false; - } - - /** - * Returns the file info as an array with the following keys: - * - * - dirname - * - basename - * - extension - * - filename - * - filesize - * - mime - * - * @return array File information. - */ - public function info() - { - if (!$this->info) { - $this->info = pathinfo($this->path); - } - if (!isset($this->info['filename'])) { - $this->info['filename'] = $this->name(); - } - if (!isset($this->info['filesize'])) { - $this->info['filesize'] = $this->size(); - } - if (!isset($this->info['mime'])) { - $this->info['mime'] = $this->mime(); - } - - return $this->info; - } - - /** - * Returns the file extension. - * - * @return string|false The file extension, false if extension cannot be extracted. - */ - public function ext() - { - if (!$this->info) { - $this->info(); - } - if (isset($this->info['extension'])) { - return $this->info['extension']; - } - - return false; - } - - /** - * Returns the file name without extension. - * - * @return string|false The file name without extension, false if name cannot be extracted. - */ - public function name() - { - if (!$this->info) { - $this->info(); - } - if (isset($this->info['extension'])) { - return static::_basename($this->name, '.' . $this->info['extension']); - } - if ($this->name) { - return $this->name; - } - - return false; - } - - /** - * Returns the file basename. simulate the php basename() for multibyte (mb_basename). - * - * @param string $path Path to file - * @param string|null $ext The name of the extension - * @return string the file basename. - */ - protected static function _basename($path, $ext = null) - { - // check for multibyte string and use basename() if not found - if (mb_strlen($path) === strlen($path)) { - return ($ext === null)? basename($path) : basename($path, $ext); - } - - $splInfo = new SplFileInfo($path); - $name = ltrim($splInfo->getFilename(), '/\\'); - - if ($ext === null || $ext === '') { - return $name; - } - $ext = preg_quote($ext); - $new = preg_replace("/({$ext})$/u", "", $name); - - // basename of '/etc/.d' is '.d' not '' - return ($new === '')? $name : $new; - } - - /** - * Makes file name safe for saving - * - * @param string|null $name The name of the file to make safe if different from $this->name - * @param string|null $ext The name of the extension to make safe if different from $this->ext - * @return string The extension of the file - */ - public function safe($name = null, $ext = null) - { - if (!$name) { - $name = $this->name; - } - if (!$ext) { - $ext = $this->ext(); - } - - return preg_replace("/(?:[^\w\.-]+)/", '_', static::_basename($name, $ext)); - } - - /** - * Get md5 Checksum of file with previous check of Filesize - * - * @param int|bool $maxsize in MB or true to force - * @return string|false md5 Checksum {@link https://secure.php.net/md5_file See md5_file()}, or false in case of an error - */ - public function md5($maxsize = 5) - { - if ($maxsize === true) { - return md5_file($this->path); - } - - $size = $this->size(); - if ($size && $size < ($maxsize * 1024) * 1024) { - return md5_file($this->path); - } - - return false; - } - - /** - * Returns the full path of the file. - * - * @return string Full path to the file - */ - public function pwd() - { - if ($this->path === null) { - $dir = $this->Folder->pwd(); - if (is_dir($dir)) { - $this->path = $this->Folder->slashTerm($dir) . $this->name; - } - } - - return $this->path; - } - - /** - * Returns true if the file exists. - * - * @return bool True if it exists, false otherwise - */ - public function exists() - { - $this->clearStatCache(); - - return (file_exists($this->path) && is_file($this->path)); - } - - /** - * Returns the "chmod" (permissions) of the file. - * - * @return string|false Permissions for the file, or false in case of an error - */ - public function perms() - { - if ($this->exists()) { - return substr(sprintf('%o', fileperms($this->path)), -4); - } - - return false; - } - - /** - * Returns the file size - * - * @return int|false Size of the file in bytes, or false in case of an error - */ - public function size() - { - if ($this->exists()) { - return filesize($this->path); - } - - return false; - } - - /** - * Returns true if the file is writable. - * - * @return bool True if it's writable, false otherwise - */ - public function writable() - { - return is_writable($this->path); - } - - /** - * Returns true if the File is executable. - * - * @return bool True if it's executable, false otherwise - */ - public function executable() - { - return is_executable($this->path); - } - - /** - * Returns true if the file is readable. - * - * @return bool True if file is readable, false otherwise - */ - public function readable() - { - return is_readable($this->path); - } - - /** - * Returns the file's owner. - * - * @return int|false The file owner, or false in case of an error - */ - public function owner() - { - if ($this->exists()) { - return fileowner($this->path); - } - - return false; - } - - /** - * Returns the file's group. - * - * @return int|false The file group, or false in case of an error - */ - public function group() - { - if ($this->exists()) { - return filegroup($this->path); - } - - return false; - } - - /** - * Returns last access time. - * - * @return int|false Timestamp of last access time, or false in case of an error - */ - public function lastAccess() - { - if ($this->exists()) { - return fileatime($this->path); - } - - return false; - } - - /** - * Returns last modified time. - * - * @return int|false Timestamp of last modification, or false in case of an error - */ - public function lastChange() - { - if ($this->exists()) { - return filemtime($this->path); - } - - return false; - } - - /** - * Returns the current folder. - * - * @return \Cake\Filesystem\Folder Current folder - */ - public function folder() - { - return $this->Folder; - } - - /** - * Copy the File to $dest - * - * @param string $dest Destination for the copy - * @param bool $overwrite Overwrite $dest if exists - * @return bool Success - */ - public function copy($dest, $overwrite = true) - { - if (!$this->exists() || is_file($dest) && !$overwrite) { - return false; - } - - return copy($this->path, $dest); - } - - /** - * Gets the mime type of the file. Uses the finfo extension if - * it's available, otherwise falls back to mime_content_type(). - * - * @return false|string The mimetype of the file, or false if reading fails. - */ - public function mime() - { - if (!$this->exists()) { - return false; - } - if (class_exists('finfo')) { - $finfo = new finfo(FILEINFO_MIME); - $type = $finfo->file($this->pwd()); - if (!$type) { - return false; - } - list($type) = explode(';', $type); - - return $type; - } - if (function_exists('mime_content_type')) { - return mime_content_type($this->pwd()); - } - - return false; - } - - /** - * Clear PHP's internal stat cache - * - * @param bool $all Clear all cache or not. Passing false will clear - * the stat cache for the current path only. - * @return void - */ - public function clearStatCache($all = false) - { - if ($all === false) { - clearstatcache(true, $this->path); - } - - clearstatcache(); - } - - /** - * Searches for a given text and replaces the text if found. - * - * @param string|array $search Text(s) to search for. - * @param string|array $replace Text(s) to replace with. - * @return bool Success - */ - public function replaceText($search, $replace) - { - if (!$this->open('r+')) { - return false; - } - - if ($this->lock !== null && flock($this->handle, LOCK_EX) === false) { - return false; - } - - $replaced = $this->write(str_replace($search, $replace, $this->read()), 'w', true); - - if ($this->lock !== null) { - flock($this->handle, LOCK_UN); - } - $this->close(); - - return $replaced; - } -} diff --git a/vendor/cakephp/cakephp/src/Filesystem/Folder.php b/vendor/cakephp/cakephp/src/Filesystem/Folder.php deleted file mode 100644 index 9b59a1e..0000000 --- a/vendor/cakephp/cakephp/src/Filesystem/Folder.php +++ /dev/null @@ -1,976 +0,0 @@ - 'getPathname', - self::SORT_TIME => 'getCTime' - ]; - - /** - * Holds messages from last method. - * - * @var array - */ - protected $_messages = []; - - /** - * Holds errors from last method. - * - * @var array - */ - protected $_errors = []; - - /** - * Holds array of complete directory paths. - * - * @var array - */ - protected $_directories; - - /** - * Holds array of complete file paths. - * - * @var array - */ - protected $_files; - - /** - * Constructor. - * - * @param string|null $path Path to folder - * @param bool $create Create folder if not found - * @param int|false $mode Mode (CHMOD) to apply to created folder, false to ignore - */ - public function __construct($path = null, $create = false, $mode = false) - { - if (empty($path)) { - $path = TMP; - } - if ($mode) { - $this->mode = $mode; - } - - if (!file_exists($path) && $create === true) { - $this->create($path, $this->mode); - } - if (!Folder::isAbsolute($path)) { - $path = realpath($path); - } - if (!empty($path)) { - $this->cd($path); - } - } - - /** - * Return current path. - * - * @return string Current path - */ - public function pwd() - { - return $this->path; - } - - /** - * Change directory to $path. - * - * @param string $path Path to the directory to change to - * @return string|bool The new path. Returns false on failure - */ - public function cd($path) - { - $path = $this->realpath($path); - if ($path !== false && is_dir($path)) { - return $this->path = $path; - } - - return false; - } - - /** - * Returns an array of the contents of the current directory. - * The returned array holds two arrays: One of directories and one of files. - * - * @param string|bool $sort Whether you want the results sorted, set this and the sort property - * to false to get unsorted results. - * @param array|bool $exceptions Either an array or boolean true will not grab dot files - * @param bool $fullPath True returns the full path - * @return array Contents of current directory as an array, an empty array on failure - */ - public function read($sort = self::SORT_NAME, $exceptions = false, $fullPath = false) - { - $dirs = $files = []; - - if (!$this->pwd()) { - return [$dirs, $files]; - } - if (is_array($exceptions)) { - $exceptions = array_flip($exceptions); - } - $skipHidden = isset($exceptions['.']) || $exceptions === true; - - try { - $iterator = new DirectoryIterator($this->path); - } catch (Exception $e) { - return [$dirs, $files]; - } - - if (!is_bool($sort) && isset($this->_fsorts[$sort])) { - $methodName = $this->_fsorts[$sort]; - } else { - $methodName = $this->_fsorts[self::SORT_NAME]; - } - - foreach ($iterator as $item) { - if ($item->isDot()) { - continue; - } - $name = $item->getFilename(); - if ($skipHidden && $name[0] === '.' || isset($exceptions[$name])) { - continue; - } - if ($fullPath) { - $name = $item->getPathname(); - } - - if ($item->isDir()) { - $dirs[$item->{$methodName}()][] = $name; - } else { - $files[$item->{$methodName}()][] = $name; - } - } - - if ($sort || $this->sort) { - ksort($dirs); - ksort($files); - } - - if ($dirs) { - $dirs = array_merge(...array_values($dirs)); - } - - if ($files) { - $files = array_merge(...array_values($files)); - } - - return [$dirs, $files]; - } - - /** - * Returns an array of all matching files in current directory. - * - * @param string $regexpPattern Preg_match pattern (Defaults to: .*) - * @param bool $sort Whether results should be sorted. - * @return array Files that match given pattern - */ - public function find($regexpPattern = '.*', $sort = false) - { - list(, $files) = $this->read($sort); - - return array_values(preg_grep('/^' . $regexpPattern . '$/i', $files)); - } - - /** - * Returns an array of all matching files in and below current directory. - * - * @param string $pattern Preg_match pattern (Defaults to: .*) - * @param bool $sort Whether results should be sorted. - * @return array Files matching $pattern - */ - public function findRecursive($pattern = '.*', $sort = false) - { - if (!$this->pwd()) { - return []; - } - $startsOn = $this->path; - $out = $this->_findRecursive($pattern, $sort); - $this->cd($startsOn); - - return $out; - } - - /** - * Private helper function for findRecursive. - * - * @param string $pattern Pattern to match against - * @param bool $sort Whether results should be sorted. - * @return array Files matching pattern - */ - protected function _findRecursive($pattern, $sort = false) - { - list($dirs, $files) = $this->read($sort); - $found = []; - - foreach ($files as $file) { - if (preg_match('/^' . $pattern . '$/i', $file)) { - $found[] = Folder::addPathElement($this->path, $file); - } - } - $start = $this->path; - - foreach ($dirs as $dir) { - $this->cd(Folder::addPathElement($start, $dir)); - $found = array_merge($found, $this->findRecursive($pattern, $sort)); - } - - return $found; - } - - /** - * Returns true if given $path is a Windows path. - * - * @param string $path Path to check - * @return bool true if windows path, false otherwise - */ - public static function isWindowsPath($path) - { - return (preg_match('/^[A-Z]:\\\\/i', $path) || substr($path, 0, 2) === '\\\\'); - } - - /** - * Returns true if given $path is an absolute path. - * - * @param string $path Path to check - * @return bool true if path is absolute. - */ - public static function isAbsolute($path) - { - if (empty($path)) { - return false; - } - - return $path[0] === '/' || - preg_match('/^[A-Z]:\\\\/i', $path) || - substr($path, 0, 2) === '\\\\' || - self::isRegisteredStreamWrapper($path); - } - - /** - * Returns true if given $path is a registered stream wrapper. - * - * @param string $path Path to check - * @return bool True if path is registered stream wrapper. - */ - public static function isRegisteredStreamWrapper($path) - { - return preg_match('/^[^:\/\/]+?(?=:\/\/)/i', $path, $matches) && - in_array($matches[0], stream_get_wrappers()); - } - - /** - * Returns a correct set of slashes for given $path. (\\ for Windows paths and / for other paths.) - * - * @param string $path Path to check - * @return string Set of slashes ("\\" or "/") - */ - public static function normalizePath($path) - { - return Folder::correctSlashFor($path); - } - - /** - * Returns a correct set of slashes for given $path. (\\ for Windows paths and / for other paths.) - * - * @param string $path Path to check - * @return string Set of slashes ("\\" or "/") - */ - public static function correctSlashFor($path) - { - return Folder::isWindowsPath($path) ? '\\' : '/'; - } - - /** - * Returns $path with added terminating slash (corrected for Windows or other OS). - * - * @param string $path Path to check - * @return string Path with ending slash - */ - public static function slashTerm($path) - { - if (Folder::isSlashTerm($path)) { - return $path; - } - - return $path . Folder::correctSlashFor($path); - } - - /** - * Returns $path with $element added, with correct slash in-between. - * - * @param string $path Path - * @param string|array $element Element to add at end of path - * @return string Combined path - */ - public static function addPathElement($path, $element) - { - $element = (array)$element; - array_unshift($element, rtrim($path, DIRECTORY_SEPARATOR)); - - return implode(DIRECTORY_SEPARATOR, $element); - } - - /** - * Returns true if the Folder is in the given Cake path. - * - * @param string $path The path to check. - * @return bool - * @deprecated 3.2.12 This method will be removed in 4.0.0. Use inPath() instead. - */ - public function inCakePath($path = '') - { - deprecationWarning('Folder::inCakePath() is deprecated. Use Folder::inPath() instead.'); - $dir = substr(Folder::slashTerm(ROOT), 0, -1); - $newdir = $dir . $path; - - return $this->inPath($newdir); - } - - /** - * Returns true if the Folder is in the given path. - * - * @param string $path The absolute path to check that the current `pwd()` resides within. - * @param bool $reverse Reverse the search, check if the given `$path` resides within the current `pwd()`. - * @return bool - * @throws \InvalidArgumentException When the given `$path` argument is not an absolute path. - */ - public function inPath($path, $reverse = false) - { - if (!Folder::isAbsolute($path)) { - throw new InvalidArgumentException('The $path argument is expected to be an absolute path.'); - } - - $dir = Folder::slashTerm($path); - $current = Folder::slashTerm($this->pwd()); - - if (!$reverse) { - $return = preg_match('/^' . preg_quote($dir, '/') . '(.*)/', $current); - } else { - $return = preg_match('/^' . preg_quote($current, '/') . '(.*)/', $dir); - } - - return (bool)$return; - } - - /** - * Change the mode on a directory structure recursively. This includes changing the mode on files as well. - * - * @param string $path The path to chmod. - * @param int|bool $mode Octal value, e.g. 0755. - * @param bool $recursive Chmod recursively, set to false to only change the current directory. - * @param array $exceptions Array of files, directories to skip. - * @return bool Success. - */ - public function chmod($path, $mode = false, $recursive = true, array $exceptions = []) - { - if (!$mode) { - $mode = $this->mode; - } - - if ($recursive === false && is_dir($path)) { - //@codingStandardsIgnoreStart - if (@chmod($path, intval($mode, 8))) { - //@codingStandardsIgnoreEnd - $this->_messages[] = sprintf('%s changed to %s', $path, $mode); - - return true; - } - - $this->_errors[] = sprintf('%s NOT changed to %s', $path, $mode); - - return false; - } - - if (is_dir($path)) { - $paths = $this->tree($path); - - foreach ($paths as $type) { - foreach ($type as $fullpath) { - $check = explode(DIRECTORY_SEPARATOR, $fullpath); - $count = count($check); - - if (in_array($check[$count - 1], $exceptions)) { - continue; - } - - //@codingStandardsIgnoreStart - if (@chmod($fullpath, intval($mode, 8))) { - //@codingStandardsIgnoreEnd - $this->_messages[] = sprintf('%s changed to %s', $fullpath, $mode); - } else { - $this->_errors[] = sprintf('%s NOT changed to %s', $fullpath, $mode); - } - } - } - - if (empty($this->_errors)) { - return true; - } - } - - return false; - } - - /** - * Returns an array of subdirectories for the provided or current path. - * - * @param string|null $path The directory path to get subdirectories for. - * @param bool $fullPath Whether to return the full path or only the directory name. - * @return array Array of subdirectories for the provided or current path. - */ - public function subdirectories($path = null, $fullPath = true) - { - if (!$path) { - $path = $this->path; - } - $subdirectories = []; - - try { - $iterator = new DirectoryIterator($path); - } catch (Exception $e) { - return []; - } - - foreach ($iterator as $item) { - if (!$item->isDir() || $item->isDot()) { - continue; - } - $subdirectories[] = $fullPath ? $item->getRealPath() : $item->getFilename(); - } - - return $subdirectories; - } - - /** - * Returns an array of nested directories and files in each directory - * - * @param string|null $path the directory path to build the tree from - * @param array|bool $exceptions Either an array of files/folder to exclude - * or boolean true to not grab dot files/folders - * @param string|null $type either 'file' or 'dir'. Null returns both files and directories - * @return array Array of nested directories and files in each directory - */ - public function tree($path = null, $exceptions = false, $type = null) - { - if (!$path) { - $path = $this->path; - } - $files = []; - $directories = [$path]; - - if (is_array($exceptions)) { - $exceptions = array_flip($exceptions); - } - $skipHidden = false; - if ($exceptions === true) { - $skipHidden = true; - } elseif (isset($exceptions['.'])) { - $skipHidden = true; - unset($exceptions['.']); - } - - try { - $directory = new RecursiveDirectoryIterator($path, RecursiveDirectoryIterator::KEY_AS_PATHNAME | RecursiveDirectoryIterator::CURRENT_AS_SELF); - $iterator = new RecursiveIteratorIterator($directory, RecursiveIteratorIterator::SELF_FIRST); - } catch (Exception $e) { - if ($type === null) { - return [[], []]; - } - - return []; - } - - foreach ($iterator as $itemPath => $fsIterator) { - if ($skipHidden) { - $subPathName = $fsIterator->getSubPathname(); - if ($subPathName{0} === '.' || strpos($subPathName, DIRECTORY_SEPARATOR . '.') !== false) { - continue; - } - } - $item = $fsIterator->current(); - if (!empty($exceptions) && isset($exceptions[$item->getFilename()])) { - continue; - } - - if ($item->isFile()) { - $files[] = $itemPath; - } elseif ($item->isDir() && !$item->isDot()) { - $directories[] = $itemPath; - } - } - if ($type === null) { - return [$directories, $files]; - } - if ($type === 'dir') { - return $directories; - } - - return $files; - } - - /** - * Create a directory structure recursively. - * - * Can be used to create deep path structures like `/foo/bar/baz/shoe/horn` - * - * @param string $pathname The directory structure to create. Either an absolute or relative - * path. If the path is relative and exists in the process' cwd it will not be created. - * Otherwise relative paths will be prefixed with the current pwd(). - * @param int|bool $mode octal value 0755 - * @return bool Returns TRUE on success, FALSE on failure - */ - public function create($pathname, $mode = false) - { - if (is_dir($pathname) || empty($pathname)) { - return true; - } - - if (!self::isAbsolute($pathname)) { - $pathname = self::addPathElement($this->pwd(), $pathname); - } - - if (!$mode) { - $mode = $this->mode; - } - - if (is_file($pathname)) { - $this->_errors[] = sprintf('%s is a file', $pathname); - - return false; - } - $pathname = rtrim($pathname, DIRECTORY_SEPARATOR); - $nextPathname = substr($pathname, 0, strrpos($pathname, DIRECTORY_SEPARATOR)); - - if ($this->create($nextPathname, $mode)) { - if (!file_exists($pathname)) { - $old = umask(0); - if (mkdir($pathname, $mode, true)) { - umask($old); - $this->_messages[] = sprintf('%s created', $pathname); - - return true; - } - umask($old); - $this->_errors[] = sprintf('%s NOT created', $pathname); - - return false; - } - } - - return false; - } - - /** - * Returns the size in bytes of this Folder and its contents. - * - * @return int size in bytes of current folder - */ - public function dirsize() - { - $size = 0; - $directory = Folder::slashTerm($this->path); - $stack = [$directory]; - $count = count($stack); - for ($i = 0, $j = $count; $i < $j; ++$i) { - if (is_file($stack[$i])) { - $size += filesize($stack[$i]); - } elseif (is_dir($stack[$i])) { - $dir = dir($stack[$i]); - if ($dir) { - while (($entry = $dir->read()) !== false) { - if ($entry === '.' || $entry === '..') { - continue; - } - $add = $stack[$i] . $entry; - - if (is_dir($stack[$i] . $entry)) { - $add = Folder::slashTerm($add); - } - $stack[] = $add; - } - $dir->close(); - } - } - $j = count($stack); - } - - return $size; - } - - /** - * Recursively Remove directories if the system allows. - * - * @param string|null $path Path of directory to delete - * @return bool Success - */ - public function delete($path = null) - { - if (!$path) { - $path = $this->pwd(); - } - if (!$path) { - return false; - } - $path = Folder::slashTerm($path); - if (is_dir($path)) { - try { - $directory = new RecursiveDirectoryIterator($path, RecursiveDirectoryIterator::CURRENT_AS_SELF); - $iterator = new RecursiveIteratorIterator($directory, RecursiveIteratorIterator::CHILD_FIRST); - } catch (Exception $e) { - return false; - } - - foreach ($iterator as $item) { - $filePath = $item->getPathname(); - if ($item->isFile() || $item->isLink()) { - //@codingStandardsIgnoreStart - if (@unlink($filePath)) { - //@codingStandardsIgnoreEnd - $this->_messages[] = sprintf('%s removed', $filePath); - } else { - $this->_errors[] = sprintf('%s NOT removed', $filePath); - } - } elseif ($item->isDir() && !$item->isDot()) { - //@codingStandardsIgnoreStart - if (@rmdir($filePath)) { - //@codingStandardsIgnoreEnd - $this->_messages[] = sprintf('%s removed', $filePath); - } else { - $this->_errors[] = sprintf('%s NOT removed', $filePath); - - return false; - } - } - } - - $path = rtrim($path, DIRECTORY_SEPARATOR); - //@codingStandardsIgnoreStart - if (@rmdir($path)) { - //@codingStandardsIgnoreEnd - $this->_messages[] = sprintf('%s removed', $path); - } else { - $this->_errors[] = sprintf('%s NOT removed', $path); - - return false; - } - } - - return true; - } - - /** - * Recursive directory copy. - * - * ### Options - * - * - `to` The directory to copy to. - * - `from` The directory to copy from, this will cause a cd() to occur, changing the results of pwd(). - * - `mode` The mode to copy the files/directories with as integer, e.g. 0775. - * - `skip` Files/directories to skip. - * - `scheme` Folder::MERGE, Folder::OVERWRITE, Folder::SKIP - * - `recursive` Whether to copy recursively or not (default: true - recursive) - * - * @param array|string $options Either an array of options (see above) or a string of the destination directory. - * @return bool Success. - */ - public function copy($options) - { - if (!$this->pwd()) { - return false; - } - $to = null; - if (is_string($options)) { - $to = $options; - $options = []; - } - $options += [ - 'to' => $to, - 'from' => $this->path, - 'mode' => $this->mode, - 'skip' => [], - 'scheme' => Folder::MERGE, - 'recursive' => true - ]; - - $fromDir = $options['from']; - $toDir = $options['to']; - $mode = $options['mode']; - - if (!$this->cd($fromDir)) { - $this->_errors[] = sprintf('%s not found', $fromDir); - - return false; - } - - if (!is_dir($toDir)) { - $this->create($toDir, $mode); - } - - if (!is_writable($toDir)) { - $this->_errors[] = sprintf('%s not writable', $toDir); - - return false; - } - - $exceptions = array_merge(['.', '..', '.svn'], $options['skip']); - //@codingStandardsIgnoreStart - if ($handle = @opendir($fromDir)) { - //@codingStandardsIgnoreEnd - while (($item = readdir($handle)) !== false) { - $to = Folder::addPathElement($toDir, $item); - if (($options['scheme'] != Folder::SKIP || !is_dir($to)) && !in_array($item, $exceptions)) { - $from = Folder::addPathElement($fromDir, $item); - if (is_file($from) && (!is_file($to) || $options['scheme'] != Folder::SKIP)) { - if (copy($from, $to)) { - chmod($to, intval($mode, 8)); - touch($to, filemtime($from)); - $this->_messages[] = sprintf('%s copied to %s', $from, $to); - } else { - $this->_errors[] = sprintf('%s NOT copied to %s', $from, $to); - } - } - - if (is_dir($from) && file_exists($to) && $options['scheme'] === Folder::OVERWRITE) { - $this->delete($to); - } - - if (is_dir($from) && $options['recursive'] === false) { - continue; - } - - if (is_dir($from) && !file_exists($to)) { - $old = umask(0); - if (mkdir($to, $mode, true)) { - umask($old); - $old = umask(0); - chmod($to, $mode); - umask($old); - $this->_messages[] = sprintf('%s created', $to); - $options = ['to' => $to, 'from' => $from] + $options; - $this->copy($options); - } else { - $this->_errors[] = sprintf('%s not created', $to); - } - } elseif (is_dir($from) && $options['scheme'] === Folder::MERGE) { - $options = ['to' => $to, 'from' => $from] + $options; - $this->copy($options); - } - } - } - closedir($handle); - } else { - return false; - } - - return empty($this->_errors); - } - - /** - * Recursive directory move. - * - * ### Options - * - * - `to` The directory to copy to. - * - `from` The directory to copy from, this will cause a cd() to occur, changing the results of pwd(). - * - `chmod` The mode to copy the files/directories with. - * - `skip` Files/directories to skip. - * - `scheme` Folder::MERGE, Folder::OVERWRITE, Folder::SKIP - * - `recursive` Whether to copy recursively or not (default: true - recursive) - * - * @param array|string $options (to, from, chmod, skip, scheme) - * @return bool Success - */ - public function move($options) - { - $to = null; - if (is_string($options)) { - $to = $options; - $options = (array)$options; - } - $options += ['to' => $to, 'from' => $this->path, 'mode' => $this->mode, 'skip' => [], 'recursive' => true]; - - if ($this->copy($options) && $this->delete($options['from'])) { - return (bool)$this->cd($options['to']); - } - - return false; - } - - /** - * get messages from latest method - * - * @param bool $reset Reset message stack after reading - * @return array - */ - public function messages($reset = true) - { - $messages = $this->_messages; - if ($reset) { - $this->_messages = []; - } - - return $messages; - } - - /** - * get error from latest method - * - * @param bool $reset Reset error stack after reading - * @return array - */ - public function errors($reset = true) - { - $errors = $this->_errors; - if ($reset) { - $this->_errors = []; - } - - return $errors; - } - - /** - * Get the real path (taking ".." and such into account) - * - * @param string $path Path to resolve - * @return string|false The resolved path - */ - public function realpath($path) - { - if (strpos($path, '..') === false) { - if (!Folder::isAbsolute($path)) { - $path = Folder::addPathElement($this->path, $path); - } - - return $path; - } - $path = str_replace('/', DIRECTORY_SEPARATOR, trim($path)); - $parts = explode(DIRECTORY_SEPARATOR, $path); - $newparts = []; - $newpath = ''; - if ($path[0] === DIRECTORY_SEPARATOR) { - $newpath = DIRECTORY_SEPARATOR; - } - - while (($part = array_shift($parts)) !== null) { - if ($part === '.' || $part === '') { - continue; - } - if ($part === '..') { - if (!empty($newparts)) { - array_pop($newparts); - continue; - } - - return false; - } - $newparts[] = $part; - } - $newpath .= implode(DIRECTORY_SEPARATOR, $newparts); - - return Folder::slashTerm($newpath); - } - - /** - * Returns true if given $path ends in a slash (i.e. is slash-terminated). - * - * @param string $path Path to check - * @return bool true if path ends with slash, false otherwise - */ - public static function isSlashTerm($path) - { - $lastChar = $path[strlen($path) - 1]; - - return $lastChar === '/' || $lastChar === '\\'; - } -} diff --git a/vendor/cakephp/cakephp/src/Filesystem/LICENSE.txt b/vendor/cakephp/cakephp/src/Filesystem/LICENSE.txt deleted file mode 100644 index 0c4b793..0000000 --- a/vendor/cakephp/cakephp/src/Filesystem/LICENSE.txt +++ /dev/null @@ -1,22 +0,0 @@ -The MIT License (MIT) - -CakePHP(tm) : The Rapid Development PHP Framework (https://cakephp.org) -Copyright (c) 2005-2016, Cake Software Foundation, Inc. (https://cakefoundation.org) - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. diff --git a/vendor/cakephp/cakephp/src/Filesystem/README.md b/vendor/cakephp/cakephp/src/Filesystem/README.md deleted file mode 100644 index 769837d..0000000 --- a/vendor/cakephp/cakephp/src/Filesystem/README.md +++ /dev/null @@ -1,35 +0,0 @@ -[![Total Downloads](https://img.shields.io/packagist/dt/cakephp/filesystem.svg?style=flat-square)](https://packagist.org/packages/cakephp/filesystem) -[![License](https://img.shields.io/badge/license-MIT-blue.svg?style=flat-square)](LICENSE.txt) - -# CakePHP Filesystem Library - -The Folder and File utilities are convenience classes to help you read from and write/append to files; list files within a folder and other common directory related tasks. - -## Basic Usage - -Create a folder instance and search for all the `.ctp` files within it: - -```php -use Cake\Filesystem\Folder; - -$dir = new Folder('/path/to/folder'); -$files = $dir->find('.*\.ctp'); -``` - -Now you can loop through the files and read from or write/append to the contents or simply delete the file: - -```php -foreach ($files as $file) { - $file = new File($dir->pwd() . DIRECTORY_SEPARATOR . $file); - $contents = $file->read(); - // $file->write('I am overwriting the contents of this file'); - // $file->append('I am adding to the bottom of this file.'); - // $file->delete(); // I am deleting this file - $file->close(); // Be sure to close the file when you're done -} -``` - -## Documentation - -Please make sure you check the [official -documentation](https://book.cakephp.org/3.0/en/core-libraries/file-folder.html) diff --git a/vendor/cakephp/cakephp/src/Filesystem/composer.json b/vendor/cakephp/cakephp/src/Filesystem/composer.json deleted file mode 100644 index e5dcb07..0000000 --- a/vendor/cakephp/cakephp/src/Filesystem/composer.json +++ /dev/null @@ -1,34 +0,0 @@ -{ - "name": "cakephp/filesystem", - "description": "CakePHP filesystem convenience classes to help you work with files and folders.", - "type": "library", - "keywords": [ - "cakephp", - "filesystem", - "files", - "folders" - ], - "homepage": "https://cakephp.org", - "license": "MIT", - "authors": [ - { - "name": "CakePHP Community", - "homepage": "https://github.com/cakephp/filesystem/graphs/contributors" - } - ], - "support": { - "issues": "https://github.com/cakephp/cakephp/issues", - "forum": "https://stackoverflow.com/tags/cakephp", - "irc": "irc://irc.freenode.org/cakephp", - "source": "https://github.com/cakephp/filesystem" - }, - "require": { - "php": ">=5.6.0", - "cakephp/core": "^3.6.0" - }, - "autoload": { - "psr-4": { - "Cake\\Filesystem\\": "." - } - } -} diff --git a/vendor/cakephp/cakephp/src/Form/Form.php b/vendor/cakephp/cakephp/src/Form/Form.php deleted file mode 100644 index 5c2197b..0000000 --- a/vendor/cakephp/cakephp/src/Form/Form.php +++ /dev/null @@ -1,322 +0,0 @@ -schema()` and `$form->validator()`. - * - * Forms are conventionally placed in the `App\Form` namespace. - */ -class Form implements EventListenerInterface, EventDispatcherInterface, ValidatorAwareInterface -{ - /** - * Schema class. - * - * @var string - */ - protected $_schemaClass = Schema::class; - - use EventDispatcherTrait; - use ValidatorAwareTrait; - - /** - * The alias this object is assigned to validators as. - * - * @var string - */ - const VALIDATOR_PROVIDER_NAME = 'form'; - - /** - * The name of the event dispatched when a validator has been built. - * - * @var string - */ - const BUILD_VALIDATOR_EVENT = 'Form.buildValidator'; - - /** - * The schema used by this form. - * - * @var \Cake\Form\Schema - */ - protected $_schema; - - /** - * The errors if any - * - * @var array - */ - protected $_errors = []; - - /** - * The validator used by this form. - * - * @var \Cake\Validation\Validator - */ - protected $_validator; - - /** - * Constructor - * - * @param \Cake\Event\EventManager|null $eventManager The event manager. - * Defaults to a new instance. - */ - public function __construct(EventManager $eventManager = null) - { - if ($eventManager !== null) { - $this->setEventManager($eventManager); - } - - $this->getEventManager()->on($this); - } - - /** - * Get the Form callbacks this form is interested in. - * - * The conventional method map is: - * - * - Form.buildValidator => buildValidator - * - * @return array - */ - public function implementedEvents() - { - return [ - 'Form.buildValidator' => 'buildValidator', - ]; - } - - /** - * Get/Set the schema for this form. - * - * This method will call `_buildSchema()` when the schema - * is first built. This hook method lets you configure the - * schema or load a pre-defined one. - * - * @param \Cake\Form\Schema|null $schema The schema to set, or null. - * @return \Cake\Form\Schema the schema instance. - */ - public function schema(Schema $schema = null) - { - if ($schema === null && empty($this->_schema)) { - $schema = $this->_buildSchema(new $this->_schemaClass); - } - if ($schema) { - $this->_schema = $schema; - } - - return $this->_schema; - } - - /** - * A hook method intended to be implemented by subclasses. - * - * You can use this method to define the schema using - * the methods on Cake\Form\Schema, or loads a pre-defined - * schema from a concrete class. - * - * @param \Cake\Form\Schema $schema The schema to customize. - * @return \Cake\Form\Schema The schema to use. - */ - protected function _buildSchema(Schema $schema) - { - return $schema; - } - - /** - * Get/Set the validator for this form. - * - * This method will call `_buildValidator()` when the validator - * is first built. This hook method lets you configure the - * validator or load a pre-defined one. - * - * @param \Cake\Validation\Validator|null $validator The validator to set, or null. - * @return \Cake\Validation\Validator the validator instance. - * @deprecated 3.6.0 Use Form::getValidator()/setValidator() instead. - */ - public function validator(Validator $validator = null) - { - deprecationWarning( - 'Form::validator() is deprecated. ' . - 'Use Form::getValidator()/setValidator() instead.' - ); - - if ($validator === null && empty($this->_validator)) { - $validator = $this->_buildValidator(new $this->_validatorClass); - } - if ($validator) { - $this->_validator = $validator; - $this->setValidator('default', $validator); - } - - return $this->getValidator(); - } - - /** - * A hook method intended to be implemented by subclasses. - * - * You can use this method to define the validator using - * the methods on Cake\Validation\Validator or loads a pre-defined - * validator from a concrete class. - * - * @param \Cake\Validation\Validator $validator The validator to customize. - * @return \Cake\Validation\Validator The validator to use. - * @deprecated 3.6.0 Use Form::getValidator()/setValidator() and buildValidator() instead. - */ - protected function _buildValidator(Validator $validator) - { - return $validator; - } - - /** - * Callback method for Form.buildValidator event. - * - * @param \Cake\Event\Event $event The Form.buildValidator event instance. - * @param \Cake\Validation\Validator $validator The validator to customize. - * @param string $name Validator name - * @return void - */ - public function buildValidator(Event $event, Validator $validator, $name) - { - $this->_buildValidator($validator); - } - - /** - * Used to check if $data passes this form's validation. - * - * @param array $data The data to check. - * @return bool Whether or not the data is valid. - */ - public function validate(array $data) - { - $validator = $this->getValidator(); - if (!$validator->count()) { - $method = new ReflectionMethod($this, 'validator'); - if ($method->getDeclaringClass()->getName() !== __CLASS__) { - $validator = $this->validator(); - } - } - $this->_errors = $validator->errors($data); - - return count($this->_errors) === 0; - } - - /** - * Get the errors in the form - * - * Will return the errors from the last call - * to `validate()` or `execute()`. - * - * @return array Last set validation errors. - */ - public function errors() - { - return $this->_errors; - } - - /** - * Set the errors in the form. - * - * ``` - * $errors = [ - * 'field_name' => ['rule_name' => 'message'] - * ]; - * - * $form->setErrors($errors); - * ``` - * - * @since 3.5.1 - * @param array $errors Errors list. - * @return $this - */ - public function setErrors(array $errors) - { - $this->_errors = $errors; - - return $this; - } - - /** - * Execute the form if it is valid. - * - * First validates the form, then calls the `_execute()` hook method. - * This hook method can be implemented in subclasses to perform - * the action of the form. This may be sending email, interacting - * with a remote API, or anything else you may need. - * - * @param array $data Form data. - * @return bool False on validation failure, otherwise returns the - * result of the `_execute()` method. - */ - public function execute(array $data) - { - if (!$this->validate($data)) { - return false; - } - - return $this->_execute($data); - } - - /** - * Hook method to be implemented in subclasses. - * - * Used by `execute()` to execute the form's action. - * - * @param array $data Form data. - * @return bool - */ - protected function _execute(array $data) - { - return true; - } - - /** - * Get the printable version of a Form instance. - * - * @return array - */ - public function __debugInfo() - { - $special = [ - '_schema' => $this->schema()->__debugInfo(), - '_errors' => $this->errors(), - '_validator' => $this->getValidator()->__debugInfo() - ]; - - return $special + get_object_vars($this); - } -} diff --git a/vendor/cakephp/cakephp/src/Form/Schema.php b/vendor/cakephp/cakephp/src/Form/Schema.php deleted file mode 100644 index 08d11fc..0000000 --- a/vendor/cakephp/cakephp/src/Form/Schema.php +++ /dev/null @@ -1,142 +0,0 @@ - null, - 'length' => null, - 'precision' => null, - 'default' => null, - ]; - - /** - * Add multiple fields to the schema. - * - * @param array $fields The fields to add. - * @return $this - */ - public function addFields(array $fields) - { - foreach ($fields as $name => $attrs) { - $this->addField($name, $attrs); - } - - return $this; - } - - /** - * Adds a field to the schema. - * - * @param string $name The field name. - * @param string|array $attrs The attributes for the field, or the type - * as a string. - * @return $this - */ - public function addField($name, $attrs) - { - if (is_string($attrs)) { - $attrs = ['type' => $attrs]; - } - $attrs = array_intersect_key($attrs, $this->_fieldDefaults); - $this->_fields[$name] = $attrs + $this->_fieldDefaults; - - return $this; - } - - /** - * Removes a field to the schema. - * - * @param string $name The field to remove. - * @return $this - */ - public function removeField($name) - { - unset($this->_fields[$name]); - - return $this; - } - - /** - * Get the list of fields in the schema. - * - * @return array The list of field names. - */ - public function fields() - { - return array_keys($this->_fields); - } - - /** - * Get the attributes for a given field. - * - * @param string $name The field name. - * @return null|array The attributes for a field, or null. - */ - public function field($name) - { - if (!isset($this->_fields[$name])) { - return null; - } - - return $this->_fields[$name]; - } - - /** - * Get the type of the named field. - * - * @param string $name The name of the field. - * @return string|null Either the field type or null if the - * field does not exist. - */ - public function fieldType($name) - { - $field = $this->field($name); - if (!$field) { - return null; - } - - return $field['type']; - } - - /** - * Get the printable version of this object - * - * @return array - */ - public function __debugInfo() - { - return [ - '_fields' => $this->_fields - ]; - } -} diff --git a/vendor/cakephp/cakephp/src/Http/ActionDispatcher.php b/vendor/cakephp/cakephp/src/Http/ActionDispatcher.php deleted file mode 100644 index 00bbec1..0000000 --- a/vendor/cakephp/cakephp/src/Http/ActionDispatcher.php +++ /dev/null @@ -1,170 +0,0 @@ -setEventManager($eventManager); - } - foreach ($filters as $filter) { - $this->addFilter($filter); - } - $this->factory = $factory ?: new ControllerFactory(); - } - - /** - * Dispatches a Request & Response - * - * @param \Cake\Http\ServerRequest $request The request to dispatch. - * @param \Cake\Http\Response $response The response to dispatch. - * @return \Cake\Http\Response A modified/replaced response. - */ - public function dispatch(ServerRequest $request, Response $response) - { - if (Router::getRequest(true) !== $request) { - Router::pushRequest($request); - } - $beforeEvent = $this->dispatchEvent('Dispatcher.beforeDispatch', compact('request', 'response')); - - $request = $beforeEvent->getData('request'); - if ($beforeEvent->getResult() instanceof Response) { - return $beforeEvent->getResult(); - } - - // Use the controller built by an beforeDispatch - // event handler if there is one. - if ($beforeEvent->getData('controller') instanceof Controller) { - $controller = $beforeEvent->getData('controller'); - } else { - $controller = $this->factory->create($request, $response); - } - - $response = $this->_invoke($controller); - if ($request->getParam('return')) { - return $response; - } - - $afterEvent = $this->dispatchEvent('Dispatcher.afterDispatch', compact('request', 'response')); - - return $afterEvent->getData('response'); - } - - /** - * Invoke a controller's action and wrapping methods. - * - * @param \Cake\Controller\Controller $controller The controller to invoke. - * @return \Cake\Http\Response The response - * @throws \LogicException If the controller action returns a non-response value. - */ - protected function _invoke(Controller $controller) - { - $this->dispatchEvent('Dispatcher.invokeController', ['controller' => $controller]); - - $result = $controller->startupProcess(); - if ($result instanceof Response) { - return $result; - } - - $response = $controller->invokeAction(); - if ($response !== null && !($response instanceof Response)) { - throw new LogicException('Controller actions can only return Cake\Http\Response or null.'); - } - - if (!$response && $controller->isAutoRenderEnabled()) { - $controller->render(); - } - - $result = $controller->shutdownProcess(); - if ($result instanceof Response) { - return $result; - } - if (!$response) { - $response = $controller->response; - } - - return $response; - } - - /** - * Add a filter to this dispatcher. - * - * The added filter will be attached to the event manager used - * by this dispatcher. - * - * @param \Cake\Event\EventListenerInterface $filter The filter to connect. Can be - * any EventListenerInterface. Typically an instance of \Cake\Routing\DispatcherFilter. - * @return void - * @deprecated This is only available for backwards compatibility with DispatchFilters - */ - public function addFilter(EventListenerInterface $filter) - { - deprecationWarning( - 'ActionDispatcher::addFilter() is deprecated. ' . - 'This is only available for backwards compatibility with DispatchFilters' - ); - - $this->filters[] = $filter; - $this->getEventManager()->on($filter); - } - - /** - * Get the connected filters. - * - * @return array - */ - public function getFilters() - { - return $this->filters; - } -} diff --git a/vendor/cakephp/cakephp/src/Http/BaseApplication.php b/vendor/cakephp/cakephp/src/Http/BaseApplication.php deleted file mode 100644 index b53391c..0000000 --- a/vendor/cakephp/cakephp/src/Http/BaseApplication.php +++ /dev/null @@ -1,240 +0,0 @@ -configDir = $configDir; - $this->plugins = Plugin::getCollection(); - $this->_eventManager = $eventManager ?: EventManager::instance(); - } - - /** - * @param \Cake\Http\MiddlewareQueue $middleware The middleware queue to set in your App Class - * @return \Cake\Http\MiddlewareQueue - */ - abstract public function middleware($middleware); - - /** - * {@inheritDoc} - */ - public function pluginMiddleware($middleware) - { - foreach ($this->plugins->with('middleware') as $plugin) { - $middleware = $plugin->middleware($middleware); - } - - return $middleware; - } - - /** - * {@inheritDoc} - */ - public function addPlugin($name, array $config = []) - { - if (is_string($name)) { - $plugin = $this->makePlugin($name, $config); - } else { - $plugin = $name; - } - $this->plugins->add($plugin); - - return $this; - } - - /** - * Get the plugin collection in use. - * - * @return \Cake\Core\PluginCollection - */ - public function getPlugins() - { - return $this->plugins; - } - - /** - * Create a plugin instance from a classname and configuration - * - * @param string $name The plugin classname - * @param array $config Configuration options for the plugin - * @return \Cake\Core\PluginInterface - */ - public function makePlugin($name, array $config) - { - if (strpos($name, '\\') === false) { - $name = str_replace('/', '\\', $name) . '\\' . 'Plugin'; - } - if (!class_exists($name)) { - throw new InvalidArgumentException( - "The plugin class `{$name}` cannot be found. " . - 'Ensure your autoloader is correct.' - ); - } - $plugin = new $name($config); - if (!$plugin instanceof PluginInterface) { - throw new InvalidArgumentException("The `{$name}` plugin does not implement Cake\Core\PluginInterface."); - } - - return $plugin; - } - - /** - * {@inheritDoc} - */ - public function bootstrap() - { - require_once $this->configDir . '/bootstrap.php'; - } - - /** - * {@inheritDoc} - */ - public function pluginBootstrap() - { - foreach ($this->plugins->with('bootstrap') as $plugin) { - $plugin->bootstrap($this); - } - } - - /** - * {@inheritDoc} - * - * By default this will load `config/routes.php` for ease of use and backwards compatibility. - * - * @param \Cake\Routing\RouteBuilder $routes A route builder to add routes into. - * @return void - */ - public function routes($routes) - { - if (!Router::$initialized) { - // Prevent routes from being loaded again - Router::$initialized = true; - - require $this->configDir . '/routes.php'; - } - } - - /** - * {@inheritDoc} - */ - public function pluginRoutes($routes) - { - foreach ($this->plugins->with('routes') as $plugin) { - $plugin->routes($routes); - } - - return $routes; - } - - /** - * Define the console commands for an application. - * - * By default all commands in CakePHP, plugins and the application will be - * loaded using conventions based names. - * - * @param \Cake\Console\CommandCollection $commands The CommandCollection to add commands into. - * @return \Cake\Console\CommandCollection The updated collection. - */ - public function console($commands) - { - return $commands->addMany($commands->autoDiscover()); - } - - /** - * {@inheritDoc} - */ - public function pluginConsole($commands) - { - foreach ($this->plugins->with('console') as $plugin) { - $commands = $plugin->console($commands); - } - - return $commands; - } - - /** - * Invoke the application. - * - * - Convert the PSR response into CakePHP equivalents. - * - Create the controller that will handle this request. - * - Invoke the controller. - * - * @param \Psr\Http\Message\ServerRequestInterface $request The request - * @param \Psr\Http\Message\ResponseInterface $response The response - * @param callable $next The next middleware - * @return \Psr\Http\Message\ResponseInterface - */ - public function __invoke(ServerRequestInterface $request, ResponseInterface $response, $next) - { - return $this->getDispatcher()->dispatch($request, $response); - } - - /** - * Get the ActionDispatcher. - * - * @return \Cake\Http\ActionDispatcher - */ - protected function getDispatcher() - { - return new ActionDispatcher(null, $this->getEventManager(), DispatcherFactory::filters()); - } -} diff --git a/vendor/cakephp/cakephp/src/Http/CallbackStream.php b/vendor/cakephp/cakephp/src/Http/CallbackStream.php deleted file mode 100644 index f165f31..0000000 --- a/vendor/cakephp/cakephp/src/Http/CallbackStream.php +++ /dev/null @@ -1,49 +0,0 @@ -detach(); - $result = $callback ? $callback() : ''; - if (!is_string($result)) { - return ''; - } - - return $result; - } -} diff --git a/vendor/cakephp/cakephp/src/Http/Client.php b/vendor/cakephp/cakephp/src/Http/Client.php deleted file mode 100644 index 16dc8a2..0000000 --- a/vendor/cakephp/cakephp/src/Http/Client.php +++ /dev/null @@ -1,614 +0,0 @@ -get('/users', [], ['type' => 'json']); - * ``` - * - * The `type` option sets both the `Content-Type` and `Accept` header, to - * the same mime type. When using `type` you can use either a full mime - * type or an alias. If you need different types in the Accept and Content-Type - * headers you should set them manually and not use `type` - * - * ### Using authentication - * - * By using the `auth` key you can use authentication. The type sub option - * can be used to specify which authentication strategy you want to use. - * CakePHP comes with a few built-in strategies: - * - * - Basic - * - Digest - * - Oauth - * - * ### Using proxies - * - * By using the `proxy` key you can set authentication credentials for - * a proxy if you need to use one. The type sub option can be used to - * specify which authentication strategy you want to use. - * CakePHP comes with built-in support for basic authentication. - * - * @mixin \Cake\Core\InstanceConfigTrait - */ -class Client -{ - - use InstanceConfigTrait; - - /** - * Default configuration for the client. - * - * @var array - */ - protected $_defaultConfig = [ - 'adapter' => 'Cake\Http\Client\Adapter\Stream', - 'host' => null, - 'port' => null, - 'scheme' => 'http', - 'timeout' => 30, - 'ssl_verify_peer' => true, - 'ssl_verify_peer_name' => true, - 'ssl_verify_depth' => 5, - 'ssl_verify_host' => true, - 'redirect' => false, - ]; - - /** - * List of cookies from responses made with this client. - * - * Cookies are indexed by the cookie's domain or - * request host name. - * - * @var \Cake\Http\Cookie\CookieCollection - */ - protected $_cookies; - - /** - * Adapter for sending requests. Defaults to - * Cake\Http\Client\Adapter\Stream - * - * @var \Cake\Http\Client\Adapter\Stream - */ - protected $_adapter; - - /** - * Create a new HTTP Client. - * - * ### Config options - * - * You can set the following options when creating a client: - * - * - host - The hostname to do requests on. - * - port - The port to use. - * - scheme - The default scheme/protocol to use. Defaults to http. - * - timeout - The timeout in seconds. Defaults to 30 - * - ssl_verify_peer - Whether or not SSL certificates should be validated. - * Defaults to true. - * - ssl_verify_peer_name - Whether or not peer names should be validated. - * Defaults to true. - * - ssl_verify_depth - The maximum certificate chain depth to traverse. - * Defaults to 5. - * - ssl_verify_host - Verify that the certificate and hostname match. - * Defaults to true. - * - redirect - Number of redirects to follow. Defaults to false. - * - * @param array $config Config options for scoped clients. - */ - public function __construct($config = []) - { - $this->setConfig($config); - - $adapter = $this->_config['adapter']; - $this->setConfig('adapter', null); - if (is_string($adapter)) { - $adapter = new $adapter(); - } - $this->_adapter = $adapter; - - if (!empty($this->_config['cookieJar'])) { - $this->_cookies = $this->_config['cookieJar']; - $this->setConfig('cookieJar', null); - } else { - $this->_cookies = new CookieCollection(); - } - } - - /** - * Get the cookies stored in the Client. - * - * @return \Cake\Http\Client\CookieCollection - */ - public function cookies() - { - return $this->_cookies; - } - - /** - * Adds a cookie to the Client collection. - * - * @param \Cake\Http\Cookie\CookieInterface $cookie Cookie object. - * @return $this - */ - public function addCookie(CookieInterface $cookie) - { - if (!$cookie->getDomain() || !$cookie->getPath()) { - throw new InvalidArgumentException('Cookie must have a domain and a path set.'); - } - $this->_cookies = $this->_cookies->add($cookie); - - return $this; - } - - /** - * Do a GET request. - * - * The $data argument supports a special `_content` key - * for providing a request body in a GET request. This is - * generally not used, but services like ElasticSearch use - * this feature. - * - * @param string $url The url or path you want to request. - * @param array $data The query data you want to send. - * @param array $options Additional options for the request. - * @return \Cake\Http\Client\Response - */ - public function get($url, $data = [], array $options = []) - { - $options = $this->_mergeOptions($options); - $body = null; - if (isset($data['_content'])) { - $body = $data['_content']; - unset($data['_content']); - } - $url = $this->buildUrl($url, $data, $options); - - return $this->_doRequest( - Request::METHOD_GET, - $url, - $body, - $options - ); - } - - /** - * Do a POST request. - * - * @param string $url The url or path you want to request. - * @param mixed $data The post data you want to send. - * @param array $options Additional options for the request. - * @return \Cake\Http\Client\Response - */ - public function post($url, $data = [], array $options = []) - { - $options = $this->_mergeOptions($options); - $url = $this->buildUrl($url, [], $options); - - return $this->_doRequest(Request::METHOD_POST, $url, $data, $options); - } - - /** - * Do a PUT request. - * - * @param string $url The url or path you want to request. - * @param mixed $data The request data you want to send. - * @param array $options Additional options for the request. - * @return \Cake\Http\Client\Response - */ - public function put($url, $data = [], array $options = []) - { - $options = $this->_mergeOptions($options); - $url = $this->buildUrl($url, [], $options); - - return $this->_doRequest(Request::METHOD_PUT, $url, $data, $options); - } - - /** - * Do a PATCH request. - * - * @param string $url The url or path you want to request. - * @param mixed $data The request data you want to send. - * @param array $options Additional options for the request. - * @return \Cake\Http\Client\Response - */ - public function patch($url, $data = [], array $options = []) - { - $options = $this->_mergeOptions($options); - $url = $this->buildUrl($url, [], $options); - - return $this->_doRequest(Request::METHOD_PATCH, $url, $data, $options); - } - - /** - * Do an OPTIONS request. - * - * @param string $url The url or path you want to request. - * @param mixed $data The request data you want to send. - * @param array $options Additional options for the request. - * @return \Cake\Http\Client\Response - */ - public function options($url, $data = [], array $options = []) - { - $options = $this->_mergeOptions($options); - $url = $this->buildUrl($url, [], $options); - - return $this->_doRequest(Request::METHOD_OPTIONS, $url, $data, $options); - } - - /** - * Do a TRACE request. - * - * @param string $url The url or path you want to request. - * @param mixed $data The request data you want to send. - * @param array $options Additional options for the request. - * @return \Cake\Http\Client\Response - */ - public function trace($url, $data = [], array $options = []) - { - $options = $this->_mergeOptions($options); - $url = $this->buildUrl($url, [], $options); - - return $this->_doRequest(Request::METHOD_TRACE, $url, $data, $options); - } - - /** - * Do a DELETE request. - * - * @param string $url The url or path you want to request. - * @param mixed $data The request data you want to send. - * @param array $options Additional options for the request. - * @return \Cake\Http\Client\Response - */ - public function delete($url, $data = [], array $options = []) - { - $options = $this->_mergeOptions($options); - $url = $this->buildUrl($url, [], $options); - - return $this->_doRequest(Request::METHOD_DELETE, $url, $data, $options); - } - - /** - * Do a HEAD request. - * - * @param string $url The url or path you want to request. - * @param array $data The query string data you want to send. - * @param array $options Additional options for the request. - * @return \Cake\Http\Client\Response - */ - public function head($url, array $data = [], array $options = []) - { - $options = $this->_mergeOptions($options); - $url = $this->buildUrl($url, $data, $options); - - return $this->_doRequest(Request::METHOD_HEAD, $url, '', $options); - } - - /** - * Helper method for doing non-GET requests. - * - * @param string $method HTTP method. - * @param string $url URL to request. - * @param mixed $data The request body. - * @param array $options The options to use. Contains auth, proxy, etc. - * @return \Cake\Http\Client\Response - */ - protected function _doRequest($method, $url, $data, $options) - { - $request = $this->_createRequest( - $method, - $url, - $data, - $options - ); - - return $this->send($request, $options); - } - - /** - * Does a recursive merge of the parameter with the scope config. - * - * @param array $options Options to merge. - * @return array Options merged with set config. - */ - protected function _mergeOptions($options) - { - return Hash::merge($this->_config, $options); - } - - /** - * Send a request. - * - * Used internally by other methods, but can also be used to send - * handcrafted Request objects. - * - * @param \Cake\Http\Client\Request $request The request to send. - * @param array $options Additional options to use. - * @return \Cake\Http\Client\Response - */ - public function send(Request $request, $options = []) - { - $redirects = 0; - if (isset($options['redirect'])) { - $redirects = (int)$options['redirect']; - unset($options['redirect']); - } - - do { - $response = $this->_sendRequest($request, $options); - - $handleRedirect = $response->isRedirect() && $redirects-- > 0; - if ($handleRedirect) { - $url = $request->getUri(); - $request = $this->_cookies->addToRequest($request, []); - - $location = $response->getHeaderLine('Location'); - $locationUrl = $this->buildUrl($location, [], [ - 'host' => $url->getHost(), - 'port' => $url->getPort(), - 'scheme' => $url->getScheme(), - 'protocolRelative' => true - ]); - - $request = $request->withUri(new Uri($locationUrl)); - } - } while ($handleRedirect); - - return $response; - } - - /** - * Send a request without redirection. - * - * @param \Cake\Http\Client\Request $request The request to send. - * @param array $options Additional options to use. - * @return \Cake\Http\Client\Response - */ - protected function _sendRequest(Request $request, $options) - { - $responses = $this->_adapter->send($request, $options); - $url = $request->getUri(); - foreach ($responses as $response) { - $this->_cookies = $this->_cookies->addFromResponse($response, $request); - } - - return array_pop($responses); - } - - /** - * Generate a URL based on the scoped client options. - * - * @param string $url Either a full URL or just the path. - * @param string|array $query The query data for the URL. - * @param array $options The config options stored with Client::config() - * @return string A complete url with scheme, port, host, and path. - */ - public function buildUrl($url, $query = [], $options = []) - { - if (empty($options) && empty($query)) { - return $url; - } - if ($query) { - $q = (strpos($url, '?') === false) ? '?' : '&'; - $url .= $q; - $url .= is_string($query) ? $query : http_build_query($query); - } - $defaults = [ - 'host' => null, - 'port' => null, - 'scheme' => 'http', - 'protocolRelative' => false - ]; - $options += $defaults; - - if ($options['protocolRelative'] && preg_match('#^//#', $url)) { - $url = $options['scheme'] . ':' . $url; - } - if (preg_match('#^https?://#', $url)) { - return $url; - } - - $defaultPorts = [ - 'http' => 80, - 'https' => 443 - ]; - $out = $options['scheme'] . '://' . $options['host']; - if ($options['port'] && $options['port'] != $defaultPorts[$options['scheme']]) { - $out .= ':' . $options['port']; - } - $out .= '/' . ltrim($url, '/'); - - return $out; - } - - /** - * Creates a new request object based on the parameters. - * - * @param string $method HTTP method name. - * @param string $url The url including query string. - * @param mixed $data The request body. - * @param array $options The options to use. Contains auth, proxy, etc. - * @return \Cake\Http\Client\Request - */ - protected function _createRequest($method, $url, $data, $options) - { - $headers = isset($options['headers']) ? (array)$options['headers'] : []; - if (isset($options['type'])) { - $headers = array_merge($headers, $this->_typeHeaders($options['type'])); - } - if (is_string($data) && !isset($headers['Content-Type']) && !isset($headers['content-type'])) { - $headers['Content-Type'] = 'application/x-www-form-urlencoded'; - } - - $request = new Request($url, $method, $headers, $data); - $cookies = isset($options['cookies']) ? $options['cookies'] : []; - /** @var \Cake\Http\Client\Request $request */ - $request = $this->_cookies->addToRequest($request, $cookies); - if (isset($options['auth'])) { - $request = $this->_addAuthentication($request, $options); - } - if (isset($options['proxy'])) { - $request = $this->_addProxy($request, $options); - } - - return $request; - } - - /** - * Returns headers for Accept/Content-Type based on a short type - * or full mime-type. - * - * @param string $type short type alias or full mimetype. - * @return array Headers to set on the request. - * @throws \Cake\Core\Exception\Exception When an unknown type alias is used. - */ - protected function _typeHeaders($type) - { - if (strpos($type, '/') !== false) { - return [ - 'Accept' => $type, - 'Content-Type' => $type - ]; - } - $typeMap = [ - 'json' => 'application/json', - 'xml' => 'application/xml', - ]; - if (!isset($typeMap[$type])) { - throw new Exception("Unknown type alias '$type'."); - } - - return [ - 'Accept' => $typeMap[$type], - 'Content-Type' => $typeMap[$type], - ]; - } - - /** - * Add authentication headers to the request. - * - * Uses the authentication type to choose the correct strategy - * and use its methods to add headers. - * - * @param \Cake\Http\Client\Request $request The request to modify. - * @param array $options Array of options containing the 'auth' key. - * @return \Cake\Http\Client\Request The updated request object. - */ - protected function _addAuthentication(Request $request, $options) - { - $auth = $options['auth']; - $adapter = $this->_createAuth($auth, $options); - $result = $adapter->authentication($request, $options['auth']); - - return $result ?: $request; - } - - /** - * Add proxy authentication headers. - * - * Uses the authentication type to choose the correct strategy - * and use its methods to add headers. - * - * @param \Cake\Http\Client\Request $request The request to modify. - * @param array $options Array of options containing the 'proxy' key. - * @return \Cake\Http\Client\Request The updated request object. - */ - protected function _addProxy(Request $request, $options) - { - $auth = $options['proxy']; - $adapter = $this->_createAuth($auth, $options); - $result = $adapter->proxyAuthentication($request, $options['proxy']); - - return $result ?: $request; - } - - /** - * Create the authentication strategy. - * - * Use the configuration options to create the correct - * authentication strategy handler. - * - * @param array $auth The authentication options to use. - * @param array $options The overall request options to use. - * @return mixed Authentication strategy instance. - * @throws \Cake\Core\Exception\Exception when an invalid strategy is chosen. - */ - protected function _createAuth($auth, $options) - { - if (empty($auth['type'])) { - $auth['type'] = 'basic'; - } - $name = ucfirst($auth['type']); - $class = App::className($name, 'Http/Client/Auth'); - if (!$class) { - throw new Exception( - sprintf('Invalid authentication type %s', $name) - ); - } - - return new $class($this, $options); - } -} -// @deprecated Backwards compatibility with earler 3.x versions. -class_alias('Cake\Http\Client', 'Cake\Network\Http\Client'); diff --git a/vendor/cakephp/cakephp/src/Http/Client/Adapter/Stream.php b/vendor/cakephp/cakephp/src/Http/Client/Adapter/Stream.php deleted file mode 100644 index 81e5742..0000000 --- a/vendor/cakephp/cakephp/src/Http/Client/Adapter/Stream.php +++ /dev/null @@ -1,331 +0,0 @@ -_stream = null; - $this->_context = null; - $this->_contextOptions = []; - $this->_sslContextOptions = []; - $this->_connectionErrors = []; - - $this->_buildContext($request, $options); - - return $this->_send($request); - } - - /** - * Create the response list based on the headers & content - * - * Creates one or many response objects based on the number - * of redirects that occurred. - * - * @param array $headers The list of headers from the request(s) - * @param string $content The response content. - * @return \Cake\Http\Client\Response[] The list of responses from the request(s) - */ - public function createResponses($headers, $content) - { - $indexes = $responses = []; - foreach ($headers as $i => $header) { - if (strtoupper(substr($header, 0, 5)) === 'HTTP/') { - $indexes[] = $i; - } - } - $last = count($indexes) - 1; - foreach ($indexes as $i => $start) { - $end = isset($indexes[$i + 1]) ? $indexes[$i + 1] - $start : null; - $headerSlice = array_slice($headers, $start, $end); - $body = $i == $last ? $content : ''; - $responses[] = $this->_buildResponse($headerSlice, $body); - } - - return $responses; - } - - /** - * Build the stream context out of the request object. - * - * @param \Cake\Http\Client\Request $request The request to build context from. - * @param array $options Additional request options. - * @return void - */ - protected function _buildContext(Request $request, $options) - { - $this->_buildContent($request, $options); - $this->_buildHeaders($request, $options); - $this->_buildOptions($request, $options); - - $url = $request->getUri(); - $scheme = parse_url($url, PHP_URL_SCHEME); - if ($scheme === 'https') { - $this->_buildSslContext($request, $options); - } - $this->_context = stream_context_create([ - 'http' => $this->_contextOptions, - 'ssl' => $this->_sslContextOptions, - ]); - } - - /** - * Build the header context for the request. - * - * Creates cookies & headers. - * - * @param \Cake\Http\Client\Request $request The request being sent. - * @param array $options Array of options to use. - * @return void - */ - protected function _buildHeaders(Request $request, $options) - { - $headers = []; - foreach ($request->getHeaders() as $name => $values) { - $headers[] = sprintf('%s: %s', $name, implode(', ', $values)); - } - $this->_contextOptions['header'] = implode("\r\n", $headers); - } - - /** - * Builds the request content based on the request object. - * - * If the $request->body() is a string, it will be used as is. - * Array data will be processed with Cake\Http\Client\FormData - * - * @param \Cake\Http\Client\Request $request The request being sent. - * @param array $options Array of options to use. - * @return void - */ - protected function _buildContent(Request $request, $options) - { - $body = $request->getBody(); - if (empty($body)) { - $this->_contextOptions['content'] = ''; - - return; - } - $body->rewind(); - $this->_contextOptions['content'] = $body->getContents(); - } - - /** - * Build miscellaneous options for the request. - * - * @param \Cake\Http\Client\Request $request The request being sent. - * @param array $options Array of options to use. - * @return void - */ - protected function _buildOptions(Request $request, $options) - { - $this->_contextOptions['method'] = $request->getMethod(); - $this->_contextOptions['protocol_version'] = $request->getProtocolVersion(); - $this->_contextOptions['ignore_errors'] = true; - - if (isset($options['timeout'])) { - $this->_contextOptions['timeout'] = $options['timeout']; - } - // Redirects are handled in the client layer because of cookie handling issues. - $this->_contextOptions['max_redirects'] = 0; - - if (isset($options['proxy']['proxy'])) { - $this->_contextOptions['request_fulluri'] = true; - $this->_contextOptions['proxy'] = $options['proxy']['proxy']; - } - } - - /** - * Build SSL options for the request. - * - * @param \Cake\Http\Client\Request $request The request being sent. - * @param array $options Array of options to use. - * @return void - */ - protected function _buildSslContext(Request $request, $options) - { - $sslOptions = [ - 'ssl_verify_peer', - 'ssl_verify_peer_name', - 'ssl_verify_depth', - 'ssl_allow_self_signed', - 'ssl_cafile', - 'ssl_local_cert', - 'ssl_passphrase', - ]; - if (empty($options['ssl_cafile'])) { - $options['ssl_cafile'] = CORE_PATH . 'config' . DIRECTORY_SEPARATOR . 'cacert.pem'; - } - if (!empty($options['ssl_verify_host'])) { - $url = $request->getUri(); - $host = parse_url($url, PHP_URL_HOST); - $this->_sslContextOptions['peer_name'] = $host; - } - foreach ($sslOptions as $key) { - if (isset($options[$key])) { - $name = substr($key, 4); - $this->_sslContextOptions[$name] = $options[$key]; - } - } - } - - /** - * Open the stream and send the request. - * - * @param \Cake\Http\Client\Request $request The request object. - * @return array Array of populated Response objects - * @throws \Cake\Http\Exception\HttpException - */ - protected function _send(Request $request) - { - $deadline = false; - if (isset($this->_contextOptions['timeout']) && $this->_contextOptions['timeout'] > 0) { - $deadline = time() + $this->_contextOptions['timeout']; - } - - $url = $request->getUri(); - $this->_open($url); - $content = ''; - $timedOut = false; - - while (!feof($this->_stream)) { - if ($deadline !== false) { - stream_set_timeout($this->_stream, max($deadline - time(), 1)); - } - - $content .= fread($this->_stream, 8192); - - $meta = stream_get_meta_data($this->_stream); - if ($meta['timed_out'] || ($deadline !== false && time() > $deadline)) { - $timedOut = true; - break; - } - } - $meta = stream_get_meta_data($this->_stream); - fclose($this->_stream); - - if ($timedOut) { - throw new HttpException('Connection timed out ' . $url, 504); - } - - $headers = $meta['wrapper_data']; - if (isset($headers['headers']) && is_array($headers['headers'])) { - $headers = $headers['headers']; - } - - return $this->createResponses($headers, $content); - } - - /** - * Build a response object - * - * @param array $headers Unparsed headers. - * @param string $body The response body. - * - * @return \Cake\Http\Client\Response - */ - protected function _buildResponse($headers, $body) - { - return new Response($headers, $body); - } - - /** - * Open the socket and handle any connection errors. - * - * @param string $url The url to connect to. - * @return void - * @throws \Cake\Core\Exception\Exception - */ - protected function _open($url) - { - set_error_handler(function ($code, $message) { - $this->_connectionErrors[] = $message; - }); - $this->_stream = fopen($url, 'rb', false, $this->_context); - restore_error_handler(); - - if (!$this->_stream || !empty($this->_connectionErrors)) { - throw new Exception(implode("\n", $this->_connectionErrors)); - } - } - - /** - * Get the context options - * - * Useful for debugging and testing context creation. - * - * @return array - */ - public function contextOptions() - { - return array_merge($this->_contextOptions, $this->_sslContextOptions); - } -} - -// @deprecated Add backwards compat alias. -class_alias('Cake\Http\Client\Adapter\Stream', 'Cake\Network\Http\Adapter\Stream'); diff --git a/vendor/cakephp/cakephp/src/Http/Client/Auth/Basic.php b/vendor/cakephp/cakephp/src/Http/Client/Auth/Basic.php deleted file mode 100644 index 6debf1b..0000000 --- a/vendor/cakephp/cakephp/src/Http/Client/Auth/Basic.php +++ /dev/null @@ -1,77 +0,0 @@ -_generateHeader($credentials['username'], $credentials['password']); - $request = $request->withHeader('Authorization', $value); - } - - return $request; - } - - /** - * Proxy Authentication - * - * @param \Cake\Http\Client\Request $request Request instance. - * @param array $credentials Credentials. - * @return \Cake\Http\Client\Request The updated request. - * @see https://www.ietf.org/rfc/rfc2617.txt - */ - public function proxyAuthentication(Request $request, array $credentials) - { - if (isset($credentials['username'], $credentials['password'])) { - $value = $this->_generateHeader($credentials['username'], $credentials['password']); - $request = $request->withHeader('Proxy-Authorization', $value); - } - - return $request; - } - - /** - * Generate basic [proxy] authentication header - * - * @param string $user Username. - * @param string $pass Password. - * @return string - */ - protected function _generateHeader($user, $pass) - { - return 'Basic ' . base64_encode($user . ':' . $pass); - } -} - -// @deprecated Add backwards compat alias. -class_alias('Cake\Http\Client\Auth\Basic', 'Cake\Network\Http\Auth\Basic'); diff --git a/vendor/cakephp/cakephp/src/Http/Client/Auth/Digest.php b/vendor/cakephp/cakephp/src/Http/Client/Auth/Digest.php deleted file mode 100644 index 9d42564..0000000 --- a/vendor/cakephp/cakephp/src/Http/Client/Auth/Digest.php +++ /dev/null @@ -1,148 +0,0 @@ -_client = $client; - } - - /** - * Add Authorization header to the request. - * - * @param \Cake\Http\Client\Request $request The request object. - * @param array $credentials Authentication credentials. - * @return \Cake\Http\Client\Request The updated request. - * @see https://www.ietf.org/rfc/rfc2617.txt - */ - public function authentication(Request $request, array $credentials) - { - if (!isset($credentials['username'], $credentials['password'])) { - return $request; - } - if (!isset($credentials['realm'])) { - $credentials = $this->_getServerInfo($request, $credentials); - } - if (!isset($credentials['realm'])) { - return $request; - } - $value = $this->_generateHeader($request, $credentials); - - return $request->withHeader('Authorization', $value); - } - - /** - * Retrieve information about the authentication - * - * Will get the realm and other tokens by performing - * another request without authentication to get authentication - * challenge. - * - * @param \Cake\Http\Client\Request $request The request object. - * @param array $credentials Authentication credentials. - * @return array modified credentials. - */ - protected function _getServerInfo(Request $request, $credentials) - { - $response = $this->_client->get( - $request->getUri(), - [], - ['auth' => ['type' => null]] - ); - - if (!$response->getHeader('WWW-Authenticate')) { - return []; - } - preg_match_all( - '@(\w+)=(?:(?:")([^"]+)"|([^\s,$]+))@', - $response->getHeaderLine('WWW-Authenticate'), - $matches, - PREG_SET_ORDER - ); - foreach ($matches as $match) { - $credentials[$match[1]] = $match[2]; - } - if (!empty($credentials['qop']) && empty($credentials['nc'])) { - $credentials['nc'] = 1; - } - - return $credentials; - } - - /** - * Generate the header Authorization - * - * @param \Cake\Http\Client\Request $request The request object. - * @param array $credentials Authentication credentials. - * @return string - */ - protected function _generateHeader(Request $request, $credentials) - { - $path = $request->getUri()->getPath(); - $a1 = md5($credentials['username'] . ':' . $credentials['realm'] . ':' . $credentials['password']); - $a2 = md5($request->getMethod() . ':' . $path); - $nc = null; - - if (empty($credentials['qop'])) { - $response = md5($a1 . ':' . $credentials['nonce'] . ':' . $a2); - } else { - $credentials['cnonce'] = uniqid(); - $nc = sprintf('%08x', $credentials['nc']++); - $response = md5($a1 . ':' . $credentials['nonce'] . ':' . $nc . ':' . $credentials['cnonce'] . ':auth:' . $a2); - } - - $authHeader = 'Digest '; - $authHeader .= 'username="' . str_replace(['\\', '"'], ['\\\\', '\\"'], $credentials['username']) . '", '; - $authHeader .= 'realm="' . $credentials['realm'] . '", '; - $authHeader .= 'nonce="' . $credentials['nonce'] . '", '; - $authHeader .= 'uri="' . $path . '", '; - $authHeader .= 'response="' . $response . '"'; - if (!empty($credentials['opaque'])) { - $authHeader .= ', opaque="' . $credentials['opaque'] . '"'; - } - if (!empty($credentials['qop'])) { - $authHeader .= ', qop="auth", nc=' . $nc . ', cnonce="' . $credentials['cnonce'] . '"'; - } - - return $authHeader; - } -} - -// @deprecated Add backwards compat alias. -class_alias('Cake\Http\Client\Auth\Digest', 'Cake\Network\Http\Auth\Digest'); diff --git a/vendor/cakephp/cakephp/src/Http/Client/Auth/Oauth.php b/vendor/cakephp/cakephp/src/Http/Client/Auth/Oauth.php deleted file mode 100644 index 2673c38..0000000 --- a/vendor/cakephp/cakephp/src/Http/Client/Auth/Oauth.php +++ /dev/null @@ -1,372 +0,0 @@ -_hmacSha1($request, $credentials); - break; - - case 'RSA-SHA1': - if (!isset($credentials['privateKey'])) { - return $request; - } - $value = $this->_rsaSha1($request, $credentials); - break; - - case 'PLAINTEXT': - $hasKeys = isset( - $credentials['consumerSecret'], - $credentials['token'], - $credentials['tokenSecret'] - ); - if (!$hasKeys) { - return $request; - } - $value = $this->_plaintext($request, $credentials); - break; - - default: - throw new Exception(sprintf('Unknown Oauth signature method %s', $credentials['method'])); - } - - return $request->withHeader('Authorization', $value); - } - - /** - * Plaintext signing - * - * This method is **not** suitable for plain HTTP. - * You should only ever use PLAINTEXT when dealing with SSL - * services. - * - * @param \Cake\Http\Client\Request $request The request object. - * @param array $credentials Authentication credentials. - * @return string Authorization header. - */ - protected function _plaintext($request, $credentials) - { - $values = [ - 'oauth_version' => '1.0', - 'oauth_nonce' => uniqid(), - 'oauth_timestamp' => time(), - 'oauth_signature_method' => 'PLAINTEXT', - 'oauth_token' => $credentials['token'], - 'oauth_consumer_key' => $credentials['consumerKey'], - ]; - if (isset($credentials['realm'])) { - $values['oauth_realm'] = $credentials['realm']; - } - $key = [$credentials['consumerSecret'], $credentials['tokenSecret']]; - $key = implode('&', $key); - $values['oauth_signature'] = $key; - - return $this->_buildAuth($values); - } - - /** - * Use HMAC-SHA1 signing. - * - * This method is suitable for plain HTTP or HTTPS. - * - * @param \Cake\Http\Client\Request $request The request object. - * @param array $credentials Authentication credentials. - * @return string - */ - protected function _hmacSha1($request, $credentials) - { - $nonce = isset($credentials['nonce']) ? $credentials['nonce'] : uniqid(); - $timestamp = isset($credentials['timestamp']) ? $credentials['timestamp'] : time(); - $values = [ - 'oauth_version' => '1.0', - 'oauth_nonce' => $nonce, - 'oauth_timestamp' => $timestamp, - 'oauth_signature_method' => 'HMAC-SHA1', - 'oauth_token' => $credentials['token'], - 'oauth_consumer_key' => $credentials['consumerKey'], - ]; - $baseString = $this->baseString($request, $values); - - if (isset($credentials['realm'])) { - $values['oauth_realm'] = $credentials['realm']; - } - $key = [$credentials['consumerSecret'], $credentials['tokenSecret']]; - $key = array_map([$this, '_encode'], $key); - $key = implode('&', $key); - - $values['oauth_signature'] = base64_encode( - hash_hmac('sha1', $baseString, $key, true) - ); - - return $this->_buildAuth($values); - } - - /** - * Use RSA-SHA1 signing. - * - * This method is suitable for plain HTTP or HTTPS. - * - * @param \Cake\Http\Client\Request $request The request object. - * @param array $credentials Authentication credentials. - * @return string - * - * @throws \RuntimeException - */ - protected function _rsaSha1($request, $credentials) - { - if (!function_exists('openssl_pkey_get_private')) { - throw new RuntimeException('RSA-SHA1 signature method requires the OpenSSL extension.'); - } - - $nonce = isset($credentials['nonce']) ? $credentials['nonce'] : bin2hex(Security::randomBytes(16)); - $timestamp = isset($credentials['timestamp']) ? $credentials['timestamp'] : time(); - $values = [ - 'oauth_version' => '1.0', - 'oauth_nonce' => $nonce, - 'oauth_timestamp' => $timestamp, - 'oauth_signature_method' => 'RSA-SHA1', - 'oauth_consumer_key' => $credentials['consumerKey'], - ]; - if (isset($credentials['consumerSecret'])) { - $values['oauth_consumer_secret'] = $credentials['consumerSecret']; - } - if (isset($credentials['token'])) { - $values['oauth_token'] = $credentials['token']; - } - if (isset($credentials['tokenSecret'])) { - $values['oauth_token_secret'] = $credentials['tokenSecret']; - } - $baseString = $this->baseString($request, $values); - - if (isset($credentials['realm'])) { - $values['oauth_realm'] = $credentials['realm']; - } - - if (is_resource($credentials['privateKey'])) { - $resource = $credentials['privateKey']; - $privateKey = stream_get_contents($resource); - rewind($resource); - $credentials['privateKey'] = $privateKey; - } - - $credentials += [ - 'privateKeyPassphrase' => null, - ]; - if (is_resource($credentials['privateKeyPassphrase'])) { - $resource = $credentials['privateKeyPassphrase']; - $passphrase = stream_get_line($resource, 0, PHP_EOL); - rewind($resource); - $credentials['privateKeyPassphrase'] = $passphrase; - } - $privateKey = openssl_pkey_get_private($credentials['privateKey'], $credentials['privateKeyPassphrase']); - $signature = ''; - openssl_sign($baseString, $signature, $privateKey); - openssl_free_key($privateKey); - - $values['oauth_signature'] = base64_encode($signature); - - return $this->_buildAuth($values); - } - - /** - * Generate the Oauth basestring - * - * - Querystring, request data and oauth_* parameters are combined. - * - Values are sorted by name and then value. - * - Request values are concatenated and urlencoded. - * - The request URL (without querystring) is normalized. - * - The HTTP method, URL and request parameters are concatenated and returned. - * - * @param \Cake\Http\Client\Request $request The request object. - * @param array $oauthValues Oauth values. - * @return string - */ - public function baseString($request, $oauthValues) - { - $parts = [ - $request->getMethod(), - $this->_normalizedUrl($request->getUri()), - $this->_normalizedParams($request, $oauthValues), - ]; - $parts = array_map([$this, '_encode'], $parts); - - return implode('&', $parts); - } - - /** - * Builds a normalized URL - * - * Section 9.1.2. of the Oauth spec - * - * @param \Psr\Http\Message\UriInterface $uri Uri object to build a normalized version of. - * @return string Normalized URL - */ - protected function _normalizedUrl($uri) - { - $out = $uri->getScheme() . '://'; - $out .= strtolower($uri->getHost()); - $out .= $uri->getPath(); - - return $out; - } - - /** - * Sorts and normalizes request data and oauthValues - * - * Section 9.1.1 of Oauth spec. - * - * - URL encode keys + values. - * - Sort keys & values by byte value. - * - * @param \Cake\Http\Client\Request $request The request object. - * @param array $oauthValues Oauth values. - * @return string sorted and normalized values - */ - protected function _normalizedParams($request, $oauthValues) - { - $query = parse_url($request->getUri(), PHP_URL_QUERY); - parse_str($query, $queryArgs); - - $post = []; - $body = $request->body(); - if (is_string($body) && $request->getHeaderLine('content-type') === 'application/x-www-form-urlencoded') { - parse_str($body, $post); - } - if (is_array($body)) { - $post = $body; - } - - $args = array_merge($queryArgs, $oauthValues, $post); - $pairs = $this->_normalizeData($args); - $data = []; - foreach ($pairs as $pair) { - $data[] = implode('=', $pair); - } - sort($data, SORT_STRING); - - return implode('&', $data); - } - - /** - * Recursively convert request data into the normalized form. - * - * @param array $args The arguments to normalize. - * @param string $path The current path being converted. - * @see https://tools.ietf.org/html/rfc5849#section-3.4.1.3.2 - * @return array - */ - protected function _normalizeData($args, $path = '') - { - $data = []; - foreach ($args as $key => $value) { - if ($path) { - // Fold string keys with []. - // Numeric keys result in a=b&a=c. While this isn't - // standard behavior in PHP, it is common in other platforms. - if (!is_numeric($key)) { - $key = "{$path}[{$key}]"; - } else { - $key = $path; - } - } - if (is_array($value)) { - uksort($value, 'strcmp'); - $data = array_merge($data, $this->_normalizeData($value, $key)); - } else { - $data[] = [$key, $value]; - } - } - - return $data; - } - - /** - * Builds the Oauth Authorization header value. - * - * @param array $data The oauth_* values to build - * @return string - */ - protected function _buildAuth($data) - { - $out = 'OAuth '; - $params = []; - foreach ($data as $key => $value) { - $params[] = $key . '="' . $this->_encode($value) . '"'; - } - $out .= implode(',', $params); - - return $out; - } - - /** - * URL Encodes a value based on rules of rfc3986 - * - * @param string $value Value to encode. - * @return string - */ - protected function _encode($value) - { - return str_replace( - '+', - ' ', - str_replace('%7E', '~', rawurlencode($value)) - ); - } -} - -// @deprecated Add backwards compat alias. -class_alias('Cake\Http\Client\Auth\Oauth', 'Cake\Network\Http\Auth\Oauth'); diff --git a/vendor/cakephp/cakephp/src/Http/Client/CookieCollection.php b/vendor/cakephp/cakephp/src/Http/Client/CookieCollection.php deleted file mode 100644 index 817bb06..0000000 --- a/vendor/cakephp/cakephp/src/Http/Client/CookieCollection.php +++ /dev/null @@ -1,121 +0,0 @@ -getHeader('Set-Cookie'); - $cookies = $this->parseSetCookieHeader($header); - $cookies = $this->setRequestDefaults($cookies, $host, $path); - foreach ($cookies as $cookie) { - $this->cookies[$cookie->getId()] = $cookie; - } - $this->removeExpiredCookies($host, $path); - } - - /** - * Get stored cookies for a URL. - * - * Finds matching stored cookies and returns a simple array - * of name => value - * - * @param string $url The URL to find cookies for. - * @return array - */ - public function get($url) - { - $path = parse_url($url, PHP_URL_PATH) ?: '/'; - $host = parse_url($url, PHP_URL_HOST); - $scheme = parse_url($url, PHP_URL_SCHEME); - - return $this->findMatchingCookies($scheme, $host, $path); - } - - /** - * Get all the stored cookies as arrays. - * - * @return array - */ - public function getAll() - { - $out = []; - foreach ($this->cookies as $cookie) { - $out[] = $this->convertCookieToArray($cookie); - } - - return $out; - } - - /** - * Convert the cookie into an array of its properties. - * - * Primarily useful where backwards compatibility is needed. - * - * @param \Cake\Http\Cookie\CookieInterface $cookie Cookie object. - * @return array - */ - protected function convertCookieToArray(CookieInterface $cookie) - { - return [ - 'name' => $cookie->getName(), - 'value' => $cookie->getValue(), - 'path' => $cookie->getPath(), - 'domain' => $cookie->getDomain(), - 'secure' => $cookie->isSecure(), - 'httponly' => $cookie->isHttpOnly(), - 'expires' => $cookie->getExpiresTimestamp() - ]; - } -} - -// @deprecated Add backwards compat alias. -class_alias('Cake\Http\Client\CookieCollection', 'Cake\Network\Http\CookieCollection'); diff --git a/vendor/cakephp/cakephp/src/Http/Client/FormData.php b/vendor/cakephp/cakephp/src/Http/Client/FormData.php deleted file mode 100644 index 5e7a32a..0000000 --- a/vendor/cakephp/cakephp/src/Http/Client/FormData.php +++ /dev/null @@ -1,267 +0,0 @@ -_boundary) { - return $this->_boundary; - } - $this->_boundary = md5(uniqid(time())); - - return $this->_boundary; - } - - /** - * Method for creating new instances of Part - * - * @param string $name The name of the part. - * @param string $value The value to add. - * @return \Cake\Http\Client\FormDataPart - */ - public function newPart($name, $value) - { - return new FormDataPart($name, $value); - } - - /** - * Add a new part to the data. - * - * The value for a part can be a string, array, int, - * float, filehandle, or object implementing __toString() - * - * If the $value is an array, multiple parts will be added. - * Files will be read from their current position and saved in memory. - * - * @param string|\Cake\Http\Client\FormData $name The name of the part to add, - * or the part data object. - * @param mixed $value The value for the part. - * @return $this - */ - public function add($name, $value = null) - { - if (is_array($value)) { - $this->addRecursive($name, $value); - } elseif (is_resource($value)) { - $this->addFile($name, $value); - } elseif ($name instanceof FormDataPart && $value === null) { - $this->_hasComplexPart = true; - $this->_parts[] = $name; - } else { - $this->_parts[] = $this->newPart($name, $value); - } - - return $this; - } - - /** - * Add multiple parts at once. - * - * Iterates the parameter and adds all the key/values. - * - * @param array $data Array of data to add. - * @return $this - */ - public function addMany(array $data) - { - foreach ($data as $name => $value) { - $this->add($name, $value); - } - - return $this; - } - - /** - * Add either a file reference (string starting with @) - * or a file handle. - * - * @param string $name The name to use. - * @param mixed $value Either a string filename, or a filehandle. - * @return \Cake\Http\Client\FormDataPart - */ - public function addFile($name, $value) - { - $this->_hasFile = true; - - $filename = false; - $contentType = 'application/octet-stream'; - if (is_resource($value)) { - $content = stream_get_contents($value); - if (stream_is_local($value)) { - $finfo = new finfo(FILEINFO_MIME); - $metadata = stream_get_meta_data($value); - $contentType = $finfo->file($metadata['uri']); - $filename = basename($metadata['uri']); - } - } else { - $finfo = new finfo(FILEINFO_MIME); - $value = substr($value, 1); - $filename = basename($value); - $content = file_get_contents($value); - $contentType = $finfo->file($value); - } - $part = $this->newPart($name, $content); - $part->type($contentType); - if ($filename) { - $part->filename($filename); - } - $this->add($part); - - return $part; - } - - /** - * Recursively add data. - * - * @param string $name The name to use. - * @param mixed $value The value to add. - * @return void - */ - public function addRecursive($name, $value) - { - foreach ($value as $key => $value) { - $key = $name . '[' . $key . ']'; - $this->add($key, $value); - } - } - - /** - * Returns the count of parts inside this object. - * - * @return int - */ - public function count() - { - return count($this->_parts); - } - - /** - * Check whether or not the current payload - * has any files. - * - * @return bool Whether or not there is a file in this payload. - */ - public function hasFile() - { - return $this->_hasFile; - } - - /** - * Check whether or not the current payload - * is multipart. - * - * A payload will become multipart when you add files - * or use add() with a Part instance. - * - * @return bool Whether or not the payload is multipart. - */ - public function isMultipart() - { - return $this->hasFile() || $this->_hasComplexPart; - } - - /** - * Get the content type for this payload. - * - * If this object contains files, `multipart/form-data` will be used, - * otherwise `application/x-www-form-urlencoded` will be used. - * - * @return string - */ - public function contentType() - { - if (!$this->isMultipart()) { - return 'application/x-www-form-urlencoded'; - } - - return 'multipart/form-data; boundary="' . $this->boundary() . '"'; - } - - /** - * Converts the FormData and its parts into a string suitable - * for use in an HTTP request. - * - * @return string - */ - public function __toString() - { - if ($this->isMultipart()) { - $boundary = $this->boundary(); - $out = ''; - foreach ($this->_parts as $part) { - $out .= "--$boundary\r\n"; - $out .= (string)$part; - $out .= "\r\n"; - } - $out .= "--$boundary--\r\n\r\n"; - - return $out; - } - $data = []; - foreach ($this->_parts as $part) { - $data[$part->name()] = $part->value(); - } - - return http_build_query($data); - } -} - -// @deprecated Add backwards compat alias. -class_alias('Cake\Http\Client\FormData', 'Cake\Network\Http\FormData'); diff --git a/vendor/cakephp/cakephp/src/Http/Client/FormDataPart.php b/vendor/cakephp/cakephp/src/Http/Client/FormDataPart.php deleted file mode 100644 index a079c72..0000000 --- a/vendor/cakephp/cakephp/src/Http/Client/FormDataPart.php +++ /dev/null @@ -1,226 +0,0 @@ -_name = $name; - $this->_value = $value; - $this->_disposition = $disposition; - } - - /** - * Get/set the disposition type - * - * By passing in `false` you can disable the disposition - * header from being added. - * - * @param null|string $disposition Use null to get/string to set. - * @return string|null - */ - public function disposition($disposition = null) - { - if ($disposition === null) { - return $this->_disposition; - } - $this->_disposition = $disposition; - } - - /** - * Get/set the contentId for a part. - * - * @param null|string $id The content id. - * @return string|null - */ - public function contentId($id = null) - { - if ($id === null) { - return $this->_contentId; - } - $this->_contentId = $id; - } - - /** - * Get/set the filename. - * - * Setting the filename to `false` will exclude it from the - * generated output. - * - * @param null|string $filename Use null to get/string to set. - * @return string|null - */ - public function filename($filename = null) - { - if ($filename === null) { - return $this->_filename; - } - $this->_filename = $filename; - } - - /** - * Get/set the content type. - * - * @param null|string $type Use null to get/string to set. - * @return string|null - */ - public function type($type) - { - if ($type === null) { - return $this->_type; - } - $this->_type = $type; - } - - /** - * Set the transfer-encoding for multipart. - * - * Useful when content bodies are in encodings like base64. - * - * @param null|string $type The type of encoding the value has. - * @return string|null - */ - public function transferEncoding($type) - { - if ($type === null) { - return $this->_transferEncoding; - } - $this->_transferEncoding = $type; - } - - /** - * Get the part name. - * - * @return string - */ - public function name() - { - return $this->_name; - } - - /** - * Get the value. - * - * @return string - */ - public function value() - { - return $this->_value; - } - - /** - * Convert the part into a string. - * - * Creates a string suitable for use in HTTP requests. - * - * @return string - */ - public function __toString() - { - $out = ''; - if ($this->_disposition) { - $out .= 'Content-Disposition: ' . $this->_disposition; - if ($this->_name) { - $out .= '; name="' . $this->_name . '"'; - } - if ($this->_filename) { - $out .= '; filename="' . $this->_filename . '"'; - } - $out .= "\r\n"; - } - if ($this->_type) { - $out .= 'Content-Type: ' . $this->_type . "\r\n"; - } - if ($this->_transferEncoding) { - $out .= 'Content-Transfer-Encoding: ' . $this->_transferEncoding . "\r\n"; - } - if ($this->_contentId) { - $out .= 'Content-ID: <' . $this->_contentId . ">\r\n"; - } - $out .= "\r\n"; - $out .= (string)$this->_value; - - return $out; - } -} - -// @deprecated Add backwards compat alias. -class_alias('Cake\Http\Client\FormDataPart', 'Cake\Network\Http\FormData\Part'); diff --git a/vendor/cakephp/cakephp/src/Http/Client/Message.php b/vendor/cakephp/cakephp/src/Http/Client/Message.php deleted file mode 100644 index eb11e2d..0000000 --- a/vendor/cakephp/cakephp/src/Http/Client/Message.php +++ /dev/null @@ -1,204 +0,0 @@ -headers; - } - - /** - * Get all cookies - * - * @return array - */ - public function cookies() - { - return $this->_cookies; - } - - /** - * Get/set the body for the message. - * - * @param string|null $body The body for the request. Leave null for get - * @return mixed Either $this or the body value. - */ - public function body($body = null) - { - if ($body === null) { - return $this->_body; - } - $this->_body = $body; - - return $this; - } -} - -// @deprecated Add backwards compat alias. -class_alias('Cake\Http\Client\Message', 'Cake\Network\Http\Message'); diff --git a/vendor/cakephp/cakephp/src/Http/Client/Request.php b/vendor/cakephp/cakephp/src/Http/Client/Request.php deleted file mode 100644 index 7829a9f..0000000 --- a/vendor/cakephp/cakephp/src/Http/Client/Request.php +++ /dev/null @@ -1,287 +0,0 @@ -validateMethod($method); - $this->method = $method; - $this->uri = $this->createUri($url); - $headers += [ - 'Connection' => 'close', - 'User-Agent' => 'CakePHP' - ]; - $this->addHeaders($headers); - $this->body($data); - } - - /** - * Get/Set the HTTP method. - * - * *Warning* This method mutates the request in-place for backwards - * compatibility reasons, and is not part of the PSR7 interface. - * - * @param string|null $method The method for the request. - * @return $this|string Either this or the current method. - * @throws \Cake\Core\Exception\Exception On invalid methods. - * @deprecated 3.3.0 Use getMethod() and withMethod() instead. - */ - public function method($method = null) - { - deprecationWarning( - 'Request::method() is deprecated. ' . - 'Use getMethod() and withMethod() instead.' - ); - - if ($method === null) { - return $this->method; - } - $name = get_called_class() . '::METHOD_' . strtoupper($method); - if (!defined($name)) { - throw new Exception('Invalid method type'); - } - $this->method = $method; - - return $this; - } - - /** - * Get/Set the url for the request. - * - * *Warning* This method mutates the request in-place for backwards - * compatibility reasons, and is not part of the PSR7 interface. - * - * @param string|null $url The url for the request. Leave null for get - * @return $this|string Either $this or the url value. - * @deprecated 3.3.0 Use getUri() and withUri() instead. - */ - public function url($url = null) - { - deprecationWarning( - 'Request::url() is deprecated. ' . - 'Use getUri() and withUri() instead.' - ); - - if ($url === null) { - return '' . $this->getUri(); - } - $this->uri = $this->createUri($url); - - return $this; - } - - /** - * Get/Set headers into the request. - * - * You can get the value of a header, or set one/many headers. - * Headers are set / fetched in a case insensitive way. - * - * ### Getting headers - * - * ``` - * $request->header('Content-Type'); - * ``` - * - * ### Setting one header - * - * ``` - * $request->header('Content-Type', 'application/json'); - * ``` - * - * ### Setting multiple headers - * - * ``` - * $request->header(['Connection' => 'close', 'User-Agent' => 'CakePHP']); - * ``` - * - * *Warning* This method mutates the request in-place for backwards - * compatibility reasons, and is not part of the PSR7 interface. - * - * @param string|array|null $name The name to get, or array of multiple values to set. - * @param string|null $value The value to set for the header. - * @return mixed Either $this when setting or header value when getting. - * @deprecated 3.3.0 Use withHeader() and getHeaderLine() instead. - */ - public function header($name = null, $value = null) - { - deprecationWarning( - 'Request::header() is deprecated. ' . - 'Use withHeader() and getHeaderLine() instead.' - ); - - if ($value === null && is_string($name)) { - $val = $this->getHeaderLine($name); - if ($val === '') { - return null; - } - - return $val; - } - - if ($value !== null && !is_array($name)) { - $name = [$name => $value]; - } - $this->addHeaders($name); - - return $this; - } - - /** - * Add an array of headers to the request. - * - * @param array $headers The headers to add. - * @return void - */ - protected function addHeaders(array $headers) - { - foreach ($headers as $key => $val) { - $normalized = strtolower($key); - $this->headers[$key] = (array)$val; - $this->headerNames[$normalized] = $key; - } - } - - /** - * Get/Set cookie values. - * - * ### Getting a cookie - * - * ``` - * $request->cookie('session'); - * ``` - * - * ### Setting one cookie - * - * ``` - * $request->cookie('session', '123456'); - * ``` - * - * ### Setting multiple headers - * - * ``` - * $request->cookie(['test' => 'value', 'split' => 'banana']); - * ``` - * - * @param string $name The name of the cookie to get/set - * @param string|null $value Either the value or null when getting values. - * @return mixed Either $this or the cookie value. - * @deprecated 3.5.0 No longer used. CookieCollections now add `Cookie` header to the request - * before sending. Use Cake\Http\Cookie\CookieCollection::addToRequest() to make adding cookies - * to a request easier. - */ - public function cookie($name, $value = null) - { - deprecationWarning( - 'Request::cookie() is deprecated. ' . - 'The Client internals now add the required `Cookie` header to the ' . - 'request before sending. Use Cake\Http\Cookie\CookieCollection::addToRequest() ' . - 'to make adding cookies to a request easier.' - ); - - if ($value === null && is_string($name)) { - return isset($this->_cookies[$name]) ? $this->_cookies[$name] : null; - } - if (is_string($name) && is_string($value)) { - $name = [$name => $value]; - } - foreach ($name as $key => $val) { - $this->_cookies[$key] = $val; - } - - return $this; - } - - /** - * Get/Set HTTP version. - * - * *Warning* This method mutates the request in-place for backwards - * compatibility reasons, and is not part of the PSR7 interface. - * - * @param string|null $version The HTTP version. - * @return $this|string Either $this or the HTTP version. - * @deprecated 3.3.0 Use getProtocolVersion() and withProtocolVersion() instead. - */ - public function version($version = null) - { - deprecationWarning( - 'Request::version() is deprecated. ' . - 'Use getProtocolVersion() and withProtocolVersion() instead.' - ); - - if ($version === null) { - return $this->protocol; - } - - $this->protocol = $version; - - return $this; - } - - /** - * Get/set the body/payload for the message. - * - * Array data will be serialized with Cake\Http\FormData, - * and the content-type will be set. - * - * @param string|array|null $body The body for the request. Leave null for get - * @return mixed Either $this or the body value. - */ - public function body($body = null) - { - if ($body === null) { - $body = $this->getBody(); - - return $body ? $body->__toString() : ''; - } - if (is_array($body)) { - $formData = new FormData(); - $formData->addMany($body); - $this->addHeaders(['Content-Type' => $formData->contentType()]); - $body = (string)$formData; - } - $stream = new Stream('php://memory', 'rw'); - $stream->write($body); - $this->stream = $stream; - - return $this; - } -} - -// @deprecated Add backwards compact alias. -class_alias('Cake\Http\Client\Request', 'Cake\Network\Http\Request'); diff --git a/vendor/cakephp/cakephp/src/Http/Client/Response.php b/vendor/cakephp/cakephp/src/Http/Client/Response.php deleted file mode 100644 index 9e896c3..0000000 --- a/vendor/cakephp/cakephp/src/Http/Client/Response.php +++ /dev/null @@ -1,673 +0,0 @@ -getHeaderLine('content-type'); - * ``` - * - * Will read the Content-Type header. You can get all set - * headers using: - * - * ``` - * $response->getHeaders(); - * ``` - * - * You can also get at the headers using object access. When getting - * headers with object access, you have to use case-sensitive header - * names: - * - * ``` - * $val = $response->headers['Content-Type']; - * ``` - * - * ### Get the response body - * - * You can access the response body stream using: - * - * ``` - * $content = $response->getBody(); - * ``` - * - * You can also use object access to get the string version - * of the response body: - * - * ``` - * $content = $response->body; - * ``` - * - * If your response body is in XML or JSON you can use - * special content type specific accessors to read the decoded data. - * JSON data will be returned as arrays, while XML data will be returned - * as SimpleXML nodes: - * - * ``` - * // Get as xml - * $content = $response->xml - * // Get as json - * $content = $response->json - * ``` - * - * If the response cannot be decoded, null will be returned. - * - * ### Check the status code - * - * You can access the response status code using: - * - * ``` - * $content = $response->getStatusCode(); - * ``` - * - * You can also use object access: - * - * ``` - * $content = $response->code; - * ``` - */ -class Response extends Message implements ResponseInterface -{ - use MessageTrait; - - /** - * The status code of the response. - * - * @var int - */ - protected $code; - - /** - * Cookie Collection instance - * - * @var \Cake\Http\Cookie\CookieCollection - */ - protected $cookies; - - /** - * The reason phrase for the status code - * - * @var string - */ - protected $reasonPhrase; - - /** - * Cached decoded XML data. - * - * @var \SimpleXMLElement - */ - protected $_xml; - - /** - * Cached decoded JSON data. - * - * @var array - */ - protected $_json; - - /** - * Map of public => property names for __get() - * - * @var array - */ - protected $_exposedProperties = [ - 'cookies' => '_getCookies', - 'body' => '_getBody', - 'code' => 'code', - 'json' => '_getJson', - 'xml' => '_getXml', - 'headers' => '_getHeaders', - ]; - - /** - * Constructor - * - * @param array $headers Unparsed headers. - * @param string $body The response body. - */ - public function __construct($headers = [], $body = '') - { - $this->_parseHeaders($headers); - if ($this->getHeaderLine('Content-Encoding') === 'gzip') { - $body = $this->_decodeGzipBody($body); - } - $stream = new Stream('php://memory', 'wb+'); - $stream->write($body); - $stream->rewind(); - $this->stream = $stream; - } - - /** - * Uncompress a gzip response. - * - * Looks for gzip signatures, and if gzinflate() exists, - * the body will be decompressed. - * - * @param string $body Gzip encoded body. - * @return string - * @throws \RuntimeException When attempting to decode gzip content without gzinflate. - */ - protected function _decodeGzipBody($body) - { - if (!function_exists('gzinflate')) { - throw new RuntimeException('Cannot decompress gzip response body without gzinflate()'); - } - $offset = 0; - // Look for gzip 'signature' - if (substr($body, 0, 2) === "\x1f\x8b") { - $offset = 2; - } - // Check the format byte - if (substr($body, $offset, 1) === "\x08") { - return gzinflate(substr($body, $offset + 8)); - } - } - - /** - * Parses headers if necessary. - * - * - Decodes the status code and reasonphrase. - * - Parses and normalizes header names + values. - * - * @param array $headers Headers to parse. - * @return void - */ - protected function _parseHeaders($headers) - { - foreach ($headers as $key => $value) { - if (substr($value, 0, 5) === 'HTTP/') { - preg_match('/HTTP\/([\d.]+) ([0-9]+)(.*)/i', $value, $matches); - $this->protocol = $matches[1]; - $this->code = (int)$matches[2]; - $this->reasonPhrase = trim($matches[3]); - continue; - } - list($name, $value) = explode(':', $value, 2); - $value = trim($value); - $name = trim($name); - - $normalized = strtolower($name); - - if (isset($this->headers[$name])) { - $this->headers[$name][] = $value; - } else { - $this->headers[$name] = (array)$value; - $this->headerNames[$normalized] = $name; - } - } - } - - /** - * Check if the response was OK - * - * @return bool - */ - public function isOk() - { - $codes = [ - static::STATUS_OK, - static::STATUS_CREATED, - static::STATUS_ACCEPTED, - static::STATUS_NON_AUTHORITATIVE_INFORMATION, - static::STATUS_NO_CONTENT - ]; - - return in_array($this->code, $codes); - } - - /** - * Check if the response had a redirect status code. - * - * @return bool - */ - public function isRedirect() - { - $codes = [ - static::STATUS_MOVED_PERMANENTLY, - static::STATUS_FOUND, - static::STATUS_SEE_OTHER, - static::STATUS_TEMPORARY_REDIRECT, - ]; - - return ( - in_array($this->code, $codes) && - $this->getHeaderLine('Location') - ); - } - - /** - * Get the status code from the response - * - * @return int - * @deprecated 3.3.0 Use getStatusCode() instead. - */ - public function statusCode() - { - deprecationWarning( - 'Response::statusCode() is deprecated. ' . - 'Use Response::getStatusCode() instead.' - ); - - return $this->code; - } - - /** - * {@inheritdoc} - * - * @return int The status code. - */ - public function getStatusCode() - { - return $this->code; - } - - /** - * {@inheritdoc} - * - * @param int $code The status code to set. - * @param string $reasonPhrase The status reason phrase. - * @return $this A copy of the current object with an updated status code. - */ - public function withStatus($code, $reasonPhrase = '') - { - $new = clone $this; - $new->code = $code; - $new->reasonPhrase = $reasonPhrase; - - return $new; - } - - /** - * {@inheritdoc} - * - * @return string The current reason phrase. - */ - public function getReasonPhrase() - { - return $this->reasonPhrase; - } - - /** - * Get the encoding if it was set. - * - * @return string|null - * @deprecated 3.3.0 Use getEncoding() instead. - */ - public function encoding() - { - deprecationWarning( - 'Response::encoding() is deprecated. ' . - 'Use Response::getEncoding() instead.' - ); - - return $this->getEncoding(); - } - - /** - * Get the encoding if it was set. - * - * @return string|null - */ - public function getEncoding() - { - $content = $this->getHeaderLine('content-type'); - if (!$content) { - return null; - } - preg_match('/charset\s?=\s?[\'"]?([a-z0-9-_]+)[\'"]?/i', $content, $matches); - if (empty($matches[1])) { - return null; - } - - return $matches[1]; - } - - /** - * Read single/multiple header value(s) out. - * - * @param string|null $name The name of the header you want. Leave - * null to get all headers. - * @return mixed Null when the header doesn't exist. An array - * will be returned when getting all headers or when getting - * a header that had multiple values set. Otherwise a string - * will be returned. - * @deprecated 3.3.0 Use getHeader() and getHeaderLine() instead. - */ - public function header($name = null) - { - deprecationWarning( - 'Response::header() is deprecated. ' . - 'Use Response::getHeader() and getHeaderLine() instead.' - ); - - if ($name === null) { - return $this->_getHeaders(); - } - $header = $this->getHeader($name); - if (count($header) === 1) { - return $header[0]; - } - - return $header; - } - - /** - * Read single/multiple cookie values out. - * - * *Note* This method will only provide access to cookies that - * were added as part of the constructor. If cookies are added post - * construction they will not be accessible via this method. - * - * @param string|null $name The name of the cookie you want. Leave - * null to get all cookies. - * @param bool $all Get all parts of the cookie. When false only - * the value will be returned. - * @return mixed - * @deprecated 3.3.0 Use getCookie(), getCookieData() or getCookies() instead. - */ - public function cookie($name = null, $all = false) - { - deprecationWarning( - 'Response::cookie() is deprecated. ' . - 'Use Response::getCookie(), getCookieData() or getCookies() instead.' - ); - - if ($name === null) { - return $this->getCookies(); - } - if ($all) { - return $this->getCookieData($name); - } - - return $this->getCookie($name); - } - - /** - * Get the all cookie data. - * - * @return array The cookie data - */ - public function getCookies() - { - return $this->_getCookies(); - } - - /** - * Get the cookie collection from this response. - * - * This method exposes the response's CookieCollection - * instance allowing you to interact with cookie objects directly. - * - * @return \Cake\Http\Cookie\CookieCollection - */ - public function getCookieCollection() - { - $this->buildCookieCollection(); - - return $this->cookies; - } - - /** - * Get the value of a single cookie. - * - * @param string $name The name of the cookie value. - * @return string|array|null Either the cookie's value or null when the cookie is undefined. - */ - public function getCookie($name) - { - $this->buildCookieCollection(); - if (!$this->cookies->has($name)) { - return null; - } - - return $this->cookies->get($name)->getValue(); - } - - /** - * Get the full data for a single cookie. - * - * @param string $name The name of the cookie value. - * @return array|null Either the cookie's data or null when the cookie is undefined. - */ - public function getCookieData($name) - { - $this->buildCookieCollection(); - - if (!$this->cookies->has($name)) { - return null; - } - - $cookie = $this->cookies->get($name); - - return $this->convertCookieToArray($cookie); - } - - /** - * Convert the cookie into an array of its properties. - * - * This method is compatible with older client code that - * expects date strings instead of timestamps. - * - * @param \Cake\Http\Cookie\CookieInterface $cookie Cookie object. - * @return array - */ - protected function convertCookieToArray(CookieInterface $cookie) - { - return [ - 'name' => $cookie->getName(), - 'value' => $cookie->getValue(), - 'path' => $cookie->getPath(), - 'domain' => $cookie->getDomain(), - 'secure' => $cookie->isSecure(), - 'httponly' => $cookie->isHttpOnly(), - 'expires' => $cookie->getFormattedExpires() - ]; - } - - /** - * Lazily build the CookieCollection and cookie objects from the response header - * - * @return void - */ - protected function buildCookieCollection() - { - if ($this->cookies) { - return; - } - $this->cookies = CookiesCollection::createFromHeader($this->getHeader('Set-Cookie')); - } - - /** - * Property accessor for `$this->cookies` - * - * @return array Array of Cookie data. - */ - protected function _getCookies() - { - $this->buildCookieCollection(); - - $cookies = []; - foreach ($this->cookies as $cookie) { - $cookies[$cookie->getName()] = $this->convertCookieToArray($cookie); - } - - return $cookies; - } - - /** - * Get the HTTP version used. - * - * @return string - * @deprecated 3.3.0 Use getProtocolVersion() - */ - public function version() - { - deprecationWarning( - 'Response::version() is deprecated. ' . - 'Use Response::getProtocolVersion() instead.' - ); - - return $this->protocol; - } - - /** - * Get the response body. - * - * By passing in a $parser callable, you can get the decoded - * response content back. - * - * For example to get the json data as an object: - * - * ``` - * $body = $response->body('json_decode'); - * ``` - * - * @param callable|null $parser The callback to use to decode - * the response body. - * @return mixed The response body. - */ - public function body($parser = null) - { - $stream = $this->stream; - $stream->rewind(); - if ($parser) { - return $parser($stream->getContents()); - } - - return $stream->getContents(); - } - - /** - * Get the response body as JSON decoded data. - * - * @return array|null - */ - protected function _getJson() - { - if ($this->_json) { - return $this->_json; - } - - return $this->_json = json_decode($this->_getBody(), true); - } - - /** - * Get the response body as XML decoded data. - * - * @return null|\SimpleXMLElement - */ - protected function _getXml() - { - if ($this->_xml) { - return $this->_xml; - } - libxml_use_internal_errors(); - $data = simplexml_load_string($this->_getBody()); - if ($data) { - $this->_xml = $data; - - return $this->_xml; - } - - return null; - } - - /** - * Provides magic __get() support. - * - * @return array - */ - protected function _getHeaders() - { - $out = []; - foreach ($this->headers as $key => $values) { - $out[$key] = implode(',', $values); - } - - return $out; - } - - /** - * Provides magic __get() support. - * - * @return array - */ - protected function _getBody() - { - $this->stream->rewind(); - - return $this->stream->getContents(); - } - - /** - * Read values as properties. - * - * @param string $name Property name. - * @return mixed - */ - public function __get($name) - { - if (!isset($this->_exposedProperties[$name])) { - return false; - } - $key = $this->_exposedProperties[$name]; - if (substr($key, 0, 4) === '_get') { - return $this->{$key}(); - } - - return $this->{$key}; - } - - /** - * isset/empty test with -> syntax. - * - * @param string $name Property name. - * @return bool - */ - public function __isset($name) - { - if (!isset($this->_exposedProperties[$name])) { - return false; - } - $key = $this->_exposedProperties[$name]; - if (substr($key, 0, 4) === '_get') { - $val = $this->{$key}(); - - return $val !== null; - } - - return isset($this->{$key}); - } -} - -// @deprecated Add backwards compat alias. -class_alias('Cake\Http\Client\Response', 'Cake\Network\Http\Response'); diff --git a/vendor/cakephp/cakephp/src/Http/ControllerFactory.php b/vendor/cakephp/cakephp/src/Http/ControllerFactory.php deleted file mode 100644 index eebb1ec..0000000 --- a/vendor/cakephp/cakephp/src/Http/ControllerFactory.php +++ /dev/null @@ -1,107 +0,0 @@ -getControllerClass($request); - if (!$className) { - $this->missingController($request); - } - $reflection = new ReflectionClass($className); - if ($reflection->isAbstract() || $reflection->isInterface()) { - $this->missingController($request); - } - - return $reflection->newInstance($request, $response); - } - - /** - * Determine the controller class name based on current request and controller param - * - * @param \Cake\Http\ServerRequest $request The request to build a controller for. - * @return string|null - */ - public function getControllerClass(ServerRequest $request) - { - $pluginPath = $controller = null; - $namespace = 'Controller'; - if ($request->getParam('controller')) { - $controller = $request->getParam('controller'); - } - if ($request->getParam('plugin')) { - $pluginPath = $request->getParam('plugin') . '.'; - } - if ($request->getParam('prefix')) { - if (strpos($request->getParam('prefix'), '/') === false) { - $namespace .= '/' . Inflector::camelize($request->getParam('prefix')); - } else { - $prefixes = array_map( - 'Cake\Utility\Inflector::camelize', - explode('/', $request->getParam('prefix')) - ); - $namespace .= '/' . implode('/', $prefixes); - } - } - $firstChar = substr($controller, 0, 1); - - // Disallow plugin short forms, / and \\ from - // controller names as they allow direct references to - // be created. - if (strpos($controller, '\\') !== false || - strpos($controller, '/') !== false || - strpos($controller, '.') !== false || - $firstChar === strtolower($firstChar) - ) { - $this->missingController($request); - } - - return App::className($pluginPath . $controller, $namespace, 'Controller') ?: null; - } - - /** - * Throws an exception when a controller is missing. - * - * @param \Cake\Http\ServerRequest $request The request. - * @throws \Cake\Routing\Exception\MissingControllerException - * @return void - */ - protected function missingController($request) - { - throw new MissingControllerException([ - 'class' => $request->getParam('controller'), - 'plugin' => $request->getParam('plugin'), - 'prefix' => $request->getParam('prefix'), - '_ext' => $request->getParam('_ext') - ]); - } -} diff --git a/vendor/cakephp/cakephp/src/Http/MiddlewareQueue.php b/vendor/cakephp/cakephp/src/Http/MiddlewareQueue.php deleted file mode 100644 index 7f12d3b..0000000 --- a/vendor/cakephp/cakephp/src/Http/MiddlewareQueue.php +++ /dev/null @@ -1,233 +0,0 @@ -queue = $middleware; - } - - /** - * Get the middleware at the provided index. - * - * @param int $index The index to fetch. - * @return callable|null Either the callable middleware or null - * if the index is undefined. - */ - public function get($index) - { - if (isset($this->callables[$index])) { - return $this->callables[$index]; - } - - return $this->resolve($index); - } - - /** - * Resolve middleware name to callable. - * - * @param int $index The index to fetch. - * @return callable|null Either the callable middleware or null - * if the index is undefined. - */ - protected function resolve($index) - { - if (!isset($this->queue[$index])) { - return null; - } - - if (is_string($this->queue[$index])) { - $class = $this->queue[$index]; - $className = App::className($class, 'Middleware', 'Middleware'); - if (!$className || !class_exists($className)) { - throw new RuntimeException(sprintf( - 'Middleware "%s" was not found.', - $class - )); - } - $callable = new $className; - } else { - $callable = $this->queue[$index]; - } - - return $this->callables[$index] = $callable; - } - - /** - * Append a middleware callable to the end of the queue. - * - * @param callable|string|array $middleware The middleware(s) to append. - * @return $this - */ - public function add($middleware) - { - if (is_array($middleware)) { - $this->queue = array_merge($this->queue, $middleware); - - return $this; - } - $this->queue[] = $middleware; - - return $this; - } - - /** - * Alias for MiddlewareQueue::add(). - * - * @param callable|string|array $middleware The middleware(s) to append. - * @return $this - * @see MiddlewareQueue::add() - */ - public function push($middleware) - { - return $this->add($middleware); - } - - /** - * Prepend a middleware to the start of the queue. - * - * @param callable|string|array $middleware The middleware(s) to prepend. - * @return $this - */ - public function prepend($middleware) - { - if (is_array($middleware)) { - $this->queue = array_merge($middleware, $this->queue); - - return $this; - } - array_unshift($this->queue, $middleware); - - return $this; - } - - /** - * Insert a middleware callable at a specific index. - * - * If the index already exists, the new callable will be inserted, - * and the existing element will be shifted one index greater. - * - * @param int $index The index to insert at. - * @param callable|string $middleware The middleware to insert. - * @return $this - */ - public function insertAt($index, $middleware) - { - array_splice($this->queue, $index, 0, [$middleware]); - - return $this; - } - - /** - * Insert a middleware object before the first matching class. - * - * Finds the index of the first middleware that matches the provided class, - * and inserts the supplied callable before it. - * - * @param string $class The classname to insert the middleware before. - * @param callable|string $middleware The middleware to insert. - * @return $this - * @throws \LogicException If middleware to insert before is not found. - */ - public function insertBefore($class, $middleware) - { - $found = false; - $i = null; - foreach ($this->queue as $i => $object) { - if ((is_string($object) && $object === $class) - || is_a($object, $class) - ) { - $found = true; - break; - } - } - if ($found) { - return $this->insertAt($i, $middleware); - } - throw new LogicException(sprintf("No middleware matching '%s' could be found.", $class)); - } - - /** - * Insert a middleware object after the first matching class. - * - * Finds the index of the first middleware that matches the provided class, - * and inserts the supplied callable after it. If the class is not found, - * this method will behave like add(). - * - * @param string $class The classname to insert the middleware before. - * @param callable|string $middleware The middleware to insert. - * @return $this - */ - public function insertAfter($class, $middleware) - { - $found = false; - $i = null; - foreach ($this->queue as $i => $object) { - if ((is_string($object) && $object === $class) - || is_a($object, $class) - ) { - $found = true; - break; - } - } - if ($found) { - return $this->insertAt($i + 1, $middleware); - } - - return $this->add($middleware); - } - - /** - * Get the number of connected middleware layers. - * - * Implement the Countable interface. - * - * @return int - */ - public function count() - { - return count($this->queue); - } -} diff --git a/vendor/cakephp/cakephp/src/Http/RequestTransformer.php b/vendor/cakephp/cakephp/src/Http/RequestTransformer.php deleted file mode 100644 index df89d29..0000000 --- a/vendor/cakephp/cakephp/src/Http/RequestTransformer.php +++ /dev/null @@ -1,157 +0,0 @@ -getParsedBody(); - $headers = []; - foreach ($request->getHeaders() as $k => $value) { - $name = sprintf('HTTP_%s', strtoupper(str_replace('-', '_', $k))); - $headers[$name] = implode(',', $value); - } - $server = $headers + $request->getServerParams(); - - $files = static::getFiles($request); - if (!empty($files)) { - $post = Hash::merge($post, $files); - } - - $input = $request->getBody()->getContents(); - $input = $input === '' ? null : $input; - - return new ServerRequest([ - 'query' => $request->getQueryParams(), - 'post' => $post, - 'cookies' => $request->getCookieParams(), - 'environment' => $server, - 'params' => static::getParams($request), - 'url' => $request->getUri()->getPath(), - 'base' => $request->getAttribute('base', ''), - 'webroot' => $request->getAttribute('webroot', '/'), - 'session' => $request->getAttribute('session', null), - 'input' => $input, - ]); - } - - /** - * Extract the routing parameters out of the request object. - * - * @param \Psr\Http\Message\ServerRequestInterface $request The request to extract params from. - * @return array The routing parameters. - */ - protected static function getParams(PsrRequest $request) - { - $params = (array)$request->getAttribute('params', []); - $params += [ - 'plugin' => null, - 'controller' => null, - 'action' => null, - '_ext' => null, - 'pass' => [] - ]; - - return $params; - } - - /** - * Extract the uploaded files out of the request object. - * - * CakePHP expects to get arrays of file information and - * not the parsed objects that PSR7 requests contain. Downsample the data here. - * - * @param \Psr\Http\Message\ServerRequestInterface $request The request to extract files from. - * @return array The routing parameters. - */ - protected static function getFiles($request) - { - return static::convertFiles([], $request->getUploadedFiles()); - } - - /** - * Convert a nested array of files to arrays. - * - * @param array $data The data to add files to. - * @param array $files The file objects to convert. - * @param string $path The current array path. - * @return array Converted file data - */ - protected static function convertFiles($data, $files, $path = '') - { - foreach ($files as $key => $file) { - $newPath = $path; - if ($newPath === '') { - $newPath = $key; - } - if ($newPath !== $key) { - $newPath .= '.' . $key; - } - - if (is_array($file)) { - $data = static::convertFiles($data, $file, $newPath); - } else { - $data = Hash::insert($data, $newPath, static::convertFile($file)); - } - } - - return $data; - } - - /** - * Convert a single file back into an array. - * - * @param \Psr\Http\Message\UploadedFileInterface $file The file to convert. - * @return array - */ - protected static function convertFile($file) - { - $error = $file->getError(); - $tmpName = ''; - if ($error === UPLOAD_ERR_OK) { - $tmpName = $file->getStream()->getMetadata('uri'); - } - - return [ - 'name' => $file->getClientFilename(), - 'type' => $file->getClientMediaType(), - 'tmp_name' => $tmpName, - 'error' => $error, - 'size' => $file->getSize(), - ]; - } -} diff --git a/vendor/cakephp/cakephp/src/Http/ResponseEmitter.php b/vendor/cakephp/cakephp/src/Http/ResponseEmitter.php deleted file mode 100644 index 9e320bc..0000000 --- a/vendor/cakephp/cakephp/src/Http/ResponseEmitter.php +++ /dev/null @@ -1,294 +0,0 @@ -emitStatusLine($response); - $this->emitHeaders($response); - $this->flush(); - - $range = $this->parseContentRange($response->getHeaderLine('Content-Range')); - if (is_array($range)) { - $this->emitBodyRange($range, $response, $maxBufferLength); - } else { - $this->emitBody($response, $maxBufferLength); - } - - if (function_exists('fastcgi_finish_request')) { - fastcgi_finish_request(); - } - } - - /** - * Emit the message body. - * - * @param \Psr\Http\Message\ResponseInterface $response The response to emit - * @param int $maxBufferLength The chunk size to emit - * @return void - */ - protected function emitBody(ResponseInterface $response, $maxBufferLength) - { - if (in_array($response->getStatusCode(), [204, 304])) { - return; - } - $body = $response->getBody(); - - if (!$body->isSeekable()) { - echo $body; - - return; - } - - $body->rewind(); - while (!$body->eof()) { - echo $body->read($maxBufferLength); - } - } - - /** - * Emit a range of the message body. - * - * @param array $range The range data to emit - * @param \Psr\Http\Message\ResponseInterface $response The response to emit - * @param int $maxBufferLength The chunk size to emit - * @return void - */ - protected function emitBodyRange(array $range, ResponseInterface $response, $maxBufferLength) - { - list($unit, $first, $last, $length) = $range; - - $body = $response->getBody(); - - if (!$body->isSeekable()) { - $contents = $body->getContents(); - echo substr($contents, $first, $last - $first + 1); - - return; - } - - $body = new RelativeStream($body, $first); - $body->rewind(); - $pos = 0; - $length = $last - $first + 1; - while (!$body->eof() && $pos < $length) { - if (($pos + $maxBufferLength) > $length) { - echo $body->read($length - $pos); - break; - } - - echo $body->read($maxBufferLength); - $pos = $body->tell(); - } - } - - /** - * Emit the status line. - * - * Emits the status line using the protocol version and status code from - * the response; if a reason phrase is available, it, too, is emitted. - * - * @param \Psr\Http\Message\ResponseInterface $response The response to emit - * @return void - */ - protected function emitStatusLine(ResponseInterface $response) - { - $reasonPhrase = $response->getReasonPhrase(); - header(sprintf( - 'HTTP/%s %d%s', - $response->getProtocolVersion(), - $response->getStatusCode(), - ($reasonPhrase ? ' ' . $reasonPhrase : '') - )); - } - - /** - * Emit response headers. - * - * Loops through each header, emitting each; if the header value - * is an array with multiple values, ensures that each is sent - * in such a way as to create aggregate headers (instead of replace - * the previous). - * - * @param \Psr\Http\Message\ResponseInterface $response The response to emit - * @return void - */ - protected function emitHeaders(ResponseInterface $response) - { - $cookies = []; - if (method_exists($response, 'getCookies')) { - $cookies = $response->getCookies(); - } - - foreach ($response->getHeaders() as $name => $values) { - if (strtolower($name) === 'set-cookie') { - $cookies = array_merge($cookies, $values); - continue; - } - $first = true; - foreach ($values as $value) { - header(sprintf( - '%s: %s', - $name, - $value - ), $first); - $first = false; - } - } - - $this->emitCookies($cookies); - } - - /** - * Emit cookies using setcookie() - * - * @param array $cookies An array of Set-Cookie headers. - * @return void - */ - protected function emitCookies(array $cookies) - { - foreach ($cookies as $cookie) { - if (is_array($cookie)) { - setcookie( - $cookie['name'], - $cookie['value'], - $cookie['expire'], - $cookie['path'], - $cookie['domain'], - $cookie['secure'], - $cookie['httpOnly'] - ); - continue; - } - - if (strpos($cookie, '";"') !== false) { - $cookie = str_replace('";"', '{__cookie_replace__}', $cookie); - $parts = str_replace('{__cookie_replace__}', '";"', explode(';', $cookie)); - } else { - $parts = preg_split('/\;[ \t]*/', $cookie); - } - - list($name, $value) = explode('=', array_shift($parts), 2); - $data = [ - 'name' => urldecode($name), - 'value' => urldecode($value), - 'expires' => 0, - 'path' => '', - 'domain' => '', - 'secure' => false, - 'httponly' => false - ]; - - foreach ($parts as $part) { - if (strpos($part, '=') !== false) { - list($key, $value) = explode('=', $part); - } else { - $key = $part; - $value = true; - } - - $key = strtolower($key); - $data[$key] = $value; - } - if (!empty($data['expires'])) { - $data['expires'] = strtotime($data['expires']); - } - setcookie( - $data['name'], - $data['value'], - $data['expires'], - $data['path'], - $data['domain'], - $data['secure'], - $data['httponly'] - ); - } - } - - /** - * Loops through the output buffer, flushing each, before emitting - * the response. - * - * @param int|null $maxBufferLevel Flush up to this buffer level. - * @return void - */ - protected function flush($maxBufferLevel = null) - { - if (null === $maxBufferLevel) { - $maxBufferLevel = ob_get_level(); - } - - while (ob_get_level() > $maxBufferLevel) { - ob_end_flush(); - } - } - - /** - * Parse content-range header - * https://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.16 - * - * @param string $header The Content-Range header to parse. - * @return false|array [unit, first, last, length]; returns false if no - * content range or an invalid content range is provided - */ - protected function parseContentRange($header) - { - if (preg_match('/(?P[\w]+)\s+(?P\d+)-(?P\d+)\/(?P\d+|\*)/', $header, $matches)) { - return [ - $matches['unit'], - (int)$matches['first'], - (int)$matches['last'], - $matches['length'] === '*' ? '*' : (int)$matches['length'], - ]; - } - - return false; - } -} diff --git a/vendor/cakephp/cakephp/src/Http/ResponseTransformer.php b/vendor/cakephp/cakephp/src/Http/ResponseTransformer.php deleted file mode 100644 index 58363ba..0000000 --- a/vendor/cakephp/cakephp/src/Http/ResponseTransformer.php +++ /dev/null @@ -1,275 +0,0 @@ - $response->getStatusCode(), - 'body' => $body['body'], - ]; - $cake = new CakeResponse($data); - if ($body['file']) { - $cake->file($body['file']); - } - $cookies = static::parseCookies($response->getHeader('Set-Cookie')); - foreach ($cookies as $cookie) { - $cake->cookie($cookie); - } - $headers = static::collapseHeaders($response); - $cake->header($headers); - - if (!empty($headers['Content-Type'])) { - $cake->type($headers['Content-Type']); - } - - return $cake; - } - - /** - * Get the response body from a PSR7 Response. - * - * @param \Psr\Http\Message\ResponseInterface $response The response to convert. - * @return array A hash of 'body' and 'file' - */ - protected static function getBody(PsrResponse $response) - { - $stream = $response->getBody(); - if ($stream->getMetadata('wrapper_type') === 'plainfile') { - return ['body' => '', 'file' => $stream->getMetadata('uri')]; - } - if ($stream->getSize() === 0) { - return ['body' => '', 'file' => false]; - } - $stream->rewind(); - - return ['body' => $stream->getContents(), 'file' => false]; - } - - /** - * Parse the Set-Cookie headers in a PSR7 response - * into the format CakePHP expects. - * - * @param array $cookieHeader A list of Set-Cookie headers. - * @return array Parsed cookie data. - */ - protected static function parseCookies(array $cookieHeader) - { - $cookies = []; - foreach ($cookieHeader as $cookie) { - if (strpos($cookie, '";"') !== false) { - $cookie = str_replace('";"', '{__cookie_replace__}', $cookie); - $parts = preg_split('/\;[ \t]*/', $cookie); - $parts = str_replace('{__cookie_replace__}', '";"', $parts); - } else { - $parts = preg_split('/\;[ \t]*/', $cookie); - } - - list($name, $value) = explode('=', array_shift($parts), 2); - $parsed = ['name' => $name, 'value' => urldecode($value)]; - - foreach ($parts as $part) { - if (strpos($part, '=') !== false) { - list($key, $value) = explode('=', $part); - } else { - $key = $part; - $value = true; - } - - $key = strtolower($key); - if ($key === 'httponly') { - $key = 'httpOnly'; - } - if ($key === 'expires') { - $key = 'expire'; - $value = strtotime($value); - } - if (!isset($parsed[$key])) { - $parsed[$key] = $value; - } - } - $cookies[] = $parsed; - } - - return $cookies; - } - - /** - * Convert a PSR7 Response headers into a flat array - * - * @param \Psr\Http\Message\ResponseInterface $response The response to convert. - * @return array Headers. - */ - protected static function collapseHeaders(PsrResponse $response) - { - $out = []; - foreach ($response->getHeaders() as $name => $value) { - if (count($value) === 1) { - $out[$name] = $value[0]; - } else { - $out[$name] = $value; - } - } - - return $out; - } - - /** - * Convert a CakePHP response into a PSR7 one. - * - * @param \Cake\Http\Response $response The CakePHP response to convert - * @return \Psr\Http\Message\ResponseInterface $response The equivalent PSR7 response. - */ - public static function toPsr(CakeResponse $response) - { - $status = $response->statusCode(); - $headers = $response->header(); - if (!isset($headers['Content-Type'])) { - $headers = static::setContentType($headers, $response); - } - $cookies = $response->cookie(); - if ($cookies) { - $headers['Set-Cookie'] = static::buildCookieHeader($cookies); - } - $stream = static::getStream($response); - - return new DiactorosResponse($stream, $status, $headers); - } - - /** - * Add in the Content-Type header if necessary. - * - * @param array $headers The headers to update - * @param \Cake\Http\Response $response The CakePHP response to convert - * @return array The updated headers. - */ - protected static function setContentType($headers, $response) - { - if (isset($headers['Content-Type'])) { - return $headers; - } - if (in_array($response->statusCode(), [204, 304])) { - return $headers; - } - - $whitelist = [ - 'application/javascript', 'application/json', 'application/xml', 'application/rss+xml' - ]; - - $type = $response->type(); - $charset = $response->charset(); - - $hasCharset = false; - if ($charset && (strpos($type, 'text/') === 0 || in_array($type, $whitelist))) { - $hasCharset = true; - } - - $value = $type; - if ($hasCharset) { - $value = "{$type}; charset={$charset}"; - } - $headers['Content-Type'] = $value; - - return $headers; - } - - /** - * Convert an array of cookies into header lines. - * - * @param array $cookies The cookies to serialize. - * @return array A list of cookie header values. - */ - protected static function buildCookieHeader($cookies) - { - $headers = []; - foreach ($cookies as $cookie) { - $parts = [ - sprintf('%s=%s', urlencode($cookie['name']), urlencode($cookie['value'])) - ]; - if ($cookie['expire']) { - $cookie['expire'] = gmdate('D, d M Y H:i:s T', $cookie['expire']); - } - $attributes = [ - 'expire' => 'Expires=%s', - 'path' => 'Path=%s', - 'domain' => 'Domain=%s', - 'httpOnly' => 'HttpOnly', - 'secure' => 'Secure', - ]; - foreach ($attributes as $key => $attr) { - if ($cookie[$key]) { - $parts[] = sprintf($attr, $cookie[$key]); - } - } - $headers[] = implode('; ', $parts); - } - - return $headers; - } - - /** - * Get the stream for the new response. - * - * @param \Cake\Http\Response $response The cake response to extract the body from. - * @return \Psr\Http\Message\StreamInterface|string The stream. - */ - protected static function getStream($response) - { - $stream = 'php://memory'; - $body = $response->body(); - if (is_string($body) && strlen($body)) { - $stream = new Stream('php://memory', 'wb'); - $stream->write($body); - - return $stream; - } - if (is_callable($body)) { - $stream = new CallbackStream($body); - - return $stream; - } - $file = $response->getFile(); - if ($file) { - $stream = new Stream($file->path, 'rb'); - - return $stream; - } - - return $stream; - } -} diff --git a/vendor/cakephp/cakephp/src/Http/Runner.php b/vendor/cakephp/cakephp/src/Http/Runner.php deleted file mode 100644 index a6eaa81..0000000 --- a/vendor/cakephp/cakephp/src/Http/Runner.php +++ /dev/null @@ -1,71 +0,0 @@ -middleware = $middleware; - $this->index = 0; - - return $this->__invoke($request, $response); - } - - /** - * @param \Psr\Http\Message\ServerRequestInterface $request The server request - * @param \Psr\Http\Message\ResponseInterface $response The response object - * @return \Psr\Http\Message\ResponseInterface An updated response - */ - public function __invoke(ServerRequestInterface $request, ResponseInterface $response) - { - $next = $this->middleware->get($this->index); - if ($next) { - $this->index++; - - return $next($request, $response, $this); - } - - // End of the queue - return $response; - } -} diff --git a/vendor/cakephp/cakephp/src/Http/Server.php b/vendor/cakephp/cakephp/src/Http/Server.php deleted file mode 100644 index 5e2691b..0000000 --- a/vendor/cakephp/cakephp/src/Http/Server.php +++ /dev/null @@ -1,220 +0,0 @@ -app = $app; - $this->setRunner(new Runner()); - } - - /** - * Run the request/response through the Application and its middleware. - * - * This will invoke the following methods: - * - * - App->bootstrap() - Perform any bootstrapping logic for your application here. - * - App->middleware() - Attach any application middleware here. - * - Trigger the 'Server.buildMiddleware' event. You can use this to modify the - * from event listeners. - * - Run the middleware queue including the application. - * - * @param \Psr\Http\Message\ServerRequestInterface|null $request The request to use or null. - * @param \Psr\Http\Message\ResponseInterface|null $response The response to use or null. - * @return \Psr\Http\Message\ResponseInterface - * @throws \RuntimeException When the application does not make a response. - */ - public function run(ServerRequestInterface $request = null, ResponseInterface $response = null) - { - $this->bootstrap(); - - $response = $response ?: new Response(); - $request = $request ?: ServerRequestFactory::fromGlobals(); - - $middleware = $this->app->middleware(new MiddlewareQueue()); - if ($this->app instanceof PluginApplicationInterface) { - $middleware = $this->app->pluginMiddleware($middleware); - } - - if (!($middleware instanceof MiddlewareQueue)) { - throw new RuntimeException('The application `middleware` method did not return a middleware queue.'); - } - $this->dispatchEvent('Server.buildMiddleware', ['middleware' => $middleware]); - $middleware->add($this->app); - - $response = $this->runner->run($middleware, $request, $response); - - if (!($response instanceof ResponseInterface)) { - throw new RuntimeException(sprintf( - 'Application did not create a response. Got "%s" instead.', - is_object($response) ? get_class($response) : $response - )); - } - - return $response; - } - - /** - * Application bootstrap wrapper. - * - * Calls `bootstrap()` and `events()` if application implements `EventApplicationInterface`. - * After the application is bootstrapped and events are attached, plugins are bootstrapped - * and have their events attached. - * - * @return void - */ - protected function bootstrap() - { - $this->app->bootstrap(); - - if ($this->app instanceof PluginApplicationInterface) { - $this->app->pluginBootstrap(); - } - } - - /** - * Emit the response using the PHP SAPI. - * - * @param \Psr\Http\Message\ResponseInterface $response The response to emit - * @param \Zend\Diactoros\Response\EmitterInterface|null $emitter The emitter to use. - * When null, a SAPI Stream Emitter will be used. - * @return void - */ - public function emit(ResponseInterface $response, EmitterInterface $emitter = null) - { - if (!$emitter) { - $emitter = new ResponseEmitter(); - } - $emitter->emit($response); - } - - /** - * Get the current application. - * - * @return \Cake\Core\HttpApplicationInterface The application that will be run. - */ - public function getApp() - { - return $this->app; - } - - /** - * Set the runner - * - * @param \Cake\Http\Runner $runner The runner to use. - * @return $this - */ - public function setRunner(Runner $runner) - { - $this->runner = $runner; - - return $this; - } - - /** - * Get the application's event manager or the global one. - * - * @return \Cake\Event\EventManagerInterface - */ - public function getEventManager() - { - if ($this->app instanceof PluginApplicationInterface) { - return $this->app->getEventManager(); - } - - return EventManager::instance(); - } - - /** - * Get/set the application's event manager. - * - * If the application does not support events and this method is used as - * a setter, an exception will be raised. - * - * @param \Cake\Event\EventManager|null $events The event manager to set. - * @return \Cake\Event\EventManager|$this - * @deprecated 3.6.0 Will be removed in 4.0 - */ - public function eventManager(EventManager $events = null) - { - deprecationWarning('eventManager() is deprecated. Use getEventManager()/setEventManager() instead.'); - if ($events === null) { - return $this->getEventManager(); - } - - return $this->setEventManager($events); - } - - /** - * Get/set the application's event manager. - * - * If the application does not support events and this method is used as - * a setter, an exception will be raised. - * - * @param \Cake\Event\EventManager $events The event manager to set. - * @return $this - */ - public function setEventManager(EventManager $events) - { - if ($this->app instanceof PluginApplicationInterface) { - $this->app->setEventManager($events); - - return $this; - } - - throw new InvalidArgumentException('Cannot set the event manager, the application does not support events.'); - } -} diff --git a/vendor/cakephp/cakephp/src/Http/ServerRequestFactory.php b/vendor/cakephp/cakephp/src/Http/ServerRequestFactory.php deleted file mode 100644 index f86b66b..0000000 --- a/vendor/cakephp/cakephp/src/Http/ServerRequestFactory.php +++ /dev/null @@ -1,206 +0,0 @@ - 'php', - 'cookiePath' => $uri->webroot - ]; - $session = Session::create($sessionConfig); - $request = new ServerRequest([ - 'environment' => $server, - 'uri' => $uri, - 'files' => $files ?: $_FILES, - 'cookies' => $cookies ?: $_COOKIE, - 'query' => $query ?: $_GET, - 'post' => $body ?: $_POST, - 'webroot' => $uri->webroot, - 'base' => $uri->base, - 'session' => $session, - ]); - - return $request; - } - - /** - * Create a new Uri instance from the provided server data. - * - * @param array $server Array of server data to build the Uri from. - * $_SERVER will be added into the $server parameter. - * @return \Psr\Http\Message\UriInterface New instance. - */ - public static function createUri(array $server = []) - { - $server += $_SERVER; - $server = static::normalizeServer($server); - $headers = static::marshalHeaders($server); - - return static::marshalUriFromServer($server, $headers); - } - - /** - * Build a UriInterface object. - * - * Add in some CakePHP specific logic/properties that help - * perserve backwards compatibility. - * - * @param array $server The server parameters. - * @param array $headers The normalized headers - * @return \Psr\Http\Message\UriInterface a constructed Uri - */ - public static function marshalUriFromServer(array $server, array $headers) - { - $uri = parent::marshalUriFromServer($server, $headers); - list($base, $webroot) = static::getBase($uri, $server); - - // Look in PATH_INFO first, as this is the exact value we need prepared - // by PHP. - $pathInfo = Hash::get($server, 'PATH_INFO'); - if ($pathInfo) { - $uri = $uri->withPath($pathInfo); - } else { - $uri = static::updatePath($base, $uri); - } - - if (!$uri->getHost()) { - $uri = $uri->withHost('localhost'); - } - - // Splat on some extra attributes to save - // some method calls. - $uri->base = $base; - $uri->webroot = $webroot; - - return $uri; - } - - /** - * Updates the request URI to remove the base directory. - * - * @param string $base The base path to remove. - * @param \Psr\Http\Message\UriInterface $uri The uri to update. - * @return \Psr\Http\Message\UriInterface The modified Uri instance. - */ - protected static function updatePath($base, $uri) - { - $path = $uri->getPath(); - if (strlen($base) > 0 && strpos($path, $base) === 0) { - $path = substr($path, strlen($base)); - } - if ($path === '/index.php' && $uri->getQuery()) { - $path = $uri->getQuery(); - } - if (empty($path) || $path === '/' || $path === '//' || $path === '/index.php') { - $path = '/'; - } - $endsWithIndex = '/webroot/index.php'; - $endsWithLength = strlen($endsWithIndex); - if (strlen($path) >= $endsWithLength && - substr($path, -$endsWithLength) === $endsWithIndex - ) { - $path = '/'; - } - - return $uri->withPath($path); - } - - /** - * Calculate the base directory and webroot directory. - * - * @param \Psr\Http\Message\UriInterface $uri The Uri instance. - * @param array $server The SERVER data to use. - * @return array An array containing the [baseDir, webroot] - */ - protected static function getBase($uri, $server) - { - $config = (array)Configure::read('App') + [ - 'base' => null, - 'webroot' => null, - 'baseUrl' => null - ]; - $base = $config['base']; - $baseUrl = $config['baseUrl']; - $webroot = $config['webroot']; - - if ($base !== false && $base !== null) { - return [$base, $base . '/']; - } - - if (!$baseUrl) { - $base = dirname(Hash::get($server, 'PHP_SELF')); - // Clean up additional / which cause following code to fail.. - $base = preg_replace('#/+#', '/', $base); - - $indexPos = strpos($base, '/' . $webroot . '/index.php'); - if ($indexPos !== false) { - $base = substr($base, 0, $indexPos) . '/' . $webroot; - } - if ($webroot === basename($base)) { - $base = dirname($base); - } - - if ($base === DIRECTORY_SEPARATOR || $base === '.') { - $base = ''; - } - $base = implode('/', array_map('rawurlencode', explode('/', $base))); - - return [$base, $base . '/']; - } - - $file = '/' . basename($baseUrl); - $base = dirname($baseUrl); - - if ($base === DIRECTORY_SEPARATOR || $base === '.') { - $base = ''; - } - $webrootDir = $base . '/'; - - $docRoot = Hash::get($server, 'DOCUMENT_ROOT'); - $docRootContainsWebroot = strpos($docRoot, $webroot); - - if (!empty($base) || !$docRootContainsWebroot) { - if (strpos($webrootDir, '/' . $webroot . '/') === false) { - $webrootDir .= $webroot . '/'; - } - } - - return [$base . $file, $webrootDir]; - } -} diff --git a/vendor/cakephp/cakephp/src/I18n/ChainMessagesLoader.php b/vendor/cakephp/cakephp/src/I18n/ChainMessagesLoader.php deleted file mode 100644 index 9b61301..0000000 --- a/vendor/cakephp/cakephp/src/I18n/ChainMessagesLoader.php +++ /dev/null @@ -1,79 +0,0 @@ -_loaders = $loaders; - } - - /** - * Executes this object returning the translations package as configured in - * the chain. - * - * @return \Aura\Intl\Package - * @throws \RuntimeException if any of the loaders in the chain is not a valid callable - */ - public function __invoke() - { - foreach ($this->_loaders as $k => $loader) { - if (!is_callable($loader)) { - throw new RuntimeException(sprintf( - 'Loader "%s" in the chain is not a valid callable', - $k - )); - } - - $package = $loader(); - if (!$package) { - continue; - } - - if (!($package instanceof Package)) { - throw new RuntimeException(sprintf( - 'Loader "%s" in the chain did not return a valid Package object', - $k - )); - } - - return $package; - } - - return new Package(); - } -} diff --git a/vendor/cakephp/cakephp/src/I18n/Date.php b/vendor/cakephp/cakephp/src/I18n/Date.php deleted file mode 100644 index a021724..0000000 --- a/vendor/cakephp/cakephp/src/I18n/Date.php +++ /dev/null @@ -1,135 +0,0 @@ - 'day', - 'month' => 'day', - 'week' => 'day', - 'day' => 'day', - 'hour' => 'day', - 'minute' => 'day', - 'second' => 'day', - ]; - - /** - * The end of relative time telling - * - * @var string - * @see \Cake\I18n\Date::timeAgoInWords() - */ - public static $wordEnd = '+1 month'; - - /** - * Returns either a relative or a formatted absolute date depending - * on the difference between the current date and this object. - * - * ### Options: - * - * - `from` => another Date object representing the "now" date - * - `format` => a fall back format if the relative time is longer than the duration specified by end - * - `accuracy` => Specifies how accurate the date should be described (array) - * - year => The format if years > 0 (default "day") - * - month => The format if months > 0 (default "day") - * - week => The format if weeks > 0 (default "day") - * - day => The format if weeks > 0 (default "day") - * - `end` => The end of relative date telling - * - `relativeString` => The printf compatible string when outputting relative date - * - `absoluteString` => The printf compatible string when outputting absolute date - * - `timezone` => The user timezone the timestamp should be formatted in. - * - * Relative dates look something like this: - * - * - 3 weeks, 4 days ago - * - 1 day ago - * - * Default date formatting is d/M/YY e.g: on 18/2/09. Formatting is done internally using - * `i18nFormat`, see the method for the valid formatting strings. - * - * The returned string includes 'ago' or 'on' and assumes you'll properly add a word - * like 'Posted ' before the function output. - * - * NOTE: If the difference is one week or more, the lowest level of accuracy is day. - * - * @param array $options Array of options. - * @return string Relative time string. - */ - public function timeAgoInWords(array $options = []) - { - return static::diffFormatter()->dateAgoInWords($this, $options); - } -} diff --git a/vendor/cakephp/cakephp/src/I18n/DateFormatTrait.php b/vendor/cakephp/cakephp/src/I18n/DateFormatTrait.php deleted file mode 100644 index f0b043b..0000000 --- a/vendor/cakephp/cakephp/src/I18n/DateFormatTrait.php +++ /dev/null @@ -1,436 +0,0 @@ -i18nFormat(static::$niceFormat, $timezone, $locale); - } - - /** - * Returns a formatted string for this time object using the preferred format and - * language for the specified locale. - * - * It is possible to specify the desired format for the string to be displayed. - * You can either pass `IntlDateFormatter` constants as the first argument of this - * function, or pass a full ICU date formatting string as specified in the following - * resource: http://www.icu-project.org/apiref/icu4c/classSimpleDateFormat.html#details. - * - * Additional to `IntlDateFormatter` constants and date formatting string you can use - * Time::UNIX_TIMESTAMP_FORMAT to get a unix timestamp - * - * ### Examples - * - * ``` - * $time = new Time('2014-04-20 22:10'); - * $time->i18nFormat(); // outputs '4/20/14, 10:10 PM' for the en-US locale - * $time->i18nFormat(\IntlDateFormatter::FULL); // Use the full date and time format - * $time->i18nFormat([\IntlDateFormatter::FULL, \IntlDateFormatter::SHORT]); // Use full date but short time format - * $time->i18nFormat('yyyy-MM-dd HH:mm:ss'); // outputs '2014-04-20 22:10' - * $time->i18nFormat(Time::UNIX_TIMESTAMP_FORMAT); // outputs '1398031800' - * ``` - * - * If you wish to control the default format to be used for this method, you can alter - * the value of the static `Time::$defaultLocale` variable and set it to one of the - * possible formats accepted by this function. - * - * You can read about the available IntlDateFormatter constants at - * https://secure.php.net/manual/en/class.intldateformatter.php - * - * If you need to display the date in a different timezone than the one being used for - * this Time object without altering its internal state, you can pass a timezone - * string or object as the second parameter. - * - * Finally, should you need to use a different locale for displaying this time object, - * pass a locale string as the third parameter to this function. - * - * ### Examples - * - * ``` - * $time = new Time('2014-04-20 22:10'); - * $time->i18nFormat(null, null, 'de-DE'); - * $time->i18nFormat(\IntlDateFormatter::FULL, 'Europe/Berlin', 'de-DE'); - * ``` - * - * You can control the default locale to be used by setting the static variable - * `Time::$defaultLocale` to a valid locale string. If empty, the default will be - * taken from the `intl.default_locale` ini config. - * - * @param string|int|null $format Format string. - * @param string|\DateTimeZone|null $timezone Timezone string or DateTimeZone object - * in which the date will be displayed. The timezone stored for this object will not - * be changed. - * @param string|null $locale The locale name in which the date should be displayed (e.g. pt-BR) - * @return string Formatted and translated date string - */ - public function i18nFormat($format = null, $timezone = null, $locale = null) - { - if ($format === Time::UNIX_TIMESTAMP_FORMAT) { - return $this->getTimestamp(); - } - - $time = $this; - - if ($timezone) { - // Handle the immutable and mutable object cases. - $time = clone $this; - $time = $time->timezone($timezone); - } - - $format = $format !== null ? $format : static::$_toStringFormat; - $locale = $locale ?: static::$defaultLocale; - - return $this->_formatObject($time, $format, $locale); - } - - /** - * Returns a translated and localized date string. - * Implements what IntlDateFormatter::formatObject() is in PHP 5.5+ - * - * @param \DateTime $date Date. - * @param string|int|array $format Format. - * @param string $locale The locale name in which the date should be displayed. - * @return string - */ - protected function _formatObject($date, $format, $locale) - { - $pattern = $dateFormat = $timeFormat = $calendar = null; - - if (is_array($format)) { - list($dateFormat, $timeFormat) = $format; - } elseif (is_numeric($format)) { - $dateFormat = $format; - } else { - $dateFormat = $timeFormat = IntlDateFormatter::FULL; - $pattern = $format; - } - - if (preg_match('/@calendar=(japanese|buddhist|chinese|persian|indian|islamic|hebrew|coptic|ethiopic)/', $locale)) { - $calendar = IntlDateFormatter::TRADITIONAL; - } else { - $calendar = IntlDateFormatter::GREGORIAN; - } - - $timezone = $date->getTimezone()->getName(); - $key = "{$locale}.{$dateFormat}.{$timeFormat}.{$timezone}.{$calendar}.{$pattern}"; - - if (!isset(static::$_formatters[$key])) { - if ($timezone === '+00:00' || $timezone === 'Z') { - $timezone = 'UTC'; - } elseif ($timezone[0] === '+' || $timezone[0] === '-') { - $timezone = 'GMT' . $timezone; - } - static::$_formatters[$key] = datefmt_create( - $locale, - $dateFormat, - $timeFormat, - $timezone, - $calendar, - $pattern - ); - } - - return static::$_formatters[$key]->format($date->format('U')); - } - - /** - * {@inheritDoc} - */ - public function __toString() - { - return $this->i18nFormat(); - } - - /** - * Resets the format used to the default when converting an instance of this type to - * a string - * - * @return void - */ - public static function resetToStringFormat() - { - static::setToStringFormat([IntlDateFormatter::SHORT, IntlDateFormatter::SHORT]); - } - - /** - * Sets the default format used when type converting instances of this type to string - * - * @param string|array|int $format Format. - * @return void - */ - public static function setToStringFormat($format) - { - static::$_toStringFormat = $format; - } - - /** - * Sets the default format used when converting this object to json - * - * @param string|array|int $format Format. - * @return void - */ - public static function setJsonEncodeFormat($format) - { - static::$_jsonEncodeFormat = $format; - } - - /** - * Returns a new Time object after parsing the provided time string based on - * the passed or configured date time format. This method is locale dependent, - * Any string that is passed to this function will be interpreted as a locale - * dependent string. - * - * When no $format is provided, the `toString` format will be used. - * - * If it was impossible to parse the provided time, null will be returned. - * - * Example: - * - * ``` - * $time = Time::parseDateTime('10/13/2013 12:54am'); - * $time = Time::parseDateTime('13 Oct, 2013 13:54', 'dd MMM, y H:mm'); - * $time = Time::parseDateTime('10/10/2015', [IntlDateFormatter::SHORT, -1]); - * ``` - * - * @param string $time The time string to parse. - * @param string|array|null $format Any format accepted by IntlDateFormatter. - * @return static|null - */ - public static function parseDateTime($time, $format = null) - { - $dateFormat = $format ?: static::$_toStringFormat; - $timeFormat = $pattern = null; - - if (is_array($dateFormat)) { - list($newDateFormat, $timeFormat) = $dateFormat; - $dateFormat = $newDateFormat; - } else { - $pattern = $dateFormat; - $dateFormat = null; - } - - if (static::$_isDateInstance === null) { - static::$_isDateInstance = - is_subclass_of(static::class, ChronosDate::class) || - is_subclass_of(static::class, MutableDate::class); - } - - $defaultTimezone = static::$_isDateInstance ? 'UTC' : date_default_timezone_get(); - $formatter = datefmt_create( - static::$defaultLocale, - $dateFormat, - $timeFormat, - $defaultTimezone, - null, - $pattern - ); - $time = $formatter->parse($time); - if ($time !== false) { - $result = new static('@' . $time); - - return static::$_isDateInstance ? $result : $result->setTimezone($defaultTimezone); - } - - return null; - } - - /** - * Returns a new Time object after parsing the provided $date string based on - * the passed or configured date time format. This method is locale dependent, - * Any string that is passed to this function will be interpreted as a locale - * dependent string. - * - * When no $format is provided, the `wordFormat` format will be used. - * - * If it was impossible to parse the provided time, null will be returned. - * - * Example: - * - * ``` - * $time = Time::parseDate('10/13/2013'); - * $time = Time::parseDate('13 Oct, 2013', 'dd MMM, y'); - * $time = Time::parseDate('13 Oct, 2013', IntlDateFormatter::SHORT); - * ``` - * - * @param string $date The date string to parse. - * @param string|int|null $format Any format accepted by IntlDateFormatter. - * @return static|null - */ - public static function parseDate($date, $format = null) - { - if (is_int($format)) { - $format = [$format, -1]; - } - $format = $format ?: static::$wordFormat; - - return static::parseDateTime($date, $format); - } - - /** - * Returns a new Time object after parsing the provided $time string based on - * the passed or configured date time format. This method is locale dependent, - * Any string that is passed to this function will be interpreted as a locale - * dependent string. - * - * When no $format is provided, the IntlDateFormatter::SHORT format will be used. - * - * If it was impossible to parse the provided time, null will be returned. - * - * Example: - * - * ``` - * $time = Time::parseTime('11:23pm'); - * ``` - * - * @param string $time The time string to parse. - * @param string|int|null $format Any format accepted by IntlDateFormatter. - * @return static|null - */ - public static function parseTime($time, $format = null) - { - if (is_int($format)) { - $format = [-1, $format]; - } - $format = $format ?: [-1, IntlDateFormatter::SHORT]; - - return static::parseDateTime($time, $format); - } - - /** - * Returns a string that should be serialized when converting this object to json - * - * @return string - */ - public function jsonSerialize() - { - return $this->i18nFormat(static::$_jsonEncodeFormat); - } - - /** - * Get the difference formatter instance or overwrite the current one. - * - * @param \Cake\I18n\RelativeTimeFormatter|null $formatter The formatter instance when setting. - * @return \Cake\I18n\RelativeTimeFormatter The formatter instance. - */ - public static function diffFormatter($formatter = null) - { - if ($formatter === null) { - // Use the static property defined in chronos. - if (static::$diffFormatter === null) { - static::$diffFormatter = new RelativeTimeFormatter(); - } - - return static::$diffFormatter; - } - - return static::$diffFormatter = $formatter; - } - - /** - * Returns the data that should be displayed when debugging this object - * - * @return array - */ - public function __debugInfo() - { - return [ - 'time' => $this->toIso8601String(), - 'timezone' => $this->getTimezone()->getName(), - 'fixedNowTime' => static::hasTestNow() ? static::getTestNow()->toIso8601String() : false - ]; - } -} diff --git a/vendor/cakephp/cakephp/src/I18n/Formatter/IcuFormatter.php b/vendor/cakephp/cakephp/src/I18n/Formatter/IcuFormatter.php deleted file mode 100644 index a5d4644..0000000 --- a/vendor/cakephp/cakephp/src/I18n/Formatter/IcuFormatter.php +++ /dev/null @@ -1,79 +0,0 @@ -_formatMessage($locale, $message, $vars); - } - - /** - * Does the actual formatting using the MessageFormatter class - * - * @param string $locale The locale in which the message is presented. - * @param string|array $message The message to be translated - * @param array $vars The list of values to interpolate in the message - * @return string The formatted message - * @throws \Aura\Intl\Exception\CannotInstantiateFormatter if any error occurred - * while parsing the message - * @throws \Aura\Intl\Exception\CannotFormat If any error related to the passed - * variables is found - */ - protected function _formatMessage($locale, $message, $vars) - { - if ($message === '') { - return $message; - } - // Using procedural style as it showed twice as fast as - // its counterpart in PHP 5.5 - $result = MessageFormatter::formatMessage($locale, $message, $vars); - - if ($result === false) { - // The user might be interested in what went wrong, so replay the - // previous action using the object oriented style to figure out - $formatter = new MessageFormatter($locale, $message); - if (!$formatter) { - throw new CannotInstantiateFormatter(intl_get_error_message(), intl_get_error_code()); - } - - $formatter->format($vars); - throw new CannotFormat($formatter->getErrorMessage(), $formatter->getErrorCode()); - } - - return $result; - } -} diff --git a/vendor/cakephp/cakephp/src/I18n/Formatter/SprintfFormatter.php b/vendor/cakephp/cakephp/src/I18n/Formatter/SprintfFormatter.php deleted file mode 100644 index 2cb8d5d..0000000 --- a/vendor/cakephp/cakephp/src/I18n/Formatter/SprintfFormatter.php +++ /dev/null @@ -1,41 +0,0 @@ - 'day', - 'month' => 'day', - 'week' => 'day', - 'day' => 'day', - 'hour' => 'day', - 'minute' => 'day', - 'second' => 'day', - ]; - - /** - * The end of relative time telling - * - * @var string - * @see \Cake\I18n\Date::timeAgoInWords() - */ - public static $wordEnd = '+1 month'; - - /** - * Returns either a relative or a formatted absolute date depending - * on the difference between the current date and this object. - * - * ### Options: - * - * - `from` => another Date object representing the "now" date - * - `format` => a fall back format if the relative time is longer than the duration specified by end - * - `accuracy` => Specifies how accurate the date should be described (array) - * - year => The format if years > 0 (default "day") - * - month => The format if months > 0 (default "day") - * - week => The format if weeks > 0 (default "day") - * - day => The format if weeks > 0 (default "day") - * - `end` => The end of relative date telling - * - `relativeString` => The printf compatible string when outputting relative date - * - `absoluteString` => The printf compatible string when outputting absolute date - * - `timezone` => The user timezone the timestamp should be formatted in. - * - * Relative dates look something like this: - * - * - 3 weeks, 4 days ago - * - 1 day ago - * - * Default date formatting is d/M/YY e.g: on 18/2/09. Formatting is done internally using - * `i18nFormat`, see the method for the valid formatting strings. - * - * The returned string includes 'ago' or 'on' and assumes you'll properly add a word - * like 'Posted ' before the function output. - * - * NOTE: If the difference is one week or more, the lowest level of accuracy is day. - * - * @param array $options Array of options. - * @return string Relative time string. - */ - public function timeAgoInWords(array $options = []) - { - return static::diffFormatter()->dateAgoInWords($this, $options); - } -} diff --git a/vendor/cakephp/cakephp/src/I18n/FrozenTime.php b/vendor/cakephp/cakephp/src/I18n/FrozenTime.php deleted file mode 100644 index 500aa21..0000000 --- a/vendor/cakephp/cakephp/src/I18n/FrozenTime.php +++ /dev/null @@ -1,292 +0,0 @@ - 'day', - 'month' => 'day', - 'week' => 'day', - 'day' => 'hour', - 'hour' => 'minute', - 'minute' => 'minute', - 'second' => 'second', - ]; - - /** - * The end of relative time telling - * - * @var string - * @see \Cake\I18n\FrozenTime::timeAgoInWords() - */ - public static $wordEnd = '+1 month'; - - /** - * serialise the value as a Unix Timestamp - * - * @var string - */ - const UNIX_TIMESTAMP_FORMAT = 'unixTimestampFormat'; - - /** - * {@inheritDoc} - */ - public function __construct($time = null, $tz = null) - { - if ($time instanceof DateTimeInterface) { - $tz = $time->getTimezone(); - $time = $time->format('Y-m-d H:i:s'); - } - - if (is_numeric($time)) { - $time = '@' . $time; - } - - parent::__construct($time, $tz); - } - - /** - * Returns either a relative or a formatted absolute date depending - * on the difference between the current time and this object. - * - * ### Options: - * - * - `from` => another Time object representing the "now" time - * - `format` => a fall back format if the relative time is longer than the duration specified by end - * - `accuracy` => Specifies how accurate the date should be described (array) - * - year => The format if years > 0 (default "day") - * - month => The format if months > 0 (default "day") - * - week => The format if weeks > 0 (default "day") - * - day => The format if weeks > 0 (default "hour") - * - hour => The format if hours > 0 (default "minute") - * - minute => The format if minutes > 0 (default "minute") - * - second => The format if seconds > 0 (default "second") - * - `end` => The end of relative time telling - * - `relativeString` => The printf compatible string when outputting relative time - * - `absoluteString` => The printf compatible string when outputting absolute time - * - `timezone` => The user timezone the timestamp should be formatted in. - * - * Relative dates look something like this: - * - * - 3 weeks, 4 days ago - * - 15 seconds ago - * - * Default date formatting is d/M/YY e.g: on 18/2/09. Formatting is done internally using - * `i18nFormat`, see the method for the valid formatting strings - * - * The returned string includes 'ago' or 'on' and assumes you'll properly add a word - * like 'Posted ' before the function output. - * - * NOTE: If the difference is one week or more, the lowest level of accuracy is day - * - * @param array $options Array of options. - * @return string Relative time string. - */ - public function timeAgoInWords(array $options = []) - { - return static::diffFormatter()->timeAgoInWords($this, $options); - } - - /** - * Get list of timezone identifiers - * - * @param int|string|null $filter A regex to filter identifier - * Or one of DateTimeZone class constants - * @param string|null $country A two-letter ISO 3166-1 compatible country code. - * This option is only used when $filter is set to DateTimeZone::PER_COUNTRY - * @param bool|array $options If true (default value) groups the identifiers list by primary region. - * Otherwise, an array containing `group`, `abbr`, `before`, and `after` - * keys. Setting `group` and `abbr` to true will group results and append - * timezone abbreviation in the display value. Set `before` and `after` - * to customize the abbreviation wrapper. - * @return array List of timezone identifiers - * @since 2.2 - */ - public static function listTimezones($filter = null, $country = null, $options = []) - { - if (is_bool($options)) { - $options = [ - 'group' => $options, - ]; - } - $defaults = [ - 'group' => true, - 'abbr' => false, - 'before' => ' - ', - 'after' => null, - ]; - $options += $defaults; - $group = $options['group']; - - $regex = null; - if (is_string($filter)) { - $regex = $filter; - $filter = null; - } - if ($filter === null) { - $filter = DateTimeZone::ALL; - } - $identifiers = DateTimeZone::listIdentifiers($filter, $country); - - if ($regex) { - foreach ($identifiers as $key => $tz) { - if (!preg_match($regex, $tz)) { - unset($identifiers[$key]); - } - } - } - - if ($group) { - $groupedIdentifiers = []; - $now = time(); - $before = $options['before']; - $after = $options['after']; - foreach ($identifiers as $key => $tz) { - $abbr = null; - if ($options['abbr']) { - $dateTimeZone = new DateTimeZone($tz); - $trans = $dateTimeZone->getTransitions($now, $now); - $abbr = isset($trans[0]['abbr']) ? - $before . $trans[0]['abbr'] . $after : - null; - } - $item = explode('/', $tz, 2); - if (isset($item[1])) { - $groupedIdentifiers[$item[0]][$tz] = $item[1] . $abbr; - } else { - $groupedIdentifiers[$item[0]] = [$tz => $item[0] . $abbr]; - } - } - - return $groupedIdentifiers; - } - - return array_combine($identifiers, $identifiers); - } - - /** - * Returns true this instance will happen within the specified interval - * - * This overridden method provides backwards compatible behavior for integers, - * or strings with trailing spaces. This behavior is *deprecated* and will be - * removed in future versions of CakePHP. - * - * @param string|int $timeInterval the numeric value with space then time type. - * Example of valid types: 6 hours, 2 days, 1 minute. - * @return bool - */ - public function wasWithinLast($timeInterval) - { - $tmp = trim($timeInterval); - if (is_numeric($tmp)) { - deprecationWarning( - 'Passing int/numeric string into FrozenTime::wasWithinLast() is deprecated. ' . - 'Pass strings including interval eg. "6 days"' - ); - $timeInterval = $tmp . ' days'; - } - - return parent::wasWithinLast($timeInterval); - } - - /** - * Returns true this instance happened within the specified interval - * - * This overridden method provides backwards compatible behavior for integers, - * or strings with trailing spaces. This behavior is *deprecated* and will be - * removed in future versions of CakePHP. - * - * @param string|int $timeInterval the numeric value with space then time type. - * Example of valid types: 6 hours, 2 days, 1 minute. - * @return bool - */ - public function isWithinNext($timeInterval) - { - $tmp = trim($timeInterval); - if (is_numeric($tmp)) { - deprecationWarning( - 'Passing int/numeric string into FrozenTime::isWithinNext() is deprecated. ' . - 'Pass strings including interval eg. "6 days"' - ); - $timeInterval = $tmp . ' days'; - } - - return parent::isWithinNext($timeInterval); - } -} diff --git a/vendor/cakephp/cakephp/src/I18n/I18n.php b/vendor/cakephp/cakephp/src/I18n/I18n.php deleted file mode 100644 index d10dc97..0000000 --- a/vendor/cakephp/cakephp/src/I18n/I18n.php +++ /dev/null @@ -1,424 +0,0 @@ - function () { - return new SprintfFormatter(); - }, - 'default' => function () { - return new IcuFormatter(); - }, - ]), - new TranslatorFactory, - static::getLocale() - ); - - if (class_exists('Cake\Cache\Cache')) { - static::$_collection->setCacher(Cache::engine('_cake_core_')); - } - - return static::$_collection; - } - - /** - * Returns an instance of a translator that was configured for the name and passed - * locale. If no locale is passed then it takes the value returned by the `getLocale()` method. - * - * This method can be used to configure future translators, this is achieved by passing a callable - * as the last argument of this function. - * - * ### Example: - * - * ``` - * I18n::setTranslator('default', function () { - * $package = new \Aura\Intl\Package(); - * $package->setMessages([ - * 'Cake' => 'Gâteau' - * ]); - * return $package; - * }, 'fr_FR'); - * - * $translator = I18n::translator('default', 'fr_FR'); - * echo $translator->translate('Cake'); - * ``` - * - * You can also use the `Cake\I18n\MessagesFileLoader` class to load a specific - * file from a folder. For example for loading a `my_translations.po` file from - * the `src/Locale/custom` folder, you would do: - * - * ``` - * I18n::translator( - * 'default', - * 'fr_FR', - * new MessagesFileLoader('my_translations', 'custom', 'po'); - * ); - * ``` - * - * @deprecated 3.5 Use getTranslator() and setTranslator() - * @param string $name The domain of the translation messages. - * @param string|null $locale The locale for the translator. - * @param callable|null $loader A callback function or callable class responsible for - * constructing a translations package instance. - * @return \Aura\Intl\TranslatorInterface|null The configured translator. - */ - public static function translator($name = 'default', $locale = null, callable $loader = null) - { - deprecationWarning( - 'I18n::translator() is deprecated. ' . - 'Use I18n::setTranslator()/getTranslator() instead.' - ); - if ($loader !== null) { - static::setTranslator($name, $loader, $locale); - - return null; - } - - return self::getTranslator($name, $locale); - } - - /** - * Sets a translator. - * - * Configures future translators, this is achieved by passing a callable - * as the last argument of this function. - * - * ### Example: - * - * ``` - * I18n::setTranslator('default', function () { - * $package = new \Aura\Intl\Package(); - * $package->setMessages([ - * 'Cake' => 'Gâteau' - * ]); - * return $package; - * }, 'fr_FR'); - * - * $translator = I18n::getTranslator('default', 'fr_FR'); - * echo $translator->translate('Cake'); - * ``` - * - * You can also use the `Cake\I18n\MessagesFileLoader` class to load a specific - * file from a folder. For example for loading a `my_translations.po` file from - * the `src/Locale/custom` folder, you would do: - * - * ``` - * I18n::setTranslator( - * 'default', - * new MessagesFileLoader('my_translations', 'custom', 'po'), - * 'fr_FR' - * ); - * ``` - * - * @param string $name The domain of the translation messages. - * @param callable $loader A callback function or callable class responsible for - * constructing a translations package instance. - * @param string|null $locale The locale for the translator. - * @return void - */ - public static function setTranslator($name, callable $loader, $locale = null) - { - $locale = $locale ?: static::getLocale(); - - $translators = static::translators(); - $loader = $translators->setLoaderFallback($name, $loader); - $packages = $translators->getPackages(); - $packages->set($name, $locale, $loader); - } - - /** - * Returns an instance of a translator that was configured for the name and locale. - * - * If no locale is passed then it takes the value returned by the `getLocale()` method. - * - * @param string $name The domain of the translation messages. - * @param string|null $locale The locale for the translator. - * @return \Aura\Intl\TranslatorInterface The configured translator. - */ - public static function getTranslator($name = 'default', $locale = null) - { - $translators = static::translators(); - - if ($locale) { - $currentLocale = $translators->getLocale(); - $translators->setLocale($locale); - } - - $translator = $translators->get($name); - - if (isset($currentLocale)) { - $translators->setLocale($currentLocale); - } - - return $translator; - } - - /** - * Registers a callable object that can be used for creating new translator - * instances for the same translations domain. Loaders will be invoked whenever - * a translator object is requested for a domain that has not been configured or - * loaded already. - * - * Registering loaders is useful when you need to lazily use translations in multiple - * different locales for the same domain, and don't want to use the built-in - * translation service based of `gettext` files. - * - * Loader objects will receive two arguments: The domain name that needs to be - * built, and the locale that is requested. These objects can assemble the messages - * from any source, but must return an `Aura\Intl\Package` object. - * - * ### Example: - * - * ``` - * use Cake\I18n\MessagesFileLoader; - * I18n::config('my_domain', function ($name, $locale) { - * // Load src/Locale/$locale/filename.po - * $fileLoader = new MessagesFileLoader('filename', $locale, 'po'); - * return $fileLoader(); - * }); - * ``` - * - * You can also assemble the package object yourself: - * - * ``` - * use Aura\Intl\Package; - * I18n::config('my_domain', function ($name, $locale) { - * $package = new Package('default'); - * $messages = (...); // Fetch messages for locale from external service. - * $package->setMessages($message); - * $package->setFallback('default'); - * return $package; - * }); - * ``` - * - * @param string $name The name of the translator to create a loader for - * @param callable $loader A callable object that should return a Package - * instance to be used for assembling a new translator. - * @return void - */ - public static function config($name, callable $loader) - { - static::translators()->registerLoader($name, $loader); - } - - /** - * Sets the default locale to use for future translator instances. - * This also affects the `intl.default_locale` PHP setting. - * - * When called with no arguments it will return the currently configure - * locale as stored in the `intl.default_locale` PHP setting. - * - * @deprecated 3.5 Use setLocale() and getLocale(). - * @param string|null $locale The name of the locale to set as default. - * @return string|null The name of the default locale. - */ - public static function locale($locale = null) - { - deprecationWarning( - 'I18n::locale() is deprecated. ' . - 'Use I18n::setLocale()/getLocale() instead.' - ); - if (!empty($locale)) { - static::setLocale($locale); - - return null; - } - - return self::getLocale(); - } - - /** - * Sets the default locale to use for future translator instances. - * This also affects the `intl.default_locale` PHP setting. - * - * @param string $locale The name of the locale to set as default. - * @return void - */ - public static function setLocale($locale) - { - static::getDefaultLocale(); - Locale::setDefault($locale); - if (isset(static::$_collection)) { - static::translators()->setLocale($locale); - } - } - - /** - * Will return the currently configure locale as stored in the - * `intl.default_locale` PHP setting. - * - * @return string The name of the default locale. - */ - public static function getLocale() - { - static::getDefaultLocale(); - $current = Locale::getDefault(); - if ($current === '') { - $current = static::DEFAULT_LOCALE; - Locale::setDefault($current); - } - - return $current; - } - - /** - * This returns the default locale before any modifications, i.e. - * the value as stored in the `intl.default_locale` PHP setting before - * any manipulation by this class. - * - * @deprecated 3.5 Use getDefaultLocale() - * @return string - */ - public static function defaultLocale() - { - deprecationWarning('I18n::defaultLocale() is deprecated. Use I18n::getDefaultLocale() instead.'); - - return static::getDefaultLocale(); - } - - /** - * Returns the default locale. - * - * This returns the default locale before any modifications, i.e. - * the value as stored in the `intl.default_locale` PHP setting before - * any manipulation by this class. - * - * @return string - */ - public static function getDefaultLocale() - { - if (static::$_defaultLocale === null) { - static::$_defaultLocale = Locale::getDefault() ?: static::DEFAULT_LOCALE; - } - - return static::$_defaultLocale; - } - - /** - * Sets the name of the default messages formatter to use for future - * translator instances. - * - * By default the `default` and `sprintf` formatters are available. - * - * If called with no arguments, it will return the currently configured value. - * - * @deprecated 3.5 Use getDefaultFormatter() and setDefaultFormatter(). - * @param string|null $name The name of the formatter to use. - * @return string The name of the formatter. - */ - public static function defaultFormatter($name = null) - { - deprecationWarning( - 'I18n::defaultFormatter() is deprecated. ' . - 'Use I18n::setDefaultFormatter()/getDefaultFormatter() instead.' - ); - - return static::translators()->defaultFormatter($name); - } - - /** - * Returns the currently configured default formatter. - * - * @return string The name of the formatter. - */ - public static function getDefaultFormatter() - { - return static::translators()->defaultFormatter(); - } - - /** - * Sets the name of the default messages formatter to use for future - * translator instances. By default the `default` and `sprintf` formatters - * are available. - * - * @param string $name The name of the formatter to use. - * @return void - */ - public static function setDefaultFormatter($name) - { - static::translators()->defaultFormatter($name); - } - - /** - * Set if the domain fallback is used. - * - * @param bool $enable flag to enable or disable fallback - * @return void - */ - public static function useFallback($enable = true) - { - static::translators()->useFallback($enable); - } - - /** - * Destroys all translator instances and creates a new empty translations - * collection. - * - * @return void - */ - public static function clear() - { - static::$_collection = null; - } -} diff --git a/vendor/cakephp/cakephp/src/I18n/LICENSE.txt b/vendor/cakephp/cakephp/src/I18n/LICENSE.txt deleted file mode 100644 index 0c4b793..0000000 --- a/vendor/cakephp/cakephp/src/I18n/LICENSE.txt +++ /dev/null @@ -1,22 +0,0 @@ -The MIT License (MIT) - -CakePHP(tm) : The Rapid Development PHP Framework (https://cakephp.org) -Copyright (c) 2005-2016, Cake Software Foundation, Inc. (https://cakefoundation.org) - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. diff --git a/vendor/cakephp/cakephp/src/I18n/MessagesFileLoader.php b/vendor/cakephp/cakephp/src/I18n/MessagesFileLoader.php deleted file mode 100644 index 3fb0d60..0000000 --- a/vendor/cakephp/cakephp/src/I18n/MessagesFileLoader.php +++ /dev/null @@ -1,183 +0,0 @@ -_name = $name; - $this->_locale = $locale; - $this->_extension = $extension; - } - - /** - * Loads the translation file and parses it. Returns an instance of a translations - * package containing the messages loaded from the file. - * - * @return \Aura\Intl\Package|false - * @throws \RuntimeException if no file parser class could be found for the specified - * file extension. - */ - public function __invoke() - { - $folders = $this->translationsFolders(); - $ext = $this->_extension; - $file = false; - - $fileName = $this->_name; - $pos = strpos($fileName, '/'); - if ($pos !== false) { - $fileName = substr($fileName, $pos + 1); - } - foreach ($folders as $folder) { - $path = $folder . $fileName . ".$ext"; - if (is_file($path)) { - $file = $path; - break; - } - } - - if (!$file) { - return false; - } - - $name = ucfirst($ext); - $class = App::className($name, 'I18n\Parser', 'FileParser'); - - if (!$class) { - throw new RuntimeException(sprintf('Could not find class %s', "{$name}FileParser")); - } - - $messages = (new $class)->parse($file); - $package = new Package('default'); - $package->setMessages($messages); - - return $package; - } - - /** - * Returns the folders where the file should be looked for according to the locale - * and package name. - * - * @return array The list of folders where the translation file should be looked for - */ - public function translationsFolders() - { - $locale = Locale::parseLocale($this->_locale) + ['region' => null]; - - $folders = [ - implode('_', [$locale['language'], $locale['region']]), - $locale['language'] - ]; - - $searchPaths = []; - - $localePaths = App::path('Locale'); - if (empty($localePaths) && defined('APP')) { - $localePaths[] = APP . 'Locale' . DIRECTORY_SEPARATOR; - } - foreach ($localePaths as $path) { - foreach ($folders as $folder) { - $searchPaths[] = $path . $folder . DIRECTORY_SEPARATOR; - } - } - - // If space is not added after slash, the character after it remains lowercased - $pluginName = Inflector::camelize(str_replace('/', '/ ', $this->_name)); - if (Plugin::loaded($pluginName)) { - $basePath = Plugin::classPath($pluginName) . 'Locale' . DIRECTORY_SEPARATOR; - foreach ($folders as $folder) { - $searchPaths[] = $basePath . $folder . DIRECTORY_SEPARATOR; - } - } - - return $searchPaths; - } -} diff --git a/vendor/cakephp/cakephp/src/I18n/Middleware/LocaleSelectorMiddleware.php b/vendor/cakephp/cakephp/src/I18n/Middleware/LocaleSelectorMiddleware.php deleted file mode 100644 index 421fe85..0000000 --- a/vendor/cakephp/cakephp/src/I18n/Middleware/LocaleSelectorMiddleware.php +++ /dev/null @@ -1,64 +0,0 @@ -locales = $locales; - } - - /** - * @param ServerRequestInterface $request The request. - * @param ResponseInterface $response The response. - * @param callable $next The next middleware to call. - * @return \Psr\Http\Message\ResponseInterface A response. - */ - public function __invoke(ServerRequestInterface $request, ResponseInterface $response, $next) - { - $locale = Locale::acceptFromHttp($request->getHeaderLine('Accept-Language')); - if (!$locale) { - return $next($request, $response); - } - if (in_array($locale, $this->locales) || $this->locales === ['*']) { - I18n::setLocale($locale); - } - - return $next($request, $response); - } -} diff --git a/vendor/cakephp/cakephp/src/I18n/Number.php b/vendor/cakephp/cakephp/src/I18n/Number.php deleted file mode 100644 index 0027bd9..0000000 --- a/vendor/cakephp/cakephp/src/I18n/Number.php +++ /dev/null @@ -1,391 +0,0 @@ - $precision, 'places' => $precision] + $options); - - return $formatter->format($value); - } - - /** - * Returns a formatted-for-humans file size. - * - * @param int $size Size in bytes - * @return string Human readable size - * @link https://book.cakephp.org/3.0/en/core-libraries/number.html#interacting-with-human-readable-values - */ - public static function toReadableSize($size) - { - switch (true) { - case $size < 1024: - return __dn('cake', '{0,number,integer} Byte', '{0,number,integer} Bytes', $size, $size); - case round($size / 1024) < 1024: - return __d('cake', '{0,number,#,###.##} KB', $size / 1024); - case round($size / 1024 / 1024, 2) < 1024: - return __d('cake', '{0,number,#,###.##} MB', $size / 1024 / 1024); - case round($size / 1024 / 1024 / 1024, 2) < 1024: - return __d('cake', '{0,number,#,###.##} GB', $size / 1024 / 1024 / 1024); - default: - return __d('cake', '{0,number,#,###.##} TB', $size / 1024 / 1024 / 1024 / 1024); - } - } - - /** - * Formats a number into a percentage string. - * - * Options: - * - * - `multiply`: Multiply the input value by 100 for decimal percentages. - * - `locale`: The locale name to use for formatting the number, e.g. fr_FR - * - * @param float $value A floating point number - * @param int $precision The precision of the returned number - * @param array $options Options - * @return string Percentage string - * @link https://book.cakephp.org/3.0/en/core-libraries/number.html#formatting-percentages - */ - public static function toPercentage($value, $precision = 2, array $options = []) - { - $options += ['multiply' => false]; - if ($options['multiply']) { - $value *= 100; - } - - return static::precision($value, $precision, $options) . '%'; - } - - /** - * Formats a number into the correct locale format - * - * Options: - * - * - `places` - Minimum number or decimals to use, e.g 0 - * - `precision` - Maximum Number of decimal places to use, e.g. 2 - * - `pattern` - An ICU number pattern to use for formatting the number. e.g #,###.00 - * - `locale` - The locale name to use for formatting the number, e.g. fr_FR - * - `before` - The string to place before whole numbers, e.g. '[' - * - `after` - The string to place after decimal numbers, e.g. ']' - * - * @param float $value A floating point number. - * @param array $options An array with options. - * @return string Formatted number - */ - public static function format($value, array $options = []) - { - $formatter = static::formatter($options); - $options += ['before' => '', 'after' => '']; - - return $options['before'] . $formatter->format($value) . $options['after']; - } - - /** - * Parse a localized numeric string and transform it in a float point - * - * Options: - * - * - `locale` - The locale name to use for parsing the number, e.g. fr_FR - * - `type` - The formatter type to construct, set it to `currency` if you need to parse - * numbers representing money. - * - * @param string $value A numeric string. - * @param array $options An array with options. - * @return float point number - */ - public static function parseFloat($value, array $options = []) - { - $formatter = static::formatter($options); - - return (float)$formatter->parse($value, NumberFormatter::TYPE_DOUBLE); - } - - /** - * Formats a number into the correct locale format to show deltas (signed differences in value). - * - * ### Options - * - * - `places` - Minimum number or decimals to use, e.g 0 - * - `precision` - Maximum Number of decimal places to use, e.g. 2 - * - `locale` - The locale name to use for formatting the number, e.g. fr_FR - * - `before` - The string to place before whole numbers, e.g. '[' - * - `after` - The string to place after decimal numbers, e.g. ']' - * - * @param float $value A floating point number - * @param array $options Options list. - * @return string formatted delta - */ - public static function formatDelta($value, array $options = []) - { - $options += ['places' => 0]; - $value = number_format($value, $options['places'], '.', ''); - $sign = $value > 0 ? '+' : ''; - $options['before'] = isset($options['before']) ? $options['before'] . $sign : $sign; - - return static::format($value, $options); - } - - /** - * Formats a number into a currency format. - * - * ### Options - * - * - `locale` - The locale name to use for formatting the number, e.g. fr_FR - * - `fractionSymbol` - The currency symbol to use for fractional numbers. - * - `fractionPosition` - The position the fraction symbol should be placed - * valid options are 'before' & 'after'. - * - `before` - Text to display before the rendered number - * - `after` - Text to display after the rendered number - * - `zero` - The text to use for zero values, can be a string or a number. e.g. 0, 'Free!' - * - `places` - Number of decimal places to use. e.g. 2 - * - `precision` - Maximum Number of decimal places to use, e.g. 2 - * - `pattern` - An ICU number pattern to use for formatting the number. e.g #,###.00 - * - `useIntlCode` - Whether or not to replace the currency symbol with the international - * currency code. - * - * @param float $value Value to format. - * @param string|null $currency International currency name such as 'USD', 'EUR', 'JPY', 'CAD' - * @param array $options Options list. - * @return string Number formatted as a currency. - */ - public static function currency($value, $currency = null, array $options = []) - { - $value = (float)$value; - $currency = $currency ?: static::defaultCurrency(); - - if (isset($options['zero']) && !$value) { - return $options['zero']; - } - - $formatter = static::formatter(['type' => static::FORMAT_CURRENCY] + $options); - $abs = abs($value); - if (!empty($options['fractionSymbol']) && $abs > 0 && $abs < 1) { - $value *= 100; - $pos = isset($options['fractionPosition']) ? $options['fractionPosition'] : 'after'; - - return static::format($value, ['precision' => 0, $pos => $options['fractionSymbol']]); - } - - $before = isset($options['before']) ? $options['before'] : null; - $after = isset($options['after']) ? $options['after'] : null; - - return $before . $formatter->formatCurrency($value, $currency) . $after; - } - - /** - * Getter/setter for default currency - * - * @param string|bool|null $currency Default currency string to be used by currency() - * if $currency argument is not provided. If boolean false is passed, it will clear the - * currently stored value - * @return string|null Currency - */ - public static function defaultCurrency($currency = null) - { - if (!empty($currency)) { - return self::$_defaultCurrency = $currency; - } - - if ($currency === false) { - return self::$_defaultCurrency = null; - } - - if (empty(self::$_defaultCurrency)) { - $locale = ini_get('intl.default_locale') ?: static::DEFAULT_LOCALE; - $formatter = new NumberFormatter($locale, NumberFormatter::CURRENCY); - self::$_defaultCurrency = $formatter->getTextAttribute(NumberFormatter::CURRENCY_CODE); - } - - return self::$_defaultCurrency; - } - - /** - * Returns a formatter object that can be reused for similar formatting task - * under the same locale and options. This is often a speedier alternative to - * using other methods in this class as only one formatter object needs to be - * constructed. - * - * ### Options - * - * - `locale` - The locale name to use for formatting the number, e.g. fr_FR - * - `type` - The formatter type to construct, set it to `currency` if you need to format - * numbers representing money or a NumberFormatter constant. - * - `places` - Number of decimal places to use. e.g. 2 - * - `precision` - Maximum Number of decimal places to use, e.g. 2 - * - `pattern` - An ICU number pattern to use for formatting the number. e.g #,###.00 - * - `useIntlCode` - Whether or not to replace the currency symbol with the international - * currency code. - * - * @param array $options An array with options. - * @return \NumberFormatter The configured formatter instance - */ - public static function formatter($options = []) - { - $locale = isset($options['locale']) ? $options['locale'] : ini_get('intl.default_locale'); - - if (!$locale) { - $locale = static::DEFAULT_LOCALE; - } - - $type = NumberFormatter::DECIMAL; - if (!empty($options['type'])) { - $type = $options['type']; - if ($options['type'] === static::FORMAT_CURRENCY) { - $type = NumberFormatter::CURRENCY; - } - } - - if (!isset(static::$_formatters[$locale][$type])) { - static::$_formatters[$locale][$type] = new NumberFormatter($locale, $type); - } - - $formatter = static::$_formatters[$locale][$type]; - - $options = array_intersect_key($options, [ - 'places' => null, - 'precision' => null, - 'pattern' => null, - 'useIntlCode' => null - ]); - if (empty($options)) { - return $formatter; - } - - $formatter = clone $formatter; - - return static::_setAttributes($formatter, $options); - } - - /** - * Configure formatters. - * - * @param string $locale The locale name to use for formatting the number, e.g. fr_FR - * @param int $type The formatter type to construct. Defaults to NumberFormatter::DECIMAL. - * @param array $options See Number::formatter() for possible options. - * @return void - */ - public static function config($locale, $type = NumberFormatter::DECIMAL, array $options = []) - { - static::$_formatters[$locale][$type] = static::_setAttributes( - new NumberFormatter($locale, $type), - $options - ); - } - - /** - * Set formatter attributes - * - * @param \NumberFormatter $formatter Number formatter instance. - * @param array $options See Number::formatter() for possible options. - * @return \NumberFormatter - */ - protected static function _setAttributes(NumberFormatter $formatter, array $options = []) - { - if (isset($options['places'])) { - $formatter->setAttribute(NumberFormatter::MIN_FRACTION_DIGITS, $options['places']); - } - - if (isset($options['precision'])) { - $formatter->setAttribute(NumberFormatter::MAX_FRACTION_DIGITS, $options['precision']); - } - - if (!empty($options['pattern'])) { - $formatter->setPattern($options['pattern']); - } - - if (!empty($options['useIntlCode'])) { - // One of the odd things about ICU is that the currency marker in patterns - // is denoted with ¤, whereas the international code is marked with ¤¤, - // in order to use the code we need to simply duplicate the character wherever - // it appears in the pattern. - $pattern = trim(str_replace('¤', '¤¤ ', $formatter->getPattern())); - $formatter->setPattern($pattern); - } - - return $formatter; - } - - /** - * Returns a formatted integer as an ordinal number string (e.g. 1st, 2nd, 3rd, 4th, [...]) - * - * ### Options - * - * - `type` - The formatter type to construct, set it to `currency` if you need to format - * numbers representing money or a NumberFormatter constant. - * - * For all other options see formatter(). - * - * @param int|float $value An integer - * @param array $options An array with options. - * @return string - */ - public static function ordinal($value, array $options = []) - { - return static::formatter(['type' => NumberFormatter::ORDINAL] + $options)->format($value); - } -} diff --git a/vendor/cakephp/cakephp/src/I18n/Parser/MoFileParser.php b/vendor/cakephp/cakephp/src/I18n/Parser/MoFileParser.php deleted file mode 100644 index c8037e0..0000000 --- a/vendor/cakephp/cakephp/src/I18n/Parser/MoFileParser.php +++ /dev/null @@ -1,162 +0,0 @@ -_readLong($stream, $isBigEndian); - $offsetId = $this->_readLong($stream, $isBigEndian); - $offsetTranslated = $this->_readLong($stream, $isBigEndian); - - // Offset to start of translations - fread($stream, 8); - $messages = []; - - for ($i = 0; $i < $count; $i++) { - $pluralId = null; - $context = null; - $plurals = null; - - fseek($stream, $offsetId + $i * 8); - - $length = $this->_readLong($stream, $isBigEndian); - $offset = $this->_readLong($stream, $isBigEndian); - - if ($length < 1) { - continue; - } - - fseek($stream, $offset); - $singularId = fread($stream, $length); - - if (strpos($singularId, "\x04") !== false) { - list($context, $singularId) = explode("\x04", $singularId); - } - - if (strpos($singularId, "\000") !== false) { - list($singularId, $pluralId) = explode("\000", $singularId); - } - - fseek($stream, $offsetTranslated + $i * 8); - $length = $this->_readLong($stream, $isBigEndian); - $offset = $this->_readLong($stream, $isBigEndian); - fseek($stream, $offset); - $translated = fread($stream, $length); - - if ($pluralId !== null || strpos($translated, "\000") !== false) { - $translated = explode("\000", $translated); - $plurals = $pluralId !== null ? array_map('stripcslashes', $translated) : null; - $translated = $translated[0]; - } - - $singular = stripcslashes($translated); - if ($context !== null) { - $messages[$singularId]['_context'][$context] = $singular; - if ($pluralId !== null) { - $messages[$pluralId]['_context'][$context] = $plurals; - } - continue; - } - - $messages[$singularId] = $singular; - if ($pluralId !== null) { - $messages[$pluralId] = $plurals; - } - } - - fclose($stream); - - return $messages; - } - - /** - * Reads an unsigned long from stream respecting endianess. - * - * @param resource $stream The File being read. - * @param bool $isBigEndian Whether or not the current platform is Big Endian - * @return int - */ - protected function _readLong($stream, $isBigEndian) - { - $result = unpack($isBigEndian ? 'N1' : 'V1', fread($stream, 4)); - $result = current($result); - - return (int)substr($result, -8); - } -} diff --git a/vendor/cakephp/cakephp/src/I18n/Parser/PoFileParser.php b/vendor/cakephp/cakephp/src/I18n/Parser/PoFileParser.php deleted file mode 100644 index d0bbc4f..0000000 --- a/vendor/cakephp/cakephp/src/I18n/Parser/PoFileParser.php +++ /dev/null @@ -1,184 +0,0 @@ - [], - 'translated' => null - ]; - - $messages = []; - $item = $defaults; - $stage = null; - - while ($line = fgets($stream)) { - $line = trim($line); - - if ($line === '') { - // Whitespace indicated current item is done - $this->_addMessage($messages, $item); - $item = $defaults; - $stage = null; - } elseif (substr($line, 0, 7) === 'msgid "') { - // We start a new msg so save previous - $this->_addMessage($messages, $item); - $item['ids']['singular'] = substr($line, 7, -1); - $stage = ['ids', 'singular']; - } elseif (substr($line, 0, 8) === 'msgstr "') { - $item['translated'] = substr($line, 8, -1); - $stage = ['translated']; - } elseif (substr($line, 0, 9) === 'msgctxt "') { - $item['context'] = substr($line, 9, -1); - $stage = ['context']; - } elseif ($line[0] === '"') { - switch (count($stage)) { - case 2: - $item[$stage[0]][$stage[1]] .= substr($line, 1, -1); - break; - - case 1: - $item[$stage[0]] .= substr($line, 1, -1); - break; - } - } elseif (substr($line, 0, 14) === 'msgid_plural "') { - $item['ids']['plural'] = substr($line, 14, -1); - $stage = ['ids', 'plural']; - } elseif (substr($line, 0, 7) === 'msgstr[') { - $size = strpos($line, ']'); - $row = (int)substr($line, 7, 1); - $item['translated'][$row] = substr($line, $size + 3, -1); - $stage = ['translated', $row]; - } - } - // save last item - $this->_addMessage($messages, $item); - fclose($stream); - - return $messages; - } - - /** - * Saves a translation item to the messages. - * - * @param array $messages The messages array being collected from the file - * @param array $item The current item being inspected - * @return void - */ - protected function _addMessage(array &$messages, array $item) - { - if (empty($item['ids']['singular']) && empty($item['ids']['plural'])) { - return; - } - - $singular = stripcslashes($item['ids']['singular']); - $context = isset($item['context']) ? $item['context'] : null; - $translation = $item['translated']; - - if (is_array($translation)) { - $translation = $translation[0]; - } - - $translation = stripcslashes($translation); - - if ($context !== null && !isset($messages[$singular]['_context'][$context])) { - $messages[$singular]['_context'][$context] = $translation; - } elseif (!isset($messages[$singular]['_context'][''])) { - $messages[$singular]['_context'][''] = $translation; - } - - if (isset($item['ids']['plural'])) { - $plurals = $item['translated']; - // PO are by definition indexed so sort by index. - ksort($plurals); - - // Make sure every index is filled. - end($plurals); - $count = key($plurals); - - // Fill missing spots with an empty string. - $empties = array_fill(0, $count + 1, ''); - $plurals += $empties; - ksort($plurals); - - $plurals = array_map('stripcslashes', $plurals); - $key = stripcslashes($item['ids']['plural']); - - if ($context !== null) { - $messages[Translator::PLURAL_PREFIX . $key]['_context'][$context] = $plurals; - } else { - $messages[Translator::PLURAL_PREFIX . $key]['_context'][''] = $plurals; - } - } - } -} diff --git a/vendor/cakephp/cakephp/src/I18n/PluralRules.php b/vendor/cakephp/cakephp/src/I18n/PluralRules.php deleted file mode 100644 index 8a420ce..0000000 --- a/vendor/cakephp/cakephp/src/I18n/PluralRules.php +++ /dev/null @@ -1,200 +0,0 @@ - plurals group used to determine - * which plural rules apply to the language - * - * @var array - */ - protected static $_rulesMap = [ - 'af' => 1, - 'am' => 2, - 'ar' => 13, - 'az' => 1, - 'be' => 3, - 'bg' => 1, - 'bh' => 2, - 'bn' => 1, - 'bo' => 0, - 'bs' => 3, - 'ca' => 1, - 'cs' => 4, - 'cy' => 14, - 'da' => 1, - 'de' => 1, - 'dz' => 0, - 'el' => 1, - 'en' => 1, - 'eo' => 1, - 'es' => 1, - 'et' => 1, - 'eu' => 1, - 'fa' => 1, - 'fi' => 1, - 'fil' => 2, - 'fo' => 1, - 'fr' => 2, - 'fur' => 1, - 'fy' => 1, - 'ga' => 5, - 'gl' => 1, - 'gu' => 1, - 'gun' => 2, - 'ha' => 1, - 'he' => 1, - 'hi' => 2, - 'hr' => 3, - 'hu' => 1, - 'id' => 0, - 'is' => 15, - 'it' => 1, - 'ja' => 0, - 'jv' => 0, - 'ka' => 0, - 'km' => 0, - 'kn' => 0, - 'ko' => 0, - 'ku' => 1, - 'lb' => 1, - 'ln' => 2, - 'lt' => 6, - 'lv' => 10, - 'mg' => 2, - 'mk' => 8, - 'ml' => 1, - 'mn' => 1, - 'mr' => 1, - 'ms' => 0, - 'mt' => 9, - 'nah' => 1, - 'nb' => 1, - 'ne' => 1, - 'nl' => 1, - 'nn' => 1, - 'no' => 1, - 'nso' => 2, - 'om' => 1, - 'or' => 1, - 'pa' => 1, - 'pap' => 1, - 'pl' => 11, - 'ps' => 1, - 'pt_pt' => 2, - 'pt' => 1, - 'ro' => 12, - 'ru' => 3, - 'sk' => 4, - 'sl' => 7, - 'so' => 1, - 'sq' => 1, - 'sr' => 3, - 'sv' => 1, - 'sw' => 1, - 'ta' => 1, - 'te' => 1, - 'th' => 0, - 'ti' => 2, - 'tk' => 1, - 'tr' => 0, - 'uk' => 3, - 'ur' => 1, - 'vi' => 0, - 'wa' => 2, - 'zh' => 0, - 'zu' => 1, - ]; - - /** - * Returns the plural form number for the passed locale corresponding - * to the countable provided in $n. - * - * @param string $locale The locale to get the rule calculated for. - * @param int|float $n The number to apply the rules to. - * @return int The plural rule number that should be used. - * @link http://localization-guide.readthedocs.org/en/latest/l10n/pluralforms.html - * @link https://developer.mozilla.org/en-US/docs/Mozilla/Localization/Localization_and_Plurals#List_of_Plural_Rules - */ - public static function calculate($locale, $n) - { - $locale = strtolower($locale); - - if (!isset(static::$_rulesMap[$locale])) { - $locale = explode('_', $locale)[0]; - } - - if (!isset(static::$_rulesMap[$locale])) { - return 0; - } - - switch (static::$_rulesMap[$locale]) { - case 0: - return 0; - case 1: - return $n == 1 ? 0 : 1; - case 2: - return $n > 1 ? 1 : 0; - case 3: - return $n % 10 == 1 && $n % 100 != 11 ? 0 : - (($n % 10 >= 2 && $n % 10 <= 4) && ($n % 100 < 10 || $n % 100 >= 20) ? 1 : 2); - case 4: - return $n == 1 ? 0 : - ($n >= 2 && $n <= 4 ? 1 : 2); - case 5: - return $n == 1 ? 0 : - ($n == 2 ? 1 : ($n < 7 ? 2 : ($n < 11 ? 3 : 4))); - case 6: - return $n % 10 == 1 && $n % 100 != 11 ? 0 : - ($n % 10 >= 2 && ($n % 100 < 10 || $n % 100 >= 20) ? 1 : 2); - case 7: - return $n % 100 == 1 ? 1 : - ($n % 100 == 2 ? 2 : ($n % 100 == 3 || $n % 100 == 4 ? 3 : 0)); - case 8: - return $n % 10 == 1 ? 0 : ($n % 10 == 2 ? 1 : 2); - case 9: - return $n == 1 ? 0 : - ($n == 0 || ($n % 100 > 0 && $n % 100 <= 10) ? 1 : - ($n % 100 > 10 && $n % 100 < 20 ? 2 : 3)); - case 10: - return $n % 10 == 1 && $n % 100 != 11 ? 0 : ($n != 0 ? 1 : 2); - case 11: - return $n == 1 ? 0 : - ($n % 10 >= 2 && $n % 10 <= 4 && ($n % 100 < 10 || $n % 100 >= 20) ? 1 : 2); - case 12: - return $n == 1 ? 0 : - ($n == 0 || $n % 100 > 0 && $n % 100 < 20 ? 1 : 2); - case 13: - return $n == 0 ? 0 : - ($n == 1 ? 1 : - ($n == 2 ? 2 : - ($n % 100 >= 3 && $n % 100 <= 10 ? 3 : - ($n % 100 >= 11 ? 4 : 5)))); - case 14: - return $n == 1 ? 0 : - ($n == 2 ? 1 : - ($n != 8 && $n != 11 ? 2 : 3)); - case 15: - return ($n % 10 != 1 || $n % 100 == 11) ? 1 : 0; - } - } -} diff --git a/vendor/cakephp/cakephp/src/I18n/README.md b/vendor/cakephp/cakephp/src/I18n/README.md deleted file mode 100644 index 4c96116..0000000 --- a/vendor/cakephp/cakephp/src/I18n/README.md +++ /dev/null @@ -1,102 +0,0 @@ -[![Total Downloads](https://img.shields.io/packagist/dt/cakephp/i18n.svg?style=flat-square)](https://packagist.org/packages/cakephp/i18n) -[![License](https://img.shields.io/badge/license-MIT-blue.svg?style=flat-square)](LICENSE.txt) - -# CakePHP Internationalization Library - -The I18n library provides a `I18n` service locator that can be used for setting -the current locale, building translation bundles and translating messages. - -Additionally, it provides the `Time` and `Number` classes which can be used to -output dates, currencies and any numbers in the right format for the specified locale. - -## Usage - -Internally, the `I18n` class uses [Aura.Intl](https://github.com/auraphp/Aura.Intl). -Getting familiar with it will help you understand how to build and manipulate translation bundles, -should you wish to create them manually instead of using the conventions this library uses. - -### Setting the Current Locale - -```php -use Cake\I18n\I18n; - -I18n::setLocale('en_US'); -``` - -### Setting path to folder containing po files. - -```php -use Cake\Core\Configure; - -Configure::write('App.paths.locales', ['/path/with/trailing/slash/']); - -Please refer to the [CakePHP Manual](https://book.cakephp.org/3.0/en/core-libraries/internationalization-and-localization.html#language-files) for details -about expected folder structure and file naming. - -### Translating a Message - -```php -echo __( - 'Hi {0,string}, your balance on the {1,date} is {2,number,currency}', - ['Charles', '2014-01-13 11:12:00', 1354.37] -); - -// Returns -Hi Charles, your balance on the Jan 13, 2014, 11:12 AM is $ 1,354.37 -``` - -### Creating Your Own Translators - -```php -use Cake\I18n\I18n; -use Aura\Intl\Package; - -I18n::translator('animals', 'fr_FR', function () { - $package = new Package( - 'default', // The formatting strategy (ICU) - 'default', // The fallback domain - ); - $package->setMessages([ - 'Dog' => 'Chien', - 'Cat' => 'Chat', - 'Bird' => 'Oiseau' - ... - ]); - - return $package; -}); - -I18n::getLocale('fr_FR'); -__d('animals', 'Dog'); // Returns "Chien" -``` - -### Formatting Time - -```php -$time = Time::now(); -echo $time; // shows '4/20/14, 10:10 PM' for the en-US locale -``` - -### Formatting Numbers - -```php -echo Number::format(100100100); -``` - -```php -echo Number::currency(123456.7890, 'EUR'); -// outputs €123,456.79 -``` - -## Documentation - -Please make sure you check the [official I18n -documentation](https://book.cakephp.org/3.0/en/core-libraries/internationalization-and-localization.html). - -The [documentation for the Time -class](https://book.cakephp.org/3.0/en/core-libraries/time.html) contains -instructions on how to configure and output time strings for selected locales. - -The [documentation for the Number -class](https://book.cakephp.org/3.0/en/core-libraries/number.html) shows how to -use the `Number` class for displaying numbers in specific locales. diff --git a/vendor/cakephp/cakephp/src/I18n/RelativeTimeFormatter.php b/vendor/cakephp/cakephp/src/I18n/RelativeTimeFormatter.php deleted file mode 100644 index 8d2d7d5..0000000 --- a/vendor/cakephp/cakephp/src/I18n/RelativeTimeFormatter.php +++ /dev/null @@ -1,385 +0,0 @@ -now($date->getTimezone()); - } - $diffInterval = $date->diff($other); - - switch (true) { - case ($diffInterval->y > 0): - $count = $diffInterval->y; - $message = __dn('cake', '{0} year', '{0} years', $count, $count); - break; - case ($diffInterval->m > 0): - $count = $diffInterval->m; - $message = __dn('cake', '{0} month', '{0} months', $count, $count); - break; - case ($diffInterval->d > 0): - $count = $diffInterval->d; - if ($count >= ChronosInterface::DAYS_PER_WEEK) { - $count = (int)($count / ChronosInterface::DAYS_PER_WEEK); - $message = __dn('cake', '{0} week', '{0} weeks', $count, $count); - } else { - $message = __dn('cake', '{0} day', '{0} days', $count, $count); - } - break; - case ($diffInterval->h > 0): - $count = $diffInterval->h; - $message = __dn('cake', '{0} hour', '{0} hours', $count, $count); - break; - case ($diffInterval->i > 0): - $count = $diffInterval->i; - $message = __dn('cake', '{0} minute', '{0} minutes', $count, $count); - break; - default: - $count = $diffInterval->s; - $message = __dn('cake', '{0} second', '{0} seconds', $count, $count); - break; - } - if ($absolute) { - return $message; - } - $isFuture = $diffInterval->invert === 1; - if ($isNow) { - return $isFuture ? __d('cake', '{0} from now', $message) : __d('cake', '{0} ago', $message); - } - - return $isFuture ? __d('cake', '{0} after', $message) : __d('cake', '{0} before', $message); - } - - /** - * Format a into a relative timestring. - * - * @param \DateTimeInterface $time The time instance to format. - * @param array $options Array of options. - * @return string Relative time string. - * @see \Cake\I18n\Time::timeAgoInWords() - */ - public function timeAgoInWords(DateTimeInterface $time, array $options = []) - { - $options = $this->_options($options, FrozenTime::class); - if ($options['timezone'] && $time instanceof ChronosInterface) { - $time = $time->timezone($options['timezone']); - } - - $now = $options['from']->format('U'); - $inSeconds = $time->format('U'); - $backwards = ($inSeconds > $now); - - $futureTime = $now; - $pastTime = $inSeconds; - if ($backwards) { - $futureTime = $inSeconds; - $pastTime = $now; - } - $diff = $futureTime - $pastTime; - - if (!$diff) { - return __d('cake', 'just now', 'just now'); - } - - if ($diff > abs($now - (new FrozenTime($options['end']))->format('U'))) { - return sprintf($options['absoluteString'], $time->i18nFormat($options['format'])); - } - - $diffData = $this->_diffData($futureTime, $pastTime, $backwards, $options); - list($fNum, $fWord, $years, $months, $weeks, $days, $hours, $minutes, $seconds) = array_values($diffData); - - $relativeDate = []; - if ($fNum >= 1 && $years > 0) { - $relativeDate[] = __dn('cake', '{0} year', '{0} years', $years, $years); - } - if ($fNum >= 2 && $months > 0) { - $relativeDate[] = __dn('cake', '{0} month', '{0} months', $months, $months); - } - if ($fNum >= 3 && $weeks > 0) { - $relativeDate[] = __dn('cake', '{0} week', '{0} weeks', $weeks, $weeks); - } - if ($fNum >= 4 && $days > 0) { - $relativeDate[] = __dn('cake', '{0} day', '{0} days', $days, $days); - } - if ($fNum >= 5 && $hours > 0) { - $relativeDate[] = __dn('cake', '{0} hour', '{0} hours', $hours, $hours); - } - if ($fNum >= 6 && $minutes > 0) { - $relativeDate[] = __dn('cake', '{0} minute', '{0} minutes', $minutes, $minutes); - } - if ($fNum >= 7 && $seconds > 0) { - $relativeDate[] = __dn('cake', '{0} second', '{0} seconds', $seconds, $seconds); - } - $relativeDate = implode(', ', $relativeDate); - - // When time has passed - if (!$backwards) { - $aboutAgo = [ - 'second' => __d('cake', 'about a second ago'), - 'minute' => __d('cake', 'about a minute ago'), - 'hour' => __d('cake', 'about an hour ago'), - 'day' => __d('cake', 'about a day ago'), - 'week' => __d('cake', 'about a week ago'), - 'month' => __d('cake', 'about a month ago'), - 'year' => __d('cake', 'about a year ago') - ]; - - return $relativeDate ? sprintf($options['relativeString'], $relativeDate) : $aboutAgo[$fWord]; - } - - // When time is to come - if ($relativeDate) { - return $relativeDate; - } - $aboutIn = [ - 'second' => __d('cake', 'in about a second'), - 'minute' => __d('cake', 'in about a minute'), - 'hour' => __d('cake', 'in about an hour'), - 'day' => __d('cake', 'in about a day'), - 'week' => __d('cake', 'in about a week'), - 'month' => __d('cake', 'in about a month'), - 'year' => __d('cake', 'in about a year') - ]; - - return $aboutIn[$fWord]; - } - - /** - * Calculate the data needed to format a relative difference string. - * - * @param \DateTime $futureTime The time from the future. - * @param \DateTime $pastTime The time from the past. - * @param bool $backwards Whether or not the difference was backwards. - * @param array $options An array of options. - * @return array An array of values. - */ - protected function _diffData($futureTime, $pastTime, $backwards, $options) - { - $diff = $futureTime - $pastTime; - - // If more than a week, then take into account the length of months - if ($diff >= 604800) { - list($future['H'], $future['i'], $future['s'], $future['d'], $future['m'], $future['Y']) = explode('/', date('H/i/s/d/m/Y', $futureTime)); - - list($past['H'], $past['i'], $past['s'], $past['d'], $past['m'], $past['Y']) = explode('/', date('H/i/s/d/m/Y', $pastTime)); - $weeks = $days = $hours = $minutes = $seconds = 0; - - $years = $future['Y'] - $past['Y']; - $months = $future['m'] + ((12 * $years) - $past['m']); - - if ($months >= 12) { - $years = floor($months / 12); - $months -= ($years * 12); - } - if ($future['m'] < $past['m'] && $future['Y'] - $past['Y'] === 1) { - $years--; - } - - if ($future['d'] >= $past['d']) { - $days = $future['d'] - $past['d']; - } else { - $daysInPastMonth = date('t', $pastTime); - $daysInFutureMonth = date('t', mktime(0, 0, 0, $future['m'] - 1, 1, $future['Y'])); - - if (!$backwards) { - $days = ($daysInPastMonth - $past['d']) + $future['d']; - } else { - $days = ($daysInFutureMonth - $past['d']) + $future['d']; - } - - if ($future['m'] != $past['m']) { - $months--; - } - } - - if (!$months && $years >= 1 && $diff < ($years * 31536000)) { - $months = 11; - $years--; - } - - if ($months >= 12) { - $years++; - $months -= 12; - } - - if ($days >= 7) { - $weeks = floor($days / 7); - $days -= ($weeks * 7); - } - } else { - $years = $months = $weeks = 0; - $days = floor($diff / 86400); - - $diff -= ($days * 86400); - - $hours = floor($diff / 3600); - $diff -= ($hours * 3600); - - $minutes = floor($diff / 60); - $diff -= ($minutes * 60); - $seconds = $diff; - } - - $fWord = $options['accuracy']['second']; - if ($years > 0) { - $fWord = $options['accuracy']['year']; - } elseif (abs($months) > 0) { - $fWord = $options['accuracy']['month']; - } elseif (abs($weeks) > 0) { - $fWord = $options['accuracy']['week']; - } elseif (abs($days) > 0) { - $fWord = $options['accuracy']['day']; - } elseif (abs($hours) > 0) { - $fWord = $options['accuracy']['hour']; - } elseif (abs($minutes) > 0) { - $fWord = $options['accuracy']['minute']; - } - - $fNum = str_replace(['year', 'month', 'week', 'day', 'hour', 'minute', 'second'], [1, 2, 3, 4, 5, 6, 7], $fWord); - - return [$fNum, $fWord, $years, $months, $weeks, $days, $hours, $minutes, $seconds]; - } - - /** - * Format a into a relative date string. - * - * @param \DateTimeInterface $date The date to format. - * @param array $options Array of options. - * @return string Relative date string. - * @see \Cake\I18n\Date::timeAgoInWords() - */ - public function dateAgoInWords(DateTimeInterface $date, array $options = []) - { - $options = $this->_options($options, FrozenDate::class); - if ($options['timezone'] && $date instanceof ChronosInterface) { - $date = $date->timezone($options['timezone']); - } - - $now = $options['from']->format('U'); - $inSeconds = $date->format('U'); - $backwards = ($inSeconds > $now); - - $futureTime = $now; - $pastTime = $inSeconds; - if ($backwards) { - $futureTime = $inSeconds; - $pastTime = $now; - } - $diff = $futureTime - $pastTime; - - if (!$diff) { - return __d('cake', 'today'); - } - - if ($diff > abs($now - (new FrozenDate($options['end']))->format('U'))) { - return sprintf($options['absoluteString'], $date->i18nFormat($options['format'])); - } - - $diffData = $this->_diffData($futureTime, $pastTime, $backwards, $options); - list($fNum, $fWord, $years, $months, $weeks, $days) = array_values($diffData); - - $relativeDate = []; - if ($fNum >= 1 && $years > 0) { - $relativeDate[] = __dn('cake', '{0} year', '{0} years', $years, $years); - } - if ($fNum >= 2 && $months > 0) { - $relativeDate[] = __dn('cake', '{0} month', '{0} months', $months, $months); - } - if ($fNum >= 3 && $weeks > 0) { - $relativeDate[] = __dn('cake', '{0} week', '{0} weeks', $weeks, $weeks); - } - if ($fNum >= 4 && $days > 0) { - $relativeDate[] = __dn('cake', '{0} day', '{0} days', $days, $days); - } - $relativeDate = implode(', ', $relativeDate); - - // When time has passed - if (!$backwards) { - $aboutAgo = [ - 'day' => __d('cake', 'about a day ago'), - 'week' => __d('cake', 'about a week ago'), - 'month' => __d('cake', 'about a month ago'), - 'year' => __d('cake', 'about a year ago') - ]; - - return $relativeDate ? sprintf($options['relativeString'], $relativeDate) : $aboutAgo[$fWord]; - } - - // When time is to come - if ($relativeDate) { - return $relativeDate; - } - $aboutIn = [ - 'day' => __d('cake', 'in about a day'), - 'week' => __d('cake', 'in about a week'), - 'month' => __d('cake', 'in about a month'), - 'year' => __d('cake', 'in about a year') - ]; - - return $aboutIn[$fWord]; - } - - /** - * Build the options for relative date formatting. - * - * @param array $options The options provided by the user. - * @param string $class The class name to use for defaults. - * @return array Options with defaults applied. - */ - protected function _options($options, $class) - { - $options += [ - 'from' => $class::now(), - 'timezone' => null, - 'format' => $class::$wordFormat, - 'accuracy' => $class::$wordAccuracy, - 'end' => $class::$wordEnd, - 'relativeString' => __d('cake', '%s ago'), - 'absoluteString' => __d('cake', 'on %s'), - ]; - if (is_string($options['accuracy'])) { - $accuracy = $options['accuracy']; - $options['accuracy'] = []; - foreach ($class::$wordAccuracy as $key => $level) { - $options['accuracy'][$key] = $accuracy; - } - } else { - $options['accuracy'] += $class::$wordAccuracy; - } - - return $options; - } -} diff --git a/vendor/cakephp/cakephp/src/I18n/Time.php b/vendor/cakephp/cakephp/src/I18n/Time.php deleted file mode 100644 index 0d05665..0000000 --- a/vendor/cakephp/cakephp/src/I18n/Time.php +++ /dev/null @@ -1,371 +0,0 @@ - 'day', - 'month' => 'day', - 'week' => 'day', - 'day' => 'hour', - 'hour' => 'minute', - 'minute' => 'minute', - 'second' => 'second', - ]; - - /** - * The end of relative time telling - * - * @var string - * @see \Cake\I18n\Time::timeAgoInWords() - */ - public static $wordEnd = '+1 month'; - - /** - * serialise the value as a Unix Timestamp - * - * @var string - */ - const UNIX_TIMESTAMP_FORMAT = 'unixTimestampFormat'; - - /** - * {@inheritDoc} - */ - public function __construct($time = null, $tz = null) - { - if ($time instanceof DateTimeInterface) { - $tz = $time->getTimezone(); - $time = $time->format('Y-m-d H:i:s'); - } - - if (is_numeric($time)) { - $time = '@' . $time; - } - parent::__construct($time, $tz); - } - - /** - * Returns a nicely formatted date string for this object. - * - * The format to be used is stored in the static property `Time::niceFormat`. - * - * @param string|\DateTimeZone|null $timezone Timezone string or DateTimeZone object - * in which the date will be displayed. The timezone stored for this object will not - * be changed. - * @param string|null $locale The locale name in which the date should be displayed (e.g. pt-BR) - * @return string Formatted date string - */ - public function nice($timezone = null, $locale = null) - { - return $this->i18nFormat(static::$niceFormat, $timezone, $locale); - } - - /** - * Returns true if this object represents a date within the current week - * - * @return bool - */ - public function isThisWeek() - { - return static::now($this->getTimezone())->format('W o') == $this->format('W o'); - } - - /** - * Returns true if this object represents a date within the current month - * - * @return bool - */ - public function isThisMonth() - { - return static::now($this->getTimezone())->format('m Y') == $this->format('m Y'); - } - - /** - * Returns true if this object represents a date within the current year - * - * @return bool - */ - public function isThisYear() - { - return static::now($this->getTimezone())->format('Y') == $this->format('Y'); - } - - /** - * Returns the quarter - * - * @param bool $range Range. - * @return int|array 1, 2, 3, or 4 quarter of year, or array if $range true - */ - public function toQuarter($range = false) - { - $quarter = ceil($this->format('m') / 3); - if ($range === false) { - return $quarter; - } - - $year = $this->format('Y'); - switch ($quarter) { - case 1: - return [$year . '-01-01', $year . '-03-31']; - case 2: - return [$year . '-04-01', $year . '-06-30']; - case 3: - return [$year . '-07-01', $year . '-09-30']; - case 4: - return [$year . '-10-01', $year . '-12-31']; - } - } - - /** - * Returns a UNIX timestamp. - * - * @return string UNIX timestamp - */ - public function toUnixString() - { - return $this->format('U'); - } - - /** - * Returns either a relative or a formatted absolute date depending - * on the difference between the current time and this object. - * - * ### Options: - * - * - `from` => another Time object representing the "now" time - * - `format` => a fall back format if the relative time is longer than the duration specified by end - * - `accuracy` => Specifies how accurate the date should be described (array) - * - year => The format if years > 0 (default "day") - * - month => The format if months > 0 (default "day") - * - week => The format if weeks > 0 (default "day") - * - day => The format if weeks > 0 (default "hour") - * - hour => The format if hours > 0 (default "minute") - * - minute => The format if minutes > 0 (default "minute") - * - second => The format if seconds > 0 (default "second") - * - `end` => The end of relative time telling - * - `relativeString` => The `printf` compatible string when outputting relative time - * - `absoluteString` => The `printf` compatible string when outputting absolute time - * - `timezone` => The user timezone the timestamp should be formatted in. - * - * Relative dates look something like this: - * - * - 3 weeks, 4 days ago - * - 15 seconds ago - * - * Default date formatting is d/M/YY e.g: on 18/2/09. Formatting is done internally using - * `i18nFormat`, see the method for the valid formatting strings - * - * The returned string includes 'ago' or 'on' and assumes you'll properly add a word - * like 'Posted ' before the function output. - * - * NOTE: If the difference is one week or more, the lowest level of accuracy is day - * - * @param array $options Array of options. - * @return string Relative time string. - */ - public function timeAgoInWords(array $options = []) - { - return static::diffFormatter()->timeAgoInWords($this, $options); - } - - /** - * Get list of timezone identifiers - * - * @param int|string|null $filter A regex to filter identifier - * Or one of DateTimeZone class constants - * @param string|null $country A two-letter ISO 3166-1 compatible country code. - * This option is only used when $filter is set to DateTimeZone::PER_COUNTRY - * @param bool|array $options If true (default value) groups the identifiers list by primary region. - * Otherwise, an array containing `group`, `abbr`, `before`, and `after` - * keys. Setting `group` and `abbr` to true will group results and append - * timezone abbreviation in the display value. Set `before` and `after` - * to customize the abbreviation wrapper. - * @return array List of timezone identifiers - * @since 2.2 - */ - public static function listTimezones($filter = null, $country = null, $options = []) - { - if (is_bool($options)) { - $options = [ - 'group' => $options, - ]; - } - $defaults = [ - 'group' => true, - 'abbr' => false, - 'before' => ' - ', - 'after' => null, - ]; - $options += $defaults; - $group = $options['group']; - - $regex = null; - if (is_string($filter)) { - $regex = $filter; - $filter = null; - } - if ($filter === null) { - $filter = DateTimeZone::ALL; - } - $identifiers = DateTimeZone::listIdentifiers($filter, $country); - - if ($regex) { - foreach ($identifiers as $key => $tz) { - if (!preg_match($regex, $tz)) { - unset($identifiers[$key]); - } - } - } - - if ($group) { - $groupedIdentifiers = []; - $now = time(); - $before = $options['before']; - $after = $options['after']; - foreach ($identifiers as $key => $tz) { - $abbr = null; - if ($options['abbr']) { - $dateTimeZone = new DateTimeZone($tz); - $trans = $dateTimeZone->getTransitions($now, $now); - $abbr = isset($trans[0]['abbr']) ? - $before . $trans[0]['abbr'] . $after : - null; - } - $item = explode('/', $tz, 2); - if (isset($item[1])) { - $groupedIdentifiers[$item[0]][$tz] = $item[1] . $abbr; - } else { - $groupedIdentifiers[$item[0]] = [$tz => $item[0] . $abbr]; - } - } - - return $groupedIdentifiers; - } - - return array_combine($identifiers, $identifiers); - } - - /** - * Returns true this instance will happen within the specified interval - * - * This overridden method provides backwards compatible behavior for integers, - * or strings with trailing spaces. This behavior is *deprecated* and will be - * removed in future versions of CakePHP. - * - * @param string|int $timeInterval the numeric value with space then time type. - * Example of valid types: 6 hours, 2 days, 1 minute. - * @return bool - */ - public function wasWithinLast($timeInterval) - { - $tmp = trim($timeInterval); - if (is_numeric($tmp)) { - deprecationWarning( - 'Passing int/numeric string into Time::wasWithinLast() is deprecated. ' . - 'Pass strings including interval eg. "6 days"' - ); - $timeInterval = $tmp . ' days'; - } - - return parent::wasWithinLast($timeInterval); - } - - /** - * Returns true this instance happened within the specified interval - * - * This overridden method provides backwards compatible behavior for integers, - * or strings with trailing spaces. This behavior is *deprecated* and will be - * removed in future versions of CakePHP. - * - * @param string|int $timeInterval the numeric value with space then time type. - * Example of valid types: 6 hours, 2 days, 1 minute. - * @return bool - */ - public function isWithinNext($timeInterval) - { - $tmp = trim($timeInterval); - if (is_numeric($tmp)) { - deprecationWarning( - 'Passing int/numeric string into Time::isWithinNext() is deprecated. ' . - 'Pass strings including interval eg. "6 days"' - ); - $timeInterval = $tmp . ' days'; - } - - return parent::isWithinNext($timeInterval); - } -} diff --git a/vendor/cakephp/cakephp/src/I18n/TranslatorRegistry.php b/vendor/cakephp/cakephp/src/I18n/TranslatorRegistry.php deleted file mode 100644 index df06dc6..0000000 --- a/vendor/cakephp/cakephp/src/I18n/TranslatorRegistry.php +++ /dev/null @@ -1,300 +0,0 @@ -registerLoader($this->_fallbackLoader, function ($name, $locale) { - $chain = new ChainMessagesLoader([ - new MessagesFileLoader($name, $locale, 'mo'), - new MessagesFileLoader($name, $locale, 'po') - ]); - - // \Aura\Intl\Package by default uses formatter configured with key "basic". - // and we want to make sure the cake domain always uses the default formatter - $formatter = $name === 'cake' ? 'default' : $this->_defaultFormatter; - $chain = function () use ($formatter, $chain) { - $package = $chain(); - $package->setFormatter($formatter); - - return $package; - }; - - return $chain; - }); - } - - /** - * Sets the CacheEngine instance used to remember translators across - * requests. - * - * @param \Cake\Cache\CacheEngine $cacher The cacher instance. - * @return void - */ - public function setCacher(CacheEngine $cacher) - { - $this->_cacher = $cacher; - } - - /** - * Gets a translator from the registry by package for a locale. - * - * @param string $name The translator package to retrieve. - * @param string|null $locale The locale to use; if empty, uses the default - * locale. - * @return \Aura\Intl\TranslatorInterface|null A translator object. - * @throws \Aura\Intl\Exception If no translator with that name could be found - * for the given locale. - */ - public function get($name, $locale = null) - { - if (!$name) { - return null; - } - - if ($locale === null) { - $locale = $this->getLocale(); - } - - if (isset($this->registry[$name][$locale])) { - return $this->registry[$name][$locale]; - } - - if (!$this->_cacher) { - return $this->registry[$name][$locale] = $this->_getTranslator($name, $locale); - } - - $key = "translations.$name.$locale"; - $translator = $this->_cacher->read($key); - if (!$translator || !$translator->getPackage()) { - $translator = $this->_getTranslator($name, $locale); - $this->_cacher->write($key, $translator); - } - - return $this->registry[$name][$locale] = $translator; - } - - /** - * Gets a translator from the registry by package for a locale. - * - * @param string $name The translator package to retrieve. - * @param string|null $locale The locale to use; if empty, uses the default - * locale. - * @return \Aura\Intl\TranslatorInterface A translator object. - */ - protected function _getTranslator($name, $locale) - { - try { - return parent::get($name, $locale); - } catch (Exception $e) { - } - - if (!isset($this->_loaders[$name])) { - $this->registerLoader($name, $this->_partialLoader()); - } - - return $this->_getFromLoader($name, $locale); - } - - /** - * Registers a loader function for a package name that will be used as a fallback - * in case no package with that name can be found. - * - * Loader callbacks will get as first argument the package name and the locale as - * the second argument. - * - * @param string $name The name of the translator package to register a loader for - * @param callable $loader A callable object that should return a Package - * @return void - */ - public function registerLoader($name, callable $loader) - { - $this->_loaders[$name] = $loader; - } - - /** - * Sets the name of the default messages formatter to use for future - * translator instances. - * - * If called with no arguments, it will return the currently configured value. - * - * @param string|null $name The name of the formatter to use. - * @return string The name of the formatter. - */ - public function defaultFormatter($name = null) - { - if ($name === null) { - return $this->_defaultFormatter; - } - - return $this->_defaultFormatter = $name; - } - - /** - * Set if the default domain fallback is used. - * - * @param bool $enable flag to enable or disable fallback - * @return void - */ - public function useFallback($enable = true) - { - $this->_useFallback = $enable; - } - - /** - * Returns a new translator instance for the given name and locale - * based of conventions. - * - * @param string $name The translation package name. - * @param string $locale The locale to create the translator for. - * @return \Aura\Intl\Translator - */ - protected function _fallbackLoader($name, $locale) - { - return $this->_loaders[$this->_fallbackLoader]($name, $locale); - } - - /** - * Returns a function that can be used as a loader for the registerLoaderMethod - * - * @return callable - */ - protected function _partialLoader() - { - return function ($name, $locale) { - return $this->_fallbackLoader($name, $locale); - }; - } - - /** - * Registers a new package by passing the register loaded function for the - * package name. - * - * @param string $name The name of the translator package - * @param string $locale The locale that should be built the package for - * @return \Aura\Intl\TranslatorInterface A translator object. - */ - protected function _getFromLoader($name, $locale) - { - $loader = $this->_loaders[$name]($name, $locale); - $package = $loader; - - if (!is_callable($loader)) { - $loader = function () use ($package) { - return $package; - }; - } - - $loader = $this->setLoaderFallback($name, $loader); - - $this->packages->set($name, $locale, $loader); - - return parent::get($name, $locale); - } - - /** - * Set domain fallback for loader. - * - * @param string $name The name of the loader domain - * @param callable $loader invokable loader - * @return callable loader - */ - public function setLoaderFallback($name, callable $loader) - { - $fallbackDomain = 'default'; - if (!$this->_useFallback || $name === $fallbackDomain) { - return $loader; - } - $loader = function () use ($loader, $fallbackDomain) { - /* @var \Aura\Intl\Package $package */ - $package = $loader(); - if (!$package->getFallback()) { - $package->setFallback($fallbackDomain); - } - - return $package; - }; - - return $loader; - } -} diff --git a/vendor/cakephp/cakephp/src/I18n/composer.json b/vendor/cakephp/cakephp/src/I18n/composer.json deleted file mode 100644 index 7ffc86f..0000000 --- a/vendor/cakephp/cakephp/src/I18n/composer.json +++ /dev/null @@ -1,48 +0,0 @@ -{ - "name": "cakephp/i18n", - "description": "CakePHP Internationalization library with support for messages translation and dates and numbers localization", - "type": "library", - "keywords": [ - "cakephp", - "i18n", - "internationalisation", - "internationalization", - "localisation", - "localization", - "translation", - "date", - "number" - ], - "homepage": "https://cakephp.org", - "license": "MIT", - "authors": [ - { - "name": "CakePHP Community", - "homepage": "https://github.com/cakephp/i18n/graphs/contributors" - } - ], - "support": { - "issues": "https://github.com/cakephp/cakephp/issues", - "forum": "https://stackoverflow.com/tags/cakephp", - "irc": "irc://irc.freenode.org/cakephp", - "source": "https://github.com/cakephp/i18n" - }, - "require": { - "php": ">=5.6.0", - "ext-intl": "*", - "cakephp/core": "^3.6.0", - "cakephp/chronos": "^1.0.0", - "aura/intl": "^3.0.0" - }, - "suggest": { - "cakephp/cache": "Require this if you want automatic caching of translators" - }, - "autoload": { - "psr-4": { - "Cake\\I18n\\": "." - }, - "files": [ - "functions.php" - ] - } -} diff --git a/vendor/cakephp/cakephp/src/I18n/functions.php b/vendor/cakephp/cakephp/src/I18n/functions.php deleted file mode 100644 index 65f46ab..0000000 --- a/vendor/cakephp/cakephp/src/I18n/functions.php +++ /dev/null @@ -1,243 +0,0 @@ -translate($singular, $args); - } - -} - -if (!function_exists('__n')) { - /** - * Returns correct plural form of message identified by $singular and $plural for count $count. - * Some languages have more than one form for plural messages dependent on the count. - * - * @param string $singular Singular text to translate. - * @param string $plural Plural text. - * @param int $count Count. - * @param array ...$args Array with arguments or multiple arguments in function. - * @return string|null Plural form of translated string, or null if invalid. - * @link https://book.cakephp.org/3.0/en/core-libraries/global-constants-and-functions.html#__n - */ - function __n($singular, $plural, $count, ...$args) - { - if (!$singular) { - return null; - } - if (isset($args[0]) && is_array($args[0])) { - $args = $args[0]; - } - - return I18n::getTranslator()->translate( - $plural, - ['_count' => $count, '_singular' => $singular] + $args - ); - } - -} - -if (!function_exists('__d')) { - /** - * Allows you to override the current domain for a single message lookup. - * - * @param string $domain Domain. - * @param string $msg String to translate. - * @param array ...$args Array with arguments or multiple arguments in function. - * @return string|null Translated string. - * @link https://book.cakephp.org/3.0/en/core-libraries/global-constants-and-functions.html#__d - */ - function __d($domain, $msg, ...$args) - { - if (!$msg) { - return null; - } - if (isset($args[0]) && is_array($args[0])) { - $args = $args[0]; - } - - return I18n::getTranslator($domain)->translate($msg, $args); - } - -} - -if (!function_exists('__dn')) { - /** - * Allows you to override the current domain for a single plural message lookup. - * Returns correct plural form of message identified by $singular and $plural for count $count - * from domain $domain. - * - * @param string $domain Domain. - * @param string $singular Singular string to translate. - * @param string $plural Plural. - * @param int $count Count. - * @param array ...$args Array with arguments or multiple arguments in function. - * @return string|null Plural form of translated string. - * @link https://book.cakephp.org/3.0/en/core-libraries/global-constants-and-functions.html#__dn - */ - function __dn($domain, $singular, $plural, $count, ...$args) - { - if (!$singular) { - return null; - } - if (isset($args[0]) && is_array($args[0])) { - $args = $args[0]; - } - - return I18n::getTranslator($domain)->translate( - $plural, - ['_count' => $count, '_singular' => $singular] + $args - ); - } - -} - -if (!function_exists('__x')) { - /** - * Returns a translated string if one is found; Otherwise, the submitted message. - * The context is a unique identifier for the translations string that makes it unique - * within the same domain. - * - * @param string $context Context of the text. - * @param string $singular Text to translate. - * @param array ...$args Array with arguments or multiple arguments in function. - * @return string|null Translated string. - * @link https://book.cakephp.org/3.0/en/core-libraries/global-constants-and-functions.html#__x - */ - function __x($context, $singular, ...$args) - { - if (!$singular) { - return null; - } - if (isset($args[0]) && is_array($args[0])) { - $args = $args[0]; - } - - return I18n::getTranslator()->translate($singular, ['_context' => $context] + $args); - } - -} - -if (!function_exists('__xn')) { - /** - * Returns correct plural form of message identified by $singular and $plural for count $count. - * Some languages have more than one form for plural messages dependent on the count. - * The context is a unique identifier for the translations string that makes it unique - * within the same domain. - * - * @param string $context Context of the text. - * @param string $singular Singular text to translate. - * @param string $plural Plural text. - * @param int $count Count. - * @param array ...$args Array with arguments or multiple arguments in function. - * @return string|null Plural form of translated string. - * @link https://book.cakephp.org/3.0/en/core-libraries/global-constants-and-functions.html#__xn - */ - function __xn($context, $singular, $plural, $count, ...$args) - { - if (!$singular) { - return null; - } - if (isset($args[0]) && is_array($args[0])) { - $args = $args[0]; - } - - return I18n::getTranslator()->translate( - $plural, - ['_count' => $count, '_singular' => $singular, '_context' => $context] + $args - ); - } - -} - -if (!function_exists('__dx')) { - /** - * Allows you to override the current domain for a single message lookup. - * The context is a unique identifier for the translations string that makes it unique - * within the same domain. - * - * @param string $domain Domain. - * @param string $context Context of the text. - * @param string $msg String to translate. - * @param array ...$args Array with arguments or multiple arguments in function. - * @return string|null Translated string. - * @link https://book.cakephp.org/3.0/en/core-libraries/global-constants-and-functions.html#__dx - */ - function __dx($domain, $context, $msg, ...$args) - { - if (!$msg) { - return null; - } - if (isset($args[0]) && is_array($args[0])) { - $args = $args[0]; - } - - return I18n::getTranslator($domain)->translate( - $msg, - ['_context' => $context] + $args - ); - } - -} - -if (!function_exists('__dxn')) { - /** - * Returns correct plural form of message identified by $singular and $plural for count $count. - * Allows you to override the current domain for a single message lookup. - * The context is a unique identifier for the translations string that makes it unique - * within the same domain. - * - * @param string $domain Domain. - * @param string $context Context of the text. - * @param string $singular Singular text to translate. - * @param string $plural Plural text. - * @param int $count Count. - * @param array ...$args Array with arguments or multiple arguments in function. - * @return string|null Plural form of translated string. - * @link https://book.cakephp.org/3.0/en/core-libraries/global-constants-and-functions.html#__dxn - */ - function __dxn($domain, $context, $singular, $plural, $count, ...$args) - { - if (!$singular) { - return null; - } - if (isset($args[0]) && is_array($args[0])) { - $args = $args[0]; - } - - return I18n::getTranslator($domain)->translate( - $plural, - ['_count' => $count, '_singular' => $singular, '_context' => $context] + $args - ); - } - -} diff --git a/vendor/cakephp/cakephp/src/Log/Engine/BaseLog.php b/vendor/cakephp/cakephp/src/Log/Engine/BaseLog.php deleted file mode 100644 index c35e533..0000000 --- a/vendor/cakephp/cakephp/src/Log/Engine/BaseLog.php +++ /dev/null @@ -1,115 +0,0 @@ - [], - 'scopes' => [] - ]; - - /** - * __construct method - * - * @param array $config Configuration array - */ - public function __construct(array $config = []) - { - $this->setConfig($config); - - if (!is_array($this->_config['scopes']) && $this->_config['scopes'] !== false) { - $this->_config['scopes'] = (array)$this->_config['scopes']; - } - - if (!is_array($this->_config['levels'])) { - $this->_config['levels'] = (array)$this->_config['levels']; - } - - if (!empty($this->_config['types']) && empty($this->_config['levels'])) { - $this->_config['levels'] = (array)$this->_config['types']; - } - } - - /** - * Get the levels this logger is interested in. - * - * @return array - */ - public function levels() - { - return $this->_config['levels']; - } - - /** - * Get the scopes this logger is interested in. - * - * @return array - */ - public function scopes() - { - return $this->_config['scopes']; - } - - /** - * Converts to string the provided data so it can be logged. The context - * can optionally be used by log engines to interpolate variables - * or add additional info to the logged message. - * - * @param mixed $data The data to be converted to string and logged. - * @param array $context Additional logging information for the message. - * @return string - */ - protected function _format($data, array $context = []) - { - if (is_string($data)) { - return $data; - } - - $isObject = is_object($data); - - if ($isObject && $data instanceof EntityInterface) { - return json_encode($data, JSON_UNESCAPED_UNICODE | JSON_PRETTY_PRINT); - } - - if ($isObject && method_exists($data, '__toString')) { - return (string)$data; - } - - if ($isObject && $data instanceof JsonSerializable) { - return json_encode($data, JSON_UNESCAPED_UNICODE); - } - - return print_r($data, true); - } -} diff --git a/vendor/cakephp/cakephp/src/Log/Engine/ConsoleLog.php b/vendor/cakephp/cakephp/src/Log/Engine/ConsoleLog.php deleted file mode 100644 index db8e72b..0000000 --- a/vendor/cakephp/cakephp/src/Log/Engine/ConsoleLog.php +++ /dev/null @@ -1,96 +0,0 @@ - 'php://stderr', - 'levels' => null, - 'scopes' => [], - 'outputAs' => 'see constructor' - ]; - - /** - * Output stream - * - * @var \Cake\Console\ConsoleOutput - */ - protected $_output; - - /** - * Constructs a new Console Logger. - * - * Config - * - * - `levels` string or array, levels the engine is interested in - * - `scopes` string or array, scopes the engine is interested in - * - `stream` the path to save logs on. - * - `outputAs` integer or ConsoleOutput::[RAW|PLAIN|COLOR] - * - * @param array $config Options for the FileLog, see above. - * @throws \InvalidArgumentException - */ - public function __construct(array $config = []) - { - if ((DIRECTORY_SEPARATOR === '\\' && !(bool)env('ANSICON') && env('ConEmuANSI') !== 'ON') || - (function_exists('posix_isatty') && !posix_isatty($this->_output)) - ) { - $this->_defaultConfig['outputAs'] = ConsoleOutput::PLAIN; - } else { - $this->_defaultConfig['outputAs'] = ConsoleOutput::COLOR; - } - - parent::__construct($config); - - $config = $this->_config; - if ($config['stream'] instanceof ConsoleOutput) { - $this->_output = $config['stream']; - } elseif (is_string($config['stream'])) { - $this->_output = new ConsoleOutput($config['stream']); - } else { - throw new InvalidArgumentException('`stream` not a ConsoleOutput nor string'); - } - $this->_output->setOutputAs($config['outputAs']); - } - - /** - * Implements writing to console. - * - * @param string $level The severity level of log you are making. - * @param string $message The message you want to log. - * @param array $context Additional information about the logged message - * @return bool success of write. - */ - public function log($level, $message, array $context = []) - { - $message = $this->_format($message, $context); - $output = date('Y-m-d H:i:s') . ' ' . ucfirst($level) . ': ' . $message; - - return (bool)$this->_output->write(sprintf('<%s>%s', $level, $output, $level)); - } -} diff --git a/vendor/cakephp/cakephp/src/Log/Engine/FileLog.php b/vendor/cakephp/cakephp/src/Log/Engine/FileLog.php deleted file mode 100644 index 5e424be..0000000 --- a/vendor/cakephp/cakephp/src/Log/Engine/FileLog.php +++ /dev/null @@ -1,212 +0,0 @@ - null, - 'file' => null, - 'types' => null, - 'levels' => [], - 'scopes' => [], - 'rotate' => 10, - 'size' => 10485760, // 10MB - 'mask' => null, - ]; - - /** - * Path to save log files on. - * - * @var string|null - */ - protected $_path; - - /** - * The name of the file to save logs into. - * - * @var string|null - */ - protected $_file; - - /** - * Max file size, used for log file rotation. - * - * @var int|null - */ - protected $_size; - - /** - * Sets protected properties based on config provided - * - * @param array $config Configuration array - */ - public function __construct(array $config = []) - { - parent::__construct($config); - - if (!empty($this->_config['path'])) { - $this->_path = $this->_config['path']; - } - if ($this->_path !== null && - Configure::read('debug') && - !is_dir($this->_path) - ) { - mkdir($this->_path, 0775, true); - } - - if (!empty($this->_config['file'])) { - $this->_file = $this->_config['file']; - if (substr($this->_file, -4) !== '.log') { - $this->_file .= '.log'; - } - } - - if (!empty($this->_config['size'])) { - if (is_numeric($this->_config['size'])) { - $this->_size = (int)$this->_config['size']; - } else { - $this->_size = Text::parseFileSize($this->_config['size']); - } - } - } - - /** - * Implements writing to log files. - * - * @param string $level The severity level of the message being written. - * See Cake\Log\Log::$_levels for list of possible levels. - * @param string $message The message you want to log. - * @param array $context Additional information about the logged message - * @return bool success of write. - */ - public function log($level, $message, array $context = []) - { - $message = $this->_format($message, $context); - $output = date('Y-m-d H:i:s') . ' ' . ucfirst($level) . ': ' . $message . "\n"; - $filename = $this->_getFilename($level); - if ($this->_size) { - $this->_rotateFile($filename); - } - - $pathname = $this->_path . $filename; - $mask = $this->_config['mask']; - if (!$mask) { - return file_put_contents($pathname, $output, FILE_APPEND); - } - - $exists = file_exists($pathname); - $result = file_put_contents($pathname, $output, FILE_APPEND); - static $selfError = false; - - if (!$selfError && !$exists && !chmod($pathname, (int)$mask)) { - $selfError = true; - trigger_error(vsprintf( - 'Could not apply permission mask "%s" on log file "%s"', - [$mask, $pathname] - ), E_USER_WARNING); - $selfError = false; - } - - return $result; - } - - /** - * Get filename - * - * @param string $level The level of log. - * @return string File name - */ - protected function _getFilename($level) - { - $debugTypes = ['notice', 'info', 'debug']; - - if ($this->_file) { - $filename = $this->_file; - } elseif ($level === 'error' || $level === 'warning') { - $filename = 'error.log'; - } elseif (in_array($level, $debugTypes)) { - $filename = 'debug.log'; - } else { - $filename = $level . '.log'; - } - - return $filename; - } - - /** - * Rotate log file if size specified in config is reached. - * Also if `rotate` count is reached oldest file is removed. - * - * @param string $filename Log file name - * @return bool|null True if rotated successfully or false in case of error. - * Null if file doesn't need to be rotated. - */ - protected function _rotateFile($filename) - { - $filePath = $this->_path . $filename; - clearstatcache(true, $filePath); - - if (!file_exists($filePath) || - filesize($filePath) < $this->_size - ) { - return null; - } - - $rotate = $this->_config['rotate']; - if ($rotate === 0) { - $result = unlink($filePath); - } else { - $result = rename($filePath, $filePath . '.' . time()); - } - - $files = glob($filePath . '.*'); - if ($files) { - $filesToDelete = count($files) - $rotate; - while ($filesToDelete > 0) { - unlink(array_shift($files)); - $filesToDelete--; - } - } - - return $result; - } -} diff --git a/vendor/cakephp/cakephp/src/Log/Engine/SyslogLog.php b/vendor/cakephp/cakephp/src/Log/Engine/SyslogLog.php deleted file mode 100644 index 503c9ce..0000000 --- a/vendor/cakephp/cakephp/src/Log/Engine/SyslogLog.php +++ /dev/null @@ -1,150 +0,0 @@ - 'Syslog', - * 'levels' => ['emergency', 'alert', 'critical', 'error'], - * 'format' => "%s: My-App - %s", - * 'prefix' => 'Web Server 01' - * ]); - * ``` - * - * @var array - */ - protected $_defaultConfig = [ - 'levels' => [], - 'scopes' => [], - 'format' => '%s: %s', - 'flag' => LOG_ODELAY, - 'prefix' => '', - 'facility' => LOG_USER - ]; - - /** - * Used to map the string names back to their LOG_* constants - * - * @var int[] - */ - protected $_levelMap = [ - 'emergency' => LOG_EMERG, - 'alert' => LOG_ALERT, - 'critical' => LOG_CRIT, - 'error' => LOG_ERR, - 'warning' => LOG_WARNING, - 'notice' => LOG_NOTICE, - 'info' => LOG_INFO, - 'debug' => LOG_DEBUG - ]; - - /** - * Whether the logger connection is open or not - * - * @var bool - */ - protected $_open = false; - - /** - * Writes a message to syslog - * - * Map the $level back to a LOG_ constant value, split multi-line messages into multiple - * log messages, pass all messages through the format defined in the configuration - * - * @param string $level The severity level of log you are making. - * @param string $message The message you want to log. - * @param array $context Additional information about the logged message - * @return bool success of write. - */ - public function log($level, $message, array $context = []) - { - if (!$this->_open) { - $config = $this->_config; - $this->_open($config['prefix'], $config['flag'], $config['facility']); - $this->_open = true; - } - - $priority = LOG_DEBUG; - if (isset($this->_levelMap[$level])) { - $priority = $this->_levelMap[$level]; - } - - $messages = explode("\n", $this->_format($message, $context)); - foreach ($messages as $message) { - $message = sprintf($this->_config['format'], $level, $message); - $this->_write($priority, $message); - } - - return true; - } - - /** - * Extracts the call to openlog() in order to run unit tests on it. This function - * will initialize the connection to the system logger - * - * @param string $ident the prefix to add to all messages logged - * @param int $options the options flags to be used for logged messages - * @param int $facility the stream or facility to log to - * @return void - */ - protected function _open($ident, $options, $facility) - { - openlog($ident, $options, $facility); - } - - /** - * Extracts the call to syslog() in order to run unit tests on it. This function - * will perform the actual write in the system logger - * - * @param int $priority Message priority. - * @param string $message Message to log. - * @return bool - */ - protected function _write($priority, $message) - { - return syslog($priority, $message); - } - - /** - * Closes the logger connection - */ - public function __destruct() - { - closelog(); - } -} diff --git a/vendor/cakephp/cakephp/src/Log/LICENSE.txt b/vendor/cakephp/cakephp/src/Log/LICENSE.txt deleted file mode 100644 index 0c4b793..0000000 --- a/vendor/cakephp/cakephp/src/Log/LICENSE.txt +++ /dev/null @@ -1,22 +0,0 @@ -The MIT License (MIT) - -CakePHP(tm) : The Rapid Development PHP Framework (https://cakephp.org) -Copyright (c) 2005-2016, Cake Software Foundation, Inc. (https://cakefoundation.org) - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. diff --git a/vendor/cakephp/cakephp/src/Log/Log.php b/vendor/cakephp/cakephp/src/Log/Log.php deleted file mode 100644 index 894c2f0..0000000 --- a/vendor/cakephp/cakephp/src/Log/Log.php +++ /dev/null @@ -1,519 +0,0 @@ - 'FileLog']); - * ``` - * - * You can define the className as any fully namespaced classname or use a short hand - * classname to use loggers in the `App\Log\Engine` & `Cake\Log\Engine` namespaces. - * You can also use plugin short hand to use logging classes provided by plugins. - * - * Log adapters are required to implement `Psr\Log\LoggerInterface`, and there is a - * built-in base class (`Cake\Log\Engine\BaseLog`) that can be used for custom loggers. - * - * Outside of the `className` key, all other configuration values will be passed to the - * logging adapter's constructor as an array. - * - * ### Logging levels - * - * When configuring loggers, you can set which levels a logger will handle. - * This allows you to disable debug messages in production for example: - * - * ``` - * Log::setConfig('default', [ - * 'className' => 'File', - * 'path' => LOGS, - * 'levels' => ['error', 'critical', 'alert', 'emergency'] - * ]); - * ``` - * - * The above logger would only log error messages or higher. Any - * other log messages would be discarded. - * - * ### Logging scopes - * - * When configuring loggers you can define the active scopes the logger - * is for. If defined, only the listed scopes will be handled by the - * logger. If you don't define any scopes an adapter will catch - * all scopes that match the handled levels. - * - * ``` - * Log::setConfig('payments', [ - * 'className' => 'File', - * 'scopes' => ['payment', 'order'] - * ]); - * ``` - * - * The above logger will only capture log entries made in the - * `payment` and `order` scopes. All other scopes including the - * undefined scope will be ignored. - * - * ### Writing to the log - * - * You write to the logs using Log::write(). See its documentation for more information. - * - * ### Logging Levels - * - * By default Cake Log supports all the log levels defined in - * RFC 5424. When logging messages you can either use the named methods, - * or the correct constants with `write()`: - * - * ``` - * Log::error('Something horrible happened'); - * Log::write(LOG_ERR, 'Something horrible happened'); - * ``` - * - * ### Logging scopes - * - * When logging messages and configuring log adapters, you can specify - * 'scopes' that the logger will handle. You can think of scopes as subsystems - * in your application that may require different logging setups. For - * example in an e-commerce application you may want to handle logged errors - * in the cart and ordering subsystems differently than the rest of the - * application. By using scopes you can control logging for each part - * of your application and also use standard log levels. - */ -class Log -{ - - use StaticConfigTrait { - setConfig as protected _setConfig; - } - - /** - * An array mapping url schemes to fully qualified Log engine class names - * - * @var array - */ - protected static $_dsnClassMap = [ - 'console' => 'Cake\Log\Engine\ConsoleLog', - 'file' => 'Cake\Log\Engine\FileLog', - 'syslog' => 'Cake\Log\Engine\SyslogLog', - ]; - - /** - * Internal flag for tracking whether or not configuration has been changed. - * - * @var bool - */ - protected static $_dirtyConfig = false; - - /** - * LogEngineRegistry class - * - * @var \Cake\Log\LogEngineRegistry|null - */ - protected static $_registry; - - /** - * Handled log levels - * - * @var array - */ - protected static $_levels = [ - 'emergency', - 'alert', - 'critical', - 'error', - 'warning', - 'notice', - 'info', - 'debug' - ]; - - /** - * Log levels as detailed in RFC 5424 - * https://tools.ietf.org/html/rfc5424 - * - * @var array - */ - protected static $_levelMap = [ - 'emergency' => LOG_EMERG, - 'alert' => LOG_ALERT, - 'critical' => LOG_CRIT, - 'error' => LOG_ERR, - 'warning' => LOG_WARNING, - 'notice' => LOG_NOTICE, - 'info' => LOG_INFO, - 'debug' => LOG_DEBUG, - ]; - - /** - * Initializes registry and configurations - * - * @return void - */ - protected static function _init() - { - if (empty(static::$_registry)) { - static::$_registry = new LogEngineRegistry(); - } - if (static::$_dirtyConfig) { - static::_loadConfig(); - } - static::$_dirtyConfig = false; - } - - /** - * Load the defined configuration and create all the defined logging - * adapters. - * - * @return void - */ - protected static function _loadConfig() - { - foreach (static::$_config as $name => $properties) { - if (isset($properties['engine'])) { - $properties['className'] = $properties['engine']; - } - if (!static::$_registry->has($name)) { - static::$_registry->load($name, $properties); - } - } - } - - /** - * Reset all the connected loggers. This is useful to do when changing the logging - * configuration or during testing when you want to reset the internal state of the - * Log class. - * - * Resets the configured logging adapters, as well as any custom logging levels. - * This will also clear the configuration data. - * - * @return void - */ - public static function reset() - { - static::$_registry = null; - static::$_config = []; - static::$_dirtyConfig = true; - } - - /** - * Gets log levels - * - * Call this method to obtain current - * level configuration. - * - * @return array active log levels - */ - public static function levels() - { - return static::$_levels; - } - - /** - * This method can be used to define logging adapters for an application - * or read existing configuration. - * - * To change an adapter's configuration at runtime, first drop the adapter and then - * reconfigure it. - * - * Loggers will not be constructed until the first log message is written. - * - * ### Usage - * - * Setting a cache engine up. - * - * ``` - * Log::setConfig('default', $settings); - * ``` - * - * Injecting a constructed adapter in: - * - * ``` - * Log::setConfig('default', $instance); - * ``` - * - * Using a factory function to get an adapter: - * - * ``` - * Log::setConfig('default', function () { return new FileLog(); }); - * ``` - * - * Configure multiple adapters at once: - * - * ``` - * Log::setConfig($arrayOfConfig); - * ``` - * - * @param string|array $key The name of the logger config, or an array of multiple configs. - * @param array|null $config An array of name => config data for adapter. - * @return void - * @throws \BadMethodCallException When trying to modify an existing config. - */ - public static function setConfig($key, $config = null) - { - static::_setConfig($key, $config); - static::$_dirtyConfig = true; - } - - /** - * Get a logging engine. - * - * @param string $name Key name of a configured adapter to get. - * @return \Cake\Log\Engine\BaseLog|false Instance of BaseLog or false if not found - */ - public static function engine($name) - { - static::_init(); - if (static::$_registry->{$name}) { - return static::$_registry->{$name}; - } - - return false; - } - - /** - * Writes the given message and type to all of the configured log adapters. - * Configured adapters are passed both the $level and $message variables. $level - * is one of the following strings/values. - * - * ### Levels: - * - * - `LOG_EMERG` => 'emergency', - * - `LOG_ALERT` => 'alert', - * - `LOG_CRIT` => 'critical', - * - `LOG_ERR` => 'error', - * - `LOG_WARNING` => 'warning', - * - `LOG_NOTICE` => 'notice', - * - `LOG_INFO` => 'info', - * - `LOG_DEBUG` => 'debug', - * - * ### Basic usage - * - * Write a 'warning' message to the logs: - * - * ``` - * Log::write('warning', 'Stuff is broken here'); - * ``` - * - * ### Using scopes - * - * When writing a log message you can define one or many scopes for the message. - * This allows you to handle messages differently based on application section/feature. - * - * ``` - * Log::write('warning', 'Payment failed', ['scope' => 'payment']); - * ``` - * - * When configuring loggers you can configure the scopes a particular logger will handle. - * When using scopes, you must ensure that the level of the message, and the scope of the message - * intersect with the defined levels & scopes for a logger. - * - * ### Unhandled log messages - * - * If no configured logger can handle a log message (because of level or scope restrictions) - * then the logged message will be ignored and silently dropped. You can check if this has happened - * by inspecting the return of write(). If false the message was not handled. - * - * @param int|string $level The severity level of the message being written. - * The value must be an integer or string matching a known level. - * @param mixed $message Message content to log - * @param string|array $context Additional data to be used for logging the message. - * The special `scope` key can be passed to be used for further filtering of the - * log engines to be used. If a string or a numerically index array is passed, it - * will be treated as the `scope` key. - * See Cake\Log\Log::setConfig() for more information on logging scopes. - * @return bool Success - * @throws \InvalidArgumentException If invalid level is passed. - */ - public static function write($level, $message, $context = []) - { - static::_init(); - if (is_int($level) && in_array($level, static::$_levelMap)) { - $level = array_search($level, static::$_levelMap); - } - - if (!in_array($level, static::$_levels)) { - throw new InvalidArgumentException(sprintf('Invalid log level "%s"', $level)); - } - - $logged = false; - $context = (array)$context; - if (isset($context[0])) { - $context = ['scope' => $context]; - } - $context += ['scope' => []]; - - foreach (static::$_registry->loaded() as $streamName) { - $logger = static::$_registry->{$streamName}; - $levels = $scopes = null; - - if ($logger instanceof BaseLog) { - $levels = $logger->levels(); - $scopes = $logger->scopes(); - } - if ($scopes === null) { - $scopes = []; - } - - $correctLevel = empty($levels) || in_array($level, $levels); - $inScope = $scopes === false && empty($context['scope']) || $scopes === [] || - is_array($scopes) && array_intersect((array)$context['scope'], $scopes); - - if ($correctLevel && $inScope) { - $logger->log($level, $message, $context); - $logged = true; - } - } - - return $logged; - } - - /** - * Convenience method to log emergency messages - * - * @param string $message log message - * @param string|array $context Additional data to be used for logging the message. - * The special `scope` key can be passed to be used for further filtering of the - * log engines to be used. If a string or a numerically index array is passed, it - * will be treated as the `scope` key. - * See Cake\Log\Log::setConfig() for more information on logging scopes. - * @return bool Success - */ - public static function emergency($message, $context = []) - { - return static::write(__FUNCTION__, $message, $context); - } - - /** - * Convenience method to log alert messages - * - * @param string $message log message - * @param string|array $context Additional data to be used for logging the message. - * The special `scope` key can be passed to be used for further filtering of the - * log engines to be used. If a string or a numerically index array is passed, it - * will be treated as the `scope` key. - * See Cake\Log\Log::setConfig() for more information on logging scopes. - * @return bool Success - */ - public static function alert($message, $context = []) - { - return static::write(__FUNCTION__, $message, $context); - } - - /** - * Convenience method to log critical messages - * - * @param string $message log message - * @param string|array $context Additional data to be used for logging the message. - * The special `scope` key can be passed to be used for further filtering of the - * log engines to be used. If a string or a numerically index array is passed, it - * will be treated as the `scope` key. - * See Cake\Log\Log::setConfig() for more information on logging scopes. - * @return bool Success - */ - public static function critical($message, $context = []) - { - return static::write(__FUNCTION__, $message, $context); - } - - /** - * Convenience method to log error messages - * - * @param string $message log message - * @param string|array $context Additional data to be used for logging the message. - * The special `scope` key can be passed to be used for further filtering of the - * log engines to be used. If a string or a numerically index array is passed, it - * will be treated as the `scope` key. - * See Cake\Log\Log::setConfig() for more information on logging scopes. - * @return bool Success - */ - public static function error($message, $context = []) - { - return static::write(__FUNCTION__, $message, $context); - } - - /** - * Convenience method to log warning messages - * - * @param string $message log message - * @param string|array $context Additional data to be used for logging the message. - * The special `scope` key can be passed to be used for further filtering of the - * log engines to be used. If a string or a numerically index array is passed, it - * will be treated as the `scope` key. - * See Cake\Log\Log::setConfig() for more information on logging scopes. - * @return bool Success - */ - public static function warning($message, $context = []) - { - return static::write(__FUNCTION__, $message, $context); - } - - /** - * Convenience method to log notice messages - * - * @param string $message log message - * @param string|array $context Additional data to be used for logging the message. - * The special `scope` key can be passed to be used for further filtering of the - * log engines to be used. If a string or a numerically index array is passed, it - * will be treated as the `scope` key. - * See Cake\Log\Log::setConfig() for more information on logging scopes. - * @return bool Success - */ - public static function notice($message, $context = []) - { - return static::write(__FUNCTION__, $message, $context); - } - - /** - * Convenience method to log debug messages - * - * @param string $message log message - * @param string|array $context Additional data to be used for logging the message. - * The special `scope` key can be passed to be used for further filtering of the - * log engines to be used. If a string or a numerically index array is passed, it - * will be treated as the `scope` key. - * See Cake\Log\Log::setConfig() for more information on logging scopes. - * @return bool Success - */ - public static function debug($message, $context = []) - { - return static::write(__FUNCTION__, $message, $context); - } - - /** - * Convenience method to log info messages - * - * @param string $message log message - * @param string|array $context Additional data to be used for logging the message. - * The special `scope` key can be passed to be used for further filtering of the - * log engines to be used. If a string or a numerically index array is passed, it - * will be treated as the `scope` key. - * See Cake\Log\Log::setConfig() for more information on logging scopes. - * @return bool Success - */ - public static function info($message, $context = []) - { - return static::write(__FUNCTION__, $message, $context); - } -} diff --git a/vendor/cakephp/cakephp/src/Log/LogEngineRegistry.php b/vendor/cakephp/cakephp/src/Log/LogEngineRegistry.php deleted file mode 100644 index 0fa534f..0000000 --- a/vendor/cakephp/cakephp/src/Log/LogEngineRegistry.php +++ /dev/null @@ -1,104 +0,0 @@ -_loaded[$name]); - } -} diff --git a/vendor/cakephp/cakephp/src/Log/LogTrait.php b/vendor/cakephp/cakephp/src/Log/LogTrait.php deleted file mode 100644 index 31b943e..0000000 --- a/vendor/cakephp/cakephp/src/Log/LogTrait.php +++ /dev/null @@ -1,38 +0,0 @@ - 'FileLog', - 'levels' => ['notice', 'info', 'debug'], - 'file' => '/path/to/file.log', -]); - -// Fully namespaced name. -Log::config('production', [ - 'className' => 'Cake\Log\Engine\SyslogLog', - 'levels' => ['warning', 'error', 'critical', 'alert', 'emergency'], -]); -``` - -It is also possible to create loggers by providing a closure. - -```php -Log::config('special', function () { - // Return any PSR-3 compatible logger - return new MyPSR3CompatibleLogger(); -}); -``` - -Or by injecting an instance directly: - -```php -Log::config('special', new MyPSR3CompatibleLogger()); -``` - -You can then use the `Log` class to pass messages to the logging backends: - -```php -Log::write('debug', 'Something did not work'); -``` - -Only the logging engines subscribed to the log level you are writing to will -get the message passed. In the example above, only the 'local' engine will get -the log message. - -### Filtering messages with scopes - -The Log library supports another level of message filtering. By using scopes, -you can limit the logging engines that receive a particular message. - -```php -// Configure /logs/payments.log to receive all levels, but only -// those with `payments` scope. -Log::config('payments', [ - 'className' => 'FileLog', - 'levels' => ['error', 'info', 'warning'], - 'scopes' => ['payments'], - 'file' => '/logs/payments.log', -]); - -Log::warning('this gets written only to payments.log', ['scope' => ['payments']]); -``` - -## Documentation - -Please make sure you check the [official documentation](https://book.cakephp.org/3.0/en/core-libraries/logging.html) diff --git a/vendor/cakephp/cakephp/src/Log/composer.json b/vendor/cakephp/cakephp/src/Log/composer.json deleted file mode 100644 index a775a4f..0000000 --- a/vendor/cakephp/cakephp/src/Log/composer.json +++ /dev/null @@ -1,35 +0,0 @@ -{ - "name": "cakephp/log", - "description": "CakePHP logging library with support for multiple different streams", - "type": "library", - "keywords": [ - "cakephp", - "log", - "logging", - "streams" - ], - "homepage": "https://cakephp.org", - "license": "MIT", - "authors": [ - { - "name": "CakePHP Community", - "homepage": "https://github.com/cakephp/log/graphs/contributors" - } - ], - "support": { - "issues": "https://github.com/cakephp/cakephp/issues", - "forum": "https://stackoverflow.com/tags/cakephp", - "irc": "irc://irc.freenode.org/cakephp", - "source": "https://github.com/cakephp/log" - }, - "require": { - "php": ">=5.6.0", - "cakephp/core": "^3.6.0", - "psr/log": "^1.0.0" - }, - "autoload": { - "psr-4": { - "Cake\\Log\\": "." - } - } -} diff --git a/vendor/cakephp/cakephp/src/Mailer/AbstractTransport.php b/vendor/cakephp/cakephp/src/Mailer/AbstractTransport.php deleted file mode 100644 index 908b15d..0000000 --- a/vendor/cakephp/cakephp/src/Mailer/AbstractTransport.php +++ /dev/null @@ -1,76 +0,0 @@ -setConfig($config); - } - - /** - * Help to convert headers in string - * - * @param array $headers Headers in format key => value - * @param string $eol End of line string. - * @return string - */ - protected function _headersToString($headers, $eol = "\r\n") - { - $out = ''; - foreach ($headers as $key => $value) { - if ($value === false || $value === null || $value === '') { - continue; - } - $out .= $key . ': ' . $value . $eol; - } - if (!empty($out)) { - $out = substr($out, 0, -1 * strlen($eol)); - } - - return $out; - } -} diff --git a/vendor/cakephp/cakephp/src/Mailer/Email.php b/vendor/cakephp/cakephp/src/Mailer/Email.php deleted file mode 100644 index 19cfde9..0000000 --- a/vendor/cakephp/cakephp/src/Mailer/Email.php +++ /dev/null @@ -1,2923 +0,0 @@ - 'Cake\Mailer\Transport\DebugTransport', - 'mail' => 'Cake\Mailer\Transport\MailTransport', - 'smtp' => 'Cake\Mailer\Transport\SmtpTransport', - ]; - - /** - * Configuration profiles for transports. - * - * @var array - */ - protected static $_transportConfig = []; - - /** - * A copy of the configuration profile for this - * instance. This copy can be modified with Email::profile(). - * - * @var array - */ - protected $_profile = []; - - /** - * 8Bit character sets - * - * @var array - */ - protected $_charset8bit = ['UTF-8', 'SHIFT_JIS']; - - /** - * Define Content-Type charset name - * - * @var array - */ - protected $_contentTypeCharset = [ - 'ISO-2022-JP-MS' => 'ISO-2022-JP' - ]; - - /** - * Regex for email validation - * - * If null, filter_var() will be used. Use the emailPattern() method - * to set a custom pattern.' - * - * @var string - */ - protected $_emailPattern = self::EMAIL_PATTERN; - - /** - * Constructor - * - * @param array|string|null $config Array of configs, or string to load configs from email.php - */ - public function __construct($config = null) - { - $this->_appCharset = Configure::read('App.encoding'); - if ($this->_appCharset !== null) { - $this->charset = $this->_appCharset; - } - $this->_domain = preg_replace('/\:\d+$/', '', env('HTTP_HOST')); - if (empty($this->_domain)) { - $this->_domain = php_uname('n'); - } - - $this->viewBuilder() - ->setClassName('Cake\View\View') - ->setTemplate('') - ->setLayout('default') - ->setHelpers(['Html']); - - if ($config === null) { - $config = static::getConfig('default'); - } - if ($config) { - $this->setProfile($config); - } - if (empty($this->headerCharset)) { - $this->headerCharset = $this->charset; - } - } - - /** - * Clone ViewBuilder instance when email object is cloned. - * - * @return void - */ - public function __clone() - { - $this->_viewBuilder = clone $this->viewBuilder(); - } - - /** - * Sets "from" address. - * - * @param string|array $email Null to get, String with email, - * Array with email as key, name as value or email as value (without name) - * @param string|null $name Name - * @return $this - * @throws \InvalidArgumentException - */ - public function setFrom($email, $name = null) - { - return $this->_setEmailSingle('_from', $email, $name, 'From requires only 1 email address.'); - } - - /** - * Gets "from" address. - * - * @return array - */ - public function getFrom() - { - return $this->_from; - } - - /** - * From - * - * @deprecated 3.4.0 Use setFrom()/getFrom() instead. - * @param string|array|null $email Null to get, String with email, - * Array with email as key, name as value or email as value (without name) - * @param string|null $name Name - * @return array|$this - * @throws \InvalidArgumentException - */ - public function from($email = null, $name = null) - { - deprecationWarning('Email::from() is deprecated. Use Email::setFrom() or Email::getFrom() instead.'); - if ($email === null) { - return $this->getFrom(); - } - - return $this->setFrom($email, $name); - } - - /** - * Sets "sender" address. - * - * @param string|array $email String with email, - * Array with email as key, name as value or email as value (without name) - * @param string|null $name Name - * @return $this - * @throws \InvalidArgumentException - */ - public function setSender($email, $name = null) - { - return $this->_setEmailSingle('_sender', $email, $name, 'Sender requires only 1 email address.'); - } - - /** - * Gets "sender" address. - * - * @return array - */ - public function getSender() - { - return $this->_sender; - } - - /** - * Sender - * - * @deprecated 3.4.0 Use setSender()/getSender() instead. - * @param string|array|null $email Null to get, String with email, - * Array with email as key, name as value or email as value (without name) - * @param string|null $name Name - * @return array|$this - * @throws \InvalidArgumentException - */ - public function sender($email = null, $name = null) - { - deprecationWarning('Email::sender() is deprecated. Use Email::setSender() or Email::getSender() instead.'); - - if ($email === null) { - return $this->getSender(); - } - - return $this->setSender($email, $name); - } - - /** - * Sets "Reply-To" address. - * - * @param string|array $email String with email, - * Array with email as key, name as value or email as value (without name) - * @param string|null $name Name - * @return $this - * @throws \InvalidArgumentException - */ - public function setReplyTo($email, $name = null) - { - return $this->_setEmailSingle('_replyTo', $email, $name, 'Reply-To requires only 1 email address.'); - } - - /** - * Gets "Reply-To" address. - * - * @return array - */ - public function getReplyTo() - { - return $this->_replyTo; - } - - /** - * Reply-To - * - * @deprecated 3.4.0 Use setReplyTo()/getReplyTo() instead. - * @param string|array|null $email Null to get, String with email, - * Array with email as key, name as value or email as value (without name) - * @param string|null $name Name - * @return array|$this - * @throws \InvalidArgumentException - */ - public function replyTo($email = null, $name = null) - { - deprecationWarning('Email::replyTo() is deprecated. Use Email::setReplyTo() or Email::getReplyTo() instead.'); - - if ($email === null) { - return $this->getReplyTo(); - } - - return $this->setReplyTo($email, $name); - } - - /** - * Sets Read Receipt (Disposition-Notification-To header). - * - * @param string|array $email String with email, - * Array with email as key, name as value or email as value (without name) - * @param string|null $name Name - * @return $this - * @throws \InvalidArgumentException - */ - public function setReadReceipt($email, $name = null) - { - return $this->_setEmailSingle('_readReceipt', $email, $name, 'Disposition-Notification-To requires only 1 email address.'); - } - - /** - * Gets Read Receipt (Disposition-Notification-To header). - * - * @return array - */ - public function getReadReceipt() - { - return $this->_readReceipt; - } - - /** - * Read Receipt (Disposition-Notification-To header) - * - * @deprecated 3.4.0 Use setReadReceipt()/getReadReceipt() instead. - * @param string|array|null $email Null to get, String with email, - * Array with email as key, name as value or email as value (without name) - * @param string|null $name Name - * @return array|$this - * @throws \InvalidArgumentException - */ - public function readReceipt($email = null, $name = null) - { - deprecationWarning('Email::readReceipt() is deprecated. Use Email::setReadReceipt() or Email::getReadReceipt() instead.'); - - if ($email === null) { - return $this->getReadReceipt(); - } - - return $this->setReadReceipt($email, $name); - } - - /** - * Return Path - * - * @param string|array $email String with email, - * Array with email as key, name as value or email as value (without name) - * @param string|null $name Name - * @return $this - * @throws \InvalidArgumentException - */ - public function setReturnPath($email, $name = null) - { - return $this->_setEmailSingle('_returnPath', $email, $name, 'Return-Path requires only 1 email address.'); - } - - /** - * Gets return path. - * - * @return array - */ - public function getReturnPath() - { - return $this->_returnPath; - } - - /** - * Return Path - * - * @deprecated 3.4.0 Use setReturnPath()/getReturnPath() instead. - * @param string|array|null $email Null to get, String with email, - * Array with email as key, name as value or email as value (without name) - * @param string|null $name Name - * @return array|$this - * @throws \InvalidArgumentException - */ - public function returnPath($email = null, $name = null) - { - deprecationWarning('Email::returnPath() is deprecated. Use Email::setReturnPath() or Email::getReturnPath() instead.'); - if ($email === null) { - return $this->getReturnPath(); - } - - return $this->setReturnPath($email, $name); - } - - /** - * Sets "to" address. - * - * @param string|array $email String with email, - * Array with email as key, name as value or email as value (without name) - * @param string|null $name Name - * @return $this - */ - public function setTo($email, $name = null) - { - return $this->_setEmail('_to', $email, $name); - } - - /** - * Gets "to" address - * - * @return array - */ - public function getTo() - { - return $this->_to; - } - - /** - * To - * - * @deprecated 3.4.0 Use setTo()/getTo() instead. - * @param string|array|null $email Null to get, String with email, - * Array with email as key, name as value or email as value (without name) - * @param string|null $name Name - * @return array|$this - */ - public function to($email = null, $name = null) - { - deprecationWarning('Email::to() is deprecated. Use Email::setTo() or Email::getTo() instead.'); - - if ($email === null) { - return $this->getTo(); - } - - return $this->setTo($email, $name); - } - - /** - * Add To - * - * @param string|array $email Null to get, String with email, - * Array with email as key, name as value or email as value (without name) - * @param string|null $name Name - * @return $this - */ - public function addTo($email, $name = null) - { - return $this->_addEmail('_to', $email, $name); - } - - /** - * Sets "cc" address. - * - * @param string|array $email String with email, - * Array with email as key, name as value or email as value (without name) - * @param string|null $name Name - * @return $this - */ - public function setCc($email, $name = null) - { - return $this->_setEmail('_cc', $email, $name); - } - - /** - * Gets "cc" address. - * - * @return array - */ - public function getCc() - { - return $this->_cc; - } - - /** - * Cc - * - * @deprecated 3.4.0 Use setCc()/getCc() instead. - * @param string|array|null $email Null to get, String with email, - * Array with email as key, name as value or email as value (without name) - * @param string|null $name Name - * @return array|$this - */ - public function cc($email = null, $name = null) - { - deprecationWarning('Email::cc() is deprecated. Use Email::setCc() or Email::getCc() instead.'); - - if ($email === null) { - return $this->getCc(); - } - - return $this->setCc($email, $name); - } - - /** - * Add Cc - * - * @param string|array $email Null to get, String with email, - * Array with email as key, name as value or email as value (without name) - * @param string|null $name Name - * @return $this - */ - public function addCc($email, $name = null) - { - return $this->_addEmail('_cc', $email, $name); - } - - /** - * Sets "bcc" address. - * - * @param string|array $email String with email, - * Array with email as key, name as value or email as value (without name) - * @param string|null $name Name - * @return $this - */ - public function setBcc($email, $name = null) - { - return $this->_setEmail('_bcc', $email, $name); - } - - /** - * Gets "bcc" address. - * - * @return array - */ - public function getBcc() - { - return $this->_bcc; - } - - /** - * Bcc - * - * @deprecated 3.4.0 Use setBcc()/getBcc() instead. - * @param string|array|null $email Null to get, String with email, - * Array with email as key, name as value or email as value (without name) - * @param string|null $name Name - * @return array|$this - */ - public function bcc($email = null, $name = null) - { - deprecationWarning('Email::bcc() is deprecated. Use Email::setBcc() or Email::getBcc() instead.'); - - if ($email === null) { - return $this->getBcc(); - } - - return $this->setBcc($email, $name); - } - - /** - * Add Bcc - * - * @param string|array $email Null to get, String with email, - * Array with email as key, name as value or email as value (without name) - * @param string|null $name Name - * @return $this - */ - public function addBcc($email, $name = null) - { - return $this->_addEmail('_bcc', $email, $name); - } - - /** - * Charset setter. - * - * @param string|null $charset Character set. - * @return $this - */ - public function setCharset($charset) - { - $this->charset = $charset; - if (!$this->headerCharset) { - $this->headerCharset = $charset; - } - - return $this; - } - - /** - * Charset getter. - * - * @return string Charset - */ - public function getCharset() - { - return $this->charset; - } - - /** - * Charset setter/getter - * - * @deprecated 3.4.0 Use setCharset()/getCharset() instead. - * @param string|null $charset Character set. - * @return string Charset - */ - public function charset($charset = null) - { - deprecationWarning('Email::charset() is deprecated. Use Email::setCharset() or Email::getCharset() instead.'); - - if ($charset === null) { - return $this->getCharset(); - } - $this->setCharset($charset); - - return $this->charset; - } - - /** - * HeaderCharset setter. - * - * @param string|null $charset Character set. - * @return $this - */ - public function setHeaderCharset($charset) - { - $this->headerCharset = $charset; - - return $this; - } - - /** - * HeaderCharset getter. - * - * @return string Charset - */ - public function getHeaderCharset() - { - return $this->headerCharset; - } - - /** - * HeaderCharset setter/getter - * - * @deprecated 3.4.0 Use setHeaderCharset()/getHeaderCharset() instead. - * @param string|null $charset Character set. - * @return string Charset - */ - public function headerCharset($charset = null) - { - deprecationWarning('Email::headerCharset() is deprecated. Use Email::setHeaderCharset() or Email::getHeaderCharset() instead.'); - - if ($charset === null) { - return $this->getHeaderCharset(); - } - - $this->setHeaderCharset($charset); - - return $this->headerCharset; - } - - /** - * TransferEncoding setter. - * - * @param string|null $encoding Encoding set. - * @return $this - */ - public function setTransferEncoding($encoding) - { - $encoding = strtolower($encoding); - if (!in_array($encoding, $this->_transferEncodingAvailable)) { - throw new InvalidArgumentException( - sprintf( - 'Transfer encoding not available. Can be : %s.', - implode(', ', $this->_transferEncodingAvailable) - ) - ); - } - $this->transferEncoding = $encoding; - - return $this; - } - - /** - * TransferEncoding getter. - * - * @return string|null Encoding - */ - public function getTransferEncoding() - { - return $this->transferEncoding; - } - - /** - * EmailPattern setter/getter - * - * @param string|null $regex The pattern to use for email address validation, - * null to unset the pattern and make use of filter_var() instead. - * @return $this - */ - public function setEmailPattern($regex) - { - $this->_emailPattern = $regex; - - return $this; - } - - /** - * EmailPattern setter/getter - * - * @return string - */ - public function getEmailPattern() - { - return $this->_emailPattern; - } - - /** - * EmailPattern setter/getter - * - * @deprecated 3.4.0 Use setEmailPattern()/getEmailPattern() instead. - * @param string|bool|null $regex The pattern to use for email address validation, - * null to unset the pattern and make use of filter_var() instead, false or - * nothing to return the current value - * @return string|$this - */ - public function emailPattern($regex = false) - { - deprecationWarning('Email::emailPattern() is deprecated. Use Email::setEmailPattern() or Email::getEmailPattern() instead.'); - - if ($regex === false) { - return $this->getEmailPattern(); - } - - return $this->setEmailPattern($regex); - } - - /** - * Set email - * - * @param string $varName Property name - * @param string|array $email String with email, - * Array with email as key, name as value or email as value (without name) - * @param string $name Name - * @return $this - * @throws \InvalidArgumentException - */ - protected function _setEmail($varName, $email, $name) - { - if (!is_array($email)) { - $this->_validateEmail($email, $varName); - if ($name === null) { - $name = $email; - } - $this->{$varName} = [$email => $name]; - - return $this; - } - $list = []; - foreach ($email as $key => $value) { - if (is_int($key)) { - $key = $value; - } - $this->_validateEmail($key, $varName); - $list[$key] = $value; - } - $this->{$varName} = $list; - - return $this; - } - - /** - * Validate email address - * - * @param string $email Email address to validate - * @param string $context Which property was set - * @return void - * @throws \InvalidArgumentException If email address does not validate - */ - protected function _validateEmail($email, $context) - { - if ($this->_emailPattern === null) { - if (filter_var($email, FILTER_VALIDATE_EMAIL)) { - return; - } - } elseif (preg_match($this->_emailPattern, $email)) { - return; - } - - $context = ltrim($context, '_'); - if ($email == '') { - throw new InvalidArgumentException(sprintf('The email set for "%s" is empty.', $context)); - } - throw new InvalidArgumentException(sprintf('Invalid email set for "%s". You passed "%s".', $context, $email)); - } - - /** - * Set only 1 email - * - * @param string $varName Property name - * @param string|array $email String with email, - * Array with email as key, name as value or email as value (without name) - * @param string $name Name - * @param string $throwMessage Exception message - * @return $this - * @throws \InvalidArgumentException - */ - protected function _setEmailSingle($varName, $email, $name, $throwMessage) - { - if ($email === []) { - $this->{$varName} = $email; - - return $this; - } - - $current = $this->{$varName}; - $this->_setEmail($varName, $email, $name); - if (count($this->{$varName}) !== 1) { - $this->{$varName} = $current; - throw new InvalidArgumentException($throwMessage); - } - - return $this; - } - - /** - * Add email - * - * @param string $varName Property name - * @param string|array $email String with email, - * Array with email as key, name as value or email as value (without name) - * @param string $name Name - * @return $this - * @throws \InvalidArgumentException - */ - protected function _addEmail($varName, $email, $name) - { - if (!is_array($email)) { - $this->_validateEmail($email, $varName); - if ($name === null) { - $name = $email; - } - $this->{$varName}[$email] = $name; - - return $this; - } - $list = []; - foreach ($email as $key => $value) { - if (is_int($key)) { - $key = $value; - } - $this->_validateEmail($key, $varName); - $list[$key] = $value; - } - $this->{$varName} = array_merge($this->{$varName}, $list); - - return $this; - } - - /** - * Sets subject. - * - * @param string $subject Subject string. - * @return $this - */ - public function setSubject($subject) - { - $this->_subject = $this->_encode((string)$subject); - - return $this; - } - - /** - * Gets subject. - * - * @return string - */ - public function getSubject() - { - return $this->_subject; - } - - /** - * Get/Set Subject. - * - * @deprecated 3.4.0 Use setSubject()/getSubject() instead. - * @param string|null $subject Subject string. - * @return string|$this - */ - public function subject($subject = null) - { - deprecationWarning('Email::subject() is deprecated. Use Email::setSubject() or Email::getSubject() instead.'); - - if ($subject === null) { - return $this->getSubject(); - } - - return $this->setSubject($subject); - } - - /** - * Get original subject without encoding - * - * @return string Original subject - */ - public function getOriginalSubject() - { - return $this->_decode($this->_subject); - } - - /** - * Sets headers for the message - * - * @param array $headers Associative array containing headers to be set. - * @return $this - */ - public function setHeaders(array $headers) - { - $this->_headers = $headers; - - return $this; - } - - /** - * Add header for the message - * - * @param array $headers Headers to set. - * @return $this - */ - public function addHeaders(array $headers) - { - $this->_headers = array_merge($this->_headers, $headers); - - return $this; - } - - /** - * Get list of headers - * - * ### Includes: - * - * - `from` - * - `replyTo` - * - `readReceipt` - * - `returnPath` - * - `to` - * - `cc` - * - `bcc` - * - `subject` - * - * @param array $include List of headers. - * @return array - */ - public function getHeaders(array $include = []) - { - if ($include == array_values($include)) { - $include = array_fill_keys($include, true); - } - $defaults = array_fill_keys( - [ - 'from', 'sender', 'replyTo', 'readReceipt', 'returnPath', - 'to', 'cc', 'bcc', 'subject'], - false - ); - $include += $defaults; - - $headers = []; - $relation = [ - 'from' => 'From', - 'replyTo' => 'Reply-To', - 'readReceipt' => 'Disposition-Notification-To', - 'returnPath' => 'Return-Path' - ]; - foreach ($relation as $var => $header) { - if ($include[$var]) { - $var = '_' . $var; - $headers[$header] = current($this->_formatAddress($this->{$var})); - } - } - if ($include['sender']) { - if (key($this->_sender) === key($this->_from)) { - $headers['Sender'] = ''; - } else { - $headers['Sender'] = current($this->_formatAddress($this->_sender)); - } - } - - foreach (['to', 'cc', 'bcc'] as $var) { - if ($include[$var]) { - $classVar = '_' . $var; - $headers[ucfirst($var)] = implode(', ', $this->_formatAddress($this->{$classVar})); - } - } - - $headers += $this->_headers; - if (!isset($headers['Date'])) { - $headers['Date'] = date(DATE_RFC2822); - } - if ($this->_messageId !== false) { - if ($this->_messageId === true) { - $headers['Message-ID'] = '<' . str_replace('-', '', Text::uuid()) . '@' . $this->_domain . '>'; - } else { - $headers['Message-ID'] = $this->_messageId; - } - } - - if ($this->_priority) { - $headers['X-Priority'] = $this->_priority; - } - - if ($include['subject']) { - $headers['Subject'] = $this->_subject; - } - - $headers['MIME-Version'] = '1.0'; - if ($this->_attachments) { - $headers['Content-Type'] = 'multipart/mixed; boundary="' . $this->_boundary . '"'; - } elseif ($this->_emailFormat === 'both') { - $headers['Content-Type'] = 'multipart/alternative; boundary="' . $this->_boundary . '"'; - } elseif ($this->_emailFormat === 'text') { - $headers['Content-Type'] = 'text/plain; charset=' . $this->_getContentTypeCharset(); - } elseif ($this->_emailFormat === 'html') { - $headers['Content-Type'] = 'text/html; charset=' . $this->_getContentTypeCharset(); - } - $headers['Content-Transfer-Encoding'] = $this->_getContentTransferEncoding(); - - return $headers; - } - - /** - * Format addresses - * - * If the address contains non alphanumeric/whitespace characters, it will - * be quoted as characters like `:` and `,` are known to cause issues - * in address header fields. - * - * @param array $address Addresses to format. - * @return array - */ - protected function _formatAddress($address) - { - $return = []; - foreach ($address as $email => $alias) { - if ($email === $alias) { - $return[] = $email; - } else { - $encoded = $this->_encode($alias); - if ($encoded === $alias && preg_match('/[^a-z0-9 ]/i', $encoded)) { - $encoded = '"' . str_replace('"', '\"', $encoded) . '"'; - } - $return[] = sprintf('%s <%s>', $encoded, $email); - } - } - - return $return; - } - - /** - * Sets template. - * - * @param string|null $template Template name or null to not use. - * @return $this - */ - public function setTemplate($template) - { - $this->viewBuilder()->setTemplate($template ?: ''); - - return $this; - } - - /** - * Gets template. - * - * @return string - */ - public function getTemplate() - { - return $this->viewBuilder()->getTemplate(); - } - - /** - * Sets layout. - * - * @param string|null $layout Layout name or null to not use - * @return $this - */ - public function setLayout($layout) - { - $this->viewBuilder()->setLayout($layout ?: false); - - return $this; - } - - /** - * Gets layout. - * - * @return string - */ - public function getLayout() - { - return $this->viewBuilder()->getLayout(); - } - - /** - * Template and layout - * - * @deprecated 3.4.0 Use setTemplate()/getTemplate() and setLayout()/getLayout() instead. - * @param bool|string $template Template name or null to not use - * @param bool|string $layout Layout name or null to not use - * @return array|$this - */ - public function template($template = false, $layout = false) - { - deprecationWarning('Email::template() is deprecated. Use Email::setTemplate() or Email::getTemplate() and Email::setLayout() or Email::getLayout() instead.'); - - if ($template === false) { - return [ - 'template' => $this->getTemplate(), - 'layout' => $this->getLayout() - ]; - } - $this->setTemplate($template); - if ($layout !== false) { - $this->setLayout($layout); - } - - return $this; - } - - /** - * Sets view class for render. - * - * @param string $viewClass View class name. - * @return $this - */ - public function setViewRenderer($viewClass) - { - $this->viewBuilder()->setClassName($viewClass); - - return $this; - } - - /** - * Gets view class for render. - * - * @return string - */ - public function getViewRenderer() - { - return $this->viewBuilder()->getClassName(); - } - - /** - * View class for render - * - * @deprecated 3.4.0 Use setViewRenderer()/getViewRenderer() instead. - * @param string|null $viewClass View class name. - * @return string|$this - */ - public function viewRender($viewClass = null) - { - deprecationWarning('Email::viewRender() is deprecated. Use Email::setViewRenderer() or Email::getViewRenderer() instead.'); - - if ($viewClass === null) { - return $this->getViewRenderer(); - } - $this->setViewRenderer($viewClass); - - return $this; - } - - /** - * Sets variables to be set on render. - * - * @param array $viewVars Variables to set for view. - * @return $this - */ - public function setViewVars($viewVars) - { - $this->set((array)$viewVars); - - return $this; - } - - /** - * Gets variables to be set on render. - * - * @return array - */ - public function getViewVars() - { - return $this->viewVars; - } - - /** - * Variables to be set on render - * - * @deprecated 3.4.0 Use setViewVars()/getViewVars() instead. - * @param array|null $viewVars Variables to set for view. - * @return array|$this - */ - public function viewVars($viewVars = null) - { - deprecationWarning('Email::viewVars() is deprecated. Use Email::setViewVars() or Email::getViewVars() instead.'); - - if ($viewVars === null) { - return $this->getViewVars(); - } - - return $this->setViewVars($viewVars); - } - - /** - * Sets theme to use when rendering. - * - * @param string $theme Theme name. - * @return $this - */ - public function setTheme($theme) - { - $this->viewBuilder()->setTheme($theme); - - return $this; - } - - /** - * Gets theme to use when rendering. - * - * @return string - */ - public function getTheme() - { - return $this->viewBuilder()->getTheme(); - } - - /** - * Theme to use when rendering - * - * @deprecated 3.4.0 Use setTheme()/getTheme() instead. - * @param string|null $theme Theme name. - * @return string|$this - */ - public function theme($theme = null) - { - deprecationWarning('Email::theme() is deprecated. Use Email::setTheme() or Email::getTheme() instead.'); - - if ($theme === null) { - return $this->getTheme(); - } - - return $this->setTheme($theme); - } - - /** - * Sets helpers to be used when rendering. - * - * @param array $helpers Helpers list. - * @return $this - */ - public function setHelpers(array $helpers) - { - $this->viewBuilder()->setHelpers($helpers, false); - - return $this; - } - - /** - * Gets helpers to be used when rendering. - * - * @return array - */ - public function getHelpers() - { - return $this->viewBuilder()->getHelpers(); - } - - /** - * Helpers to be used in render - * - * @deprecated 3.4.0 Use setHelpers()/getHelpers() instead. - * @param array|null $helpers Helpers list. - * @return array|$this - */ - public function helpers($helpers = null) - { - deprecationWarning('Email::helpers() is deprecated. Use Email::setHelpers() or Email::getHelpers() instead.'); - - if ($helpers === null) { - return $this->getHelpers(); - } - - return $this->setHelpers((array)$helpers); - } - - /** - * Sets email format. - * - * @param string $format Formatting string. - * @return $this - * @throws \InvalidArgumentException - */ - public function setEmailFormat($format) - { - if (!in_array($format, $this->_emailFormatAvailable)) { - throw new InvalidArgumentException('Format not available.'); - } - $this->_emailFormat = $format; - - return $this; - } - - /** - * Gets email format. - * - * @return string - */ - public function getEmailFormat() - { - return $this->_emailFormat; - } - - /** - * Email format - * - * @deprecated 3.4.0 Use setEmailFormat()/getEmailFormat() instead. - * @param string|null $format Formatting string. - * @return string|$this - * @throws \InvalidArgumentException - */ - public function emailFormat($format = null) - { - deprecationWarning('Email::emailFormat() is deprecated. Use Email::setEmailFormat() or Email::getEmailFormat() instead.'); - - if ($format === null) { - return $this->getEmailFormat(); - } - - return $this->setEmailFormat($format); - } - - /** - * Sets the transport. - * - * When setting the transport you can either use the name - * of a configured transport or supply a constructed transport. - * - * @param string|\Cake\Mailer\AbstractTransport $name Either the name of a configured - * transport, or a transport instance. - * @return $this - * @throws \LogicException When the chosen transport lacks a send method. - * @throws \InvalidArgumentException When $name is neither a string nor an object. - */ - public function setTransport($name) - { - if (is_string($name)) { - $transport = $this->_constructTransport($name); - } elseif (is_object($name)) { - $transport = $name; - } else { - throw new InvalidArgumentException( - sprintf('The value passed for the "$name" argument must be either a string, or an object, %s given.', gettype($name)) - ); - } - if (!method_exists($transport, 'send')) { - throw new LogicException(sprintf('The "%s" do not have send method.', get_class($transport))); - } - - $this->_transport = $transport; - - return $this; - } - - /** - * Gets the transport. - * - * @return \Cake\Mailer\AbstractTransport - */ - public function getTransport() - { - return $this->_transport; - } - - /** - * Get/set the transport. - * - * When setting the transport you can either use the name - * of a configured transport or supply a constructed transport. - * - * @deprecated 3.4.0 Use setTransport()/getTransport() instead. - * @param string|\Cake\Mailer\AbstractTransport|null $name Either the name of a configured - * transport, or a transport instance. - * @return \Cake\Mailer\AbstractTransport|$this - * @throws \LogicException When the chosen transport lacks a send method. - * @throws \InvalidArgumentException When $name is neither a string nor an object. - */ - public function transport($name = null) - { - deprecationWarning('Email::transport() is deprecated. Use Email::setTransport() or Email::getTransport() instead.'); - - if ($name === null) { - return $this->getTransport(); - } - - return $this->setTransport($name); - } - - /** - * Build a transport instance from configuration data. - * - * @param string $name The transport configuration name to build. - * @return \Cake\Mailer\AbstractTransport - * @throws \InvalidArgumentException When transport configuration is missing or invalid. - */ - protected function _constructTransport($name) - { - if (!isset(static::$_transportConfig[$name])) { - throw new InvalidArgumentException(sprintf('Transport config "%s" is missing.', $name)); - } - - if (!isset(static::$_transportConfig[$name]['className'])) { - throw new InvalidArgumentException( - sprintf('Transport config "%s" is invalid, the required `className` option is missing', $name) - ); - } - - $config = static::$_transportConfig[$name]; - - if (is_object($config['className'])) { - if (!$config['className'] instanceof AbstractTransport) { - throw new InvalidArgumentException(sprintf( - 'Transport object must be of type "AbstractTransport". Found invalid type: "%s".', - get_class($config['className']) - )); - } - - return $config['className']; - } - - $className = App::className($config['className'], 'Mailer/Transport', 'Transport'); - if (!$className) { - $className = App::className($config['className'], 'Network/Email', 'Transport'); - if ($className) { - trigger_error( - 'Transports in "Network/Email" are deprecated, use "Mailer/Transport" instead.', - E_USER_DEPRECATED - ); - } - } - - if (!$className) { - throw new InvalidArgumentException(sprintf('Transport class "%s" not found.', $config['className'])); - } - if (!method_exists($className, 'send')) { - throw new InvalidArgumentException(sprintf('The "%s" does not have a send() method.', $className)); - } - - unset($config['className']); - - return new $className($config); - } - - /** - * Sets message ID. - * - * @param bool|string $message True to generate a new Message-ID, False to ignore (not send in email), String to set as Message-ID. - * @return $this - * @throws \InvalidArgumentException - */ - public function setMessageId($message) - { - if (is_bool($message)) { - $this->_messageId = $message; - } else { - if (!preg_match('/^\<.+@.+\>$/', $message)) { - throw new InvalidArgumentException('Invalid format to Message-ID. The text should be something like ""'); - } - $this->_messageId = $message; - } - - return $this; - } - - /** - * Gets message ID. - * - * @return bool|string - */ - public function getMessageId() - { - return $this->_messageId; - } - - /** - * Message-ID - * - * @deprecated 3.4.0 Use setMessageId()/getMessageId() instead. - * @param bool|string|null $message True to generate a new Message-ID, False to ignore (not send in email), String to set as Message-ID - * @return bool|string|$this - * @throws \InvalidArgumentException - */ - public function messageId($message = null) - { - deprecationWarning('Email::messageId() is deprecated. Use Email::setMessageId() or Email::getMessageId() instead.'); - - if ($message === null) { - return $this->getMessageId(); - } - - return $this->setMessageId($message); - } - - /** - * Sets domain. - * - * Domain as top level (the part after @). - * - * @param string $domain Manually set the domain for CLI mailing. - * @return $this - */ - public function setDomain($domain) - { - $this->_domain = $domain; - - return $this; - } - - /** - * Gets domain. - * - * @return string - */ - public function getDomain() - { - return $this->_domain; - } - - /** - * Domain as top level (the part after @) - * - * @deprecated 3.4.0 Use setDomain()/getDomain() instead. - * @param string|null $domain Manually set the domain for CLI mailing - * @return string|$this - */ - public function domain($domain = null) - { - deprecationWarning('Email::domain() is deprecated. Use Email::setDomain() or Email::getDomain() instead.'); - - if ($domain === null) { - return $this->getDomain(); - } - - return $this->setDomain($domain); - } - - /** - * Add attachments to the email message - * - * Attachments can be defined in a few forms depending on how much control you need: - * - * Attach a single file: - * - * ``` - * $email->setAttachments('path/to/file'); - * ``` - * - * Attach a file with a different filename: - * - * ``` - * $email->setAttachments(['custom_name.txt' => 'path/to/file.txt']); - * ``` - * - * Attach a file and specify additional properties: - * - * ``` - * $email->setAttachments(['custom_name.png' => [ - * 'file' => 'path/to/file', - * 'mimetype' => 'image/png', - * 'contentId' => 'abc123', - * 'contentDisposition' => false - * ] - * ]); - * ``` - * - * Attach a file from string and specify additional properties: - * - * ``` - * $email->setAttachments(['custom_name.png' => [ - * 'data' => file_get_contents('path/to/file'), - * 'mimetype' => 'image/png' - * ] - * ]); - * ``` - * - * The `contentId` key allows you to specify an inline attachment. In your email text, you - * can use `` to display the image inline. - * - * The `contentDisposition` key allows you to disable the `Content-Disposition` header, this can improve - * attachment compatibility with outlook email clients. - * - * @param string|array $attachments String with the filename or array with filenames - * @return $this - * @throws \InvalidArgumentException - */ - public function setAttachments($attachments) - { - $attach = []; - foreach ((array)$attachments as $name => $fileInfo) { - if (!is_array($fileInfo)) { - $fileInfo = ['file' => $fileInfo]; - } - if (!isset($fileInfo['file'])) { - if (!isset($fileInfo['data'])) { - throw new InvalidArgumentException('No file or data specified.'); - } - if (is_int($name)) { - throw new InvalidArgumentException('No filename specified.'); - } - $fileInfo['data'] = chunk_split(base64_encode($fileInfo['data']), 76, "\r\n"); - } else { - $fileName = $fileInfo['file']; - $fileInfo['file'] = realpath($fileInfo['file']); - if ($fileInfo['file'] === false || !file_exists($fileInfo['file'])) { - throw new InvalidArgumentException(sprintf('File not found: "%s"', $fileName)); - } - if (is_int($name)) { - $name = basename($fileInfo['file']); - } - } - if (!isset($fileInfo['mimetype']) && function_exists('mime_content_type')) { - $fileInfo['mimetype'] = mime_content_type($fileInfo['file']); - } - if (!isset($fileInfo['mimetype'])) { - $fileInfo['mimetype'] = 'application/octet-stream'; - } - $attach[$name] = $fileInfo; - } - $this->_attachments = $attach; - - return $this; - } - - /** - * Gets attachments to the email message. - * - * @return array Array of attachments. - */ - public function getAttachments() - { - return $this->_attachments; - } - - /** - * Add attachments to the email message - * - * Attachments can be defined in a few forms depending on how much control you need: - * - * Attach a single file: - * - * ``` - * $email->setAttachments('path/to/file'); - * ``` - * - * Attach a file with a different filename: - * - * ``` - * $email->setAttachments(['custom_name.txt' => 'path/to/file.txt']); - * ``` - * - * Attach a file and specify additional properties: - * - * ``` - * $email->setAttachments(['custom_name.png' => [ - * 'file' => 'path/to/file', - * 'mimetype' => 'image/png', - * 'contentId' => 'abc123', - * 'contentDisposition' => false - * ] - * ]); - * ``` - * - * Attach a file from string and specify additional properties: - * - * ``` - * $email->setAttachments(['custom_name.png' => [ - * 'data' => file_get_contents('path/to/file'), - * 'mimetype' => 'image/png' - * ] - * ]); - * ``` - * - * The `contentId` key allows you to specify an inline attachment. In your email text, you - * can use `` to display the image inline. - * - * The `contentDisposition` key allows you to disable the `Content-Disposition` header, this can improve - * attachment compatibility with outlook email clients. - * - * @deprecated 3.4.0 Use setAttachments()/getAttachments() instead. - * @param string|array|null $attachments String with the filename or array with filenames - * @return array|$this Either the array of attachments when getting or $this when setting. - * @throws \InvalidArgumentException - */ - public function attachments($attachments = null) - { - deprecationWarning('Email::attachments() is deprecated. Use Email::setAttachments() or Email::getAttachments() instead.'); - - if ($attachments === null) { - return $this->getAttachments(); - } - - return $this->setAttachments($attachments); - } - - /** - * Add attachments - * - * @param string|array $attachments String with the filename or array with filenames - * @return $this - * @throws \InvalidArgumentException - * @see \Cake\Mailer\Email::attachments() - */ - public function addAttachments($attachments) - { - $current = $this->_attachments; - $this->setAttachments($attachments); - $this->_attachments = array_merge($current, $this->_attachments); - - return $this; - } - - /** - * Get generated message (used by transport classes) - * - * @param string|null $type Use MESSAGE_* constants or null to return the full message as array - * @return string|array String if type is given, array if type is null - */ - public function message($type = null) - { - switch ($type) { - case static::MESSAGE_HTML: - return $this->_htmlMessage; - case static::MESSAGE_TEXT: - return $this->_textMessage; - } - - return $this->_message; - } - - /** - * Sets priority. - * - * @param int|null $priority 1 (highest) to 5 (lowest) - * @return $this - */ - public function setPriority($priority) - { - $this->_priority = $priority; - - return $this; - } - - /** - * Gets priority. - * - * @return int - */ - public function getPriority() - { - return $this->_priority; - } - - /** - * Sets transport configuration. - * - * Use this method to define transports to use in delivery profiles. - * Once defined you cannot edit the configurations, and must use - * Email::dropTransport() to flush the configuration first. - * - * When using an array of configuration data a new transport - * will be constructed for each message sent. When using a Closure, the - * closure will be evaluated for each message. - * - * The `className` is used to define the class to use for a transport. - * It can either be a short name, or a fully qualified class name - * - * @param string|array $key The configuration name to write. Or - * an array of multiple transports to set. - * @param array|\Cake\Mailer\AbstractTransport|null $config Either an array of configuration - * data, or a transport instance. Null when using key as array. - * @return void - * @throws \BadMethodCallException When modifying an existing configuration. - */ - public static function setConfigTransport($key, $config = null) - { - if (is_array($key)) { - foreach ($key as $name => $settings) { - static::setConfigTransport($name, $settings); - } - - return; - } - - if (isset(static::$_transportConfig[$key])) { - throw new BadMethodCallException(sprintf('Cannot modify an existing config "%s"', $key)); - } - - if (is_object($config)) { - $config = ['className' => $config]; - } - - if (isset($config['url'])) { - $parsed = static::parseDsn($config['url']); - unset($config['url']); - $config = $parsed + $config; - } - - static::$_transportConfig[$key] = $config; - } - - /** - * Gets current transport configuration. - * - * @param string $key The configuration name to read. - * @return array|null Transport config. - */ - public static function getConfigTransport($key) - { - return isset(static::$_transportConfig[$key]) ? static::$_transportConfig[$key] : null; - } - - /** - * Add or read transport configuration. - * - * Use this method to define transports to use in delivery profiles. - * Once defined you cannot edit the configurations, and must use - * Email::dropTransport() to flush the configuration first. - * - * When using an array of configuration data a new transport - * will be constructed for each message sent. When using a Closure, the - * closure will be evaluated for each message. - * - * The `className` is used to define the class to use for a transport. - * It can either be a short name, or a fully qualified classname - * - * @deprecated 3.4.0 Use setConfigTransport()/getConfigTransport() instead. - * @param string|array $key The configuration name to read/write. Or - * an array of multiple transports to set. - * @param array|\Cake\Mailer\AbstractTransport|null $config Either an array of configuration - * data, or a transport instance. - * @return array|null Either null when setting or an array of data when reading. - * @throws \BadMethodCallException When modifying an existing configuration. - */ - public static function configTransport($key, $config = null) - { - deprecationWarning('Email::configTransport() is deprecated. Use Email::setConfigTransport() or Email::getConfigTransport() instead.'); - - if ($config === null && is_string($key)) { - return static::getConfigTransport($key); - } - if ($config === null && is_array($key)) { - static::setConfigTransport($key); - - return null; - } - - static::setConfigTransport($key, $config); - } - - /** - * Returns an array containing the named transport configurations - * - * @return array Array of configurations. - */ - public static function configuredTransport() - { - return array_keys(static::$_transportConfig); - } - - /** - * Delete transport configuration. - * - * @param string $key The transport name to remove. - * @return void - */ - public static function dropTransport($key) - { - unset(static::$_transportConfig[$key]); - } - - /** - * Sets the configuration profile to use for this instance. - * - * @param string|array $config String with configuration name, or - * an array with config. - * @return $this - */ - public function setProfile($config) - { - if (!is_array($config)) { - $config = (string)$config; - } - $this->_applyConfig($config); - - return $this; - } - - /** - * Gets the configuration profile to use for this instance. - * - * @return string|array - */ - public function getProfile() - { - return $this->_profile; - } - - /** - * Get/Set the configuration profile to use for this instance. - * - * @deprecated 3.4.0 Use setProfile()/getProfile() instead. - * @param null|string|array $config String with configuration name, or - * an array with config or null to return current config. - * @return string|array|$this - */ - public function profile($config = null) - { - deprecationWarning('Email::profile() is deprecated. Use Email::setProfile() or Email::getProfile() instead.'); - - if ($config === null) { - return $this->getProfile(); - } - - return $this->setProfile($config); - } - - /** - * Send an email using the specified content, template and layout - * - * @param string|array|null $content String with message or array with messages - * @return array - * @throws \BadMethodCallException - */ - public function send($content = null) - { - if (empty($this->_from)) { - throw new BadMethodCallException('From is not specified.'); - } - if (empty($this->_to) && empty($this->_cc) && empty($this->_bcc)) { - throw new BadMethodCallException('You need specify one destination on to, cc or bcc.'); - } - - if (is_array($content)) { - $content = implode("\n", $content) . "\n"; - } - - $this->_message = $this->_render($this->_wrap($content)); - - $transport = $this->getTransport(); - if (!$transport) { - $msg = 'Cannot send email, transport was not defined. Did you call transport() or define ' . - ' a transport in the set profile?'; - throw new BadMethodCallException($msg); - } - $contents = $transport->send($this); - $this->_logDelivery($contents); - - return $contents; - } - - /** - * Log the email message delivery. - * - * @param array $contents The content with 'headers' and 'message' keys. - * @return void - */ - protected function _logDelivery($contents) - { - if (empty($this->_profile['log'])) { - return; - } - $config = [ - 'level' => 'debug', - 'scope' => 'email' - ]; - if ($this->_profile['log'] !== true) { - if (!is_array($this->_profile['log'])) { - $this->_profile['log'] = ['level' => $this->_profile['log']]; - } - $config = $this->_profile['log'] + $config; - } - Log::write( - $config['level'], - PHP_EOL . $this->flatten($contents['headers']) . PHP_EOL . PHP_EOL . $this->flatten($contents['message']), - $config['scope'] - ); - } - - /** - * Converts given value to string - * - * @param string|array $value The value to convert - * @return string - */ - protected function flatten($value) - { - return is_array($value) ? implode(';', $value) : (string)$value; - } - - /** - * Static method to fast create an instance of \Cake\Mailer\Email - * - * @param string|array|null $to Address to send (see Cake\Mailer\Email::to()). If null, will try to use 'to' from transport config - * @param string|null $subject String of subject or null to use 'subject' from transport config - * @param string|array|null $message String with message or array with variables to be used in render - * @param string|array $transportConfig String to use config from EmailConfig or array with configs - * @param bool $send Send the email or just return the instance pre-configured - * @return static Instance of Cake\Mailer\Email - * @throws \InvalidArgumentException - */ - public static function deliver($to = null, $subject = null, $message = null, $transportConfig = 'default', $send = true) - { - $class = __CLASS__; - - if (is_array($transportConfig) && !isset($transportConfig['transport'])) { - $transportConfig['transport'] = 'default'; - } - /* @var \Cake\Mailer\Email $instance */ - $instance = new $class($transportConfig); - if ($to !== null) { - $instance->setTo($to); - } - if ($subject !== null) { - $instance->setSubject($subject); - } - if (is_array($message)) { - $instance->setViewVars($message); - $message = null; - } elseif ($message === null && array_key_exists('message', $config = $instance->getProfile())) { - $message = $config['message']; - } - - if ($send === true) { - $instance->send($message); - } - - return $instance; - } - - /** - * Apply the config to an instance - * - * @param string|array $config Configuration options. - * @return void - * @throws \InvalidArgumentException When using a configuration that doesn't exist. - */ - protected function _applyConfig($config) - { - if (is_string($config)) { - $name = $config; - $config = static::getConfig($name); - if (empty($config)) { - throw new InvalidArgumentException(sprintf('Unknown email configuration "%s".', $name)); - } - unset($name); - } - - $this->_profile = array_merge($this->_profile, $config); - - $simpleMethods = [ - 'from', 'sender', 'to', 'replyTo', 'readReceipt', 'returnPath', - 'cc', 'bcc', 'messageId', 'domain', 'subject', 'attachments', - 'transport', 'emailFormat', 'emailPattern', 'charset', 'headerCharset' - ]; - foreach ($simpleMethods as $method) { - if (isset($config[$method])) { - $this->{'set' . ucfirst($method)}($config[$method]); - } - } - - if (empty($this->headerCharset)) { - $this->headerCharset = $this->charset; - } - if (isset($config['headers'])) { - $this->setHeaders($config['headers']); - } - - $viewBuilderMethods = [ - 'template', 'layout', 'theme' - ]; - foreach ($viewBuilderMethods as $method) { - if (array_key_exists($method, $config)) { - $this->viewBuilder()->{'set' . ucfirst($method)}($config[$method]); - } - } - - if (array_key_exists('helpers', $config)) { - $this->viewBuilder()->setHelpers($config['helpers'], false); - } - if (array_key_exists('viewRender', $config)) { - $this->viewBuilder()->setClassName($config['viewRender']); - } - if (array_key_exists('viewVars', $config)) { - $this->set($config['viewVars']); - } - } - - /** - * Reset all the internal variables to be able to send out a new email. - * - * @return $this - */ - public function reset() - { - $this->_to = []; - $this->_from = []; - $this->_sender = []; - $this->_replyTo = []; - $this->_readReceipt = []; - $this->_returnPath = []; - $this->_cc = []; - $this->_bcc = []; - $this->_messageId = true; - $this->_subject = ''; - $this->_headers = []; - $this->_textMessage = ''; - $this->_htmlMessage = ''; - $this->_message = []; - $this->_emailFormat = 'text'; - $this->_transport = null; - $this->_priority = null; - $this->charset = 'utf-8'; - $this->headerCharset = null; - $this->transferEncoding = null; - $this->_attachments = []; - $this->_profile = []; - $this->_emailPattern = self::EMAIL_PATTERN; - - $this->viewBuilder()->setLayout('default'); - $this->viewBuilder()->setTemplate(''); - $this->viewBuilder()->setClassName('Cake\View\View'); - $this->viewVars = []; - $this->viewBuilder()->setTheme(false); - $this->viewBuilder()->setHelpers(['Html'], false); - - return $this; - } - - /** - * Encode the specified string using the current charset - * - * @param string $text String to encode - * @return string Encoded string - */ - protected function _encode($text) - { - $restore = mb_internal_encoding(); - mb_internal_encoding($this->_appCharset); - if (empty($this->headerCharset)) { - $this->headerCharset = $this->charset; - } - $return = mb_encode_mimeheader($text, $this->headerCharset, 'B'); - mb_internal_encoding($restore); - - return $return; - } - - /** - * Decode the specified string - * - * @param string $text String to decode - * @return string Decoded string - */ - protected function _decode($text) - { - $restore = mb_internal_encoding(); - mb_internal_encoding($this->_appCharset); - $return = mb_decode_mimeheader($text); - mb_internal_encoding($restore); - - return $return; - } - - /** - * Translates a string for one charset to another if the App.encoding value - * differs and the mb_convert_encoding function exists - * - * @param string $text The text to be converted - * @param string $charset the target encoding - * @return string - */ - protected function _encodeString($text, $charset) - { - if ($this->_appCharset === $charset) { - return $text; - } - - return mb_convert_encoding($text, $charset, $this->_appCharset); - } - - /** - * Wrap the message to follow the RFC 2822 - 2.1.1 - * - * @param string $message Message to wrap - * @param int $wrapLength The line length - * @return array Wrapped message - */ - protected function _wrap($message, $wrapLength = Email::LINE_LENGTH_MUST) - { - if (strlen($message) === 0) { - return ['']; - } - $message = str_replace(["\r\n", "\r"], "\n", $message); - $lines = explode("\n", $message); - $formatted = []; - $cut = ($wrapLength == Email::LINE_LENGTH_MUST); - - foreach ($lines as $line) { - if (empty($line) && $line !== '0') { - $formatted[] = ''; - continue; - } - if (strlen($line) < $wrapLength) { - $formatted[] = $line; - continue; - } - if (!preg_match('/<[a-z]+.*>/i', $line)) { - $formatted = array_merge( - $formatted, - explode("\n", wordwrap($line, $wrapLength, "\n", $cut)) - ); - continue; - } - - $tagOpen = false; - $tmpLine = $tag = ''; - $tmpLineLength = 0; - for ($i = 0, $count = strlen($line); $i < $count; $i++) { - $char = $line[$i]; - if ($tagOpen) { - $tag .= $char; - if ($char === '>') { - $tagLength = strlen($tag); - if ($tagLength + $tmpLineLength < $wrapLength) { - $tmpLine .= $tag; - $tmpLineLength += $tagLength; - } else { - if ($tmpLineLength > 0) { - $formatted = array_merge( - $formatted, - explode("\n", wordwrap(trim($tmpLine), $wrapLength, "\n", $cut)) - ); - $tmpLine = ''; - $tmpLineLength = 0; - } - if ($tagLength > $wrapLength) { - $formatted[] = $tag; - } else { - $tmpLine = $tag; - $tmpLineLength = $tagLength; - } - } - $tag = ''; - $tagOpen = false; - } - continue; - } - if ($char === '<') { - $tagOpen = true; - $tag = '<'; - continue; - } - if ($char === ' ' && $tmpLineLength >= $wrapLength) { - $formatted[] = $tmpLine; - $tmpLineLength = 0; - continue; - } - $tmpLine .= $char; - $tmpLineLength++; - if ($tmpLineLength === $wrapLength) { - $nextChar = $line[$i + 1]; - if ($nextChar === ' ' || $nextChar === '<') { - $formatted[] = trim($tmpLine); - $tmpLine = ''; - $tmpLineLength = 0; - if ($nextChar === ' ') { - $i++; - } - } else { - $lastSpace = strrpos($tmpLine, ' '); - if ($lastSpace === false) { - continue; - } - $formatted[] = trim(substr($tmpLine, 0, $lastSpace)); - $tmpLine = substr($tmpLine, $lastSpace + 1); - - $tmpLineLength = strlen($tmpLine); - } - } - } - if (!empty($tmpLine)) { - $formatted[] = $tmpLine; - } - } - $formatted[] = ''; - - return $formatted; - } - - /** - * Create unique boundary identifier - * - * @return void - */ - protected function _createBoundary() - { - if ($this->_attachments || $this->_emailFormat === 'both') { - $this->_boundary = md5(Security::randomBytes(16)); - } - } - - /** - * Attach non-embedded files by adding file contents inside boundaries. - * - * @param string|null $boundary Boundary to use. If null, will default to $this->_boundary - * @return array An array of lines to add to the message - */ - protected function _attachFiles($boundary = null) - { - if ($boundary === null) { - $boundary = $this->_boundary; - } - - $msg = []; - foreach ($this->_attachments as $filename => $fileInfo) { - if (!empty($fileInfo['contentId'])) { - continue; - } - $data = isset($fileInfo['data']) ? $fileInfo['data'] : $this->_readFile($fileInfo['file']); - $hasDisposition = ( - !isset($fileInfo['contentDisposition']) || - $fileInfo['contentDisposition'] - ); - $part = new FormDataPart(false, $data, false); - - if ($hasDisposition) { - $part->disposition('attachment'); - $part->filename($filename); - } - $part->transferEncoding('base64'); - $part->type($fileInfo['mimetype']); - - $msg[] = '--' . $boundary; - $msg[] = (string)$part; - $msg[] = ''; - } - - return $msg; - } - - /** - * Read the file contents and return a base64 version of the file contents. - * - * @param string $path The absolute path to the file to read. - * @return string File contents in base64 encoding - */ - protected function _readFile($path) - { - $File = new File($path); - - return chunk_split(base64_encode($File->read())); - } - - /** - * Attach inline/embedded files to the message. - * - * @param string|null $boundary Boundary to use. If null, will default to $this->_boundary - * @return array An array of lines to add to the message - */ - protected function _attachInlineFiles($boundary = null) - { - if ($boundary === null) { - $boundary = $this->_boundary; - } - - $msg = []; - foreach ($this->_attachments as $filename => $fileInfo) { - if (empty($fileInfo['contentId'])) { - continue; - } - $data = isset($fileInfo['data']) ? $fileInfo['data'] : $this->_readFile($fileInfo['file']); - - $msg[] = '--' . $boundary; - $part = new FormDataPart(false, $data, 'inline'); - $part->type($fileInfo['mimetype']); - $part->transferEncoding('base64'); - $part->contentId($fileInfo['contentId']); - $part->filename($filename); - $msg[] = (string)$part; - $msg[] = ''; - } - - return $msg; - } - - /** - * Render the body of the email. - * - * @param array $content Content to render - * @return array Email body ready to be sent - */ - protected function _render($content) - { - $this->_textMessage = $this->_htmlMessage = ''; - - $content = implode("\n", $content); - $rendered = $this->_renderTemplates($content); - - $this->_createBoundary(); - $msg = []; - - $contentIds = array_filter((array)Hash::extract($this->_attachments, '{s}.contentId')); - $hasInlineAttachments = count($contentIds) > 0; - $hasAttachments = !empty($this->_attachments); - $hasMultipleTypes = count($rendered) > 1; - $multiPart = ($hasAttachments || $hasMultipleTypes); - - $boundary = $relBoundary = $textBoundary = $this->_boundary; - - if ($hasInlineAttachments) { - $msg[] = '--' . $boundary; - $msg[] = 'Content-Type: multipart/related; boundary="rel-' . $boundary . '"'; - $msg[] = ''; - $relBoundary = $textBoundary = 'rel-' . $boundary; - } - - if ($hasMultipleTypes && $hasAttachments) { - $msg[] = '--' . $relBoundary; - $msg[] = 'Content-Type: multipart/alternative; boundary="alt-' . $boundary . '"'; - $msg[] = ''; - $textBoundary = 'alt-' . $boundary; - } - - if (isset($rendered['text'])) { - if ($multiPart) { - $msg[] = '--' . $textBoundary; - $msg[] = 'Content-Type: text/plain; charset=' . $this->_getContentTypeCharset(); - $msg[] = 'Content-Transfer-Encoding: ' . $this->_getContentTransferEncoding(); - $msg[] = ''; - } - $this->_textMessage = $rendered['text']; - $content = explode("\n", $this->_textMessage); - $msg = array_merge($msg, $content); - $msg[] = ''; - } - - if (isset($rendered['html'])) { - if ($multiPart) { - $msg[] = '--' . $textBoundary; - $msg[] = 'Content-Type: text/html; charset=' . $this->_getContentTypeCharset(); - $msg[] = 'Content-Transfer-Encoding: ' . $this->_getContentTransferEncoding(); - $msg[] = ''; - } - $this->_htmlMessage = $rendered['html']; - $content = explode("\n", $this->_htmlMessage); - $msg = array_merge($msg, $content); - $msg[] = ''; - } - - if ($textBoundary !== $relBoundary) { - $msg[] = '--' . $textBoundary . '--'; - $msg[] = ''; - } - - if ($hasInlineAttachments) { - $attachments = $this->_attachInlineFiles($relBoundary); - $msg = array_merge($msg, $attachments); - $msg[] = ''; - $msg[] = '--' . $relBoundary . '--'; - $msg[] = ''; - } - - if ($hasAttachments) { - $attachments = $this->_attachFiles($boundary); - $msg = array_merge($msg, $attachments); - } - if ($hasAttachments || $hasMultipleTypes) { - $msg[] = ''; - $msg[] = '--' . $boundary . '--'; - $msg[] = ''; - } - - return $msg; - } - - /** - * Gets the text body types that are in this email message - * - * @return array Array of types. Valid types are 'text' and 'html' - */ - protected function _getTypes() - { - $types = [$this->_emailFormat]; - if ($this->_emailFormat === 'both') { - $types = ['html', 'text']; - } - - return $types; - } - - /** - * Build and set all the view properties needed to render the templated emails. - * If there is no template set, the $content will be returned in a hash - * of the text content types for the email. - * - * @param string $content The content passed in from send() in most cases. - * @return array The rendered content with html and text keys. - */ - protected function _renderTemplates($content) - { - $types = $this->_getTypes(); - $rendered = []; - $template = $this->viewBuilder()->getTemplate(); - if (empty($template)) { - foreach ($types as $type) { - $rendered[$type] = $this->_encodeString($content, $this->charset); - } - - return $rendered; - } - - $View = $this->createView(); - - list($templatePlugin) = pluginSplit($View->getTemplate()); - list($layoutPlugin) = pluginSplit($View->getLayout()); - if ($templatePlugin) { - $View->plugin = $templatePlugin; - } elseif ($layoutPlugin) { - $View->plugin = $layoutPlugin; - } - - if ($View->get('content') === null) { - $View->set('content', $content); - } - - foreach ($types as $type) { - $View->hasRendered = false; - $View->setTemplatePath('Email' . DIRECTORY_SEPARATOR . $type); - $View->setLayoutPath('Email' . DIRECTORY_SEPARATOR . $type); - - $render = $View->render(); - $render = str_replace(["\r\n", "\r"], "\n", $render); - $rendered[$type] = $this->_encodeString($render, $this->charset); - } - - foreach ($rendered as $type => $content) { - $rendered[$type] = $this->_wrap($content); - $rendered[$type] = implode("\n", $rendered[$type]); - $rendered[$type] = rtrim($rendered[$type], "\n"); - } - - return $rendered; - } - - /** - * Return the Content-Transfer Encoding value based - * on the set transferEncoding or set charset. - * - * @return string - */ - protected function _getContentTransferEncoding() - { - if ($this->transferEncoding) { - return $this->transferEncoding; - } - - $charset = strtoupper($this->charset); - if (in_array($charset, $this->_charset8bit)) { - return '8bit'; - } - - return '7bit'; - } - - /** - * Return charset value for Content-Type. - * - * Checks fallback/compatibility types which include workarounds - * for legacy japanese character sets. - * - * @return string - */ - protected function _getContentTypeCharset() - { - $charset = strtoupper($this->charset); - if (array_key_exists($charset, $this->_contentTypeCharset)) { - return strtoupper($this->_contentTypeCharset[$charset]); - } - - return strtoupper($this->charset); - } - - /** - * Serializes the email object to a value that can be natively serialized and re-used - * to clone this email instance. - * - * It has certain limitations for viewVars that are good to know: - * - * - ORM\Query executed and stored as resultset - * - SimpleXMLElements stored as associative array - * - Exceptions stored as strings - * - Resources, \Closure and \PDO are not supported. - * - * @return array Serializable array of configuration properties. - * @throws \Exception When a view var object can not be properly serialized. - */ - public function jsonSerialize() - { - $properties = [ - '_to', '_from', '_sender', '_replyTo', '_cc', '_bcc', '_subject', - '_returnPath', '_readReceipt', '_emailFormat', '_emailPattern', '_domain', - '_attachments', '_messageId', '_headers', '_appCharset', 'viewVars', 'charset', 'headerCharset' - ]; - - $array = ['viewConfig' => $this->viewBuilder()->jsonSerialize()]; - - foreach ($properties as $property) { - $array[$property] = $this->{$property}; - } - - array_walk($array['_attachments'], function (&$item, $key) { - if (!empty($item['file'])) { - $item['data'] = $this->_readFile($item['file']); - unset($item['file']); - } - }); - - array_walk_recursive($array['viewVars'], [$this, '_checkViewVars']); - - return array_filter($array, function ($i) { - return !is_array($i) && strlen($i) || !empty($i); - }); - } - - /** - * Iterates through hash to clean up and normalize. - * - * @param mixed $item Reference to the view var value. - * @param string $key View var key. - * @return void - */ - protected function _checkViewVars(&$item, $key) - { - if ($item instanceof Exception) { - $item = (string)$item; - } - - if (is_resource($item) || - $item instanceof Closure || - $item instanceof PDO - ) { - throw new RuntimeException(sprintf( - 'Failed serializing the `%s` %s in the `%s` view var', - is_resource($item) ? get_resource_type($item) : get_class($item), - is_resource($item) ? 'resource' : 'object', - $key - )); - } - } - - /** - * Configures an email instance object from serialized config. - * - * @param array $config Email configuration array. - * @return $this Configured email instance. - */ - public function createFromArray($config) - { - if (isset($config['viewConfig'])) { - $this->viewBuilder()->createFromArray($config['viewConfig']); - unset($config['viewConfig']); - } - - foreach ($config as $property => $value) { - $this->{$property} = $value; - } - - return $this; - } - - /** - * Serializes the Email object. - * - * @return string - */ - public function serialize() - { - $array = $this->jsonSerialize(); - array_walk_recursive($array, function (&$item, $key) { - if ($item instanceof SimpleXMLElement) { - $item = json_decode(json_encode((array)$item), true); - } - }); - - return serialize($array); - } - - /** - * Unserializes the Email object. - * - * @param string $data Serialized string. - * @return static Configured email instance. - */ - public function unserialize($data) - { - return $this->createFromArray(unserialize($data)); - } -} diff --git a/vendor/cakephp/cakephp/src/Mailer/Exception/MissingActionException.php b/vendor/cakephp/cakephp/src/Mailer/Exception/MissingActionException.php deleted file mode 100644 index d1a9734..0000000 --- a/vendor/cakephp/cakephp/src/Mailer/Exception/MissingActionException.php +++ /dev/null @@ -1,32 +0,0 @@ -setSubject('Reset Password') - * ->setTo($user->email) - * ->set(['token' => $user->token]); - * } - * } - * ``` - * - * Is a trivial example but shows how a mailer could be declared. - * - * ## Sending Messages - * - * After you have defined some messages you will want to send them: - * - * ``` - * $mailer = new UserMailer(); - * $mailer->send('resetPassword', $user); - * ``` - * - * ## Event Listener - * - * Mailers can also subscribe to application event allowing you to - * decouple email delivery from your application code. By re-declaring the - * `implementedEvents()` method you can define event handlers that can - * convert events into email. For example, if your application had a user - * registration event: - * - * ``` - * public function implementedEvents() - * { - * return [ - * 'Model.afterSave' => 'onRegistration', - * ]; - * } - * - * public function onRegistration(Event $event, Entity $entity, ArrayObject $options) - * { - * if ($entity->isNew()) { - * $this->send('welcome', [$entity]); - * } - * } - * ``` - * - * The onRegistration method converts the application event into a mailer method. - * Our mailer could either be registered in the application bootstrap, or - * in the Table class' initialize() hook. - * - * @method \Cake\Mailer\Email setTo($email, $name = null) - * @method array getTo() - * @method \Cake\Mailer\Email to($email = null, $name = null) - * @method \Cake\Mailer\Email setFrom($email, $name = null) - * @method array getFrom() - * @method \Cake\Mailer\Email from($email = null, $name = null) - * @method \Cake\Mailer\Email setSender($email, $name = null) - * @method array getSender() - * @method \Cake\Mailer\Email sender($email = null, $name = null) - * @method \Cake\Mailer\Email setReplyTo($email, $name = null) - * @method array getReplyTo() - * @method \Cake\Mailer\Email replyTo($email = null, $name = null) - * @method \Cake\Mailer\Email setReadReceipt($email, $name = null) - * @method array getReadReceipt() - * @method \Cake\Mailer\Email readReceipt($email = null, $name = null) - * @method \Cake\Mailer\Email setReturnPath($email, $name = null) - * @method array getReturnPath() - * @method \Cake\Mailer\Email returnPath($email = null, $name = null) - * @method \Cake\Mailer\Email addTo($email, $name = null) - * @method \Cake\Mailer\Email setCc($email, $name = null) - * @method array getCc() - * @method \Cake\Mailer\Email cc($email = null, $name = null) - * @method \Cake\Mailer\Email addCc($email, $name = null) - * @method \Cake\Mailer\Email setBcc($email, $name = null) - * @method array getBcc() - * @method \Cake\Mailer\Email bcc($email = null, $name = null) - * @method \Cake\Mailer\Email addBcc($email, $name = null) - * @method \Cake\Mailer\Email setCharset($charset) - * @method string getCharset() - * @method \Cake\Mailer\Email charset($charset = null) - * @method \Cake\Mailer\Email setHeaderCharset($charset) - * @method string getHeaderCharset() - * @method \Cake\Mailer\Email headerCharset($charset = null) - * @method \Cake\Mailer\Email setSubject($subject) - * @method string getSubject() - * @method \Cake\Mailer\Email subject($subject = null) - * @method \Cake\Mailer\Email setHeaders(array $headers) - * @method \Cake\Mailer\Email addHeaders(array $headers) - * @method \Cake\Mailer\Email getHeaders(array $include = []) - * @method \Cake\Mailer\Email setTemplate($template) - * @method string getTemplate() - * @method \Cake\Mailer\Email setLayout($layout) - * @method string getLayout() - * @method \Cake\Mailer\Email template($template = false, $layout = false) - * @method \Cake\Mailer\Email setViewRenderer($viewClass) - * @method string getViewRenderer() - * @method \Cake\Mailer\Email viewRender($viewClass = null) - * @method \Cake\Mailer\Email setViewVars($viewVars) - * @method array getViewVars() - * @method \Cake\Mailer\Email viewVars($viewVars = null) - * @method \Cake\Mailer\Email setTheme($theme) - * @method string getTheme() - * @method \Cake\Mailer\Email theme($theme = null) - * @method \Cake\Mailer\Email setHelpers(array $helpers) - * @method array getHelpers() - * @method \Cake\Mailer\Email helpers($helpers = null) - * @method \Cake\Mailer\Email setEmailFormat($format) - * @method string getEmailFormat() - * @method \Cake\Mailer\Email emailFormat($format = null) - * @method \Cake\Mailer\Email setTransport($name) - * @method \Cake\Mailer\AbstractTransport getTransport() - * @method \Cake\Mailer\Email transport($name = null) - * @method \Cake\Mailer\Email setMessageId($message) - * @method bool|string getMessageId() - * @method \Cake\Mailer\Email messageId($message = null) - * @method \Cake\Mailer\Email setDomain($domain) - * @method string getDomain() - * @method \Cake\Mailer\Email domain($domain = null) - * @method \Cake\Mailer\Email setAttachments($attachments) - * @method array getAttachments() - * @method \Cake\Mailer\Email attachments($attachments = null) - * @method \Cake\Mailer\Email addAttachments($attachments) - * @method \Cake\Mailer\Email message($type = null) - * @method \Cake\Mailer\Email setProfile($config) - * @method string|array getProfile() - * @method \Cake\Mailer\Email profile($config = null) - */ -abstract class Mailer implements EventListenerInterface -{ - - use ModelAwareTrait; - - /** - * Mailer's name. - * - * @var string - */ - static public $name; - - /** - * Email instance. - * - * @var \Cake\Mailer\Email - */ - protected $_email; - - /** - * Cloned Email instance for restoring instance after email is sent by - * mailer action. - * - * @var \Cake\Mailer\Email - */ - protected $_clonedEmail; - - /** - * Constructor. - * - * @param \Cake\Mailer\Email|null $email Email instance. - */ - public function __construct(Email $email = null) - { - if ($email === null) { - $email = new Email(); - } - - $this->_email = $email; - $this->_clonedEmail = clone $email; - } - - /** - * Returns the mailer's name. - * - * @return string - */ - public function getName() - { - if (!static::$name) { - static::$name = str_replace( - 'Mailer', - '', - implode('', array_slice(explode('\\', get_class($this)), -1)) - ); - } - - return static::$name; - } - - /** - * Sets layout to use. - * - * @deprecated 3.4.0 Use setLayout() which sets the layout on the email class instead. - * @param string $layout Name of the layout to use. - * @return $this - */ - public function layout($layout) - { - deprecationWarning('Mailer::layout() is deprecated. Use setLayout() which sets the layout on the email class instead.'); - - $this->_email->viewBuilder()->setLayout($layout); - - return $this; - } - - /** - * Get Email instance's view builder. - * - * @return \Cake\View\ViewBuilder - */ - public function viewBuilder() - { - return $this->_email->viewBuilder(); - } - - /** - * Magic method to forward method class to Email instance. - * - * @param string $method Method name. - * @param array $args Method arguments - * @return $this|mixed - */ - public function __call($method, $args) - { - $result = $this->_email->$method(...$args); - if (strpos($method, 'get') === 0) { - return $result; - } - - return $this; - } - - /** - * Sets email view vars. - * - * @param string|array $key Variable name or hash of view variables. - * @param mixed $value View variable value. - * @return $this - */ - public function set($key, $value = null) - { - $this->_email->setViewVars(is_string($key) ? [$key => $value] : $key); - - return $this; - } - - /** - * Sends email. - * - * @param string $action The name of the mailer action to trigger. - * @param array $args Arguments to pass to the triggered mailer action. - * @param array $headers Headers to set. - * @return array - * @throws \Cake\Mailer\Exception\MissingActionException - * @throws \BadMethodCallException - */ - public function send($action, $args = [], $headers = []) - { - try { - if (!method_exists($this, $action)) { - throw new MissingActionException([ - 'mailer' => $this->getName() . 'Mailer', - 'action' => $action, - ]); - } - - $this->_email->setHeaders($headers); - if (!$this->_email->viewBuilder()->getTemplate()) { - $this->_email->viewBuilder()->setTemplate($action); - } - - $this->$action(...$args); - - $result = $this->_email->send(); - } finally { - $this->reset(); - } - - return $result; - } - - /** - * Reset email instance. - * - * @return $this - */ - protected function reset() - { - $this->_email = clone $this->_clonedEmail; - - return $this; - } - - /** - * Implemented events. - * - * @return array - */ - public function implementedEvents() - { - return []; - } -} diff --git a/vendor/cakephp/cakephp/src/Mailer/MailerAwareTrait.php b/vendor/cakephp/cakephp/src/Mailer/MailerAwareTrait.php deleted file mode 100644 index 8b98f50..0000000 --- a/vendor/cakephp/cakephp/src/Mailer/MailerAwareTrait.php +++ /dev/null @@ -1,52 +0,0 @@ -getHeaders(['from', 'sender', 'replyTo', 'readReceipt', 'returnPath', 'to', 'cc', 'subject']); - $headers = $this->_headersToString($headers); - $message = implode("\r\n", (array)$email->message()); - - return ['headers' => $headers, 'message' => $message]; - } -} diff --git a/vendor/cakephp/cakephp/src/Mailer/Transport/MailTransport.php b/vendor/cakephp/cakephp/src/Mailer/Transport/MailTransport.php deleted file mode 100644 index 885eff6..0000000 --- a/vendor/cakephp/cakephp/src/Mailer/Transport/MailTransport.php +++ /dev/null @@ -1,83 +0,0 @@ -_config['eol'])) { - $eol = $this->_config['eol']; - } - $headers = $email->getHeaders(['from', 'sender', 'replyTo', 'readReceipt', 'returnPath', 'to', 'cc', 'bcc']); - $to = $headers['To']; - unset($headers['To']); - foreach ($headers as $key => $header) { - $headers[$key] = str_replace(["\r", "\n"], '', $header); - } - $headers = $this->_headersToString($headers, $eol); - $subject = str_replace(["\r", "\n"], '', $email->getSubject()); - $to = str_replace(["\r", "\n"], '', $to); - - $message = implode($eol, $email->message()); - - $params = isset($this->_config['additionalParameters']) ? $this->_config['additionalParameters'] : null; - $this->_mail($to, $subject, $message, $headers, $params); - - $headers .= $eol . 'To: ' . $to; - $headers .= $eol . 'Subject: ' . $subject; - - return ['headers' => $headers, 'message' => $message]; - } - - /** - * Wraps internal function mail() and throws exception instead of errors if anything goes wrong - * - * @param string $to email's recipient - * @param string $subject email's subject - * @param string $message email's body - * @param string $headers email's custom headers - * @param string|null $params additional params for sending email - * @throws \Cake\Network\Exception\SocketException if mail could not be sent - * @return void - */ - protected function _mail($to, $subject, $message, $headers, $params = null) - { - //@codingStandardsIgnoreStart - if (!@mail($to, $subject, $message, $headers, $params)) { - $error = error_get_last(); - $msg = 'Could not send email: ' . (isset($error['message']) ? $error['message'] : 'unknown'); - throw new SocketException($msg); - } - //@codingStandardsIgnoreEnd - } -} diff --git a/vendor/cakephp/cakephp/src/Mailer/Transport/SmtpTransport.php b/vendor/cakephp/cakephp/src/Mailer/Transport/SmtpTransport.php deleted file mode 100644 index ed0a36e..0000000 --- a/vendor/cakephp/cakephp/src/Mailer/Transport/SmtpTransport.php +++ /dev/null @@ -1,460 +0,0 @@ - 'localhost', - 'port' => 25, - 'timeout' => 30, - 'username' => null, - 'password' => null, - 'client' => null, - 'tls' => false, - 'keepAlive' => false - ]; - - /** - * Socket to SMTP server - * - * @var \Cake\Network\Socket - */ - protected $_socket; - - /** - * Content of email to return - * - * @var array - */ - protected $_content = []; - - /** - * The response of the last sent SMTP command. - * - * @var array - */ - protected $_lastResponse = []; - - /** - * Destructor - * - * Tries to disconnect to ensure that the connection is being - * terminated properly before the socket gets closed. - */ - public function __destruct() - { - try { - $this->disconnect(); - } catch (Exception $e) { - // avoid fatal error on script termination - } - } - - /** - * Connect to the SMTP server. - * - * This method tries to connect only in case there is no open - * connection available already. - * - * @return void - */ - public function connect() - { - if (!$this->connected()) { - $this->_connect(); - $this->_auth(); - } - } - - /** - * Check whether an open connection to the SMTP server is available. - * - * @return bool - */ - public function connected() - { - return $this->_socket !== null && $this->_socket->connected; - } - - /** - * Disconnect from the SMTP server. - * - * This method tries to disconnect only in case there is an open - * connection available. - * - * @return void - */ - public function disconnect() - { - if ($this->connected()) { - $this->_disconnect(); - } - } - - /** - * Returns the response of the last sent SMTP command. - * - * A response consists of one or more lines containing a response - * code and an optional response message text: - * ``` - * [ - * [ - * 'code' => '250', - * 'message' => 'mail.example.com' - * ], - * [ - * 'code' => '250', - * 'message' => 'PIPELINING' - * ], - * [ - * 'code' => '250', - * 'message' => '8BITMIME' - * ], - * // etc... - * ] - * ``` - * - * @return array - */ - public function getLastResponse() - { - return $this->_lastResponse; - } - - /** - * Send mail - * - * @param \Cake\Mailer\Email $email Email instance - * @return array - * @throws \Cake\Network\Exception\SocketException - */ - public function send(Email $email) - { - if (!$this->connected()) { - $this->_connect(); - $this->_auth(); - } else { - $this->_smtpSend('RSET'); - } - - $this->_sendRcpt($email); - $this->_sendData($email); - - if (!$this->_config['keepAlive']) { - $this->_disconnect(); - } - - return $this->_content; - } - - /** - * Parses and stores the response lines in `'code' => 'message'` format. - * - * @param array $responseLines Response lines to parse. - * @return void - */ - protected function _bufferResponseLines(array $responseLines) - { - $response = []; - foreach ($responseLines as $responseLine) { - if (preg_match('/^(\d{3})(?:[ -]+(.*))?$/', $responseLine, $match)) { - $response[] = [ - 'code' => $match[1], - 'message' => isset($match[2]) ? $match[2] : null - ]; - } - } - $this->_lastResponse = array_merge($this->_lastResponse, $response); - } - - /** - * Connect to SMTP Server - * - * @return void - * @throws \Cake\Network\Exception\SocketException - */ - protected function _connect() - { - $this->_generateSocket(); - if (!$this->_socket->connect()) { - throw new SocketException('Unable to connect to SMTP server.'); - } - $this->_smtpSend(null, '220'); - - $config = $this->_config; - - if (isset($config['client'])) { - $host = $config['client']; - } elseif ($httpHost = env('HTTP_HOST')) { - list($host) = explode(':', $httpHost); - } else { - $host = 'localhost'; - } - - try { - $this->_smtpSend("EHLO {$host}", '250'); - if ($config['tls']) { - $this->_smtpSend('STARTTLS', '220'); - $this->_socket->enableCrypto('tls'); - $this->_smtpSend("EHLO {$host}", '250'); - } - } catch (SocketException $e) { - if ($config['tls']) { - throw new SocketException('SMTP server did not accept the connection or trying to connect to non TLS SMTP server using TLS.', null, $e); - } - try { - $this->_smtpSend("HELO {$host}", '250'); - } catch (SocketException $e2) { - throw new SocketException('SMTP server did not accept the connection.', null, $e2); - } - } - } - - /** - * Send authentication - * - * @return void - * @throws \Cake\Network\Exception\SocketException - */ - protected function _auth() - { - if (isset($this->_config['username'], $this->_config['password'])) { - $replyCode = (string)$this->_smtpSend('AUTH LOGIN', '334|500|502|504'); - if ($replyCode === '334') { - try { - $this->_smtpSend(base64_encode($this->_config['username']), '334'); - } catch (SocketException $e) { - throw new SocketException('SMTP server did not accept the username.', null, $e); - } - try { - $this->_smtpSend(base64_encode($this->_config['password']), '235'); - } catch (SocketException $e) { - throw new SocketException('SMTP server did not accept the password.', null, $e); - } - } elseif ($replyCode === '504') { - throw new SocketException('SMTP authentication method not allowed, check if SMTP server requires TLS.'); - } else { - throw new SocketException('AUTH command not recognized or not implemented, SMTP server may not require authentication.'); - } - } - } - - /** - * Prepares the `MAIL FROM` SMTP command. - * - * @param string $email The email address to send with the command. - * @return string - */ - protected function _prepareFromCmd($email) - { - return 'MAIL FROM:<' . $email . '>'; - } - - /** - * Prepares the `RCPT TO` SMTP command. - * - * @param string $email The email address to send with the command. - * @return string - */ - protected function _prepareRcptCmd($email) - { - return 'RCPT TO:<' . $email . '>'; - } - - /** - * Prepares the `from` email address. - * - * @param \Cake\Mailer\Email $email Email instance - * @return array - */ - protected function _prepareFromAddress($email) - { - $from = $email->getReturnPath(); - if (empty($from)) { - $from = $email->getFrom(); - } - - return $from; - } - - /** - * Prepares the recipient email addresses. - * - * @param \Cake\Mailer\Email $email Email instance - * @return array - */ - protected function _prepareRecipientAddresses($email) - { - $to = $email->getTo(); - $cc = $email->getCc(); - $bcc = $email->getBcc(); - - return array_merge(array_keys($to), array_keys($cc), array_keys($bcc)); - } - - /** - * Prepares the message headers. - * - * @param \Cake\Mailer\Email $email Email instance - * @return array - */ - protected function _prepareMessageHeaders($email) - { - return $email->getHeaders(['from', 'sender', 'replyTo', 'readReceipt', 'to', 'cc', 'subject', 'returnPath']); - } - - /** - * Prepares the message body. - * - * @param \Cake\Mailer\Email $email Email instance - * @return string - */ - protected function _prepareMessage($email) - { - $lines = $email->message(); - $messages = []; - foreach ($lines as $line) { - if ((!empty($line)) && ($line[0] === '.')) { - $messages[] = '.' . $line; - } else { - $messages[] = $line; - } - } - - return implode("\r\n", $messages); - } - - /** - * Send emails - * - * @return void - * @param \Cake\Mailer\Email $email Cake Email - * @throws \Cake\Network\Exception\SocketException - */ - protected function _sendRcpt($email) - { - $from = $this->_prepareFromAddress($email); - $this->_smtpSend($this->_prepareFromCmd(key($from))); - - $emails = $this->_prepareRecipientAddresses($email); - foreach ($emails as $mail) { - $this->_smtpSend($this->_prepareRcptCmd($mail)); - } - } - - /** - * Send Data - * - * @param \Cake\Mailer\Email $email Email instance - * @return void - * @throws \Cake\Network\Exception\SocketException - */ - protected function _sendData($email) - { - $this->_smtpSend('DATA', '354'); - - $headers = $this->_headersToString($this->_prepareMessageHeaders($email)); - $message = $this->_prepareMessage($email); - - $this->_smtpSend($headers . "\r\n\r\n" . $message . "\r\n\r\n\r\n."); - $this->_content = ['headers' => $headers, 'message' => $message]; - } - - /** - * Disconnect - * - * @return void - * @throws \Cake\Network\Exception\SocketException - */ - protected function _disconnect() - { - $this->_smtpSend('QUIT', false); - $this->_socket->disconnect(); - } - - /** - * Helper method to generate socket - * - * @return void - * @throws \Cake\Network\Exception\SocketException - */ - protected function _generateSocket() - { - $this->_socket = new Socket($this->_config); - } - - /** - * Protected method for sending data to SMTP connection - * - * @param string|null $data Data to be sent to SMTP server - * @param string|bool $checkCode Code to check for in server response, false to skip - * @return string|null The matched code, or null if nothing matched - * @throws \Cake\Network\Exception\SocketException - */ - protected function _smtpSend($data, $checkCode = '250') - { - $this->_lastResponse = []; - - if ($data !== null) { - $this->_socket->write($data . "\r\n"); - } - - $timeout = $this->_config['timeout']; - - while ($checkCode !== false) { - $response = ''; - $startTime = time(); - while (substr($response, -2) !== "\r\n" && ((time() - $startTime) < $timeout)) { - $bytes = $this->_socket->read(); - if ($bytes === false || $bytes === null) { - break; - } - $response .= $bytes; - } - if (substr($response, -2) !== "\r\n") { - throw new SocketException('SMTP timeout.'); - } - $responseLines = explode("\r\n", rtrim($response, "\r\n")); - $response = end($responseLines); - - $this->_bufferResponseLines($responseLines); - - if (preg_match('/^(' . $checkCode . ')(.)/', $response, $code)) { - if ($code[2] === '-') { - continue; - } - - return $code[1]; - } - throw new SocketException(sprintf('SMTP Error: %s', $response)); - } - } -} diff --git a/vendor/cakephp/cakephp/src/Network/CorsBuilder.php b/vendor/cakephp/cakephp/src/Network/CorsBuilder.php deleted file mode 100644 index 155ac80..0000000 --- a/vendor/cakephp/cakephp/src/Network/CorsBuilder.php +++ /dev/null @@ -1,4 +0,0 @@ - false, - 'host' => 'localhost', - 'protocol' => 'tcp', - 'port' => 80, - 'timeout' => 30 - ]; - - /** - * Reference to socket connection resource - * - * @var resource|null - */ - public $connection; - - /** - * This boolean contains the current state of the Socket class - * - * @var bool - */ - public $connected = false; - - /** - * This variable contains an array with the last error number (num) and string (str) - * - * @var array - */ - public $lastError = []; - - /** - * True if the socket stream is encrypted after a Cake\Network\Socket::enableCrypto() call - * - * @var bool - */ - public $encrypted = false; - - /** - * Contains all the encryption methods available - * - * SSLv2 and SSLv3 are deprecated, and should not be used as they - * have several published vulnerablilities. - * - * @var array - */ - protected $_encryptMethods = [ - // @codingStandardsIgnoreStart - // @deprecated Will be removed in 4.0.0 - 'sslv2_client' => STREAM_CRYPTO_METHOD_SSLv2_CLIENT, - // @deprecated Will be removed in 4.0.0 - 'sslv3_client' => STREAM_CRYPTO_METHOD_SSLv3_CLIENT, - 'sslv23_client' => STREAM_CRYPTO_METHOD_SSLv23_CLIENT, - 'tls_client' => STREAM_CRYPTO_METHOD_TLS_CLIENT, - 'tlsv10_client' => STREAM_CRYPTO_METHOD_TLSv1_0_CLIENT, - 'tlsv11_client' => STREAM_CRYPTO_METHOD_TLSv1_1_CLIENT, - 'tlsv12_client' => STREAM_CRYPTO_METHOD_TLSv1_2_CLIENT, - // @deprecated Will be removed in 4.0.0 - 'sslv2_server' => STREAM_CRYPTO_METHOD_SSLv2_SERVER, - // @deprecated Will be removed in 4.0.0 - 'sslv3_server' => STREAM_CRYPTO_METHOD_SSLv3_SERVER, - 'sslv23_server' => STREAM_CRYPTO_METHOD_SSLv23_SERVER, - 'tls_server' => STREAM_CRYPTO_METHOD_TLS_SERVER, - 'tlsv10_server' => STREAM_CRYPTO_METHOD_TLSv1_0_SERVER, - 'tlsv11_server' => STREAM_CRYPTO_METHOD_TLSv1_1_SERVER, - 'tlsv12_server' => STREAM_CRYPTO_METHOD_TLSv1_2_SERVER - // @codingStandardsIgnoreEnd - ]; - - /** - * Used to capture connection warnings which can happen when there are - * SSL errors for example. - * - * @var array - */ - protected $_connectionErrors = []; - - /** - * Constructor. - * - * @param array $config Socket configuration, which will be merged with the base configuration - * @see \Cake\Network\Socket::$_baseConfig - */ - public function __construct(array $config = []) - { - $this->setConfig($config); - } - - /** - * Connect the socket to the given host and port. - * - * @return bool Success - * @throws \Cake\Network\Exception\SocketException - */ - public function connect() - { - if ($this->connection) { - $this->disconnect(); - } - - $hasProtocol = strpos($this->_config['host'], '://') !== false; - if ($hasProtocol) { - list($this->_config['protocol'], $this->_config['host']) = explode('://', $this->_config['host']); - } - $scheme = null; - if (!empty($this->_config['protocol'])) { - $scheme = $this->_config['protocol'] . '://'; - } - - $this->_setSslContext($this->_config['host']); - if (!empty($this->_config['context'])) { - $context = stream_context_create($this->_config['context']); - } else { - $context = stream_context_create(); - } - - $connectAs = STREAM_CLIENT_CONNECT; - if ($this->_config['persistent']) { - $connectAs |= STREAM_CLIENT_PERSISTENT; - } - - set_error_handler([$this, '_connectionErrorHandler']); - $this->connection = stream_socket_client( - $scheme . $this->_config['host'] . ':' . $this->_config['port'], - $errNum, - $errStr, - $this->_config['timeout'], - $connectAs, - $context - ); - restore_error_handler(); - - if (!empty($errNum) || !empty($errStr)) { - $this->setLastError($errNum, $errStr); - throw new SocketException($errStr, $errNum); - } - - if (!$this->connection && $this->_connectionErrors) { - $message = implode("\n", $this->_connectionErrors); - throw new SocketException($message, E_WARNING); - } - - $this->connected = is_resource($this->connection); - if ($this->connected) { - stream_set_timeout($this->connection, $this->_config['timeout']); - } - - return $this->connected; - } - - /** - * Configure the SSL context options. - * - * @param string $host The host name being connected to. - * @return void - */ - protected function _setSslContext($host) - { - foreach ($this->_config as $key => $value) { - if (substr($key, 0, 4) !== 'ssl_') { - continue; - } - $contextKey = substr($key, 4); - if (empty($this->_config['context']['ssl'][$contextKey])) { - $this->_config['context']['ssl'][$contextKey] = $value; - } - unset($this->_config[$key]); - } - if (!isset($this->_config['context']['ssl']['SNI_enabled'])) { - $this->_config['context']['ssl']['SNI_enabled'] = true; - } - if (empty($this->_config['context']['ssl']['peer_name'])) { - $this->_config['context']['ssl']['peer_name'] = $host; - } - if (empty($this->_config['context']['ssl']['cafile'])) { - $dir = dirname(dirname(__DIR__)); - $this->_config['context']['ssl']['cafile'] = $dir . DIRECTORY_SEPARATOR . - 'config' . DIRECTORY_SEPARATOR . 'cacert.pem'; - } - if (!empty($this->_config['context']['ssl']['verify_host'])) { - $this->_config['context']['ssl']['CN_match'] = $host; - } - unset($this->_config['context']['ssl']['verify_host']); - } - - /** - * socket_stream_client() does not populate errNum, or $errStr when there are - * connection errors, as in the case of SSL verification failure. - * - * Instead we need to handle those errors manually. - * - * @param int $code Code number. - * @param string $message Message. - * @return void - */ - protected function _connectionErrorHandler($code, $message) - { - $this->_connectionErrors[] = $message; - } - - /** - * Get the connection context. - * - * @return null|array Null when there is no connection, an array when there is. - */ - public function context() - { - if (!$this->connection) { - return null; - } - - return stream_context_get_options($this->connection); - } - - /** - * Get the host name of the current connection. - * - * @return string Host name - */ - public function host() - { - if (Validation::ip($this->_config['host'])) { - return gethostbyaddr($this->_config['host']); - } - - return gethostbyaddr($this->address()); - } - - /** - * Get the IP address of the current connection. - * - * @return string IP address - */ - public function address() - { - if (Validation::ip($this->_config['host'])) { - return $this->_config['host']; - } - - return gethostbyname($this->_config['host']); - } - - /** - * Get all IP addresses associated with the current connection. - * - * @return array IP addresses - */ - public function addresses() - { - if (Validation::ip($this->_config['host'])) { - return [$this->_config['host']]; - } - - return gethostbynamel($this->_config['host']); - } - - /** - * Get the last error as a string. - * - * @return string|null Last error - */ - public function lastError() - { - if (!empty($this->lastError)) { - return $this->lastError['num'] . ': ' . $this->lastError['str']; - } - - return null; - } - - /** - * Set the last error. - * - * @param int $errNum Error code - * @param string $errStr Error string - * @return void - */ - public function setLastError($errNum, $errStr) - { - $this->lastError = ['num' => $errNum, 'str' => $errStr]; - } - - /** - * Write data to the socket. - * - * The bool false return value is deprecated and will be int 0 in the next major. - * Please code respectively to be future proof. - * - * @param string $data The data to write to the socket. - * @return int|false Bytes written. - */ - public function write($data) - { - if (!$this->connected && !$this->connect()) { - return false; - } - $totalBytes = strlen($data); - $written = 0; - while ($written < $totalBytes) { - $rv = fwrite($this->connection, substr($data, $written)); - if ($rv === false || $rv === 0) { - return $written; - } - $written += $rv; - } - - return $written; - } - - /** - * Read data from the socket. Returns false if no data is available or no connection could be - * established. - * - * The bool false return value is deprecated and will be null in the next major. - * Please code respectively to be future proof. - * - * @param int $length Optional buffer length to read; defaults to 1024 - * @return mixed Socket data - */ - public function read($length = 1024) - { - if (!$this->connected && !$this->connect()) { - return false; - } - - if (!feof($this->connection)) { - $buffer = fread($this->connection, $length); - $info = stream_get_meta_data($this->connection); - if ($info['timed_out']) { - $this->setLastError(E_WARNING, 'Connection timed out'); - - return false; - } - - return $buffer; - } - - return false; - } - - /** - * Disconnect the socket from the current connection. - * - * @return bool Success - */ - public function disconnect() - { - if (!is_resource($this->connection)) { - $this->connected = false; - - return true; - } - $this->connected = !fclose($this->connection); - - if (!$this->connected) { - $this->connection = null; - } - - return !$this->connected; - } - - /** - * Destructor, used to disconnect from current connection. - */ - public function __destruct() - { - $this->disconnect(); - } - - /** - * Resets the state of this Socket instance to it's initial state (before Object::__construct got executed) - * - * @param array|null $state Array with key and values to reset - * @return bool True on success - */ - public function reset($state = null) - { - if (empty($state)) { - static $initalState = []; - if (empty($initalState)) { - $initalState = get_class_vars(__CLASS__); - } - $state = $initalState; - } - - foreach ($state as $property => $value) { - $this->{$property} = $value; - } - - return true; - } - - /** - * Encrypts current stream socket, using one of the defined encryption methods - * - * @param string $type can be one of 'ssl2', 'ssl3', 'ssl23' or 'tls' - * @param string $clientOrServer can be one of 'client', 'server'. Default is 'client' - * @param bool $enable enable or disable encryption. Default is true (enable) - * @return bool True on success - * @throws \InvalidArgumentException When an invalid encryption scheme is chosen. - * @throws \Cake\Network\Exception\SocketException When attempting to enable SSL/TLS fails - * @see stream_socket_enable_crypto - */ - public function enableCrypto($type, $clientOrServer = 'client', $enable = true) - { - if (!array_key_exists($type . '_' . $clientOrServer, $this->_encryptMethods)) { - throw new InvalidArgumentException('Invalid encryption scheme chosen'); - } - $method = $this->_encryptMethods[$type . '_' . $clientOrServer]; - - // Prior to PHP 5.6.7 TLS_CLIENT was any version of TLS. This was changed in 5.6.7 - // to fix backwards compatibility issues, and now only resolves to TLS1.0 - // - // See https://github.com/php/php-src/commit/10bc5fd4c4c8e1dd57bd911b086e9872a56300a0 - if (version_compare(PHP_VERSION, '5.6.7', '>=')) { - if ($method == STREAM_CRYPTO_METHOD_TLS_CLIENT) { - // @codingStandardsIgnoreStart - $method |= STREAM_CRYPTO_METHOD_TLSv1_1_CLIENT | STREAM_CRYPTO_METHOD_TLSv1_2_CLIENT; - // @codingStandardsIgnoreEnd - } - if ($method == STREAM_CRYPTO_METHOD_TLS_SERVER) { - // @codingStandardsIgnoreStart - $method |= STREAM_CRYPTO_METHOD_TLSv1_1_SERVER | STREAM_CRYPTO_METHOD_TLSv1_2_SERVER; - // @codingStandardsIgnoreEnd - } - } - - try { - $enableCryptoResult = stream_socket_enable_crypto($this->connection, $enable, $method); - } catch (Exception $e) { - $this->setLastError(null, $e->getMessage()); - throw new SocketException($e->getMessage(), null, $e); - } - if ($enableCryptoResult === true) { - $this->encrypted = $enable; - - return true; - } - $errorMessage = 'Unable to perform enableCrypto operation on the current socket'; - $this->setLastError(null, $errorMessage); - throw new SocketException($errorMessage); - } -} diff --git a/vendor/cakephp/cakephp/src/ORM/Association.php b/vendor/cakephp/cakephp/src/ORM/Association.php deleted file mode 100644 index eda333f..0000000 --- a/vendor/cakephp/cakephp/src/ORM/Association.php +++ /dev/null @@ -1,1491 +0,0 @@ -{'_' . $property} = $options[$property]; - } - } - - if (empty($this->_className) && strpos($alias, '.')) { - $this->_className = $alias; - } - - list(, $name) = pluginSplit($alias); - $this->_name = $name; - - $this->_options($options); - - if (!empty($options['strategy'])) { - $this->setStrategy($options['strategy']); - } - } - - /** - * Sets the name for this association, usually the alias - * assigned to the target associated table - * - * @param string $name Name to be assigned - * @return $this - */ - public function setName($name) - { - if ($this->_targetTable !== null) { - $alias = $this->_targetTable->getAlias(); - if ($alias !== $name) { - throw new InvalidArgumentException('Association name does not match target table alias.'); - } - } - - $this->_name = $name; - - return $this; - } - - /** - * Gets the name for this association, usually the alias - * assigned to the target associated table - * - * @return string - */ - public function getName() - { - return $this->_name; - } - - /** - * Sets the name for this association. - * - * @deprecated 3.4.0 Use setName()/getName() instead. - * @param string|null $name Name to be assigned - * @return string - */ - public function name($name = null) - { - deprecationWarning( - get_called_class() . '::name() is deprecated. ' . - 'Use setName()/getName() instead.' - ); - if ($name !== null) { - $this->setName($name); - } - - return $this->getName(); - } - - /** - * Sets whether or not cascaded deletes should also fire callbacks. - * - * @param bool $cascadeCallbacks cascade callbacks switch value - * @return $this - */ - public function setCascadeCallbacks($cascadeCallbacks) - { - $this->_cascadeCallbacks = $cascadeCallbacks; - - return $this; - } - - /** - * Gets whether or not cascaded deletes should also fire callbacks. - * - * @return bool - */ - public function getCascadeCallbacks() - { - return $this->_cascadeCallbacks; - } - - /** - * Sets whether or not cascaded deletes should also fire callbacks. If no - * arguments are passed, the current configured value is returned - * - * @deprecated 3.4.0 Use setCascadeCallbacks()/getCascadeCallbacks() instead. - * @param bool|null $cascadeCallbacks cascade callbacks switch value - * @return bool - */ - public function cascadeCallbacks($cascadeCallbacks = null) - { - deprecationWarning( - get_called_class() . '::cascadeCallbacks() is deprecated. ' . - 'Use setCascadeCallbacks()/getCascadeCallbacks() instead.' - ); - if ($cascadeCallbacks !== null) { - $this->setCascadeCallbacks($cascadeCallbacks); - } - - return $this->getCascadeCallbacks(); - } - - /** - * The class name of the target table object - * - * @return string - */ - public function className() - { - return $this->_className; - } - - /** - * Sets the table instance for the source side of the association. - * - * @param \Cake\ORM\Table $table the instance to be assigned as source side - * @return $this - */ - public function setSource(Table $table) - { - $this->_sourceTable = $table; - - return $this; - } - - /** - * Gets the table instance for the source side of the association. - * - * @return \Cake\ORM\Table - */ - public function getSource() - { - return $this->_sourceTable; - } - - /** - * Sets the table instance for the source side of the association. If no arguments - * are passed, the current configured table instance is returned - * - * @deprecated 3.4.0 Use setSource()/getSource() instead. - * @param \Cake\ORM\Table|null $table the instance to be assigned as source side - * @return \Cake\ORM\Table - */ - public function source(Table $table = null) - { - deprecationWarning( - get_called_class() . '::source() is deprecated. ' . - 'Use setSource()/getSource() instead.' - ); - if ($table === null) { - return $this->_sourceTable; - } - - return $this->_sourceTable = $table; - } - - /** - * Sets the table instance for the target side of the association. - * - * @param \Cake\ORM\Table $table the instance to be assigned as target side - * @return $this - */ - public function setTarget(Table $table) - { - $this->_targetTable = $table; - - return $this; - } - - /** - * Gets the table instance for the target side of the association. - * - * @return \Cake\ORM\Table - */ - public function getTarget() - { - if (!$this->_targetTable) { - if (strpos($this->_className, '.')) { - list($plugin) = pluginSplit($this->_className, true); - $registryAlias = $plugin . $this->_name; - } else { - $registryAlias = $this->_name; - } - - $tableLocator = $this->getTableLocator(); - - $config = []; - $exists = $tableLocator->exists($registryAlias); - if (!$exists) { - $config = ['className' => $this->_className]; - } - $this->_targetTable = $tableLocator->get($registryAlias, $config); - - if ($exists) { - $className = $this->_getClassName($registryAlias, ['className' => $this->_className]); - - if (!$this->_targetTable instanceof $className) { - $errorMessage = '%s association "%s" of type "%s" to "%s" doesn\'t match the expected class "%s". '; - $errorMessage .= 'You can\'t have an association of the same name with a different target "className" option anywhere in your app.'; - - throw new RuntimeException(sprintf( - $errorMessage, - $this->_sourceTable ? get_class($this->_sourceTable) : 'null', - $this->getName(), - $this->type(), - $this->_targetTable ? get_class($this->_targetTable) : 'null', - $className - )); - } - } - } - - return $this->_targetTable; - } - - /** - * Sets the table instance for the target side of the association. If no arguments - * are passed, the current configured table instance is returned - * - * @deprecated 3.4.0 Use setTarget()/getTarget() instead. - * @param \Cake\ORM\Table|null $table the instance to be assigned as target side - * @return \Cake\ORM\Table - */ - public function target(Table $table = null) - { - deprecationWarning( - get_called_class() . '::target() is deprecated. ' . - 'Use setTarget()/getTarget() instead.' - ); - if ($table !== null) { - $this->setTarget($table); - } - - return $this->getTarget(); - } - - /** - * Sets a list of conditions to be always included when fetching records from - * the target association. - * - * @param array|callable $conditions list of conditions to be used - * @see \Cake\Database\Query::where() for examples on the format of the array - * @return $this - */ - public function setConditions($conditions) - { - $this->_conditions = $conditions; - - return $this; - } - - /** - * Gets a list of conditions to be always included when fetching records from - * the target association. - * - * @see \Cake\Database\Query::where() for examples on the format of the array - * @return array|callable - */ - public function getConditions() - { - return $this->_conditions; - } - - /** - * Sets a list of conditions to be always included when fetching records from - * the target association. If no parameters are passed the current list is returned - * - * @deprecated 3.4.0 Use setConditions()/getConditions() instead. - * @param array|null $conditions list of conditions to be used - * @see \Cake\Database\Query::where() for examples on the format of the array - * @return array|callable - */ - public function conditions($conditions = null) - { - deprecationWarning( - get_called_class() . '::conditions() is deprecated. ' . - 'Use setConditions()/getConditions() instead.' - ); - if ($conditions !== null) { - $this->setConditions($conditions); - } - - return $this->getConditions(); - } - - /** - * Sets the name of the field representing the binding field with the target table. - * When not manually specified the primary key of the owning side table is used. - * - * @param string|array $key the table field or fields to be used to link both tables together - * @return $this - */ - public function setBindingKey($key) - { - $this->_bindingKey = $key; - - return $this; - } - - /** - * Gets the name of the field representing the binding field with the target table. - * When not manually specified the primary key of the owning side table is used. - * - * @return string|array - */ - public function getBindingKey() - { - if ($this->_bindingKey === null) { - $this->_bindingKey = $this->isOwningSide($this->getSource()) ? - $this->getSource()->getPrimaryKey() : - $this->getTarget()->getPrimaryKey(); - } - - return $this->_bindingKey; - } - - /** - * Sets the name of the field representing the binding field with the target table. - * When not manually specified the primary key of the owning side table is used. - * - * If no parameters are passed the current field is returned - * - * @deprecated 3.4.0 Use setBindingKey()/getBindingKey() instead. - * @param string|null $key the table field to be used to link both tables together - * @return string|array - */ - public function bindingKey($key = null) - { - deprecationWarning( - get_called_class() . '::bindingKey() is deprecated. ' . - 'Use setBindingKey()/getBindingKey() instead.' - ); - if ($key !== null) { - $this->setBindingKey($key); - } - - return $this->getBindingKey(); - } - - /** - * Gets the name of the field representing the foreign key to the target table. - * - * @return string|array - */ - public function getForeignKey() - { - return $this->_foreignKey; - } - - /** - * Sets the name of the field representing the foreign key to the target table. - * - * @param string|array $key the key or keys to be used to link both tables together - * @return $this - */ - public function setForeignKey($key) - { - $this->_foreignKey = $key; - - return $this; - } - - /** - * Sets the name of the field representing the foreign key to the target table. - * If no parameters are passed the current field is returned - * - * @deprecated 3.4.0 Use setForeignKey()/getForeignKey() instead. - * @param string|null $key the key to be used to link both tables together - * @return string|array - */ - public function foreignKey($key = null) - { - deprecationWarning( - get_called_class() . '::foreignKey() is deprecated. ' . - 'Use setForeignKey()/getForeignKey() instead.' - ); - if ($key !== null) { - $this->setForeignKey($key); - } - - return $this->getForeignKey(); - } - - /** - * Sets whether the records on the target table are dependent on the source table. - * - * This is primarily used to indicate that records should be removed if the owning record in - * the source table is deleted. - * - * If no parameters are passed the current setting is returned. - * - * @param bool $dependent Set the dependent mode. Use null to read the current state. - * @return $this - */ - public function setDependent($dependent) - { - $this->_dependent = $dependent; - - return $this; - } - - /** - * Sets whether the records on the target table are dependent on the source table. - * - * This is primarily used to indicate that records should be removed if the owning record in - * the source table is deleted. - * - * @return bool - */ - public function getDependent() - { - return $this->_dependent; - } - - /** - * Sets whether the records on the target table are dependent on the source table. - * - * This is primarily used to indicate that records should be removed if the owning record in - * the source table is deleted. - * - * If no parameters are passed the current setting is returned. - * - * @deprecated 3.4.0 Use setDependent()/getDependent() instead. - * @param bool|null $dependent Set the dependent mode. Use null to read the current state. - * @return bool - */ - public function dependent($dependent = null) - { - deprecationWarning( - get_called_class() . '::dependent() is deprecated. ' . - 'Use setDependent()/getDependent() instead.' - ); - if ($dependent !== null) { - $this->setDependent($dependent); - } - - return $this->getDependent(); - } - - /** - * Whether this association can be expressed directly in a query join - * - * @param array $options custom options key that could alter the return value - * @return bool - */ - public function canBeJoined(array $options = []) - { - $strategy = isset($options['strategy']) ? $options['strategy'] : $this->getStrategy(); - - return $strategy == $this::STRATEGY_JOIN; - } - - /** - * Sets the type of join to be used when adding the association to a query. - * - * @param string $type the join type to be used (e.g. INNER) - * @return $this - */ - public function setJoinType($type) - { - $this->_joinType = $type; - - return $this; - } - - /** - * Gets the type of join to be used when adding the association to a query. - * - * @return string - */ - public function getJoinType() - { - return $this->_joinType; - } - - /** - * Sets the type of join to be used when adding the association to a query. - * If no arguments are passed, the currently configured type is returned. - * - * @deprecated 3.4.0 Use setJoinType()/getJoinType() instead. - * @param string|null $type the join type to be used (e.g. INNER) - * @return string - */ - public function joinType($type = null) - { - deprecationWarning( - get_called_class() . '::joinType() is deprecated. ' . - 'Use setJoinType()/getJoinType() instead.' - ); - if ($type !== null) { - $this->setJoinType($type); - } - - return $this->getJoinType(); - } - - /** - * Sets the property name that should be filled with data from the target table - * in the source table record. - * - * @param string $name The name of the association property. Use null to read the current value. - * @return $this - */ - public function setProperty($name) - { - $this->_propertyName = $name; - - return $this; - } - - /** - * Gets the property name that should be filled with data from the target table - * in the source table record. - * - * @return string - */ - public function getProperty() - { - if (!$this->_propertyName) { - $this->_propertyName = $this->_propertyName(); - if (in_array($this->_propertyName, $this->_sourceTable->getSchema()->columns())) { - $msg = 'Association property name "%s" clashes with field of same name of table "%s".' . - ' You should explicitly specify the "propertyName" option.'; - trigger_error( - sprintf($msg, $this->_propertyName, $this->_sourceTable->getTable()), - E_USER_WARNING - ); - } - } - - return $this->_propertyName; - } - - /** - * Sets the property name that should be filled with data from the target table - * in the source table record. - * If no arguments are passed, the currently configured type is returned. - * - * @deprecated 3.4.0 Use setProperty()/getProperty() instead. - * @param string|null $name The name of the association property. Use null to read the current value. - * @return string - */ - public function property($name = null) - { - deprecationWarning( - get_called_class() . '::property() is deprecated. ' . - 'Use setProperty()/getProperty() instead.' - ); - if ($name !== null) { - $this->setProperty($name); - } - - return $this->getProperty(); - } - - /** - * Returns default property name based on association name. - * - * @return string - */ - protected function _propertyName() - { - list(, $name) = pluginSplit($this->_name); - - return Inflector::underscore($name); - } - - /** - * Sets the strategy name to be used to fetch associated records. Keep in mind - * that some association types might not implement but a default strategy, - * rendering any changes to this setting void. - * - * @param string $name The strategy type. Use null to read the current value. - * @return $this - * @throws \InvalidArgumentException When an invalid strategy is provided. - */ - public function setStrategy($name) - { - if (!in_array($name, $this->_validStrategies)) { - throw new InvalidArgumentException( - sprintf('Invalid strategy "%s" was provided', $name) - ); - } - $this->_strategy = $name; - - return $this; - } - - /** - * Gets the strategy name to be used to fetch associated records. Keep in mind - * that some association types might not implement but a default strategy, - * rendering any changes to this setting void. - * - * @return string - */ - public function getStrategy() - { - return $this->_strategy; - } - - /** - * Sets the strategy name to be used to fetch associated records. Keep in mind - * that some association types might not implement but a default strategy, - * rendering any changes to this setting void. - * If no arguments are passed, the currently configured strategy is returned. - * - * @deprecated 3.4.0 Use setStrategy()/getStrategy() instead. - * @param string|null $name The strategy type. Use null to read the current value. - * @return string - * @throws \InvalidArgumentException When an invalid strategy is provided. - */ - public function strategy($name = null) - { - deprecationWarning( - get_called_class() . '::strategy() is deprecated. ' . - 'Use setStrategy()/getStrategy() instead.' - ); - if ($name !== null) { - $this->setStrategy($name); - } - - return $this->getStrategy(); - } - - /** - * Gets the default finder to use for fetching rows from the target table. - * - * @return string - */ - public function getFinder() - { - return $this->_finder; - } - - /** - * Sets the default finder to use for fetching rows from the target table. - * - * @param string $finder the finder name to use - * @return $this - */ - public function setFinder($finder) - { - $this->_finder = $finder; - - return $this; - } - - /** - * Sets the default finder to use for fetching rows from the target table. - * If no parameters are passed, it will return the currently configured - * finder name. - * - * @deprecated 3.4.0 Use setFinder()/getFinder() instead. - * @param string|null $finder the finder name to use - * @return string - */ - public function finder($finder = null) - { - deprecationWarning( - get_called_class() . '::finder() is deprecated. ' . - 'Use setFinder()/getFinder() instead.' - ); - if ($finder !== null) { - $this->setFinder($finder); - } - - return $this->getFinder(); - } - - /** - * Override this function to initialize any concrete association class, it will - * get passed the original list of options used in the constructor - * - * @param array $options List of options used for initialization - * @return void - */ - protected function _options(array $options) - { - } - - /** - * Alters a Query object to include the associated target table data in the final - * result - * - * The options array accept the following keys: - * - * - includeFields: Whether to include target model fields in the result or not - * - foreignKey: The name of the field to use as foreign key, if false none - * will be used - * - conditions: array with a list of conditions to filter the join with, this - * will be merged with any conditions originally configured for this association - * - fields: a list of fields in the target table to include in the result - * - type: The type of join to be used (e.g. INNER) - * the records found on this association - * - aliasPath: A dot separated string representing the path of association names - * followed from the passed query main table to this association. - * - propertyPath: A dot separated string representing the path of association - * properties to be followed from the passed query main entity to this - * association - * - joinType: The SQL join type to use in the query. - * - negateMatch: Will append a condition to the passed query for excluding matches. - * with this association. - * - * @param \Cake\ORM\Query $query the query to be altered to include the target table data - * @param array $options Any extra options or overrides to be taken in account - * @return void - * @throws \RuntimeException if the query builder passed does not return a query - * object - */ - public function attachTo(Query $query, array $options = []) - { - $target = $this->getTarget(); - $joinType = empty($options['joinType']) ? $this->getJoinType() : $options['joinType']; - $table = $target->getTable(); - - $options += [ - 'includeFields' => true, - 'foreignKey' => $this->getForeignKey(), - 'conditions' => [], - 'fields' => [], - 'type' => $joinType, - 'table' => $table, - 'finder' => $this->getFinder() - ]; - - if (!empty($options['foreignKey'])) { - $joinCondition = $this->_joinCondition($options); - if ($joinCondition) { - $options['conditions'][] = $joinCondition; - } - } - - list($finder, $opts) = $this->_extractFinder($options['finder']); - $dummy = $this - ->find($finder, $opts) - ->eagerLoaded(true); - - if (!empty($options['queryBuilder'])) { - $dummy = $options['queryBuilder']($dummy); - if (!($dummy instanceof Query)) { - throw new RuntimeException(sprintf( - 'Query builder for association "%s" did not return a query', - $this->getName() - )); - } - } - - $dummy->where($options['conditions']); - $this->_dispatchBeforeFind($dummy); - - $joinOptions = ['table' => 1, 'conditions' => 1, 'type' => 1]; - $options['conditions'] = $dummy->clause('where'); - $query->join([$this->_name => array_intersect_key($options, $joinOptions)]); - - $this->_appendFields($query, $dummy, $options); - $this->_formatAssociationResults($query, $dummy, $options); - $this->_bindNewAssociations($query, $dummy, $options); - $this->_appendNotMatching($query, $options); - } - - /** - * Conditionally adds a condition to the passed Query that will make it find - * records where there is no match with this association. - * - * @param \Cake\Datasource\QueryInterface $query The query to modify - * @param array $options Options array containing the `negateMatch` key. - * @return void - */ - protected function _appendNotMatching($query, $options) - { - $target = $this->_targetTable; - if (!empty($options['negateMatch'])) { - $primaryKey = $query->aliasFields((array)$target->getPrimaryKey(), $this->_name); - $query->andWhere(function ($exp) use ($primaryKey) { - array_map([$exp, 'isNull'], $primaryKey); - - return $exp; - }); - } - } - - /** - * Correctly nests a result row associated values into the correct array keys inside the - * source results. - * - * @param array $row The row to transform - * @param string $nestKey The array key under which the results for this association - * should be found - * @param bool $joined Whether or not the row is a result of a direct join - * with this association - * @param string|null $targetProperty The property name in the source results where the association - * data shuld be nested in. Will use the default one if not provided. - * @return array - */ - public function transformRow($row, $nestKey, $joined, $targetProperty = null) - { - $sourceAlias = $this->getSource()->getAlias(); - $nestKey = $nestKey ?: $this->_name; - $targetProperty = $targetProperty ?: $this->getProperty(); - if (isset($row[$sourceAlias])) { - $row[$sourceAlias][$targetProperty] = $row[$nestKey]; - unset($row[$nestKey]); - } - - return $row; - } - - /** - * Returns a modified row after appending a property for this association - * with the default empty value according to whether the association was - * joined or fetched externally. - * - * @param array $row The row to set a default on. - * @param bool $joined Whether or not the row is a result of a direct join - * with this association - * @return array - */ - public function defaultRowValue($row, $joined) - { - $sourceAlias = $this->getSource()->getAlias(); - if (isset($row[$sourceAlias])) { - $row[$sourceAlias][$this->getProperty()] = null; - } - - return $row; - } - - /** - * Proxies the finding operation to the target table's find method - * and modifies the query accordingly based of this association - * configuration - * - * @param string|array|null $type the type of query to perform, if an array is passed, - * it will be interpreted as the `$options` parameter - * @param array $options The options to for the find - * @see \Cake\ORM\Table::find() - * @return \Cake\ORM\Query - */ - public function find($type = null, array $options = []) - { - $type = $type ?: $this->getFinder(); - list($type, $opts) = $this->_extractFinder($type); - - return $this->getTarget() - ->find($type, $options + $opts) - ->where($this->getConditions()); - } - - /** - * Proxies the operation to the target table's exists method after - * appending the default conditions for this association - * - * @param array|callable|\Cake\Database\ExpressionInterface $conditions The conditions to use - * for checking if any record matches. - * @see \Cake\ORM\Table::exists() - * @return bool - */ - public function exists($conditions) - { - if ($this->_conditions) { - $conditions = $this - ->find('all', ['conditions' => $conditions]) - ->clause('where'); - } - - return $this->getTarget()->exists($conditions); - } - - /** - * Proxies the update operation to the target table's updateAll method - * - * @param array $fields A hash of field => new value. - * @param mixed $conditions Conditions to be used, accepts anything Query::where() - * can take. - * @see \Cake\ORM\Table::updateAll() - * @return int Count Returns the affected rows. - */ - public function updateAll($fields, $conditions) - { - $target = $this->getTarget(); - $expression = $target->query() - ->where($this->getConditions()) - ->where($conditions) - ->clause('where'); - - return $target->updateAll($fields, $expression); - } - - /** - * Proxies the delete operation to the target table's deleteAll method - * - * @param mixed $conditions Conditions to be used, accepts anything Query::where() - * can take. - * @return int Returns the number of affected rows. - * @see \Cake\ORM\Table::deleteAll() - */ - public function deleteAll($conditions) - { - $target = $this->getTarget(); - $expression = $target->query() - ->where($this->getConditions()) - ->where($conditions) - ->clause('where'); - - return $target->deleteAll($expression); - } - - /** - * Returns true if the eager loading process will require a set of the owning table's - * binding keys in order to use them as a filter in the finder query. - * - * @param array $options The options containing the strategy to be used. - * @return bool true if a list of keys will be required - */ - public function requiresKeys(array $options = []) - { - $strategy = isset($options['strategy']) ? $options['strategy'] : $this->getStrategy(); - - return $strategy === static::STRATEGY_SELECT; - } - - /** - * Triggers beforeFind on the target table for the query this association is - * attaching to - * - * @param \Cake\ORM\Query $query the query this association is attaching itself to - * @return void - */ - protected function _dispatchBeforeFind($query) - { - $query->triggerBeforeFind(); - } - - /** - * Helper function used to conditionally append fields to the select clause of - * a query from the fields found in another query object. - * - * @param \Cake\ORM\Query $query the query that will get the fields appended to - * @param \Cake\ORM\Query $surrogate the query having the fields to be copied from - * @param array $options options passed to the method `attachTo` - * @return void - */ - protected function _appendFields($query, $surrogate, $options) - { - if ($query->getEagerLoader()->isAutoFieldsEnabled() === false) { - return; - } - - $fields = $surrogate->clause('select') ?: $options['fields']; - $target = $this->_targetTable; - $autoFields = $surrogate->isAutoFieldsEnabled(); - - if (empty($fields) && !$autoFields) { - if ($options['includeFields'] && ($fields === null || $fields !== false)) { - $fields = $target->getSchema()->columns(); - } - } - - if ($autoFields === true) { - $fields = array_filter((array)$fields); - $fields = array_merge($fields, $target->getSchema()->columns()); - } - - if ($fields) { - $query->select($query->aliasFields($fields, $this->_name)); - } - $query->addDefaultTypes($target); - } - - /** - * Adds a formatter function to the passed `$query` if the `$surrogate` query - * declares any other formatter. Since the `$surrogate` query correspond to - * the associated target table, the resulting formatter will be the result of - * applying the surrogate formatters to only the property corresponding to - * such table. - * - * @param \Cake\ORM\Query $query the query that will get the formatter applied to - * @param \Cake\ORM\Query $surrogate the query having formatters for the associated - * target table. - * @param array $options options passed to the method `attachTo` - * @return void - */ - protected function _formatAssociationResults($query, $surrogate, $options) - { - $formatters = $surrogate->getResultFormatters(); - - if (!$formatters || empty($options['propertyPath'])) { - return; - } - - $property = $options['propertyPath']; - $propertyPath = explode('.', $property); - $query->formatResults(function ($results) use ($formatters, $property, $propertyPath) { - $extracted = []; - foreach ($results as $result) { - foreach ($propertyPath as $propertyPathItem) { - if (!isset($result[$propertyPathItem])) { - $result = null; - break; - } - $result = $result[$propertyPathItem]; - } - $extracted[] = $result; - } - $extracted = new Collection($extracted); - foreach ($formatters as $callable) { - $extracted = new ResultSetDecorator($callable($extracted)); - } - - /* @var \Cake\Collection\CollectionInterface $results */ - return $results->insert($property, $extracted); - }, Query::PREPEND); - } - - /** - * Applies all attachable associations to `$query` out of the containments found - * in the `$surrogate` query. - * - * Copies all contained associations from the `$surrogate` query into the - * passed `$query`. Containments are altered so that they respect the associations - * chain from which they originated. - * - * @param \Cake\ORM\Query $query the query that will get the associations attached to - * @param \Cake\ORM\Query $surrogate the query having the containments to be attached - * @param array $options options passed to the method `attachTo` - * @return void - */ - protected function _bindNewAssociations($query, $surrogate, $options) - { - $loader = $surrogate->getEagerLoader(); - $contain = $loader->getContain(); - $matching = $loader->getMatching(); - - if (!$contain && !$matching) { - return; - } - - $newContain = []; - foreach ($contain as $alias => $value) { - $newContain[$options['aliasPath'] . '.' . $alias] = $value; - } - - $eagerLoader = $query->getEagerLoader(); - if ($newContain) { - $eagerLoader->contain($newContain); - } - - foreach ($matching as $alias => $value) { - $eagerLoader->setMatching( - $options['aliasPath'] . '.' . $alias, - $value['queryBuilder'], - $value - ); - } - } - - /** - * Returns a single or multiple conditions to be appended to the generated join - * clause for getting the results on the target table. - * - * @param array $options list of options passed to attachTo method - * @return array - * @throws \RuntimeException if the number of columns in the foreignKey do not - * match the number of columns in the source table primaryKey - */ - protected function _joinCondition($options) - { - $conditions = []; - $tAlias = $this->_name; - $sAlias = $this->getSource()->getAlias(); - $foreignKey = (array)$options['foreignKey']; - $bindingKey = (array)$this->getBindingKey(); - - if (count($foreignKey) !== count($bindingKey)) { - if (empty($bindingKey)) { - $table = $this->getTarget()->getTable(); - if ($this->isOwningSide($this->getSource())) { - $table = $this->getSource()->getTable(); - } - $msg = 'The "%s" table does not define a primary key, and cannot have join conditions generated.'; - throw new RuntimeException(sprintf($msg, $table)); - } - - $msg = 'Cannot match provided foreignKey for "%s", got "(%s)" but expected foreign key for "(%s)"'; - throw new RuntimeException(sprintf( - $msg, - $this->_name, - implode(', ', $foreignKey), - implode(', ', $bindingKey) - )); - } - - foreach ($foreignKey as $k => $f) { - $field = sprintf('%s.%s', $sAlias, $bindingKey[$k]); - $value = new IdentifierExpression(sprintf('%s.%s', $tAlias, $f)); - $conditions[$field] = $value; - } - - return $conditions; - } - - /** - * Helper method to infer the requested finder and its options. - * - * Returns the inferred options from the finder $type. - * - * ### Examples: - * - * The following will call the finder 'translations' with the value of the finder as its options: - * $query->contain(['Comments' => ['finder' => ['translations']]]); - * $query->contain(['Comments' => ['finder' => ['translations' => []]]]); - * $query->contain(['Comments' => ['finder' => ['translations' => ['locales' => ['en_US']]]]]); - * - * @param string|array $finderData The finder name or an array having the name as key - * and options as value. - * @return array - */ - protected function _extractFinder($finderData) - { - $finderData = (array)$finderData; - - if (is_numeric(key($finderData))) { - return [current($finderData), []]; - } - - return [key($finderData), current($finderData)]; - } - - /** - * Gets the table class name. - * - * @param string $alias The alias name you want to get. - * @param array $options Table options array. - * @return string - */ - protected function _getClassName($alias, array $options = []) - { - if (empty($options['className'])) { - $options['className'] = Inflector::camelize($alias); - } - - $className = App::className($options['className'], 'Model/Table', 'Table') ?: 'Cake\ORM\Table'; - - return ltrim($className, '\\'); - } - - /** - * Proxies property retrieval to the target table. This is handy for getting this - * association's associations - * - * @param string $property the property name - * @return \Cake\ORM\Association - * @throws \RuntimeException if no association with such name exists - */ - public function __get($property) - { - return $this->getTarget()->{$property}; - } - - /** - * Proxies the isset call to the target table. This is handy to check if the - * target table has another association with the passed name - * - * @param string $property the property name - * @return bool true if the property exists - */ - public function __isset($property) - { - return isset($this->getTarget()->{$property}); - } - - /** - * Proxies method calls to the target table. - * - * @param string $method name of the method to be invoked - * @param array $argument List of arguments passed to the function - * @return mixed - * @throws \BadMethodCallException - */ - public function __call($method, $argument) - { - return $this->getTarget()->$method(...$argument); - } - - /** - * Get the relationship type. - * - * @return string Constant of either ONE_TO_ONE, MANY_TO_ONE, ONE_TO_MANY or MANY_TO_MANY. - */ - abstract public function type(); - - /** - * Eager loads a list of records in the target table that are related to another - * set of records in the source table. Source records can specified in two ways: - * first one is by passing a Query object setup to find on the source table and - * the other way is by explicitly passing an array of primary key values from - * the source table. - * - * The required way of passing related source records is controlled by "strategy" - * When the subquery strategy is used it will require a query on the source table. - * When using the select strategy, the list of primary keys will be used. - * - * Returns a closure that should be run for each record returned in a specific - * Query. This callable will be responsible for injecting the fields that are - * related to each specific passed row. - * - * Options array accepts the following keys: - * - * - query: Query object setup to find the source table records - * - keys: List of primary key values from the source table - * - foreignKey: The name of the field used to relate both tables - * - conditions: List of conditions to be passed to the query where() method - * - sort: The direction in which the records should be returned - * - fields: List of fields to select from the target table - * - contain: List of related tables to eager load associated to the target table - * - strategy: The name of strategy to use for finding target table records - * - nestKey: The array key under which results will be found when transforming the row - * - * @param array $options The options for eager loading. - * @return \Closure - */ - abstract public function eagerLoader(array $options); - - /** - * Handles cascading a delete from an associated model. - * - * Each implementing class should handle the cascaded delete as - * required. - * - * @param \Cake\Datasource\EntityInterface $entity The entity that started the cascaded delete. - * @param array $options The options for the original delete. - * @return bool Success - */ - abstract public function cascadeDelete(EntityInterface $entity, array $options = []); - - /** - * Returns whether or not the passed table is the owning side for this - * association. This means that rows in the 'target' table would miss important - * or required information if the row in 'source' did not exist. - * - * @param \Cake\ORM\Table $side The potential Table with ownership - * @return bool - */ - abstract public function isOwningSide(Table $side); - - /** - * Extract the target's association data our from the passed entity and proxies - * the saving operation to the target table. - * - * @param \Cake\Datasource\EntityInterface $entity the data to be saved - * @param array $options The options for saving associated data. - * @return bool|\Cake\Datasource\EntityInterface false if $entity could not be saved, otherwise it returns - * the saved entity - * @see \Cake\ORM\Table::save() - */ - abstract public function saveAssociated(EntityInterface $entity, array $options = []); -} diff --git a/vendor/cakephp/cakephp/src/ORM/Association/BelongsTo.php b/vendor/cakephp/cakephp/src/ORM/Association/BelongsTo.php deleted file mode 100644 index 651f81e..0000000 --- a/vendor/cakephp/cakephp/src/ORM/Association/BelongsTo.php +++ /dev/null @@ -1,202 +0,0 @@ -_foreignKey === null) { - $this->_foreignKey = $this->_modelKey($this->getTarget()->getAlias()); - } - - return $this->_foreignKey; - } - - /** - * Handle cascading deletes. - * - * BelongsTo associations are never cleared in a cascading delete scenario. - * - * @param \Cake\Datasource\EntityInterface $entity The entity that started the cascaded delete. - * @param array $options The options for the original delete. - * @return bool Success. - */ - public function cascadeDelete(EntityInterface $entity, array $options = []) - { - return true; - } - - /** - * Returns default property name based on association name. - * - * @return string - */ - protected function _propertyName() - { - list(, $name) = pluginSplit($this->_name); - - return Inflector::underscore(Inflector::singularize($name)); - } - - /** - * Returns whether or not the passed table is the owning side for this - * association. This means that rows in the 'target' table would miss important - * or required information if the row in 'source' did not exist. - * - * @param \Cake\ORM\Table $side The potential Table with ownership - * @return bool - */ - public function isOwningSide(Table $side) - { - return $side === $this->getTarget(); - } - - /** - * Get the relationship type. - * - * @return string - */ - public function type() - { - return self::MANY_TO_ONE; - } - - /** - * Takes an entity from the source table and looks if there is a field - * matching the property name for this association. The found entity will be - * saved on the target table for this association by passing supplied - * `$options` - * - * @param \Cake\Datasource\EntityInterface $entity an entity from the source table - * @param array $options options to be passed to the save method in the target table - * @return bool|\Cake\Datasource\EntityInterface false if $entity could not be saved, otherwise it returns - * the saved entity - * @see \Cake\ORM\Table::save() - */ - public function saveAssociated(EntityInterface $entity, array $options = []) - { - $targetEntity = $entity->get($this->getProperty()); - if (empty($targetEntity) || !($targetEntity instanceof EntityInterface)) { - return $entity; - } - - $table = $this->getTarget(); - $targetEntity = $table->save($targetEntity, $options); - if (!$targetEntity) { - return false; - } - - $properties = array_combine( - (array)$this->getForeignKey(), - $targetEntity->extract((array)$this->getBindingKey()) - ); - $entity->set($properties, ['guard' => false]); - - return $entity; - } - - /** - * Returns a single or multiple conditions to be appended to the generated join - * clause for getting the results on the target table. - * - * @param array $options list of options passed to attachTo method - * @return array - * @throws \RuntimeException if the number of columns in the foreignKey do not - * match the number of columns in the target table primaryKey - */ - protected function _joinCondition($options) - { - $conditions = []; - $tAlias = $this->_name; - $sAlias = $this->_sourceTable->getAlias(); - $foreignKey = (array)$options['foreignKey']; - $bindingKey = (array)$this->getBindingKey(); - - if (count($foreignKey) !== count($bindingKey)) { - if (empty($bindingKey)) { - $msg = 'The "%s" table does not define a primary key. Please set one.'; - throw new RuntimeException(sprintf($msg, $this->getTarget()->getTable())); - } - - $msg = 'Cannot match provided foreignKey for "%s", got "(%s)" but expected foreign key for "(%s)"'; - throw new RuntimeException(sprintf( - $msg, - $this->_name, - implode(', ', $foreignKey), - implode(', ', $bindingKey) - )); - } - - foreach ($foreignKey as $k => $f) { - $field = sprintf('%s.%s', $tAlias, $bindingKey[$k]); - $value = new IdentifierExpression(sprintf('%s.%s', $sAlias, $f)); - $conditions[$field] = $value; - } - - return $conditions; - } - - /** - * {@inheritDoc} - * - * @return \Closure - */ - public function eagerLoader(array $options) - { - $loader = new SelectLoader([ - 'alias' => $this->getAlias(), - 'sourceAlias' => $this->getSource()->getAlias(), - 'targetAlias' => $this->getTarget()->getAlias(), - 'foreignKey' => $this->getForeignKey(), - 'bindingKey' => $this->getBindingKey(), - 'strategy' => $this->getStrategy(), - 'associationType' => $this->type(), - 'finder' => [$this, 'find'] - ]); - - return $loader->buildEagerLoader($options); - } -} diff --git a/vendor/cakephp/cakephp/src/ORM/Association/BelongsToMany.php b/vendor/cakephp/cakephp/src/ORM/Association/BelongsToMany.php deleted file mode 100644 index 506801a..0000000 --- a/vendor/cakephp/cakephp/src/ORM/Association/BelongsToMany.php +++ /dev/null @@ -1,1471 +0,0 @@ -_targetForeignKey = $key; - - return $this; - } - - /** - * Gets the name of the field representing the foreign key to the target table. - * - * @return string - */ - public function getTargetForeignKey() - { - if ($this->_targetForeignKey === null) { - $this->_targetForeignKey = $this->_modelKey($this->getTarget()->getAlias()); - } - - return $this->_targetForeignKey; - } - - /** - * Sets the name of the field representing the foreign key to the target table. - * If no parameters are passed current field is returned - * - * @deprecated 3.4.0 Use setTargetForeignKey()/getTargetForeignKey() instead. - * @param string|null $key the key to be used to link both tables together - * @return string - */ - public function targetForeignKey($key = null) - { - deprecationWarning( - 'BelongToMany::targetForeignKey() is deprecated. ' . - 'Use setTargetForeignKey()/getTargetForeignKey() instead.' - ); - if ($key !== null) { - $this->setTargetForeignKey($key); - } - - return $this->getTargetForeignKey(); - } - - /** - * Whether this association can be expressed directly in a query join - * - * @param array $options custom options key that could alter the return value - * @return bool if the 'matching' key in $option is true then this function - * will return true, false otherwise - */ - public function canBeJoined(array $options = []) - { - return !empty($options['matching']); - } - - /** - * Gets the name of the field representing the foreign key to the source table. - * - * @return string - */ - public function getForeignKey() - { - if ($this->_foreignKey === null) { - $this->_foreignKey = $this->_modelKey($this->getSource()->getTable()); - } - - return $this->_foreignKey; - } - - /** - * Sets the sort order in which target records should be returned. - * - * @param mixed $sort A find() compatible order clause - * @return $this - */ - public function setSort($sort) - { - $this->_sort = $sort; - - return $this; - } - - /** - * Gets the sort order in which target records should be returned. - * - * @return mixed - */ - public function getSort() - { - return $this->_sort; - } - - /** - * Sets the sort order in which target records should be returned. - * If no arguments are passed the currently configured value is returned - * - * @deprecated 3.5.0 Use setSort()/getSort() instead. - * @param mixed $sort A find() compatible order clause - * @return mixed - */ - public function sort($sort = null) - { - deprecationWarning( - 'BelongToMany::sort() is deprecated. ' . - 'Use setSort()/getSort() instead.' - ); - if ($sort !== null) { - $this->setSort($sort); - } - - return $this->getSort(); - } - - /** - * {@inheritDoc} - */ - public function defaultRowValue($row, $joined) - { - $sourceAlias = $this->getSource()->getAlias(); - if (isset($row[$sourceAlias])) { - $row[$sourceAlias][$this->getProperty()] = $joined ? null : []; - } - - return $row; - } - - /** - * Sets the table instance for the junction relation. If no arguments - * are passed, the current configured table instance is returned - * - * @param string|\Cake\ORM\Table|null $table Name or instance for the join table - * @return \Cake\ORM\Table - */ - public function junction($table = null) - { - if ($table === null && $this->_junctionTable) { - return $this->_junctionTable; - } - - $tableLocator = $this->getTableLocator(); - if ($table === null && $this->_through) { - $table = $this->_through; - } elseif ($table === null) { - $tableName = $this->_junctionTableName(); - $tableAlias = Inflector::camelize($tableName); - - $config = []; - if (!$tableLocator->exists($tableAlias)) { - $config = ['table' => $tableName]; - - // Propagate the connection if we'll get an auto-model - if (!App::className($tableAlias, 'Model/Table', 'Table')) { - $config['connection'] = $this->getSource()->getConnection(); - } - } - $table = $tableLocator->get($tableAlias, $config); - } - - if (is_string($table)) { - $table = $tableLocator->get($table); - } - $source = $this->getSource(); - $target = $this->getTarget(); - - $this->_generateSourceAssociations($table, $source); - $this->_generateTargetAssociations($table, $source, $target); - $this->_generateJunctionAssociations($table, $source, $target); - - return $this->_junctionTable = $table; - } - - /** - * Generate reciprocal associations as necessary. - * - * Generates the following associations: - * - * - target hasMany junction e.g. Articles hasMany ArticlesTags - * - target belongsToMany source e.g Articles belongsToMany Tags. - * - * You can override these generated associations by defining associations - * with the correct aliases. - * - * @param \Cake\ORM\Table $junction The junction table. - * @param \Cake\ORM\Table $source The source table. - * @param \Cake\ORM\Table $target The target table. - * @return void - */ - protected function _generateTargetAssociations($junction, $source, $target) - { - $junctionAlias = $junction->getAlias(); - $sAlias = $source->getAlias(); - - if (!$target->hasAssociation($junctionAlias)) { - $target->hasMany($junctionAlias, [ - 'targetTable' => $junction, - 'foreignKey' => $this->getTargetForeignKey(), - 'strategy' => $this->_strategy, - ]); - } - if (!$target->hasAssociation($sAlias)) { - $target->belongsToMany($sAlias, [ - 'sourceTable' => $target, - 'targetTable' => $source, - 'foreignKey' => $this->getTargetForeignKey(), - 'targetForeignKey' => $this->getForeignKey(), - 'through' => $junction, - 'conditions' => $this->getConditions(), - 'strategy' => $this->_strategy, - ]); - } - } - - /** - * Generate additional source table associations as necessary. - * - * Generates the following associations: - * - * - source hasMany junction e.g. Tags hasMany ArticlesTags - * - * You can override these generated associations by defining associations - * with the correct aliases. - * - * @param \Cake\ORM\Table $junction The junction table. - * @param \Cake\ORM\Table $source The source table. - * @return void - */ - protected function _generateSourceAssociations($junction, $source) - { - $junctionAlias = $junction->getAlias(); - if (!$source->hasAssociation($junctionAlias)) { - $source->hasMany($junctionAlias, [ - 'targetTable' => $junction, - 'foreignKey' => $this->getForeignKey(), - 'strategy' => $this->_strategy, - ]); - } - } - - /** - * Generate associations on the junction table as necessary - * - * Generates the following associations: - * - * - junction belongsTo source e.g. ArticlesTags belongsTo Tags - * - junction belongsTo target e.g. ArticlesTags belongsTo Articles - * - * You can override these generated associations by defining associations - * with the correct aliases. - * - * @param \Cake\ORM\Table $junction The junction table. - * @param \Cake\ORM\Table $source The source table. - * @param \Cake\ORM\Table $target The target table. - * @return void - */ - protected function _generateJunctionAssociations($junction, $source, $target) - { - $tAlias = $target->getAlias(); - $sAlias = $source->getAlias(); - - if (!$junction->hasAssociation($tAlias)) { - $junction->belongsTo($tAlias, [ - 'foreignKey' => $this->getTargetForeignKey(), - 'targetTable' => $target - ]); - } - if (!$junction->hasAssociation($sAlias)) { - $junction->belongsTo($sAlias, [ - 'foreignKey' => $this->getForeignKey(), - 'targetTable' => $source - ]); - } - } - - /** - * Alters a Query object to include the associated target table data in the final - * result - * - * The options array accept the following keys: - * - * - includeFields: Whether to include target model fields in the result or not - * - foreignKey: The name of the field to use as foreign key, if false none - * will be used - * - conditions: array with a list of conditions to filter the join with - * - fields: a list of fields in the target table to include in the result - * - type: The type of join to be used (e.g. INNER) - * - * @param \Cake\ORM\Query $query the query to be altered to include the target table data - * @param array $options Any extra options or overrides to be taken in account - * @return void - */ - public function attachTo(Query $query, array $options = []) - { - if (!empty($options['negateMatch'])) { - $this->_appendNotMatching($query, $options); - - return; - } - - $junction = $this->junction(); - $belongsTo = $junction->getAssociation($this->getSource()->getAlias()); - $cond = $belongsTo->_joinCondition(['foreignKey' => $belongsTo->getForeignKey()]); - $cond += $this->junctionConditions(); - - $includeFields = null; - if (isset($options['includeFields'])) { - $includeFields = $options['includeFields']; - } - - // Attach the junction table as well we need it to populate _joinData. - $assoc = $this->_targetTable->getAssociation($junction->getAlias()); - $newOptions = array_intersect_key($options, ['joinType' => 1, 'fields' => 1]); - $newOptions += [ - 'conditions' => $cond, - 'includeFields' => $includeFields, - 'foreignKey' => false, - ]; - $assoc->attachTo($query, $newOptions); - $query->getEagerLoader()->addToJoinsMap($junction->getAlias(), $assoc, true); - - parent::attachTo($query, $options); - - $foreignKey = $this->getTargetForeignKey(); - $thisJoin = $query->clause('join')[$this->getName()]; - $thisJoin['conditions']->add($assoc->_joinCondition(['foreignKey' => $foreignKey])); - } - - /** - * {@inheritDoc} - */ - protected function _appendNotMatching($query, $options) - { - if (empty($options['negateMatch'])) { - return; - } - if (!isset($options['conditions'])) { - $options['conditions'] = []; - } - $junction = $this->junction(); - $belongsTo = $junction->getAssociation($this->getSource()->getAlias()); - $conds = $belongsTo->_joinCondition(['foreignKey' => $belongsTo->getForeignKey()]); - - $subquery = $this->find() - ->select(array_values($conds)) - ->where($options['conditions']) - ->andWhere($this->junctionConditions()); - - if (!empty($options['queryBuilder'])) { - $subquery = $options['queryBuilder']($subquery); - } - - $assoc = $junction->getAssociation($this->getTarget()->getAlias()); - $conditions = $assoc->_joinCondition([ - 'foreignKey' => $this->getTargetForeignKey() - ]); - $subquery = $this->_appendJunctionJoin($subquery, $conditions); - - $query - ->andWhere(function ($exp) use ($subquery, $conds) { - $identifiers = []; - foreach (array_keys($conds) as $field) { - $identifiers[] = new IdentifierExpression($field); - } - $identifiers = $subquery->newExpr()->add($identifiers)->setConjunction(','); - $nullExp = clone $exp; - - return $exp - ->or_([ - $exp->notIn($identifiers, $subquery), - $nullExp->and(array_map([$nullExp, 'isNull'], array_keys($conds))), - ]); - }); - } - - /** - * Get the relationship type. - * - * @return string - */ - public function type() - { - return self::MANY_TO_MANY; - } - - /** - * Return false as join conditions are defined in the junction table - * - * @param array $options list of options passed to attachTo method - * @return bool false - */ - protected function _joinCondition($options) - { - return false; - } - - /** - * {@inheritDoc} - * - * @return \Closure - */ - public function eagerLoader(array $options) - { - $name = $this->_junctionAssociationName(); - $loader = new SelectWithPivotLoader([ - 'alias' => $this->getAlias(), - 'sourceAlias' => $this->getSource()->getAlias(), - 'targetAlias' => $this->getTarget()->getAlias(), - 'foreignKey' => $this->getForeignKey(), - 'bindingKey' => $this->getBindingKey(), - 'strategy' => $this->getStrategy(), - 'associationType' => $this->type(), - 'sort' => $this->getSort(), - 'junctionAssociationName' => $name, - 'junctionProperty' => $this->_junctionProperty, - 'junctionAssoc' => $this->getTarget()->getAssociation($name), - 'junctionConditions' => $this->junctionConditions(), - 'finder' => function () { - return $this->_appendJunctionJoin($this->find(), []); - } - ]); - - return $loader->buildEagerLoader($options); - } - - /** - * Clear out the data in the junction table for a given entity. - * - * @param \Cake\Datasource\EntityInterface $entity The entity that started the cascading delete. - * @param array $options The options for the original delete. - * @return bool Success. - */ - public function cascadeDelete(EntityInterface $entity, array $options = []) - { - if (!$this->getDependent()) { - return true; - } - $foreignKey = (array)$this->getForeignKey(); - $bindingKey = (array)$this->getBindingKey(); - $conditions = []; - - if (!empty($bindingKey)) { - $conditions = array_combine($foreignKey, $entity->extract($bindingKey)); - } - - $table = $this->junction(); - $hasMany = $this->getSource()->getAssociation($table->getAlias()); - if ($this->_cascadeCallbacks) { - foreach ($hasMany->find('all')->where($conditions)->all()->toList() as $related) { - $table->delete($related, $options); - } - - return true; - } - - $conditions = array_merge($conditions, $hasMany->getConditions()); - - $table->deleteAll($conditions); - - return true; - } - - /** - * Returns boolean true, as both of the tables 'own' rows in the other side - * of the association via the joint table. - * - * @param \Cake\ORM\Table $side The potential Table with ownership - * @return bool - */ - public function isOwningSide(Table $side) - { - return true; - } - - /** - * Sets the strategy that should be used for saving. - * - * @param string $strategy the strategy name to be used - * @throws \InvalidArgumentException if an invalid strategy name is passed - * @return $this - */ - public function setSaveStrategy($strategy) - { - if (!in_array($strategy, [self::SAVE_APPEND, self::SAVE_REPLACE])) { - $msg = sprintf('Invalid save strategy "%s"', $strategy); - throw new InvalidArgumentException($msg); - } - - $this->_saveStrategy = $strategy; - - return $this; - } - - /** - * Gets the strategy that should be used for saving. - * - * @return string the strategy to be used for saving - */ - public function getSaveStrategy() - { - return $this->_saveStrategy; - } - - /** - * Sets the strategy that should be used for saving. If called with no - * arguments, it will return the currently configured strategy - * - * @deprecated 3.4.0 Use setSaveStrategy()/getSaveStrategy() instead. - * @param string|null $strategy the strategy name to be used - * @throws \InvalidArgumentException if an invalid strategy name is passed - * @return string the strategy to be used for saving - */ - public function saveStrategy($strategy = null) - { - deprecationWarning( - 'BelongsToMany::saveStrategy() is deprecated. ' . - 'Use setSaveStrategy()/getSaveStrategy() instead.' - ); - if ($strategy !== null) { - $this->setSaveStrategy($strategy); - } - - return $this->getSaveStrategy(); - } - - /** - * Takes an entity from the source table and looks if there is a field - * matching the property name for this association. The found entity will be - * saved on the target table for this association by passing supplied - * `$options` - * - * When using the 'append' strategy, this function will only create new links - * between each side of this association. It will not destroy existing ones even - * though they may not be present in the array of entities to be saved. - * - * When using the 'replace' strategy, existing links will be removed and new links - * will be created in the joint table. If there exists links in the database to some - * of the entities intended to be saved by this method, they will be updated, - * not deleted. - * - * @param \Cake\Datasource\EntityInterface $entity an entity from the source table - * @param array $options options to be passed to the save method in the target table - * @throws \InvalidArgumentException if the property representing the association - * in the parent entity cannot be traversed - * @return bool|\Cake\Datasource\EntityInterface false if $entity could not be saved, otherwise it returns - * the saved entity - * @see \Cake\ORM\Table::save() - * @see \Cake\ORM\Association\BelongsToMany::replaceLinks() - */ - public function saveAssociated(EntityInterface $entity, array $options = []) - { - $targetEntity = $entity->get($this->getProperty()); - $strategy = $this->getSaveStrategy(); - - $isEmpty = in_array($targetEntity, [null, [], '', false], true); - if ($isEmpty && $entity->isNew()) { - return $entity; - } - if ($isEmpty) { - $targetEntity = []; - } - - if ($strategy === self::SAVE_APPEND) { - return $this->_saveTarget($entity, $targetEntity, $options); - } - - if ($this->replaceLinks($entity, $targetEntity, $options)) { - return $entity; - } - - return false; - } - - /** - * Persists each of the entities into the target table and creates links between - * the parent entity and each one of the saved target entities. - * - * @param \Cake\Datasource\EntityInterface $parentEntity the source entity containing the target - * entities to be saved. - * @param array|\Traversable $entities list of entities to persist in target table and to - * link to the parent entity - * @param array $options list of options accepted by `Table::save()` - * @throws \InvalidArgumentException if the property representing the association - * in the parent entity cannot be traversed - * @return \Cake\Datasource\EntityInterface|bool The parent entity after all links have been - * created if no errors happened, false otherwise - */ - protected function _saveTarget(EntityInterface $parentEntity, $entities, $options) - { - $joinAssociations = false; - if (!empty($options['associated'][$this->_junctionProperty]['associated'])) { - $joinAssociations = $options['associated'][$this->_junctionProperty]['associated']; - } - unset($options['associated'][$this->_junctionProperty]); - - if (!(is_array($entities) || $entities instanceof Traversable)) { - $name = $this->getProperty(); - $message = sprintf('Could not save %s, it cannot be traversed', $name); - throw new InvalidArgumentException($message); - } - - $table = $this->getTarget(); - $original = $entities; - $persisted = []; - - foreach ($entities as $k => $entity) { - if (!($entity instanceof EntityInterface)) { - break; - } - - if (!empty($options['atomic'])) { - $entity = clone $entity; - } - - $saved = $table->save($entity, $options); - if ($saved) { - $entities[$k] = $entity; - $persisted[] = $entity; - continue; - } - - // Saving the new linked entity failed, copy errors back into the - // original entity if applicable and abort. - if (!empty($options['atomic'])) { - $original[$k]->setErrors($entity->getErrors()); - } - if (!$saved) { - return false; - } - } - - $options['associated'] = $joinAssociations; - $success = $this->_saveLinks($parentEntity, $persisted, $options); - if (!$success && !empty($options['atomic'])) { - $parentEntity->set($this->getProperty(), $original); - - return false; - } - - $parentEntity->set($this->getProperty(), $entities); - - return $parentEntity; - } - - /** - * Creates links between the source entity and each of the passed target entities - * - * @param \Cake\Datasource\EntityInterface $sourceEntity the entity from source table in this - * association - * @param array $targetEntities list of entities to link to link to the source entity using the - * junction table - * @param array $options list of options accepted by `Table::save()` - * @return bool success - */ - protected function _saveLinks(EntityInterface $sourceEntity, $targetEntities, $options) - { - $target = $this->getTarget(); - $junction = $this->junction(); - $entityClass = $junction->getEntityClass(); - $belongsTo = $junction->getAssociation($target->getAlias()); - $foreignKey = (array)$this->getForeignKey(); - $assocForeignKey = (array)$belongsTo->getForeignKey(); - $targetPrimaryKey = (array)$target->getPrimaryKey(); - $bindingKey = (array)$this->getBindingKey(); - $jointProperty = $this->_junctionProperty; - $junctionAlias = $junction->getAlias(); - - foreach ($targetEntities as $e) { - $joint = $e->get($jointProperty); - if (!$joint || !($joint instanceof EntityInterface)) { - $joint = new $entityClass([], ['markNew' => true, 'source' => $junctionAlias]); - } - $sourceKeys = array_combine($foreignKey, $sourceEntity->extract($bindingKey)); - $targetKeys = array_combine($assocForeignKey, $e->extract($targetPrimaryKey)); - - $changedKeys = ( - $sourceKeys !== $joint->extract($foreignKey) || - $targetKeys !== $joint->extract($assocForeignKey) - ); - // Keys were changed, the junction table record _could_ be - // new. By clearing the primary key values, and marking the entity - // as new, we let save() sort out whether or not we have a new link - // or if we are updating an existing link. - if ($changedKeys) { - $joint->isNew(true); - $joint->unsetProperty($junction->getPrimaryKey()) - ->set(array_merge($sourceKeys, $targetKeys), ['guard' => false]); - } - $saved = $junction->save($joint, $options); - - if (!$saved && !empty($options['atomic'])) { - return false; - } - - $e->set($jointProperty, $joint); - $e->setDirty($jointProperty, false); - } - - return true; - } - - /** - * Associates the source entity to each of the target entities provided by - * creating links in the junction table. Both the source entity and each of - * the target entities are assumed to be already persisted, if they are marked - * as new or their status is unknown then an exception will be thrown. - * - * When using this method, all entities in `$targetEntities` will be appended to - * the source entity's property corresponding to this association object. - * - * This method does not check link uniqueness. - * - * ### Example: - * - * ``` - * $newTags = $tags->find('relevant')->toArray(); - * $articles->getAssociation('tags')->link($article, $newTags); - * ``` - * - * `$article->get('tags')` will contain all tags in `$newTags` after liking - * - * @param \Cake\Datasource\EntityInterface $sourceEntity the row belonging to the `source` side - * of this association - * @param array $targetEntities list of entities belonging to the `target` side - * of this association - * @param array $options list of options to be passed to the internal `save` call - * @throws \InvalidArgumentException when any of the values in $targetEntities is - * detected to not be already persisted - * @return bool true on success, false otherwise - */ - public function link(EntityInterface $sourceEntity, array $targetEntities, array $options = []) - { - $this->_checkPersistenceStatus($sourceEntity, $targetEntities); - $property = $this->getProperty(); - $links = $sourceEntity->get($property) ?: []; - $links = array_merge($links, $targetEntities); - $sourceEntity->set($property, $links); - - return $this->junction()->getConnection()->transactional( - function () use ($sourceEntity, $targetEntities, $options) { - return $this->_saveLinks($sourceEntity, $targetEntities, $options); - } - ); - } - - /** - * Removes all links between the passed source entity and each of the provided - * target entities. This method assumes that all passed objects are already persisted - * in the database and that each of them contain a primary key value. - * - * ### Options - * - * Additionally to the default options accepted by `Table::delete()`, the following - * keys are supported: - * - * - cleanProperty: Whether or not to remove all the objects in `$targetEntities` that - * are stored in `$sourceEntity` (default: true) - * - * By default this method will unset each of the entity objects stored inside the - * source entity. - * - * ### Example: - * - * ``` - * $article->tags = [$tag1, $tag2, $tag3, $tag4]; - * $tags = [$tag1, $tag2, $tag3]; - * $articles->getAssociation('tags')->unlink($article, $tags); - * ``` - * - * `$article->get('tags')` will contain only `[$tag4]` after deleting in the database - * - * @param \Cake\Datasource\EntityInterface $sourceEntity an entity persisted in the source table for - * this association - * @param array $targetEntities list of entities persisted in the target table for - * this association - * @param array|bool $options list of options to be passed to the internal `delete` call, - * or a `boolean` - * @throws \InvalidArgumentException if non persisted entities are passed or if - * any of them is lacking a primary key value - * @return bool Success - */ - public function unlink(EntityInterface $sourceEntity, array $targetEntities, $options = []) - { - if (is_bool($options)) { - $options = [ - 'cleanProperty' => $options - ]; - } else { - $options += ['cleanProperty' => true]; - } - - $this->_checkPersistenceStatus($sourceEntity, $targetEntities); - $property = $this->getProperty(); - - $this->junction()->getConnection()->transactional( - function () use ($sourceEntity, $targetEntities, $options) { - $links = $this->_collectJointEntities($sourceEntity, $targetEntities); - foreach ($links as $entity) { - $this->_junctionTable->delete($entity, $options); - } - } - ); - - $existing = $sourceEntity->get($property) ?: []; - if (!$options['cleanProperty'] || empty($existing)) { - return true; - } - - $storage = new SplObjectStorage(); - foreach ($targetEntities as $e) { - $storage->attach($e); - } - - foreach ($existing as $k => $e) { - if ($storage->contains($e)) { - unset($existing[$k]); - } - } - - $sourceEntity->set($property, array_values($existing)); - $sourceEntity->setDirty($property, false); - - return true; - } - - /** - * {@inheritDoc} - */ - public function setConditions($conditions) - { - parent::setConditions($conditions); - $this->_targetConditions = $this->_junctionConditions = null; - - return $this; - } - - /** - * Sets the current join table, either the name of the Table instance or the instance itself. - * - * @param string|\Cake\ORM\Table $through Name of the Table instance or the instance itself - * @return $this - */ - public function setThrough($through) - { - $this->_through = $through; - - return $this; - } - - /** - * Gets the current join table, either the name of the Table instance or the instance itself. - * - * @return string|\Cake\ORM\Table - */ - public function getThrough() - { - return $this->_through; - } - - /** - * Returns filtered conditions that reference the target table. - * - * Any string expressions, or expression objects will - * also be returned in this list. - * - * @return mixed Generally an array. If the conditions - * are not an array, the association conditions will be - * returned unmodified. - */ - protected function targetConditions() - { - if ($this->_targetConditions !== null) { - return $this->_targetConditions; - } - $conditions = $this->getConditions(); - if (!is_array($conditions)) { - return $conditions; - } - $matching = []; - $alias = $this->getAlias() . '.'; - foreach ($conditions as $field => $value) { - if (is_string($field) && strpos($field, $alias) === 0) { - $matching[$field] = $value; - } elseif (is_int($field) || $value instanceof ExpressionInterface) { - $matching[$field] = $value; - } - } - - return $this->_targetConditions = $matching; - } - - /** - * Returns filtered conditions that specifically reference - * the junction table. - * - * @return array - */ - protected function junctionConditions() - { - if ($this->_junctionConditions !== null) { - return $this->_junctionConditions; - } - $matching = []; - $conditions = $this->getConditions(); - if (!is_array($conditions)) { - return $matching; - } - $alias = $this->_junctionAssociationName() . '.'; - foreach ($conditions as $field => $value) { - $isString = is_string($field); - if ($isString && strpos($field, $alias) === 0) { - $matching[$field] = $value; - } - // Assume that operators contain junction conditions. - // Trying to manage complex conditions could result in incorrect queries. - if ($isString && in_array(strtoupper($field), ['OR', 'NOT', 'AND', 'XOR'])) { - $matching[$field] = $value; - } - } - - return $this->_junctionConditions = $matching; - } - - /** - * Proxies the finding operation to the target table's find method - * and modifies the query accordingly based of this association - * configuration. - * - * If your association includes conditions, the junction table will be - * included in the query's contained associations. - * - * @param string|array|null $type the type of query to perform, if an array is passed, - * it will be interpreted as the `$options` parameter - * @param array $options The options to for the find - * @see \Cake\ORM\Table::find() - * @return \Cake\ORM\Query - */ - public function find($type = null, array $options = []) - { - $type = $type ?: $this->getFinder(); - list($type, $opts) = $this->_extractFinder($type); - $query = $this->getTarget() - ->find($type, $options + $opts) - ->where($this->targetConditions()) - ->addDefaultTypes($this->getTarget()); - - if (!$this->junctionConditions()) { - return $query; - } - - $belongsTo = $this->junction()->getAssociation($this->getTarget()->getAlias()); - $conditions = $belongsTo->_joinCondition([ - 'foreignKey' => $this->getTargetForeignKey() - ]); - $conditions += $this->junctionConditions(); - - return $this->_appendJunctionJoin($query, $conditions); - } - - /** - * Append a join to the junction table. - * - * @param \Cake\ORM\Query $query The query to append. - * @param string|array $conditions The query conditions to use. - * @return \Cake\ORM\Query The modified query. - */ - protected function _appendJunctionJoin($query, $conditions) - { - $name = $this->_junctionAssociationName(); - $joins = $query->join(); - $matching = [ - $name => [ - 'table' => $this->junction()->getTable(), - 'conditions' => $conditions, - 'type' => QueryInterface::JOIN_TYPE_INNER - ] - ]; - - $assoc = $this->getTarget()->getAssociation($name); - $query - ->addDefaultTypes($assoc->getTarget()) - ->join($matching + $joins, [], true); - - return $query; - } - - /** - * Replaces existing association links between the source entity and the target - * with the ones passed. This method does a smart cleanup, links that are already - * persisted and present in `$targetEntities` will not be deleted, new links will - * be created for the passed target entities that are not already in the database - * and the rest will be removed. - * - * For example, if an article is linked to tags 'cake' and 'framework' and you pass - * to this method an array containing the entities for tags 'cake', 'php' and 'awesome', - * only the link for cake will be kept in database, the link for 'framework' will be - * deleted and the links for 'php' and 'awesome' will be created. - * - * Existing links are not deleted and created again, they are either left untouched - * or updated so that potential extra information stored in the joint row is not - * lost. Updating the link row can be done by making sure the corresponding passed - * target entity contains the joint property with its primary key and any extra - * information to be stored. - * - * On success, the passed `$sourceEntity` will contain `$targetEntities` as value - * in the corresponding property for this association. - * - * This method assumes that links between both the source entity and each of the - * target entities are unique. That is, for any given row in the source table there - * can only be one link in the junction table pointing to any other given row in - * the target table. - * - * Additional options for new links to be saved can be passed in the third argument, - * check `Table::save()` for information on the accepted options. - * - * ### Example: - * - * ``` - * $article->tags = [$tag1, $tag2, $tag3, $tag4]; - * $articles->save($article); - * $tags = [$tag1, $tag3]; - * $articles->getAssociation('tags')->replaceLinks($article, $tags); - * ``` - * - * `$article->get('tags')` will contain only `[$tag1, $tag3]` at the end - * - * @param \Cake\Datasource\EntityInterface $sourceEntity an entity persisted in the source table for - * this association - * @param array $targetEntities list of entities from the target table to be linked - * @param array $options list of options to be passed to the internal `save`/`delete` calls - * when persisting/updating new links, or deleting existing ones - * @throws \InvalidArgumentException if non persisted entities are passed or if - * any of them is lacking a primary key value - * @return bool success - */ - public function replaceLinks(EntityInterface $sourceEntity, array $targetEntities, array $options = []) - { - $bindingKey = (array)$this->getBindingKey(); - $primaryValue = $sourceEntity->extract($bindingKey); - - if (count(array_filter($primaryValue, 'strlen')) !== count($bindingKey)) { - $message = 'Could not find primary key value for source entity'; - throw new InvalidArgumentException($message); - } - - return $this->junction()->getConnection()->transactional( - function () use ($sourceEntity, $targetEntities, $primaryValue, $options) { - $foreignKey = array_map([$this->_junctionTable, 'aliasField'], (array)$this->getForeignKey()); - $hasMany = $this->getSource()->getAssociation($this->_junctionTable->getAlias()); - $existing = $hasMany->find('all') - ->where(array_combine($foreignKey, $primaryValue)); - - $associationConditions = $this->getConditions(); - if ($associationConditions) { - $existing->contain($this->getTarget()->getAlias()); - $existing->andWhere($associationConditions); - } - - $jointEntities = $this->_collectJointEntities($sourceEntity, $targetEntities); - $inserts = $this->_diffLinks($existing, $jointEntities, $targetEntities, $options); - - if ($inserts && !$this->_saveTarget($sourceEntity, $inserts, $options)) { - return false; - } - - $property = $this->getProperty(); - - if (count($inserts)) { - $inserted = array_combine( - array_keys($inserts), - (array)$sourceEntity->get($property) - ); - $targetEntities = $inserted + $targetEntities; - } - - ksort($targetEntities); - $sourceEntity->set($property, array_values($targetEntities)); - $sourceEntity->setDirty($property, false); - - return true; - } - ); - } - - /** - * Helper method used to delete the difference between the links passed in - * `$existing` and `$jointEntities`. This method will return the values from - * `$targetEntities` that were not deleted from calculating the difference. - * - * @param \Cake\ORM\Query $existing a query for getting existing links - * @param array $jointEntities link entities that should be persisted - * @param array $targetEntities entities in target table that are related to - * the `$jointEntities` - * @param array $options list of options accepted by `Table::delete()` - * @return array - */ - protected function _diffLinks($existing, $jointEntities, $targetEntities, $options = []) - { - $junction = $this->junction(); - $target = $this->getTarget(); - $belongsTo = $junction->getAssociation($target->getAlias()); - $foreignKey = (array)$this->getForeignKey(); - $assocForeignKey = (array)$belongsTo->getForeignKey(); - - $keys = array_merge($foreignKey, $assocForeignKey); - $deletes = $indexed = $present = []; - - foreach ($jointEntities as $i => $entity) { - $indexed[$i] = $entity->extract($keys); - $present[$i] = array_values($entity->extract($assocForeignKey)); - } - - foreach ($existing as $result) { - $fields = $result->extract($keys); - $found = false; - foreach ($indexed as $i => $data) { - if ($fields === $data) { - unset($indexed[$i]); - $found = true; - break; - } - } - - if (!$found) { - $deletes[] = $result; - } - } - - $primary = (array)$target->getPrimaryKey(); - $jointProperty = $this->_junctionProperty; - foreach ($targetEntities as $k => $entity) { - if (!($entity instanceof EntityInterface)) { - continue; - } - $key = array_values($entity->extract($primary)); - foreach ($present as $i => $data) { - if ($key === $data && !$entity->get($jointProperty)) { - unset($targetEntities[$k], $present[$i]); - break; - } - } - } - - if ($deletes) { - foreach ($deletes as $entity) { - $junction->delete($entity, $options); - } - } - - return $targetEntities; - } - - /** - * Throws an exception should any of the passed entities is not persisted. - * - * @param \Cake\Datasource\EntityInterface $sourceEntity the row belonging to the `source` side - * of this association - * @param array $targetEntities list of entities belonging to the `target` side - * of this association - * @return bool - * @throws \InvalidArgumentException - */ - protected function _checkPersistenceStatus($sourceEntity, array $targetEntities) - { - if ($sourceEntity->isNew()) { - $error = 'Source entity needs to be persisted before links can be created or removed.'; - throw new InvalidArgumentException($error); - } - - foreach ($targetEntities as $entity) { - if ($entity->isNew()) { - $error = 'Cannot link entities that have not been persisted yet.'; - throw new InvalidArgumentException($error); - } - } - - return true; - } - - /** - * Returns the list of joint entities that exist between the source entity - * and each of the passed target entities - * - * @param \Cake\Datasource\EntityInterface $sourceEntity The row belonging to the source side - * of this association. - * @param array $targetEntities The rows belonging to the target side of this - * association. - * @throws \InvalidArgumentException if any of the entities is lacking a primary - * key value - * @return array - */ - protected function _collectJointEntities($sourceEntity, $targetEntities) - { - $target = $this->getTarget(); - $source = $this->getSource(); - $junction = $this->junction(); - $jointProperty = $this->_junctionProperty; - $primary = (array)$target->getPrimaryKey(); - - $result = []; - $missing = []; - - foreach ($targetEntities as $entity) { - if (!($entity instanceof EntityInterface)) { - continue; - } - $joint = $entity->get($jointProperty); - - if (!$joint || !($joint instanceof EntityInterface)) { - $missing[] = $entity->extract($primary); - continue; - } - - $result[] = $joint; - } - - if (empty($missing)) { - return $result; - } - - $belongsTo = $junction->getAssociation($target->getAlias()); - $hasMany = $source->getAssociation($junction->getAlias()); - $foreignKey = (array)$this->getForeignKey(); - $assocForeignKey = (array)$belongsTo->getForeignKey(); - $sourceKey = $sourceEntity->extract((array)$source->getPrimaryKey()); - - foreach ($missing as $key) { - $unions[] = $hasMany->find('all') - ->where(array_combine($foreignKey, $sourceKey)) - ->andWhere(array_combine($assocForeignKey, $key)); - } - - $query = array_shift($unions); - foreach ($unions as $q) { - $query->union($q); - } - - return array_merge($result, $query->toArray()); - } - - /** - * Returns the name of the association from the target table to the junction table, - * this name is used to generate alias in the query and to later on retrieve the - * results. - * - * @return string - */ - protected function _junctionAssociationName() - { - if (!$this->_junctionAssociationName) { - $this->_junctionAssociationName = $this->getTarget() - ->getAssociation($this->junction()->getAlias()) - ->getName(); - } - - return $this->_junctionAssociationName; - } - - /** - * Sets the name of the junction table. - * If no arguments are passed the current configured name is returned. A default - * name based of the associated tables will be generated if none found. - * - * @param string|null $name The name of the junction table. - * @return string - */ - protected function _junctionTableName($name = null) - { - if ($name === null) { - if (empty($this->_junctionTableName)) { - $tablesNames = array_map('Cake\Utility\Inflector::underscore', [ - $this->getSource()->getTable(), - $this->getTarget()->getTable() - ]); - sort($tablesNames); - $this->_junctionTableName = implode('_', $tablesNames); - } - - return $this->_junctionTableName; - } - - return $this->_junctionTableName = $name; - } - - /** - * Parse extra options passed in the constructor. - * - * @param array $opts original list of options passed in constructor - * @return void - */ - protected function _options(array $opts) - { - if (!empty($opts['targetForeignKey'])) { - $this->setTargetForeignKey($opts['targetForeignKey']); - } - if (!empty($opts['joinTable'])) { - $this->_junctionTableName($opts['joinTable']); - } - if (!empty($opts['through'])) { - $this->setThrough($opts['through']); - } - if (!empty($opts['saveStrategy'])) { - $this->setSaveStrategy($opts['saveStrategy']); - } - if (isset($opts['sort'])) { - $this->setSort($opts['sort']); - } - } -} diff --git a/vendor/cakephp/cakephp/src/ORM/Association/DependentDeleteTrait.php b/vendor/cakephp/cakephp/src/ORM/Association/DependentDeleteTrait.php deleted file mode 100644 index aab6048..0000000 --- a/vendor/cakephp/cakephp/src/ORM/Association/DependentDeleteTrait.php +++ /dev/null @@ -1,49 +0,0 @@ -cascadeDelete($this, $entity, $options); - } -} diff --git a/vendor/cakephp/cakephp/src/ORM/Association/HasMany.php b/vendor/cakephp/cakephp/src/ORM/Association/HasMany.php deleted file mode 100644 index 725c2eb..0000000 --- a/vendor/cakephp/cakephp/src/ORM/Association/HasMany.php +++ /dev/null @@ -1,707 +0,0 @@ -getSource(); - } - - /** - * Sets the strategy that should be used for saving. - * - * @param string $strategy the strategy name to be used - * @throws \InvalidArgumentException if an invalid strategy name is passed - * @return $this - */ - public function setSaveStrategy($strategy) - { - if (!in_array($strategy, [self::SAVE_APPEND, self::SAVE_REPLACE])) { - $msg = sprintf('Invalid save strategy "%s"', $strategy); - throw new InvalidArgumentException($msg); - } - - $this->_saveStrategy = $strategy; - - return $this; - } - - /** - * Gets the strategy that should be used for saving. - * - * @return string the strategy to be used for saving - */ - public function getSaveStrategy() - { - return $this->_saveStrategy; - } - - /** - * Sets the strategy that should be used for saving. If called with no - * arguments, it will return the currently configured strategy - * - * @deprecated 3.4.0 Use setSaveStrategy()/getSaveStrategy() instead. - * @param string|null $strategy the strategy name to be used - * @throws \InvalidArgumentException if an invalid strategy name is passed - * @return string the strategy to be used for saving - */ - public function saveStrategy($strategy = null) - { - deprecationWarning( - 'HasMany::saveStrategy() is deprecated. ' . - 'Use setSaveStrategy()/getSaveStrategy() instead.' - ); - if ($strategy !== null) { - $this->setSaveStrategy($strategy); - } - - return $this->getSaveStrategy(); - } - - /** - * Takes an entity from the source table and looks if there is a field - * matching the property name for this association. The found entity will be - * saved on the target table for this association by passing supplied - * `$options` - * - * @param \Cake\Datasource\EntityInterface $entity an entity from the source table - * @param array $options options to be passed to the save method in the target table - * @return bool|\Cake\Datasource\EntityInterface false if $entity could not be saved, otherwise it returns - * the saved entity - * @see \Cake\ORM\Table::save() - * @throws \InvalidArgumentException when the association data cannot be traversed. - */ - public function saveAssociated(EntityInterface $entity, array $options = []) - { - $targetEntities = $entity->get($this->getProperty()); - - $isEmpty = in_array($targetEntities, [null, [], '', false], true); - if ($isEmpty) { - if ($entity->isNew() || - $this->getSaveStrategy() !== self::SAVE_REPLACE - ) { - return $entity; - } - - $targetEntities = []; - } - - if (!is_array($targetEntities) && - !($targetEntities instanceof Traversable) - ) { - $name = $this->getProperty(); - $message = sprintf('Could not save %s, it cannot be traversed', $name); - throw new InvalidArgumentException($message); - } - - $foreignKeyReference = array_combine( - (array)$this->getForeignKey(), - $entity->extract((array)$this->getBindingKey()) - ); - - $options['_sourceTable'] = $this->getSource(); - - if ($this->_saveStrategy === self::SAVE_REPLACE && - !$this->_unlinkAssociated($foreignKeyReference, $entity, $this->getTarget(), $targetEntities, $options) - ) { - return false; - } - - if (!$this->_saveTarget($foreignKeyReference, $entity, $targetEntities, $options)) { - return false; - } - - return $entity; - } - - /** - * Persists each of the entities into the target table and creates links between - * the parent entity and each one of the saved target entities. - * - * @param array $foreignKeyReference The foreign key reference defining the link between the - * target entity, and the parent entity. - * @param \Cake\Datasource\EntityInterface $parentEntity The source entity containing the target - * entities to be saved. - * @param array|\Traversable $entities list of entities to persist in target table and to - * link to the parent entity - * @param array $options list of options accepted by `Table::save()`. - * @return bool `true` on success, `false` otherwise. - */ - protected function _saveTarget(array $foreignKeyReference, EntityInterface $parentEntity, $entities, array $options) - { - $foreignKey = array_keys($foreignKeyReference); - $table = $this->getTarget(); - $original = $entities; - - foreach ($entities as $k => $entity) { - if (!($entity instanceof EntityInterface)) { - break; - } - - if (!empty($options['atomic'])) { - $entity = clone $entity; - } - - if ($foreignKeyReference !== $entity->extract($foreignKey)) { - $entity->set($foreignKeyReference, ['guard' => false]); - } - - if ($table->save($entity, $options)) { - $entities[$k] = $entity; - continue; - } - - if (!empty($options['atomic'])) { - $original[$k]->setErrors($entity->getErrors()); - $entity->set($this->getProperty(), $original); - - return false; - } - } - - $parentEntity->set($this->getProperty(), $entities); - - return true; - } - - /** - * Associates the source entity to each of the target entities provided. - * When using this method, all entities in `$targetEntities` will be appended to - * the source entity's property corresponding to this association object. - * - * This method does not check link uniqueness. - * Changes are persisted in the database and also in the source entity. - * - * ### Example: - * - * ``` - * $user = $users->get(1); - * $allArticles = $articles->find('all')->toArray(); - * $users->Articles->link($user, $allArticles); - * ``` - * - * `$user->get('articles')` will contain all articles in `$allArticles` after linking - * - * @param \Cake\Datasource\EntityInterface $sourceEntity the row belonging to the `source` side - * of this association - * @param array $targetEntities list of entities belonging to the `target` side - * of this association - * @param array $options list of options to be passed to the internal `save` call - * @return bool true on success, false otherwise - */ - public function link(EntityInterface $sourceEntity, array $targetEntities, array $options = []) - { - $saveStrategy = $this->getSaveStrategy(); - $this->setSaveStrategy(self::SAVE_APPEND); - $property = $this->getProperty(); - - $currentEntities = array_unique( - array_merge( - (array)$sourceEntity->get($property), - $targetEntities - ) - ); - - $sourceEntity->set($property, $currentEntities); - - $savedEntity = $this->getConnection()->transactional(function () use ($sourceEntity, $options) { - return $this->saveAssociated($sourceEntity, $options); - }); - - $ok = ($savedEntity instanceof EntityInterface); - - $this->setSaveStrategy($saveStrategy); - - if ($ok) { - $sourceEntity->set($property, $savedEntity->get($property)); - $sourceEntity->setDirty($property, false); - } - - return $ok; - } - - /** - * Removes all links between the passed source entity and each of the provided - * target entities. This method assumes that all passed objects are already persisted - * in the database and that each of them contain a primary key value. - * - * ### Options - * - * Additionally to the default options accepted by `Table::delete()`, the following - * keys are supported: - * - * - cleanProperty: Whether or not to remove all the objects in `$targetEntities` that - * are stored in `$sourceEntity` (default: true) - * - * By default this method will unset each of the entity objects stored inside the - * source entity. - * - * Changes are persisted in the database and also in the source entity. - * - * ### Example: - * - * ``` - * $user = $users->get(1); - * $user->articles = [$article1, $article2, $article3, $article4]; - * $users->save($user, ['Associated' => ['Articles']]); - * $allArticles = [$article1, $article2, $article3]; - * $users->Articles->unlink($user, $allArticles); - * ``` - * - * `$article->get('articles')` will contain only `[$article4]` after deleting in the database - * - * @param \Cake\Datasource\EntityInterface $sourceEntity an entity persisted in the source table for - * this association - * @param array $targetEntities list of entities persisted in the target table for - * this association - * @param array $options list of options to be passed to the internal `delete` call - * @throws \InvalidArgumentException if non persisted entities are passed or if - * any of them is lacking a primary key value - * @return void - */ - public function unlink(EntityInterface $sourceEntity, array $targetEntities, $options = []) - { - if (is_bool($options)) { - $options = [ - 'cleanProperty' => $options - ]; - } else { - $options += ['cleanProperty' => true]; - } - if (count($targetEntities) === 0) { - return; - } - - $foreignKey = (array)$this->getForeignKey(); - $target = $this->getTarget(); - $targetPrimaryKey = array_merge((array)$target->getPrimaryKey(), $foreignKey); - $property = $this->getProperty(); - - $conditions = [ - 'OR' => (new Collection($targetEntities)) - ->map(function ($entity) use ($targetPrimaryKey) { - return $entity->extract($targetPrimaryKey); - }) - ->toList() - ]; - - $this->_unlink($foreignKey, $target, $conditions, $options); - - $result = $sourceEntity->get($property); - if ($options['cleanProperty'] && $result !== null) { - $sourceEntity->set( - $property, - (new Collection($sourceEntity->get($property))) - ->reject( - function ($assoc) use ($targetEntities) { - return in_array($assoc, $targetEntities); - } - ) - ->toList() - ); - } - - $sourceEntity->setDirty($property, false); - } - - /** - * Replaces existing association links between the source entity and the target - * with the ones passed. This method does a smart cleanup, links that are already - * persisted and present in `$targetEntities` will not be deleted, new links will - * be created for the passed target entities that are not already in the database - * and the rest will be removed. - * - * For example, if an author has many articles, such as 'article1','article 2' and 'article 3' and you pass - * to this method an array containing the entities for articles 'article 1' and 'article 4', - * only the link for 'article 1' will be kept in database, the links for 'article 2' and 'article 3' will be - * deleted and the link for 'article 4' will be created. - * - * Existing links are not deleted and created again, they are either left untouched - * or updated. - * - * This method does not check link uniqueness. - * - * On success, the passed `$sourceEntity` will contain `$targetEntities` as value - * in the corresponding property for this association. - * - * Additional options for new links to be saved can be passed in the third argument, - * check `Table::save()` for information on the accepted options. - * - * ### Example: - * - * ``` - * $author->articles = [$article1, $article2, $article3, $article4]; - * $authors->save($author); - * $articles = [$article1, $article3]; - * $authors->getAssociation('articles')->replace($author, $articles); - * ``` - * - * `$author->get('articles')` will contain only `[$article1, $article3]` at the end - * - * @param \Cake\Datasource\EntityInterface $sourceEntity an entity persisted in the source table for - * this association - * @param array $targetEntities list of entities from the target table to be linked - * @param array $options list of options to be passed to the internal `save`/`delete` calls - * when persisting/updating new links, or deleting existing ones - * @throws \InvalidArgumentException if non persisted entities are passed or if - * any of them is lacking a primary key value - * @return bool success - */ - public function replace(EntityInterface $sourceEntity, array $targetEntities, array $options = []) - { - $property = $this->getProperty(); - $sourceEntity->set($property, $targetEntities); - $saveStrategy = $this->getSaveStrategy(); - $this->setSaveStrategy(self::SAVE_REPLACE); - $result = $this->saveAssociated($sourceEntity, $options); - $ok = ($result instanceof EntityInterface); - - if ($ok) { - $sourceEntity = $result; - } - $this->setSaveStrategy($saveStrategy); - - return $ok; - } - - /** - * Deletes/sets null the related objects according to the dependency between source and targets and foreign key nullability - * Skips deleting records present in $remainingEntities - * - * @param array $foreignKeyReference The foreign key reference defining the link between the - * target entity, and the parent entity. - * @param \Cake\Datasource\EntityInterface $entity the entity which should have its associated entities unassigned - * @param \Cake\ORM\Table $target The associated table - * @param array $remainingEntities Entities that should not be deleted - * @param array $options list of options accepted by `Table::delete()` - * @return bool success - */ - protected function _unlinkAssociated(array $foreignKeyReference, EntityInterface $entity, Table $target, array $remainingEntities = [], array $options = []) - { - $primaryKey = (array)$target->getPrimaryKey(); - $exclusions = new Collection($remainingEntities); - $exclusions = $exclusions->map( - function ($ent) use ($primaryKey) { - return $ent->extract($primaryKey); - } - ) - ->filter( - function ($v) { - return !in_array(null, array_values($v), true); - } - ) - ->toArray(); - - $conditions = $foreignKeyReference; - - if (count($exclusions) > 0) { - $conditions = [ - 'NOT' => [ - 'OR' => $exclusions - ], - $foreignKeyReference - ]; - } - - return $this->_unlink(array_keys($foreignKeyReference), $target, $conditions, $options); - } - - /** - * Deletes/sets null the related objects matching $conditions. - * The action which is taken depends on the dependency between source and targets and also on foreign key nullability - * - * @param array $foreignKey array of foreign key properties - * @param \Cake\ORM\Table $target The associated table - * @param array $conditions The conditions that specifies what are the objects to be unlinked - * @param array $options list of options accepted by `Table::delete()` - * @return bool success - */ - protected function _unlink(array $foreignKey, Table $target, array $conditions = [], array $options = []) - { - $mustBeDependent = (!$this->_foreignKeyAcceptsNull($target, $foreignKey) || $this->getDependent()); - - if ($mustBeDependent) { - if ($this->_cascadeCallbacks) { - $conditions = new QueryExpression($conditions); - $conditions->traverse(function ($entry) use ($target) { - if ($entry instanceof FieldInterface) { - $entry->setField($target->aliasField($entry->getField())); - } - }); - $query = $this->find('all')->where($conditions); - $ok = true; - foreach ($query as $assoc) { - $ok = $ok && $target->delete($assoc, $options); - } - - return $ok; - } - - $conditions = array_merge($conditions, $this->getConditions()); - $target->deleteAll($conditions); - - return true; - } - - $updateFields = array_fill_keys($foreignKey, null); - $conditions = array_merge($conditions, $this->getConditions()); - $target->updateAll($updateFields, $conditions); - - return true; - } - - /** - * Checks the nullable flag of the foreign key - * - * @param \Cake\ORM\Table $table the table containing the foreign key - * @param array $properties the list of fields that compose the foreign key - * @return bool - */ - protected function _foreignKeyAcceptsNull(Table $table, array $properties) - { - return !in_array( - false, - array_map( - function ($prop) use ($table) { - return $table->getSchema()->isNullable($prop); - }, - $properties - ) - ); - } - - /** - * Get the relationship type. - * - * @return string - */ - public function type() - { - return self::ONE_TO_MANY; - } - - /** - * Whether this association can be expressed directly in a query join - * - * @param array $options custom options key that could alter the return value - * @return bool if the 'matching' key in $option is true then this function - * will return true, false otherwise - */ - public function canBeJoined(array $options = []) - { - return !empty($options['matching']); - } - - /** - * Gets the name of the field representing the foreign key to the source table. - * - * @return string - */ - public function getForeignKey() - { - if ($this->_foreignKey === null) { - $this->_foreignKey = $this->_modelKey($this->getSource()->getTable()); - } - - return $this->_foreignKey; - } - - /** - * Sets the sort order in which target records should be returned. - * - * @param mixed $sort A find() compatible order clause - * @return $this - */ - public function setSort($sort) - { - $this->_sort = $sort; - - return $this; - } - - /** - * Gets the sort order in which target records should be returned. - * - * @return mixed - */ - public function getSort() - { - return $this->_sort; - } - - /** - * Sets the sort order in which target records should be returned. - * If no arguments are passed the currently configured value is returned - * - * @deprecated 3.4.0 Use setSort()/getSort() instead. - * @param mixed $sort A find() compatible order clause - * @return mixed - */ - public function sort($sort = null) - { - deprecationWarning( - 'HasMany::sort() is deprecated. ' . - 'Use setSort()/getSort() instead.' - ); - if ($sort !== null) { - $this->setSort($sort); - } - - return $this->getSort(); - } - - /** - * {@inheritDoc} - */ - public function defaultRowValue($row, $joined) - { - $sourceAlias = $this->getSource()->getAlias(); - if (isset($row[$sourceAlias])) { - $row[$sourceAlias][$this->getProperty()] = $joined ? null : []; - } - - return $row; - } - - /** - * Parse extra options passed in the constructor. - * - * @param array $opts original list of options passed in constructor - * @return void - */ - protected function _options(array $opts) - { - if (!empty($opts['saveStrategy'])) { - $this->setSaveStrategy($opts['saveStrategy']); - } - if (isset($opts['sort'])) { - $this->setSort($opts['sort']); - } - } - - /** - * {@inheritDoc} - * - * @return \Closure - */ - public function eagerLoader(array $options) - { - $loader = new SelectLoader([ - 'alias' => $this->getAlias(), - 'sourceAlias' => $this->getSource()->getAlias(), - 'targetAlias' => $this->getTarget()->getAlias(), - 'foreignKey' => $this->getForeignKey(), - 'bindingKey' => $this->getBindingKey(), - 'strategy' => $this->getStrategy(), - 'associationType' => $this->type(), - 'sort' => $this->getSort(), - 'finder' => [$this, 'find'] - ]); - - return $loader->buildEagerLoader($options); - } - - /** - * {@inheritDoc} - */ - public function cascadeDelete(EntityInterface $entity, array $options = []) - { - $helper = new DependentDeleteHelper(); - - return $helper->cascadeDelete($this, $entity, $options); - } -} diff --git a/vendor/cakephp/cakephp/src/ORM/Association/HasOne.php b/vendor/cakephp/cakephp/src/ORM/Association/HasOne.php deleted file mode 100644 index 88e6b49..0000000 --- a/vendor/cakephp/cakephp/src/ORM/Association/HasOne.php +++ /dev/null @@ -1,155 +0,0 @@ -_foreignKey === null) { - $this->_foreignKey = $this->_modelKey($this->getSource()->getAlias()); - } - - return $this->_foreignKey; - } - - /** - * Returns default property name based on association name. - * - * @return string - */ - protected function _propertyName() - { - list(, $name) = pluginSplit($this->_name); - - return Inflector::underscore(Inflector::singularize($name)); - } - - /** - * Returns whether or not the passed table is the owning side for this - * association. This means that rows in the 'target' table would miss important - * or required information if the row in 'source' did not exist. - * - * @param \Cake\ORM\Table $side The potential Table with ownership - * @return bool - */ - public function isOwningSide(Table $side) - { - return $side === $this->getSource(); - } - - /** - * Get the relationship type. - * - * @return string - */ - public function type() - { - return self::ONE_TO_ONE; - } - - /** - * Takes an entity from the source table and looks if there is a field - * matching the property name for this association. The found entity will be - * saved on the target table for this association by passing supplied - * `$options` - * - * @param \Cake\Datasource\EntityInterface $entity an entity from the source table - * @param array $options options to be passed to the save method in the target table - * @return bool|\Cake\Datasource\EntityInterface false if $entity could not be saved, otherwise it returns - * the saved entity - * @see \Cake\ORM\Table::save() - */ - public function saveAssociated(EntityInterface $entity, array $options = []) - { - $targetEntity = $entity->get($this->getProperty()); - if (empty($targetEntity) || !($targetEntity instanceof EntityInterface)) { - return $entity; - } - - $properties = array_combine( - (array)$this->getForeignKey(), - $entity->extract((array)$this->getBindingKey()) - ); - $targetEntity->set($properties, ['guard' => false]); - - if (!$this->getTarget()->save($targetEntity, $options)) { - $targetEntity->unsetProperty(array_keys($properties)); - - return false; - } - - return $entity; - } - - /** - * {@inheritDoc} - * - * @return \Closure - */ - public function eagerLoader(array $options) - { - $loader = new SelectLoader([ - 'alias' => $this->getAlias(), - 'sourceAlias' => $this->getSource()->getAlias(), - 'targetAlias' => $this->getTarget()->getAlias(), - 'foreignKey' => $this->getForeignKey(), - 'bindingKey' => $this->getBindingKey(), - 'strategy' => $this->getStrategy(), - 'associationType' => $this->type(), - 'finder' => [$this, 'find'] - ]); - - return $loader->buildEagerLoader($options); - } - - /** - * {@inheritDoc} - */ - public function cascadeDelete(EntityInterface $entity, array $options = []) - { - $helper = new DependentDeleteHelper(); - - return $helper->cascadeDelete($this, $entity, $options); - } -} diff --git a/vendor/cakephp/cakephp/src/ORM/AssociationCollection.php b/vendor/cakephp/cakephp/src/ORM/AssociationCollection.php deleted file mode 100644 index 5098116..0000000 --- a/vendor/cakephp/cakephp/src/ORM/AssociationCollection.php +++ /dev/null @@ -1,391 +0,0 @@ -_tableLocator = $tableLocator; - } - } - - /** - * Add an association to the collection - * - * If the alias added contains a `.` the part preceding the `.` will be dropped. - * This makes using plugins simpler as the Plugin.Class syntax is frequently used. - * - * @param string $alias The association alias - * @param \Cake\ORM\Association $association The association to add. - * @return \Cake\ORM\Association The association object being added. - */ - public function add($alias, Association $association) - { - list(, $alias) = pluginSplit($alias); - - return $this->_items[strtolower($alias)] = $association; - } - - /** - * Creates and adds the Association object to this collection. - * - * @param string $className The name of association class. - * @param string $associated The alias for the target table. - * @param array $options List of options to configure the association definition. - * @return \Cake\ORM\Association - * @throws InvalidArgumentException - */ - public function load($className, $associated, array $options = []) - { - $options += [ - 'tableLocator' => $this->getTableLocator() - ]; - - $association = new $className($associated, $options); - if (!$association instanceof Association) { - $message = sprintf('The association must extend `%s` class, `%s` given.', Association::class, get_class($association)); - throw new InvalidArgumentException($message); - } - - return $this->add($association->getName(), $association); - } - - /** - * Fetch an attached association by name. - * - * @param string $alias The association alias to get. - * @return \Cake\ORM\Association|null Either the association or null. - */ - public function get($alias) - { - $alias = strtolower($alias); - if (isset($this->_items[$alias])) { - return $this->_items[$alias]; - } - - return null; - } - - /** - * Fetch an association by property name. - * - * @param string $prop The property to find an association by. - * @return \Cake\ORM\Association|null Either the association or null. - */ - public function getByProperty($prop) - { - foreach ($this->_items as $assoc) { - if ($assoc->getProperty() === $prop) { - return $assoc; - } - } - - return null; - } - - /** - * Check for an attached association by name. - * - * @param string $alias The association alias to get. - * @return bool Whether or not the association exists. - */ - public function has($alias) - { - return isset($this->_items[strtolower($alias)]); - } - - /** - * Get the names of all the associations in the collection. - * - * @return array - */ - public function keys() - { - return array_keys($this->_items); - } - - /** - * Get an array of associations matching a specific type. - * - * @param string|array $class The type of associations you want. - * For example 'BelongsTo' or array like ['BelongsTo', 'HasOne'] - * @return array An array of Association objects. - * @deprecated 3.5.3 Use getByType() instead. - */ - public function type($class) - { - deprecationWarning( - 'AssociationCollection::type() is deprecated. ' . - 'Use getByType() instead.' - ); - - return $this->getByType($class); - } - - /** - * Get an array of associations matching a specific type. - * - * @param string|array $class The type of associations you want. - * For example 'BelongsTo' or array like ['BelongsTo', 'HasOne'] - * @return array An array of Association objects. - * @since 3.5.3 - */ - public function getByType($class) - { - $class = array_map('strtolower', (array)$class); - - $out = array_filter($this->_items, function ($assoc) use ($class) { - list(, $name) = namespaceSplit(get_class($assoc)); - - return in_array(strtolower($name), $class, true); - }); - - return array_values($out); - } - - /** - * Drop/remove an association. - * - * Once removed the association will not longer be reachable - * - * @param string $alias The alias name. - * @return void - */ - public function remove($alias) - { - unset($this->_items[strtolower($alias)]); - } - - /** - * Remove all registered associations. - * - * Once removed associations will not longer be reachable - * - * @return void - */ - public function removeAll() - { - foreach ($this->_items as $alias => $object) { - $this->remove($alias); - } - } - - /** - * Save all the associations that are parents of the given entity. - * - * Parent associations include any association where the given table - * is the owning side. - * - * @param \Cake\ORM\Table $table The table entity is for. - * @param \Cake\Datasource\EntityInterface $entity The entity to save associated data for. - * @param array $associations The list of associations to save parents from. - * associations not in this list will not be saved. - * @param array $options The options for the save operation. - * @return bool Success - */ - public function saveParents(Table $table, EntityInterface $entity, $associations, array $options = []) - { - if (empty($associations)) { - return true; - } - - return $this->_saveAssociations($table, $entity, $associations, $options, false); - } - - /** - * Save all the associations that are children of the given entity. - * - * Child associations include any association where the given table - * is not the owning side. - * - * @param \Cake\ORM\Table $table The table entity is for. - * @param \Cake\Datasource\EntityInterface $entity The entity to save associated data for. - * @param array $associations The list of associations to save children from. - * associations not in this list will not be saved. - * @param array $options The options for the save operation. - * @return bool Success - */ - public function saveChildren(Table $table, EntityInterface $entity, array $associations, array $options) - { - if (empty($associations)) { - return true; - } - - return $this->_saveAssociations($table, $entity, $associations, $options, true); - } - - /** - * Helper method for saving an association's data. - * - * @param \Cake\ORM\Table $table The table the save is currently operating on - * @param \Cake\Datasource\EntityInterface $entity The entity to save - * @param array $associations Array of associations to save. - * @param array $options Original options - * @param bool $owningSide Compared with association classes' - * isOwningSide method. - * @return bool Success - * @throws \InvalidArgumentException When an unknown alias is used. - */ - protected function _saveAssociations($table, $entity, $associations, $options, $owningSide) - { - unset($options['associated']); - foreach ($associations as $alias => $nested) { - if (is_int($alias)) { - $alias = $nested; - $nested = []; - } - $relation = $this->get($alias); - if (!$relation) { - $msg = sprintf( - 'Cannot save %s, it is not associated to %s', - $alias, - $table->getAlias() - ); - throw new InvalidArgumentException($msg); - } - if ($relation->isOwningSide($table) !== $owningSide) { - continue; - } - if (!$this->_save($relation, $entity, $nested, $options)) { - return false; - } - } - - return true; - } - - /** - * Helper method for saving an association's data. - * - * @param \Cake\ORM\Association $association The association object to save with. - * @param \Cake\Datasource\EntityInterface $entity The entity to save - * @param array $nested Options for deeper associations - * @param array $options Original options - * @return bool Success - */ - protected function _save($association, $entity, $nested, $options) - { - if (!$entity->isDirty($association->getProperty())) { - return true; - } - if (!empty($nested)) { - $options = (array)$nested + $options; - } - - return (bool)$association->saveAssociated($entity, $options); - } - - /** - * Cascade a delete across the various associations. - * Cascade first across associations for which cascadeCallbacks is true. - * - * @param \Cake\Datasource\EntityInterface $entity The entity to delete associations for. - * @param array $options The options used in the delete operation. - * @return void - */ - public function cascadeDelete(EntityInterface $entity, array $options) - { - $noCascade = $this->_getNoCascadeItems($entity, $options); - foreach ($noCascade as $assoc) { - $assoc->cascadeDelete($entity, $options); - } - } - - /** - * Returns items that have no cascade callback. - * - * @param \Cake\Datasource\EntityInterface $entity The entity to delete associations for. - * @param array $options The options used in the delete operation. - * @return \Cake\ORM\Association[] - */ - protected function _getNoCascadeItems($entity, $options) - { - $noCascade = []; - foreach ($this->_items as $assoc) { - if (!$assoc->getCascadeCallbacks()) { - $noCascade[] = $assoc; - continue; - } - $assoc->cascadeDelete($entity, $options); - } - - return $noCascade; - } - - /** - * Returns an associative array of association names out a mixed - * array. If true is passed, then it returns all association names - * in this collection. - * - * @param bool|array $keys the list of association names to normalize - * @return array - */ - public function normalizeKeys($keys) - { - if ($keys === true) { - $keys = $this->keys(); - } - - if (empty($keys)) { - return []; - } - - return $this->_normalizeAssociations($keys); - } - - /** - * Allow looping through the associations - * - * @return \ArrayIterator - */ - public function getIterator() - { - return new ArrayIterator($this->_items); - } -} diff --git a/vendor/cakephp/cakephp/src/ORM/AssociationsNormalizerTrait.php b/vendor/cakephp/cakephp/src/ORM/AssociationsNormalizerTrait.php deleted file mode 100644 index 335804b..0000000 --- a/vendor/cakephp/cakephp/src/ORM/AssociationsNormalizerTrait.php +++ /dev/null @@ -1,67 +0,0 @@ - $options) { - $pointer =& $result; - - if (is_int($table)) { - $table = $options; - $options = []; - } - - if (!strpos($table, '.')) { - $result[$table] = $options; - continue; - } - - $path = explode('.', $table); - $table = array_pop($path); - $first = array_shift($path); - $pointer += [$first => []]; - $pointer =& $pointer[$first]; - $pointer += ['associated' => []]; - - foreach ($path as $t) { - $pointer += ['associated' => []]; - $pointer['associated'] += [$t => []]; - $pointer['associated'][$t] += ['associated' => []]; - $pointer =& $pointer['associated'][$t]; - } - - $pointer['associated'] += [$table => []]; - $pointer['associated'][$table] = $options + $pointer['associated'][$table]; - } - - return isset($result['associated']) ? $result['associated'] : $result; - } -} diff --git a/vendor/cakephp/cakephp/src/ORM/Behavior.php b/vendor/cakephp/cakephp/src/ORM/Behavior.php deleted file mode 100644 index 7f434d7..0000000 --- a/vendor/cakephp/cakephp/src/ORM/Behavior.php +++ /dev/null @@ -1,419 +0,0 @@ -doSomething($arg1, $arg2);`. - * - * ### Callback methods - * - * Behaviors can listen to any events fired on a Table. By default - * CakePHP provides a number of lifecycle events your behaviors can - * listen to: - * - * - `beforeFind(Event $event, Query $query, ArrayObject $options, boolean $primary)` - * Fired before each find operation. By stopping the event and supplying a - * return value you can bypass the find operation entirely. Any changes done - * to the $query instance will be retained for the rest of the find. The - * $primary parameter indicates whether or not this is the root query, - * or an associated query. - * - * - `buildValidator(Event $event, Validator $validator, string $name)` - * Fired when the validator object identified by $name is being built. You can use this - * callback to add validation rules or add validation providers. - * - * - `buildRules(Event $event, RulesChecker $rules)` - * Fired when the rules checking object for the table is being built. You can use this - * callback to add more rules to the set. - * - * - `beforeRules(Event $event, EntityInterface $entity, ArrayObject $options, $operation)` - * Fired before an entity is validated using by a rules checker. By stopping this event, - * you can return the final value of the rules checking operation. - * - * - `afterRules(Event $event, EntityInterface $entity, ArrayObject $options, bool $result, $operation)` - * Fired after the rules have been checked on the entity. By stopping this event, - * you can return the final value of the rules checking operation. - * - * - `beforeSave(Event $event, EntityInterface $entity, ArrayObject $options)` - * Fired before each entity is saved. Stopping this event will abort the save - * operation. When the event is stopped the result of the event will be returned. - * - * - `afterSave(Event $event, EntityInterface $entity, ArrayObject $options)` - * Fired after an entity is saved. - * - * - `beforeDelete(Event $event, EntityInterface $entity, ArrayObject $options)` - * Fired before an entity is deleted. By stopping this event you will abort - * the delete operation. - * - * - `afterDelete(Event $event, EntityInterface $entity, ArrayObject $options)` - * Fired after an entity has been deleted. - * - * In addition to the core events, behaviors can respond to any - * event fired from your Table classes including custom application - * specific ones. - * - * You can set the priority of a behaviors callbacks by using the - * `priority` setting when attaching a behavior. This will set the - * priority for all the callbacks a behavior provides. - * - * ### Finder methods - * - * Behaviors can provide finder methods that hook into a Table's - * find() method. Custom finders are a great way to provide preset - * queries that relate to your behavior. For example a SluggableBehavior - * could provide a find('slugged') finder. Behavior finders - * are implemented the same as other finders. Any method - * starting with `find` will be setup as a finder. Your finder - * methods should expect the following arguments: - * - * ``` - * findSlugged(Query $query, array $options) - * ``` - * - * @see \Cake\ORM\Table::addBehavior() - * @see \Cake\Event\EventManager - * @mixin \Cake\Core\InstanceConfigTrait - */ -class Behavior implements EventListenerInterface -{ - - use InstanceConfigTrait; - - /** - * Table instance. - * - * @var \Cake\ORM\Table - */ - protected $_table; - - /** - * Reflection method cache for behaviors. - * - * Stores the reflected method + finder methods per class. - * This prevents reflecting the same class multiple times in a single process. - * - * @var array - */ - protected static $_reflectionCache = []; - - /** - * Default configuration - * - * These are merged with user-provided configuration when the behavior is used. - * - * @var array - */ - protected $_defaultConfig = []; - - /** - * Constructor - * - * Merges config with the default and store in the config property - * - * @param \Cake\ORM\Table $table The table this behavior is attached to. - * @param array $config The config for this behavior. - */ - public function __construct(Table $table, array $config = []) - { - $config = $this->_resolveMethodAliases( - 'implementedFinders', - $this->_defaultConfig, - $config - ); - $config = $this->_resolveMethodAliases( - 'implementedMethods', - $this->_defaultConfig, - $config - ); - $this->_table = $table; - $this->setConfig($config); - $this->initialize($config); - } - - /** - * Constructor hook method. - * - * Implement this method to avoid having to overwrite - * the constructor and call parent. - * - * @param array $config The configuration settings provided to this behavior. - * @return void - */ - public function initialize(array $config) - { - } - - /** - * Get the table instance this behavior is bound to. - * - * @return \Cake\ORM\Table The bound table instance. - */ - public function getTable() - { - return $this->_table; - } - - /** - * Removes aliased methods that would otherwise be duplicated by userland configuration. - * - * @param string $key The key to filter. - * @param array $defaults The default method mappings. - * @param array $config The customized method mappings. - * @return array A de-duped list of config data. - */ - protected function _resolveMethodAliases($key, $defaults, $config) - { - if (!isset($defaults[$key], $config[$key])) { - return $config; - } - if (isset($config[$key]) && $config[$key] === []) { - $this->setConfig($key, [], false); - unset($config[$key]); - - return $config; - } - - $indexed = array_flip($defaults[$key]); - $indexedCustom = array_flip($config[$key]); - foreach ($indexed as $method => $alias) { - if (!isset($indexedCustom[$method])) { - $indexedCustom[$method] = $alias; - } - } - $this->setConfig($key, array_flip($indexedCustom), false); - unset($config[$key]); - - return $config; - } - - /** - * verifyConfig - * - * Checks that implemented keys contain values pointing at callable. - * - * @return void - * @throws \Cake\Core\Exception\Exception if config are invalid - */ - public function verifyConfig() - { - $keys = ['implementedFinders', 'implementedMethods']; - foreach ($keys as $key) { - if (!isset($this->_config[$key])) { - continue; - } - - foreach ($this->_config[$key] as $method) { - if (!is_callable([$this, $method])) { - throw new Exception(sprintf('The method %s is not callable on class %s', $method, get_class($this))); - } - } - } - } - - /** - * Gets the Model callbacks this behavior is interested in. - * - * By defining one of the callback methods a behavior is assumed - * to be interested in the related event. - * - * Override this method if you need to add non-conventional event listeners. - * Or if you want your behavior to listen to non-standard events. - * - * @return array - */ - public function implementedEvents() - { - $eventMap = [ - 'Model.beforeMarshal' => 'beforeMarshal', - 'Model.beforeFind' => 'beforeFind', - 'Model.beforeSave' => 'beforeSave', - 'Model.afterSave' => 'afterSave', - 'Model.afterSaveCommit' => 'afterSaveCommit', - 'Model.beforeDelete' => 'beforeDelete', - 'Model.afterDelete' => 'afterDelete', - 'Model.afterDeleteCommit' => 'afterDeleteCommit', - 'Model.buildValidator' => 'buildValidator', - 'Model.buildRules' => 'buildRules', - 'Model.beforeRules' => 'beforeRules', - 'Model.afterRules' => 'afterRules', - ]; - $config = $this->getConfig(); - $priority = isset($config['priority']) ? $config['priority'] : null; - $events = []; - - foreach ($eventMap as $event => $method) { - if (!method_exists($this, $method)) { - continue; - } - if ($priority === null) { - $events[$event] = $method; - } else { - $events[$event] = [ - 'callable' => $method, - 'priority' => $priority - ]; - } - } - - return $events; - } - - /** - * implementedFinders - * - * Provides an alias->methodname map of which finders a behavior implements. Example: - * - * ``` - * [ - * 'this' => 'findThis', - * 'alias' => 'findMethodName' - * ] - * ``` - * - * With the above example, a call to `$Table->find('this')` will call `$Behavior->findThis()` - * and a call to `$Table->find('alias')` will call `$Behavior->findMethodName()` - * - * It is recommended, though not required, to define implementedFinders in the config property - * of child classes such that it is not necessary to use reflections to derive the available - * method list. See core behaviors for examples - * - * @return array - */ - public function implementedFinders() - { - $methods = $this->getConfig('implementedFinders'); - if (isset($methods)) { - return $methods; - } - - return $this->_reflectionCache()['finders']; - } - - /** - * implementedMethods - * - * Provides an alias->methodname map of which methods a behavior implements. Example: - * - * ``` - * [ - * 'method' => 'method', - * 'aliasedmethod' => 'somethingElse' - * ] - * ``` - * - * With the above example, a call to `$Table->method()` will call `$Behavior->method()` - * and a call to `$Table->aliasedmethod()` will call `$Behavior->somethingElse()` - * - * It is recommended, though not required, to define implementedFinders in the config property - * of child classes such that it is not necessary to use reflections to derive the available - * method list. See core behaviors for examples - * - * @return array - */ - public function implementedMethods() - { - $methods = $this->getConfig('implementedMethods'); - if (isset($methods)) { - return $methods; - } - - return $this->_reflectionCache()['methods']; - } - - /** - * Gets the methods implemented by this behavior - * - * Uses the implementedEvents() method to exclude callback methods. - * Methods starting with `_` will be ignored, as will methods - * declared on Cake\ORM\Behavior - * - * @return array - */ - protected function _reflectionCache() - { - $class = get_class($this); - if (isset(self::$_reflectionCache[$class])) { - return self::$_reflectionCache[$class]; - } - - $events = $this->implementedEvents(); - $eventMethods = []; - foreach ($events as $e => $binding) { - if (is_array($binding) && isset($binding['callable'])) { - /* @var string $callable */ - $callable = $binding['callable']; - $binding = $callable; - } - $eventMethods[$binding] = true; - } - - $baseClass = 'Cake\ORM\Behavior'; - if (isset(self::$_reflectionCache[$baseClass])) { - $baseMethods = self::$_reflectionCache[$baseClass]; - } else { - $baseMethods = get_class_methods($baseClass); - self::$_reflectionCache[$baseClass] = $baseMethods; - } - - $return = [ - 'finders' => [], - 'methods' => [] - ]; - - $reflection = new ReflectionClass($class); - - foreach ($reflection->getMethods(ReflectionMethod::IS_PUBLIC) as $method) { - $methodName = $method->getName(); - if (in_array($methodName, $baseMethods) || - isset($eventMethods[$methodName]) - ) { - continue; - } - - if (substr($methodName, 0, 4) === 'find') { - $return['finders'][lcfirst(substr($methodName, 4))] = $methodName; - } else { - $return['methods'][$methodName] = $methodName; - } - } - - return self::$_reflectionCache[$class] = $return; - } -} diff --git a/vendor/cakephp/cakephp/src/ORM/Behavior/CounterCacheBehavior.php b/vendor/cakephp/cakephp/src/ORM/Behavior/CounterCacheBehavior.php deleted file mode 100644 index b89a42d..0000000 --- a/vendor/cakephp/cakephp/src/ORM/Behavior/CounterCacheBehavior.php +++ /dev/null @@ -1,287 +0,0 @@ - [ - * 'post_count' - * ] - * ] - * ``` - * - * Counter cache with scope - * ``` - * [ - * 'Users' => [ - * 'posts_published' => [ - * 'conditions' => [ - * 'published' => true - * ] - * ] - * ] - * ] - * ``` - * - * Counter cache using custom find - * ``` - * [ - * 'Users' => [ - * 'posts_published' => [ - * 'finder' => 'published' // Will be using findPublished() - * ] - * ] - * ] - * ``` - * - * Counter cache using lambda function returning the count - * This is equivalent to example #2 - * - * ``` - * [ - * 'Users' => [ - * 'posts_published' => function (Event $event, EntityInterface $entity, Table $table) { - * $query = $table->find('all')->where([ - * 'published' => true, - * 'user_id' => $entity->get('user_id') - * ]); - * return $query->count(); - * } - * ] - * ] - * ``` - * - * When using a lambda function you can return `false` to disable updating the counter value - * for the current operation. - * - * Ignore updating the field if it is dirty - * ``` - * [ - * 'Users' => [ - * 'posts_published' => [ - * 'ignoreDirty' => true - * ] - * ] - * ] - * ``` - * - * You can disable counter updates entirely by sending the `ignoreCounterCache` option - * to your save operation: - * - * ``` - * $this->Articles->save($article, ['ignoreCounterCache' => true]); - * ``` - */ -class CounterCacheBehavior extends Behavior -{ - - /** - * Store the fields which should be ignored - * - * @var array - */ - protected $_ignoreDirty = []; - - /** - * beforeSave callback. - * - * Check if a field, which should be ignored, is dirty - * - * @param \Cake\Event\Event $event The beforeSave event that was fired - * @param \Cake\Datasource\EntityInterface $entity The entity that is going to be saved - * @param \ArrayObject $options The options for the query - * @return void - */ - public function beforeSave(Event $event, EntityInterface $entity, $options) - { - if (isset($options['ignoreCounterCache']) && $options['ignoreCounterCache'] === true) { - return; - } - - foreach ($this->_config as $assoc => $settings) { - $assoc = $this->_table->getAssociation($assoc); - foreach ($settings as $field => $config) { - if (is_int($field)) { - continue; - } - - $registryAlias = $assoc->getTarget()->getRegistryAlias(); - $entityAlias = $assoc->getProperty(); - - if (!is_callable($config) && - isset($config['ignoreDirty']) && - $config['ignoreDirty'] === true && - $entity->$entityAlias->isDirty($field) - ) { - $this->_ignoreDirty[$registryAlias][$field] = true; - } - } - } - } - - /** - * afterSave callback. - * - * Makes sure to update counter cache when a new record is created or updated. - * - * @param \Cake\Event\Event $event The afterSave event that was fired. - * @param \Cake\Datasource\EntityInterface $entity The entity that was saved. - * @param \ArrayObject $options The options for the query - * @return void - */ - public function afterSave(Event $event, EntityInterface $entity, $options) - { - if (isset($options['ignoreCounterCache']) && $options['ignoreCounterCache'] === true) { - return; - } - - $this->_processAssociations($event, $entity); - $this->_ignoreDirty = []; - } - - /** - * afterDelete callback. - * - * Makes sure to update counter cache when a record is deleted. - * - * @param \Cake\Event\Event $event The afterDelete event that was fired. - * @param \Cake\Datasource\EntityInterface $entity The entity that was deleted. - * @param \ArrayObject $options The options for the query - * @return void - */ - public function afterDelete(Event $event, EntityInterface $entity, $options) - { - if (isset($options['ignoreCounterCache']) && $options['ignoreCounterCache'] === true) { - return; - } - - $this->_processAssociations($event, $entity); - } - - /** - * Iterate all associations and update counter caches. - * - * @param \Cake\Event\Event $event Event instance. - * @param \Cake\Datasource\EntityInterface $entity Entity. - * @return void - */ - protected function _processAssociations(Event $event, EntityInterface $entity) - { - foreach ($this->_config as $assoc => $settings) { - $assoc = $this->_table->getAssociation($assoc); - $this->_processAssociation($event, $entity, $assoc, $settings); - } - } - - /** - * Updates counter cache for a single association - * - * @param \Cake\Event\Event $event Event instance. - * @param \Cake\Datasource\EntityInterface $entity Entity - * @param \Cake\ORM\Association $assoc The association object - * @param array $settings The settings for for counter cache for this association - * @return void - * @throws \RuntimeException If invalid callable is passed. - */ - protected function _processAssociation(Event $event, EntityInterface $entity, Association $assoc, array $settings) - { - $foreignKeys = (array)$assoc->getForeignKey(); - $primaryKeys = (array)$assoc->getBindingKey(); - $countConditions = $entity->extract($foreignKeys); - $updateConditions = array_combine($primaryKeys, $countConditions); - $countOriginalConditions = $entity->extractOriginalChanged($foreignKeys); - - if ($countOriginalConditions !== []) { - $updateOriginalConditions = array_combine($primaryKeys, $countOriginalConditions); - } - - foreach ($settings as $field => $config) { - if (is_int($field)) { - $field = $config; - $config = []; - } - - if (isset($this->_ignoreDirty[$assoc->getTarget()->getRegistryAlias()][$field]) && - $this->_ignoreDirty[$assoc->getTarget()->getRegistryAlias()][$field] === true - ) { - continue; - } - - if (is_callable($config)) { - if (is_string($config)) { - throw new RuntimeException('You must not use a string as callable.'); - } - $count = $config($event, $entity, $this->_table, false); - } else { - $count = $this->_getCount($config, $countConditions); - } - if ($count !== false) { - $assoc->getTarget()->updateAll([$field => $count], $updateConditions); - } - - if (isset($updateOriginalConditions)) { - if (is_callable($config)) { - if (is_string($config)) { - throw new RuntimeException('You must not use a string as callable.'); - } - $count = $config($event, $entity, $this->_table, true); - } else { - $count = $this->_getCount($config, $countOriginalConditions); - } - if ($count !== false) { - $assoc->getTarget()->updateAll([$field => $count], $updateOriginalConditions); - } - } - } - } - - /** - * Fetches and returns the count for a single field in an association - * - * @param array $config The counter cache configuration for a single field - * @param array $conditions Additional conditions given to the query - * @return int The number of relations matching the given config and conditions - */ - protected function _getCount(array $config, array $conditions) - { - $finder = 'all'; - if (!empty($config['finder'])) { - $finder = $config['finder']; - unset($config['finder']); - } - - if (!isset($config['conditions'])) { - $config['conditions'] = []; - } - $config['conditions'] = array_merge($conditions, $config['conditions']); - $query = $this->_table->find($finder, $config); - - return $query->count(); - } -} diff --git a/vendor/cakephp/cakephp/src/ORM/Behavior/TimestampBehavior.php b/vendor/cakephp/cakephp/src/ORM/Behavior/TimestampBehavior.php deleted file mode 100644 index 5cbcfcf..0000000 --- a/vendor/cakephp/cakephp/src/ORM/Behavior/TimestampBehavior.php +++ /dev/null @@ -1,219 +0,0 @@ - [], - 'implementedMethods' => [ - 'timestamp' => 'timestamp', - 'touch' => 'touch' - ], - 'events' => [ - 'Model.beforeSave' => [ - 'created' => 'new', - 'modified' => 'always' - ] - ], - 'refreshTimestamp' => true - ]; - - /** - * Current timestamp - * - * @var \DateTime - */ - protected $_ts; - - /** - * Initialize hook - * - * If events are specified - do *not* merge them with existing events, - * overwrite the events to listen on - * - * @param array $config The config for this behavior. - * @return void - */ - public function initialize(array $config) - { - if (isset($config['events'])) { - $this->setConfig('events', $config['events'], false); - } - } - - /** - * There is only one event handler, it can be configured to be called for any event - * - * @param \Cake\Event\Event $event Event instance. - * @param \Cake\Datasource\EntityInterface $entity Entity instance. - * @throws \UnexpectedValueException if a field's when value is misdefined - * @return bool Returns true irrespective of the behavior logic, the save will not be prevented. - * @throws \UnexpectedValueException When the value for an event is not 'always', 'new' or 'existing' - */ - public function handleEvent(Event $event, EntityInterface $entity) - { - $eventName = $event->getName(); - $events = $this->_config['events']; - - $new = $entity->isNew() !== false; - $refresh = $this->_config['refreshTimestamp']; - - foreach ($events[$eventName] as $field => $when) { - if (!in_array($when, ['always', 'new', 'existing'])) { - throw new UnexpectedValueException( - sprintf('When should be one of "always", "new" or "existing". The passed value "%s" is invalid', $when) - ); - } - if ($when === 'always' || - ($when === 'new' && $new) || - ($when === 'existing' && !$new) - ) { - $this->_updateField($entity, $field, $refresh); - } - } - - return true; - } - - /** - * implementedEvents - * - * The implemented events of this behavior depend on configuration - * - * @return array - */ - public function implementedEvents() - { - return array_fill_keys(array_keys($this->_config['events']), 'handleEvent'); - } - - /** - * Get or set the timestamp to be used - * - * Set the timestamp to the given DateTime object, or if not passed a new DateTime object - * If an explicit date time is passed, the config option `refreshTimestamp` is - * automatically set to false. - * - * @param \DateTime|null $ts Timestamp - * @param bool $refreshTimestamp If true timestamp is refreshed. - * @return \DateTime - */ - public function timestamp(DateTime $ts = null, $refreshTimestamp = false) - { - if ($ts) { - if ($this->_config['refreshTimestamp']) { - $this->_config['refreshTimestamp'] = false; - } - $this->_ts = new Time($ts); - } elseif ($this->_ts === null || $refreshTimestamp) { - $this->_ts = new Time(); - } - - return $this->_ts; - } - - /** - * Touch an entity - * - * Bumps timestamp fields for an entity. For any fields configured to be updated - * "always" or "existing", update the timestamp value. This method will overwrite - * any pre-existing value. - * - * @param \Cake\Datasource\EntityInterface $entity Entity instance. - * @param string $eventName Event name. - * @return bool true if a field is updated, false if no action performed - */ - public function touch(EntityInterface $entity, $eventName = 'Model.beforeSave') - { - $events = $this->_config['events']; - if (empty($events[$eventName])) { - return false; - } - - $return = false; - $refresh = $this->_config['refreshTimestamp']; - - foreach ($events[$eventName] as $field => $when) { - if (in_array($when, ['always', 'existing'])) { - $return = true; - $entity->setDirty($field, false); - $this->_updateField($entity, $field, $refresh); - } - } - - return $return; - } - - /** - * Update a field, if it hasn't been updated already - * - * @param \Cake\Datasource\EntityInterface $entity Entity instance. - * @param string $field Field name - * @param bool $refreshTimestamp Whether to refresh timestamp. - * @return void - */ - protected function _updateField($entity, $field, $refreshTimestamp) - { - if ($entity->isDirty($field)) { - return; - } - - $ts = $this->timestamp(null, $refreshTimestamp); - - $columnType = $this->getTable()->getSchema()->getColumnType($field); - if (!$columnType) { - return; - } - - /** @var \Cake\Database\Type\DateTimeType $type */ - $type = Type::build($columnType); - - if (!$type instanceof Type\DateTimeType) { - deprecationWarning('TimestampBehavior support for column types other than DateTimeType will be removed in 4.0.'); - $entity->set($field, (string)$ts); - - return; - } - - $class = $type->getDateTimeClassName(); - - $entity->set($field, new $class($ts)); - } -} diff --git a/vendor/cakephp/cakephp/src/ORM/Behavior/Translate/TranslateTrait.php b/vendor/cakephp/cakephp/src/ORM/Behavior/Translate/TranslateTrait.php deleted file mode 100644 index 343740e..0000000 --- a/vendor/cakephp/cakephp/src/ORM/Behavior/Translate/TranslateTrait.php +++ /dev/null @@ -1,65 +0,0 @@ -get('_locale')) { - return $this; - } - - $i18n = $this->get('_translations'); - $created = false; - - if (empty($i18n)) { - $i18n = []; - $created = true; - } - - if ($created || empty($i18n[$language]) || !($i18n[$language] instanceof EntityInterface)) { - $className = get_class($this); - - $i18n[$language] = new $className(); - $created = true; - } - - if ($created) { - $this->set('_translations', $i18n); - } - - // Assume the user will modify any of the internal translations, helps with saving - $this->setDirty('_translations', true); - - return $i18n[$language]; - } -} diff --git a/vendor/cakephp/cakephp/src/ORM/Behavior/TranslateBehavior.php b/vendor/cakephp/cakephp/src/ORM/Behavior/TranslateBehavior.php deleted file mode 100644 index 55244e6..0000000 --- a/vendor/cakephp/cakephp/src/ORM/Behavior/TranslateBehavior.php +++ /dev/null @@ -1,766 +0,0 @@ - ['translations' => 'findTranslations'], - 'implementedMethods' => [ - 'setLocale' => 'setLocale', - 'getLocale' => 'getLocale', - 'locale' => 'locale', - 'translationField' => 'translationField' - ], - 'fields' => [], - 'translationTable' => 'I18n', - 'defaultLocale' => '', - 'referenceName' => '', - 'allowEmptyTranslations' => true, - 'onlyTranslated' => false, - 'strategy' => 'subquery', - 'tableLocator' => null, - 'validator' => false - ]; - - /** - * Constructor - * - * @param \Cake\ORM\Table $table The table this behavior is attached to. - * @param array $config The config for this behavior. - */ - public function __construct(Table $table, array $config = []) - { - $config += [ - 'defaultLocale' => I18n::getDefaultLocale(), - 'referenceName' => $this->_referenceName($table) - ]; - - if (isset($config['tableLocator'])) { - $this->_tableLocator = $config['tableLocator']; - } - - parent::__construct($table, $config); - } - - /** - * Initialize hook - * - * @param array $config The config for this behavior. - * @return void - */ - public function initialize(array $config) - { - $this->_translationTable = $this->getTableLocator()->get($this->_config['translationTable']); - - $this->setupFieldAssociations( - $this->_config['fields'], - $this->_config['translationTable'], - $this->_config['referenceName'], - $this->_config['strategy'] - ); - } - - /** - * Creates the associations between the bound table and every field passed to - * this method. - * - * Additionally it creates a `i18n` HasMany association that will be - * used for fetching all translations for each record in the bound table - * - * @param array $fields list of fields to create associations for - * @param string $table the table name to use for storing each field translation - * @param string $model the model field value - * @param string $strategy the strategy used in the _i18n association - * - * @return void - */ - public function setupFieldAssociations($fields, $table, $model, $strategy) - { - $targetAlias = $this->_translationTable->getAlias(); - $alias = $this->_table->getAlias(); - $filter = $this->_config['onlyTranslated']; - $tableLocator = $this->getTableLocator(); - - foreach ($fields as $field) { - $name = $alias . '_' . $field . '_translation'; - - if (!$tableLocator->exists($name)) { - $fieldTable = $tableLocator->get($name, [ - 'className' => $table, - 'alias' => $name, - 'table' => $this->_translationTable->getTable() - ]); - } else { - $fieldTable = $tableLocator->get($name); - } - - $conditions = [ - $name . '.model' => $model, - $name . '.field' => $field, - ]; - if (!$this->_config['allowEmptyTranslations']) { - $conditions[$name . '.content !='] = ''; - } - - $this->_table->hasOne($name, [ - 'targetTable' => $fieldTable, - 'foreignKey' => 'foreign_key', - 'joinType' => $filter ? QueryInterface::JOIN_TYPE_INNER : QueryInterface::JOIN_TYPE_LEFT, - 'conditions' => $conditions, - 'propertyName' => $field . '_translation' - ]); - } - - $conditions = ["$targetAlias.model" => $model]; - if (!$this->_config['allowEmptyTranslations']) { - $conditions["$targetAlias.content !="] = ''; - } - - $this->_table->hasMany($targetAlias, [ - 'className' => $table, - 'foreignKey' => 'foreign_key', - 'strategy' => $strategy, - 'conditions' => $conditions, - 'propertyName' => '_i18n', - 'dependent' => true - ]); - } - - /** - * Callback method that listens to the `beforeFind` event in the bound - * table. It modifies the passed query by eager loading the translated fields - * and adding a formatter to copy the values into the main table records. - * - * @param \Cake\Event\Event $event The beforeFind event that was fired. - * @param \Cake\ORM\Query $query Query - * @param \ArrayObject $options The options for the query - * @return void - */ - public function beforeFind(Event $event, Query $query, $options) - { - $locale = $this->getLocale(); - - if ($locale === $this->getConfig('defaultLocale')) { - return; - } - - $conditions = function ($field, $locale, $query, $select) { - return function ($q) use ($field, $locale, $query, $select) { - /* @var \Cake\Datasource\QueryInterface $q */ - $q->where([$q->getRepository()->aliasField('locale') => $locale]); - - /* @var \Cake\ORM\Query $query */ - if ($query->isAutoFieldsEnabled() || - in_array($field, $select, true) || - in_array($this->_table->aliasField($field), $select, true) - ) { - $q->select(['id', 'content']); - } - - return $q; - }; - }; - - $contain = []; - $fields = $this->_config['fields']; - $alias = $this->_table->getAlias(); - $select = $query->clause('select'); - - $changeFilter = isset($options['filterByCurrentLocale']) && - $options['filterByCurrentLocale'] !== $this->_config['onlyTranslated']; - - foreach ($fields as $field) { - $name = $alias . '_' . $field . '_translation'; - - $contain[$name]['queryBuilder'] = $conditions( - $field, - $locale, - $query, - $select - ); - - if ($changeFilter) { - $filter = $options['filterByCurrentLocale'] ? QueryInterface::JOIN_TYPE_INNER : QueryInterface::JOIN_TYPE_LEFT; - $contain[$name]['joinType'] = $filter; - } - } - - $query->contain($contain); - $query->formatResults(function ($results) use ($locale) { - return $this->_rowMapper($results, $locale); - }, $query::PREPEND); - } - - /** - * Modifies the entity before it is saved so that translated fields are persisted - * in the database too. - * - * @param \Cake\Event\Event $event The beforeSave event that was fired - * @param \Cake\Datasource\EntityInterface $entity The entity that is going to be saved - * @param \ArrayObject $options the options passed to the save method - * @return void - */ - public function beforeSave(Event $event, EntityInterface $entity, ArrayObject $options) - { - $locale = $entity->get('_locale') ?: $this->getLocale(); - $newOptions = [$this->_translationTable->getAlias() => ['validate' => false]]; - $options['associated'] = $newOptions + $options['associated']; - - // Check early if empty translations are present in the entity. - // If this is the case, unset them to prevent persistence. - // This only applies if $this->_config['allowEmptyTranslations'] is false - if ($this->_config['allowEmptyTranslations'] === false) { - $this->_unsetEmptyFields($entity); - } - - $this->_bundleTranslatedFields($entity); - $bundled = $entity->get('_i18n') ?: []; - $noBundled = count($bundled) === 0; - - // No additional translation records need to be saved, - // as the entity is in the default locale. - if ($noBundled && $locale === $this->getConfig('defaultLocale')) { - return; - } - - $values = $entity->extract($this->_config['fields'], true); - $fields = array_keys($values); - $noFields = empty($fields); - - // If there are no fields and no bundled translations, or both fields - // in the default locale and bundled translations we can - // skip the remaining logic as its not necessary. - if ($noFields && $noBundled || ($fields && $bundled)) { - return; - } - - $primaryKey = (array)$this->_table->getPrimaryKey(); - $key = $entity->get(current($primaryKey)); - - // When we have no key and bundled translations, we - // need to mark the entity dirty so the root - // entity persists. - if ($noFields && $bundled && !$key) { - foreach ($this->_config['fields'] as $field) { - $entity->setDirty($field, true); - } - - return; - } - - if ($noFields) { - return; - } - - $model = $this->_config['referenceName']; - $preexistent = $this->_translationTable->find() - ->select(['id', 'field']) - ->where([ - 'field IN' => $fields, - 'locale' => $locale, - 'foreign_key' => $key, - 'model' => $model - ]) - ->enableBufferedResults(false) - ->all() - ->indexBy('field'); - - $modified = []; - foreach ($preexistent as $field => $translation) { - $translation->set('content', $values[$field]); - $modified[$field] = $translation; - } - - $new = array_diff_key($values, $modified); - foreach ($new as $field => $content) { - $new[$field] = new Entity(compact('locale', 'field', 'content', 'model'), [ - 'useSetters' => false, - 'markNew' => true - ]); - } - - $entity->set('_i18n', array_merge($bundled, array_values($modified + $new))); - $entity->set('_locale', $locale, ['setter' => false]); - $entity->setDirty('_locale', false); - - foreach ($fields as $field) { - $entity->setDirty($field, false); - } - } - - /** - * Unsets the temporary `_i18n` property after the entity has been saved - * - * @param \Cake\Event\Event $event The beforeSave event that was fired - * @param \Cake\Datasource\EntityInterface $entity The entity that is going to be saved - * @return void - */ - public function afterSave(Event $event, EntityInterface $entity) - { - $entity->unsetProperty('_i18n'); - } - - /** - * Add in `_translations` marshalling handlers. You can disable marshalling - * of translations by setting `'translations' => false` in the options - * provided to `Table::newEntity()` or `Table::patchEntity()`. - * - * {@inheritDoc} - */ - public function buildMarshalMap($marshaller, $map, $options) - { - if (isset($options['translations']) && !$options['translations']) { - return []; - } - - return [ - '_translations' => function ($value, $entity) use ($marshaller, $options) { - /* @var \Cake\Datasource\EntityInterface $entity */ - $translations = $entity->get('_translations'); - foreach ($this->_config['fields'] as $field) { - $options['validate'] = $this->_config['validator']; - $errors = []; - if (!is_array($value)) { - return null; - } - foreach ($value as $language => $fields) { - if (!isset($translations[$language])) { - $translations[$language] = $this->_table->newEntity(); - } - $marshaller->merge($translations[$language], $fields, $options); - if ((bool)$translations[$language]->getErrors()) { - $errors[$language] = $translations[$language]->getErrors(); - } - } - // Set errors into the root entity, so validation errors - // match the original form data position. - $entity->setErrors($errors); - } - - return $translations; - } - ]; - } - - /** - * Sets the locale that should be used for all future find and save operations on - * the table where this behavior is attached to. - * - * When fetching records, the behavior will include the content for the locale set - * via this method, and likewise when saving data, it will save the data in that - * locale. - * - * Note that in case an entity has a `_locale` property set, that locale will win - * over the locale set via this method (and over the globally configured one for - * that matter)! - * - * @param string|null $locale The locale to use for fetching and saving records. Pass `null` - * in order to unset the current locale, and to make the behavior fall back to using the - * globally configured locale. - * @return $this - * @see \Cake\ORM\Behavior\TranslateBehavior::getLocale() - * @link https://book.cakephp.org/3.0/en/orm/behaviors/translate.html#retrieving-one-language-without-using-i18n-locale - * @link https://book.cakephp.org/3.0/en/orm/behaviors/translate.html#saving-in-another-language - */ - public function setLocale($locale) - { - $this->_locale = $locale; - - return $this; - } - - /** - * Returns the current locale. - * - * If no locale has been explicitly set via `setLocale()`, this method will return - * the currently configured global locale. - * - * @return string - * @see \Cake\I18n\I18n::getLocale() - * @see \Cake\ORM\Behavior\TranslateBehavior::setLocale() - */ - public function getLocale() - { - return $this->_locale ?: I18n::getLocale(); - } - - /** - * Sets all future finds for the bound table to also fetch translated fields for - * the passed locale. If no value is passed, it returns the currently configured - * locale - * - * @deprecated 3.6.0 Use setLocale()/getLocale() instead. - * @param string|null $locale The locale to use for fetching translated records - * @return string - */ - public function locale($locale = null) - { - deprecationWarning( - get_called_class() . '::locale() is deprecated. ' . - 'Use setLocale()/getLocale() instead.' - ); - - if ($locale !== null) { - $this->setLocale($locale); - } - - return $this->getLocale(); - } - - /** - * Returns a fully aliased field name for translated fields. - * - * If the requested field is configured as a translation field, the `content` - * field with an alias of a corresponding association is returned. Table-aliased - * field name is returned for all other fields. - * - * @param string $field Field name to be aliased. - * @return string - */ - public function translationField($field) - { - $table = $this->_table; - if ($this->getLocale() === $this->getConfig('defaultLocale')) { - return $table->aliasField($field); - } - $associationName = $table->getAlias() . '_' . $field . '_translation'; - - if ($table->associations()->has($associationName)) { - return $associationName . '.content'; - } - - return $table->aliasField($field); - } - - /** - * Custom finder method used to retrieve all translations for the found records. - * Fetched translations can be filtered by locale by passing the `locales` key - * in the options array. - * - * Translated values will be found for each entity under the property `_translations`, - * containing an array indexed by locale name. - * - * ### Example: - * - * ``` - * $article = $articles->find('translations', ['locales' => ['eng', 'deu'])->first(); - * $englishTranslatedFields = $article->get('_translations')['eng']; - * ``` - * - * If the `locales` array is not passed, it will bring all translations found - * for each record. - * - * @param \Cake\ORM\Query $query The original query to modify - * @param array $options Options - * @return \Cake\ORM\Query - */ - public function findTranslations(Query $query, array $options) - { - $locales = isset($options['locales']) ? $options['locales'] : []; - $targetAlias = $this->_translationTable->getAlias(); - - return $query - ->contain([$targetAlias => function ($query) use ($locales, $targetAlias) { - if ($locales) { - /* @var \Cake\Datasource\QueryInterface $query */ - $query->where(["$targetAlias.locale IN" => $locales]); - } - - return $query; - }]) - ->formatResults([$this, 'groupTranslations'], $query::PREPEND); - } - - /** - * Determine the reference name to use for a given table - * - * The reference name is usually derived from the class name of the table object - * (PostsTable -> Posts), however for autotable instances it is derived from - * the database table the object points at - or as a last resort, the alias - * of the autotable instance. - * - * @param \Cake\ORM\Table $table The table class to get a reference name for. - * @return string - */ - protected function _referenceName(Table $table) - { - $name = namespaceSplit(get_class($table)); - $name = substr(end($name), 0, -5); - if (empty($name)) { - $name = $table->getTable() ?: $table->getAlias(); - $name = Inflector::camelize($name); - } - - return $name; - } - - /** - * Modifies the results from a table find in order to merge the translated fields - * into each entity for a given locale. - * - * @param \Cake\Datasource\ResultSetInterface $results Results to map. - * @param string $locale Locale string - * @return \Cake\Collection\CollectionInterface - */ - protected function _rowMapper($results, $locale) - { - return $results->map(function ($row) use ($locale) { - if ($row === null) { - return $row; - } - $hydrated = !is_array($row); - - foreach ($this->_config['fields'] as $field) { - $name = $field . '_translation'; - $translation = isset($row[$name]) ? $row[$name] : null; - - if ($translation === null || $translation === false) { - unset($row[$name]); - continue; - } - - $content = isset($translation['content']) ? $translation['content'] : null; - if ($content !== null) { - $row[$field] = $content; - } - - unset($row[$name]); - } - - $row['_locale'] = $locale; - if ($hydrated) { - /* @var \Cake\Datasource\EntityInterface $row */ - $row->clean(); - } - - return $row; - }); - } - - /** - * Modifies the results from a table find in order to merge full translation records - * into each entity under the `_translations` key - * - * @param \Cake\Datasource\ResultSetInterface $results Results to modify. - * @return \Cake\Collection\CollectionInterface - */ - public function groupTranslations($results) - { - return $results->map(function ($row) { - if (!$row instanceof EntityInterface) { - return $row; - } - $translations = (array)$row->get('_i18n'); - if (empty($translations) && $row->get('_translations')) { - return $row; - } - $grouped = new Collection($translations); - - $result = []; - foreach ($grouped->combine('field', 'content', 'locale') as $locale => $keys) { - $entityClass = $this->_table->getEntityClass(); - $translation = new $entityClass($keys + ['locale' => $locale], [ - 'markNew' => false, - 'useSetters' => false, - 'markClean' => true - ]); - $result[$locale] = $translation; - } - - $options = ['setter' => false, 'guard' => false]; - $row->set('_translations', $result, $options); - unset($row['_i18n']); - $row->clean(); - - return $row; - }); - } - - /** - * Helper method used to generated multiple translated field entities - * out of the data found in the `_translations` property in the passed - * entity. The result will be put into its `_i18n` property - * - * @param \Cake\Datasource\EntityInterface $entity Entity - * @return void - */ - protected function _bundleTranslatedFields($entity) - { - $translations = (array)$entity->get('_translations'); - - if (empty($translations) && !$entity->isDirty('_translations')) { - return; - } - - $fields = $this->_config['fields']; - $primaryKey = (array)$this->_table->getPrimaryKey(); - $key = $entity->get(current($primaryKey)); - $find = []; - $contents = []; - - foreach ($translations as $lang => $translation) { - foreach ($fields as $field) { - if (!$translation->isDirty($field)) { - continue; - } - $find[] = ['locale' => $lang, 'field' => $field, 'foreign_key' => $key]; - $contents[] = new Entity(['content' => $translation->get($field)], [ - 'useSetters' => false - ]); - } - } - - if (empty($find)) { - return; - } - - $results = $this->_findExistingTranslations($find); - - foreach ($find as $i => $translation) { - if (!empty($results[$i])) { - $contents[$i]->set('id', $results[$i], ['setter' => false]); - $contents[$i]->isNew(false); - } else { - $translation['model'] = $this->_config['referenceName']; - $contents[$i]->set($translation, ['setter' => false, 'guard' => false]); - $contents[$i]->isNew(true); - } - } - - $entity->set('_i18n', $contents); - } - - /** - * Unset empty translations to avoid persistence. - * - * Should only be called if $this->_config['allowEmptyTranslations'] is false. - * - * @param \Cake\Datasource\EntityInterface $entity The entity to check for empty translations fields inside. - * @return void - */ - protected function _unsetEmptyFields(EntityInterface $entity) - { - $translations = (array)$entity->get('_translations'); - foreach ($translations as $locale => $translation) { - $fields = $translation->extract($this->_config['fields'], false); - foreach ($fields as $field => $value) { - if (strlen($value) === 0) { - $translation->unsetProperty($field); - } - } - - $translation = $translation->extract($this->_config['fields']); - - // If now, the current locale property is empty, - // unset it completely. - if (empty(array_filter($translation))) { - unset($entity->get('_translations')[$locale]); - } - } - - // If now, the whole _translations property is empty, - // unset it completely and return - if (empty($entity->get('_translations'))) { - $entity->unsetProperty('_translations'); - } - } - - /** - * Returns the ids found for each of the condition arrays passed for the translations - * table. Each records is indexed by the corresponding position to the conditions array - * - * @param array $ruleSet an array of arary of conditions to be used for finding each - * @return array - */ - protected function _findExistingTranslations($ruleSet) - { - $association = $this->_table->getAssociation($this->_translationTable->getAlias()); - - $query = $association->find() - ->select(['id', 'num' => 0]) - ->where(current($ruleSet)) - ->enableHydration(false) - ->enableBufferedResults(false); - - unset($ruleSet[0]); - foreach ($ruleSet as $i => $conditions) { - $q = $association->find() - ->select(['id', 'num' => $i]) - ->where($conditions); - $query->unionAll($q); - } - - return $query->all()->combine('num', 'id')->toArray(); - } -} diff --git a/vendor/cakephp/cakephp/src/ORM/Behavior/TreeBehavior.php b/vendor/cakephp/cakephp/src/ORM/Behavior/TreeBehavior.php deleted file mode 100644 index 9c4c44f..0000000 --- a/vendor/cakephp/cakephp/src/ORM/Behavior/TreeBehavior.php +++ /dev/null @@ -1,1016 +0,0 @@ - [ - 'path' => 'findPath', - 'children' => 'findChildren', - 'treeList' => 'findTreeList', - ], - 'implementedMethods' => [ - 'childCount' => 'childCount', - 'moveUp' => 'moveUp', - 'moveDown' => 'moveDown', - 'recover' => 'recover', - 'removeFromTree' => 'removeFromTree', - 'getLevel' => 'getLevel', - 'formatTreeList' => 'formatTreeList', - ], - 'parent' => 'parent_id', - 'left' => 'lft', - 'right' => 'rght', - 'scope' => null, - 'level' => null, - 'recoverOrder' => null, - ]; - - /** - * {@inheritDoc} - */ - public function initialize(array $config) - { - $this->_config['leftField'] = new IdentifierExpression($this->_config['left']); - $this->_config['rightField'] = new IdentifierExpression($this->_config['right']); - } - - /** - * Before save listener. - * Transparently manages setting the lft and rght fields if the parent field is - * included in the parameters to be saved. - * - * @param \Cake\Event\Event $event The beforeSave event that was fired - * @param \Cake\Datasource\EntityInterface $entity the entity that is going to be saved - * @return void - * @throws \RuntimeException if the parent to set for the node is invalid - */ - public function beforeSave(Event $event, EntityInterface $entity) - { - $isNew = $entity->isNew(); - $config = $this->getConfig(); - $parent = $entity->get($config['parent']); - $primaryKey = $this->_getPrimaryKey(); - $dirty = $entity->isDirty($config['parent']); - $level = $config['level']; - - if ($parent && $entity->get($primaryKey) == $parent) { - throw new RuntimeException("Cannot set a node's parent as itself"); - } - - if ($isNew && $parent) { - $parentNode = $this->_getNode($parent); - $edge = $parentNode->get($config['right']); - $entity->set($config['left'], $edge); - $entity->set($config['right'], $edge + 1); - $this->_sync(2, '+', ">= {$edge}"); - - if ($level) { - $entity->set($level, $parentNode[$level] + 1); - } - - return; - } - - if ($isNew && !$parent) { - $edge = $this->_getMax(); - $entity->set($config['left'], $edge + 1); - $entity->set($config['right'], $edge + 2); - - if ($level) { - $entity->set($level, 0); - } - - return; - } - - if (!$isNew && $dirty && $parent) { - $this->_setParent($entity, $parent); - - if ($level) { - $parentNode = $this->_getNode($parent); - $entity->set($level, $parentNode[$level] + 1); - } - - return; - } - - if (!$isNew && $dirty && !$parent) { - $this->_setAsRoot($entity); - - if ($level) { - $entity->set($level, 0); - } - } - } - - /** - * After save listener. - * - * Manages updating level of descendants of currently saved entity. - * - * @param \Cake\Event\Event $event The afterSave event that was fired - * @param \Cake\Datasource\EntityInterface $entity the entity that is going to be saved - * @return void - */ - public function afterSave(Event $event, EntityInterface $entity) - { - if (!$this->_config['level'] || $entity->isNew()) { - return; - } - - $this->_setChildrenLevel($entity); - } - - /** - * Set level for descendants. - * - * @param \Cake\Datasource\EntityInterface $entity The entity whose descendants need to be updated. - * @return void - */ - protected function _setChildrenLevel($entity) - { - $config = $this->getConfig(); - - if ($entity->get($config['left']) + 1 === $entity->get($config['right'])) { - return; - } - - $primaryKey = $this->_getPrimaryKey(); - $primaryKeyValue = $entity->get($primaryKey); - $depths = [$primaryKeyValue => $entity->get($config['level'])]; - - $children = $this->_table->find('children', [ - 'for' => $primaryKeyValue, - 'fields' => [$this->_getPrimaryKey(), $config['parent'], $config['level']], - 'order' => $config['left'], - ]); - - /* @var \Cake\Datasource\EntityInterface $node */ - foreach ($children as $node) { - $parentIdValue = $node->get($config['parent']); - $depth = $depths[$parentIdValue] + 1; - $depths[$node->get($primaryKey)] = $depth; - - $this->_table->updateAll( - [$config['level'] => $depth], - [$primaryKey => $node->get($primaryKey)] - ); - } - } - - /** - * Also deletes the nodes in the subtree of the entity to be delete - * - * @param \Cake\Event\Event $event The beforeDelete event that was fired - * @param \Cake\Datasource\EntityInterface $entity The entity that is going to be saved - * @return void - */ - public function beforeDelete(Event $event, EntityInterface $entity) - { - $config = $this->getConfig(); - $this->_ensureFields($entity); - $left = $entity->get($config['left']); - $right = $entity->get($config['right']); - $diff = $right - $left + 1; - - if ($diff > 2) { - $query = $this->_scope($this->_table->query()) - ->delete() - ->where(function ($exp) use ($config, $left, $right) { - /* @var \Cake\Database\Expression\QueryExpression $exp */ - return $exp - ->gte($config['leftField'], $left + 1) - ->lte($config['leftField'], $right - 1); - }); - $statement = $query->execute(); - $statement->closeCursor(); - } - - $this->_sync($diff, '-', "> {$right}"); - } - - /** - * Sets the correct left and right values for the passed entity so it can be - * updated to a new parent. It also makes the hole in the tree so the node - * move can be done without corrupting the structure. - * - * @param \Cake\Datasource\EntityInterface $entity The entity to re-parent - * @param mixed $parent the id of the parent to set - * @return void - * @throws \RuntimeException if the parent to set to the entity is not valid - */ - protected function _setParent($entity, $parent) - { - $config = $this->getConfig(); - $parentNode = $this->_getNode($parent); - $this->_ensureFields($entity); - $parentLeft = $parentNode->get($config['left']); - $parentRight = $parentNode->get($config['right']); - $right = $entity->get($config['right']); - $left = $entity->get($config['left']); - - if ($parentLeft > $left && $parentLeft < $right) { - throw new RuntimeException(sprintf( - 'Cannot use node "%s" as parent for entity "%s"', - $parent, - $entity->get($this->_getPrimaryKey()) - )); - } - - // Values for moving to the left - $diff = $right - $left + 1; - $targetLeft = $parentRight; - $targetRight = $diff + $parentRight - 1; - $min = $parentRight; - $max = $left - 1; - - if ($left < $targetLeft) { - // Moving to the right - $targetLeft = $parentRight - $diff; - $targetRight = $parentRight - 1; - $min = $right + 1; - $max = $parentRight - 1; - $diff *= -1; - } - - if ($right - $left > 1) { - // Correcting internal subtree - $internalLeft = $left + 1; - $internalRight = $right - 1; - $this->_sync($targetLeft - $left, '+', "BETWEEN {$internalLeft} AND {$internalRight}", true); - } - - $this->_sync($diff, '+', "BETWEEN {$min} AND {$max}"); - - if ($right - $left > 1) { - $this->_unmarkInternalTree(); - } - - // Allocating new position - $entity->set($config['left'], $targetLeft); - $entity->set($config['right'], $targetRight); - } - - /** - * Updates the left and right column for the passed entity so it can be set as - * a new root in the tree. It also modifies the ordering in the rest of the tree - * so the structure remains valid - * - * @param \Cake\Datasource\EntityInterface $entity The entity to set as a new root - * @return void - */ - protected function _setAsRoot($entity) - { - $config = $this->getConfig(); - $edge = $this->_getMax(); - $this->_ensureFields($entity); - $right = $entity->get($config['right']); - $left = $entity->get($config['left']); - $diff = $right - $left; - - if ($right - $left > 1) { - //Correcting internal subtree - $internalLeft = $left + 1; - $internalRight = $right - 1; - $this->_sync($edge - $diff - $left, '+', "BETWEEN {$internalLeft} AND {$internalRight}", true); - } - - $this->_sync($diff + 1, '-', "BETWEEN {$right} AND {$edge}"); - - if ($right - $left > 1) { - $this->_unmarkInternalTree(); - } - - $entity->set($config['left'], $edge - $diff); - $entity->set($config['right'], $edge); - } - - /** - * Helper method used to invert the sign of the left and right columns that are - * less than 0. They were set to negative values before so their absolute value - * wouldn't change while performing other tree transformations. - * - * @return void - */ - protected function _unmarkInternalTree() - { - $config = $this->getConfig(); - $this->_table->updateAll( - function ($exp) use ($config) { - /* @var \Cake\Database\Expression\QueryExpression $exp */ - $leftInverse = clone $exp; - $leftInverse->setConjunction('*')->add('-1'); - $rightInverse = clone $leftInverse; - - return $exp - ->eq($config['leftField'], $leftInverse->add($config['leftField'])) - ->eq($config['rightField'], $rightInverse->add($config['rightField'])); - }, - function ($exp) use ($config) { - /* @var \Cake\Database\Expression\QueryExpression $exp */ - return $exp->lt($config['leftField'], 0); - } - ); - } - - /** - * Custom finder method which can be used to return the list of nodes from the root - * to a specific node in the tree. This custom finder requires that the key 'for' - * is passed in the options containing the id of the node to get its path for. - * - * @param \Cake\ORM\Query $query The constructed query to modify - * @param array $options the list of options for the query - * @return \Cake\ORM\Query - * @throws \InvalidArgumentException If the 'for' key is missing in options - */ - public function findPath(Query $query, array $options) - { - if (empty($options['for'])) { - throw new InvalidArgumentException("The 'for' key is required for find('path')"); - } - - $config = $this->getConfig(); - list($left, $right) = array_map( - function ($field) { - return $this->_table->aliasField($field); - }, - [$config['left'], $config['right']] - ); - - $node = $this->_table->get($options['for'], ['fields' => [$left, $right]]); - - return $this->_scope($query) - ->where([ - "$left <=" => $node->get($config['left']), - "$right >=" => $node->get($config['right']), - ]) - ->order([$left => 'ASC']); - } - - /** - * Get the number of children nodes. - * - * @param \Cake\Datasource\EntityInterface $node The entity to count children for - * @param bool $direct whether to count all nodes in the subtree or just - * direct children - * @return int Number of children nodes. - */ - public function childCount(EntityInterface $node, $direct = false) - { - $config = $this->getConfig(); - $parent = $this->_table->aliasField($config['parent']); - - if ($direct) { - return $this->_scope($this->_table->find()) - ->where([$parent => $node->get($this->_getPrimaryKey())]) - ->count(); - } - - $this->_ensureFields($node); - - return ($node->get($config['right']) - $node->get($config['left']) - 1) / 2; - } - - /** - * Get the children nodes of the current model - * - * Available options are: - * - * - for: The id of the record to read. - * - direct: Boolean, whether to return only the direct (true), or all (false) children, - * defaults to false (all children). - * - * If the direct option is set to true, only the direct children are returned (based upon the parent_id field) - * - * @param \Cake\ORM\Query $query Query. - * @param array $options Array of options as described above - * @return \Cake\ORM\Query - * @throws \InvalidArgumentException When the 'for' key is not passed in $options - */ - public function findChildren(Query $query, array $options) - { - $config = $this->getConfig(); - $options += ['for' => null, 'direct' => false]; - list($parent, $left, $right) = array_map( - function ($field) { - return $this->_table->aliasField($field); - }, - [$config['parent'], $config['left'], $config['right']] - ); - - list($for, $direct) = [$options['for'], $options['direct']]; - - if (empty($for)) { - throw new InvalidArgumentException("The 'for' key is required for find('children')"); - } - - if ($query->clause('order') === null) { - $query->order([$left => 'ASC']); - } - - if ($direct) { - return $this->_scope($query)->where([$parent => $for]); - } - - $node = $this->_getNode($for); - - return $this->_scope($query) - ->where([ - "{$right} <" => $node->get($config['right']), - "{$left} >" => $node->get($config['left']), - ]); - } - - /** - * Gets a representation of the elements in the tree as a flat list where the keys are - * the primary key for the table and the values are the display field for the table. - * Values are prefixed to visually indicate relative depth in the tree. - * - * ### Options - * - * - keyPath: A dot separated path to fetch the field to use for the array key, or a closure to - * return the key out of the provided row. - * - valuePath: A dot separated path to fetch the field to use for the array value, or a closure to - * return the value out of the provided row. - * - spacer: A string to be used as prefix for denoting the depth in the tree for each item - * - * @param \Cake\ORM\Query $query Query. - * @param array $options Array of options as described above. - * @return \Cake\ORM\Query - */ - public function findTreeList(Query $query, array $options) - { - $left = $this->_table->aliasField($this->getConfig('left')); - - $results = $this->_scope($query) - ->find('threaded', [ - 'parentField' => $this->getConfig('parent'), - 'order' => [$left => 'ASC'], - ]); - - return $this->formatTreeList($results, $options); - } - - /** - * Formats query as a flat list where the keys are the primary key for the table - * and the values are the display field for the table. Values are prefixed to visually - * indicate relative depth in the tree. - * - * ### Options - * - * - keyPath: A dot separated path to the field that will be the result array key, or a closure to - * return the key from the provided row. - * - valuePath: A dot separated path to the field that is the array's value, or a closure to - * return the value from the provided row. - * - spacer: A string to be used as prefix for denoting the depth in the tree for each item. - * - * @param \Cake\ORM\Query $query The query object to format. - * @param array $options Array of options as described above. - * @return \Cake\ORM\Query Augmented query. - */ - public function formatTreeList(Query $query, array $options = []) - { - return $query->formatResults(function ($results) use ($options) { - /* @var \Cake\Collection\CollectionTrait $results */ - $options += [ - 'keyPath' => $this->_getPrimaryKey(), - 'valuePath' => $this->_table->getDisplayField(), - 'spacer' => '_', - ]; - - return $results - ->listNested() - ->printer($options['valuePath'], $options['keyPath'], $options['spacer']); - }); - } - - /** - * Removes the current node from the tree, by positioning it as a new root - * and re-parents all children up one level. - * - * Note that the node will not be deleted just moved away from its current position - * without moving its children with it. - * - * @param \Cake\Datasource\EntityInterface $node The node to remove from the tree - * @return \Cake\Datasource\EntityInterface|false the node after being removed from the tree or - * false on error - */ - public function removeFromTree(EntityInterface $node) - { - return $this->_table->getConnection()->transactional(function () use ($node) { - $this->_ensureFields($node); - - return $this->_removeFromTree($node); - }); - } - - /** - * Helper function containing the actual code for removeFromTree - * - * @param \Cake\Datasource\EntityInterface $node The node to remove from the tree - * @return \Cake\Datasource\EntityInterface|false the node after being removed from the tree or - * false on error - */ - protected function _removeFromTree($node) - { - $config = $this->getConfig(); - $left = $node->get($config['left']); - $right = $node->get($config['right']); - $parent = $node->get($config['parent']); - - $node->set($config['parent'], null); - - if ($right - $left == 1) { - return $this->_table->save($node); - } - - $primary = $this->_getPrimaryKey(); - $this->_table->updateAll( - [$config['parent'] => $parent], - [$config['parent'] => $node->get($primary)] - ); - $this->_sync(1, '-', 'BETWEEN ' . ($left + 1) . ' AND ' . ($right - 1)); - $this->_sync(2, '-', "> {$right}"); - $edge = $this->_getMax(); - $node->set($config['left'], $edge + 1); - $node->set($config['right'], $edge + 2); - $fields = [$config['parent'], $config['left'], $config['right']]; - - $this->_table->updateAll($node->extract($fields), [$primary => $node->get($primary)]); - - foreach ($fields as $field) { - $node->setDirty($field, false); - } - - return $node; - } - - /** - * Reorders the node without changing its parent. - * - * If the node is the first child, or is a top level node with no previous node - * this method will return false - * - * @param \Cake\Datasource\EntityInterface $node The node to move - * @param int|bool $number How many places to move the node, or true to move to first position - * @throws \Cake\Datasource\Exception\RecordNotFoundException When node was not found - * @return \Cake\Datasource\EntityInterface|bool $node The node after being moved or false on failure - */ - public function moveUp(EntityInterface $node, $number = 1) - { - if ($number < 1) { - return false; - } - - return $this->_table->getConnection()->transactional(function () use ($node, $number) { - $this->_ensureFields($node); - - return $this->_moveUp($node, $number); - }); - } - - /** - * Helper function used with the actual code for moveUp - * - * @param \Cake\Datasource\EntityInterface $node The node to move - * @param int|bool $number How many places to move the node, or true to move to first position - * @throws \Cake\Datasource\Exception\RecordNotFoundException When node was not found - * @return \Cake\Datasource\EntityInterface|bool $node The node after being moved or false on failure - */ - protected function _moveUp($node, $number) - { - $config = $this->getConfig(); - list($parent, $left, $right) = [$config['parent'], $config['left'], $config['right']]; - list($nodeParent, $nodeLeft, $nodeRight) = array_values($node->extract([$parent, $left, $right])); - - $targetNode = null; - if ($number !== true) { - $targetNode = $this->_scope($this->_table->find()) - ->select([$left, $right]) - ->where(["$parent IS" => $nodeParent]) - ->where(function ($exp) use ($config, $nodeLeft) { - /* @var \Cake\Database\Expression\QueryExpression $exp */ - return $exp->lt($config['rightField'], $nodeLeft); - }) - ->orderDesc($config['leftField']) - ->offset($number - 1) - ->limit(1) - ->first(); - } - if (!$targetNode) { - $targetNode = $this->_scope($this->_table->find()) - ->select([$left, $right]) - ->where(["$parent IS" => $nodeParent]) - ->where(function ($exp) use ($config, $nodeLeft) { - /* @var \Cake\Database\Expression\QueryExpression $exp */ - return $exp->lt($config['rightField'], $nodeLeft); - }) - ->orderAsc($config['leftField']) - ->limit(1) - ->first(); - - if (!$targetNode) { - return $node; - } - } - - list($targetLeft) = array_values($targetNode->extract([$left, $right])); - $edge = $this->_getMax(); - $leftBoundary = $targetLeft; - $rightBoundary = $nodeLeft - 1; - - $nodeToEdge = $edge - $nodeLeft + 1; - $shift = $nodeRight - $nodeLeft + 1; - $nodeToHole = $edge - $leftBoundary + 1; - $this->_sync($nodeToEdge, '+', "BETWEEN {$nodeLeft} AND {$nodeRight}"); - $this->_sync($shift, '+', "BETWEEN {$leftBoundary} AND {$rightBoundary}"); - $this->_sync($nodeToHole, '-', "> {$edge}"); - - $node->set($left, $targetLeft); - $node->set($right, $targetLeft + ($nodeRight - $nodeLeft)); - - $node->setDirty($left, false); - $node->setDirty($right, false); - - return $node; - } - - /** - * Reorders the node without changing the parent. - * - * If the node is the last child, or is a top level node with no subsequent node - * this method will return false - * - * @param \Cake\Datasource\EntityInterface $node The node to move - * @param int|bool $number How many places to move the node or true to move to last position - * @throws \Cake\Datasource\Exception\RecordNotFoundException When node was not found - * @return \Cake\Datasource\EntityInterface|bool the entity after being moved or false on failure - */ - public function moveDown(EntityInterface $node, $number = 1) - { - if ($number < 1) { - return false; - } - - return $this->_table->getConnection()->transactional(function () use ($node, $number) { - $this->_ensureFields($node); - - return $this->_moveDown($node, $number); - }); - } - - /** - * Helper function used with the actual code for moveDown - * - * @param \Cake\Datasource\EntityInterface $node The node to move - * @param int|bool $number How many places to move the node, or true to move to last position - * @throws \Cake\Datasource\Exception\RecordNotFoundException When node was not found - * @return \Cake\Datasource\EntityInterface|bool $node The node after being moved or false on failure - */ - protected function _moveDown($node, $number) - { - $config = $this->getConfig(); - list($parent, $left, $right) = [$config['parent'], $config['left'], $config['right']]; - list($nodeParent, $nodeLeft, $nodeRight) = array_values($node->extract([$parent, $left, $right])); - - $targetNode = null; - if ($number !== true) { - $targetNode = $this->_scope($this->_table->find()) - ->select([$left, $right]) - ->where(["$parent IS" => $nodeParent]) - ->where(function ($exp) use ($config, $nodeRight) { - /* @var \Cake\Database\Expression\QueryExpression $exp */ - return $exp->gt($config['leftField'], $nodeRight); - }) - ->orderAsc($config['leftField']) - ->offset($number - 1) - ->limit(1) - ->first(); - } - if (!$targetNode) { - $targetNode = $this->_scope($this->_table->find()) - ->select([$left, $right]) - ->where(["$parent IS" => $nodeParent]) - ->where(function ($exp) use ($config, $nodeRight) { - /* @var \Cake\Database\Expression\QueryExpression $exp */ - return $exp->gt($config['leftField'], $nodeRight); - }) - ->orderDesc($config['leftField']) - ->limit(1) - ->first(); - - if (!$targetNode) { - return $node; - } - } - - list(, $targetRight) = array_values($targetNode->extract([$left, $right])); - $edge = $this->_getMax(); - $leftBoundary = $nodeRight + 1; - $rightBoundary = $targetRight; - - $nodeToEdge = $edge - $nodeLeft + 1; - $shift = $nodeRight - $nodeLeft + 1; - $nodeToHole = $edge - $rightBoundary + $shift; - $this->_sync($nodeToEdge, '+', "BETWEEN {$nodeLeft} AND {$nodeRight}"); - $this->_sync($shift, '-', "BETWEEN {$leftBoundary} AND {$rightBoundary}"); - $this->_sync($nodeToHole, '-', "> {$edge}"); - - $node->set($left, $targetRight - ($nodeRight - $nodeLeft)); - $node->set($right, $targetRight); - - $node->setDirty($left, false); - $node->setDirty($right, false); - - return $node; - } - - /** - * Returns a single node from the tree from its primary key - * - * @param mixed $id Record id. - * @return \Cake\Datasource\EntityInterface - * @throws \Cake\Datasource\Exception\RecordNotFoundException When node was not found - */ - protected function _getNode($id) - { - $config = $this->getConfig(); - list($parent, $left, $right) = [$config['parent'], $config['left'], $config['right']]; - $primaryKey = $this->_getPrimaryKey(); - $fields = [$parent, $left, $right]; - if ($config['level']) { - $fields[] = $config['level']; - } - - $node = $this->_scope($this->_table->find()) - ->select($fields) - ->where([$this->_table->aliasField($primaryKey) => $id]) - ->first(); - - if (!$node) { - throw new RecordNotFoundException("Node \"{$id}\" was not found in the tree."); - } - - return $node; - } - - /** - * Recovers the lft and right column values out of the hierarchy defined by the - * parent column. - * - * @return void - */ - public function recover() - { - $this->_table->getConnection()->transactional(function () { - $this->_recoverTree(); - }); - } - - /** - * Recursive method used to recover a single level of the tree - * - * @param int $counter The Last left column value that was assigned - * @param mixed $parentId the parent id of the level to be recovered - * @param int $level Node level - * @return int The next value to use for the left column - */ - protected function _recoverTree($counter = 0, $parentId = null, $level = -1) - { - $config = $this->getConfig(); - list($parent, $left, $right) = [$config['parent'], $config['left'], $config['right']]; - $primaryKey = $this->_getPrimaryKey(); - $aliasedPrimaryKey = $this->_table->aliasField($primaryKey); - $order = $config['recoverOrder'] ?: $aliasedPrimaryKey; - - $query = $this->_scope($this->_table->query()) - ->select([$aliasedPrimaryKey]) - ->where([$this->_table->aliasField($parent) . ' IS' => $parentId]) - ->order($order) - ->enableHydration(false); - - $leftCounter = $counter; - $nextLevel = $level + 1; - foreach ($query as $row) { - $counter++; - $counter = $this->_recoverTree($counter, $row[$primaryKey], $nextLevel); - } - - if ($parentId === null) { - return $counter; - } - - $fields = [$left => $leftCounter, $right => $counter + 1]; - if ($config['level']) { - $fields[$config['level']] = $level; - } - - $this->_table->updateAll( - $fields, - [$primaryKey => $parentId] - ); - - return $counter + 1; - } - - /** - * Returns the maximum index value in the table. - * - * @return int - */ - protected function _getMax() - { - $field = $this->_config['right']; - $rightField = $this->_config['rightField']; - $edge = $this->_scope($this->_table->find()) - ->select([$field]) - ->orderDesc($rightField) - ->first(); - - if (empty($edge->{$field})) { - return 0; - } - - return $edge->{$field}; - } - - /** - * Auxiliary function used to automatically alter the value of both the left and - * right columns by a certain amount that match the passed conditions - * - * @param int $shift the value to use for operating the left and right columns - * @param string $dir The operator to use for shifting the value (+/-) - * @param string $conditions a SQL snipped to be used for comparing left or right - * against it. - * @param bool $mark whether to mark the updated values so that they can not be - * modified by future calls to this function. - * @return void - */ - protected function _sync($shift, $dir, $conditions, $mark = false) - { - $config = $this->_config; - - foreach ([$config['leftField'], $config['rightField']] as $field) { - $query = $this->_scope($this->_table->query()); - $exp = $query->newExpr(); - - $movement = clone $exp; - $movement->add($field)->add("$shift")->setConjunction($dir); - - $inverse = clone $exp; - $movement = $mark ? - $inverse->add($movement)->setConjunction('*')->add('-1') : - $movement; - - $where = clone $exp; - $where->add($field)->add($conditions)->setConjunction(''); - - $query->update() - ->set($exp->eq($field, $movement)) - ->where($where); - - $query->execute()->closeCursor(); - } - } - - /** - * Alters the passed query so that it only returns scoped records as defined - * in the tree configuration. - * - * @param \Cake\ORM\Query $query the Query to modify - * @return \Cake\ORM\Query - */ - protected function _scope($query) - { - $scope = $this->getConfig('scope'); - - if (is_array($scope)) { - return $query->where($scope); - } - if (is_callable($scope)) { - return $scope($query); - } - - return $query; - } - - /** - * Ensures that the provided entity contains non-empty values for the left and - * right fields - * - * @param \Cake\Datasource\EntityInterface $entity The entity to ensure fields for - * @return void - */ - protected function _ensureFields($entity) - { - $config = $this->getConfig(); - $fields = [$config['left'], $config['right']]; - $values = array_filter($entity->extract($fields)); - if (count($values) === count($fields)) { - return; - } - - $fresh = $this->_table->get($entity->get($this->_getPrimaryKey()), $fields); - $entity->set($fresh->extract($fields), ['guard' => false]); - - foreach ($fields as $field) { - $entity->setDirty($field, false); - } - } - - /** - * Returns a single string value representing the primary key of the attached table - * - * @return string - */ - protected function _getPrimaryKey() - { - if (!$this->_primaryKey) { - $primaryKey = (array)$this->_table->getPrimaryKey(); - $this->_primaryKey = $primaryKey[0]; - } - - return $this->_primaryKey; - } - - /** - * Returns the depth level of a node in the tree. - * - * @param int|string|\Cake\Datasource\EntityInterface $entity The entity or primary key get the level of. - * @return int|bool Integer of the level or false if the node does not exist. - */ - public function getLevel($entity) - { - $primaryKey = $this->_getPrimaryKey(); - $id = $entity; - if ($entity instanceof EntityInterface) { - $id = $entity->get($primaryKey); - } - $config = $this->getConfig(); - $entity = $this->_table->find('all') - ->select([$config['left'], $config['right']]) - ->where([$primaryKey => $id]) - ->first(); - - if ($entity === null) { - return false; - } - - $query = $this->_table->find('all')->where([ - $config['left'] . ' <' => $entity[$config['left']], - $config['right'] . ' >' => $entity[$config['right']], - ]); - - return $this->_scope($query)->count(); - } -} diff --git a/vendor/cakephp/cakephp/src/ORM/BehaviorRegistry.php b/vendor/cakephp/cakephp/src/ORM/BehaviorRegistry.php deleted file mode 100644 index a72389e..0000000 --- a/vendor/cakephp/cakephp/src/ORM/BehaviorRegistry.php +++ /dev/null @@ -1,283 +0,0 @@ -setTable($table); - } - } - - /** - * Attaches a table instance to this registry. - * - * @param \Cake\ORM\Table $table The table this registry is attached to. - * @return void - */ - public function setTable(Table $table) - { - $this->_table = $table; - $eventManager = $table->getEventManager(); - if ($eventManager !== null) { - $this->setEventManager($eventManager); - } - } - - /** - * Resolve a behavior classname. - * - * @param string $class Partial classname to resolve. - * @return string|null Either the correct classname or null. - * @since 3.5.7 - */ - public static function className($class) - { - $result = App::className($class, 'Model/Behavior', 'Behavior'); - if (!$result) { - $result = App::className($class, 'ORM/Behavior', 'Behavior'); - } - - return $result ?: null; - } - - /** - * Resolve a behavior classname. - * - * Part of the template method for Cake\Core\ObjectRegistry::load() - * - * @param string $class Partial classname to resolve. - * @return string|false Either the correct classname or false. - */ - protected function _resolveClassName($class) - { - return static::className($class) ?: false; - } - - /** - * Throws an exception when a behavior is missing. - * - * Part of the template method for Cake\Core\ObjectRegistry::load() - * and Cake\Core\ObjectRegistry::unload() - * - * @param string $class The classname that is missing. - * @param string $plugin The plugin the behavior is missing in. - * @return void - * @throws \Cake\ORM\Exception\MissingBehaviorException - */ - protected function _throwMissingClassError($class, $plugin) - { - throw new MissingBehaviorException([ - 'class' => $class . 'Behavior', - 'plugin' => $plugin - ]); - } - - /** - * Create the behavior instance. - * - * Part of the template method for Cake\Core\ObjectRegistry::load() - * Enabled behaviors will be registered with the event manager. - * - * @param string $class The classname that is missing. - * @param string $alias The alias of the object. - * @param array $config An array of config to use for the behavior. - * @return \Cake\ORM\Behavior The constructed behavior class. - */ - protected function _create($class, $alias, $config) - { - $instance = new $class($this->_table, $config); - $enable = isset($config['enabled']) ? $config['enabled'] : true; - if ($enable) { - $this->getEventManager()->on($instance); - } - $methods = $this->_getMethods($instance, $class, $alias); - $this->_methodMap += $methods['methods']; - $this->_finderMap += $methods['finders']; - - return $instance; - } - - /** - * Get the behavior methods and ensure there are no duplicates. - * - * Use the implementedEvents() method to exclude callback methods. - * Methods starting with `_` will be ignored, as will methods - * declared on Cake\ORM\Behavior - * - * @param \Cake\ORM\Behavior $instance The behavior to get methods from. - * @param string $class The classname that is missing. - * @param string $alias The alias of the object. - * @return array A list of implemented finders and methods. - * @throws \LogicException when duplicate methods are connected. - */ - protected function _getMethods(Behavior $instance, $class, $alias) - { - $finders = array_change_key_case($instance->implementedFinders()); - $methods = array_change_key_case($instance->implementedMethods()); - - foreach ($finders as $finder => $methodName) { - if (isset($this->_finderMap[$finder]) && $this->has($this->_finderMap[$finder][0])) { - $duplicate = $this->_finderMap[$finder]; - $error = sprintf( - '%s contains duplicate finder "%s" which is already provided by "%s"', - $class, - $finder, - $duplicate[0] - ); - throw new LogicException($error); - } - $finders[$finder] = [$alias, $methodName]; - } - - foreach ($methods as $method => $methodName) { - if (isset($this->_methodMap[$method]) && $this->has($this->_methodMap[$method][0])) { - $duplicate = $this->_methodMap[$method]; - $error = sprintf( - '%s contains duplicate method "%s" which is already provided by "%s"', - $class, - $method, - $duplicate[0] - ); - throw new LogicException($error); - } - $methods[$method] = [$alias, $methodName]; - } - - return compact('methods', 'finders'); - } - - /** - * Check if any loaded behavior implements a method. - * - * Will return true if any behavior provides a public non-finder method - * with the chosen name. - * - * @param string $method The method to check for. - * @return bool - */ - public function hasMethod($method) - { - $method = strtolower($method); - - return isset($this->_methodMap[$method]); - } - - /** - * Check if any loaded behavior implements the named finder. - * - * Will return true if any behavior provides a public method with - * the chosen name. - * - * @param string $method The method to check for. - * @return bool - */ - public function hasFinder($method) - { - $method = strtolower($method); - - return isset($this->_finderMap[$method]); - } - - /** - * Invoke a method on a behavior. - * - * @param string $method The method to invoke. - * @param array $args The arguments you want to invoke the method with. - * @return mixed The return value depends on the underlying behavior method. - * @throws \BadMethodCallException When the method is unknown. - */ - public function call($method, array $args = []) - { - $method = strtolower($method); - if ($this->hasMethod($method) && $this->has($this->_methodMap[$method][0])) { - list($behavior, $callMethod) = $this->_methodMap[$method]; - - return call_user_func_array([$this->_loaded[$behavior], $callMethod], $args); - } - - throw new BadMethodCallException( - sprintf('Cannot call "%s" it does not belong to any attached behavior.', $method) - ); - } - - /** - * Invoke a finder on a behavior. - * - * @param string $type The finder type to invoke. - * @param array $args The arguments you want to invoke the method with. - * @return mixed The return value depends on the underlying behavior method. - * @throws \BadMethodCallException When the method is unknown. - */ - public function callFinder($type, array $args = []) - { - $type = strtolower($type); - - if ($this->hasFinder($type) && $this->has($this->_finderMap[$type][0])) { - list($behavior, $callMethod) = $this->_finderMap[$type]; - - return call_user_func_array([$this->_loaded[$behavior], $callMethod], $args); - } - - throw new BadMethodCallException( - sprintf('Cannot call finder "%s" it does not belong to any attached behavior.', $type) - ); - } -} diff --git a/vendor/cakephp/cakephp/src/ORM/EagerLoadable.php b/vendor/cakephp/cakephp/src/ORM/EagerLoadable.php deleted file mode 100644 index 9d93f5b..0000000 --- a/vendor/cakephp/cakephp/src/ORM/EagerLoadable.php +++ /dev/null @@ -1,344 +0,0 @@ -author->company->country - * ``` - * - * The property path of `country` will be `author.company` - * - * @var string - */ - protected $_propertyPath; - - /** - * Whether or not this level can be fetched using a join. - * - * @var bool - */ - protected $_canBeJoined = false; - - /** - * Whether or not this level was meant for a "matching" fetch - * operation - * - * @var bool - */ - protected $_forMatching; - - /** - * The property name where the association result should be nested - * in the result. - * - * For example, in the following nested property: - * - * ``` - * $article->author->company->country - * ``` - * - * The target property of `country` will be just `country` - * - * @var string - */ - protected $_targetProperty; - - /** - * Constructor. The $config parameter accepts the following array - * keys: - * - * - associations - * - instance - * - config - * - canBeJoined - * - aliasPath - * - propertyPath - * - forMatching - * - targetProperty - * - * The keys maps to the settable properties in this class. - * - * @param string $name The Association name. - * @param array $config The list of properties to set. - */ - public function __construct($name, array $config = []) - { - $this->_name = $name; - $allowed = [ - 'associations', 'instance', 'config', 'canBeJoined', - 'aliasPath', 'propertyPath', 'forMatching', 'targetProperty' - ]; - foreach ($allowed as $property) { - if (isset($config[$property])) { - $this->{'_' . $property} = $config[$property]; - } - } - } - - /** - * Adds a new association to be loaded from this level. - * - * @param string $name The association name. - * @param \Cake\ORM\EagerLoadable $association The association to load. - * @return void - */ - public function addAssociation($name, EagerLoadable $association) - { - $this->_associations[$name] = $association; - } - - /** - * Returns the Association class instance to use for loading the records. - * - * @return array - */ - public function associations() - { - return $this->_associations; - } - - /** - * Gets the Association class instance to use for loading the records. - * - * @return \Cake\ORM\Association|null - */ - public function instance() - { - return $this->_instance; - } - - /** - * Gets a dot separated string representing the path of associations - * that should be followed to fetch this level. - * - * @return string|null - */ - public function aliasPath() - { - return $this->_aliasPath; - } - - /** - * Gets a dot separated string representing the path of entity properties - * in which results for this level should be placed. - * - * For example, in the following nested property: - * - * ``` - * $article->author->company->country - * ``` - * - * The property path of `country` will be `author.company` - * - * @return string|null - */ - public function propertyPath() - { - return $this->_propertyPath; - } - - /** - * Sets whether or not this level can be fetched using a join. - * - * @param bool $possible The value to set. - * @return $this - */ - public function setCanBeJoined($possible) - { - $this->_canBeJoined = (bool)$possible; - - return $this; - } - - /** - * Gets whether or not this level can be fetched using a join. - * - * If called with arguments it sets the value. - * As of 3.4.0 the setter part is deprecated, use setCanBeJoined() instead. - * - * @param bool|null $possible The value to set. - * @return bool - */ - public function canBeJoined($possible = null) - { - if ($possible !== null) { - deprecationWarning( - 'Using EagerLoadable::canBeJoined() as a setter is deprecated. ' . - 'Use setCanBeJoined() instead.' - ); - $this->setCanBeJoined($possible); - } - - return $this->_canBeJoined; - } - - /** - * Sets the list of options to pass to the association object for loading - * the records. - * - * @param array $config The value to set. - * @return $this - */ - public function setConfig(array $config) - { - $this->_config = $config; - - return $this; - } - - /** - * Gets the list of options to pass to the association object for loading - * the records. - * - * @return array - */ - public function getConfig() - { - return $this->_config; - } - - /** - * Sets the list of options to pass to the association object for loading - * the records. - * - * If called with no arguments it returns the current - * value. - * - * @deprecated 3.4.0 Use setConfig()/getConfig() instead. - * @param array|null $config The value to set. - * @return array - */ - public function config(array $config = null) - { - deprecationWarning( - 'EagerLoadable::config() is deprecated. ' . - 'Use setConfig()/getConfig() instead.' - ); - if ($config !== null) { - $this->setConfig($config); - } - - return $this->getConfig(); - } - - /** - * Gets whether or not this level was meant for a - * "matching" fetch operation. - * - * @return bool|null - */ - public function forMatching() - { - return $this->_forMatching; - } - - /** - * The property name where the result of this association - * should be nested at the end. - * - * For example, in the following nested property: - * - * ``` - * $article->author->company->country - * ``` - * - * The target property of `country` will be just `country` - * - * @return string|null - */ - public function targetProperty() - { - return $this->_targetProperty; - } - - /** - * Returns a representation of this object that can be passed to - * Cake\ORM\EagerLoader::contain() - * - * @return array - */ - public function asContainArray() - { - $associations = []; - foreach ($this->_associations as $assoc) { - $associations += $assoc->asContainArray(); - } - $config = $this->_config; - if ($this->_forMatching !== null) { - $config = ['matching' => $this->_forMatching] + $config; - } - - return [ - $this->_name => [ - 'associations' => $associations, - 'config' => $config - ] - ]; - } -} diff --git a/vendor/cakephp/cakephp/src/ORM/EagerLoader.php b/vendor/cakephp/cakephp/src/ORM/EagerLoader.php deleted file mode 100644 index 749f436..0000000 --- a/vendor/cakephp/cakephp/src/ORM/EagerLoader.php +++ /dev/null @@ -1,891 +0,0 @@ - 1, - 'foreignKey' => 1, - 'conditions' => 1, - 'fields' => 1, - 'sort' => 1, - 'matching' => 1, - 'queryBuilder' => 1, - 'finder' => 1, - 'joinType' => 1, - 'strategy' => 1, - 'negateMatch' => 1 - ]; - - /** - * A list of associations that should be loaded with a separate query - * - * @var \Cake\ORM\EagerLoadable[] - */ - protected $_loadExternal = []; - - /** - * Contains a list of the association names that are to be eagerly loaded - * - * @var array - */ - protected $_aliasList = []; - - /** - * Another EagerLoader instance that will be used for 'matching' associations. - * - * @var \Cake\ORM\EagerLoader - */ - protected $_matching; - - /** - * A map of table aliases pointing to the association objects they represent - * for the query. - * - * @var array - */ - protected $_joinsMap = []; - - /** - * Controls whether or not fields from associated tables - * will be eagerly loaded. When set to false, no fields will - * be loaded from associations. - * - * @var bool - */ - protected $_autoFields = true; - - /** - * Sets the list of associations that should be eagerly loaded along for a - * specific table using when a query is provided. The list of associated tables - * passed to this method must have been previously set as associations using the - * Table API. - * - * Associations can be arbitrarily nested using dot notation or nested arrays, - * this allows this object to calculate joins or any additional queries that - * must be executed to bring the required associated data. - * - * The getter part is deprecated as of 3.6.0. Use getContain() instead. - * - * Accepted options per passed association: - * - * - foreignKey: Used to set a different field to match both tables, if set to false - * no join conditions will be generated automatically - * - fields: An array with the fields that should be fetched from the association - * - queryBuilder: Equivalent to passing a callable instead of an options array - * - matching: Whether to inform the association class that it should filter the - * main query by the results fetched by that class. - * - joinType: For joinable associations, the SQL join type to use. - * - strategy: The loading strategy to use (join, select, subquery) - * - * @param array|string $associations list of table aliases to be queried. - * When this method is called multiple times it will merge previous list with - * the new one. - * @param callable|null $queryBuilder The query builder callable - * @return array Containments. - * @throws \InvalidArgumentException When using $queryBuilder with an array of $associations - */ - public function contain($associations = [], callable $queryBuilder = null) - { - if (empty($associations)) { - deprecationWarning( - 'Using EagerLoader::contain() as getter is deprecated. ' . - 'Use getContain() instead.' - ); - - return $this->getContain(); - } - - if ($queryBuilder) { - if (!is_string($associations)) { - throw new InvalidArgumentException( - sprintf('Cannot set containments. To use $queryBuilder, $associations must be a string') - ); - } - - $associations = [ - $associations => [ - 'queryBuilder' => $queryBuilder - ] - ]; - } - - $associations = (array)$associations; - $associations = $this->_reformatContain($associations, $this->_containments); - $this->_normalized = null; - $this->_loadExternal = []; - $this->_aliasList = []; - - return $this->_containments = $associations; - } - - /** - * Gets the list of associations that should be eagerly loaded along for a - * specific table using when a query is provided. The list of associated tables - * passed to this method must have been previously set as associations using the - * Table API. - * - * @return array Containments. - */ - public function getContain() - { - return $this->_containments; - } - - /** - * Remove any existing non-matching based containments. - * - * This will reset/clear out any contained associations that were not - * added via matching(). - * - * @return void - */ - public function clearContain() - { - $this->_containments = []; - $this->_normalized = null; - $this->_loadExternal = []; - $this->_aliasList = []; - } - - /** - * Sets whether or not contained associations will load fields automatically. - * - * @param bool $enable The value to set. - * @return $this - */ - public function enableAutoFields($enable = true) - { - $this->_autoFields = (bool)$enable; - - return $this; - } - - /** - * Gets whether or not contained associations will load fields automatically. - * - * @return bool The current value. - */ - public function isAutoFieldsEnabled() - { - return $this->_autoFields; - } - - /** - * Sets/Gets whether or not contained associations will load fields automatically. - * - * @deprecated 3.4.0 Use enableAutoFields()/isAutoFieldsEnabled() instead. - * @param bool|null $enable The value to set. - * @return bool The current value. - */ - public function autoFields($enable = null) - { - deprecationWarning( - 'EagerLoader::autoFields() is deprecated. ' . - 'Use enableAutoFields()/isAutoFieldsEnabled() instead.' - ); - if ($enable !== null) { - $this->enableAutoFields($enable); - } - - return $this->isAutoFieldsEnabled(); - } - - /** - * Adds a new association to the list that will be used to filter the results of - * any given query based on the results of finding records for that association. - * You can pass a dot separated path of associations to this method as its first - * parameter, this will translate in setting all those associations with the - * `matching` option. - * - * ### Options - * - 'joinType': INNER, OUTER, ... - * - 'fields': Fields to contain - * - * @param string $assoc A single association or a dot separated path of associations. - * @param callable|null $builder the callback function to be used for setting extra - * options to the filtering query - * @param array $options Extra options for the association matching. - * @return $this - */ - public function setMatching($assoc, callable $builder = null, $options = []) - { - if ($this->_matching === null) { - $this->_matching = new static(); - } - - if (!isset($options['joinType'])) { - $options['joinType'] = QueryInterface::JOIN_TYPE_INNER; - } - - $assocs = explode('.', $assoc); - $last = array_pop($assocs); - $containments = []; - $pointer =& $containments; - $opts = ['matching' => true] + $options; - unset($opts['negateMatch']); - - foreach ($assocs as $name) { - $pointer[$name] = $opts; - $pointer =& $pointer[$name]; - } - - $pointer[$last] = ['queryBuilder' => $builder, 'matching' => true] + $options; - - $this->_matching->contain($containments); - - return $this; - } - - /** - * Returns the current tree of associations to be matched. - * - * @return array The resulting containments array - */ - public function getMatching() - { - if ($this->_matching === null) { - $this->_matching = new static(); - } - - return $this->_matching->getContain(); - } - - /** - * Adds a new association to the list that will be used to filter the results of - * any given query based on the results of finding records for that association. - * You can pass a dot separated path of associations to this method as its first - * parameter, this will translate in setting all those associations with the - * `matching` option. - * - * If called with no arguments it will return the current tree of associations to - * be matched. - * - * @deprecated 3.4.0 Use setMatching()/getMatching() instead. - * @param string|null $assoc A single association or a dot separated path of associations. - * @param callable|null $builder the callback function to be used for setting extra - * options to the filtering query - * @param array $options Extra options for the association matching, such as 'joinType' - * and 'fields' - * @return array The resulting containments array - */ - public function matching($assoc = null, callable $builder = null, $options = []) - { - deprecationWarning( - 'EagerLoader::matching() is deprecated. ' . - 'Use setMatch()/getMatching() instead.' - ); - if ($assoc !== null) { - $this->setMatching($assoc, $builder, $options); - } - - return $this->getMatching(); - } - - /** - * Returns the fully normalized array of associations that should be eagerly - * loaded for a table. The normalized array will restructure the original array - * by sorting all associations under one key and special options under another. - * - * Each of the levels of the associations tree will converted to a Cake\ORM\EagerLoadable - * object, that contains all the information required for the association objects - * to load the information from the database. - * - * Additionally it will set an 'instance' key per association containing the - * association instance from the corresponding source table - * - * @param \Cake\ORM\Table $repository The table containing the association that - * will be normalized - * @return array - */ - public function normalized(Table $repository) - { - if ($this->_normalized !== null || empty($this->_containments)) { - return (array)$this->_normalized; - } - - $contain = []; - foreach ($this->_containments as $alias => $options) { - if (!empty($options['instance'])) { - $contain = (array)$this->_containments; - break; - } - $contain[$alias] = $this->_normalizeContain( - $repository, - $alias, - $options, - ['root' => null] - ); - } - - return $this->_normalized = $contain; - } - - /** - * Formats the containments array so that associations are always set as keys - * in the array. This function merges the original associations array with - * the new associations provided - * - * @param array $associations user provided containments array - * @param array $original The original containments array to merge - * with the new one - * @return array - */ - protected function _reformatContain($associations, $original) - { - $result = $original; - - foreach ((array)$associations as $table => $options) { - $pointer =& $result; - if (is_int($table)) { - $table = $options; - $options = []; - } - - if ($options instanceof EagerLoadable) { - $options = $options->asContainArray(); - $table = key($options); - $options = current($options); - } - - if (isset($this->_containOptions[$table])) { - $pointer[$table] = $options; - continue; - } - - if (strpos($table, '.')) { - $path = explode('.', $table); - $table = array_pop($path); - foreach ($path as $t) { - $pointer += [$t => []]; - $pointer =& $pointer[$t]; - } - } - - if (is_array($options)) { - $options = isset($options['config']) ? - $options['config'] + $options['associations'] : - $options; - $options = $this->_reformatContain( - $options, - isset($pointer[$table]) ? $pointer[$table] : [] - ); - } - - if ($options instanceof Closure) { - $options = ['queryBuilder' => $options]; - } - - $pointer += [$table => []]; - - if (isset($options['queryBuilder'], $pointer[$table]['queryBuilder'])) { - $first = $pointer[$table]['queryBuilder']; - $second = $options['queryBuilder']; - $options['queryBuilder'] = function ($query) use ($first, $second) { - return $second($first($query)); - }; - } - - if (!is_array($options)) { - $options = [$options => []]; - } - - $pointer[$table] = $options + $pointer[$table]; - } - - return $result; - } - - /** - * Modifies the passed query to apply joins or any other transformation required - * in order to eager load the associations described in the `contain` array. - * This method will not modify the query for loading external associations, i.e. - * those that cannot be loaded without executing a separate query. - * - * @param \Cake\ORM\Query $query The query to be modified - * @param \Cake\ORM\Table $repository The repository containing the associations - * @param bool $includeFields whether to append all fields from the associations - * to the passed query. This can be overridden according to the settings defined - * per association in the containments array - * @return void - */ - public function attachAssociations(Query $query, Table $repository, $includeFields) - { - if (empty($this->_containments) && $this->_matching === null) { - return; - } - - $attachable = $this->attachableAssociations($repository); - $processed = []; - do { - foreach ($attachable as $alias => $loadable) { - $config = $loadable->getConfig() + [ - 'aliasPath' => $loadable->aliasPath(), - 'propertyPath' => $loadable->propertyPath(), - 'includeFields' => $includeFields, - ]; - $loadable->instance()->attachTo($query, $config); - $processed[$alias] = true; - } - - $newAttachable = $this->attachableAssociations($repository); - $attachable = array_diff_key($newAttachable, $processed); - } while (!empty($attachable)); - } - - /** - * Returns an array with the associations that can be fetched using a single query, - * the array keys are the association aliases and the values will contain an array - * with Cake\ORM\EagerLoadable objects. - * - * @param \Cake\ORM\Table $repository The table containing the associations to be - * attached - * @return array - */ - public function attachableAssociations(Table $repository) - { - $contain = $this->normalized($repository); - $matching = $this->_matching ? $this->_matching->normalized($repository) : []; - $this->_fixStrategies(); - $this->_loadExternal = []; - - return $this->_resolveJoins($contain, $matching); - } - - /** - * Returns an array with the associations that need to be fetched using a - * separate query, each array value will contain a Cake\ORM\EagerLoadable object. - * - * @param \Cake\ORM\Table $repository The table containing the associations - * to be loaded - * @return \Cake\ORM\EagerLoadable[] - */ - public function externalAssociations(Table $repository) - { - if ($this->_loadExternal) { - return $this->_loadExternal; - } - - $this->attachableAssociations($repository); - - return $this->_loadExternal; - } - - /** - * Auxiliary function responsible for fully normalizing deep associations defined - * using `contain()` - * - * @param \Cake\ORM\Table $parent owning side of the association - * @param string $alias name of the association to be loaded - * @param array $options list of extra options to use for this association - * @param array $paths An array with two values, the first one is a list of dot - * separated strings representing associations that lead to this `$alias` in the - * chain of associations to be loaded. The second value is the path to follow in - * entities' properties to fetch a record of the corresponding association. - * @return \Cake\ORM\EagerLoadable Object with normalized associations - * @throws \InvalidArgumentException When containments refer to associations that do not exist. - */ - protected function _normalizeContain(Table $parent, $alias, $options, $paths) - { - $defaults = $this->_containOptions; - $instance = $parent->getAssociation($alias); - if (!$instance) { - throw new InvalidArgumentException( - sprintf('%s is not associated with %s', $parent->getAlias(), $alias) - ); - } - - $paths += ['aliasPath' => '', 'propertyPath' => '', 'root' => $alias]; - $paths['aliasPath'] .= '.' . $alias; - $paths['propertyPath'] .= '.' . $instance->getProperty(); - - $table = $instance->getTarget(); - - $extra = array_diff_key($options, $defaults); - $config = [ - 'associations' => [], - 'instance' => $instance, - 'config' => array_diff_key($options, $extra), - 'aliasPath' => trim($paths['aliasPath'], '.'), - 'propertyPath' => trim($paths['propertyPath'], '.'), - 'targetProperty' => $instance->getProperty() - ]; - $config['canBeJoined'] = $instance->canBeJoined($config['config']); - $eagerLoadable = new EagerLoadable($alias, $config); - - if ($config['canBeJoined']) { - $this->_aliasList[$paths['root']][$alias][] = $eagerLoadable; - } else { - $paths['root'] = $config['aliasPath']; - } - - foreach ($extra as $t => $assoc) { - $eagerLoadable->addAssociation( - $t, - $this->_normalizeContain($table, $t, $assoc, $paths) - ); - } - - return $eagerLoadable; - } - - /** - * Iterates over the joinable aliases list and corrects the fetching strategies - * in order to avoid aliases collision in the generated queries. - * - * This function operates on the array references that were generated by the - * _normalizeContain() function. - * - * @return void - */ - protected function _fixStrategies() - { - foreach ($this->_aliasList as $aliases) { - foreach ($aliases as $configs) { - if (count($configs) < 2) { - continue; - } - /* @var \Cake\ORM\EagerLoadable $loadable */ - foreach ($configs as $loadable) { - if (strpos($loadable->aliasPath(), '.')) { - $this->_correctStrategy($loadable); - } - } - } - } - } - - /** - * Changes the association fetching strategy if required because of duplicate - * under the same direct associations chain - * - * @param \Cake\ORM\EagerLoadable $loadable The association config - * @return void - */ - protected function _correctStrategy($loadable) - { - $config = $loadable->getConfig(); - $currentStrategy = isset($config['strategy']) ? - $config['strategy'] : - 'join'; - - if (!$loadable->canBeJoined() || $currentStrategy !== 'join') { - return; - } - - $config['strategy'] = Association::STRATEGY_SELECT; - $loadable->setConfig($config); - $loadable->setCanBeJoined(false); - } - - /** - * Helper function used to compile a list of all associations that can be - * joined in the query. - * - * @param array $associations list of associations from which to obtain joins. - * @param array $matching list of associations that should be forcibly joined. - * @return array - */ - protected function _resolveJoins($associations, $matching = []) - { - $result = []; - foreach ($matching as $table => $loadable) { - $result[$table] = $loadable; - $result += $this->_resolveJoins($loadable->associations(), []); - } - foreach ($associations as $table => $loadable) { - $inMatching = isset($matching[$table]); - if (!$inMatching && $loadable->canBeJoined()) { - $result[$table] = $loadable; - $result += $this->_resolveJoins($loadable->associations(), []); - continue; - } - - if ($inMatching) { - $this->_correctStrategy($loadable); - } - - $loadable->setCanBeJoined(false); - $this->_loadExternal[] = $loadable; - } - - return $result; - } - - /** - * Decorates the passed statement object in order to inject data from associations - * that cannot be joined directly. - * - * @param \Cake\ORM\Query $query The query for which to eager load external - * associations - * @param \Cake\Database\StatementInterface $statement The statement created after executing the $query - * @return \Cake\Database\StatementInterface statement modified statement with extra loaders - */ - public function loadExternal($query, $statement) - { - $external = $this->externalAssociations($query->getRepository()); - if (empty($external)) { - return $statement; - } - - $driver = $query->getConnection()->getDriver(); - list($collected, $statement) = $this->_collectKeys($external, $query, $statement); - - foreach ($external as $meta) { - $contain = $meta->associations(); - $instance = $meta->instance(); - $config = $meta->getConfig(); - $alias = $instance->getSource()->getAlias(); - $path = $meta->aliasPath(); - - $requiresKeys = $instance->requiresKeys($config); - if ($requiresKeys && empty($collected[$path][$alias])) { - continue; - } - - $keys = isset($collected[$path][$alias]) ? $collected[$path][$alias] : null; - $f = $instance->eagerLoader( - $config + [ - 'query' => $query, - 'contain' => $contain, - 'keys' => $keys, - 'nestKey' => $meta->aliasPath() - ] - ); - $statement = new CallbackStatement($statement, $driver, $f); - } - - return $statement; - } - - /** - * Returns an array having as keys a dotted path of associations that participate - * in this eager loader. The values of the array will contain the following keys - * - * - alias: The association alias - * - instance: The association instance - * - canBeJoined: Whether or not the association will be loaded using a JOIN - * - entityClass: The entity that should be used for hydrating the results - * - nestKey: A dotted path that can be used to correctly insert the data into the results. - * - matching: Whether or not it is an association loaded through `matching()`. - * - * @param \Cake\ORM\Table $table The table containing the association that - * will be normalized - * @return array - */ - public function associationsMap($table) - { - $map = []; - - if (!$this->getMatching() && !$this->getContain() && empty($this->_joinsMap)) { - return $map; - } - - $map = $this->_buildAssociationsMap($map, $this->_matching->normalized($table), true); - $map = $this->_buildAssociationsMap($map, $this->normalized($table)); - $map = $this->_buildAssociationsMap($map, $this->_joinsMap); - - return $map; - } - - /** - * An internal method to build a map which is used for the return value of the - * associationsMap() method. - * - * @param array $map An initial array for the map. - * @param array $level An array of EagerLoadable instances. - * @param bool $matching Whether or not it is an association loaded through `matching()`. - * @return array - */ - protected function _buildAssociationsMap($map, $level, $matching = false) - { - /* @var \Cake\ORM\EagerLoadable $meta */ - foreach ($level as $assoc => $meta) { - $canBeJoined = $meta->canBeJoined(); - $instance = $meta->instance(); - $associations = $meta->associations(); - $forMatching = $meta->forMatching(); - $map[] = [ - 'alias' => $assoc, - 'instance' => $instance, - 'canBeJoined' => $canBeJoined, - 'entityClass' => $instance->getTarget()->getEntityClass(), - 'nestKey' => $canBeJoined ? $assoc : $meta->aliasPath(), - 'matching' => $forMatching !== null ? $forMatching : $matching, - 'targetProperty' => $meta->targetProperty() - ]; - if ($canBeJoined && $associations) { - $map = $this->_buildAssociationsMap($map, $associations, $matching); - } - } - - return $map; - } - - /** - * Registers a table alias, typically loaded as a join in a query, as belonging to - * an association. This helps hydrators know what to do with the columns coming - * from such joined table. - * - * @param string $alias The table alias as it appears in the query. - * @param \Cake\ORM\Association $assoc The association object the alias represents; - * will be normalized - * @param bool $asMatching Whether or not this join results should be treated as a - * 'matching' association. - * @param string $targetProperty The property name where the results of the join should be nested at. - * If not passed, the default property for the association will be used. - * @return void - */ - public function addToJoinsMap($alias, Association $assoc, $asMatching = false, $targetProperty = null) - { - $this->_joinsMap[$alias] = new EagerLoadable($alias, [ - 'aliasPath' => $alias, - 'instance' => $assoc, - 'canBeJoined' => true, - 'forMatching' => $asMatching, - 'targetProperty' => $targetProperty ?: $assoc->getProperty() - ]); - } - - /** - * Helper function used to return the keys from the query records that will be used - * to eagerly load associations. - * - * @param array $external the list of external associations to be loaded - * @param \Cake\ORM\Query $query The query from which the results where generated - * @param \Cake\Database\Statement\BufferedStatement $statement The statement to work on - * @return array - */ - protected function _collectKeys($external, $query, $statement) - { - $collectKeys = []; - /* @var \Cake\ORM\EagerLoadable $meta */ - foreach ($external as $meta) { - $instance = $meta->instance(); - if (!$instance->requiresKeys($meta->getConfig())) { - continue; - } - - $source = $instance->getSource(); - $keys = $instance->type() === Association::MANY_TO_ONE ? - (array)$instance->getForeignKey() : - (array)$instance->getBindingKey(); - - $alias = $source->getAlias(); - $pkFields = []; - foreach ($keys as $key) { - $pkFields[] = key($query->aliasField($key, $alias)); - } - $collectKeys[$meta->aliasPath()] = [$alias, $pkFields, count($pkFields) === 1]; - } - - if (empty($collectKeys)) { - return [[], $statement]; - } - - if (!($statement instanceof BufferedStatement)) { - $statement = new BufferedStatement($statement, $query->getConnection()->getDriver()); - } - - return [$this->_groupKeys($statement, $collectKeys), $statement]; - } - - /** - * Helper function used to iterate a statement and extract the columns - * defined in $collectKeys - * - * @param \Cake\Database\Statement\BufferedStatement $statement The statement to read from. - * @param array $collectKeys The keys to collect - * @return array - */ - protected function _groupKeys($statement, $collectKeys) - { - $keys = []; - while ($result = $statement->fetch('assoc')) { - foreach ($collectKeys as $nestKey => $parts) { - // Missed joins will have null in the results. - if ($parts[2] === true && !isset($result[$parts[1][0]])) { - continue; - } - if ($parts[2] === true) { - $value = $result[$parts[1][0]]; - $keys[$nestKey][$parts[0]][$value] = $value; - continue; - } - - // Handle composite keys. - $collected = []; - foreach ($parts[1] as $key) { - $collected[] = $result[$key]; - } - $keys[$nestKey][$parts[0]][implode(';', $collected)] = $collected; - } - } - - $statement->rewind(); - - return $keys; - } - - /** - * Clone hook implementation - * - * Clone the _matching eager loader as well. - * - * @return void - */ - public function __clone() - { - if ($this->_matching) { - $this->_matching = clone $this->_matching; - } - } -} diff --git a/vendor/cakephp/cakephp/src/ORM/Entity.php b/vendor/cakephp/cakephp/src/ORM/Entity.php deleted file mode 100644 index a377149..0000000 --- a/vendor/cakephp/cakephp/src/ORM/Entity.php +++ /dev/null @@ -1,83 +0,0 @@ - 1, 'name' => 'Andrew']) - * ``` - * - * @param array $properties hash of properties to set in this entity - * @param array $options list of options to use when creating this entity - */ - public function __construct(array $properties = [], array $options = []) - { - $options += [ - 'useSetters' => true, - 'markClean' => false, - 'markNew' => null, - 'guard' => false, - 'source' => null - ]; - - if (!empty($options['source'])) { - $this->setSource($options['source']); - } - - if ($options['markNew'] !== null) { - $this->isNew($options['markNew']); - } - - if (!empty($properties) && $options['markClean'] && !$options['useSetters']) { - $this->_properties = $properties; - - return; - } - - if (!empty($properties)) { - $this->set($properties, [ - 'setter' => $options['useSetters'], - 'guard' => $options['guard'] - ]); - } - - if ($options['markClean']) { - $this->clean(); - } - } -} diff --git a/vendor/cakephp/cakephp/src/ORM/Exception/MissingBehaviorException.php b/vendor/cakephp/cakephp/src/ORM/Exception/MissingBehaviorException.php deleted file mode 100644 index 725e5e8..0000000 --- a/vendor/cakephp/cakephp/src/ORM/Exception/MissingBehaviorException.php +++ /dev/null @@ -1,24 +0,0 @@ -_getQuery($entities, $contain, $source); - $associations = array_keys($query->getContain()); - - $entities = $this->_injectResults($entities, $query, $associations, $source); - - return $returnSingle ? array_shift($entities) : $entities; - } - - /** - * Builds a query for loading the passed list of entity objects along with the - * associations specified in $contain. - * - * @param \Cake\Collection\CollectionInterface $objects The original entities - * @param array $contain The associations to be loaded - * @param \Cake\ORM\Table $source The table to use for fetching the top level entities - * @return \Cake\ORM\Query - */ - protected function _getQuery($objects, $contain, $source) - { - $primaryKey = $source->getPrimaryKey(); - $method = is_string($primaryKey) ? 'get' : 'extract'; - - $keys = $objects->map(function ($entity) use ($primaryKey, $method) { - return $entity->{$method}($primaryKey); - }); - - /** @var \Cake\ORM\Query $query */ - $query = $source - ->find() - ->select((array)$primaryKey) - ->where(function ($exp, $q) use ($primaryKey, $keys, $source) { - if (is_array($primaryKey) && count($primaryKey) === 1) { - $primaryKey = current($primaryKey); - } - - if (is_string($primaryKey)) { - return $exp->in($source->aliasField($primaryKey), $keys->toList()); - } - - $types = array_intersect_key($q->getDefaultTypes(), array_flip($primaryKey)); - $primaryKey = array_map([$source, 'aliasField'], $primaryKey); - - return new TupleComparison($primaryKey, $keys->toList(), $types, 'IN'); - }) - ->contain($contain); - - foreach ($query->getEagerLoader()->attachableAssociations($source) as $loadable) { - $config = $loadable->getConfig(); - $config['includeFields'] = true; - $loadable->setConfig($config); - } - - return $query; - } - - /** - * Returns a map of property names where the association results should be injected - * in the top level entities. - * - * @param \Cake\ORM\Table $source The table having the top level associations - * @param array $associations The name of the top level associations - * @return array - */ - protected function _getPropertyMap($source, $associations) - { - $map = []; - $container = $source->associations(); - foreach ($associations as $assoc) { - $map[$assoc] = $container->get($assoc)->getProperty(); - } - - return $map; - } - - /** - * Injects the results of the eager loader query into the original list of - * entities. - * - * @param array|\Traversable $objects The original list of entities - * @param \Cake\Collection\CollectionInterface|\Cake\Database\Query $results The loaded results - * @param array $associations The top level associations that were loaded - * @param \Cake\ORM\Table $source The table where the entities came from - * @return array - */ - protected function _injectResults($objects, $results, $associations, $source) - { - $injected = []; - $properties = $this->_getPropertyMap($source, $associations); - $primaryKey = (array)$source->getPrimaryKey(); - $results = $results - ->indexBy(function ($e) use ($primaryKey) { - return implode(';', $e->extract($primaryKey)); - }) - ->toArray(); - - foreach ($objects as $k => $object) { - $key = implode(';', $object->extract($primaryKey)); - if (!isset($results[$key])) { - $injected[$k] = $object; - continue; - } - - $loaded = $results[$key]; - foreach ($associations as $assoc) { - $property = $properties[$assoc]; - $object->set($property, $loaded->get($property), ['useSetters' => false]); - $object->setDirty($property, false); - } - $injected[$k] = $object; - } - - return $injected; - } -} diff --git a/vendor/cakephp/cakephp/src/ORM/Locator/LocatorAwareTrait.php b/vendor/cakephp/cakephp/src/ORM/Locator/LocatorAwareTrait.php deleted file mode 100644 index 2d26e51..0000000 --- a/vendor/cakephp/cakephp/src/ORM/Locator/LocatorAwareTrait.php +++ /dev/null @@ -1,79 +0,0 @@ -setTableLocator($tableLocator); - } - - return $this->getTableLocator(); - } - - /** - * Sets the table locator. - * - * @param \Cake\ORM\Locator\LocatorInterface $tableLocator LocatorInterface instance. - * @return $this - */ - public function setTableLocator(LocatorInterface $tableLocator) - { - $this->_tableLocator = $tableLocator; - - return $this; - } - - /** - * Gets the table locator. - * - * @return \Cake\ORM\Locator\LocatorInterface - */ - public function getTableLocator() - { - if (!$this->_tableLocator) { - $this->_tableLocator = TableRegistry::getTableLocator(); - } - - return $this->_tableLocator; - } -} diff --git a/vendor/cakephp/cakephp/src/ORM/Locator/LocatorInterface.php b/vendor/cakephp/cakephp/src/ORM/Locator/LocatorInterface.php deleted file mode 100644 index 08cddd6..0000000 --- a/vendor/cakephp/cakephp/src/ORM/Locator/LocatorInterface.php +++ /dev/null @@ -1,78 +0,0 @@ -_config = $alias; - - return $this; - } - - if (isset($this->_instances[$alias])) { - throw new RuntimeException(sprintf( - 'You cannot configure "%s", it has already been constructed.', - $alias - )); - } - - $this->_config[$alias] = $options; - - return $this; - } - - /** - * Returns configuration for an alias or the full configuration array for all aliases. - * - * @param string|null $alias Alias to get config for, null for complete config. - * @return array The config data. - */ - public function getConfig($alias = null) - { - if ($alias === null) { - return $this->_config; - } - - return isset($this->_config[$alias]) ? $this->_config[$alias] : []; - } - - /** - * Stores a list of options to be used when instantiating an object - * with a matching alias. - * - * The options that can be stored are those that are recognized by `get()` - * If second argument is omitted, it will return the current settings - * for $alias. - * - * If no arguments are passed it will return the full configuration array for - * all aliases - * - * @deprecated 3.4.0 Use setConfig()/getConfig() instead. - * @param string|array|null $alias Name of the alias - * @param array|null $options list of options for the alias - * @return array The config data. - * @throws \RuntimeException When you attempt to configure an existing table instance. - */ - public function config($alias = null, $options = null) - { - deprecationWarning( - 'TableLocator::config() is deprecated. ' . - 'Use getConfig()/setConfig() instead.' - ); - if ($alias !== null) { - if (is_string($alias) && $options === null) { - return $this->getConfig($alias); - } - - $this->setConfig($alias, $options); - } - - return $this->getConfig($alias); - } - - /** - * Get a table instance from the registry. - * - * Tables are only created once until the registry is flushed. - * This means that aliases must be unique across your application. - * This is important because table associations are resolved at runtime - * and cyclic references need to be handled correctly. - * - * The options that can be passed are the same as in Cake\ORM\Table::__construct(), but the - * `className` key is also recognized. - * - * ### Options - * - * - `className` Define the specific class name to use. If undefined, CakePHP will generate the - * class name based on the alias. For example 'Users' would result in - * `App\Model\Table\UsersTable` being used. If this class does not exist, - * then the default `Cake\ORM\Table` class will be used. By setting the `className` - * option you can define the specific class to use. The className option supports - * plugin short class references {@link Cake\Core\App::shortName()}. - * - `table` Define the table name to use. If undefined, this option will default to the underscored - * version of the alias name. - * - `connection` Inject the specific connection object to use. If this option and `connectionName` are undefined, - * The table class' `defaultConnectionName()` method will be invoked to fetch the connection name. - * - `connectionName` Define the connection name to use. The named connection will be fetched from - * Cake\Datasource\ConnectionManager. - * - * *Note* If your `$alias` uses plugin syntax only the name part will be used as - * key in the registry. This means that if two plugins, or a plugin and app provide - * the same alias, the registry will only store the first instance. - * - * @param string $alias The alias name you want to get. - * @param array $options The options you want to build the table with. - * If a table has already been loaded the options will be ignored. - * @return \Cake\ORM\Table - * @throws \RuntimeException When you try to configure an alias that already exists. - */ - public function get($alias, array $options = []) - { - if (isset($this->_instances[$alias])) { - if (!empty($options) && $this->_options[$alias] !== $options) { - throw new RuntimeException(sprintf( - 'You cannot configure "%s", it already exists in the registry.', - $alias - )); - } - - return $this->_instances[$alias]; - } - - $this->_options[$alias] = $options; - list(, $classAlias) = pluginSplit($alias); - $options = ['alias' => $classAlias] + $options; - - if (isset($this->_config[$alias])) { - $options += $this->_config[$alias]; - } - - if (empty($options['className'])) { - $options['className'] = Inflector::camelize($alias); - } - - $className = $this->_getClassName($alias, $options); - if ($className) { - $options['className'] = $className; - } else { - if (!isset($options['table']) && strpos($options['className'], '\\') === false) { - list(, $table) = pluginSplit($options['className']); - $options['table'] = Inflector::underscore($table); - } - $options['className'] = 'Cake\ORM\Table'; - } - - if (empty($options['connection'])) { - if (!empty($options['connectionName'])) { - $connectionName = $options['connectionName']; - } else { - /* @var \Cake\ORM\Table $className */ - $className = $options['className']; - $connectionName = $className::defaultConnectionName(); - } - $options['connection'] = ConnectionManager::get($connectionName); - } - if (empty($options['associations'])) { - $associations = new AssociationCollection($this); - $options['associations'] = $associations; - } - - $options['registryAlias'] = $alias; - $this->_instances[$alias] = $this->_create($options); - - if ($options['className'] === 'Cake\ORM\Table') { - $this->_fallbacked[$alias] = $this->_instances[$alias]; - } - - return $this->_instances[$alias]; - } - - /** - * Gets the table class name. - * - * @param string $alias The alias name you want to get. - * @param array $options Table options array. - * @return string|false - */ - protected function _getClassName($alias, array $options = []) - { - if (empty($options['className'])) { - $options['className'] = Inflector::camelize($alias); - } - - return App::className($options['className'], 'Model/Table', 'Table'); - } - - /** - * Wrapper for creating table instances - * - * @param array $options The alias to check for. - * @return \Cake\ORM\Table - */ - protected function _create(array $options) - { - return new $options['className']($options); - } - - /** - * {@inheritDoc} - */ - public function exists($alias) - { - return isset($this->_instances[$alias]); - } - - /** - * {@inheritDoc} - */ - public function set($alias, Table $object) - { - return $this->_instances[$alias] = $object; - } - - /** - * {@inheritDoc} - */ - public function clear() - { - $this->_instances = []; - $this->_config = []; - $this->_fallbacked = []; - } - - /** - * Returns the list of tables that were created by this registry that could - * not be instantiated from a specific subclass. This method is useful for - * debugging common mistakes when setting up associations or created new table - * classes. - * - * @return \Cake\ORM\Table[] - */ - public function genericInstances() - { - return $this->_fallbacked; - } - - /** - * {@inheritDoc} - */ - public function remove($alias) - { - unset( - $this->_instances[$alias], - $this->_config[$alias], - $this->_fallbacked[$alias] - ); - } -} diff --git a/vendor/cakephp/cakephp/src/ORM/Marshaller.php b/vendor/cakephp/cakephp/src/ORM/Marshaller.php deleted file mode 100644 index 45ae613..0000000 --- a/vendor/cakephp/cakephp/src/ORM/Marshaller.php +++ /dev/null @@ -1,850 +0,0 @@ -_table = $table; - } - - /** - * Build the map of property => marshalling callable. - * - * @param array $data The data being marshalled. - * @param array $options List of options containing the 'associated' key. - * @throws \InvalidArgumentException When associations do not exist. - * @return array - */ - protected function _buildPropertyMap($data, $options) - { - $map = []; - $schema = $this->_table->getSchema(); - - // Is a concrete column? - foreach (array_keys($data) as $prop) { - $columnType = $schema->getColumnType($prop); - if ($columnType) { - $map[$prop] = function ($value, $entity) use ($columnType) { - return Type::build($columnType)->marshal($value); - }; - } - } - - // Map associations - if (!isset($options['associated'])) { - $options['associated'] = []; - } - $include = $this->_normalizeAssociations($options['associated']); - foreach ($include as $key => $nested) { - if (is_int($key) && is_scalar($nested)) { - $key = $nested; - $nested = []; - } - // If the key is not a special field like _ids or _joinData - // it is a missing association that we should error on. - if (!$this->_table->hasAssociation($key)) { - if (substr($key, 0, 1) !== '_') { - throw new \InvalidArgumentException(sprintf( - 'Cannot marshal data for "%s" association. It is not associated with "%s".', - $key, - $this->_table->getAlias() - )); - } - continue; - } - $assoc = $this->_table->getAssociation($key); - - if (isset($options['forceNew'])) { - $nested['forceNew'] = $options['forceNew']; - } - if (isset($options['isMerge'])) { - $callback = function ($value, $entity) use ($assoc, $nested) { - /** @var \Cake\Datasource\EntityInterface $entity */ - $options = $nested + ['associated' => [], 'association' => $assoc]; - - return $this->_mergeAssociation($entity->get($assoc->getProperty()), $assoc, $value, $options); - }; - } else { - $callback = function ($value, $entity) use ($assoc, $nested) { - $options = $nested + ['associated' => []]; - - return $this->_marshalAssociation($assoc, $value, $options); - }; - } - $map[$assoc->getProperty()] = $callback; - } - - $behaviors = $this->_table->behaviors(); - foreach ($behaviors->loaded() as $name) { - $behavior = $behaviors->get($name); - if ($behavior instanceof PropertyMarshalInterface) { - $map += $behavior->buildMarshalMap($this, $map, $options); - } - } - - return $map; - } - - /** - * Hydrate one entity and its associated data. - * - * ### Options: - * - * - validate: Set to false to disable validation. Can also be a string of the validator ruleset to be applied. - * Defaults to true/default. - * - associated: Associations listed here will be marshalled as well. Defaults to null. - * - fieldList: (deprecated) Since 3.4.0. Use fields instead. - * - fields: A whitelist of fields to be assigned to the entity. If not present, - * the accessible fields list in the entity will be used. Defaults to null. - * - accessibleFields: A list of fields to allow or deny in entity accessible fields. Defaults to null - * - forceNew: When enabled, belongsToMany associations will have 'new' entities created - * when primary key values are set, and a record does not already exist. Normally primary key - * on missing entities would be ignored. Defaults to false. - * - * The above options can be used in each nested `associated` array. In addition to the above - * options you can also use the `onlyIds` option for HasMany and BelongsToMany associations. - * When true this option restricts the request data to only be read from `_ids`. - * - * ``` - * $result = $marshaller->one($data, [ - * 'associated' => ['Tags' => ['onlyIds' => true]] - * ]); - * ``` - * - * @param array $data The data to hydrate. - * @param array $options List of options - * @return \Cake\Datasource\EntityInterface - * @see \Cake\ORM\Table::newEntity() - * @see \Cake\ORM\Entity::$_accessible - */ - public function one(array $data, array $options = []) - { - list($data, $options) = $this->_prepareDataAndOptions($data, $options); - - $primaryKey = (array)$this->_table->getPrimaryKey(); - $entityClass = $this->_table->getEntityClass(); - /** @var \Cake\Datasource\EntityInterface $entity */ - $entity = new $entityClass(); - $entity->setSource($this->_table->getRegistryAlias()); - - if (isset($options['accessibleFields'])) { - foreach ((array)$options['accessibleFields'] as $key => $value) { - $entity->setAccess($key, $value); - } - } - $errors = $this->_validate($data, $options, true); - - $options['isMerge'] = false; - $propertyMap = $this->_buildPropertyMap($data, $options); - $properties = []; - foreach ($data as $key => $value) { - if (!empty($errors[$key])) { - if ($entity instanceof InvalidPropertyInterface) { - $entity->setInvalidField($key, $value); - } - continue; - } - - if ($value === '' && in_array($key, $primaryKey, true)) { - // Skip marshalling '' for pk fields. - continue; - } - if (isset($propertyMap[$key])) { - $properties[$key] = $propertyMap[$key]($value, $entity); - } else { - $properties[$key] = $value; - } - } - - if (isset($options['fields'])) { - foreach ((array)$options['fields'] as $field) { - if (array_key_exists($field, $properties)) { - $entity->set($field, $properties[$field]); - } - } - } else { - $entity->set($properties); - } - - // Don't flag clean association entities as - // dirty so we don't persist empty records. - foreach ($properties as $field => $value) { - if ($value instanceof EntityInterface) { - $entity->setDirty($field, $value->isDirty()); - } - } - - $entity->setErrors($errors); - - return $entity; - } - - /** - * Returns the validation errors for a data set based on the passed options - * - * @param array $data The data to validate. - * @param array $options The options passed to this marshaller. - * @param bool $isNew Whether it is a new entity or one to be updated. - * @return array The list of validation errors. - * @throws \RuntimeException If no validator can be created. - */ - protected function _validate($data, $options, $isNew) - { - if (!$options['validate']) { - return []; - } - - $validator = null; - if ($options['validate'] === true) { - $validator = $this->_table->getValidator(); - } elseif (is_string($options['validate'])) { - $validator = $this->_table->getValidator($options['validate']); - } elseif (is_object($options['validate'])) { - $validator = $options['validate']; - } - - if ($validator === null) { - throw new RuntimeException( - sprintf('validate must be a boolean, a string or an object. Got %s.', getTypeName($options['validate'])) - ); - } - - return $validator->errors($data, $isNew); - } - - /** - * Returns data and options prepared to validate and marshall. - * - * @param array $data The data to prepare. - * @param array $options The options passed to this marshaller. - * @return array An array containing prepared data and options. - */ - protected function _prepareDataAndOptions($data, $options) - { - $options += ['validate' => true]; - - if (!isset($options['fields']) && isset($options['fieldList'])) { - deprecationWarning( - 'The `fieldList` option for marshalling is deprecated. Use the `fields` option instead.' - ); - $options['fields'] = $options['fieldList']; - unset($options['fieldList']); - } - - $tableName = $this->_table->getAlias(); - if (isset($data[$tableName])) { - $data += $data[$tableName]; - unset($data[$tableName]); - } - - $data = new ArrayObject($data); - $options = new ArrayObject($options); - $this->_table->dispatchEvent('Model.beforeMarshal', compact('data', 'options')); - - return [(array)$data, (array)$options]; - } - - /** - * Create a new sub-marshaller and marshal the associated data. - * - * @param \Cake\ORM\Association $assoc The association to marshall - * @param array $value The data to hydrate - * @param array $options List of options. - * @return \Cake\Datasource\EntityInterface|\Cake\Datasource\EntityInterface[]|null - */ - protected function _marshalAssociation($assoc, $value, $options) - { - if (!is_array($value)) { - return null; - } - $targetTable = $assoc->getTarget(); - $marshaller = $targetTable->marshaller(); - $types = [Association::ONE_TO_ONE, Association::MANY_TO_ONE]; - if (in_array($assoc->type(), $types)) { - return $marshaller->one($value, (array)$options); - } - if ($assoc->type() === Association::ONE_TO_MANY || $assoc->type() === Association::MANY_TO_MANY) { - $hasIds = array_key_exists('_ids', $value); - $onlyIds = array_key_exists('onlyIds', $options) && $options['onlyIds']; - - if ($hasIds && is_array($value['_ids'])) { - return $this->_loadAssociatedByIds($assoc, $value['_ids']); - } - if ($hasIds || $onlyIds) { - return []; - } - } - if ($assoc->type() === Association::MANY_TO_MANY) { - return $marshaller->_belongsToMany($assoc, $value, (array)$options); - } - - return $marshaller->many($value, (array)$options); - } - - /** - * Hydrate many entities and their associated data. - * - * ### Options: - * - * - validate: Set to false to disable validation. Can also be a string of the validator ruleset to be applied. - * Defaults to true/default. - * - associated: Associations listed here will be marshalled as well. Defaults to null. - * - fieldList: (deprecated) Since 3.4.0. Use fields instead - * - fields: A whitelist of fields to be assigned to the entity. If not present, - * the accessible fields list in the entity will be used. Defaults to null. - * - accessibleFields: A list of fields to allow or deny in entity accessible fields. Defaults to null - * - forceNew: When enabled, belongsToMany associations will have 'new' entities created - * when primary key values are set, and a record does not already exist. Normally primary key - * on missing entities would be ignored. Defaults to false. - * - * @param array $data The data to hydrate. - * @param array $options List of options - * @return \Cake\Datasource\EntityInterface[] An array of hydrated records. - * @see \Cake\ORM\Table::newEntities() - * @see \Cake\ORM\Entity::$_accessible - */ - public function many(array $data, array $options = []) - { - $output = []; - foreach ($data as $record) { - if (!is_array($record)) { - continue; - } - $output[] = $this->one($record, $options); - } - - return $output; - } - - /** - * Marshals data for belongsToMany associations. - * - * Builds the related entities and handles the special casing - * for junction table entities. - * - * @param \Cake\ORM\Association\BelongsToMany $assoc The association to marshal. - * @param array $data The data to convert into entities. - * @param array $options List of options. - * @return \Cake\Datasource\EntityInterface[] An array of built entities. - * @throws \BadMethodCallException - * @throws \InvalidArgumentException - * @throws \RuntimeException - */ - protected function _belongsToMany(BelongsToMany $assoc, array $data, $options = []) - { - $associated = isset($options['associated']) ? $options['associated'] : []; - $forceNew = isset($options['forceNew']) ? $options['forceNew'] : false; - - $data = array_values($data); - - $target = $assoc->getTarget(); - $primaryKey = array_flip((array)$target->getPrimaryKey()); - $records = $conditions = []; - $primaryCount = count($primaryKey); - $conditions = []; - - foreach ($data as $i => $row) { - if (!is_array($row)) { - continue; - } - if (array_intersect_key($primaryKey, $row) === $primaryKey) { - $keys = array_intersect_key($row, $primaryKey); - if (count($keys) === $primaryCount) { - $rowConditions = []; - foreach ($keys as $key => $value) { - $rowConditions[][$target->aliasField($key)] = $value; - } - - if ($forceNew && !$target->exists($rowConditions)) { - $records[$i] = $this->one($row, $options); - } - - $conditions = array_merge($conditions, $rowConditions); - } - } else { - $records[$i] = $this->one($row, $options); - } - } - - if (!empty($conditions)) { - $query = $target->find(); - $query->andWhere(function ($exp) use ($conditions) { - /** @var \Cake\Database\Expression\QueryExpression $exp */ - return $exp->or_($conditions); - }); - - $keyFields = array_keys($primaryKey); - - $existing = []; - foreach ($query as $row) { - $k = implode(';', $row->extract($keyFields)); - $existing[$k] = $row; - } - - foreach ($data as $i => $row) { - $key = []; - foreach ($keyFields as $k) { - if (isset($row[$k])) { - $key[] = $row[$k]; - } - } - $key = implode(';', $key); - - // Update existing record and child associations - if (isset($existing[$key])) { - $records[$i] = $this->merge($existing[$key], $data[$i], $options); - } - } - } - - $jointMarshaller = $assoc->junction()->marshaller(); - - $nested = []; - if (isset($associated['_joinData'])) { - $nested = (array)$associated['_joinData']; - } - - foreach ($records as $i => $record) { - // Update junction table data in _joinData. - if (isset($data[$i]['_joinData'])) { - $joinData = $jointMarshaller->one($data[$i]['_joinData'], $nested); - $record->set('_joinData', $joinData); - } - } - - return $records; - } - - /** - * Loads a list of belongs to many from ids. - * - * @param \Cake\ORM\Association $assoc The association class for the belongsToMany association. - * @param array $ids The list of ids to load. - * @return \Cake\Datasource\EntityInterface[] An array of entities. - */ - protected function _loadAssociatedByIds($assoc, $ids) - { - if (empty($ids)) { - return []; - } - - $target = $assoc->getTarget(); - $primaryKey = (array)$target->getPrimaryKey(); - $multi = count($primaryKey) > 1; - $primaryKey = array_map([$target, 'aliasField'], $primaryKey); - - if ($multi) { - $first = current($ids); - if (!is_array($first) || count($first) !== count($primaryKey)) { - return []; - } - $filter = new TupleComparison($primaryKey, $ids, [], 'IN'); - } else { - $filter = [$primaryKey[0] . ' IN' => $ids]; - } - - return $target->find()->where($filter)->toArray(); - } - - /** - * Loads a list of belongs to many from ids. - * - * @param \Cake\ORM\Association $assoc The association class for the belongsToMany association. - * @param array $ids The list of ids to load. - * @return \Cake\Datasource\EntityInterface[] An array of entities. - * @deprecated Use _loadAssociatedByIds() - */ - protected function _loadBelongsToMany($assoc, $ids) - { - deprecationWarning( - 'Marshaller::_loadBelongsToMany() is deprecated. Use _loadAssociatedByIds() instead.' - ); - - return $this->_loadAssociatedByIds($assoc, $ids); - } - - /** - * Merges `$data` into `$entity` and recursively does the same for each one of - * the association names passed in `$options`. When merging associations, if an - * entity is not present in the parent entity for a given association, a new one - * will be created. - * - * When merging HasMany or BelongsToMany associations, all the entities in the - * `$data` array will appear, those that can be matched by primary key will get - * the data merged, but those that cannot, will be discarded. `ids` option can be used - * to determine whether the association must use the `_ids` format. - * - * ### Options: - * - * - associated: Associations listed here will be marshalled as well. - * - validate: Whether or not to validate data before hydrating the entities. Can - * also be set to a string to use a specific validator. Defaults to true/default. - * - fieldList: (deprecated) Since 3.4.0. Use fields instead - * - fields: A whitelist of fields to be assigned to the entity. If not present - * the accessible fields list in the entity will be used. - * - accessibleFields: A list of fields to allow or deny in entity accessible fields. - * - * The above options can be used in each nested `associated` array. In addition to the above - * options you can also use the `onlyIds` option for HasMany and BelongsToMany associations. - * When true this option restricts the request data to only be read from `_ids`. - * - * ``` - * $result = $marshaller->merge($entity, $data, [ - * 'associated' => ['Tags' => ['onlyIds' => true]] - * ]); - * ``` - * - * @param \Cake\Datasource\EntityInterface $entity the entity that will get the - * data merged in - * @param array $data key value list of fields to be merged into the entity - * @param array $options List of options. - * @return \Cake\Datasource\EntityInterface - * @see \Cake\ORM\Entity::$_accessible - */ - public function merge(EntityInterface $entity, array $data, array $options = []) - { - list($data, $options) = $this->_prepareDataAndOptions($data, $options); - - $isNew = $entity->isNew(); - $keys = []; - - if (!$isNew) { - $keys = $entity->extract((array)$this->_table->getPrimaryKey()); - } - - if (isset($options['accessibleFields'])) { - foreach ((array)$options['accessibleFields'] as $key => $value) { - $entity->setAccess($key, $value); - } - } - - $errors = $this->_validate($data + $keys, $options, $isNew); - $options['isMerge'] = true; - $propertyMap = $this->_buildPropertyMap($data, $options); - $properties = $marshalledAssocs = []; - foreach ($data as $key => $value) { - if (!empty($errors[$key])) { - if ($entity instanceof InvalidPropertyInterface) { - $entity->setInvalidField($key, $value); - } - continue; - } - $original = $entity->get($key); - - if (isset($propertyMap[$key])) { - $value = $propertyMap[$key]($value, $entity); - - // Don't dirty scalar values and objects that didn't - // change. Arrays will always be marked as dirty because - // the original/updated list could contain references to the - // same objects, even though those objects may have changed internally. - if ((is_scalar($value) && $original === $value) || - ($value === null && $original === $value) || - (is_object($value) && !($value instanceof EntityInterface) && $original == $value) - ) { - continue; - } - } - $properties[$key] = $value; - } - - $entity->setErrors($errors); - if (!isset($options['fields'])) { - $entity->set($properties); - - foreach ($properties as $field => $value) { - if ($value instanceof EntityInterface) { - $entity->setDirty($field, $value->isDirty()); - } - } - - return $entity; - } - - foreach ((array)$options['fields'] as $field) { - if (!array_key_exists($field, $properties)) { - continue; - } - $entity->set($field, $properties[$field]); - if ($properties[$field] instanceof EntityInterface) { - $entity->setDirty($field, $properties[$field]->isDirty()); - } - } - - return $entity; - } - - /** - * Merges each of the elements from `$data` into each of the entities in `$entities` - * and recursively does the same for each of the association names passed in - * `$options`. When merging associations, if an entity is not present in the parent - * entity for a given association, a new one will be created. - * - * Records in `$data` are matched against the entities using the primary key - * column. Entries in `$entities` that cannot be matched to any record in - * `$data` will be discarded. Records in `$data` that could not be matched will - * be marshalled as a new entity. - * - * When merging HasMany or BelongsToMany associations, all the entities in the - * `$data` array will appear, those that can be matched by primary key will get - * the data merged, but those that cannot, will be discarded. - * - * ### Options: - * - * - validate: Whether or not to validate data before hydrating the entities. Can - * also be set to a string to use a specific validator. Defaults to true/default. - * - associated: Associations listed here will be marshalled as well. - * - fieldList: (deprecated) Since 3.4.0. Use fields instead - * - fields: A whitelist of fields to be assigned to the entity. If not present, - * the accessible fields list in the entity will be used. - * - accessibleFields: A list of fields to allow or deny in entity accessible fields. - * - * @param \Cake\Datasource\EntityInterface[]|\Traversable $entities the entities that will get the - * data merged in - * @param array $data list of arrays to be merged into the entities - * @param array $options List of options. - * @return \Cake\Datasource\EntityInterface[] - * @see \Cake\ORM\Entity::$_accessible - */ - public function mergeMany($entities, array $data, array $options = []) - { - $primary = (array)$this->_table->getPrimaryKey(); - - $indexed = (new Collection($data)) - ->groupBy(function ($el) use ($primary) { - $keys = []; - foreach ($primary as $key) { - $keys[] = isset($el[$key]) ? $el[$key] : ''; - } - - return implode(';', $keys); - }) - ->map(function ($element, $key) { - return $key === '' ? $element : $element[0]; - }) - ->toArray(); - - $new = isset($indexed[null]) ? $indexed[null] : []; - unset($indexed[null]); - $output = []; - - foreach ($entities as $entity) { - if (!($entity instanceof EntityInterface)) { - continue; - } - - $key = implode(';', $entity->extract($primary)); - if ($key === null || !isset($indexed[$key])) { - continue; - } - - $output[] = $this->merge($entity, $indexed[$key], $options); - unset($indexed[$key]); - } - - $conditions = (new Collection($indexed)) - ->map(function ($data, $key) { - return explode(';', $key); - }) - ->filter(function ($keys) use ($primary) { - return count(array_filter($keys, 'strlen')) === count($primary); - }) - ->reduce(function ($conditions, $keys) use ($primary) { - $fields = array_map([$this->_table, 'aliasField'], $primary); - $conditions['OR'][] = array_combine($fields, $keys); - - return $conditions; - }, ['OR' => []]); - $maybeExistentQuery = $this->_table->find()->where($conditions); - - if (!empty($indexed) && count($maybeExistentQuery->clause('where'))) { - foreach ($maybeExistentQuery as $entity) { - $key = implode(';', $entity->extract($primary)); - if (isset($indexed[$key])) { - $output[] = $this->merge($entity, $indexed[$key], $options); - unset($indexed[$key]); - } - } - } - - foreach ((new Collection($indexed))->append($new) as $value) { - if (!is_array($value)) { - continue; - } - $output[] = $this->one($value, $options); - } - - return $output; - } - - /** - * Creates a new sub-marshaller and merges the associated data. - * - * @param \Cake\Datasource\EntityInterface|\Cake\Datasource\EntityInterface[] $original The original entity - * @param \Cake\ORM\Association $assoc The association to merge - * @param array $value The data to hydrate - * @param array $options List of options. - * @return \Cake\Datasource\EntityInterface|\Cake\Datasource\EntityInterface[]|null - */ - protected function _mergeAssociation($original, $assoc, $value, $options) - { - if (!$original) { - return $this->_marshalAssociation($assoc, $value, $options); - } - if (!is_array($value)) { - return null; - } - - $targetTable = $assoc->getTarget(); - $marshaller = $targetTable->marshaller(); - $types = [Association::ONE_TO_ONE, Association::MANY_TO_ONE]; - if (in_array($assoc->type(), $types)) { - return $marshaller->merge($original, $value, (array)$options); - } - if ($assoc->type() === Association::MANY_TO_MANY) { - return $marshaller->_mergeBelongsToMany($original, $assoc, $value, (array)$options); - } - - return $marshaller->mergeMany($original, $value, (array)$options); - } - - /** - * Creates a new sub-marshaller and merges the associated data for a BelongstoMany - * association. - * - * @param \Cake\Datasource\EntityInterface $original The original entity - * @param \Cake\ORM\Association $assoc The association to marshall - * @param array $value The data to hydrate - * @param array $options List of options. - * @return \Cake\Datasource\EntityInterface[] - */ - protected function _mergeBelongsToMany($original, $assoc, $value, $options) - { - $associated = isset($options['associated']) ? $options['associated'] : []; - - $hasIds = array_key_exists('_ids', $value); - $onlyIds = array_key_exists('onlyIds', $options) && $options['onlyIds']; - - if ($hasIds && is_array($value['_ids'])) { - return $this->_loadAssociatedByIds($assoc, $value['_ids']); - } - if ($hasIds || $onlyIds) { - return []; - } - - if (!empty($associated) && !in_array('_joinData', $associated) && !isset($associated['_joinData'])) { - return $this->mergeMany($original, $value, $options); - } - - return $this->_mergeJoinData($original, $assoc, $value, $options); - } - - /** - * Merge the special _joinData property into the entity set. - * - * @param \Cake\Datasource\EntityInterface $original The original entity - * @param \Cake\ORM\Association\BelongsToMany $assoc The association to marshall - * @param array $value The data to hydrate - * @param array $options List of options. - * @return \Cake\Datasource\EntityInterface[] An array of entities - */ - protected function _mergeJoinData($original, $assoc, $value, $options) - { - $associated = isset($options['associated']) ? $options['associated'] : []; - $extra = []; - foreach ($original as $entity) { - // Mark joinData as accessible so we can marshal it properly. - $entity->setAccess('_joinData', true); - - $joinData = $entity->get('_joinData'); - if ($joinData && $joinData instanceof EntityInterface) { - $extra[spl_object_hash($entity)] = $joinData; - } - } - - $joint = $assoc->junction(); - $marshaller = $joint->marshaller(); - - $nested = []; - if (isset($associated['_joinData'])) { - $nested = (array)$associated['_joinData']; - } - - $options['accessibleFields'] = ['_joinData' => true]; - - $records = $this->mergeMany($original, $value, $options); - foreach ($records as $record) { - $hash = spl_object_hash($record); - $value = $record->get('_joinData'); - - // Already an entity, no further marshalling required. - if ($value instanceof EntityInterface) { - continue; - } - - // Scalar data can't be handled - if (!is_array($value)) { - $record->unsetProperty('_joinData'); - continue; - } - - // Marshal data into the old object, or make a new joinData object. - if (isset($extra[$hash])) { - $record->set('_joinData', $marshaller->merge($extra[$hash], $value, $nested)); - } elseif (is_array($value)) { - $joinData = $marshaller->one($value, $nested); - $record->set('_joinData', $joinData); - } - } - - return $records; - } -} diff --git a/vendor/cakephp/cakephp/src/ORM/PropertyMarshalInterface.php b/vendor/cakephp/cakephp/src/ORM/PropertyMarshalInterface.php deleted file mode 100644 index bf2c6d5..0000000 --- a/vendor/cakephp/cakephp/src/ORM/PropertyMarshalInterface.php +++ /dev/null @@ -1,34 +0,0 @@ - callable]` of additional properties to marshal. - */ - public function buildMarshalMap($marshaller, $map, $options); -} diff --git a/vendor/cakephp/cakephp/src/ORM/Query.php b/vendor/cakephp/cakephp/src/ORM/Query.php deleted file mode 100644 index 210201b..0000000 --- a/vendor/cakephp/cakephp/src/ORM/Query.php +++ /dev/null @@ -1,1368 +0,0 @@ -repository($table); - - if ($this->_repository) { - $this->addDefaultTypes($this->_repository); - } - } - - /** - * {@inheritDoc} - * - * If you pass an instance of a `Cake\ORM\Table` or `Cake\ORM\Association` class, - * all the fields in the schema of the table or the association will be added to - * the select clause. - * - * @param array|\Cake\Database\ExpressionInterface|string|\Cake\ORM\Table|\Cake\ORM\Association $fields fields - * to be added to the list. - * @param bool $overwrite whether to reset fields with passed list or not - * @return $this - */ - public function select($fields = [], $overwrite = false) - { - if ($fields instanceof Association) { - $fields = $fields->getTarget(); - } - - if ($fields instanceof Table) { - $fields = $this->aliasFields($fields->getSchema()->columns(), $fields->getAlias()); - } - - return parent::select($fields, $overwrite); - } - - /** - * All the fields associated with the passed table except the excluded - * fields will be added to the select clause of the query. Passed excluded fields should not be aliased. - * After the first call to this method, a second call cannot be used to remove fields that have already - * been added to the query by the first. If you need to change the list after the first call, - * pass overwrite boolean true which will reset the select clause removing all previous additions. - * - * - * - * @param \Cake\ORM\Table|\Cake\ORM\Association $table The table to use to get an array of columns - * @param array $excludedFields The un-aliased column names you do not want selected from $table - * @param bool $overwrite Whether to reset/remove previous selected fields - * @return Query - * @throws \InvalidArgumentException If Association|Table is not passed in first argument - */ - public function selectAllExcept($table, array $excludedFields, $overwrite = false) - { - if ($table instanceof Association) { - $table = $table->getTarget(); - } - - if (!($table instanceof Table)) { - throw new \InvalidArgumentException('You must provide either an Association or a Table object'); - } - - $fields = array_diff($table->getSchema()->columns(), $excludedFields); - $aliasedFields = $this->aliasFields($fields); - - return $this->select($aliasedFields, $overwrite); - } - - /** - * Hints this object to associate the correct types when casting conditions - * for the database. This is done by extracting the field types from the schema - * associated to the passed table object. This prevents the user from repeating - * themselves when specifying conditions. - * - * This method returns the same query object for chaining. - * - * @param \Cake\ORM\Table $table The table to pull types from - * @return $this - */ - public function addDefaultTypes(Table $table) - { - $alias = $table->getAlias(); - $map = $table->getSchema()->typeMap(); - $fields = []; - foreach ($map as $f => $type) { - $fields[$f] = $fields[$alias . '.' . $f] = $fields[$alias . '__' . $f] = $type; - } - $this->getTypeMap()->addDefaults($fields); - - return $this; - } - - /** - * Sets the instance of the eager loader class to use for loading associations - * and storing containments. - * - * @param \Cake\ORM\EagerLoader $instance The eager loader to use. - * @return $this - */ - public function setEagerLoader(EagerLoader $instance) - { - $this->_eagerLoader = $instance; - - return $this; - } - - /** - * Returns the currently configured instance. - * - * @return \Cake\ORM\EagerLoader - */ - public function getEagerLoader() - { - if ($this->_eagerLoader === null) { - $this->_eagerLoader = new EagerLoader(); - } - - return $this->_eagerLoader; - } - - /** - * Sets the instance of the eager loader class to use for loading associations - * and storing containments. If called with no arguments, it will return the - * currently configured instance. - * - * @deprecated 3.4.0 Use setEagerLoader()/getEagerLoader() instead. - * @param \Cake\ORM\EagerLoader|null $instance The eager loader to use. Pass null - * to get the current eagerloader. - * @return \Cake\ORM\EagerLoader|$this - */ - public function eagerLoader(EagerLoader $instance = null) - { - deprecationWarning( - 'Query::eagerLoader() is deprecated. ' . - 'Use setEagerLoader()/getEagerLoader() instead.' - ); - if ($instance !== null) { - return $this->setEagerLoader($instance); - } - - return $this->getEagerLoader(); - } - - /** - * Sets the list of associations that should be eagerly loaded along with this - * query. The list of associated tables passed must have been previously set as - * associations using the Table API. - * - * ### Example: - * - * ``` - * // Bring articles' author information - * $query->contain('Author'); - * - * // Also bring the category and tags associated to each article - * $query->contain(['Category', 'Tag']); - * ``` - * - * Associations can be arbitrarily nested using dot notation or nested arrays, - * this allows this object to calculate joins or any additional queries that - * must be executed to bring the required associated data. - * - * ### Example: - * - * ``` - * // Eager load the product info, and for each product load other 2 associations - * $query->contain(['Product' => ['Manufacturer', 'Distributor']); - * - * // Which is equivalent to calling - * $query->contain(['Products.Manufactures', 'Products.Distributors']); - * - * // For an author query, load his region, state and country - * $query->contain('Regions.States.Countries'); - * ``` - * - * It is possible to control the conditions and fields selected for each of the - * contained associations: - * - * ### Example: - * - * ``` - * $query->contain(['Tags' => function ($q) { - * return $q->where(['Tags.is_popular' => true]); - * }]); - * - * $query->contain(['Products.Manufactures' => function ($q) { - * return $q->select(['name'])->where(['Manufactures.active' => true]); - * }]); - * ``` - * - * Each association might define special options when eager loaded, the allowed - * options that can be set per association are: - * - * - `foreignKey`: Used to set a different field to match both tables, if set to false - * no join conditions will be generated automatically. `false` can only be used on - * joinable associations and cannot be used with hasMany or belongsToMany associations. - * - `fields`: An array with the fields that should be fetched from the association. - * - `finder`: The finder to use when loading associated records. Either the name of the - * finder as a string, or an array to define options to pass to the finder. - * - `queryBuilder`: Equivalent to passing a callable instead of an options array. - * - * ### Example: - * - * ``` - * // Set options for the hasMany articles that will be eagerly loaded for an author - * $query->contain([ - * 'Articles' => [ - * 'fields' => ['title', 'author_id'] - * ] - * ]); - * ``` - * - * Finders can be configured to use options. - * - * ``` - * // Retrieve translations for the articles, but only those for the `en` and `es` locales - * $query->contain([ - * 'Articles' => [ - * 'finder' => [ - * 'translations' => [ - * 'locales' => ['en', 'es'] - * ] - * ] - * ] - * ]); - * ``` - * - * When containing associations, it is important to include foreign key columns. - * Failing to do so will trigger exceptions. - * - * ``` - * // Use a query builder to add conditions to the containment - * $query->contain('Authors', function ($q) { - * return $q->where(...); // add conditions - * }); - * // Use special join conditions for multiple containments in the same method call - * $query->contain([ - * 'Authors' => [ - * 'foreignKey' => false, - * 'queryBuilder' => function ($q) { - * return $q->where(...); // Add full filtering conditions - * } - * ], - * 'Tags' => function ($q) { - * return $q->where(...); // add conditions - * } - * ]); - * ``` - * - * If called with no arguments, this function will return an array with - * with the list of previously configured associations to be contained in the - * result. This getter part is deprecated as of 3.6.0. Use getContain() instead. - * - * If called with an empty first argument and `$override` is set to true, the - * previous list will be emptied. - * - * @param array|string|null $associations List of table aliases to be queried. - * @param callable|bool $override The query builder for the association, or - * if associations is an array, a bool on whether to override previous list - * with the one passed - * defaults to merging previous list with the new one. - * @return array|$this - */ - public function contain($associations = null, $override = false) - { - $loader = $this->getEagerLoader(); - if ($override === true) { - $this->clearContain(); - } - - if ($associations === null) { - deprecationWarning( - 'Using Query::contain() as getter is deprecated. ' . - 'Use getContain() instead.' - ); - - return $loader->getContain(); - } - - $queryBuilder = null; - if (is_callable($override)) { - $queryBuilder = $override; - } - - if ($associations) { - $loader->contain($associations, $queryBuilder); - } - $this->_addAssociationsToTypeMap( - $this->getRepository(), - $this->getTypeMap(), - $loader->getContain() - ); - - return $this; - } - - /** - * @return array - */ - public function getContain() - { - return $this->getEagerLoader()->getContain(); - } - - /** - * Clears the contained associations from the current query. - * - * @return $this - */ - public function clearContain() - { - $this->getEagerLoader()->clearContain(); - $this->_dirty(); - - return $this; - } - - /** - * Used to recursively add contained association column types to - * the query. - * - * @param \Cake\ORM\Table $table The table instance to pluck associations from. - * @param \Cake\Database\TypeMap $typeMap The typemap to check for columns in. - * This typemap is indirectly mutated via Cake\ORM\Query::addDefaultTypes() - * @param array $associations The nested tree of associations to walk. - * @return void - */ - protected function _addAssociationsToTypeMap($table, $typeMap, $associations) - { - foreach ($associations as $name => $nested) { - if (!$table->hasAssociation($name)) { - continue; - } - $association = $table->getAssociation($name); - $target = $association->getTarget(); - $primary = (array)$target->getPrimaryKey(); - if (empty($primary) || $typeMap->type($target->aliasField($primary[0])) === null) { - $this->addDefaultTypes($target); - } - if (!empty($nested)) { - $this->_addAssociationsToTypeMap($target, $typeMap, $nested); - } - } - } - - /** - * Adds filtering conditions to this query to only bring rows that have a relation - * to another from an associated table, based on conditions in the associated table. - * - * This function will add entries in the `contain` graph. - * - * ### Example: - * - * ``` - * // Bring only articles that were tagged with 'cake' - * $query->matching('Tags', function ($q) { - * return $q->where(['name' => 'cake']); - * ); - * ``` - * - * It is possible to filter by deep associations by using dot notation: - * - * ### Example: - * - * ``` - * // Bring only articles that were commented by 'markstory' - * $query->matching('Comments.Users', function ($q) { - * return $q->where(['username' => 'markstory']); - * ); - * ``` - * - * As this function will create `INNER JOIN`, you might want to consider - * calling `distinct` on this query as you might get duplicate rows if - * your conditions don't filter them already. This might be the case, for example, - * of the same user commenting more than once in the same article. - * - * ### Example: - * - * ``` - * // Bring unique articles that were commented by 'markstory' - * $query->distinct(['Articles.id']) - * ->matching('Comments.Users', function ($q) { - * return $q->where(['username' => 'markstory']); - * ); - * ``` - * - * Please note that the query passed to the closure will only accept calling - * `select`, `where`, `andWhere` and `orWhere` on it. If you wish to - * add more complex clauses you can do it directly in the main query. - * - * @param string $assoc The association to filter by - * @param callable|null $builder a function that will receive a pre-made query object - * that can be used to add custom conditions or selecting some fields - * @return $this - */ - public function matching($assoc, callable $builder = null) - { - $result = $this->getEagerLoader()->setMatching($assoc, $builder)->getMatching(); - $this->_addAssociationsToTypeMap($this->getRepository(), $this->getTypeMap(), $result); - $this->_dirty(); - - return $this; - } - - /** - * Creates a LEFT JOIN with the passed association table while preserving - * the foreign key matching and the custom conditions that were originally set - * for it. - * - * This function will add entries in the `contain` graph. - * - * ### Example: - * - * ``` - * // Get the count of articles per user - * $usersQuery - * ->select(['total_articles' => $query->func()->count('Articles.id')]) - * ->leftJoinWith('Articles') - * ->group(['Users.id']) - * ->enableAutoFields(true); - * ``` - * - * You can also customize the conditions passed to the LEFT JOIN: - * - * ``` - * // Get the count of articles per user with at least 5 votes - * $usersQuery - * ->select(['total_articles' => $query->func()->count('Articles.id')]) - * ->leftJoinWith('Articles', function ($q) { - * return $q->where(['Articles.votes >=' => 5]); - * }) - * ->group(['Users.id']) - * ->enableAutoFields(true); - * ``` - * - * This will create the following SQL: - * - * ``` - * SELECT COUNT(Articles.id) AS total_articles, Users.* - * FROM users Users - * LEFT JOIN articles Articles ON Articles.user_id = Users.id AND Articles.votes >= 5 - * GROUP BY USers.id - * ``` - * - * It is possible to left join deep associations by using dot notation - * - * ### Example: - * - * ``` - * // Total comments in articles by 'markstory' - * $query - * ->select(['total_comments' => $query->func()->count('Comments.id')]) - * ->leftJoinWith('Comments.Users', function ($q) { - * return $q->where(['username' => 'markstory']); - * ) - * ->group(['Users.id']); - * ``` - * - * Please note that the query passed to the closure will only accept calling - * `select`, `where`, `andWhere` and `orWhere` on it. If you wish to - * add more complex clauses you can do it directly in the main query. - * - * @param string $assoc The association to join with - * @param callable|null $builder a function that will receive a pre-made query object - * that can be used to add custom conditions or selecting some fields - * @return $this - */ - public function leftJoinWith($assoc, callable $builder = null) - { - $result = $this->getEagerLoader() - ->setMatching($assoc, $builder, [ - 'joinType' => QueryInterface::JOIN_TYPE_LEFT, - 'fields' => false - ]) - ->getMatching(); - $this->_addAssociationsToTypeMap($this->getRepository(), $this->getTypeMap(), $result); - $this->_dirty(); - - return $this; - } - - /** - * Creates an INNER JOIN with the passed association table while preserving - * the foreign key matching and the custom conditions that were originally set - * for it. - * - * This function will add entries in the `contain` graph. - * - * ### Example: - * - * ``` - * // Bring only articles that were tagged with 'cake' - * $query->innerJoinWith('Tags', function ($q) { - * return $q->where(['name' => 'cake']); - * ); - * ``` - * - * This will create the following SQL: - * - * ``` - * SELECT Articles.* - * FROM articles Articles - * INNER JOIN tags Tags ON Tags.name = 'cake' - * INNER JOIN articles_tags ArticlesTags ON ArticlesTags.tag_id = Tags.id - * AND ArticlesTags.articles_id = Articles.id - * ``` - * - * This function works the same as `matching()` with the difference that it - * will select no fields from the association. - * - * @param string $assoc The association to join with - * @param callable|null $builder a function that will receive a pre-made query object - * that can be used to add custom conditions or selecting some fields - * @return $this - * @see \Cake\ORM\Query::matching() - */ - public function innerJoinWith($assoc, callable $builder = null) - { - $result = $this->getEagerLoader() - ->setMatching($assoc, $builder, [ - 'joinType' => QueryInterface::JOIN_TYPE_INNER, - 'fields' => false - ]) - ->getMatching(); - $this->_addAssociationsToTypeMap($this->getRepository(), $this->getTypeMap(), $result); - $this->_dirty(); - - return $this; - } - - /** - * Adds filtering conditions to this query to only bring rows that have no match - * to another from an associated table, based on conditions in the associated table. - * - * This function will add entries in the `contain` graph. - * - * ### Example: - * - * ``` - * // Bring only articles that were not tagged with 'cake' - * $query->notMatching('Tags', function ($q) { - * return $q->where(['name' => 'cake']); - * ); - * ``` - * - * It is possible to filter by deep associations by using dot notation: - * - * ### Example: - * - * ``` - * // Bring only articles that weren't commented by 'markstory' - * $query->notMatching('Comments.Users', function ($q) { - * return $q->where(['username' => 'markstory']); - * ); - * ``` - * - * As this function will create a `LEFT JOIN`, you might want to consider - * calling `distinct` on this query as you might get duplicate rows if - * your conditions don't filter them already. This might be the case, for example, - * of the same article having multiple comments. - * - * ### Example: - * - * ``` - * // Bring unique articles that were commented by 'markstory' - * $query->distinct(['Articles.id']) - * ->notMatching('Comments.Users', function ($q) { - * return $q->where(['username' => 'markstory']); - * ); - * ``` - * - * Please note that the query passed to the closure will only accept calling - * `select`, `where`, `andWhere` and `orWhere` on it. If you wish to - * add more complex clauses you can do it directly in the main query. - * - * @param string $assoc The association to filter by - * @param callable|null $builder a function that will receive a pre-made query object - * that can be used to add custom conditions or selecting some fields - * @return $this - */ - public function notMatching($assoc, callable $builder = null) - { - $result = $this->getEagerLoader() - ->setMatching($assoc, $builder, [ - 'joinType' => QueryInterface::JOIN_TYPE_LEFT, - 'fields' => false, - 'negateMatch' => true - ]) - ->getMatching(); - $this->_addAssociationsToTypeMap($this->getRepository(), $this->getTypeMap(), $result); - $this->_dirty(); - - return $this; - } - - /** - * {@inheritDoc} - * - * Populates or adds parts to current query clauses using an array. - * This is handy for passing all query clauses at once. The option array accepts: - * - * - fields: Maps to the select method - * - conditions: Maps to the where method - * - limit: Maps to the limit method - * - order: Maps to the order method - * - offset: Maps to the offset method - * - group: Maps to the group method - * - having: Maps to the having method - * - contain: Maps to the contain options for eager loading - * - join: Maps to the join method - * - page: Maps to the page method - * - * ### Example: - * - * ``` - * $query->applyOptions([ - * 'fields' => ['id', 'name'], - * 'conditions' => [ - * 'created >=' => '2013-01-01' - * ], - * 'limit' => 10 - * ]); - * ``` - * - * Is equivalent to: - * - * ``` - * $query - * ->select(['id', 'name']) - * ->where(['created >=' => '2013-01-01']) - * ->limit(10) - * ``` - */ - public function applyOptions(array $options) - { - $valid = [ - 'fields' => 'select', - 'conditions' => 'where', - 'join' => 'join', - 'order' => 'order', - 'limit' => 'limit', - 'offset' => 'offset', - 'group' => 'group', - 'having' => 'having', - 'contain' => 'contain', - 'page' => 'page', - ]; - - ksort($options); - foreach ($options as $option => $values) { - if (isset($valid[$option], $values)) { - $this->{$valid[$option]}($values); - } else { - $this->_options[$option] = $values; - } - } - - return $this; - } - - /** - * Creates a copy of this current query, triggers beforeFind and resets some state. - * - * The following state will be cleared: - * - * - autoFields - * - limit - * - offset - * - map/reduce functions - * - result formatters - * - order - * - containments - * - * This method creates query clones that are useful when working with subqueries. - * - * @return \Cake\ORM\Query - */ - public function cleanCopy() - { - $clone = clone $this; - $clone->setEagerLoader(clone $this->getEagerLoader()); - $clone->triggerBeforeFind(); - $clone->enableAutoFields(false); - $clone->limit(null); - $clone->order([], true); - $clone->offset(null); - $clone->mapReduce(null, null, true); - $clone->formatResults(null, true); - $clone->setSelectTypeMap(new TypeMap()); - $clone->decorateResults(null, true); - - return $clone; - } - - /** - * Object clone hook. - * - * Destroys the clones inner iterator and clones the value binder, and eagerloader instances. - * - * @return void - */ - public function __clone() - { - parent::__clone(); - if ($this->_eagerLoader) { - $this->_eagerLoader = clone $this->_eagerLoader; - } - } - - /** - * {@inheritDoc} - * - * Returns the COUNT(*) for the query. If the query has not been - * modified, and the count has already been performed the cached - * value is returned - */ - public function count() - { - if ($this->_resultsCount === null) { - $this->_resultsCount = $this->_performCount(); - } - - return $this->_resultsCount; - } - - /** - * Performs and returns the COUNT(*) for the query. - * - * @return int - */ - protected function _performCount() - { - $query = $this->cleanCopy(); - $counter = $this->_counter; - if ($counter) { - $query->counter(null); - - return (int)$counter($query); - } - - $complex = ( - $query->clause('distinct') || - count($query->clause('group')) || - count($query->clause('union')) || - $query->clause('having') - ); - - if (!$complex) { - // Expression fields could have bound parameters. - foreach ($query->clause('select') as $field) { - if ($field instanceof ExpressionInterface) { - $complex = true; - break; - } - } - } - - if (!$complex && $this->_valueBinder !== null) { - $order = $this->clause('order'); - $complex = $order === null ? false : $order->hasNestedExpression(); - } - - $count = ['count' => $query->func()->count('*')]; - - if (!$complex) { - $query->getEagerLoader()->enableAutoFields(false); - $statement = $query - ->select($count, true) - ->enableAutoFields(false) - ->execute(); - } else { - $statement = $this->getConnection()->newQuery() - ->select($count) - ->from(['count_source' => $query]) - ->execute(); - } - - $result = $statement->fetch('assoc')['count']; - $statement->closeCursor(); - - return (int)$result; - } - - /** - * Registers a callable function that will be executed when the `count` method in - * this query is called. The return value for the function will be set as the - * return value of the `count` method. - * - * This is particularly useful when you need to optimize a query for returning the - * count, for example removing unnecessary joins, removing group by or just return - * an estimated number of rows. - * - * The callback will receive as first argument a clone of this query and not this - * query itself. - * - * If the first param is a null value, the built-in counter function will be called - * instead - * - * @param callable|null $counter The counter value - * @return $this - */ - public function counter($counter) - { - $this->_counter = $counter; - - return $this; - } - - /** - * Toggle hydrating entities. - * - * If set to false array results will be returned for the query. - * - * @param bool $enable Use a boolean to set the hydration mode. - * @return $this - */ - public function enableHydration($enable = true) - { - $this->_dirty(); - $this->_hydrate = (bool)$enable; - - return $this; - } - - /** - * Returns the current hydration mode. - * - * @return bool - */ - public function isHydrationEnabled() - { - return $this->_hydrate; - } - - /** - * Toggle hydrating entities. - * - * If set to false array results will be returned. - * - * @deprecated 3.4.0 Use enableHydration()/isHydrationEnabled() instead. - * @param bool|null $enable Use a boolean to set the hydration mode. - * Null will fetch the current hydration mode. - * @return bool|$this A boolean when reading, and $this when setting the mode. - */ - public function hydrate($enable = null) - { - deprecationWarning( - 'Query::hydrate() is deprecated. ' . - 'Use enableHydration()/isHydrationEnabled() instead.' - ); - if ($enable === null) { - return $this->isHydrationEnabled(); - } - - return $this->enableHydration($enable); - } - - /** - * {@inheritDoc} - * - * @return $this - * @throws \RuntimeException When you attempt to cache a non-select query. - */ - public function cache($key, $config = 'default') - { - if ($this->_type !== 'select' && $this->_type !== null) { - throw new RuntimeException('You cannot cache the results of non-select queries.'); - } - - return $this->_cache($key, $config); - } - - /** - * {@inheritDoc} - * - * @throws \RuntimeException if this method is called on a non-select Query. - */ - public function all() - { - if ($this->_type !== 'select' && $this->_type !== null) { - throw new RuntimeException( - 'You cannot call all() on a non-select query. Use execute() instead.' - ); - } - - return $this->_all(); - } - - /** - * Trigger the beforeFind event on the query's repository object. - * - * Will not trigger more than once, and only for select queries. - * - * @return void - */ - public function triggerBeforeFind() - { - if (!$this->_beforeFindFired && $this->_type === 'select') { - $table = $this->getRepository(); - $this->_beforeFindFired = true; - /* @var \Cake\Event\EventDispatcherInterface $table */ - $table->dispatchEvent('Model.beforeFind', [ - $this, - new ArrayObject($this->_options), - !$this->isEagerLoaded() - ]); - } - } - - /** - * {@inheritDoc} - */ - public function sql(ValueBinder $binder = null) - { - $this->triggerBeforeFind(); - - $this->_transformQuery(); - - return parent::sql($binder); - } - - /** - * Executes this query and returns a ResultSet object containing the results. - * This will also setup the correct statement class in order to eager load deep - * associations. - * - * @return \Cake\ORM\ResultSet - */ - protected function _execute() - { - $this->triggerBeforeFind(); - if ($this->_results) { - $decorator = $this->_decoratorClass(); - - return new $decorator($this->_results); - } - - $statement = $this->getEagerLoader()->loadExternal($this, $this->execute()); - - return new ResultSet($this, $statement); - } - - /** - * Applies some defaults to the query object before it is executed. - * - * Specifically add the FROM clause, adds default table fields if none are - * specified and applies the joins required to eager load associations defined - * using `contain` - * - * It also sets the default types for the columns in the select clause - * - * @see \Cake\Database\Query::execute() - * @return void - */ - protected function _transformQuery() - { - if (!$this->_dirty || $this->_type !== 'select') { - return; - } - - if (empty($this->_parts['from'])) { - $this->from([$this->_repository->getAlias() => $this->_repository->getTable()]); - } - $this->_addDefaultFields(); - $this->getEagerLoader()->attachAssociations($this, $this->_repository, !$this->_hasFields); - $this->_addDefaultSelectTypes(); - } - - /** - * Inspects if there are any set fields for selecting, otherwise adds all - * the fields for the default table. - * - * @return void - */ - protected function _addDefaultFields() - { - $select = $this->clause('select'); - $this->_hasFields = true; - - if (!count($select) || $this->_autoFields === true) { - $this->_hasFields = false; - $this->select($this->getRepository()->getSchema()->columns()); - $select = $this->clause('select'); - } - - $aliased = $this->aliasFields($select, $this->getRepository()->getAlias()); - $this->select($aliased, true); - } - - /** - * Sets the default types for converting the fields in the select clause - * - * @return void - */ - protected function _addDefaultSelectTypes() - { - $typeMap = $this->getTypeMap()->getDefaults(); - $select = $this->clause('select'); - $types = []; - - foreach ($select as $alias => $value) { - if (isset($typeMap[$alias])) { - $types[$alias] = $typeMap[$alias]; - continue; - } - if (is_string($value) && isset($typeMap[$value])) { - $types[$alias] = $typeMap[$value]; - } - if ($value instanceof TypedResultInterface) { - $types[$alias] = $value->getReturnType(); - } - } - $this->getSelectTypeMap()->addDefaults($types); - } - - /** - * {@inheritDoc} - * - * @see \Cake\ORM\Table::find() - */ - public function find($finder, array $options = []) - { - return $this->getRepository()->callFinder($finder, $this, $options); - } - - /** - * Marks a query as dirty, removing any preprocessed information - * from in memory caching such as previous results - * - * @return void - */ - protected function _dirty() - { - $this->_results = null; - $this->_resultsCount = null; - parent::_dirty(); - } - - /** - * Create an update query. - * - * This changes the query type to be 'update'. - * Can be combined with set() and where() methods to create update queries. - * - * @param string|null $table Unused parameter. - * @return $this - */ - public function update($table = null) - { - $table = $table ?: $this->getRepository()->getTable(); - - return parent::update($table); - } - - /** - * Create a delete query. - * - * This changes the query type to be 'delete'. - * Can be combined with the where() method to create delete queries. - * - * @param string|null $table Unused parameter. - * @return $this - */ - public function delete($table = null) - { - $repo = $this->getRepository(); - $this->from([$repo->getAlias() => $repo->getTable()]); - - return parent::delete(); - } - - /** - * Create an insert query. - * - * This changes the query type to be 'insert'. - * Note calling this method will reset any data previously set - * with Query::values() - * - * Can be combined with the where() method to create delete queries. - * - * @param array $columns The columns to insert into. - * @param array $types A map between columns & their datatypes. - * @return $this - */ - public function insert(array $columns, array $types = []) - { - $table = $this->getRepository()->getTable(); - $this->into($table); - - return parent::insert($columns, $types); - } - - /** - * {@inheritDoc} - * - * @throws \BadMethodCallException if the method is called for a non-select query - */ - public function __call($method, $arguments) - { - if ($this->type() === 'select') { - return $this->_call($method, $arguments); - } - - throw new \BadMethodCallException( - sprintf('Cannot call method "%s" on a "%s" query', $method, $this->type()) - ); - } - - /** - * {@inheritDoc} - */ - public function __debugInfo() - { - $eagerLoader = $this->getEagerLoader(); - - return parent::__debugInfo() + [ - 'hydrate' => $this->_hydrate, - 'buffered' => $this->_useBufferedResults, - 'formatters' => count($this->_formatters), - 'mapReducers' => count($this->_mapReduce), - 'contain' => $eagerLoader ? $eagerLoader->getContain() : [], - 'matching' => $eagerLoader ? $eagerLoader->getMatching() : [], - 'extraOptions' => $this->_options, - 'repository' => $this->_repository - ]; - } - - /** - * Executes the query and converts the result set into JSON. - * - * Part of JsonSerializable interface. - * - * @return \Cake\Datasource\ResultSetInterface The data to convert to JSON. - */ - public function jsonSerialize() - { - return $this->all(); - } - - /** - * Sets whether or not the ORM should automatically append fields. - * - * By default calling select() will disable auto-fields. You can re-enable - * auto-fields with this method. - * - * @param bool $value Set true to enable, false to disable. - * @return $this - */ - public function enableAutoFields($value = true) - { - $this->_autoFields = (bool)$value; - - return $this; - } - - /** - * Gets whether or not the ORM should automatically append fields. - * - * By default calling select() will disable auto-fields. You can re-enable - * auto-fields with enableAutoFields(). - * - * @return bool The current value. - */ - public function isAutoFieldsEnabled() - { - return $this->_autoFields; - } - - /** - * Get/Set whether or not the ORM should automatically append fields. - * - * By default calling select() will disable auto-fields. You can re-enable - * auto-fields with this method. - * - * @deprecated 3.4.0 Use enableAutoFields()/isAutoFieldsEnabled() instead. - * @param bool|null $value The value to set or null to read the current value. - * @return bool|$this Either the current value or the query object. - */ - public function autoFields($value = null) - { - deprecationWarning( - 'Query::autoFields() is deprecated. ' . - 'Use enableAutoFields()/isAutoFieldsEnabled() instead.' - ); - if ($value === null) { - return $this->isAutoFieldsEnabled(); - } - - return $this->enableAutoFields($value); - } - - /** - * Decorates the results iterator with MapReduce routines and formatters - * - * @param \Traversable $result Original results - * @return \Cake\Datasource\ResultSetInterface - */ - protected function _decorateResults($result) - { - $result = $this->_applyDecorators($result); - - if (!($result instanceof ResultSet) && $this->isBufferedResultsEnabled()) { - $class = $this->_decoratorClass(); - $result = new $class($result->buffered()); - } - - return $result; - } -} diff --git a/vendor/cakephp/cakephp/src/ORM/README.md b/vendor/cakephp/cakephp/src/ORM/README.md deleted file mode 100644 index 9cbcbac..0000000 --- a/vendor/cakephp/cakephp/src/ORM/README.md +++ /dev/null @@ -1,169 +0,0 @@ -[![Total Downloads](https://img.shields.io/packagist/dt/cakephp/orm.svg?style=flat-square)](https://packagist.org/packages/cakephp/orm) -[![License](https://img.shields.io/badge/license-MIT-blue.svg?style=flat-square)](LICENSE.txt) - -# CakePHP ORM - -The CakePHP ORM provides a powerful and flexible way to work with relational -databases. Using a datamapper pattern the ORM allows you to manipulate data as -entities allowing you to create expressive domain layers in your applications. - -## Database engines supported - -The CakePHP ORM is compatible with: - -* MySQL 5.1+ -* Postgres 8+ -* SQLite3 -* SQLServer 2008+ -* Oracle (through a [community plugin](https://github.com/CakeDC/cakephp-oracle-driver)) - -## Connecting to the Database - -The first thing you need to do when using this library is register a connection -object. Before performing any operations with the connection, you need to -specify a driver to use: - -```php -use Cake\Datasource\ConnectionManager; - -ConnectionManager::setConfig('default', [ - 'className' => 'Cake\Database\Connection', - 'driver' => 'Cake\Database\Driver\Mysql', - 'database' => 'test', - 'username' => 'root', - 'password' => 'secret', - 'cacheMetadata' => true, - 'quoteIdentifiers' => false, -]); -``` - -Once a 'default' connection is registered, it will be used by all the Table -mappers if no explicit connection is defined. - -## Using Table Locator - -In order to access table instances you need to use a *Table Locator*. - -```php -use Cake\ORM\Locator\TableLocator; - -$locator = new TableLocator(); -$articles = $locator->get('Articles'); -``` - -You can also use a trait for easy access to the locator instance: - -```php -use Cake\ORM\Locator\LocatorAwareTrait; - -$articles = $this->getTableLocator()->get('Articles'); -``` - -By default classes using `LocatorAwareTrait` will share a global locator instance. -You can inject your own locator instance into the object: - -```php -use Cake\ORM\Locator\TableLocator; -use Cake\ORM\Locator\LocatorAwareTrait; - -$locator = new TableLocator(); -$this->setTableLocator($locator); - -$articles = $this->getTableLocator()->get('Articles'); -``` - -## Creating Associations - -In your table classes you can define the relations between your tables. CakePHP's ORM -supports 4 association types out of the box: - -* belongsTo - E.g. Many articles belong to a user. -* hasOne - E.g. A user has one profile -* hasMany - E.g. A user has many articles -* belongsToMany - E.g. An article belongsToMany tags. - -You define associations in your table's `initialize()` method. See the -[documentation](https://book.cakephp.org/3.0/en/orm/associations.html) for -complete examples. - -## Reading Data - -Once you've defined some table classes you can read existing data in your tables: - -```php -use Cake\ORM\Locator\LocatorAwareTrait; - -$articles = $this->getTableLocator()->get('Articles'); -foreach ($articles->find() as $article) { - echo $article->title; -} -``` - -You can use the [query builder](https://book.cakephp.org/3.0/en/orm/query-builder.html) to create -complex queries, and a [variety of methods](https://book.cakephp.org/3.0/en/orm/retrieving-data-and-resultsets.html) -to access your data. - -## Saving Data - -Table objects provide ways to convert request data into entities, and then persist -those entities to the database: - -```php -use Cake\ORM\Locator\LocatorAwareTrait; - -$data = [ - 'title' => 'My first article', - 'body' => 'It is a great article', - 'user_id' => 1, - 'tags' => [ - '_ids' => [1, 2, 3] - ], - 'comments' => [ - ['comment' => 'Good job'], - ['comment' => 'Awesome work'], - ] -]; - -$articles = $this->getTableLocator()->get('Articles'); -$article = $articles->newEntity($data, [ - 'associated' => ['Tags', 'Comments'] -]); -$articles->save($article, [ - 'associated' => ['Tags', 'Comments'] -]) -``` - -The above shows how you can easily marshal and save an entity and its -associations in a simple & powerful way. Consult the [ORM documentation](https://book.cakephp.org/3.0/en/orm/saving-data.html) -for more in-depth examples. - -## Deleting Data - -Once you have a reference to an entity, you can use it to delete data: - -```php -$articles = $this->getTableLocator()->get('Articles'); -$article = $articles->get(2); -$articles->delete($article); -``` - -## Meta Data Cache - -It is recommended to enable meta data cache for production systems to avoid performance issues. -For e.g. file system strategy your bootstrap file could look like this: -```php -use Cake\Cache\Engine\FileEngine; - -$cacheConfig = [ - 'className' => FileEngine::class, - 'duration' => '+1 year', - 'serialize' => true, - 'prefix' => 'orm_', -], -Cache::setConfig('_cake_model_', $cacheConfig); -``` - -## Additional Documentation - -Consult [the CakePHP ORM documentation](https://book.cakephp.org/3.0/en/orm.html) -for more in-depth documentation. diff --git a/vendor/cakephp/cakephp/src/ORM/ResultSet.php b/vendor/cakephp/cakephp/src/ORM/ResultSet.php deleted file mode 100644 index 725d583..0000000 --- a/vendor/cakephp/cakephp/src/ORM/ResultSet.php +++ /dev/null @@ -1,627 +0,0 @@ -getRepository(); - $this->_statement = $statement; - $this->_driver = $query->getConnection()->getDriver(); - $this->_defaultTable = $query->getRepository(); - $this->_calculateAssociationMap($query); - $this->_hydrate = $query->isHydrationEnabled(); - $this->_entityClass = $repository->getEntityClass(); - $this->_useBuffering = $query->isBufferedResultsEnabled(); - $this->_defaultAlias = $this->_defaultTable->getAlias(); - $this->_calculateColumnMap($query); - $this->_autoFields = $query->isAutoFieldsEnabled(); - - if ($this->_useBuffering) { - $count = $this->count(); - $this->_results = new SplFixedArray($count); - } - } - - /** - * Returns the current record in the result iterator - * - * Part of Iterator interface. - * - * @return array|object - */ - public function current() - { - return $this->_current; - } - - /** - * Returns the key of the current record in the iterator - * - * Part of Iterator interface. - * - * @return int - */ - public function key() - { - return $this->_index; - } - - /** - * Advances the iterator pointer to the next record - * - * Part of Iterator interface. - * - * @return void - */ - public function next() - { - $this->_index++; - } - - /** - * Rewinds a ResultSet. - * - * Part of Iterator interface. - * - * @throws \Cake\Database\Exception - * @return void - */ - public function rewind() - { - if ($this->_index == 0) { - return; - } - - if (!$this->_useBuffering) { - $msg = 'You cannot rewind an un-buffered ResultSet. Use Query::bufferResults() to get a buffered ResultSet.'; - throw new Exception($msg); - } - - $this->_index = 0; - } - - /** - * Whether there are more results to be fetched from the iterator - * - * Part of Iterator interface. - * - * @return bool - */ - public function valid() - { - if ($this->_useBuffering) { - $valid = $this->_index < $this->_count; - if ($valid && $this->_results[$this->_index] !== null) { - $this->_current = $this->_results[$this->_index]; - - return true; - } - if (!$valid) { - return $valid; - } - } - - $this->_current = $this->_fetchResult(); - $valid = $this->_current !== false; - - if ($valid && $this->_useBuffering) { - $this->_results[$this->_index] = $this->_current; - } - if (!$valid && $this->_statement !== null) { - $this->_statement->closeCursor(); - } - - return $valid; - } - - /** - * Get the first record from a result set. - * - * This method will also close the underlying statement cursor. - * - * @return array|object - */ - public function first() - { - foreach ($this as $result) { - if ($this->_statement && !$this->_useBuffering) { - $this->_statement->closeCursor(); - } - - return $result; - } - } - - /** - * Serializes a resultset. - * - * Part of Serializable interface. - * - * @return string Serialized object - */ - public function serialize() - { - if (!$this->_useBuffering) { - $msg = 'You cannot serialize an un-buffered ResultSet. Use Query::bufferResults() to get a buffered ResultSet.'; - throw new Exception($msg); - } - - while ($this->valid()) { - $this->next(); - } - - if ($this->_results instanceof SplFixedArray) { - return serialize($this->_results->toArray()); - } - - return serialize($this->_results); - } - - /** - * Unserializes a resultset. - * - * Part of Serializable interface. - * - * @param string $serialized Serialized object - * @return void - */ - public function unserialize($serialized) - { - $results = (array)(unserialize($serialized) ?: []); - $this->_results = SplFixedArray::fromArray($results); - $this->_useBuffering = true; - $this->_count = $this->_results->count(); - } - - /** - * Gives the number of rows in the result set. - * - * Part of the Countable interface. - * - * @return int - */ - public function count() - { - if ($this->_count !== null) { - return $this->_count; - } - if ($this->_statement) { - return $this->_count = $this->_statement->rowCount(); - } - - if ($this->_results instanceof SplFixedArray) { - $this->_count = $this->_results->count(); - } else { - $this->_count = count($this->_results); - } - - return $this->_count; - } - - /** - * Calculates the list of associations that should get eager loaded - * when fetching each record - * - * @param \Cake\ORM\Query $query The query from where to derive the associations - * @return void - */ - protected function _calculateAssociationMap($query) - { - $map = $query->getEagerLoader()->associationsMap($this->_defaultTable); - $this->_matchingMap = (new Collection($map)) - ->match(['matching' => true]) - ->indexBy('alias') - ->toArray(); - - $this->_containMap = (new Collection(array_reverse($map))) - ->match(['matching' => false]) - ->indexBy('nestKey') - ->toArray(); - } - - /** - * Creates a map of row keys out of the query select clause that can be - * used to hydrate nested result sets more quickly. - * - * @param \Cake\ORM\Query $query The query from where to derive the column map - * @return void - */ - protected function _calculateColumnMap($query) - { - $map = []; - foreach ($query->clause('select') as $key => $field) { - $key = trim($key, '"`[]'); - - if (strpos($key, '__') <= 0) { - $map[$this->_defaultAlias][$key] = $key; - continue; - } - - $parts = explode('__', $key, 2); - $map[$parts[0]][$key] = $parts[1]; - } - - foreach ($this->_matchingMap as $alias => $assoc) { - if (!isset($map[$alias])) { - continue; - } - $this->_matchingMapColumns[$alias] = $map[$alias]; - unset($map[$alias]); - } - - $this->_map = $map; - } - - /** - * Creates a map of Type converter classes for each of the columns that should - * be fetched by this object. - * - * @deprecated 3.2.0 Not used anymore. Type casting is done at the statement level - * @return void - */ - protected function _calculateTypeMap() - { - deprecationWarning('ResultSet::_calculateTypeMap() is deprecated, and will be removed in 4.0.0.'); - } - - /** - * Returns the Type classes for each of the passed fields belonging to the - * table. - * - * @param \Cake\ORM\Table $table The table from which to get the schema - * @param array $fields The fields whitelist to use for fields in the schema. - * @return array - */ - protected function _getTypes($table, $fields) - { - $types = []; - $schema = $table->getSchema(); - $map = array_keys(Type::map() + ['string' => 1, 'text' => 1, 'boolean' => 1]); - $typeMap = array_combine( - $map, - array_map(['Cake\Database\Type', 'build'], $map) - ); - - foreach (['string', 'text'] as $t) { - if (get_class($typeMap[$t]) === 'Cake\Database\Type') { - unset($typeMap[$t]); - } - } - - foreach (array_intersect($fields, $schema->columns()) as $col) { - $typeName = $schema->getColumnType($col); - if (isset($typeMap[$typeName])) { - $types[$col] = $typeMap[$typeName]; - } - } - - return $types; - } - - /** - * Helper function to fetch the next result from the statement or - * seeded results. - * - * @return mixed - */ - protected function _fetchResult() - { - if (!$this->_statement) { - return false; - } - - $row = $this->_statement->fetch('assoc'); - if ($row === false) { - return $row; - } - - return $this->_groupResult($row); - } - - /** - * Correctly nests results keys including those coming from associations - * - * @param array $row Array containing columns and values or false if there is no results - * @return array Results - */ - protected function _groupResult($row) - { - $defaultAlias = $this->_defaultAlias; - $results = $presentAliases = []; - $options = [ - 'useSetters' => false, - 'markClean' => true, - 'markNew' => false, - 'guard' => false - ]; - - foreach ($this->_matchingMapColumns as $alias => $keys) { - $matching = $this->_matchingMap[$alias]; - $results['_matchingData'][$alias] = array_combine( - $keys, - array_intersect_key($row, $keys) - ); - if ($this->_hydrate) { - /* @var \Cake\ORM\Table $table */ - $table = $matching['instance']; - $options['source'] = $table->getRegistryAlias(); - /* @var \Cake\Datasource\EntityInterface $entity */ - $entity = new $matching['entityClass']($results['_matchingData'][$alias], $options); - $results['_matchingData'][$alias] = $entity; - } - } - - foreach ($this->_map as $table => $keys) { - $results[$table] = array_combine($keys, array_intersect_key($row, $keys)); - $presentAliases[$table] = true; - } - - unset($presentAliases[$defaultAlias]); - - foreach ($this->_containMap as $assoc) { - $alias = $assoc['nestKey']; - - if ($assoc['canBeJoined'] && empty($this->_map[$alias])) { - continue; - } - - /* @var \Cake\ORM\Association $instance */ - $instance = $assoc['instance']; - - if (!$assoc['canBeJoined'] && !isset($row[$alias])) { - $results = $instance->defaultRowValue($results, $assoc['canBeJoined']); - continue; - } - - if (!$assoc['canBeJoined']) { - $results[$alias] = $row[$alias]; - } - - $target = $instance->getTarget(); - $options['source'] = $target->getRegistryAlias(); - unset($presentAliases[$alias]); - - if ($assoc['canBeJoined'] && $this->_autoFields !== false) { - $hasData = false; - foreach ($results[$alias] as $v) { - if ($v !== null && $v !== []) { - $hasData = true; - break; - } - } - - if (!$hasData) { - $results[$alias] = null; - } - } - - if ($this->_hydrate && $results[$alias] !== null && $assoc['canBeJoined']) { - $entity = new $assoc['entityClass']($results[$alias], $options); - $results[$alias] = $entity; - } - - $results = $instance->transformRow($results, $alias, $assoc['canBeJoined'], $assoc['targetProperty']); - } - - foreach ($presentAliases as $alias => $present) { - if (!isset($results[$alias])) { - continue; - } - $results[$defaultAlias][$alias] = $results[$alias]; - } - - if (isset($results['_matchingData'])) { - $results[$defaultAlias]['_matchingData'] = $results['_matchingData']; - } - - $options['source'] = $this->_defaultTable->getRegistryAlias(); - if (isset($results[$defaultAlias])) { - $results = $results[$defaultAlias]; - } - if ($this->_hydrate && !($results instanceof EntityInterface)) { - $results = new $this->_entityClass($results, $options); - } - - return $results; - } - - /** - * Casts all values from a row brought from a table to the correct - * PHP type. - * - * @param string $alias The table object alias - * @param array $values The values to cast - * @deprecated 3.2.0 Not used anymore. Type casting is done at the statement level - * @return array - */ - protected function _castValues($alias, $values) - { - deprecationWarning('ResultSet::_castValues() is deprecated, and will be removed in 4.0.0.'); - - return $values; - } - - /** - * Returns an array that can be used to describe the internal state of this - * object. - * - * @return array - */ - public function __debugInfo() - { - return [ - 'items' => $this->toArray(), - ]; - } -} diff --git a/vendor/cakephp/cakephp/src/ORM/Rule/ExistsIn.php b/vendor/cakephp/cakephp/src/ORM/Rule/ExistsIn.php deleted file mode 100644 index d583120..0000000 --- a/vendor/cakephp/cakephp/src/ORM/Rule/ExistsIn.php +++ /dev/null @@ -1,160 +0,0 @@ - false]; - $this->_options = $options; - - $this->_fields = (array)$fields; - $this->_repository = $repository; - } - - /** - * Performs the existence check - * - * @param \Cake\Datasource\EntityInterface $entity The entity from where to extract the fields - * @param array $options Options passed to the check, - * where the `repository` key is required. - * @throws \RuntimeException When the rule refers to an undefined association. - * @return bool - */ - public function __invoke(EntityInterface $entity, array $options) - { - if (is_string($this->_repository)) { - if (!$options['repository']->hasAssociation($this->_repository)) { - throw new RuntimeException(sprintf( - "ExistsIn rule for '%s' is invalid. '%s' is not associated with '%s'.", - implode(', ', $this->_fields), - $this->_repository, - get_class($options['repository']) - )); - } - $repository = $options['repository']->getAssociation($this->_repository); - $this->_repository = $repository; - } - - $fields = $this->_fields; - $source = $target = $this->_repository; - $isAssociation = $target instanceof Association; - $bindingKey = $isAssociation ? (array)$target->getBindingKey() : (array)$target->getPrimaryKey(); - $realTarget = $isAssociation ? $target->getTarget() : $target; - - if (!empty($options['_sourceTable']) && $realTarget === $options['_sourceTable']) { - return true; - } - - if (!empty($options['repository'])) { - $source = $options['repository']; - } - if ($source instanceof Association) { - $source = $source->getSource(); - } - - if (!$entity->extract($this->_fields, true)) { - return true; - } - - if ($this->_fieldsAreNull($entity, $source)) { - return true; - } - - if ($this->_options['allowNullableNulls']) { - $schema = $source->getSchema(); - foreach ($fields as $i => $field) { - if ($schema->getColumn($field) && $schema->isNullable($field) && $entity->get($field) === null) { - unset($bindingKey[$i], $fields[$i]); - } - } - } - - $primary = array_map( - [$target, 'aliasField'], - $bindingKey - ); - $conditions = array_combine( - $primary, - $entity->extract($fields) - ); - - return $target->exists($conditions); - } - - /** - * Checks whether or not the given entity fields are nullable and null. - * - * @param \Cake\Datasource\EntityInterface $entity The entity to check. - * @param \Cake\ORM\Table $source The table to use schema from. - * @return bool - */ - protected function _fieldsAreNull($entity, $source) - { - $nulls = 0; - $schema = $source->getSchema(); - foreach ($this->_fields as $field) { - if ($schema->getColumn($field) && $schema->isNullable($field) && $entity->get($field) === null) { - $nulls++; - } - } - - return $nulls === count($this->_fields); - } -} diff --git a/vendor/cakephp/cakephp/src/ORM/Rule/IsUnique.php b/vendor/cakephp/cakephp/src/ORM/Rule/IsUnique.php deleted file mode 100644 index 2d024ed..0000000 --- a/vendor/cakephp/cakephp/src/ORM/Rule/IsUnique.php +++ /dev/null @@ -1,109 +0,0 @@ -_fields = $fields; - $this->_options = $options + ['allowMultipleNulls' => true]; - } - - /** - * Performs the uniqueness check - * - * @param \Cake\Datasource\EntityInterface $entity The entity from where to extract the fields - * where the `repository` key is required. - * @param array $options Options passed to the check, - * @return bool - */ - public function __invoke(EntityInterface $entity, array $options) - { - if (!$entity->extract($this->_fields, true)) { - return true; - } - $allowMultipleNulls = $this->_options['allowMultipleNulls']; - - $alias = $options['repository']->getAlias(); - $conditions = $this->_alias($alias, $entity->extract($this->_fields), $allowMultipleNulls); - if ($entity->isNew() === false) { - $keys = (array)$options['repository']->getPrimaryKey(); - $keys = $this->_alias($alias, $entity->extract($keys), $allowMultipleNulls); - if (array_filter($keys, 'strlen')) { - $conditions['NOT'] = $keys; - } - } - - return !$options['repository']->exists($conditions); - } - - /** - * Add a model alias to all the keys in a set of conditions. - * - * Null values will be omitted from the generated conditions, - * as SQL UNIQUE indexes treat `NULL != NULL` - * - * @param string $alias The alias to add. - * @param array $conditions The conditions to alias. - * @param bool $multipleNulls Whether or not to allow multiple nulls. - * @return array - */ - protected function _alias($alias, $conditions, $multipleNulls) - { - $aliased = []; - foreach ($conditions as $key => $value) { - if ($multipleNulls) { - $aliased["$alias.$key"] = $value; - } else { - $aliased["$alias.$key IS"] = $value; - } - } - - return $aliased; - } -} diff --git a/vendor/cakephp/cakephp/src/ORM/Rule/ValidCount.php b/vendor/cakephp/cakephp/src/ORM/Rule/ValidCount.php deleted file mode 100644 index 33a9808..0000000 --- a/vendor/cakephp/cakephp/src/ORM/Rule/ValidCount.php +++ /dev/null @@ -1,60 +0,0 @@ -_field = $field; - } - - /** - * Performs the count check - * - * @param \Cake\Datasource\EntityInterface $entity The entity from where to extract the fields. - * @param array $options Options passed to the check. - * @return bool True if successful, else false. - */ - public function __invoke(EntityInterface $entity, array $options) - { - $value = $entity->{$this->_field}; - if (!is_array($value) && !$value instanceof Countable) { - return false; - } - - return Validation::comparison(count($value), $options['operator'], $options['count']); - } -} diff --git a/vendor/cakephp/cakephp/src/ORM/RulesChecker.php b/vendor/cakephp/cakephp/src/ORM/RulesChecker.php deleted file mode 100644 index feea8c8..0000000 --- a/vendor/cakephp/cakephp/src/ORM/RulesChecker.php +++ /dev/null @@ -1,142 +0,0 @@ -add($rules->isUnique(['email'], 'The email should be unique')); - * ``` - * - * @param array $fields The list of fields to check for uniqueness. - * @param string|array|null $message The error message to show in case the rule does not pass. Can - * also be an array of options. When an array, the 'message' key can be used to provide a message. - * @return callable - */ - public function isUnique(array $fields, $message = null) - { - $options = []; - if (is_array($message)) { - $options = $message + ['message' => null]; - $message = $options['message']; - unset($options['message']); - } - if (!$message) { - if ($this->_useI18n) { - $message = __d('cake', 'This value is already in use'); - } else { - $message = 'This value is already in use'; - } - } - - $errorField = current($fields); - - return $this->_addError(new IsUnique($fields, $options), '_isUnique', compact('errorField', 'message')); - } - - /** - * Returns a callable that can be used as a rule for checking that the values - * extracted from the entity to check exist as the primary key in another table. - * - * This is useful for enforcing foreign key integrity checks. - * - * ### Example: - * - * ``` - * $rules->add($rules->existsIn('author_id', 'Authors', 'Invalid Author')); - * - * $rules->add($rules->existsIn('site_id', new SitesTable(), 'Invalid Site')); - * ``` - * - * Available $options are error 'message' and 'allowNullableNulls' flag. - * 'message' sets a custom error message. - * Set 'allowNullableNulls' to true to accept composite foreign keys where one or more nullable columns are null. - * - * @param string|array $field The field or list of fields to check for existence by - * primary key lookup in the other table. - * @param object|string $table The table name where the fields existence will be checked. - * @param string|array|null $message The error message to show in case the rule does not pass. Can - * also be an array of options. When an array, the 'message' key can be used to provide a message. - * @return callable - */ - public function existsIn($field, $table, $message = null) - { - $options = []; - if (is_array($message)) { - $options = $message + ['message' => null]; - $message = $options['message']; - unset($options['message']); - } - - if (!$message) { - if ($this->_useI18n) { - $message = __d('cake', 'This value does not exist'); - } else { - $message = 'This value does not exist'; - } - } - - $errorField = is_string($field) ? $field : current($field); - - return $this->_addError(new ExistsIn($field, $table, $options), '_existsIn', compact('errorField', 'message')); - } - - /** - * Validates the count of associated records. - * - * @param string $field The field to check the count on. - * @param int $count The expected count. - * @param string $operator The operator for the count comparison. - * @param string|null $message The error message to show in case the rule does not pass. - * @return callable - */ - public function validCount($field, $count = 0, $operator = '>', $message = null) - { - if (!$message) { - if ($this->_useI18n) { - $message = __d('cake', 'The count does not match {0}{1}', [$operator, $count]); - } else { - $message = sprintf('The count does not match %s%d', $operator, $count); - } - } - - $errorField = $field; - - return $this->_addError( - new ValidCount($field), - '_validCount', - compact('count', 'operator', 'errorField', 'message') - ); - } -} diff --git a/vendor/cakephp/cakephp/src/ORM/SaveOptionsBuilder.php b/vendor/cakephp/cakephp/src/ORM/SaveOptionsBuilder.php deleted file mode 100644 index f3ea0b9..0000000 --- a/vendor/cakephp/cakephp/src/ORM/SaveOptionsBuilder.php +++ /dev/null @@ -1,221 +0,0 @@ -_table = $table; - $this->parseArrayOptions($options); - - parent::__construct(); - } - - /** - * Takes an options array and populates the option object with the data. - * - * This can be used to turn an options array into the object. - * - * @throws \InvalidArgumentException If a given option key does not exist. - * @param array $array Options array. - * @return \Cake\ORM\SaveOptionsBuilder - */ - public function parseArrayOptions($array) - { - foreach ($array as $key => $value) { - $this->{$key}($value); - } - - return $this; - } - - /** - * Set associated options. - * - * @param string|array $associated String or array of associations. - * @return \Cake\ORM\SaveOptionsBuilder - */ - public function associated($associated) - { - $associated = $this->_normalizeAssociations($associated); - $this->_associated($this->_table, $associated); - $this->_options['associated'] = $associated; - - return $this; - } - - /** - * Checks that the associations exists recursively. - * - * @param \Cake\ORM\Table $table Table object. - * @param array $associations An associations array. - * @return void - */ - protected function _associated(Table $table, array $associations) - { - foreach ($associations as $key => $associated) { - if (is_int($key)) { - $this->_checkAssociation($table, $associated); - continue; - } - $this->_checkAssociation($table, $key); - if (isset($associated['associated'])) { - $this->_associated($table->getAssociation($key)->getTarget(), $associated['associated']); - continue; - } - } - } - - /** - * Checks if an association exists. - * - * @throws \RuntimeException If no such association exists for the given table. - * @param \Cake\ORM\Table $table Table object. - * @param string $association Association name. - * @return void - */ - protected function _checkAssociation(Table $table, $association) - { - if (!$table->associations()->has($association)) { - throw new RuntimeException(sprintf('Table `%s` is not associated with `%s`', get_class($table), $association)); - } - } - - /** - * Set the guard option. - * - * @param bool $guard Guard the properties or not. - * @return \Cake\ORM\SaveOptionsBuilder - */ - public function guard($guard) - { - $this->_options['guard'] = (bool)$guard; - - return $this; - } - - /** - * Set the validation rule set to use. - * - * @param string $validate Name of the validation rule set to use. - * @return \Cake\ORM\SaveOptionsBuilder - */ - public function validate($validate) - { - $this->_table->getValidator($validate); - $this->_options['validate'] = $validate; - - return $this; - } - - /** - * Set check existing option. - * - * @param bool $checkExisting Guard the properties or not. - * @return \Cake\ORM\SaveOptionsBuilder - */ - public function checkExisting($checkExisting) - { - $this->_options['checkExisting'] = (bool)$checkExisting; - - return $this; - } - - /** - * Option to check the rules. - * - * @param bool $checkRules Check the rules or not. - * @return \Cake\ORM\SaveOptionsBuilder - */ - public function checkRules($checkRules) - { - $this->_options['checkRules'] = (bool)$checkRules; - - return $this; - } - - /** - * Sets the atomic option. - * - * @param bool $atomic Atomic or not. - * @return \Cake\ORM\SaveOptionsBuilder - */ - public function atomic($atomic) - { - $this->_options['atomic'] = (bool)$atomic; - - return $this; - } - - /** - * @return array - */ - public function toArray() - { - return $this->_options; - } - - /** - * Setting custom options. - * - * @param string $option Option key. - * @param mixed $value Option value. - * @return \Cake\ORM\SaveOptionsBuilder - */ - public function set($option, $value) - { - if (method_exists($this, $option)) { - return $this->{$option}($value); - } - $this->_options[$option] = $value; - - return $this; - } -} diff --git a/vendor/cakephp/cakephp/src/ORM/Table.php b/vendor/cakephp/cakephp/src/ORM/Table.php deleted file mode 100644 index 5c46fbb..0000000 --- a/vendor/cakephp/cakephp/src/ORM/Table.php +++ /dev/null @@ -1,2924 +0,0 @@ -findByUsername('mark'); - * ``` - * - * You can also combine conditions on multiple fields using either `Or` or `And`: - * - * ``` - * $query = $users->findByUsernameOrEmail('mark', 'mark@example.org'); - * ``` - * - * ### Bulk updates/deletes - * - * You can use Table::updateAll() and Table::deleteAll() to do bulk updates/deletes. - * You should be aware that events will *not* be fired for bulk updates/deletes. - * - * ### Callbacks/events - * - * Table objects provide a few callbacks/events you can hook into to augment/replace - * find operations. Each event uses the standard event subsystem in CakePHP - * - * - `beforeFind(Event $event, Query $query, ArrayObject $options, boolean $primary)` - * Fired before each find operation. By stopping the event and supplying a - * return value you can bypass the find operation entirely. Any changes done - * to the $query instance will be retained for the rest of the find. The - * $primary parameter indicates whether or not this is the root query, - * or an associated query. - * - * - `buildValidator(Event $event, Validator $validator, string $name)` - * Allows listeners to modify validation rules for the provided named validator. - * - * - `buildRules(Event $event, RulesChecker $rules)` - * Allows listeners to modify the rules checker by adding more rules. - * - * - `beforeRules(Event $event, EntityInterface $entity, ArrayObject $options, string $operation)` - * Fired before an entity is validated using the rules checker. By stopping this event, - * you can return the final value of the rules checking operation. - * - * - `afterRules(Event $event, EntityInterface $entity, ArrayObject $options, bool $result, string $operation)` - * Fired after the rules have been checked on the entity. By stopping this event, - * you can return the final value of the rules checking operation. - * - * - `beforeSave(Event $event, EntityInterface $entity, ArrayObject $options)` - * Fired before each entity is saved. Stopping this event will abort the save - * operation. When the event is stopped the result of the event will be returned. - * - * - `afterSave(Event $event, EntityInterface $entity, ArrayObject $options)` - * Fired after an entity is saved. - * - * - `afterSaveCommit(Event $event, EntityInterface $entity, ArrayObject $options)` - * Fired after the transaction in which the save operation is wrapped has been committed. - * It’s also triggered for non atomic saves where database operations are implicitly committed. - * The event is triggered only for the primary table on which save() is directly called. - * The event is not triggered if a transaction is started before calling save. - * - * - `beforeDelete(Event $event, EntityInterface $entity, ArrayObject $options)` - * Fired before an entity is deleted. By stopping this event you will abort - * the delete operation. - * - * - `afterDelete(Event $event, EntityInterface $entity, ArrayObject $options)` - * Fired after an entity has been deleted. - * - * @see \Cake\Event\EventManager for reference on the events system. - */ -class Table implements RepositoryInterface, EventListenerInterface, EventDispatcherInterface, ValidatorAwareInterface -{ - - use EventDispatcherTrait; - use RulesAwareTrait; - use ValidatorAwareTrait; - - /** - * The alias this object is assigned to validators as. - * - * @var string - */ - const VALIDATOR_PROVIDER_NAME = 'table'; - - /** - * The name of the event dispatched when a validator has been built. - * - * @var string - */ - const BUILD_VALIDATOR_EVENT = 'Model.buildValidator'; - - /** - * The rules class name that is used. - * - * @var string - */ - const RULES_CLASS = 'Cake\ORM\RulesChecker'; - - /** - * Name of the table as it can be found in the database - * - * @var string - */ - protected $_table; - - /** - * Human name giving to this particular instance. Multiple objects representing - * the same database table can exist by using different aliases. - * - * @var string - */ - protected $_alias; - - /** - * Connection instance - * - * @var \Cake\Database\Connection - */ - protected $_connection; - - /** - * The schema object containing a description of this table fields - * - * @var \Cake\Database\Schema\TableSchema - */ - protected $_schema; - - /** - * The name of the field that represents the primary key in the table - * - * @var string|array - */ - protected $_primaryKey; - - /** - * The name of the field that represents a human readable representation of a row - * - * @var string - */ - protected $_displayField; - - /** - * The associations container for this Table. - * - * @var \Cake\ORM\AssociationCollection - */ - protected $_associations; - - /** - * BehaviorRegistry for this table - * - * @var \Cake\ORM\BehaviorRegistry - */ - protected $_behaviors; - - /** - * The name of the class that represent a single row for this table - * - * @var string - */ - protected $_entityClass; - - /** - * Registry key used to create this table object - * - * @var string - */ - protected $_registryAlias; - - /** - * Initializes a new instance - * - * The $config array understands the following keys: - * - * - table: Name of the database table to represent - * - alias: Alias to be assigned to this table (default to table name) - * - connection: The connection instance to use - * - entityClass: The fully namespaced class name of the entity class that will - * represent rows in this table. - * - schema: A \Cake\Database\Schema\TableSchema object or an array that can be - * passed to it. - * - eventManager: An instance of an event manager to use for internal events - * - behaviors: A BehaviorRegistry. Generally not used outside of tests. - * - associations: An AssociationCollection instance. - * - validator: A Validator instance which is assigned as the "default" - * validation set, or an associative array, where key is the name of the - * validation set and value the Validator instance. - * - * @param array $config List of options for this table - */ - public function __construct(array $config = []) - { - if (!empty($config['registryAlias'])) { - $this->setRegistryAlias($config['registryAlias']); - } - if (!empty($config['table'])) { - $this->setTable($config['table']); - } - if (!empty($config['alias'])) { - $this->setAlias($config['alias']); - } - if (!empty($config['connection'])) { - $this->setConnection($config['connection']); - } - if (!empty($config['schema'])) { - $this->setSchema($config['schema']); - } - if (!empty($config['entityClass'])) { - $this->setEntityClass($config['entityClass']); - } - $eventManager = $behaviors = $associations = null; - if (!empty($config['eventManager'])) { - $eventManager = $config['eventManager']; - } - if (!empty($config['behaviors'])) { - $behaviors = $config['behaviors']; - } - if (!empty($config['associations'])) { - $associations = $config['associations']; - } - if (!empty($config['validator'])) { - if (!is_array($config['validator'])) { - $this->setValidator(static::DEFAULT_VALIDATOR, $config['validator']); - } else { - foreach ($config['validator'] as $name => $validator) { - $this->setValidator($name, $validator); - } - } - } - $this->_eventManager = $eventManager ?: new EventManager(); - $this->_behaviors = $behaviors ?: new BehaviorRegistry(); - $this->_behaviors->setTable($this); - $this->_associations = $associations ?: new AssociationCollection(); - - $this->initialize($config); - $this->_eventManager->on($this); - $this->dispatchEvent('Model.initialize'); - } - - /** - * Get the default connection name. - * - * This method is used to get the fallback connection name if an - * instance is created through the TableLocator without a connection. - * - * @return string - * @see \Cake\ORM\Locator\TableLocator::get() - */ - public static function defaultConnectionName() - { - return 'default'; - } - - /** - * Initialize a table instance. Called after the constructor. - * - * You can use this method to define associations, attach behaviors - * define validation and do any other initialization logic you need. - * - * ``` - * public function initialize(array $config) - * { - * $this->belongsTo('Users'); - * $this->belongsToMany('Tagging.Tags'); - * $this->setPrimaryKey('something_else'); - * } - * ``` - * - * @param array $config Configuration options passed to the constructor - * @return void - */ - public function initialize(array $config) - { - } - - /** - * Sets the database table name. - * - * @param string $table Table name. - * @return $this - */ - public function setTable($table) - { - $this->_table = $table; - - return $this; - } - - /** - * Returns the database table name. - * - * @return string - */ - public function getTable() - { - if ($this->_table === null) { - $table = namespaceSplit(get_class($this)); - $table = substr(end($table), 0, -5); - if (!$table) { - $table = $this->getAlias(); - } - $this->_table = Inflector::underscore($table); - } - - return $this->_table; - } - - /** - * Returns the database table name or sets a new one. - * - * @deprecated 3.4.0 Use setTable()/getTable() instead. - * @param string|null $table the new table name - * @return string - */ - public function table($table = null) - { - deprecationWarning( - get_called_class() . '::table() is deprecated. ' . - 'Use setTable()/getTable() instead.' - ); - if ($table !== null) { - $this->setTable($table); - } - - return $this->getTable(); - } - - /** - * Sets the table alias. - * - * @param string $alias Table alias - * @return $this - */ - public function setAlias($alias) - { - $this->_alias = $alias; - - return $this; - } - - /** - * Returns the table alias. - * - * @return string - */ - public function getAlias() - { - if ($this->_alias === null) { - $alias = namespaceSplit(get_class($this)); - $alias = substr(end($alias), 0, -5) ?: $this->_table; - $this->_alias = $alias; - } - - return $this->_alias; - } - - /** - * {@inheritDoc} - * @deprecated 3.4.0 Use setAlias()/getAlias() instead. - */ - public function alias($alias = null) - { - deprecationWarning( - get_called_class() . '::alias() is deprecated. ' . - 'Use setAlias()/getAlias() instead.' - ); - if ($alias !== null) { - $this->setAlias($alias); - } - - return $this->getAlias(); - } - - /** - * Alias a field with the table's current alias. - * - * If field is already aliased it will result in no-op. - * - * @param string $field The field to alias. - * @return string The field prefixed with the table alias. - */ - public function aliasField($field) - { - if (strpos($field, '.') !== false) { - return $field; - } - - return $this->getAlias() . '.' . $field; - } - - /** - * Sets the table registry key used to create this table instance. - * - * @param string $registryAlias The key used to access this object. - * @return $this - */ - public function setRegistryAlias($registryAlias) - { - $this->_registryAlias = $registryAlias; - - return $this; - } - - /** - * Returns the table registry key used to create this table instance. - * - * @return string - */ - public function getRegistryAlias() - { - if ($this->_registryAlias === null) { - $this->_registryAlias = $this->getAlias(); - } - - return $this->_registryAlias; - } - - /** - * Returns the table registry key used to create this table instance or sets one. - * - * @deprecated 3.4.0 Use setRegistryAlias()/getRegistryAlias() instead. - * @param string|null $registryAlias the key used to access this object - * @return string - */ - public function registryAlias($registryAlias = null) - { - deprecationWarning( - get_called_class() . '::registryAlias() is deprecated. ' . - 'Use setRegistryAlias()/getRegistryAlias() instead.' - ); - if ($registryAlias !== null) { - $this->setRegistryAlias($registryAlias); - } - - return $this->getRegistryAlias(); - } - - /** - * Sets the connection instance. - * - * @param \Cake\Database\Connection|\Cake\Datasource\ConnectionInterface $connection The connection instance - * @return $this - */ - public function setConnection(ConnectionInterface $connection) - { - $this->_connection = $connection; - - return $this; - } - - /** - * Returns the connection instance. - * - * @return \Cake\Database\Connection - */ - public function getConnection() - { - return $this->_connection; - } - - /** - * Returns the connection instance or sets a new one - * - * @deprecated 3.4.0 Use setConnection()/getConnection() instead. - * @param \Cake\Datasource\ConnectionInterface|null $connection The new connection instance - * @return \Cake\Datasource\ConnectionInterface - */ - public function connection(ConnectionInterface $connection = null) - { - deprecationWarning( - get_called_class() . '::connection() is deprecated. ' . - 'Use setConnection()/getConnection() instead.' - ); - if ($connection !== null) { - $this->setConnection($connection); - } - - return $this->getConnection(); - } - - /** - * Returns the schema table object describing this table's properties. - * - * @return \Cake\Database\Schema\TableSchema - */ - public function getSchema() - { - if ($this->_schema === null) { - $this->_schema = $this->_initializeSchema( - $this->getConnection() - ->getSchemaCollection() - ->describe($this->getTable()) - ); - } - - return $this->_schema; - } - - /** - * Sets the schema table object describing this table's properties. - * - * If an array is passed, a new TableSchema will be constructed - * out of it and used as the schema for this table. - * - * @param array|\Cake\Database\Schema\TableSchema $schema Schema to be used for this table - * @return $this - */ - public function setSchema($schema) - { - if (is_array($schema)) { - $constraints = []; - - if (isset($schema['_constraints'])) { - $constraints = $schema['_constraints']; - unset($schema['_constraints']); - } - - $schema = new TableSchema($this->getTable(), $schema); - - foreach ($constraints as $name => $value) { - $schema->addConstraint($name, $value); - } - } - - $this->_schema = $schema; - - return $this; - } - - /** - * Returns the schema table object describing this table's properties. - * - * If a TableSchema is passed, it will be used for this table - * instead of the default one. - * - * If an array is passed, a new TableSchema will be constructed - * out of it and used as the schema for this table. - * - * @deprecated 3.4.0 Use setSchema()/getSchema() instead. - * @param array|\Cake\Database\Schema\TableSchema|null $schema New schema to be used for this table - * @return \Cake\Database\Schema\TableSchema - */ - public function schema($schema = null) - { - deprecationWarning( - get_called_class() . '::schema() is deprecated. ' . - 'Use setSchema()/getSchema() instead.' - ); - if ($schema !== null) { - $this->setSchema($schema); - } - - return $this->getSchema(); - } - - /** - * Override this function in order to alter the schema used by this table. - * This function is only called after fetching the schema out of the database. - * If you wish to provide your own schema to this table without touching the - * database, you can override schema() or inject the definitions though that - * method. - * - * ### Example: - * - * ``` - * protected function _initializeSchema(\Cake\Database\Schema\TableSchema $schema) { - * $schema->setColumnType('preferences', 'json'); - * return $schema; - * } - * ``` - * - * @param \Cake\Database\Schema\TableSchema $schema The table definition fetched from database. - * @return \Cake\Database\Schema\TableSchema the altered schema - */ - protected function _initializeSchema(TableSchema $schema) - { - return $schema; - } - - /** - * Test to see if a Table has a specific field/column. - * - * Delegates to the schema object and checks for column presence - * using the Schema\Table instance. - * - * @param string $field The field to check for. - * @return bool True if the field exists, false if it does not. - */ - public function hasField($field) - { - $schema = $this->getSchema(); - - return $schema->getColumn($field) !== null; - } - - /** - * Sets the primary key field name. - * - * @param string|array $key Sets a new name to be used as primary key - * @return $this - */ - public function setPrimaryKey($key) - { - $this->_primaryKey = $key; - - return $this; - } - - /** - * Returns the primary key field name. - * - * @return string|array - */ - public function getPrimaryKey() - { - if ($this->_primaryKey === null) { - $key = (array)$this->getSchema()->primaryKey(); - if (count($key) === 1) { - $key = $key[0]; - } - $this->_primaryKey = $key; - } - - return $this->_primaryKey; - } - - /** - * Returns the primary key field name or sets a new one - * - * @deprecated 3.4.0 Use setPrimaryKey()/getPrimaryKey() instead. - * @param string|array|null $key Sets a new name to be used as primary key - * @return string|array - */ - public function primaryKey($key = null) - { - deprecationWarning( - get_called_class() . '::primaryKey() is deprecated. ' . - 'Use setPrimaryKey()/getPrimaryKey() instead.' - ); - if ($key !== null) { - $this->setPrimaryKey($key); - } - - return $this->getPrimaryKey(); - } - - /** - * Sets the display field. - * - * @param string $key Name to be used as display field. - * @return $this - */ - public function setDisplayField($key) - { - $this->_displayField = $key; - - return $this; - } - - /** - * Returns the display field. - * - * @return string - */ - public function getDisplayField() - { - if ($this->_displayField === null) { - $schema = $this->getSchema(); - $primary = (array)$this->getPrimaryKey(); - $this->_displayField = array_shift($primary); - if ($schema->getColumn('title')) { - $this->_displayField = 'title'; - } - if ($schema->getColumn('name')) { - $this->_displayField = 'name'; - } - } - - return $this->_displayField; - } - - /** - * Returns the display field or sets a new one - * - * @deprecated 3.4.0 Use setDisplayField()/getDisplayField() instead. - * @param string|null $key sets a new name to be used as display field - * @return string - */ - public function displayField($key = null) - { - deprecationWarning( - get_called_class() . '::displayField() is deprecated. ' . - 'Use setDisplayField()/getDisplayField() instead.' - ); - if ($key !== null) { - $this->setDisplayField($key); - - return $key; - } - - return $this->getDisplayField(); - } - - /** - * Returns the class used to hydrate rows for this table. - * - * @return string - */ - public function getEntityClass() - { - if (!$this->_entityClass) { - $default = Entity::class; - $self = get_called_class(); - $parts = explode('\\', $self); - - if ($self === __CLASS__ || count($parts) < 3) { - return $this->_entityClass = $default; - } - - $alias = Inflector::singularize(substr(array_pop($parts), 0, -5)); - $name = implode('\\', array_slice($parts, 0, -1)) . '\\Entity\\' . $alias; - if (!class_exists($name)) { - return $this->_entityClass = $default; - } - - $class = App::className($name, 'Model/Entity'); - if (!$class) { - throw new MissingEntityException([$name]); - } - - $this->_entityClass = $class; - } - - return $this->_entityClass; - } - - /** - * Sets the class used to hydrate rows for this table. - * - * @param string $name The name of the class to use - * @throws \Cake\ORM\Exception\MissingEntityException when the entity class cannot be found - * @return $this - */ - public function setEntityClass($name) - { - $class = App::className($name, 'Model/Entity'); - if (!$class) { - throw new MissingEntityException([$name]); - } - - $this->_entityClass = $class; - - return $this; - } - - /** - * Returns the class used to hydrate rows for this table or sets - * a new one - * - * @deprecated 3.4.0 Use setEntityClass()/getEntityClass() instead. - * @param string|null $name The name of the class to use - * @throws \Cake\ORM\Exception\MissingEntityException when the entity class cannot be found - * @return string - */ - public function entityClass($name = null) - { - deprecationWarning( - get_called_class() . '::entityClass() is deprecated. ' . - 'Use setEntityClass()/getEntityClass() instead.' - ); - if ($name !== null) { - $this->setEntityClass($name); - } - - return $this->getEntityClass(); - } - - /** - * Add a behavior. - * - * Adds a behavior to this table's behavior collection. Behaviors - * provide an easy way to create horizontally re-usable features - * that can provide trait like functionality, and allow for events - * to be listened to. - * - * Example: - * - * Load a behavior, with some settings. - * - * ``` - * $this->addBehavior('Tree', ['parent' => 'parentId']); - * ``` - * - * Behaviors are generally loaded during Table::initialize(). - * - * @param string $name The name of the behavior. Can be a short class reference. - * @param array $options The options for the behavior to use. - * @return $this - * @throws \RuntimeException If a behavior is being reloaded. - * @see \Cake\ORM\Behavior - */ - public function addBehavior($name, array $options = []) - { - $this->_behaviors->load($name, $options); - - return $this; - } - - /** - * Adds an array of behaviors to the table's behavior collection. - * - * Example: - * - * ``` - * $this->addBehaviors([ - * 'Timestamp', - * 'Tree' => ['level' => 'level'], - * ]); - * ``` - * - * @param array $behaviors All of the behaviors to load. - * @return $this - * @throws \RuntimeException If a behavior is being reloaded. - */ - public function addBehaviors(array $behaviors) - { - foreach ($behaviors as $name => $options) { - if (is_int($name)) { - $name = $options; - $options = []; - } - - $this->addBehavior($name, $options); - } - - return $this; - } - - /** - * Removes a behavior from this table's behavior registry. - * - * Example: - * - * Remove a behavior from this table. - * - * ``` - * $this->removeBehavior('Tree'); - * ``` - * - * @param string $name The alias that the behavior was added with. - * @return $this - * @see \Cake\ORM\Behavior - */ - public function removeBehavior($name) - { - $this->_behaviors->unload($name); - - return $this; - } - - /** - * Returns the behavior registry for this table. - * - * @return \Cake\ORM\BehaviorRegistry The BehaviorRegistry instance. - */ - public function behaviors() - { - return $this->_behaviors; - } - - /** - * Get a behavior from the registry. - * - * @param string $name The behavior alias to get from the registry. - * @return \Cake\ORM\Behavior - * @throws \InvalidArgumentException If the behavior does not exist. - */ - public function getBehavior($name) - { - /** @var \Cake\ORM\Behavior $behavior */ - $behavior = $this->_behaviors->get($name); - if ($behavior === null) { - throw new InvalidArgumentException(sprintf( - 'The %s behavior is not defined on %s.', - $name, - get_class($this) - )); - } - - return $behavior; - } - - /** - * Check if a behavior with the given alias has been loaded. - * - * @param string $name The behavior alias to check. - * @return bool Whether or not the behavior exists. - */ - public function hasBehavior($name) - { - return $this->_behaviors->has($name); - } - - /** - * Returns an association object configured for the specified alias if any. - * - * @deprecated 3.6.0 Use getAssociation() and Table::hasAssocation() instead. - * @param string $name the alias used for the association. - * @return \Cake\ORM\Association|null Either the association or null. - */ - public function association($name) - { - deprecationWarning('Use Table::getAssociation() and Table::hasAssocation() instead.'); - - return $this->findAssociation($name); - } - - /** - * Returns an association object configured for the specified alias. - * - * The name argument also supports dot syntax to access deeper associations. - * - * ``` - * $users = $this->getAssociation('Articles.Comments.Users'); - * ``` - * - * Note that this method requires the association to be present or otherwise - * throws an exception. - * If you are not sure, use hasAssociation() before calling this method. - * - * @param string $name The alias used for the association. - * @return \Cake\ORM\Association The association. - * @throws \InvalidArgumentException - */ - public function getAssociation($name) - { - $association = $this->findAssociation($name); - if (!$association) { - throw new InvalidArgumentException("The {$name} association is not defined on {$this->getAlias()}."); - } - - return $association; - } - - /** - * Checks whether a specific association exists on this Table instance. - * - * The name argument also supports dot syntax to access deeper associations. - * - * ``` - * $hasUsers = $this->hasAssociation('Articles.Comments.Users'); - * ``` - * - * @param string $name The alias used for the association. - * @return bool - */ - public function hasAssociation($name) - { - return $this->findAssociation($name) !== null; - } - - /** - * Returns an association object configured for the specified alias if any. - * - * The name argument also supports dot syntax to access deeper associations. - * - * ``` - * $users = $this->getAssociation('Articles.Comments.Users'); - * ``` - * - * @param string $name The alias used for the association. - * @return \Cake\ORM\Association|null Either the association or null. - */ - protected function findAssociation($name) - { - if (strpos($name, '.') === false) { - return $this->_associations->get($name); - } - - list($name, $next) = array_pad(explode('.', $name, 2), 2, null); - $result = $this->_associations->get($name); - - if ($result !== null && $next !== null) { - $result = $result->getTarget()->getAssociation($next); - } - - return $result; - } - - /** - * Get the associations collection for this table. - * - * @return \Cake\ORM\AssociationCollection|\Cake\ORM\Association[] The collection of association objects. - */ - public function associations() - { - return $this->_associations; - } - - /** - * Setup multiple associations. - * - * It takes an array containing set of table names indexed by association type - * as argument: - * - * ``` - * $this->Posts->addAssociations([ - * 'belongsTo' => [ - * 'Users' => ['className' => 'App\Model\Table\UsersTable'] - * ], - * 'hasMany' => ['Comments'], - * 'belongsToMany' => ['Tags'] - * ]); - * ``` - * - * Each association type accepts multiple associations where the keys - * are the aliases, and the values are association config data. If numeric - * keys are used the values will be treated as association aliases. - * - * @param array $params Set of associations to bind (indexed by association type) - * @return $this - * @see \Cake\ORM\Table::belongsTo() - * @see \Cake\ORM\Table::hasOne() - * @see \Cake\ORM\Table::hasMany() - * @see \Cake\ORM\Table::belongsToMany() - */ - public function addAssociations(array $params) - { - foreach ($params as $assocType => $tables) { - foreach ($tables as $associated => $options) { - if (is_numeric($associated)) { - $associated = $options; - $options = []; - } - $this->{$assocType}($associated, $options); - } - } - - return $this; - } - - /** - * Creates a new BelongsTo association between this table and a target - * table. A "belongs to" association is a N-1 relationship where this table - * is the N side, and where there is a single associated record in the target - * table for each one in this table. - * - * Target table can be inferred by its name, which is provided in the - * first argument, or you can either pass the to be instantiated or - * an instance of it directly. - * - * The options array accept the following keys: - * - * - className: The class name of the target table object - * - targetTable: An instance of a table object to be used as the target table - * - foreignKey: The name of the field to use as foreign key, if false none - * will be used - * - conditions: array with a list of conditions to filter the join with - * - joinType: The type of join to be used (e.g. INNER) - * - strategy: The loading strategy to use. 'join' and 'select' are supported. - * - finder: The finder method to use when loading records from this association. - * Defaults to 'all'. When the strategy is 'join', only the fields, containments, - * and where conditions will be used from the finder. - * - * This method will return the association object that was built. - * - * @param string $associated the alias for the target table. This is used to - * uniquely identify the association - * @param array $options list of options to configure the association definition - * @return \Cake\ORM\Association\BelongsTo - */ - public function belongsTo($associated, array $options = []) - { - $options += ['sourceTable' => $this]; - - /** @var \Cake\ORM\Association\BelongsTo $association */ - $association = $this->_associations->load(BelongsTo::class, $associated, $options); - - return $association; - } - - /** - * Creates a new HasOne association between this table and a target - * table. A "has one" association is a 1-1 relationship. - * - * Target table can be inferred by its name, which is provided in the - * first argument, or you can either pass the class name to be instantiated or - * an instance of it directly. - * - * The options array accept the following keys: - * - * - className: The class name of the target table object - * - targetTable: An instance of a table object to be used as the target table - * - foreignKey: The name of the field to use as foreign key, if false none - * will be used - * - dependent: Set to true if you want CakePHP to cascade deletes to the - * associated table when an entity is removed on this table. The delete operation - * on the associated table will not cascade further. To get recursive cascades enable - * `cascadeCallbacks` as well. Set to false if you don't want CakePHP to remove - * associated data, or when you are using database constraints. - * - cascadeCallbacks: Set to true if you want CakePHP to fire callbacks on - * cascaded deletes. If false the ORM will use deleteAll() to remove data. - * When true records will be loaded and then deleted. - * - conditions: array with a list of conditions to filter the join with - * - joinType: The type of join to be used (e.g. LEFT) - * - strategy: The loading strategy to use. 'join' and 'select' are supported. - * - finder: The finder method to use when loading records from this association. - * Defaults to 'all'. When the strategy is 'join', only the fields, containments, - * and where conditions will be used from the finder. - * - * This method will return the association object that was built. - * - * @param string $associated the alias for the target table. This is used to - * uniquely identify the association - * @param array $options list of options to configure the association definition - * @return \Cake\ORM\Association\HasOne - */ - public function hasOne($associated, array $options = []) - { - $options += ['sourceTable' => $this]; - - /** @var \Cake\ORM\Association\HasOne $association */ - $association = $this->_associations->load(HasOne::class, $associated, $options); - - return $association; - } - - /** - * Creates a new HasMany association between this table and a target - * table. A "has many" association is a 1-N relationship. - * - * Target table can be inferred by its name, which is provided in the - * first argument, or you can either pass the class name to be instantiated or - * an instance of it directly. - * - * The options array accept the following keys: - * - * - className: The class name of the target table object - * - targetTable: An instance of a table object to be used as the target table - * - foreignKey: The name of the field to use as foreign key, if false none - * will be used - * - dependent: Set to true if you want CakePHP to cascade deletes to the - * associated table when an entity is removed on this table. The delete operation - * on the associated table will not cascade further. To get recursive cascades enable - * `cascadeCallbacks` as well. Set to false if you don't want CakePHP to remove - * associated data, or when you are using database constraints. - * - cascadeCallbacks: Set to true if you want CakePHP to fire callbacks on - * cascaded deletes. If false the ORM will use deleteAll() to remove data. - * When true records will be loaded and then deleted. - * - conditions: array with a list of conditions to filter the join with - * - sort: The order in which results for this association should be returned - * - saveStrategy: Either 'append' or 'replace'. When 'append' the current records - * are appended to any records in the database. When 'replace' associated records - * not in the current set will be removed. If the foreign key is a null able column - * or if `dependent` is true records will be orphaned. - * - strategy: The strategy to be used for selecting results Either 'select' - * or 'subquery'. If subquery is selected the query used to return results - * in the source table will be used as conditions for getting rows in the - * target table. - * - finder: The finder method to use when loading records from this association. - * Defaults to 'all'. - * - * This method will return the association object that was built. - * - * @param string $associated the alias for the target table. This is used to - * uniquely identify the association - * @param array $options list of options to configure the association definition - * @return \Cake\ORM\Association\HasMany - */ - public function hasMany($associated, array $options = []) - { - $options += ['sourceTable' => $this]; - - /** @var \Cake\ORM\Association\HasMany $association */ - $association = $this->_associations->load(HasMany::class, $associated, $options); - - return $association; - } - - /** - * Creates a new BelongsToMany association between this table and a target - * table. A "belongs to many" association is a M-N relationship. - * - * Target table can be inferred by its name, which is provided in the - * first argument, or you can either pass the class name to be instantiated or - * an instance of it directly. - * - * The options array accept the following keys: - * - * - className: The class name of the target table object. - * - targetTable: An instance of a table object to be used as the target table. - * - foreignKey: The name of the field to use as foreign key. - * - targetForeignKey: The name of the field to use as the target foreign key. - * - joinTable: The name of the table representing the link between the two - * - through: If you choose to use an already instantiated link table, set this - * key to a configured Table instance containing associations to both the source - * and target tables in this association. - * - dependent: Set to false, if you do not want junction table records removed - * when an owning record is removed. - * - cascadeCallbacks: Set to true if you want CakePHP to fire callbacks on - * cascaded deletes. If false the ORM will use deleteAll() to remove data. - * When true join/junction table records will be loaded and then deleted. - * - conditions: array with a list of conditions to filter the join with. - * - sort: The order in which results for this association should be returned. - * - strategy: The strategy to be used for selecting results Either 'select' - * or 'subquery'. If subquery is selected the query used to return results - * in the source table will be used as conditions for getting rows in the - * target table. - * - saveStrategy: Either 'append' or 'replace'. Indicates the mode to be used - * for saving associated entities. The former will only create new links - * between both side of the relation and the latter will do a wipe and - * replace to create the links between the passed entities when saving. - * - strategy: The loading strategy to use. 'select' and 'subquery' are supported. - * - finder: The finder method to use when loading records from this association. - * Defaults to 'all'. - * - * This method will return the association object that was built. - * - * @param string $associated the alias for the target table. This is used to - * uniquely identify the association - * @param array $options list of options to configure the association definition - * @return \Cake\ORM\Association\BelongsToMany - */ - public function belongsToMany($associated, array $options = []) - { - $options += ['sourceTable' => $this]; - - /** @var \Cake\ORM\Association\BelongsToMany $association */ - $association = $this->_associations->load(BelongsToMany::class, $associated, $options); - - return $association; - } - - /** - * {@inheritDoc} - * - * ### Model.beforeFind event - * - * Each find() will trigger a `Model.beforeFind` event for all attached - * listeners. Any listener can set a valid result set using $query - * - * By default, `$options` will recognize the following keys: - * - * - fields - * - conditions - * - order - * - limit - * - offset - * - page - * - group - * - having - * - contain - * - join - * - * ### Usage - * - * Using the options array: - * - * ``` - * $query = $articles->find('all', [ - * 'conditions' => ['published' => 1], - * 'limit' => 10, - * 'contain' => ['Users', 'Comments'] - * ]); - * ``` - * - * Using the builder interface: - * - * ``` - * $query = $articles->find() - * ->where(['published' => 1]) - * ->limit(10) - * ->contain(['Users', 'Comments']); - * ``` - * - * ### Calling finders - * - * The find() method is the entry point for custom finder methods. - * You can invoke a finder by specifying the type: - * - * ``` - * $query = $articles->find('published'); - * ``` - * - * Would invoke the `findPublished` method. - * - * @return \Cake\ORM\Query The query builder - */ - public function find($type = 'all', $options = []) - { - $query = $this->query(); - $query->select(); - - return $this->callFinder($type, $query, $options); - } - - /** - * Returns the query as passed. - * - * By default findAll() applies no conditions, you - * can override this method in subclasses to modify how `find('all')` works. - * - * @param \Cake\ORM\Query $query The query to find with - * @param array $options The options to use for the find - * @return \Cake\ORM\Query The query builder - */ - public function findAll(Query $query, array $options) - { - return $query; - } - - /** - * Sets up a query object so results appear as an indexed array, useful for any - * place where you would want a list such as for populating input select boxes. - * - * When calling this finder, the fields passed are used to determine what should - * be used as the array key, value and optionally what to group the results by. - * By default the primary key for the model is used for the key, and the display - * field as value. - * - * The results of this finder will be in the following form: - * - * ``` - * [ - * 1 => 'value for id 1', - * 2 => 'value for id 2', - * 4 => 'value for id 4' - * ] - * ``` - * - * You can specify which property will be used as the key and which as value - * by using the `$options` array, when not specified, it will use the results - * of calling `primaryKey` and `displayField` respectively in this table: - * - * ``` - * $table->find('list', [ - * 'keyField' => 'name', - * 'valueField' => 'age' - * ]); - * ``` - * - * Results can be put together in bigger groups when they share a property, you - * can customize the property to use for grouping by setting `groupField`: - * - * ``` - * $table->find('list', [ - * 'groupField' => 'category_id', - * ]); - * ``` - * - * When using a `groupField` results will be returned in this format: - * - * ``` - * [ - * 'group_1' => [ - * 1 => 'value for id 1', - * 2 => 'value for id 2', - * ] - * 'group_2' => [ - * 4 => 'value for id 4' - * ] - * ] - * ``` - * - * @param \Cake\ORM\Query $query The query to find with - * @param array $options The options for the find - * @return \Cake\ORM\Query The query builder - */ - public function findList(Query $query, array $options) - { - $options += [ - 'keyField' => $this->getPrimaryKey(), - 'valueField' => $this->getDisplayField(), - 'groupField' => null - ]; - - if (isset($options['idField'])) { - $options['keyField'] = $options['idField']; - unset($options['idField']); - deprecationWarning('Option "idField" is deprecated, use "keyField" instead.'); - } - - if (!$query->clause('select') && - !is_object($options['keyField']) && - !is_object($options['valueField']) && - !is_object($options['groupField']) - ) { - $fields = array_merge( - (array)$options['keyField'], - (array)$options['valueField'], - (array)$options['groupField'] - ); - $columns = $this->getSchema()->columns(); - if (count($fields) === count(array_intersect($fields, $columns))) { - $query->select($fields); - } - } - - $options = $this->_setFieldMatchers( - $options, - ['keyField', 'valueField', 'groupField'] - ); - - return $query->formatResults(function ($results) use ($options) { - /** @var \Cake\Collection\CollectionInterface $results */ - return $results->combine( - $options['keyField'], - $options['valueField'], - $options['groupField'] - ); - }); - } - - /** - * Results for this finder will be a nested array, and is appropriate if you want - * to use the parent_id field of your model data to build nested results. - * - * Values belonging to a parent row based on their parent_id value will be - * recursively nested inside the parent row values using the `children` property - * - * You can customize what fields are used for nesting results, by default the - * primary key and the `parent_id` fields are used. If you wish to change - * these defaults you need to provide the keys `keyField`, `parentField` or `nestingKey` in - * `$options`: - * - * ``` - * $table->find('threaded', [ - * 'keyField' => 'id', - * 'parentField' => 'ancestor_id' - * 'nestingKey' => 'children' - * ]); - * ``` - * - * @param \Cake\ORM\Query $query The query to find with - * @param array $options The options to find with - * @return \Cake\ORM\Query The query builder - */ - public function findThreaded(Query $query, array $options) - { - $options += [ - 'keyField' => $this->getPrimaryKey(), - 'parentField' => 'parent_id', - 'nestingKey' => 'children' - ]; - - if (isset($options['idField'])) { - $options['keyField'] = $options['idField']; - unset($options['idField']); - deprecationWarning('Option "idField" is deprecated, use "keyField" instead.'); - } - - $options = $this->_setFieldMatchers($options, ['keyField', 'parentField']); - - return $query->formatResults(function ($results) use ($options) { - /** @var \Cake\Collection\CollectionInterface $results */ - return $results->nest($options['keyField'], $options['parentField'], $options['nestingKey']); - }); - } - - /** - * Out of an options array, check if the keys described in `$keys` are arrays - * and change the values for closures that will concatenate the each of the - * properties in the value array when passed a row. - * - * This is an auxiliary function used for result formatters that can accept - * composite keys when comparing values. - * - * @param array $options the original options passed to a finder - * @param array $keys the keys to check in $options to build matchers from - * the associated value - * @return array - */ - protected function _setFieldMatchers($options, $keys) - { - foreach ($keys as $field) { - if (!is_array($options[$field])) { - continue; - } - - if (count($options[$field]) === 1) { - $options[$field] = current($options[$field]); - continue; - } - - $fields = $options[$field]; - $options[$field] = function ($row) use ($fields) { - $matches = []; - foreach ($fields as $field) { - $matches[] = $row[$field]; - } - - return implode(';', $matches); - }; - } - - return $options; - } - - /** - * {@inheritDoc} - * - * ### Usage - * - * Get an article and some relationships: - * - * ``` - * $article = $articles->get(1, ['contain' => ['Users', 'Comments']]); - * ``` - * - * @throws \Cake\Datasource\Exception\InvalidPrimaryKeyException When $primaryKey has an - * incorrect number of elements. - */ - public function get($primaryKey, $options = []) - { - $key = (array)$this->getPrimaryKey(); - $alias = $this->getAlias(); - foreach ($key as $index => $keyname) { - $key[$index] = $alias . '.' . $keyname; - } - $primaryKey = (array)$primaryKey; - if (count($key) !== count($primaryKey)) { - $primaryKey = $primaryKey ?: [null]; - $primaryKey = array_map(function ($key) { - return var_export($key, true); - }, $primaryKey); - - throw new InvalidPrimaryKeyException(sprintf( - 'Record not found in table "%s" with primary key [%s]', - $this->getTable(), - implode($primaryKey, ', ') - )); - } - $conditions = array_combine($key, $primaryKey); - - $cacheConfig = isset($options['cache']) ? $options['cache'] : false; - $cacheKey = isset($options['key']) ? $options['key'] : false; - $finder = isset($options['finder']) ? $options['finder'] : 'all'; - unset($options['key'], $options['cache'], $options['finder']); - - $query = $this->find($finder, $options)->where($conditions); - - if ($cacheConfig) { - if (!$cacheKey) { - $cacheKey = sprintf( - 'get:%s.%s%s', - $this->getConnection()->configName(), - $this->getTable(), - json_encode($primaryKey) - ); - } - $query->cache($cacheKey, $cacheConfig); - } - - return $query->firstOrFail(); - } - - /** - * Handles the logic executing of a worker inside a transaction. - * - * @param callable $worker The worker that will run inside the transaction. - * @param bool $atomic Whether to execute the worker inside a database transaction. - * @return mixed - */ - protected function _executeTransaction(callable $worker, $atomic = true) - { - if ($atomic) { - return $this->getConnection()->transactional(function () use ($worker) { - return $worker(); - }); - } - - return $worker(); - } - - /** - * Checks if the caller would have executed a commit on a transaction. - * - * @param bool $atomic True if an atomic transaction was used. - * @param bool $primary True if a primary was used. - * @return bool Returns true if a transaction was committed. - */ - protected function _transactionCommitted($atomic, $primary) - { - return !$this->getConnection()->inTransaction() && ($atomic || (!$atomic && $primary)); - } - - /** - * Finds an existing record or creates a new one. - * - * A find() will be done to locate an existing record using the attributes - * defined in $search. If records matches the conditions, the first record - * will be returned. - * - * If no record can be found, a new entity will be created - * with the $search properties. If a callback is provided, it will be - * called allowing you to define additional default values. The new - * entity will be saved and returned. - * - * If your find conditions require custom order, associations or conditions, then the $search - * parameter can be a callable that takes the Query as the argument, or a \Cake\ORM\Query object passed - * as the $search parameter. Allowing you to customize the find results. - * - * ### Options - * - * The options array is passed to the save method with exception to the following keys: - * - * - atomic: Whether to execute the methods for find, save and callbacks inside a database - * transaction (default: true) - * - defaults: Whether to use the search criteria as default values for the new entity (default: true) - * - * @param array|\Cake\ORM\Query $search The criteria to find existing - * records by. Note that when you pass a query object you'll have to use - * the 2nd arg of the method to modify the entity data before saving. - * @param callable|null $callback A callback that will be invoked for newly - * created entities. This callback will be called *before* the entity - * is persisted. - * @param array $options The options to use when saving. - * @return \Cake\Datasource\EntityInterface An entity. - */ - public function findOrCreate($search, callable $callback = null, $options = []) - { - $options += [ - 'atomic' => true, - 'defaults' => true - ]; - - return $this->_executeTransaction(function () use ($search, $callback, $options) { - return $this->_processFindOrCreate($search, $callback, $options); - }, $options['atomic']); - } - - /** - * Performs the actual find and/or create of an entity based on the passed options. - * - * @param array|callable $search The criteria to find an existing record by, or a callable tha will - * customize the find query. - * @param callable|null $callback A callback that will be invoked for newly - * created entities. This callback will be called *before* the entity - * is persisted. - * @param array $options The options to use when saving. - * @return \Cake\Datasource\EntityInterface An entity. - */ - protected function _processFindOrCreate($search, callable $callback = null, $options = []) - { - if (is_callable($search)) { - $query = $this->find(); - $search($query); - } elseif (is_array($search)) { - $query = $this->find()->where($search); - } elseif ($search instanceof Query) { - $query = $search; - } else { - throw new InvalidArgumentException('Search criteria must be an array, callable or Query'); - } - $row = $query->first(); - if ($row !== null) { - return $row; - } - $entity = $this->newEntity(); - if ($options['defaults'] && is_array($search)) { - $entity->set($search, ['guard' => false]); - } - if ($callback !== null) { - $entity = $callback($entity) ?: $entity; - } - unset($options['defaults']); - - return $this->save($entity, $options) ?: $entity; - } - - /** - * Gets the query object for findOrCreate(). - * - * @param array|\Cake\ORM\Query|string $search The criteria to find existing records by. - * @return \Cake\ORM\Query - */ - protected function _getFindOrCreateQuery($search) - { - if ($search instanceof Query) { - return $search; - } - - return $this->find()->where($search); - } - - /** - * {@inheritDoc} - */ - public function query() - { - return new Query($this->getConnection(), $this); - } - - /** - * {@inheritDoc} - */ - public function updateAll($fields, $conditions) - { - $query = $this->query(); - $query->update() - ->set($fields) - ->where($conditions); - $statement = $query->execute(); - $statement->closeCursor(); - - return $statement->rowCount(); - } - - /** - * {@inheritDoc} - */ - public function deleteAll($conditions) - { - $query = $this->query() - ->delete() - ->where($conditions); - $statement = $query->execute(); - $statement->closeCursor(); - - return $statement->rowCount(); - } - - /** - * {@inheritDoc} - */ - public function exists($conditions) - { - return (bool)count( - $this->find('all') - ->select(['existing' => 1]) - ->where($conditions) - ->limit(1) - ->enableHydration(false) - ->toArray() - ); - } - - /** - * {@inheritDoc} - * - * ### Options - * - * The options array accepts the following keys: - * - * - atomic: Whether to execute the save and callbacks inside a database - * transaction (default: true) - * - checkRules: Whether or not to check the rules on entity before saving, if the checking - * fails, it will abort the save operation. (default:true) - * - associated: If `true` it will save 1st level associated entities as they are found - * in the passed `$entity` whenever the property defined for the association - * is marked as dirty. If an array, it will be interpreted as the list of associations - * to be saved. It is possible to provide different options for saving on associated - * table objects using this key by making the custom options the array value. - * If `false` no associated records will be saved. (default: `true`) - * - checkExisting: Whether or not to check if the entity already exists, assuming that the - * entity is marked as not new, and the primary key has been set. - * - * ### Events - * - * When saving, this method will trigger four events: - * - * - Model.beforeRules: Will be triggered right before any rule checking is done - * for the passed entity if the `checkRules` key in $options is not set to false. - * Listeners will receive as arguments the entity, options array and the operation type. - * If the event is stopped the rules check result will be set to the result of the event itself. - * - Model.afterRules: Will be triggered right after the `checkRules()` method is - * called for the entity. Listeners will receive as arguments the entity, - * options array, the result of checking the rules and the operation type. - * If the event is stopped the checking result will be set to the result of - * the event itself. - * - Model.beforeSave: Will be triggered just before the list of fields to be - * persisted is calculated. It receives both the entity and the options as - * arguments. The options array is passed as an ArrayObject, so any changes in - * it will be reflected in every listener and remembered at the end of the event - * so it can be used for the rest of the save operation. Returning false in any - * of the listeners will abort the saving process. If the event is stopped - * using the event API, the event object's `result` property will be returned. - * This can be useful when having your own saving strategy implemented inside a - * listener. - * - Model.afterSave: Will be triggered after a successful insert or save, - * listeners will receive the entity and the options array as arguments. The type - * of operation performed (insert or update) can be determined by checking the - * entity's method `isNew`, true meaning an insert and false an update. - * - Model.afterSaveCommit: Will be triggered after the transaction is commited - * for atomic save, listeners will receive the entity and the options array - * as arguments. - * - * This method will determine whether the passed entity needs to be - * inserted or updated in the database. It does that by checking the `isNew` - * method on the entity. If the entity to be saved returns a non-empty value from - * its `errors()` method, it will not be saved. - * - * ### Saving on associated tables - * - * This method will by default persist entities belonging to associated tables, - * whenever a dirty property matching the name of the property name set for an - * association in this table. It is possible to control what associations will - * be saved and to pass additional option for saving them. - * - * ``` - * // Only save the comments association - * $articles->save($entity, ['associated' => ['Comments']); - * - * // Save the company, the employees and related addresses for each of them. - * // For employees do not check the entity rules - * $companies->save($entity, [ - * 'associated' => [ - * 'Employees' => [ - * 'associated' => ['Addresses'], - * 'checkRules' => false - * ] - * ] - * ]); - * - * // Save no associations - * $articles->save($entity, ['associated' => false]); - * ``` - * - * @throws \Cake\ORM\Exception\RolledbackTransactionException If the transaction - * is aborted in the afterSave event. - */ - public function save(EntityInterface $entity, $options = []) - { - if ($options instanceof SaveOptionsBuilder) { - $options = $options->toArray(); - } - - $options = new ArrayObject($options + [ - 'atomic' => true, - 'associated' => true, - 'checkRules' => true, - 'checkExisting' => true, - '_primary' => true - ]); - - if ($entity->getErrors()) { - return false; - } - - if ($entity->isNew() === false && !$entity->isDirty()) { - return $entity; - } - - $success = $this->_executeTransaction(function () use ($entity, $options) { - return $this->_processSave($entity, $options); - }, $options['atomic']); - - if ($success) { - if ($this->_transactionCommitted($options['atomic'], $options['_primary'])) { - $this->dispatchEvent('Model.afterSaveCommit', compact('entity', 'options')); - } - if ($options['atomic'] || $options['_primary']) { - $entity->clean(); - $entity->isNew(false); - $entity->setSource($this->getRegistryAlias()); - } - } - - return $success; - } - - /** - * Try to save an entity or throw a PersistenceFailedException if the application rules checks failed, - * the entity contains errors or the save was aborted by a callback. - * - * @param \Cake\Datasource\EntityInterface $entity the entity to be saved - * @param array|\ArrayAccess $options The options to use when saving. - * @return \Cake\Datasource\EntityInterface - * @throws \Cake\ORM\Exception\PersistenceFailedException When the entity couldn't be saved - * @see \Cake\ORM\Table::save() - */ - public function saveOrFail(EntityInterface $entity, $options = []) - { - $saved = $this->save($entity, $options); - if ($saved === false) { - throw new PersistenceFailedException($entity, ['save']); - } - - return $saved; - } - - /** - * Performs the actual saving of an entity based on the passed options. - * - * @param \Cake\Datasource\EntityInterface $entity the entity to be saved - * @param \ArrayObject $options the options to use for the save operation - * @return \Cake\Datasource\EntityInterface|bool - * @throws \RuntimeException When an entity is missing some of the primary keys. - * @throws \Cake\ORM\Exception\RolledbackTransactionException If the transaction - * is aborted in the afterSave event. - */ - protected function _processSave($entity, $options) - { - $primaryColumns = (array)$this->getPrimaryKey(); - - if ($options['checkExisting'] && $primaryColumns && $entity->isNew() && $entity->has($primaryColumns)) { - $alias = $this->getAlias(); - $conditions = []; - foreach ($entity->extract($primaryColumns) as $k => $v) { - $conditions["$alias.$k"] = $v; - } - $entity->isNew(!$this->exists($conditions)); - } - - $mode = $entity->isNew() ? RulesChecker::CREATE : RulesChecker::UPDATE; - if ($options['checkRules'] && !$this->checkRules($entity, $mode, $options)) { - return false; - } - - $options['associated'] = $this->_associations->normalizeKeys($options['associated']); - $event = $this->dispatchEvent('Model.beforeSave', compact('entity', 'options')); - - if ($event->isStopped()) { - return $event->getResult(); - } - - $saved = $this->_associations->saveParents( - $this, - $entity, - $options['associated'], - ['_primary' => false] + $options->getArrayCopy() - ); - - if (!$saved && $options['atomic']) { - return false; - } - - $data = $entity->extract($this->getSchema()->columns(), true); - $isNew = $entity->isNew(); - - if ($isNew) { - $success = $this->_insert($entity, $data); - } else { - $success = $this->_update($entity, $data); - } - - if ($success) { - $success = $this->_onSaveSuccess($entity, $options); - } - - if (!$success && $isNew) { - $entity->unsetProperty($this->getPrimaryKey()); - $entity->isNew(true); - } - - return $success ? $entity : false; - } - - /** - * Handles the saving of children associations and executing the afterSave logic - * once the entity for this table has been saved successfully. - * - * @param \Cake\Datasource\EntityInterface $entity the entity to be saved - * @param \ArrayObject $options the options to use for the save operation - * @return bool True on success - * @throws \Cake\ORM\Exception\RolledbackTransactionException If the transaction - * is aborted in the afterSave event. - */ - protected function _onSaveSuccess($entity, $options) - { - $success = $this->_associations->saveChildren( - $this, - $entity, - $options['associated'], - ['_primary' => false] + $options->getArrayCopy() - ); - - if (!$success && $options['atomic']) { - return false; - } - - $this->dispatchEvent('Model.afterSave', compact('entity', 'options')); - - if ($options['atomic'] && !$this->getConnection()->inTransaction()) { - throw new RolledbackTransactionException(['table' => get_class($this)]); - } - - if (!$options['atomic'] && !$options['_primary']) { - $entity->clean(); - $entity->isNew(false); - $entity->setSource($this->getRegistryAlias()); - } - - return true; - } - - /** - * Auxiliary function to handle the insert of an entity's data in the table - * - * @param \Cake\Datasource\EntityInterface $entity the subject entity from were $data was extracted - * @param array $data The actual data that needs to be saved - * @return \Cake\Datasource\EntityInterface|bool - * @throws \RuntimeException if not all the primary keys where supplied or could - * be generated when the table has composite primary keys. Or when the table has no primary key. - */ - protected function _insert($entity, $data) - { - $primary = (array)$this->getPrimaryKey(); - if (empty($primary)) { - $msg = sprintf( - 'Cannot insert row in "%s" table, it has no primary key.', - $this->getTable() - ); - throw new RuntimeException($msg); - } - $keys = array_fill(0, count($primary), null); - $id = (array)$this->_newId($primary) + $keys; - - // Generate primary keys preferring values in $data. - $primary = array_combine($primary, $id); - $primary = array_intersect_key($data, $primary) + $primary; - - $filteredKeys = array_filter($primary, 'strlen'); - $data += $filteredKeys; - - if (count($primary) > 1) { - $schema = $this->getSchema(); - foreach ($primary as $k => $v) { - if (!isset($data[$k]) && empty($schema->getColumn($k)['autoIncrement'])) { - $msg = 'Cannot insert row, some of the primary key values are missing. '; - $msg .= sprintf( - 'Got (%s), expecting (%s)', - implode(', ', $filteredKeys + $entity->extract(array_keys($primary))), - implode(', ', array_keys($primary)) - ); - throw new RuntimeException($msg); - } - } - } - - $success = false; - if (empty($data)) { - return $success; - } - - $statement = $this->query()->insert(array_keys($data)) - ->values($data) - ->execute(); - - if ($statement->rowCount() !== 0) { - $success = $entity; - $entity->set($filteredKeys, ['guard' => false]); - $schema = $this->getSchema(); - $driver = $this->getConnection()->getDriver(); - foreach ($primary as $key => $v) { - if (!isset($data[$key])) { - $id = $statement->lastInsertId($this->getTable(), $key); - $type = $schema->getColumnType($key); - $entity->set($key, Type::build($type)->toPHP($id, $driver)); - break; - } - } - } - $statement->closeCursor(); - - return $success; - } - - /** - * Generate a primary key value for a new record. - * - * By default, this uses the type system to generate a new primary key - * value if possible. You can override this method if you have specific requirements - * for id generation. - * - * Note: The ORM will not generate primary key values for composite primary keys. - * You can overwrite _newId() in your table class. - * - * @param array $primary The primary key columns to get a new ID for. - * @return null|string|array Either null or the primary key value or a list of primary key values. - */ - protected function _newId($primary) - { - if (!$primary || count((array)$primary) > 1) { - return null; - } - $typeName = $this->getSchema()->getColumnType($primary[0]); - $type = Type::build($typeName); - - return $type->newId(); - } - - /** - * Auxiliary function to handle the update of an entity's data in the table - * - * @param \Cake\Datasource\EntityInterface $entity the subject entity from were $data was extracted - * @param array $data The actual data that needs to be saved - * @return \Cake\Datasource\EntityInterface|bool - * @throws \InvalidArgumentException When primary key data is missing. - */ - protected function _update($entity, $data) - { - $primaryColumns = (array)$this->getPrimaryKey(); - $primaryKey = $entity->extract($primaryColumns); - - $data = array_diff_key($data, $primaryKey); - if (empty($data)) { - return $entity; - } - - if (count($primaryColumns) === 0) { - $entityClass = get_class($entity); - $table = $this->getTable(); - $message = "Cannot update `$entityClass`. The `$table` has no primary key."; - throw new InvalidArgumentException($message); - } - - if (!$entity->has($primaryColumns)) { - $message = 'All primary key value(s) are needed for updating, '; - $message .= get_class($entity) . ' is missing ' . implode(', ', $primaryColumns); - throw new InvalidArgumentException($message); - } - - $query = $this->query(); - $statement = $query->update() - ->set($data) - ->where($primaryKey) - ->execute(); - - $success = false; - if ($statement->errorCode() === '00000') { - $success = $entity; - } - $statement->closeCursor(); - - return $success; - } - - /** - * Persists multiple entities of a table. - * - * The records will be saved in a transaction which will be rolled back if - * any one of the records fails to save due to failed validation or database - * error. - * - * @param \Cake\Datasource\EntityInterface[]|\Cake\ORM\ResultSet $entities Entities to save. - * @param array|\ArrayAccess $options Options used when calling Table::save() for each entity. - * @return bool|\Cake\Datasource\EntityInterface[]|\Cake\ORM\ResultSet False on failure, entities list on success. - */ - public function saveMany($entities, $options = []) - { - $isNew = []; - - $return = $this->getConnection()->transactional( - function () use ($entities, $options, &$isNew) { - foreach ($entities as $key => $entity) { - $isNew[$key] = $entity->isNew(); - if ($this->save($entity, $options) === false) { - return false; - } - } - } - ); - - if ($return === false) { - foreach ($entities as $key => $entity) { - if (isset($isNew[$key]) && $isNew[$key]) { - $entity->unsetProperty($this->getPrimaryKey()); - $entity->isNew(true); - } - } - - return false; - } - - return $entities; - } - - /** - * {@inheritDoc} - * - * For HasMany and HasOne associations records will be removed based on - * the dependent option. Join table records in BelongsToMany associations - * will always be removed. You can use the `cascadeCallbacks` option - * when defining associations to change how associated data is deleted. - * - * ### Options - * - * - `atomic` Defaults to true. When true the deletion happens within a transaction. - * - `checkRules` Defaults to true. Check deletion rules before deleting the record. - * - * ### Events - * - * - `Model.beforeDelete` Fired before the delete occurs. If stopped the delete - * will be aborted. Receives the event, entity, and options. - * - `Model.afterDelete` Fired after the delete has been successful. Receives - * the event, entity, and options. - * - `Model.afterDeleteCommit` Fired after the transaction is committed for - * an atomic delete. Receives the event, entity, and options. - * - * The options argument will be converted into an \ArrayObject instance - * for the duration of the callbacks, this allows listeners to modify - * the options used in the delete operation. - * - */ - public function delete(EntityInterface $entity, $options = []) - { - $options = new ArrayObject($options + [ - 'atomic' => true, - 'checkRules' => true, - '_primary' => true, - ]); - - $success = $this->_executeTransaction(function () use ($entity, $options) { - return $this->_processDelete($entity, $options); - }, $options['atomic']); - - if ($success && $this->_transactionCommitted($options['atomic'], $options['_primary'])) { - $this->dispatchEvent('Model.afterDeleteCommit', [ - 'entity' => $entity, - 'options' => $options - ]); - } - - return $success; - } - - /** - * Try to delete an entity or throw a PersistenceFailedException if the entity is new, - * has no primary key value, application rules checks failed or the delete was aborted by a callback. - * - * @param \Cake\Datasource\EntityInterface $entity The entity to remove. - * @param array|\ArrayAccess $options The options for the delete. - * @return bool success - * @throws \Cake\ORM\Exception\PersistenceFailedException - * @see \Cake\ORM\Table::delete() - */ - public function deleteOrFail(EntityInterface $entity, $options = []) - { - $deleted = $this->delete($entity, $options); - if ($deleted === false) { - throw new PersistenceFailedException($entity, ['delete']); - } - - return $deleted; - } - - /** - * Perform the delete operation. - * - * Will delete the entity provided. Will remove rows from any - * dependent associations, and clear out join tables for BelongsToMany associations. - * - * @param \Cake\Datasource\EntityInterface $entity The entity to delete. - * @param \ArrayObject $options The options for the delete. - * @throws \InvalidArgumentException if there are no primary key values of the - * passed entity - * @return bool success - */ - protected function _processDelete($entity, $options) - { - if ($entity->isNew()) { - return false; - } - - $primaryKey = (array)$this->getPrimaryKey(); - if (!$entity->has($primaryKey)) { - $msg = 'Deleting requires all primary key values.'; - throw new InvalidArgumentException($msg); - } - - if ($options['checkRules'] && !$this->checkRules($entity, RulesChecker::DELETE, $options)) { - return false; - } - - $event = $this->dispatchEvent('Model.beforeDelete', [ - 'entity' => $entity, - 'options' => $options - ]); - - if ($event->isStopped()) { - return $event->getResult(); - } - - $this->_associations->cascadeDelete( - $entity, - ['_primary' => false] + $options->getArrayCopy() - ); - - $query = $this->query(); - $conditions = (array)$entity->extract($primaryKey); - $statement = $query->delete() - ->where($conditions) - ->execute(); - - $success = $statement->rowCount() > 0; - if (!$success) { - return $success; - } - - $this->dispatchEvent('Model.afterDelete', [ - 'entity' => $entity, - 'options' => $options - ]); - - return $success; - } - - /** - * Returns true if the finder exists for the table - * - * @param string $type name of finder to check - * - * @return bool - */ - public function hasFinder($type) - { - $finder = 'find' . $type; - - return method_exists($this, $finder) || ($this->_behaviors && $this->_behaviors->hasFinder($type)); - } - - /** - * Calls a finder method directly and applies it to the passed query, - * if no query is passed a new one will be created and returned - * - * @param string $type name of the finder to be called - * @param \Cake\ORM\Query $query The query object to apply the finder options to - * @param array $options List of options to pass to the finder - * @return \Cake\ORM\Query - * @throws \BadMethodCallException - */ - public function callFinder($type, Query $query, array $options = []) - { - $query->applyOptions($options); - $options = $query->getOptions(); - $finder = 'find' . $type; - if (method_exists($this, $finder)) { - return $this->{$finder}($query, $options); - } - - if ($this->_behaviors && $this->_behaviors->hasFinder($type)) { - return $this->_behaviors->callFinder($type, [$query, $options]); - } - - throw new BadMethodCallException( - sprintf('Unknown finder method "%s"', $type) - ); - } - - /** - * Provides the dynamic findBy and findByAll methods. - * - * @param string $method The method name that was fired. - * @param array $args List of arguments passed to the function. - * @return mixed - * @throws \BadMethodCallException when there are missing arguments, or when - * and & or are combined. - */ - protected function _dynamicFinder($method, $args) - { - $method = Inflector::underscore($method); - preg_match('/^find_([\w]+)_by_/', $method, $matches); - if (empty($matches)) { - // find_by_ is 8 characters. - $fields = substr($method, 8); - $findType = 'all'; - } else { - $fields = substr($method, strlen($matches[0])); - $findType = Inflector::variable($matches[1]); - } - $hasOr = strpos($fields, '_or_'); - $hasAnd = strpos($fields, '_and_'); - - $makeConditions = function ($fields, $args) { - $conditions = []; - if (count($args) < count($fields)) { - throw new BadMethodCallException(sprintf( - 'Not enough arguments for magic finder. Got %s required %s', - count($args), - count($fields) - )); - } - foreach ($fields as $field) { - $conditions[$this->aliasField($field)] = array_shift($args); - } - - return $conditions; - }; - - if ($hasOr !== false && $hasAnd !== false) { - throw new BadMethodCallException( - 'Cannot mix "and" & "or" in a magic finder. Use find() instead.' - ); - } - - $conditions = []; - if ($hasOr === false && $hasAnd === false) { - $conditions = $makeConditions([$fields], $args); - } elseif ($hasOr !== false) { - $fields = explode('_or_', $fields); - $conditions = [ - 'OR' => $makeConditions($fields, $args) - ]; - } elseif ($hasAnd !== false) { - $fields = explode('_and_', $fields); - $conditions = $makeConditions($fields, $args); - } - - return $this->find($findType, [ - 'conditions' => $conditions, - ]); - } - - /** - * Handles behavior delegation + dynamic finders. - * - * If your Table uses any behaviors you can call them as if - * they were on the table object. - * - * @param string $method name of the method to be invoked - * @param array $args List of arguments passed to the function - * @return mixed - * @throws \BadMethodCallException - */ - public function __call($method, $args) - { - if ($this->_behaviors && $this->_behaviors->hasMethod($method)) { - return $this->_behaviors->call($method, $args); - } - if (preg_match('/^find(?:\w+)?By/', $method) > 0) { - return $this->_dynamicFinder($method, $args); - } - - throw new BadMethodCallException( - sprintf('Unknown method "%s"', $method) - ); - } - - /** - * Returns the association named after the passed value if exists, otherwise - * throws an exception. - * - * @param string $property the association name - * @return \Cake\ORM\Association - * @throws \RuntimeException if no association with such name exists - */ - public function __get($property) - { - $association = $this->_associations->get($property); - if (!$association) { - throw new RuntimeException(sprintf( - 'Table "%s" is not associated with "%s"', - get_class($this), - $property - )); - } - - return $association; - } - - /** - * Returns whether an association named after the passed value - * exists for this table. - * - * @param string $property the association name - * @return bool - */ - public function __isset($property) - { - return $this->_associations->has($property); - } - - /** - * Get the object used to marshal/convert array data into objects. - * - * Override this method if you want a table object to use custom - * marshalling logic. - * - * @return \Cake\ORM\Marshaller - * @see \Cake\ORM\Marshaller - */ - public function marshaller() - { - return new Marshaller($this); - } - - /** - * {@inheritDoc} - * - * By default all the associations on this table will be hydrated. You can - * limit which associations are built, or include deeper associations - * using the options parameter: - * - * ``` - * $article = $this->Articles->newEntity( - * $this->request->getData(), - * ['associated' => ['Tags', 'Comments.Users']] - * ); - * ``` - * - * You can limit fields that will be present in the constructed entity by - * passing the `fieldList` option, which is also accepted for associations: - * - * ``` - * $article = $this->Articles->newEntity($this->request->getData(), [ - * 'fieldList' => ['title', 'body', 'tags', 'comments'], - * 'associated' => ['Tags', 'Comments.Users' => ['fieldList' => 'username']] - * ] - * ); - * ``` - * - * The `fieldList` option lets remove or restrict input data from ending up in - * the entity. If you'd like to relax the entity's default accessible fields, - * you can use the `accessibleFields` option: - * - * ``` - * $article = $this->Articles->newEntity( - * $this->request->getData(), - * ['accessibleFields' => ['protected_field' => true]] - * ); - * ``` - * - * By default, the data is validated before being passed to the new entity. In - * the case of invalid fields, those will not be present in the resulting object. - * The `validate` option can be used to disable validation on the passed data: - * - * ``` - * $article = $this->Articles->newEntity( - * $this->request->getData(), - * ['validate' => false] - * ); - * ``` - * - * You can also pass the name of the validator to use in the `validate` option. - * If `null` is passed to the first param of this function, no validation will - * be performed. - * - * You can use the `Model.beforeMarshal` event to modify request data - * before it is converted into entities. - */ - public function newEntity($data = null, array $options = []) - { - if ($data === null) { - $class = $this->getEntityClass(); - - return new $class([], ['source' => $this->getRegistryAlias()]); - } - if (!isset($options['associated'])) { - $options['associated'] = $this->_associations->keys(); - } - $marshaller = $this->marshaller(); - - return $marshaller->one($data, $options); - } - - /** - * {@inheritDoc} - * - * By default all the associations on this table will be hydrated. You can - * limit which associations are built, or include deeper associations - * using the options parameter: - * - * ``` - * $articles = $this->Articles->newEntities( - * $this->request->getData(), - * ['associated' => ['Tags', 'Comments.Users']] - * ); - * ``` - * - * You can limit fields that will be present in the constructed entities by - * passing the `fieldList` option, which is also accepted for associations: - * - * ``` - * $articles = $this->Articles->newEntities($this->request->getData(), [ - * 'fieldList' => ['title', 'body', 'tags', 'comments'], - * 'associated' => ['Tags', 'Comments.Users' => ['fieldList' => 'username']] - * ] - * ); - * ``` - * - * You can use the `Model.beforeMarshal` event to modify request data - * before it is converted into entities. - */ - public function newEntities(array $data, array $options = []) - { - if (!isset($options['associated'])) { - $options['associated'] = $this->_associations->keys(); - } - $marshaller = $this->marshaller(); - - return $marshaller->many($data, $options); - } - - /** - * {@inheritDoc} - * - * When merging HasMany or BelongsToMany associations, all the entities in the - * `$data` array will appear, those that can be matched by primary key will get - * the data merged, but those that cannot, will be discarded. - * - * You can limit fields that will be present in the merged entity by - * passing the `fieldList` option, which is also accepted for associations: - * - * ``` - * $article = $this->Articles->patchEntity($article, $this->request->getData(), [ - * 'fieldList' => ['title', 'body', 'tags', 'comments'], - * 'associated' => ['Tags', 'Comments.Users' => ['fieldList' => 'username']] - * ] - * ); - * ``` - * - * By default, the data is validated before being passed to the entity. In - * the case of invalid fields, those will not be assigned to the entity. - * The `validate` option can be used to disable validation on the passed data: - * - * ``` - * $article = $this->patchEntity($article, $this->request->getData(),[ - * 'validate' => false - * ]); - * ``` - * - * You can use the `Model.beforeMarshal` event to modify request data - * before it is converted into entities. - * - * When patching scalar values (null/booleans/string/integer/float), if the property - * presently has an identical value, the setter will not be called, and the - * property will not be marked as dirty. This is an optimization to prevent unnecessary field - * updates when persisting entities. - */ - public function patchEntity(EntityInterface $entity, array $data, array $options = []) - { - if (!isset($options['associated'])) { - $options['associated'] = $this->_associations->keys(); - } - $marshaller = $this->marshaller(); - - return $marshaller->merge($entity, $data, $options); - } - - /** - * {@inheritDoc} - * - * Those entries in `$entities` that cannot be matched to any record in - * `$data` will be discarded. Records in `$data` that could not be matched will - * be marshalled as a new entity. - * - * When merging HasMany or BelongsToMany associations, all the entities in the - * `$data` array will appear, those that can be matched by primary key will get - * the data merged, but those that cannot, will be discarded. - * - * You can limit fields that will be present in the merged entities by - * passing the `fieldList` option, which is also accepted for associations: - * - * ``` - * $articles = $this->Articles->patchEntities($articles, $this->request->getData(), [ - * 'fieldList' => ['title', 'body', 'tags', 'comments'], - * 'associated' => ['Tags', 'Comments.Users' => ['fieldList' => 'username']] - * ] - * ); - * ``` - * - * You can use the `Model.beforeMarshal` event to modify request data - * before it is converted into entities. - */ - public function patchEntities($entities, array $data, array $options = []) - { - if (!isset($options['associated'])) { - $options['associated'] = $this->_associations->keys(); - } - $marshaller = $this->marshaller(); - - return $marshaller->mergeMany($entities, $data, $options); - } - - /** - * Validator method used to check the uniqueness of a value for a column. - * This is meant to be used with the validation API and not to be called - * directly. - * - * ### Example: - * - * ``` - * $validator->add('email', [ - * 'unique' => ['rule' => 'validateUnique', 'provider' => 'table'] - * ]) - * ``` - * - * Unique validation can be scoped to the value of another column: - * - * ``` - * $validator->add('email', [ - * 'unique' => [ - * 'rule' => ['validateUnique', ['scope' => 'site_id']], - * 'provider' => 'table' - * ] - * ]); - * ``` - * - * In the above example, the email uniqueness will be scoped to only rows having - * the same site_id. Scoping will only be used if the scoping field is present in - * the data to be validated. - * - * @param mixed $value The value of column to be checked for uniqueness. - * @param array $options The options array, optionally containing the 'scope' key. - * May also be the validation context, if there are no options. - * @param array|null $context Either the validation context or null. - * @return bool True if the value is unique, or false if a non-scalar, non-unique value was given. - */ - public function validateUnique($value, array $options, array $context = null) - { - if ($context === null) { - $context = $options; - } - $entity = new Entity( - $context['data'], - [ - 'useSetters' => false, - 'markNew' => $context['newRecord'], - 'source' => $this->getRegistryAlias() - ] - ); - $fields = array_merge( - [$context['field']], - isset($options['scope']) ? (array)$options['scope'] : [] - ); - $values = $entity->extract($fields); - foreach ($values as $field) { - if ($field !== null && !is_scalar($field)) { - return false; - } - } - $rule = new IsUnique($fields, $options); - - return $rule($entity, ['repository' => $this]); - } - - /** - * Get the Model callbacks this table is interested in. - * - * By implementing the conventional methods a table class is assumed - * to be interested in the related event. - * - * Override this method if you need to add non-conventional event listeners. - * Or if you want you table to listen to non-standard events. - * - * The conventional method map is: - * - * - Model.beforeMarshal => beforeMarshal - * - Model.buildValidator => buildValidator - * - Model.beforeFind => beforeFind - * - Model.beforeSave => beforeSave - * - Model.afterSave => afterSave - * - Model.afterSaveCommit => afterSaveCommit - * - Model.beforeDelete => beforeDelete - * - Model.afterDelete => afterDelete - * - Model.afterDeleteCommit => afterDeleteCommit - * - Model.beforeRules => beforeRules - * - Model.afterRules => afterRules - * - * @return array - */ - public function implementedEvents() - { - $eventMap = [ - 'Model.beforeMarshal' => 'beforeMarshal', - 'Model.buildValidator' => 'buildValidator', - 'Model.beforeFind' => 'beforeFind', - 'Model.beforeSave' => 'beforeSave', - 'Model.afterSave' => 'afterSave', - 'Model.afterSaveCommit' => 'afterSaveCommit', - 'Model.beforeDelete' => 'beforeDelete', - 'Model.afterDelete' => 'afterDelete', - 'Model.afterDeleteCommit' => 'afterDeleteCommit', - 'Model.beforeRules' => 'beforeRules', - 'Model.afterRules' => 'afterRules', - ]; - $events = []; - - foreach ($eventMap as $event => $method) { - if (!method_exists($this, $method)) { - continue; - } - $events[$event] = $method; - } - - return $events; - } - - /** - * {@inheritDoc} - * - * @param \Cake\ORM\RulesChecker $rules The rules object to be modified. - * @return \Cake\ORM\RulesChecker - */ - public function buildRules(RulesChecker $rules) - { - return $rules; - } - - /** - * Gets a SaveOptionsBuilder instance. - * - * @param array $options Options to parse by the builder. - * @return \Cake\ORM\SaveOptionsBuilder - */ - public function getSaveOptionsBuilder(array $options = []) - { - return new SaveOptionsBuilder($this, $options); - } - - /** - * Loads the specified associations in the passed entity or list of entities - * by executing extra queries in the database and merging the results in the - * appropriate properties. - * - * ### Example: - * - * ``` - * $user = $usersTable->get(1); - * $user = $usersTable->loadInto($user, ['Articles.Tags', 'Articles.Comments']); - * echo $user->articles[0]->title; - * ``` - * - * You can also load associations for multiple entities at once - * - * ### Example: - * - * ``` - * $users = $usersTable->find()->where([...])->toList(); - * $users = $usersTable->loadInto($users, ['Articles.Tags', 'Articles.Comments']); - * echo $user[1]->articles[0]->title; - * ``` - * - * The properties for the associations to be loaded will be overwritten on each entity. - * - * @param \Cake\Datasource\EntityInterface|array $entities a single entity or list of entities - * @param array $contain A `contain()` compatible array. - * @see \Cake\ORM\Query::contain() - * @return \Cake\Datasource\EntityInterface|array - */ - public function loadInto($entities, array $contain) - { - return (new LazyEagerLoader)->loadInto($entities, $contain, $this); - } - - /** - * {@inheritDoc} - */ - protected function validationMethodExists($method) - { - return method_exists($this, $method) || $this->behaviors()->hasMethod($method); - } - - /** - * Returns an array that can be used to describe the internal state of this - * object. - * - * @return array - */ - public function __debugInfo() - { - $conn = $this->getConnection(); - $associations = $this->_associations; - $behaviors = $this->_behaviors; - - return [ - 'registryAlias' => $this->getRegistryAlias(), - 'table' => $this->getTable(), - 'alias' => $this->getAlias(), - 'entityClass' => $this->getEntityClass(), - 'associations' => $associations ? $associations->keys() : false, - 'behaviors' => $behaviors ? $behaviors->loaded() : false, - 'defaultConnection' => static::defaultConnectionName(), - 'connectionName' => $conn ? $conn->configName() : null - ]; - } -} diff --git a/vendor/cakephp/cakephp/src/ORM/TableRegistry.php b/vendor/cakephp/cakephp/src/ORM/TableRegistry.php deleted file mode 100644 index 5c95268..0000000 --- a/vendor/cakephp/cakephp/src/ORM/TableRegistry.php +++ /dev/null @@ -1,210 +0,0 @@ - 'my_users']); - * ``` - * - * Configuration data is stored *per alias* if you use the same table with - * multiple aliases you will need to set configuration multiple times. - * - * ### Getting instances - * - * You can fetch instances out of the registry using get(). One instance is stored - * per alias. Once an alias is populated the same instance will always be returned. - * This is used to make the ORM use less memory and help make cyclic references easier - * to solve. - * - * ``` - * $table = TableRegistry::get('Users', $config); - * ``` - */ -class TableRegistry -{ - - /** - * LocatorInterface implementation instance. - * - * @var \Cake\ORM\Locator\LocatorInterface - */ - protected static $_locator; - - /** - * Default LocatorInterface implementation class. - * - * @var string - */ - protected static $_defaultLocatorClass = 'Cake\ORM\Locator\TableLocator'; - - /** - * Sets and returns a singleton instance of LocatorInterface implementation. - * - * @param \Cake\ORM\Locator\LocatorInterface|null $locator Instance of a locator to use. - * @return \Cake\ORM\Locator\LocatorInterface - * @deprecated 3.5.0 Use getTableLocator()/setTableLocator() instead. - */ - public static function locator(LocatorInterface $locator = null) - { - deprecationWarning( - 'TableRegistry::locator() is deprecated. ' . - 'Use setTableLocator()/getTableLocator() instead.' - ); - if ($locator) { - static::setTableLocator($locator); - } - - return static::getTableLocator(); - } - - /** - * Returns a singleton instance of LocatorInterface implementation. - * - * @return \Cake\ORM\Locator\LocatorInterface - */ - public static function getTableLocator() - { - if (!static::$_locator) { - static::$_locator = new static::$_defaultLocatorClass(); - } - - return static::$_locator; - } - - /** - * Sets singleton instance of LocatorInterface implementation. - * - * @param \Cake\ORM\Locator\LocatorInterface $tableLocator Instance of a locator to use. - * @return void - */ - public static function setTableLocator(LocatorInterface $tableLocator) - { - static::$_locator = $tableLocator; - } - - /** - * Stores a list of options to be used when instantiating an object - * with a matching alias. - * - * @param string|null $alias Name of the alias - * @param array|null $options list of options for the alias - * @return array The config data. - * @deprecated 3.6.0 Use \Cake\ORM\Locator\TableLocator::getConfig()/setConfig() instead. - */ - public static function config($alias = null, $options = null) - { - deprecationWarning( - 'TableRegistry::config() is deprecated. ' . - 'Use \Cake\ORM\Locator\TableLocator::getConfig()/setConfig() instead.' - ); - - return static::getTableLocator()->config($alias, $options); - } - - /** - * Get a table instance from the registry. - * - * See options specification in {@link TableLocator::get()}. - * - * @param string $alias The alias name you want to get. - * @param array $options The options you want to build the table with. - * @return \Cake\ORM\Table - * @deprecated 3.6.0 Use \Cake\ORM\Locator\TableLocator::get() instead. - */ - public static function get($alias, array $options = []) - { - return static::getTableLocator()->get($alias, $options); - } - - /** - * Check to see if an instance exists in the registry. - * - * @param string $alias The alias to check for. - * @return bool - * @deprecated 3.6.0 Use \Cake\ORM\Locator\TableLocator::exists() instead. - */ - public static function exists($alias) - { - return static::getTableLocator()->exists($alias); - } - - /** - * Set an instance. - * - * @param string $alias The alias to set. - * @param \Cake\ORM\Table $object The table to set. - * @return \Cake\ORM\Table - * @deprecated 3.6.0 Use \Cake\ORM\Locator\TableLocator::set() instead. - */ - public static function set($alias, Table $object) - { - return static::getTableLocator()->set($alias, $object); - } - - /** - * Removes an instance from the registry. - * - * @param string $alias The alias to remove. - * @return void - * @deprecated 3.6.0 Use \Cake\ORM\Locator\TableLocator::remove() instead. - */ - public static function remove($alias) - { - static::getTableLocator()->remove($alias); - } - - /** - * Clears the registry of configuration and instances. - * - * @return void - * @deprecated 3.6.0 Use \Cake\ORM\Locator\TableLocator::clear() instead. - */ - public static function clear() - { - static::getTableLocator()->clear(); - } - - /** - * Proxy for static calls on a locator. - * - * @param string $name Method name. - * @param array $arguments Method arguments. - * @return mixed - */ - public static function __callStatic($name, $arguments) - { - deprecationWarning( - 'TableRegistry::' . $name . '() is deprecated. ' . - 'Use \Cake\ORM\Locator\TableLocator::' . $name . '() instead.' - ); - - return static::getTableLocator()->$name(...$arguments); - } -} diff --git a/vendor/cakephp/cakephp/src/ORM/composer.json b/vendor/cakephp/cakephp/src/ORM/composer.json deleted file mode 100644 index 1432893..0000000 --- a/vendor/cakephp/cakephp/src/ORM/composer.json +++ /dev/null @@ -1,43 +0,0 @@ -{ - "name": "cakephp/orm", - "description": "CakePHP ORM - Provides a flexible and powerful ORM implementing a data-mapper pattern.", - "type": "library", - "keywords": [ - "cakephp", - "orm", - "data-mapper", - "data-mapper pattern" - ], - "homepage": "https://cakephp.org", - "license": "MIT", - "authors": [ - { - "name": "CakePHP Community", - "homepage": "https://github.com/cakephp/orm/graphs/contributors" - } - ], - "support": { - "issues": "https://github.com/cakephp/cakephp/issues", - "forum": "https://stackoverflow.com/tags/cakephp", - "irc": "irc://irc.freenode.org/cakephp", - "source": "https://github.com/cakephp/orm" - }, - "require": { - "php": ">=5.6.0", - "cakephp/collection": "^3.6.0", - "cakephp/core": "^3.6.0", - "cakephp/datasource": "^3.6.0", - "cakephp/database": "^3.6.0", - "cakephp/event": "^3.6.0", - "cakephp/utility": "^3.6.0", - "cakephp/validation": "^3.6.0" - }, - "suggest": { - "cakephp/i18n": "If you are using Translate / Timestamp Behavior." - }, - "autoload": { - "psr-4": { - "Cake\\ORM\\": "." - } - } -} diff --git a/vendor/cakephp/cakephp/src/Routing/Dispatcher.php b/vendor/cakephp/cakephp/src/Routing/Dispatcher.php deleted file mode 100644 index d1a3f2b..0000000 --- a/vendor/cakephp/cakephp/src/Routing/Dispatcher.php +++ /dev/null @@ -1,99 +0,0 @@ -getEventManager(), $this->_filters); - $response = $actionDispatcher->dispatch($request, $response); - if ($request->getParam('return', null) !== null) { - return $response->body(); - } - - return $response->send(); - } - - /** - * Add a filter to this dispatcher. - * - * The added filter will be attached to the event manager used - * by this dispatcher. - * - * @param \Cake\Event\EventListenerInterface $filter The filter to connect. Can be - * any EventListenerInterface. Typically an instance of \Cake\Routing\DispatcherFilter. - * @return void - */ - public function addFilter(EventListenerInterface $filter) - { - $this->_filters[] = $filter; - } - - /** - * Get the list of connected filters. - * - * @return \Cake\Event\EventListenerInterface[] - */ - public function filters() - { - return $this->_filters; - } -} diff --git a/vendor/cakephp/cakephp/src/Routing/DispatcherFactory.php b/vendor/cakephp/cakephp/src/Routing/DispatcherFactory.php deleted file mode 100644 index 91dc686..0000000 --- a/vendor/cakephp/cakephp/src/Routing/DispatcherFactory.php +++ /dev/null @@ -1,113 +0,0 @@ -addFilter($middleware); - } - - return $dispatcher; - } - - /** - * Get the connected dispatcher filters. - * - * @return \Cake\Routing\DispatcherFilter[] - */ - public static function filters() - { - return static::$_stack; - } - - /** - * Clear the middleware stack. - * - * @return void - */ - public static function clear() - { - static::$_stack = []; - } -} diff --git a/vendor/cakephp/cakephp/src/Routing/DispatcherFilter.php b/vendor/cakephp/cakephp/src/Routing/DispatcherFilter.php deleted file mode 100644 index 56ba8da..0000000 --- a/vendor/cakephp/cakephp/src/Routing/DispatcherFilter.php +++ /dev/null @@ -1,217 +0,0 @@ - '/blog']); - * ``` - * - * When the above filter is connected to a dispatcher it will only fire - * its `beforeDispatch` and `afterDispatch` methods on requests that start with `/blog`. - * - * The for condition can also be a regular expression by using the `preg:` prefix: - * - * ``` - * $filter = new BlogFilter(['for' => 'preg:#^/blog/\d+$#']); - * ``` - * - * ### Limiting filters based on conditions - * - * In addition to simple path based matching you can use a closure to match on arbitrary request - * or response conditions. For example: - * - * ``` - * $cookieMonster = new CookieFilter([ - * 'when' => function ($req, $res) { - * // Custom code goes here. - * } - * ]); - * ``` - * - * If your when condition returns `true` the before/after methods will be called. - * - * When using the `for` or `when` matchers, conditions will be re-checked on the before and after - * callback as the conditions could change during the dispatch cycle. - * - * @mixin \Cake\Core\InstanceConfigTrait - */ -class DispatcherFilter implements EventListenerInterface -{ - - use InstanceConfigTrait; - - /** - * Default priority for all methods in this filter - * - * @var int - */ - protected $_priority = 10; - - /** - * Default config - * - * These are merged with user-provided config when the class is used. - * The when and for options allow you to define conditions that are checked before - * your filter is called. - * - * @var array - */ - protected $_defaultConfig = [ - 'when' => null, - 'for' => null, - 'priority' => null, - ]; - - /** - * Constructor. - * - * @param array $config Settings for the filter. - * @throws \InvalidArgumentException When 'when' conditions are not callable. - */ - public function __construct($config = []) - { - if (!isset($config['priority'])) { - $config['priority'] = $this->_priority; - } - $this->setConfig($config); - if (isset($config['when']) && !is_callable($config['when'])) { - throw new InvalidArgumentException('"when" conditions must be a callable.'); - } - } - - /** - * Returns the list of events this filter listens to. - * Dispatcher notifies 2 different events `Dispatcher.before` and `Dispatcher.after`. - * By default this class will attach `preDispatch` and `postDispatch` method respectively. - * - * Override this method at will to only listen to the events you are interested in. - * - * @return array - */ - public function implementedEvents() - { - return [ - 'Dispatcher.beforeDispatch' => [ - 'callable' => 'handle', - 'priority' => $this->_config['priority'] - ], - 'Dispatcher.afterDispatch' => [ - 'callable' => 'handle', - 'priority' => $this->_config['priority'] - ], - ]; - } - - /** - * Handler method that applies conditions and resolves the correct method to call. - * - * @param \Cake\Event\Event $event The event instance. - * @return mixed - */ - public function handle(Event $event) - { - $name = $event->getName(); - list(, $method) = explode('.', $name); - if (empty($this->_config['for']) && empty($this->_config['when'])) { - return $this->{$method}($event); - } - if ($this->matches($event)) { - return $this->{$method}($event); - } - } - - /** - * Check to see if the incoming request matches this filter's criteria. - * - * @param \Cake\Event\Event $event The event to match. - * @return bool - */ - public function matches(Event $event) - { - /* @var \Cake\Http\ServerRequest $request */ - $request = $event->getData('request'); - $pass = true; - if (!empty($this->_config['for'])) { - $len = strlen('preg:'); - $for = $this->_config['for']; - $url = $request->getRequestTarget(); - if (substr($for, 0, $len) === 'preg:') { - $pass = (bool)preg_match(substr($for, $len), $url); - } else { - $pass = strpos($url, $for) === 0; - } - } - if ($pass && !empty($this->_config['when'])) { - $response = $event->getData('response'); - $pass = $this->_config['when']($request, $response); - } - - return $pass; - } - - /** - * Method called before the controller is instantiated and called to serve a request. - * If used with default priority, it will be called after the Router has parsed the - * URL and set the routing params into the request object. - * - * If a Cake\Http\Response object instance is returned, it will be served at the end of the - * event cycle, not calling any controller as a result. This will also have the effect of - * not calling the after event in the dispatcher. - * - * If false is returned, the event will be stopped and no more listeners will be notified. - * Alternatively you can call `$event->stopPropagation()` to achieve the same result. - * - * @param \Cake\Event\Event $event container object having the `request`, `response` and `additionalParams` - * keys in the data property. - * @return void - */ - public function beforeDispatch(Event $event) - { - } - - /** - * Method called after the controller served a request and generated a response. - * It is possible to alter the response object at this point as it is not sent to the - * client yet. - * - * If false is returned, the event will be stopped and no more listeners will be notified. - * Alternatively you can call `$event->stopPropagation()` to achieve the same result. - * - * @param \Cake\Event\Event $event container object having the `request` and `response` - * keys in the data property. - * @return void - */ - public function afterDispatch(Event $event) - { - } -} diff --git a/vendor/cakephp/cakephp/src/Routing/Exception/DuplicateNamedRouteException.php b/vendor/cakephp/cakephp/src/Routing/Exception/DuplicateNamedRouteException.php deleted file mode 100644 index 4fbcbe8..0000000 --- a/vendor/cakephp/cakephp/src/Routing/Exception/DuplicateNamedRouteException.php +++ /dev/null @@ -1,38 +0,0 @@ -_messageTemplate = $message['message']; - } - parent::__construct($message, $code, $previous); - } -} diff --git a/vendor/cakephp/cakephp/src/Routing/Exception/MissingControllerException.php b/vendor/cakephp/cakephp/src/Routing/Exception/MissingControllerException.php deleted file mode 100644 index 5bd79f4..0000000 --- a/vendor/cakephp/cakephp/src/Routing/Exception/MissingControllerException.php +++ /dev/null @@ -1,36 +0,0 @@ -_messageTemplate = $message['message']; - } elseif (isset($message['method']) && $message['method']) { - $this->_messageTemplate = $this->_messageTemplateWithMethod; - } - } - parent::__construct($message, $code, $previous); - } -} diff --git a/vendor/cakephp/cakephp/src/Routing/Exception/RedirectException.php b/vendor/cakephp/cakephp/src/Routing/Exception/RedirectException.php deleted file mode 100644 index 2a392b9..0000000 --- a/vendor/cakephp/cakephp/src/Routing/Exception/RedirectException.php +++ /dev/null @@ -1,36 +0,0 @@ -_cacheTime = $config['cacheTime']; - } - parent::__construct($config); - } - - /** - * Checks if a requested asset exists and sends it to the browser - * - * @param \Cake\Event\Event $event Event containing the request and response object - * @return \Cake\Http\Response|null If the client is requesting a recognized asset, null otherwise - * @throws \Cake\Http\Exception\NotFoundException When asset not found - */ - public function beforeDispatch(Event $event) - { - /* @var \Cake\Http\ServerRequest $request */ - $request = $event->getData('request'); - - $url = urldecode($request->getUri()->getPath()); - if (strpos($url, '..') !== false || strpos($url, '.') === false) { - return null; - } - - $assetFile = $this->_getAssetFile($url); - if ($assetFile === null || !file_exists($assetFile)) { - return null; - } - /* @var \Cake\Http\Response $response */ - $response = $event->getData('response'); - $event->stopPropagation(); - - $response = $response->withModified(filemtime($assetFile)); - if ($response->checkNotModified($request)) { - return $response; - } - - $pathSegments = explode('.', $url); - $ext = array_pop($pathSegments); - - return $this->_deliverAsset($request, $response, $assetFile, $ext); - } - - /** - * Builds asset file path based off url - * - * @param string $url Asset URL - * @return string Absolute path for asset file - */ - protected function _getAssetFile($url) - { - $parts = explode('/', ltrim($url, '/')); - $pluginPart = []; - for ($i = 0; $i < 2; $i++) { - if (!isset($parts[$i])) { - break; - } - $pluginPart[] = Inflector::camelize($parts[$i]); - $plugin = implode('/', $pluginPart); - if ($plugin && Plugin::loaded($plugin)) { - $parts = array_slice($parts, $i + 1); - $fileFragment = implode(DIRECTORY_SEPARATOR, $parts); - $pluginWebroot = Plugin::path($plugin) . 'webroot' . DIRECTORY_SEPARATOR; - - return $pluginWebroot . $fileFragment; - } - } - } - - /** - * Sends an asset file to the client - * - * @param \Cake\Http\ServerRequest $request The request object to use. - * @param \Cake\Http\Response $response The response object to use. - * @param string $assetFile Path to the asset file in the file system - * @param string $ext The extension of the file to determine its mime type - * @return \Cake\Http\Response The updated response. - */ - protected function _deliverAsset(ServerRequest $request, Response $response, $assetFile, $ext) - { - $compressionEnabled = $response->compress(); - if ($response->getType() === $ext) { - $contentType = 'application/octet-stream'; - $agent = $request->getEnv('HTTP_USER_AGENT'); - if (preg_match('%Opera(/| )([0-9].[0-9]{1,2})%', $agent) || preg_match('/MSIE ([0-9].[0-9]{1,2})/', $agent)) { - $contentType = 'application/octetstream'; - } - $response = $response->withType($contentType); - } - if (!$compressionEnabled) { - $response = $response->withHeader('Content-Length', filesize($assetFile)); - } - $response = $response->withCache(filemtime($assetFile), $this->_cacheTime) - ->withFile($assetFile); - - return $response; - } -} diff --git a/vendor/cakephp/cakephp/src/Routing/Filter/ControllerFactoryFilter.php b/vendor/cakephp/cakephp/src/Routing/Filter/ControllerFactoryFilter.php deleted file mode 100644 index 4aed907..0000000 --- a/vendor/cakephp/cakephp/src/Routing/Filter/ControllerFactoryFilter.php +++ /dev/null @@ -1,65 +0,0 @@ -getData('request'); - $response = $event->getData('response'); - $event->setData('controller', $this->_getController($request, $response)); - } - - /** - * Gets controller to use, either plugin or application controller. - * - * @param \Cake\Http\ServerRequest $request Request object - * @param \Cake\Http\Response $response Response for the controller. - * @return \Cake\Controller\Controller - */ - protected function _getController($request, $response) - { - $factory = new ControllerFactory(); - - return $factory->create($request, $response); - } -} diff --git a/vendor/cakephp/cakephp/src/Routing/Filter/LocaleSelectorFilter.php b/vendor/cakephp/cakephp/src/Routing/Filter/LocaleSelectorFilter.php deleted file mode 100644 index 63a9ada..0000000 --- a/vendor/cakephp/cakephp/src/Routing/Filter/LocaleSelectorFilter.php +++ /dev/null @@ -1,71 +0,0 @@ -_locales = $config['locales']; - } - } - - /** - * Inspects the request for the Accept-Language header and sets the - * Locale for the current runtime if it matches the list of valid locales - * as passed in the configuration. - * - * @param \Cake\Event\Event $event The event instance. - * @return void - */ - public function beforeDispatch(Event $event) - { - /* @var \Cake\Http\ServerRequest $request */ - $request = $event->getData('request'); - $locale = Locale::acceptFromHttp($request->getHeaderLine('Accept-Language')); - - if (!$locale || (!empty($this->_locales) && !in_array($locale, $this->_locales))) { - return; - } - - I18n::setLocale($locale); - } -} diff --git a/vendor/cakephp/cakephp/src/Routing/Filter/RoutingFilter.php b/vendor/cakephp/cakephp/src/Routing/Filter/RoutingFilter.php deleted file mode 100644 index ed9f378..0000000 --- a/vendor/cakephp/cakephp/src/Routing/Filter/RoutingFilter.php +++ /dev/null @@ -1,73 +0,0 @@ -getData('request'); - if (Router::getRequest(true) !== $request) { - Router::setRequestInfo($request); - } - - try { - if (!$request->getParam('controller')) { - $params = Router::parseRequest($request); - $request->addParams($params); - } - - return null; - } catch (RedirectException $e) { - $event->stopPropagation(); - /* @var \Cake\Http\Response $response */ - $response = $event->getData('response'); - $response = $response->withStatus($e->getCode()) - ->withLocation($e->getMessage()); - - return $response; - } - } -} diff --git a/vendor/cakephp/cakephp/src/Routing/Middleware/AssetMiddleware.php b/vendor/cakephp/cakephp/src/Routing/Middleware/AssetMiddleware.php deleted file mode 100644 index 50f8396..0000000 --- a/vendor/cakephp/cakephp/src/Routing/Middleware/AssetMiddleware.php +++ /dev/null @@ -1,197 +0,0 @@ - 'text/css', - 'json' => 'application/json', - 'js' => 'application/javascript', - 'ico' => 'image/x-icon', - 'eot' => 'application/vnd.ms-fontobject', - 'svg' => 'image/svg+xml', - 'html' => 'text/html', - 'rss' => 'application/rss+xml', - 'xml' => 'application/xml', - ]; - - /** - * Constructor. - * - * @param array $options The options to use - */ - public function __construct(array $options = []) - { - if (!empty($options['cacheTime'])) { - $this->cacheTime = $options['cacheTime']; - } - if (!empty($options['types'])) { - $this->typeMap = array_merge($this->typeMap, $options['types']); - } - } - - /** - * Serve assets if the path matches one. - * - * @param \Psr\Http\Message\ServerRequestInterface $request The request. - * @param \Psr\Http\Message\ResponseInterface $response The response. - * @param callable $next Callback to invoke the next middleware. - * @return \Psr\Http\Message\ResponseInterface A response - */ - public function __invoke($request, $response, $next) - { - $url = $request->getUri()->getPath(); - if (strpos($url, '..') !== false || strpos($url, '.') === false) { - return $next($request, $response); - } - - if (strpos($url, '/.') !== false) { - return $next($request, $response); - } - - $assetFile = $this->_getAssetFile($url); - if ($assetFile === null || !file_exists($assetFile)) { - return $next($request, $response); - } - - $file = new File($assetFile); - $modifiedTime = $file->lastChange(); - if ($this->isNotModified($request, $file)) { - $headers = $response->getHeaders(); - $headers['Last-Modified'] = date(DATE_RFC850, $modifiedTime); - - return new Response('php://memory', 304, $headers); - } - - return $this->deliverAsset($request, $response, $file); - } - - /** - * Check the not modified header. - * - * @param \Psr\Http\Message\ServerRequestInterface $request The request to check. - * @param \Cake\Filesystem\File $file The file object to compare. - * @return bool - */ - protected function isNotModified($request, $file) - { - $modifiedSince = $request->getHeaderLine('If-Modified-Since'); - if (!$modifiedSince) { - return false; - } - - return strtotime($modifiedSince) === $file->lastChange(); - } - - /** - * Builds asset file path based off url - * - * @param string $url Asset URL - * @return string Absolute path for asset file - */ - protected function _getAssetFile($url) - { - $parts = explode('/', ltrim($url, '/')); - $pluginPart = []; - for ($i = 0; $i < 2; $i++) { - if (!isset($parts[$i])) { - break; - } - $pluginPart[] = Inflector::camelize($parts[$i]); - $plugin = implode('/', $pluginPart); - if ($plugin && Plugin::loaded($plugin)) { - $parts = array_slice($parts, $i + 1); - $fileFragment = implode(DIRECTORY_SEPARATOR, $parts); - $pluginWebroot = Plugin::path($plugin) . 'webroot' . DIRECTORY_SEPARATOR; - - return $pluginWebroot . $fileFragment; - } - } - - return ''; - } - - /** - * Sends an asset file to the client - * - * @param \Psr\Http\Message\ServerRequestInterface $request The request object to use. - * @param \Psr\Http\Message\ResponseInterface $response The response object to use. - * @param \Cake\Filesystem\File $file The file wrapper for the file. - * @return \Psr\Http\Message\ResponseInterface The response with the file & headers. - */ - protected function deliverAsset(ServerRequestInterface $request, ResponseInterface $response, $file) - { - $contentType = $this->getType($file); - $modified = $file->lastChange(); - $expire = strtotime($this->cacheTime); - $maxAge = $expire - time(); - - $stream = new Stream(fopen($file->path, 'rb')); - - return $response->withBody($stream) - ->withHeader('Content-Type', $contentType) - ->withHeader('Cache-Control', 'public,max-age=' . $maxAge) - ->withHeader('Date', gmdate('D, j M Y G:i:s \G\M\T', time())) - ->withHeader('Last-Modified', gmdate('D, j M Y G:i:s \G\M\T', $modified)) - ->withHeader('Expires', gmdate('D, j M Y G:i:s \G\M\T', $expire)); - } - - /** - * Return the type from a File object - * - * @param File $file The file from which you get the type - * @return string - */ - protected function getType($file) - { - $extension = $file->ext(); - if (isset($this->typeMap[$extension])) { - return $this->typeMap[$extension]; - } - - return $file->mime() ?: 'application/octet-stream'; - } -} diff --git a/vendor/cakephp/cakephp/src/Routing/Middleware/RoutingMiddleware.php b/vendor/cakephp/cakephp/src/Routing/Middleware/RoutingMiddleware.php deleted file mode 100644 index 9db5377..0000000 --- a/vendor/cakephp/cakephp/src/Routing/Middleware/RoutingMiddleware.php +++ /dev/null @@ -1,166 +0,0 @@ -app = $app; - $this->cacheConfig = $cacheConfig; - } - - /** - * Trigger the application's routes() hook if the application exists and Router isn't initialized. - * Uses the routes cache if enabled via configuration param "Router.cache" - * - * If the middleware is created without an Application, routes will be - * loaded via the automatic route loading that pre-dates the routes() hook. - * - * @return void - */ - protected function loadRoutes() - { - if (!$this->app) { - return; - } - - $routeCollection = $this->buildRouteCollection(); - Router::setRouteCollection($routeCollection); - } - - /** - * Check if route cache is enabled and use the configured Cache to 'remember' the route collection - * - * @return \Cake\Routing\RouteCollection - */ - protected function buildRouteCollection() - { - if (Cache::enabled() && $this->cacheConfig !== null) { - return Cache::remember(static::ROUTE_COLLECTION_CACHE_KEY, function () { - return $this->prepareRouteCollection(); - }, $this->cacheConfig); - } - - return $this->prepareRouteCollection(); - } - - /** - * Generate the route collection using the builder - * - * @return \Cake\Routing\RouteCollection - */ - protected function prepareRouteCollection() - { - $builder = Router::createRouteBuilder('/'); - $this->app->routes($builder); - if ($this->app instanceof PluginApplicationInterface) { - $this->app->pluginRoutes($builder); - } - - return Router::getRouteCollection(); - } - - /** - * Apply routing and update the request. - * - * Any route/path specific middleware will be wrapped around $next and then the new middleware stack will be - * invoked. - * - * @param \Psr\Http\Message\ServerRequestInterface $request The request. - * @param \Psr\Http\Message\ResponseInterface $response The response. - * @param callable $next The next middleware to call. - * @return \Psr\Http\Message\ResponseInterface A response. - * @throws \Cake\Routing\InvalidArgumentException - */ - public function __invoke(ServerRequestInterface $request, ResponseInterface $response, $next) - { - $this->loadRoutes(); - try { - Router::setRequestContext($request); - $params = (array)$request->getAttribute('params', []); - $middleware = []; - if (empty($params['controller'])) { - $parsedBody = $request->getParsedBody(); - if (is_array($parsedBody) && isset($parsedBody['_method'])) { - $request = $request->withMethod($parsedBody['_method']); - } - $params = Router::parseRequest($request) + $params; - if (isset($params['_middleware'])) { - $middleware = $params['_middleware']; - unset($params['_middleware']); - } - $request = $request->withAttribute('params', $params); - } - } catch (RedirectException $e) { - return new RedirectResponse( - $e->getMessage(), - $e->getCode(), - $response->getHeaders() - ); - } - $matching = Router::getRouteCollection()->getMiddleware($middleware); - if (!$matching) { - return $next($request, $response); - } - $matching[] = $next; - $middleware = new MiddlewareQueue($matching); - $runner = new Runner(); - - return $runner->run($middleware, $request, $response); - } -} diff --git a/vendor/cakephp/cakephp/src/Routing/RequestActionTrait.php b/vendor/cakephp/cakephp/src/Routing/RequestActionTrait.php deleted file mode 100644 index 1cc2c2f..0000000 --- a/vendor/cakephp/cakephp/src/Routing/RequestActionTrait.php +++ /dev/null @@ -1,186 +0,0 @@ -requestAction('/articles/popular'); - * ``` - * - * A basic example of request action to fetch a rendered page without the layout. - * - * ``` - * $viewHtml = $this->requestAction('/articles/popular', ['return']); - * ``` - * - * You can also pass the URL as an array: - * - * ``` - * $vars = $this->requestAction(['controller' => 'articles', 'action' => 'popular']); - * ``` - * - * ### Passing other request data - * - * You can pass POST, GET, COOKIE and other data into the request using the appropriate keys. - * Cookies can be passed using the `cookies` key. Get parameters can be set with `query` and post - * data can be sent using the `post` key. - * - * ``` - * $vars = $this->requestAction('/articles/popular', [ - * 'query' => ['page' => 1], - * 'cookies' => ['remember_me' => 1], - * ]); - * ``` - * - * ### Sending environment or header values - * - * By default actions dispatched with this method will use the global $_SERVER and $_ENV - * values. If you want to override those values for a request action, you can specify the values: - * - * ``` - * $vars = $this->requestAction('/articles/popular', [ - * 'environment' => ['CONTENT_TYPE' => 'application/json'] - * ]); - * ``` - * - * ### Transmitting the session - * - * By default actions dispatched with this method will use the standard session object. - * If you want a particular session instance to be used, you need to specify it. - * - * ``` - * $vars = $this->requestAction('/articles/popular', [ - * 'session' => new Session($someSessionConfig) - * ]); - * ``` - * - * @param string|array $url String or array-based url. Unlike other url arrays in CakePHP, this - * url will not automatically handle passed arguments in the $url parameter. - * @param array $extra if array includes the key "return" it sets the autoRender to true. Can - * also be used to submit GET/POST data, and passed arguments. - * @return mixed Boolean true or false on success/failure, or contents - * of rendered action if 'return' is set in $extra. - * @deprecated 3.3.0 You should refactor your code to use View Cells instead of this method. - */ - public function requestAction($url, array $extra = []) - { - deprecationWarning( - 'RequestActionTrait::requestAction() is deprecated. ' . - 'You should refactor to use View Cells or Components instead.' - ); - if (empty($url)) { - return false; - } - if (($index = array_search('return', $extra)) !== false) { - $extra['return'] = 0; - $extra['autoRender'] = 1; - unset($extra[$index]); - } - $extra += ['autoRender' => 0, 'return' => 1, 'bare' => 1, 'requested' => 1]; - - $baseUrl = Configure::read('App.fullBaseUrl'); - if (is_string($url) && strpos($url, $baseUrl) === 0) { - $url = Router::normalize(str_replace($baseUrl, '', $url)); - } - if (is_string($url)) { - $params = [ - 'url' => $url - ]; - } elseif (is_array($url)) { - $defaultParams = ['plugin' => null, 'controller' => null, 'action' => null]; - $params = [ - 'params' => $url + $defaultParams, - 'base' => false, - 'url' => Router::reverse($url) - ]; - if (empty($params['params']['pass'])) { - $params['params']['pass'] = []; - } - } - $current = Router::getRequest(); - if ($current) { - $params['base'] = $current->getAttribute('base'); - $params['webroot'] = $current->getAttribute('webroot'); - } - - $params['post'] = $params['query'] = []; - if (isset($extra['post'])) { - $params['post'] = $extra['post']; - } - if (isset($extra['query'])) { - $params['query'] = $extra['query']; - } - if (isset($extra['cookies'])) { - $params['cookies'] = $extra['cookies']; - } - if (isset($extra['environment'])) { - $params['environment'] = $extra['environment'] + $_SERVER + $_ENV; - } - unset($extra['environment'], $extra['post'], $extra['query']); - - $params['session'] = isset($extra['session']) ? $extra['session'] : new Session(); - - $request = new ServerRequest($params); - $request->addParams($extra); - $dispatcher = DispatcherFactory::create(); - - // If an application is using PSR7 middleware, - // we need to 'fix' their missing dispatcher filters. - $needed = [ - 'routing' => RoutingFilter::class, - 'controller' => ControllerFactoryFilter::class - ]; - foreach ($dispatcher->filters() as $filter) { - if ($filter instanceof RoutingFilter) { - unset($needed['routing']); - } - if ($filter instanceof ControllerFactoryFilter) { - unset($needed['controller']); - } - } - foreach ($needed as $class) { - $dispatcher->addFilter(new $class); - } - $result = $dispatcher->dispatch($request, new Response()); - Router::popRequest(); - - return $result; - } -} diff --git a/vendor/cakephp/cakephp/src/Routing/Route/DashedRoute.php b/vendor/cakephp/cakephp/src/Routing/Route/DashedRoute.php deleted file mode 100644 index 71ff7f4..0000000 --- a/vendor/cakephp/cakephp/src/Routing/Route/DashedRoute.php +++ /dev/null @@ -1,123 +0,0 @@ - 'MyPlugin', 'controller' => 'MyController', 'action' => 'myAction']` - */ -class DashedRoute extends Route -{ - - /** - * Flag for tracking whether or not the defaults have been inflected. - * - * Default values need to be inflected so that they match the inflections that - * match() will create. - * - * @var bool - */ - protected $_inflectedDefaults = false; - - /** - * Camelizes the previously dashed plugin route taking into account plugin vendors - * - * @param string $plugin Plugin name - * @return string - */ - protected function _camelizePlugin($plugin) - { - $plugin = str_replace('-', '_', $plugin); - if (strpos($plugin, '/') === false) { - return Inflector::camelize($plugin); - } - list($vendor, $plugin) = explode('/', $plugin, 2); - - return Inflector::camelize($vendor) . '/' . Inflector::camelize($plugin); - } - - /** - * Parses a string URL into an array. If it matches, it will convert the - * controller and plugin keys to their CamelCased form and action key to - * camelBacked form. - * - * @param string $url The URL to parse - * @param string $method The HTTP method. - * @return array|false An array of request parameters, or false on failure. - */ - public function parse($url, $method = '') - { - $params = parent::parse($url, $method); - if (!$params) { - return false; - } - if (!empty($params['controller'])) { - $params['controller'] = Inflector::camelize($params['controller'], '-'); - } - if (!empty($params['plugin'])) { - $params['plugin'] = $this->_camelizePlugin($params['plugin']); - } - if (!empty($params['action'])) { - $params['action'] = Inflector::variable(str_replace( - '-', - '_', - $params['action'] - )); - } - - return $params; - } - - /** - * Dasherizes the controller, action and plugin params before passing them on - * to the parent class. - * - * @param array $url Array of parameters to convert to a string. - * @param array $context An array of the current request context. - * Contains information such as the current host, scheme, port, and base - * directory. - * @return bool|string Either false or a string URL. - */ - public function match(array $url, array $context = []) - { - $url = $this->_dasherize($url); - if (!$this->_inflectedDefaults) { - $this->_inflectedDefaults = true; - $this->defaults = $this->_dasherize($this->defaults); - } - - return parent::match($url, $context); - } - - /** - * Helper method for dasherizing keys in a URL array. - * - * @param array $url An array of URL keys. - * @return array - */ - protected function _dasherize($url) - { - foreach (['controller', 'plugin', 'action'] as $element) { - if (!empty($url[$element])) { - $url[$element] = Inflector::dasherize($url[$element]); - } - } - - return $url; - } -} diff --git a/vendor/cakephp/cakephp/src/Routing/Route/InflectedRoute.php b/vendor/cakephp/cakephp/src/Routing/Route/InflectedRoute.php deleted file mode 100644 index face5d1..0000000 --- a/vendor/cakephp/cakephp/src/Routing/Route/InflectedRoute.php +++ /dev/null @@ -1,103 +0,0 @@ - 'MyController']` - */ -class InflectedRoute extends Route -{ - - /** - * Flag for tracking whether or not the defaults have been inflected. - * - * Default values need to be inflected so that they match the inflections that match() - * will create. - * - * @var bool - */ - protected $_inflectedDefaults = false; - - /** - * Parses a string URL into an array. If it matches, it will convert the prefix, controller and - * plugin keys to their camelized form. - * - * @param string $url The URL to parse - * @param string $method The HTTP method being matched. - * @return array|false An array of request parameters, or false on failure. - */ - public function parse($url, $method = '') - { - $params = parent::parse($url, $method); - if (!$params) { - return false; - } - if (!empty($params['controller'])) { - $params['controller'] = Inflector::camelize($params['controller']); - } - if (!empty($params['plugin'])) { - if (strpos($params['plugin'], '/') === false) { - $params['plugin'] = Inflector::camelize($params['plugin']); - } else { - list($vendor, $plugin) = explode('/', $params['plugin'], 2); - $params['plugin'] = Inflector::camelize($vendor) . '/' . Inflector::camelize($plugin); - } - } - - return $params; - } - - /** - * Underscores the prefix, controller and plugin params before passing them on to the - * parent class - * - * @param array $url Array of parameters to convert to a string. - * @param array $context An array of the current request context. - * Contains information such as the current host, scheme, port, and base - * directory. - * @return string|false Either a string URL for the parameters if they match or false. - */ - public function match(array $url, array $context = []) - { - $url = $this->_underscore($url); - if (!$this->_inflectedDefaults) { - $this->_inflectedDefaults = true; - $this->defaults = $this->_underscore($this->defaults); - } - - return parent::match($url, $context); - } - - /** - * Helper method for underscoring keys in a URL array. - * - * @param array $url An array of URL keys. - * @return array - */ - protected function _underscore($url) - { - if (!empty($url['controller'])) { - $url['controller'] = Inflector::underscore($url['controller']); - } - if (!empty($url['plugin'])) { - $url['plugin'] = Inflector::underscore($url['plugin']); - } - - return $url; - } -} diff --git a/vendor/cakephp/cakephp/src/Routing/Route/PluginShortRoute.php b/vendor/cakephp/cakephp/src/Routing/Route/PluginShortRoute.php deleted file mode 100644 index 2e7cf7d..0000000 --- a/vendor/cakephp/cakephp/src/Routing/Route/PluginShortRoute.php +++ /dev/null @@ -1,64 +0,0 @@ -defaults['controller'] = $url['controller']; - $result = parent::match($url, $context); - unset($this->defaults['controller']); - - return $result; - } -} diff --git a/vendor/cakephp/cakephp/src/Routing/Route/RedirectRoute.php b/vendor/cakephp/cakephp/src/Routing/Route/RedirectRoute.php deleted file mode 100644 index 170c56f..0000000 --- a/vendor/cakephp/cakephp/src/Routing/Route/RedirectRoute.php +++ /dev/null @@ -1,111 +0,0 @@ -redirect = (array)$defaults; - } - - /** - * Parses a string URL into an array. Parsed URLs will result in an automatic - * redirection. - * - * @param string $url The URL to parse. - * @param string $method The HTTP method being used. - * @return bool|null False on failure. An exception is raised on a successful match. - * @throws \Cake\Routing\Exception\RedirectException An exception is raised on successful match. - * This is used to halt route matching and signal to the middleware that a redirect should happen. - */ - public function parse($url, $method = '') - { - $params = parent::parse($url, $method); - if (!$params) { - return false; - } - $redirect = $this->redirect; - if (count($this->redirect) === 1 && !isset($this->redirect['controller'])) { - $redirect = $this->redirect[0]; - } - if (isset($this->options['persist']) && is_array($redirect)) { - $redirect += ['pass' => $params['pass'], 'url' => []]; - if (is_array($this->options['persist'])) { - foreach ($this->options['persist'] as $elem) { - if (isset($params[$elem])) { - $redirect[$elem] = $params[$elem]; - } - } - } - $redirect = Router::reverse($redirect); - } - $status = 301; - if (isset($this->options['status']) && ($this->options['status'] >= 300 && $this->options['status'] < 400)) { - $status = $this->options['status']; - } - throw new RedirectException(Router::url($redirect, true), $status); - } - - /** - * There is no reverse routing redirection routes. - * - * @param array $url Array of parameters to convert to a string. - * @param array $context Array of request context parameters. - * @return bool Always false. - */ - public function match(array $url, array $context = []) - { - return false; - } -} diff --git a/vendor/cakephp/cakephp/src/Routing/Route/Route.php b/vendor/cakephp/cakephp/src/Routing/Route/Route.php deleted file mode 100644 index f51feb6..0000000 --- a/vendor/cakephp/cakephp/src/Routing/Route/Route.php +++ /dev/null @@ -1,923 +0,0 @@ -template = $template; - if (isset($defaults['[method]'])) { - deprecationWarning('The `[method]` option is deprecated. Use `_method` instead.'); - $defaults['_method'] = $defaults['[method]']; - unset($defaults['[method]']); - } - $this->defaults = (array)$defaults; - $this->options = $options + ['_ext' => [], '_middleware' => []]; - $this->setExtensions((array)$this->options['_ext']); - $this->setMiddleware((array)$this->options['_middleware']); - unset($this->options['_middleware']); - } - - /** - * Get/Set the supported extensions for this route. - * - * @deprecated 3.3.9 Use getExtensions/setExtensions instead. - * @param null|string|array $extensions The extensions to set. Use null to get. - * @return array|null The extensions or null. - */ - public function extensions($extensions = null) - { - deprecationWarning( - 'Route::extensions() is deprecated. ' . - 'Use Route::setExtensions()/getExtensions() instead.' - ); - if ($extensions === null) { - return $this->_extensions; - } - $this->_extensions = (array)$extensions; - } - - /** - * Set the supported extensions for this route. - * - * @param array $extensions The extensions to set. - * @return $this - */ - public function setExtensions(array $extensions) - { - $this->_extensions = []; - foreach ($extensions as $ext) { - $this->_extensions[] = strtolower($ext); - } - - return $this; - } - - /** - * Get the supported extensions for this route. - * - * @return array - */ - public function getExtensions() - { - return $this->_extensions; - } - - /** - * Set the accepted HTTP methods for this route. - * - * @param array $methods The HTTP methods to accept. - * @return $this - * @throws \InvalidArgumentException - */ - public function setMethods(array $methods) - { - $methods = array_map('strtoupper', $methods); - $diff = array_diff($methods, static::VALID_METHODS); - if ($diff !== []) { - throw new InvalidArgumentException( - sprintf('Invalid HTTP method received. %s is invalid.', implode(', ', $diff)) - ); - } - $this->defaults['_method'] = $methods; - - return $this; - } - - /** - * Set regexp patterns for routing parameters - * - * If any of your patterns contain multibyte values, the `multibytePattern` - * mode will be enabled. - * - * @param array $patterns The patterns to apply to routing elements - * @return $this - */ - public function setPatterns(array $patterns) - { - $patternValues = implode("", $patterns); - if (mb_strlen($patternValues) < strlen($patternValues)) { - $this->options['multibytePattern'] = true; - } - $this->options = array_merge($this->options, $patterns); - - return $this; - } - - /** - * Set host requirement - * - * @param string $host The host name this route is bound to - * @return $this - */ - public function setHost($host) - { - $this->options['_host'] = $host; - - return $this; - } - - /** - * Set the names of parameters that will be converted into passed parameters - * - * @param array $names The names of the parameters that should be passed. - * @return $this - */ - public function setPass(array $names) - { - $this->options['pass'] = $names; - - return $this; - } - - /** - * Set the names of parameters that will persisted automatically - * - * Persistent parametesr allow you to define which route parameters should be automatically - * included when generating new URLs. You can override persistent parameters - * by redefining them in a URL or remove them by setting the persistent parameter to `false`. - * - * ``` - * // remove a persistent 'date' parameter - * Router::url(['date' => false', ...]); - * ``` - * - * @param array $names The names of the parameters that should be passed. - * @return $this - */ - public function setPersist(array $names) - { - $this->options['persist'] = $names; - - return $this; - } - - /** - * Check if a Route has been compiled into a regular expression. - * - * @return bool - */ - public function compiled() - { - return !empty($this->_compiledRoute); - } - - /** - * Compiles the route's regular expression. - * - * Modifies defaults property so all necessary keys are set - * and populates $this->names with the named routing elements. - * - * @return string Returns a string regular expression of the compiled route. - */ - public function compile() - { - if ($this->_compiledRoute) { - return $this->_compiledRoute; - } - $this->_writeRoute(); - - return $this->_compiledRoute; - } - - /** - * Builds a route regular expression. - * - * Uses the template, defaults and options properties to compile a - * regular expression that can be used to parse request strings. - * - * @return void - */ - protected function _writeRoute() - { - if (empty($this->template) || ($this->template === '/')) { - $this->_compiledRoute = '#^/*$#'; - $this->keys = []; - - return; - } - $route = $this->template; - $names = $routeParams = []; - $parsed = preg_quote($this->template, '#'); - - if (strpos($route, '{') !== false && strpos($route, '}') !== false) { - preg_match_all('/\{([a-z][a-z0-9-_]*)\}/i', $route, $namedElements); - $this->braceKeys = true; - } else { - preg_match_all('/:([a-z0-9-_]+(?braceKeys = false; - } - foreach ($namedElements[1] as $i => $name) { - $search = preg_quote($namedElements[0][$i]); - if (isset($this->options[$name])) { - $option = null; - if ($name !== 'plugin' && array_key_exists($name, $this->defaults)) { - $option = '?'; - } - $slashParam = '/' . $search; - if (strpos($parsed, $slashParam) !== false) { - $routeParams[$slashParam] = '(?:/(?P<' . $name . '>' . $this->options[$name] . ')' . $option . ')' . $option; - } else { - $routeParams[$search] = '(?:(?P<' . $name . '>' . $this->options[$name] . ')' . $option . ')' . $option; - } - } else { - $routeParams[$search] = '(?:(?P<' . $name . '>[^/]+))'; - } - $names[] = $name; - } - if (preg_match('#\/\*\*$#', $route)) { - $parsed = preg_replace('#/\\\\\*\\\\\*$#', '(?:/(?P<_trailing_>.*))?', $parsed); - $this->_greedy = true; - } - if (preg_match('#\/\*$#', $route)) { - $parsed = preg_replace('#/\\\\\*$#', '(?:/(?P<_args_>.*))?', $parsed); - $this->_greedy = true; - } - $mode = ''; - if (!empty($this->options['multibytePattern'])) { - $mode = 'u'; - } - krsort($routeParams); - $parsed = str_replace(array_keys($routeParams), array_values($routeParams), $parsed); - $this->_compiledRoute = '#^' . $parsed . '[/]*$#' . $mode; - $this->keys = $names; - - // Remove defaults that are also keys. They can cause match failures - foreach ($this->keys as $key) { - unset($this->defaults[$key]); - } - - $keys = $this->keys; - sort($keys); - $this->keys = array_reverse($keys); - } - - /** - * Get the standardized plugin.controller:action name for a route. - * - * @return string - */ - public function getName() - { - if (!empty($this->_name)) { - return $this->_name; - } - $name = ''; - $keys = [ - 'prefix' => ':', - 'plugin' => '.', - 'controller' => ':', - 'action' => '' - ]; - foreach ($keys as $key => $glue) { - $value = null; - if (strpos($this->template, ':' . $key) !== false) { - $value = '_' . $key; - } elseif (isset($this->defaults[$key])) { - $value = $this->defaults[$key]; - } - - if ($value === null) { - continue; - } - if ($value === true || $value === false) { - $value = $value ? '1' : '0'; - } - $name .= $value . $glue; - } - - return $this->_name = strtolower($name); - } - - /** - * Checks to see if the given URL can be parsed by this route. - * - * If the route can be parsed an array of parameters will be returned; if not - * false will be returned. - * - * @param \Psr\Http\Message\ServerRequestInterface $request The URL to attempt to parse. - * @return array|false An array of request parameters, or false on failure. - */ - public function parseRequest(ServerRequestInterface $request) - { - $uri = $request->getUri(); - if (isset($this->options['_host']) && !$this->hostMatches($uri->getHost())) { - return false; - } - - return $this->parse($uri->getPath(), $request->getMethod()); - } - - /** - * Checks to see if the given URL can be parsed by this route. - * - * If the route can be parsed an array of parameters will be returned; if not - * false will be returned. String URLs are parsed if they match a routes regular expression. - * - * @param string $url The URL to attempt to parse. - * @param string $method The HTTP method of the request being parsed. - * @return array|false An array of request parameters, or false on failure. - * @deprecated 3.4.0 Use/implement parseRequest() instead as it provides more flexibility/control. - */ - public function parse($url, $method = '') - { - if (empty($this->_compiledRoute)) { - $this->compile(); - } - list($url, $ext) = $this->_parseExtension($url); - - if (!preg_match($this->_compiledRoute, urldecode($url), $route)) { - return false; - } - - if (isset($this->defaults['_method'])) { - if (empty($method)) { - deprecationWarning( - 'Extracting the request method from global state when parsing routes is deprecated. ' . - 'Instead adopt Route::parseRequest() which extracts the method from the passed request.' - ); - // Deprecated reading the global state is deprecated and will be removed in 4.x - $request = Router::getRequest(true) ?: ServerRequestFactory::fromGlobals(); - $method = $request->getMethod(); - } - if (!in_array($method, (array)$this->defaults['_method'], true)) { - return false; - } - } - - array_shift($route); - $count = count($this->keys); - for ($i = 0; $i <= $count; $i++) { - unset($route[$i]); - } - $route['pass'] = []; - - // Assign defaults, set passed args to pass - foreach ($this->defaults as $key => $value) { - if (isset($route[$key])) { - continue; - } - if (is_int($key)) { - $route['pass'][] = $value; - continue; - } - $route[$key] = $value; - } - - if (isset($route['_args_'])) { - $pass = $this->_parseArgs($route['_args_'], $route); - $route['pass'] = array_merge($route['pass'], $pass); - unset($route['_args_']); - } - - if (isset($route['_trailing_'])) { - $route['pass'][] = $route['_trailing_']; - unset($route['_trailing_']); - } - - if (!empty($ext)) { - $route['_ext'] = $ext; - } - - // pass the name if set - if (isset($this->options['_name'])) { - $route['_name'] = $this->options['_name']; - } - - // restructure 'pass' key route params - if (isset($this->options['pass'])) { - $j = count($this->options['pass']); - while ($j--) { - if (isset($route[$this->options['pass'][$j]])) { - array_unshift($route['pass'], $route[$this->options['pass'][$j]]); - } - } - } - $route['_matchedRoute'] = $this->template; - if (count($this->middleware) > 0) { - $route['_middleware'] = $this->middleware; - } - - return $route; - } - - /** - * Check to see if the host matches the route requirements - * - * @param string $host The request's host name - * @return bool Whether or not the host matches any conditions set in for this route. - */ - public function hostMatches($host) - { - $pattern = '@^' . str_replace('\*', '.*', preg_quote($this->options['_host'], '@')) . '$@'; - - return preg_match($pattern, $host) !== 0; - } - - /** - * Removes the extension from $url if it contains a registered extension. - * If no registered extension is found, no extension is returned and the URL is returned unmodified. - * - * @param string $url The url to parse. - * @return array containing url, extension - */ - protected function _parseExtension($url) - { - if (count($this->_extensions) && strpos($url, '.') !== false) { - foreach ($this->_extensions as $ext) { - $len = strlen($ext) + 1; - if (substr($url, -$len) === '.' . $ext) { - return [substr($url, 0, $len * -1), $ext]; - } - } - } - - return [$url, null]; - } - - /** - * Parse passed parameters into a list of passed args. - * - * Return true if a given named $param's $val matches a given $rule depending on $context. - * Currently implemented rule types are controller, action and match that can be combined with each other. - * - * @param string $args A string with the passed params. eg. /1/foo - * @param string $context The current route context, which should contain controller/action keys. - * @return array Array of passed args. - */ - protected function _parseArgs($args, $context) - { - $pass = []; - $args = explode('/', $args); - - foreach ($args as $param) { - if (empty($param) && $param !== '0' && $param !== 0) { - continue; - } - $pass[] = rawurldecode($param); - } - - return $pass; - } - - /** - * Apply persistent parameters to a URL array. Persistent parameters are a - * special key used during route creation to force route parameters to - * persist when omitted from a URL array. - * - * @param array $url The array to apply persistent parameters to. - * @param array $params An array of persistent values to replace persistent ones. - * @return array An array with persistent parameters applied. - */ - protected function _persistParams(array $url, array $params) - { - foreach ($this->options['persist'] as $persistKey) { - if (array_key_exists($persistKey, $params) && !isset($url[$persistKey])) { - $url[$persistKey] = $params[$persistKey]; - } - } - - return $url; - } - - /** - * Check if a URL array matches this route instance. - * - * If the URL matches the route parameters and settings, then - * return a generated string URL. If the URL doesn't match the route parameters, false will be returned. - * This method handles the reverse routing or conversion of URL arrays into string URLs. - * - * @param array $url An array of parameters to check matching with. - * @param array $context An array of the current request context. - * Contains information such as the current host, scheme, port, base - * directory and other url params. - * @return string|false Either a string URL for the parameters if they match or false. - */ - public function match(array $url, array $context = []) - { - if (empty($this->_compiledRoute)) { - $this->compile(); - } - $defaults = $this->defaults; - $context += ['params' => [], '_port' => null, '_scheme' => null, '_host' => null]; - - if (!empty($this->options['persist']) && - is_array($this->options['persist']) - ) { - $url = $this->_persistParams($url, $context['params']); - } - unset($context['params']); - $hostOptions = array_intersect_key($url, $context); - - // Apply the _host option if possible - if (isset($this->options['_host'])) { - if (!isset($hostOptions['_host']) && strpos($this->options['_host'], '*') === false) { - $hostOptions['_host'] = $this->options['_host']; - } - if (!isset($hostOptions['_host'])) { - $hostOptions['_host'] = $context['_host']; - } - - // The host did not match the route preferences - if (!$this->hostMatches($hostOptions['_host'])) { - return false; - } - } - - // Check for properties that will cause an - // absolute url. Copy the other properties over. - if (isset($hostOptions['_scheme']) || - isset($hostOptions['_port']) || - isset($hostOptions['_host']) - ) { - $hostOptions += $context; - - if (getservbyname($hostOptions['_scheme'], 'tcp') === $hostOptions['_port']) { - unset($hostOptions['_port']); - } - } - - // If no base is set, copy one in. - if (!isset($hostOptions['_base']) && isset($context['_base'])) { - $hostOptions['_base'] = $context['_base']; - } - - $query = !empty($url['?']) ? (array)$url['?'] : []; - unset($url['_host'], $url['_scheme'], $url['_port'], $url['_base'], $url['?']); - - // Move extension into the hostOptions so its not part of - // reverse matches. - if (isset($url['_ext'])) { - $hostOptions['_ext'] = $url['_ext']; - unset($url['_ext']); - } - - // Check the method first as it is special. - if (!$this->_matchMethod($url)) { - return false; - } - unset($url['_method'], $url['[method]'], $defaults['_method']); - - // Missing defaults is a fail. - if (array_diff_key($defaults, $url) !== []) { - return false; - } - - // Defaults with different values are a fail. - if (array_intersect_key($url, $defaults) != $defaults) { - return false; - } - - // If this route uses pass option, and the passed elements are - // not set, rekey elements. - if (isset($this->options['pass'])) { - foreach ($this->options['pass'] as $i => $name) { - if (isset($url[$i]) && !isset($url[$name])) { - $url[$name] = $url[$i]; - unset($url[$i]); - } - } - } - - // check that all the key names are in the url - $keyNames = array_flip($this->keys); - if (array_intersect_key($keyNames, $url) !== $keyNames) { - return false; - } - - $pass = []; - foreach ($url as $key => $value) { - // keys that exist in the defaults and have different values is a match failure. - $defaultExists = array_key_exists($key, $defaults); - - // If the key is a routed key, it's not different yet. - if (array_key_exists($key, $keyNames)) { - continue; - } - - // pull out passed args - $numeric = is_numeric($key); - if ($numeric && isset($defaults[$key]) && $defaults[$key] == $value) { - continue; - } - if ($numeric) { - $pass[] = $value; - unset($url[$key]); - continue; - } - - // keys that don't exist are different. - if (!$defaultExists && ($value !== null && $value !== false && $value !== '')) { - $query[$key] = $value; - unset($url[$key]); - } - } - - // if not a greedy route, no extra params are allowed. - if (!$this->_greedy && !empty($pass)) { - return false; - } - - // check patterns for routed params - if (!empty($this->options)) { - foreach ($this->options as $key => $pattern) { - if (isset($url[$key]) && !preg_match('#^' . $pattern . '$#', $url[$key])) { - return false; - } - } - } - $url += $hostOptions; - - return $this->_writeUrl($url, $pass, $query); - } - - /** - * Check whether or not the URL's HTTP method matches. - * - * @param array $url The array for the URL being generated. - * @return bool - */ - protected function _matchMethod($url) - { - if (empty($this->defaults['_method'])) { - return true; - } - // @deprecated The `[method]` support should be removed in 4.0.0 - if (isset($url['[method]'])) { - deprecationWarning('The `[method]` key is deprecated. Use `_method` instead.'); - $url['_method'] = $url['[method]']; - } - if (empty($url['_method'])) { - return false; - } - $methods = array_map('strtoupper', (array)$url['_method']); - foreach ($methods as $value) { - if (in_array($value, (array)$this->defaults['_method'])) { - return true; - } - } - - return false; - } - - /** - * Converts a matching route array into a URL string. - * - * Composes the string URL using the template - * used to create the route. - * - * @param array $params The params to convert to a string url - * @param array $pass The additional passed arguments - * @param array $query An array of parameters - * @return string Composed route string. - */ - protected function _writeUrl($params, $pass = [], $query = []) - { - $pass = implode('/', array_map('rawurlencode', $pass)); - $out = $this->template; - - $search = $replace = []; - foreach ($this->keys as $key) { - $string = null; - if (isset($params[$key])) { - $string = $params[$key]; - } elseif (strpos($out, $key) != strlen($out) - strlen($key)) { - $key .= '/'; - } - if ($this->braceKeys) { - $search[] = "{{$key}}"; - } else { - $search[] = ':' . $key; - } - $replace[] = $string; - } - - if (strpos($this->template, '**') !== false) { - array_push($search, '**', '%2F'); - array_push($replace, $pass, '/'); - } elseif (strpos($this->template, '*') !== false) { - $search[] = '*'; - $replace[] = $pass; - } - $out = str_replace($search, $replace, $out); - - // add base url if applicable. - if (isset($params['_base'])) { - $out = $params['_base'] . $out; - unset($params['_base']); - } - - $out = str_replace('//', '/', $out); - if (isset($params['_scheme']) || - isset($params['_host']) || - isset($params['_port']) - ) { - $host = $params['_host']; - - // append the port & scheme if they exists. - if (isset($params['_port'])) { - $host .= ':' . $params['_port']; - } - $scheme = isset($params['_scheme']) ? $params['_scheme'] : 'http'; - $out = "{$scheme}://{$host}{$out}"; - } - if (!empty($params['_ext']) || !empty($query)) { - $out = rtrim($out, '/'); - } - if (!empty($params['_ext'])) { - $out .= '.' . $params['_ext']; - } - if (!empty($query)) { - $out .= rtrim('?' . http_build_query($query), '?'); - } - - return $out; - } - - /** - * Get the static path portion for this route. - * - * @return string - */ - public function staticPath() - { - $routeKey = strpos($this->template, ':'); - if ($routeKey !== false) { - return substr($this->template, 0, $routeKey); - } - $star = strpos($this->template, '*'); - if ($star !== false) { - $path = rtrim(substr($this->template, 0, $star), '/'); - - return $path === '' ? '/' : $path; - } - - return $this->template; - } - - /** - * Set the names of the middleware that should be applied to this route. - * - * @param array $middleware The list of middleware names to apply to this route. - * Middleware names will not be checked until the route is matched. - * @return $this - */ - public function setMiddleware(array $middleware) - { - $this->middleware = $middleware; - - return $this; - } - - /** - * Get the names of the middleware that should be applied to this route. - * - * @return array - */ - public function getMiddleware() - { - return $this->middleware; - } - - /** - * Set state magic method to support var_export - * - * This method helps for applications that want to implement - * router caching. - * - * @param array $fields Key/Value of object attributes - * @return \Cake\Routing\Route\Route A new instance of the route - */ - public static function __set_state($fields) - { - $class = get_called_class(); - $obj = new $class(''); - foreach ($fields as $field => $value) { - $obj->$field = $value; - } - - return $obj; - } -} diff --git a/vendor/cakephp/cakephp/src/Routing/RouteBuilder.php b/vendor/cakephp/cakephp/src/Routing/RouteBuilder.php deleted file mode 100644 index 9d17e36..0000000 --- a/vendor/cakephp/cakephp/src/Routing/RouteBuilder.php +++ /dev/null @@ -1,1075 +0,0 @@ - controller action map. - * - * @var array - */ - protected static $_resourceMap = [ - 'index' => ['action' => 'index', 'method' => 'GET', 'path' => ''], - 'create' => ['action' => 'add', 'method' => 'POST', 'path' => ''], - 'view' => ['action' => 'view', 'method' => 'GET', 'path' => ':id'], - 'update' => ['action' => 'edit', 'method' => ['PUT', 'PATCH'], 'path' => ':id'], - 'delete' => ['action' => 'delete', 'method' => 'DELETE', 'path' => ':id'], - ]; - - /** - * Default route class to use if none is provided in connect() options. - * - * @var string - */ - protected $_routeClass = 'Cake\Routing\Route\Route'; - - /** - * The extensions that should be set into the routes connected. - * - * @var array - */ - protected $_extensions = []; - - /** - * The path prefix scope that this collection uses. - * - * @var string - */ - protected $_path; - - /** - * The scope parameters if there are any. - * - * @var array - */ - protected $_params; - - /** - * Name prefix for connected routes. - * - * @var string - */ - protected $_namePrefix = ''; - - /** - * The route collection routes should be added to. - * - * @var \Cake\Routing\RouteCollection - */ - protected $_collection; - - /** - * The list of middleware that routes in this builder get - * added during construction. - * - * @var array - */ - protected $middleware = []; - - /** - * Constructor - * - * ### Options - * - * - `routeClass` - The default route class to use when adding routes. - * - `extensions` - The extensions to connect when adding routes. - * - `namePrefix` - The prefix to prepend to all route names. - * - `middleware` - The names of the middleware routes should have applied. - * - * @param \Cake\Routing\RouteCollection $collection The route collection to append routes into. - * @param string $path The path prefix the scope is for. - * @param array $params The scope's routing parameters. - * @param array $options Options list. - */ - public function __construct(RouteCollection $collection, $path, array $params = [], array $options = []) - { - $this->_collection = $collection; - $this->_path = $path; - $this->_params = $params; - if (isset($options['routeClass'])) { - $this->_routeClass = $options['routeClass']; - } - if (isset($options['extensions'])) { - $this->_extensions = $options['extensions']; - } - if (isset($options['namePrefix'])) { - $this->_namePrefix = $options['namePrefix']; - } - if (isset($options['middleware'])) { - $this->middleware = (array)$options['middleware']; - } - } - - /** - * Get or set default route class. - * - * @deprecated 3.5.0 Use getRouteClass/setRouteClass instead. - * @param string|null $routeClass Class name. - * @return string|null - */ - public function routeClass($routeClass = null) - { - deprecationWarning( - 'RouteBuilder::routeClass() is deprecated. ' . - 'Use RouteBuilder::setRouteClass()/getRouteClass() instead.' - ); - if ($routeClass === null) { - return $this->getRouteClass(); - } - $this->setRouteClass($routeClass); - } - - /** - * Set default route class. - * - * @param string $routeClass Class name. - * @return $this - */ - public function setRouteClass($routeClass) - { - $this->_routeClass = $routeClass; - - return $this; - } - - /** - * Get default route class. - * - * @return string - */ - public function getRouteClass() - { - return $this->_routeClass; - } - - /** - * Get or set the extensions in this route builder's scope. - * - * Future routes connected in through this builder will have the connected - * extensions applied. However, setting extensions does not modify existing routes. - * - * @deprecated 3.5.0 Use getExtensions/setExtensions instead. - * @param null|string|array $extensions Either the extensions to use or null. - * @return array|null - */ - public function extensions($extensions = null) - { - deprecationWarning( - 'RouteBuilder::extensions() is deprecated. ' . - 'Use RouteBuilder::setExtensions()/getExtensions() instead.' - ); - if ($extensions === null) { - return $this->getExtensions(); - } - $this->setExtensions($extensions); - } - - /** - * Set the extensions in this route builder's scope. - * - * Future routes connected in through this builder will have the connected - * extensions applied. However, setting extensions does not modify existing routes. - * - * @param string|array $extensions The extensions to set. - * @return $this - */ - public function setExtensions($extensions) - { - $this->_extensions = (array)$extensions; - - return $this; - } - - /** - * Get the extensions in this route builder's scope. - * - * @return array - */ - public function getExtensions() - { - return $this->_extensions; - } - - /** - * Add additional extensions to what is already in current scope - * - * @param string|array $extensions One or more extensions to add - * @return void - */ - public function addExtensions($extensions) - { - $extensions = array_merge($this->_extensions, (array)$extensions); - $this->_extensions = array_unique($extensions); - } - - /** - * Get the path this scope is for. - * - * @return string - */ - public function path() - { - $routeKey = strpos($this->_path, ':'); - if ($routeKey !== false) { - return substr($this->_path, 0, $routeKey); - } - - return $this->_path; - } - - /** - * Get the parameter names/values for this scope. - * - * @return array - */ - public function params() - { - return $this->_params; - } - - /** - * Checks if there is already a route with a given name. - * - * @param string $name Name. - * @return bool - */ - public function nameExists($name) - { - return array_key_exists($name, $this->_collection->named()); - } - - /** - * Get/set the name prefix for this scope. - * - * Modifying the name prefix will only change the prefix - * used for routes connected after the prefix is changed. - * - * @param string|null $value Either the value to set or null. - * @return string - */ - public function namePrefix($value = null) - { - if ($value !== null) { - $this->_namePrefix = $value; - } - - return $this->_namePrefix; - } - - /** - * Generate REST resource routes for the given controller(s). - * - * A quick way to generate a default routes to a set of REST resources (controller(s)). - * - * ### Usage - * - * Connect resource routes for an app controller: - * - * ``` - * $routes->resources('Posts'); - * ``` - * - * Connect resource routes for the Comments controller in the - * Comments plugin: - * - * ``` - * Router::plugin('Comments', function ($routes) { - * $routes->resources('Comments'); - * }); - * ``` - * - * Plugins will create lower_case underscored resource routes. e.g - * `/comments/comments` - * - * Connect resource routes for the Articles controller in the - * Admin prefix: - * - * ``` - * Router::prefix('admin', function ($routes) { - * $routes->resources('Articles'); - * }); - * ``` - * - * Prefixes will create lower_case underscored resource routes. e.g - * `/admin/posts` - * - * You can create nested resources by passing a callback in: - * - * ``` - * $routes->resources('Articles', function ($routes) { - * $routes->resources('Comments'); - * }); - * ``` - * - * The above would generate both resource routes for `/articles`, and `/articles/:article_id/comments`. - * You can use the `map` option to connect additional resource methods: - * - * ``` - * $routes->resources('Articles', [ - * 'map' => ['deleteAll' => ['action' => 'deleteAll', 'method' => 'DELETE']] - * ]); - * ``` - * - * In addition to the default routes, this would also connect a route for `/articles/delete_all`. - * By default the path segment will match the key name. You can use the 'path' key inside the resource - * definition to customize the path name. - * - * You can use the `inflect` option to change how path segments are generated: - * - * ``` - * $routes->resources('PaymentTypes', ['inflect' => 'dasherize']); - * ``` - * - * Will generate routes like `/payment-types` instead of `/payment_types` - * - * ### Options: - * - * - 'id' - The regular expression fragment to use when matching IDs. By default, matches - * integer values and UUIDs. - * - 'inflect' - Choose the inflection method used on the resource name. Defaults to 'underscore'. - * - 'only' - Only connect the specific list of actions. - * - 'actions' - Override the method names used for connecting actions. - * - 'map' - Additional resource routes that should be connected. If you define 'only' and 'map', - * make sure that your mapped methods are also in the 'only' list. - * - 'prefix' - Define a routing prefix for the resource controller. If the current scope - * defines a prefix, this prefix will be appended to it. - * - 'connectOptions' - Custom options for connecting the routes. - * - 'path' - Change the path so it doesn't match the resource name. E.g ArticlesController - * is available at `/posts` - * - * @param string $name A controller name to connect resource routes for. - * @param array|callable $options Options to use when generating REST routes, or a callback. - * @param callable|null $callback An optional callback to be executed in a nested scope. Nested - * scopes inherit the existing path and 'id' parameter. - * @return void - */ - public function resources($name, $options = [], $callback = null) - { - if (is_callable($options) && $callback === null) { - $callback = $options; - $options = []; - } - $options += [ - 'connectOptions' => [], - 'inflect' => 'underscore', - 'id' => static::ID . '|' . static::UUID, - 'only' => [], - 'actions' => [], - 'map' => [], - 'prefix' => null, - 'path' => null, - ]; - - foreach ($options['map'] as $k => $mapped) { - $options['map'][$k] += ['method' => 'GET', 'path' => $k, 'action' => '']; - } - - $ext = null; - if (!empty($options['_ext'])) { - $ext = $options['_ext']; - } - - $connectOptions = $options['connectOptions']; - if (empty($options['path'])) { - $method = $options['inflect']; - $options['path'] = Inflector::$method($name); - } - $resourceMap = array_merge(static::$_resourceMap, $options['map']); - - $only = (array)$options['only']; - if (empty($only)) { - $only = array_keys($resourceMap); - } - - $prefix = ''; - if ($options['prefix']) { - $prefix = $options['prefix']; - } - if (isset($this->_params['prefix']) && $prefix) { - $prefix = $this->_params['prefix'] . '/' . $prefix; - } - - foreach ($resourceMap as $method => $params) { - if (!in_array($method, $only, true)) { - continue; - } - - $action = $params['action']; - if (isset($options['actions'][$method])) { - $action = $options['actions'][$method]; - } - - $url = '/' . implode('/', array_filter([$options['path'], $params['path']])); - $params = [ - 'controller' => $name, - 'action' => $action, - '_method' => $params['method'], - ]; - if ($prefix) { - $params['prefix'] = $prefix; - } - $routeOptions = $connectOptions + [ - 'id' => $options['id'], - 'pass' => ['id'], - '_ext' => $ext, - ]; - $this->connect($url, $params, $routeOptions); - } - - if (is_callable($callback)) { - $idName = Inflector::singularize(Inflector::underscore($name)) . '_id'; - $path = '/' . $options['path'] . '/:' . $idName; - $this->scope($path, [], $callback); - } - } - - /** - * Create a route that only responds to GET requests. - * - * @param string $template The URL template to use. - * @param array $target An array describing the target route parameters. These parameters - * should indicate the plugin, prefix, controller, and action that this route points to. - * @param string $name The name of the route. - * @return \Cake\Routing\Route\Route - */ - public function get($template, $target, $name = null) - { - return $this->_methodRoute('GET', $template, $target, $name); - } - - /** - * Create a route that only responds to POST requests. - * - * @param string $template The URL template to use. - * @param array $target An array describing the target route parameters. These parameters - * should indicate the plugin, prefix, controller, and action that this route points to. - * @param string $name The name of the route. - * @return \Cake\Routing\Route\Route - */ - public function post($template, $target, $name = null) - { - return $this->_methodRoute('POST', $template, $target, $name); - } - - /** - * Create a route that only responds to PUT requests. - * - * @param string $template The URL template to use. - * @param array $target An array describing the target route parameters. These parameters - * should indicate the plugin, prefix, controller, and action that this route points to. - * @param string $name The name of the route. - * @return \Cake\Routing\Route\Route - */ - public function put($template, $target, $name = null) - { - return $this->_methodRoute('PUT', $template, $target, $name); - } - - /** - * Create a route that only responds to PATCH requests. - * - * @param string $template The URL template to use. - * @param array $target An array describing the target route parameters. These parameters - * should indicate the plugin, prefix, controller, and action that this route points to. - * @param string $name The name of the route. - * @return \Cake\Routing\Route\Route - */ - public function patch($template, $target, $name = null) - { - return $this->_methodRoute('PATCH', $template, $target, $name); - } - - /** - * Create a route that only responds to DELETE requests. - * - * @param string $template The URL template to use. - * @param array $target An array describing the target route parameters. These parameters - * should indicate the plugin, prefix, controller, and action that this route points to. - * @param string $name The name of the route. - * @return \Cake\Routing\Route\Route - */ - public function delete($template, $target, $name = null) - { - return $this->_methodRoute('DELETE', $template, $target, $name); - } - - /** - * Create a route that only responds to HEAD requests. - * - * @param string $template The URL template to use. - * @param array $target An array describing the target route parameters. These parameters - * should indicate the plugin, prefix, controller, and action that this route points to. - * @param string $name The name of the route. - * @return \Cake\Routing\Route\Route - */ - public function head($template, $target, $name = null) - { - return $this->_methodRoute('HEAD', $template, $target, $name); - } - - /** - * Create a route that only responds to OPTIONS requests. - * - * @param string $template The URL template to use. - * @param array $target An array describing the target route parameters. These parameters - * should indicate the plugin, prefix, controller, and action that this route points to. - * @param string $name The name of the route. - * @return \Cake\Routing\Route\Route - */ - public function options($template, $target, $name = null) - { - return $this->_methodRoute('OPTIONS', $template, $target, $name); - } - - /** - * Helper to create routes that only respond to a single HTTP method. - * - * @param string $method The HTTP method name to match. - * @param string $template The URL template to use. - * @param array $target An array describing the target route parameters. These parameters - * should indicate the plugin, prefix, controller, and action that this route points to. - * @param string $name The name of the route. - * @return \Cake\Routing\Route\Route - */ - protected function _methodRoute($method, $template, $target, $name) - { - if ($name !== null) { - $name = $this->_namePrefix . $name; - } - $options = [ - '_name' => $name, - '_ext' => $this->_extensions, - '_middleware' => $this->middleware, - 'routeClass' => $this->_routeClass, - ]; - - $target = $this->parseDefaults($target); - $target['_method'] = $method; - - $route = $this->_makeRoute($template, $target, $options); - $this->_collection->add($route, $options); - - return $route; - } - - /** - * Load routes from a plugin. - * - * The routes file will have a local variable named `$routes` made available which contains - * the current RouteBuilder instance. - * - * @param string $name The plugin name - * @param string $file The routes file to load. Defaults to `routes.php` - * @return void - * @throws \Cake\Core\Exception\MissingPluginException When the plugin has not been loaded. - * @throws \InvalidArgumentException When the plugin does not have a routes file. - */ - public function loadPlugin($name, $file = 'routes.php') - { - if (!Plugin::loaded($name)) { - throw new MissingPluginException(['plugin' => $name]); - } - - $path = Plugin::configPath($name) . DIRECTORY_SEPARATOR . $file; - if (!file_exists($path)) { - throw new InvalidArgumentException(sprintf( - 'Cannot load routes for the plugin named %s. The %s file does not exist.', - $name, - $path - )); - } - - $routes = $this; - include $path; - } - - /** - * Connects a new Route. - * - * Routes are a way of connecting request URLs to objects in your application. - * At their core routes are a set or regular expressions that are used to - * match requests to destinations. - * - * Examples: - * - * ``` - * $routes->connect('/:controller/:action/*'); - * ``` - * - * The first parameter will be used as a controller name while the second is - * used as the action name. The '/*' syntax makes this route greedy in that - * it will match requests like `/posts/index` as well as requests - * like `/posts/edit/1/foo/bar`. - * - * ``` - * $routes->connect('/home-page', ['controller' => 'Pages', 'action' => 'display', 'home']); - * ``` - * - * The above shows the use of route parameter defaults. And providing routing - * parameters for a static route. - * - * ``` - * $routes->connect( - * '/:lang/:controller/:action/:id', - * [], - * ['id' => '[0-9]+', 'lang' => '[a-z]{3}'] - * ); - * ``` - * - * Shows connecting a route with custom route parameters as well as - * providing patterns for those parameters. Patterns for routing parameters - * do not need capturing groups, as one will be added for each route params. - * - * $options offers several 'special' keys that have special meaning - * in the $options array. - * - * - `routeClass` is used to extend and change how individual routes parse requests - * and handle reverse routing, via a custom routing class. - * Ex. `'routeClass' => 'SlugRoute'` - * - `pass` is used to define which of the routed parameters should be shifted - * into the pass array. Adding a parameter to pass will remove it from the - * regular route array. Ex. `'pass' => ['slug']`. - * - `persist` is used to define which route parameters should be automatically - * included when generating new URLs. You can override persistent parameters - * by redefining them in a URL or remove them by setting the parameter to `false`. - * Ex. `'persist' => ['lang']` - * - `multibytePattern` Set to true to enable multibyte pattern support in route - * parameter patterns. - * - `_name` is used to define a specific name for routes. This can be used to optimize - * reverse routing lookups. If undefined a name will be generated for each - * connected route. - * - `_ext` is an array of filename extensions that will be parsed out of the url if present. - * See {@link \Cake\Routing\RouteCollection::setExtensions()}. - * - `_method` Only match requests with specific HTTP verbs. - * - * Example of using the `_method` condition: - * - * ``` - * $routes->connect('/tasks', ['controller' => 'Tasks', 'action' => 'index', '_method' => 'GET']); - * ``` - * - * The above route will only be matched for GET requests. POST requests will fail to match this route. - * - * @param string $route A string describing the template of the route - * @param array|string $defaults An array describing the default route parameters. These parameters will be used by default - * and can supply routing parameters that are not dynamic. See above. - * @param array $options An array matching the named elements in the route to regular expressions which that - * element should match. Also contains additional parameters such as which routed parameters should be - * shifted into the passed arguments, supplying patterns for routing parameters and supplying the name of a - * custom routing class. - * @return \Cake\Routing\Route\Route - * @throws \InvalidArgumentException - * @throws \BadMethodCallException - */ - public function connect($route, $defaults = [], array $options = []) - { - $defaults = $this->parseDefaults($defaults); - if (!isset($options['action']) && !isset($defaults['action'])) { - $defaults['action'] = 'index'; - } - - if (empty($options['_ext'])) { - $options['_ext'] = $this->_extensions; - } - - if (empty($options['routeClass'])) { - $options['routeClass'] = $this->_routeClass; - } - if (isset($options['_name']) && $this->_namePrefix) { - $options['_name'] = $this->_namePrefix . $options['_name']; - } - if (empty($options['_middleware'])) { - $options['_middleware'] = $this->middleware; - } - - $route = $this->_makeRoute($route, $defaults, $options); - $this->_collection->add($route, $options); - - return $route; - } - - /** - * Parse the defaults if they're a string - * - * @param string|array $defaults Defaults array from the connect() method. - * @return string|array - */ - protected static function parseDefaults($defaults) - { - if (!is_string($defaults)) { - return $defaults; - } - - $regex = '/(?:([a-zA-Z0-9\/]*)\.)?([a-zA-Z0-9\/]*?)(?:\/)?([a-zA-Z0-9]*):{2}([a-zA-Z0-9_]*)/i'; - if (preg_match($regex, $defaults, $matches)) { - unset($matches[0]); - $matches = array_filter($matches, function ($value) { - return $value !== '' && $value !== '::'; - }); - - // Intentionally incomplete switch - switch (count($matches)) { - case 2: - return [ - 'controller' => $matches[3], - 'action' => $matches[4] - ]; - case 3: - return [ - 'prefix' => strtolower($matches[2]), - 'controller' => $matches[3], - 'action' => $matches[4] - ]; - case 4: - return [ - 'plugin' => $matches[1], - 'prefix' => strtolower($matches[2]), - 'controller' => $matches[3], - 'action' => $matches[4] - ]; - } - } - throw new RuntimeException("Could not parse `{$defaults}` route destination string."); - } - - /** - * Create a route object, or return the provided object. - * - * @param string|\Cake\Routing\Route\Route $route The route template or route object. - * @param array $defaults Default parameters. - * @param array $options Additional options parameters. - * @return \Cake\Routing\Route\Route - * @throws \InvalidArgumentException when route class or route object is invalid. - * @throws \BadMethodCallException when the route to make conflicts with the current scope - */ - protected function _makeRoute($route, $defaults, $options) - { - if (is_string($route)) { - $routeClass = App::className($options['routeClass'], 'Routing/Route'); - if ($routeClass === false) { - throw new InvalidArgumentException(sprintf( - 'Cannot find route class %s', - $options['routeClass'] - )); - } - - $route = str_replace('//', '/', $this->_path . $route); - if ($route !== '/') { - $route = rtrim($route, '/'); - } - - foreach ($this->_params as $param => $val) { - if (isset($defaults[$param]) && $param !== 'prefix' && $defaults[$param] !== $val) { - $msg = 'You cannot define routes that conflict with the scope. ' . - 'Scope had %s = %s, while route had %s = %s'; - throw new BadMethodCallException(sprintf( - $msg, - $param, - $val, - $param, - $defaults[$param] - )); - } - } - $defaults += $this->_params + ['plugin' => null]; - - $route = new $routeClass($route, $defaults, $options); - } - - if ($route instanceof Route) { - return $route; - } - throw new InvalidArgumentException( - 'Route class not found, or route class is not a subclass of Cake\Routing\Route\Route' - ); - } - - /** - * Connects a new redirection Route in the router. - * - * Redirection routes are different from normal routes as they perform an actual - * header redirection if a match is found. The redirection can occur within your - * application or redirect to an outside location. - * - * Examples: - * - * ``` - * $routes->redirect('/home/*', ['controller' => 'posts', 'action' => 'view']); - * ``` - * - * Redirects /home/* to /posts/view and passes the parameters to /posts/view. Using an array as the - * redirect destination allows you to use other routes to define where a URL string should be redirected to. - * - * ``` - * $routes->redirect('/posts/*', 'http://google.com', ['status' => 302]); - * ``` - * - * Redirects /posts/* to http://google.com with a HTTP status of 302 - * - * ### Options: - * - * - `status` Sets the HTTP status (default 301) - * - `persist` Passes the params to the redirected route, if it can. This is useful with greedy routes, - * routes that end in `*` are greedy. As you can remap URLs and not lose any passed args. - * - * @param string $route A string describing the template of the route - * @param array|string $url A URL to redirect to. Can be a string or a Cake array-based URL - * @param array $options An array matching the named elements in the route to regular expressions which that - * element should match. Also contains additional parameters such as which routed parameters should be - * shifted into the passed arguments. As well as supplying patterns for routing parameters. - * @return void - */ - public function redirect($route, $url, array $options = []) - { - if (!isset($options['routeClass'])) { - $options['routeClass'] = 'Cake\Routing\Route\RedirectRoute'; - } - if (is_string($url)) { - $url = ['redirect' => $url]; - } - $this->connect($route, $url, $options); - } - - /** - * Add prefixed routes. - * - * This method creates a scoped route collection that includes - * relevant prefix information. - * - * The $name parameter is used to generate the routing parameter name. - * For example a path of `admin` would result in `'prefix' => 'admin'` being - * applied to all connected routes. - * - * You can re-open a prefix as many times as necessary, as well as nest prefixes. - * Nested prefixes will result in prefix values like `admin/api` which translates - * to the `Controller\Admin\Api\` namespace. - * - * If you need to have prefix with dots, eg: '/api/v1.0', use 'path' key - * for $params argument: - * - * ``` - * $route->prefix('api', function($route) { - * $route->prefix('v10', ['path' => '/v1.0'], function($route) { - * // Translates to `Controller\Api\V10\` namespace - * }); - * }); - * ``` - * - * @param string $name The prefix name to use. - * @param array|callable $params An array of routing defaults to add to each connected route. - * If you have no parameters, this argument can be a callable. - * @param callable|null $callback The callback to invoke that builds the prefixed routes. - * @return void - * @throws \InvalidArgumentException If a valid callback is not passed - */ - public function prefix($name, $params = [], callable $callback = null) - { - if ($callback === null) { - if (!is_callable($params)) { - throw new InvalidArgumentException('A valid callback is expected'); - } - $callback = $params; - $params = []; - } - $name = Inflector::underscore($name); - $path = '/' . $name; - if (isset($params['path'])) { - $path = $params['path']; - unset($params['path']); - } - if (isset($this->_params['prefix'])) { - $name = $this->_params['prefix'] . '/' . $name; - } - $params = array_merge($params, ['prefix' => $name]); - $this->scope($path, $params, $callback); - } - - /** - * Add plugin routes. - * - * This method creates a new scoped route collection that includes - * relevant plugin information. - * - * The plugin name will be inflected to the underscore version to create - * the routing path. If you want a custom path name, use the `path` option. - * - * Routes connected in the scoped collection will have the correct path segment - * prepended, and have a matching plugin routing key set. - * - * @param string $name The plugin name to build routes for - * @param array|callable $options Either the options to use, or a callback - * @param callable|null $callback The callback to invoke that builds the plugin routes - * Only required when $options is defined. - * @return void - */ - public function plugin($name, $options = [], $callback = null) - { - if ($callback === null) { - $callback = $options; - $options = []; - } - $params = ['plugin' => $name] + $this->_params; - if (empty($options['path'])) { - $options['path'] = '/' . Inflector::underscore($name); - } - $this->scope($options['path'], $params, $callback); - } - - /** - * Create a new routing scope. - * - * Scopes created with this method will inherit the properties of the scope they are - * added to. This means that both the current path and parameters will be appended - * to the supplied parameters. - * - * @param string $path The path to create a scope for. - * @param array|callable $params Either the parameters to add to routes, or a callback. - * @param callable|null $callback The callback to invoke that builds the plugin routes. - * Only required when $params is defined. - * @return void - * @throws \InvalidArgumentException when there is no callable parameter. - */ - public function scope($path, $params, $callback = null) - { - if ($callback === null) { - $callback = $params; - $params = []; - } - if (!is_callable($callback)) { - $msg = 'Need a callable function/object to connect routes.'; - throw new InvalidArgumentException($msg); - } - - if ($this->_path !== '/') { - $path = $this->_path . $path; - } - $namePrefix = $this->_namePrefix; - if (isset($params['_namePrefix'])) { - $namePrefix .= $params['_namePrefix']; - } - unset($params['_namePrefix']); - - $params += $this->_params; - $builder = new static($this->_collection, $path, $params, [ - 'routeClass' => $this->_routeClass, - 'extensions' => $this->_extensions, - 'namePrefix' => $namePrefix, - 'middleware' => $this->middleware, - ]); - $callback($builder); - } - - /** - * Connect the `/:controller` and `/:controller/:action/*` fallback routes. - * - * This is a shortcut method for connecting fallback routes in a given scope. - * - * @param string|null $routeClass the route class to use, uses the default routeClass - * if not specified - * @return void - */ - public function fallbacks($routeClass = null) - { - $routeClass = $routeClass ?: $this->_routeClass; - $this->connect('/:controller', ['action' => 'index'], compact('routeClass')); - $this->connect('/:controller/:action/*', [], compact('routeClass')); - } - - /** - * Register a middleware with the RouteCollection. - * - * Once middleware has been registered, it can be applied to the current routing - * scope or any child scopes that share the same RouteCollection. - * - * @param string $name The name of the middleware. Used when applying middleware to a scope. - * @param callable|string $middleware The middleware callable or class name to register. - * @return $this - * @see \Cake\Routing\RouteCollection - */ - public function registerMiddleware($name, $middleware) - { - $this->_collection->registerMiddleware($name, $middleware); - - return $this; - } - - /** - * Apply a middleware to the current route scope. - * - * Requires middleware to be registered via `registerMiddleware()` - * - * @param string ...$names The names of the middleware to apply to the current scope. - * @return $this - * @see \Cake\Routing\RouteCollection::addMiddlewareToScope() - */ - public function applyMiddleware(...$names) - { - foreach ($names as $name) { - if (!$this->_collection->middlewareExists($name)) { - $message = "Cannot apply '$name' middleware or middleware group. " . - 'Use registerMiddleware() to register middleware.'; - throw new RuntimeException($message); - } - } - $this->middleware = array_merge($this->middleware, $names); - - return $this; - } - - /** - * Apply a set of middleware to a group - * - * @param string $name Name of the middleware group - * @param array $middlewareNames Names of the middleware - * @return $this - */ - public function middlewareGroup($name, array $middlewareNames) - { - $this->_collection->middlewareGroup($name, $middlewareNames); - - return $this; - } -} diff --git a/vendor/cakephp/cakephp/src/Routing/RouteCollection.php b/vendor/cakephp/cakephp/src/Routing/RouteCollection.php deleted file mode 100644 index 30a6f67..0000000 --- a/vendor/cakephp/cakephp/src/Routing/RouteCollection.php +++ /dev/null @@ -1,552 +0,0 @@ -_routes[] = $route; - - // Explicit names - if (isset($options['_name'])) { - if (isset($this->_named[$options['_name']])) { - $matched = $this->_named[$options['_name']]; - throw new DuplicateNamedRouteException([ - 'name' => $options['_name'], - 'url' => $matched->template, - 'duplicate' => $matched, - ]); - } - $this->_named[$options['_name']] = $route; - } - - // Generated names. - $name = $route->getName(); - if (!isset($this->_routeTable[$name])) { - $this->_routeTable[$name] = []; - } - $this->_routeTable[$name][] = $route; - - // Index path prefixes (for parsing) - $path = $route->staticPath(); - $this->_paths[$path][] = $route; - - $extensions = $route->getExtensions(); - if (count($extensions) > 0) { - $this->setExtensions($extensions); - } - } - - /** - * Takes the URL string and iterates the routes until one is able to parse the route. - * - * @param string $url URL to parse. - * @param string $method The HTTP method to use. - * @return array An array of request parameters parsed from the URL. - * @throws \Cake\Routing\Exception\MissingRouteException When a URL has no matching route. - */ - public function parse($url, $method = '') - { - $decoded = urldecode($url); - - // Sort path segments matching longest paths first. - $paths = array_keys($this->_paths); - rsort($paths); - - foreach ($paths as $path) { - if (strpos($decoded, $path) !== 0) { - continue; - } - - $queryParameters = null; - if (strpos($url, '?') !== false) { - list($url, $queryParameters) = explode('?', $url, 2); - parse_str($queryParameters, $queryParameters); - } - /* @var \Cake\Routing\Route\Route $route */ - foreach ($this->_paths[$path] as $route) { - $r = $route->parse($url, $method); - if ($r === false) { - continue; - } - if ($queryParameters) { - $r['?'] = $queryParameters; - } - - return $r; - } - } - - $exceptionProperties = ['url' => $url]; - if ($method !== '') { - // Ensure that if the method is included, it is the first element of - // the array, to match the order that the strings are printed in the - // MissingRouteException error message, $_messageTemplateWithMethod. - $exceptionProperties = array_merge(['method' => $method], $exceptionProperties); - } - throw new MissingRouteException($exceptionProperties); - } - - /** - * Takes the ServerRequestInterface, iterates the routes until one is able to parse the route. - * - * @param \Psr\Http\Message\ServerRequestInterface $request The request to parse route data from. - * @return array An array of request parameters parsed from the URL. - * @throws \Cake\Routing\Exception\MissingRouteException When a URL has no matching route. - */ - public function parseRequest(ServerRequestInterface $request) - { - $uri = $request->getUri(); - $urlPath = urldecode($uri->getPath()); - - // Sort path segments matching longest paths first. - $paths = array_keys($this->_paths); - rsort($paths); - - foreach ($paths as $path) { - if (strpos($urlPath, $path) !== 0) { - continue; - } - - /* @var \Cake\Routing\Route\Route $route */ - foreach ($this->_paths[$path] as $route) { - $r = $route->parseRequest($request); - if ($r === false) { - continue; - } - if ($uri->getQuery()) { - parse_str($uri->getQuery(), $queryParameters); - $r['?'] = $queryParameters; - } - - return $r; - } - } - throw new MissingRouteException(['url' => $urlPath]); - } - - /** - * Get the set of names from the $url. Accepts both older style array urls, - * and newer style urls containing '_name' - * - * @param array $url The url to match. - * @return array The set of names of the url - */ - protected function _getNames($url) - { - $plugin = false; - if (isset($url['plugin']) && $url['plugin'] !== false) { - $plugin = strtolower($url['plugin']); - } - $prefix = false; - if (isset($url['prefix']) && $url['prefix'] !== false) { - $prefix = strtolower($url['prefix']); - } - $controller = strtolower($url['controller']); - $action = strtolower($url['action']); - - $names = [ - "${controller}:${action}", - "${controller}:_action", - "_controller:${action}", - '_controller:_action', - ]; - - // No prefix, no plugin - if ($prefix === false && $plugin === false) { - return $names; - } - - // Only a plugin - if ($prefix === false) { - return [ - "${plugin}.${controller}:${action}", - "${plugin}.${controller}:_action", - "${plugin}._controller:${action}", - "${plugin}._controller:_action", - "_plugin.${controller}:${action}", - "_plugin.${controller}:_action", - "_plugin._controller:${action}", - '_plugin._controller:_action', - ]; - } - - // Only a prefix - if ($plugin === false) { - return [ - "${prefix}:${controller}:${action}", - "${prefix}:${controller}:_action", - "${prefix}:_controller:${action}", - "${prefix}:_controller:_action", - "_prefix:${controller}:${action}", - "_prefix:${controller}:_action", - "_prefix:_controller:${action}", - '_prefix:_controller:_action', - ]; - } - - // Prefix and plugin has the most options - // as there are 4 factors. - return [ - "${prefix}:${plugin}.${controller}:${action}", - "${prefix}:${plugin}.${controller}:_action", - "${prefix}:${plugin}._controller:${action}", - "${prefix}:${plugin}._controller:_action", - "${prefix}:_plugin.${controller}:${action}", - "${prefix}:_plugin.${controller}:_action", - "${prefix}:_plugin._controller:${action}", - "${prefix}:_plugin._controller:_action", - "_prefix:${plugin}.${controller}:${action}", - "_prefix:${plugin}.${controller}:_action", - "_prefix:${plugin}._controller:${action}", - "_prefix:${plugin}._controller:_action", - "_prefix:_plugin.${controller}:${action}", - "_prefix:_plugin.${controller}:_action", - "_prefix:_plugin._controller:${action}", - '_prefix:_plugin._controller:_action', - ]; - } - - /** - * Reverse route or match a $url array with the connected routes. - * - * Returns either the URL string generated by the route, - * or throws an exception on failure. - * - * @param array $url The URL to match. - * @param array $context The request context to use. Contains _base, _port, - * _host, _scheme and params keys. - * @return string The URL string on match. - * @throws \Cake\Routing\Exception\MissingRouteException When no route could be matched. - */ - public function match($url, $context) - { - // Named routes support optimization. - if (isset($url['_name'])) { - $name = $url['_name']; - unset($url['_name']); - if (isset($this->_named[$name])) { - $route = $this->_named[$name]; - $out = $route->match($url + $route->defaults, $context); - if ($out) { - return $out; - } - throw new MissingRouteException([ - 'url' => $name, - 'context' => $context, - 'message' => 'A named route was found for "%s", but matching failed.', - ]); - } - throw new MissingRouteException(['url' => $name, 'context' => $context]); - } - - foreach ($this->_getNames($url) as $name) { - if (empty($this->_routeTable[$name])) { - continue; - } - /* @var \Cake\Routing\Route\Route $route */ - foreach ($this->_routeTable[$name] as $route) { - $match = $route->match($url, $context); - if ($match) { - return strlen($match) > 1 ? trim($match, '/') : $match; - } - } - } - throw new MissingRouteException(['url' => var_export($url, true), 'context' => $context]); - } - - /** - * Get all the connected routes as a flat list. - * - * @return \Cake\Routing\Route\Route[] - */ - public function routes() - { - return $this->_routes; - } - - /** - * Get the connected named routes. - * - * @return \Cake\Routing\Route\Route[] - */ - public function named() - { - return $this->_named; - } - - /** - * Get/set the extensions that the route collection could handle. - * - * @param null|string|array $extensions Either the list of extensions to set, - * or null to get. - * @param bool $merge Whether to merge with or override existing extensions. - * Defaults to `true`. - * @return array The valid extensions. - * @deprecated 3.5.0 Use getExtensions()/setExtensions() instead. - */ - public function extensions($extensions = null, $merge = true) - { - deprecationWarning( - 'RouteCollection::extensions() is deprecated. ' . - 'Use RouteCollection::setExtensions()/getExtensions() instead.' - ); - if ($extensions !== null) { - $this->setExtensions((array)$extensions, $merge); - } - - return $this->getExtensions(); - } - - /** - * Get the extensions that can be handled. - * - * @return array The valid extensions. - */ - public function getExtensions() - { - return $this->_extensions; - } - - /** - * Set the extensions that the route collection can handle. - * - * @param array $extensions The list of extensions to set. - * @param bool $merge Whether to merge with or override existing extensions. - * Defaults to `true`. - * @return $this - */ - public function setExtensions(array $extensions, $merge = true) - { - if ($merge) { - $extensions = array_unique(array_merge( - $this->_extensions, - $extensions - )); - } - $this->_extensions = $extensions; - - return $this; - } - - /** - * Register a middleware with the RouteCollection. - * - * Once middleware has been registered, it can be applied to the current routing - * scope or any child scopes that share the same RouteCollection. - * - * @param string $name The name of the middleware. Used when applying middleware to a scope. - * @param callable|string $middleware The middleware callable or class name to register. - * @return $this - */ - public function registerMiddleware($name, $middleware) - { - $this->_middleware[$name] = $middleware; - - return $this; - } - - /** - * Add middleware to a middleware group - * - * @param string $name Name of the middleware group - * @param array $middlewareNames Names of the middleware - * @return $this - */ - public function middlewareGroup($name, array $middlewareNames) - { - if ($this->hasMiddleware($name)) { - $message = "Cannot add middleware group '$name'. A middleware by this name has already been registered."; - throw new RuntimeException($message); - } - - foreach ($middlewareNames as $middlewareName) { - if (!$this->hasMiddleware($middlewareName)) { - $message = "Cannot add '$middlewareName' middleware to group '$name'. It has not been registered."; - throw new RuntimeException($message); - } - } - - $this->_middlewareGroups[$name] = $middlewareNames; - - return $this; - } - - /** - * Check if the named middleware group has been created. - * - * @param string $name The name of the middleware group to check. - * @return bool - */ - public function hasMiddlewareGroup($name) - { - return array_key_exists($name, $this->_middlewareGroups); - } - - /** - * Check if the named middleware has been registered. - * - * @param string $name The name of the middleware to check. - * @return bool - */ - public function hasMiddleware($name) - { - return isset($this->_middleware[$name]); - } - - /** - * Check if the named middleware or middleware group has been registered. - * - * @param string $name The name of the middleware to check. - * @return bool - */ - public function middlewareExists($name) - { - return $this->hasMiddleware($name) || $this->hasMiddlewareGroup($name); - } - - /** - * Apply a registered middleware(s) for the provided path - * - * @param string $path The URL path to register middleware for. - * @param string[] $middleware The middleware names to add for the path. - * @return $this - */ - public function applyMiddleware($path, array $middleware) - { - foreach ($middleware as $name) { - if (!$this->hasMiddleware($name) && !$this->hasMiddlewareGroup($name)) { - $message = "Cannot apply '$name' middleware or middleware group to path '$path'. It has not been registered."; - throw new RuntimeException($message); - } - } - // Matches route element pattern in Cake\Routing\Route - $path = '#^' . preg_quote($path, '#') . '#'; - $path = preg_replace('/\\\\:([a-z0-9-_]+(?_middlewarePaths[$path])) { - $this->_middlewarePaths[$path] = []; - } - $this->_middlewarePaths[$path] = array_merge($this->_middlewarePaths[$path], $middleware); - - return $this; - } - - /** - * Get an array of middleware given a list of names - * - * @param array $names The names of the middleware or groups to fetch - * @return array An array of middleware. If any of the passed names are groups, - * the groups middleware will be flattened into the returned list. - * @throws \RuntimeException when a requested middleware does not exist. - */ - public function getMiddleware(array $names) - { - $out = []; - foreach ($names as $name) { - if ($this->hasMiddlewareGroup($name)) { - $out = array_merge($out, $this->getMiddleware($this->_middlewareGroups[$name])); - continue; - } - if (!$this->hasMiddleware($name)) { - $message = "The middleware named '$name' has not been registered. Use registerMiddleware() to define it."; - throw new RuntimeException($message); - } - $out[] = $this->_middleware[$name]; - } - - return $out; - } -} diff --git a/vendor/cakephp/cakephp/src/Routing/Router.php b/vendor/cakephp/cakephp/src/Routing/Router.php deleted file mode 100644 index cab3db2..0000000 --- a/vendor/cakephp/cakephp/src/Routing/Router.php +++ /dev/null @@ -1,1174 +0,0 @@ - Router::ACTION, - 'Year' => Router::YEAR, - 'Month' => Router::MONTH, - 'Day' => Router::DAY, - 'ID' => Router::ID, - 'UUID' => Router::UUID - ]; - - /** - * Maintains the request object stack for the current request. - * This will contain more than one request object when requestAction is used. - * - * @var array - */ - protected static $_requests = []; - - /** - * Initial state is populated the first time reload() is called which is at the bottom - * of this file. This is a cheat as get_class_vars() returns the value of static vars even if they - * have changed. - * - * @var array - */ - protected static $_initialState = []; - - /** - * The stack of URL filters to apply against routing URLs before passing the - * parameters to the route collection. - * - * @var callable[] - */ - protected static $_urlFilters = []; - - /** - * Default extensions defined with Router::extensions() - * - * @var array - */ - protected static $_defaultExtensions = []; - - /** - * Get or set default route class. - * - * @param string|null $routeClass Class name. - * @return string|null - */ - public static function defaultRouteClass($routeClass = null) - { - if ($routeClass === null) { - return static::$_defaultRouteClass; - } - static::$_defaultRouteClass = $routeClass; - } - - /** - * Gets the named route patterns for use in config/routes.php - * - * @return array Named route elements - * @see \Cake\Routing\Router::$_namedExpressions - */ - public static function getNamedExpressions() - { - return static::$_namedExpressions; - } - - /** - * Connects a new Route in the router. - * - * Compatibility proxy to \Cake\Routing\RouteBuilder::connect() in the `/` scope. - * - * @param string $route A string describing the template of the route - * @param array|string $defaults An array describing the default route parameters. These parameters will be used by default - * and can supply routing parameters that are not dynamic. See above. - * @param array $options An array matching the named elements in the route to regular expressions which that - * element should match. Also contains additional parameters such as which routed parameters should be - * shifted into the passed arguments, supplying patterns for routing parameters and supplying the name of a - * custom routing class. - * @return void - * @throws \Cake\Core\Exception\Exception - * @see \Cake\Routing\RouteBuilder::connect() - * @see \Cake\Routing\Router::scope() - */ - public static function connect($route, $defaults = [], $options = []) - { - static::$initialized = true; - static::scope('/', function ($routes) use ($route, $defaults, $options) { - $routes->connect($route, $defaults, $options); - }); - } - - /** - * Connects a new redirection Route in the router. - * - * Compatibility proxy to \Cake\Routing\RouteBuilder::redirect() in the `/` scope. - * - * @param string $route A string describing the template of the route - * @param array $url A URL to redirect to. Can be a string or a Cake array-based URL - * @param array $options An array matching the named elements in the route to regular expressions which that - * element should match. Also contains additional parameters such as which routed parameters should be - * shifted into the passed arguments. As well as supplying patterns for routing parameters. - * @return void - * @see \Cake\Routing\RouteBuilder::redirect() - * @deprecated 3.3.0 Use Router::scope() and RouteBuilder::redirect() instead. - */ - public static function redirect($route, $url, $options = []) - { - deprecationWarning( - 'Router::redirect() is deprecated. ' . - 'Use Router::scope() and RouteBuilder::redirect() instead.' - ); - if (is_string($url)) { - $url = ['redirect' => $url]; - } - if (!isset($options['routeClass'])) { - $options['routeClass'] = 'Cake\Routing\Route\RedirectRoute'; - } - static::connect($route, $url, $options); - } - - /** - * Generate REST resource routes for the given controller(s). - * - * Compatibility proxy to \Cake\Routing\RouteBuilder::resources(). Additional, compatibility - * around prefixes and plugins and prefixes is handled by this method. - * - * A quick way to generate a default routes to a set of REST resources (controller(s)). - * - * ### Usage - * - * Connect resource routes for an app controller: - * - * ``` - * Router::mapResources('Posts'); - * ``` - * - * Connect resource routes for the Comment controller in the - * Comments plugin: - * - * ``` - * Router::mapResources('Comments.Comment'); - * ``` - * - * Plugins will create lower_case underscored resource routes. e.g - * `/comments/comment` - * - * Connect resource routes for the Posts controller in the - * Admin prefix: - * - * ``` - * Router::mapResources('Posts', ['prefix' => 'admin']); - * ``` - * - * Prefixes will create lower_case underscored resource routes. e.g - * `/admin/posts` - * - * ### Options: - * - * - 'id' - The regular expression fragment to use when matching IDs. By default, matches - * integer values and UUIDs. - * - 'prefix' - Routing prefix to use for the generated routes. Defaults to ''. - * Using this option will create prefixed routes, similar to using Routing.prefixes. - * - 'only' - Only connect the specific list of actions. - * - 'actions' - Override the method names used for connecting actions. - * - 'map' - Additional resource routes that should be connected. If you define 'only' and 'map', - * make sure that your mapped methods are also in the 'only' list. - * - 'path' - Change the path so it doesn't match the resource name. E.g ArticlesController - * is available at `/posts` - * - * @param string|array $controller A controller name or array of controller names (i.e. "Posts" or "ListItems") - * @param array $options Options to use when generating REST routes - * @see \Cake\Routing\RouteBuilder::resources() - * @deprecated 3.3.0 Use Router::scope() and RouteBuilder::resources() instead. - * @return void - */ - public static function mapResources($controller, $options = []) - { - deprecationWarning( - 'Router::mapResources() is deprecated. ' . - 'Use Router::scope() and RouteBuilder::resources() instead.' - ); - foreach ((array)$controller as $name) { - list($plugin, $name) = pluginSplit($name); - - $prefix = $pluginUrl = false; - if (!empty($options['prefix'])) { - $prefix = $options['prefix']; - unset($options['prefix']); - } - if ($plugin) { - $pluginUrl = Inflector::underscore($plugin); - } - - $callback = function ($routes) use ($name, $options) { - $routes->resources($name, $options); - }; - - if ($plugin && $prefix) { - $path = '/' . implode('/', [$prefix, $pluginUrl]); - $params = ['prefix' => $prefix, 'plugin' => $plugin]; - static::scope($path, $params, $callback); - - return; - } - - if ($prefix) { - static::prefix($prefix, $callback); - - return; - } - - if ($plugin) { - static::plugin($plugin, $callback); - - return; - } - - static::scope('/', $callback); - - return; - } - } - - /** - * Parses given URL string. Returns 'routing' parameters for that URL. - * - * @param string $url URL to be parsed. - * @param string $method The HTTP method being used. - * @return array Parsed elements from URL. - * @throws \Cake\Routing\Exception\MissingRouteException When a route cannot be handled - * @deprecated 3.4.0 Use Router::parseRequest() instead. - */ - public static function parse($url, $method = '') - { - deprecationWarning( - 'Router::parse() is deprecated. ' . - 'Use Router::parseRequest() instead. This will require adopting the Http\Server library.' - ); - if (!static::$initialized) { - static::_loadRoutes(); - } - if (strpos($url, '/') !== 0) { - $url = '/' . $url; - } - - return static::$_collection->parse($url, $method); - } - - /** - * Get the routing parameters for the request is possible. - * - * @param \Psr\Http\Message\ServerRequestInterface $request The request to parse request data from. - * @return array Parsed elements from URL. - * @throws \Cake\Routing\Exception\MissingRouteException When a route cannot be handled - */ - public static function parseRequest(ServerRequestInterface $request) - { - if (!static::$initialized) { - static::_loadRoutes(); - } - - return static::$_collection->parseRequest($request); - } - - /** - * Takes parameter and path information back from the Dispatcher, sets these - * parameters as the current request parameters that are merged with URL arrays - * created later in the request. - * - * Nested requests will create a stack of requests. You can remove requests using - * Router::popRequest(). This is done automatically when using Object::requestAction(). - * - * Will accept either a Cake\Http\ServerRequest object or an array of arrays. Support for - * accepting arrays may be removed in the future. - * - * @param \Cake\Http\ServerRequest|array $request Parameters and path information or a Cake\Http\ServerRequest object. - * @return void - * @deprecatd 3.6.0 Support for arrays will be removed in 4.0.0 - */ - public static function setRequestInfo($request) - { - if ($request instanceof ServerRequest) { - static::pushRequest($request); - } else { - deprecationWarning( - 'Passing an array into Router::setRequestInfo() is deprecated. ' . - 'Pass an instance of ServerRequest instead.' - ); - - $requestData = $request; - $requestData += [[], []]; - $requestData[0] += [ - 'controller' => false, - 'action' => false, - 'plugin' => null - ]; - $request = new ServerRequest([ - 'params' => $requestData[0], - 'url' => isset($requestData[1]['here']) ? $requestData[1]['here'] : '/', - 'base' => isset($requestData[1]['base']) ? $requestData[1]['base'] : '', - 'webroot' => isset($requestData[1]['webroot']) ? $requestData[1]['webroot'] : '/', - ]); - static::pushRequest($request); - } - } - - /** - * Push a request onto the request stack. Pushing a request - * sets the request context used when generating URLs. - * - * @param \Cake\Http\ServerRequest $request Request instance. - * @return void - */ - public static function pushRequest(ServerRequest $request) - { - static::$_requests[] = $request; - static::setRequestContext($request); - } - - /** - * Store the request context for a given request. - * - * @param \Psr\Http\Message\ServerRequestInterface $request The request instance. - * @return void - * @throws InvalidArgumentException When parameter is an incorrect type. - */ - public static function setRequestContext(ServerRequestInterface $request) - { - $uri = $request->getUri(); - static::$_requestContext = [ - '_base' => $request->getAttribute('base'), - '_port' => $uri->getPort(), - '_scheme' => $uri->getScheme(), - '_host' => $uri->getHost(), - ]; - } - - /** - * Pops a request off of the request stack. Used when doing requestAction - * - * @return \Cake\Http\ServerRequest The request removed from the stack. - * @see \Cake\Routing\Router::pushRequest() - * @see \Cake\Routing\RequestActionTrait::requestAction() - */ - public static function popRequest() - { - $removed = array_pop(static::$_requests); - $last = end(static::$_requests); - if ($last) { - static::setRequestContext($last); - reset(static::$_requests); - } - - return $removed; - } - - /** - * Get the current request object, or the first one. - * - * @param bool $current True to get the current request, or false to get the first one. - * @return \Cake\Http\ServerRequest|null - */ - public static function getRequest($current = false) - { - if ($current) { - $request = end(static::$_requests); - - return $request ?: null; - } - - return isset(static::$_requests[0]) ? static::$_requests[0] : null; - } - - /** - * Reloads default Router settings. Resets all class variables and - * removes all connected routes. - * - * @return void - */ - public static function reload() - { - if (empty(static::$_initialState)) { - static::$_collection = new RouteCollection(); - static::$_initialState = get_class_vars(get_called_class()); - - return; - } - foreach (static::$_initialState as $key => $val) { - if ($key !== '_initialState') { - static::${$key} = $val; - } - } - static::$_collection = new RouteCollection(); - } - - /** - * Add a URL filter to Router. - * - * URL filter functions are applied to every array $url provided to - * Router::url() before the URLs are sent to the route collection. - * - * Callback functions should expect the following parameters: - * - * - `$params` The URL params being processed. - * - `$request` The current request. - * - * The URL filter function should *always* return the params even if unmodified. - * - * ### Usage - * - * URL filters allow you to easily implement features like persistent parameters. - * - * ``` - * Router::addUrlFilter(function ($params, $request) { - * if ($request->getParam('lang') && !isset($params['lang'])) { - * $params['lang'] = $request->getParam('lang'); - * } - * return $params; - * }); - * ``` - * - * @param callable $function The function to add - * @return void - */ - public static function addUrlFilter(callable $function) - { - static::$_urlFilters[] = $function; - } - - /** - * Applies all the connected URL filters to the URL. - * - * @param array $url The URL array being modified. - * @return array The modified URL. - * @see \Cake\Routing\Router::url() - * @see \Cake\Routing\Router::addUrlFilter() - */ - protected static function _applyUrlFilters($url) - { - $request = static::getRequest(true); - foreach (static::$_urlFilters as $filter) { - $url = $filter($url, $request); - } - - return $url; - } - - /** - * Finds URL for specified action. - * - * Returns a URL pointing to a combination of controller and action. - * - * ### Usage - * - * - `Router::url('/posts/edit/1');` Returns the string with the base dir prepended. - * This usage does not use reverser routing. - * - `Router::url(['controller' => 'posts', 'action' => 'edit']);` Returns a URL - * generated through reverse routing. - * - `Router::url(['_name' => 'custom-name', ...]);` Returns a URL generated - * through reverse routing. This form allows you to leverage named routes. - * - * There are a few 'special' parameters that can change the final URL string that is generated - * - * - `_base` - Set to false to remove the base path from the generated URL. If your application - * is not in the root directory, this can be used to generate URLs that are 'cake relative'. - * cake relative URLs are required when using requestAction. - * - `_scheme` - Set to create links on different schemes like `webcal` or `ftp`. Defaults - * to the current scheme. - * - `_host` - Set the host to use for the link. Defaults to the current host. - * - `_port` - Set the port if you need to create links on non-standard ports. - * - `_full` - If true output of `Router::fullBaseUrl()` will be prepended to generated URLs. - * - `#` - Allows you to set URL hash fragments. - * - `_ssl` - Set to true to convert the generated URL to https, or false to force http. - * - `_name` - Name of route. If you have setup named routes you can use this key - * to specify it. - * - * @param string|array|null $url An array specifying any of the following: - * 'controller', 'action', 'plugin' additionally, you can provide routed - * elements or query string parameters. If string it can be name any valid url - * string. - * @param bool $full If true, the full base URL will be prepended to the result. - * Default is false. - * @return string Full translated URL with base path. - * @throws \Cake\Core\Exception\Exception When the route name is not found - */ - public static function url($url = null, $full = false) - { - if (!static::$initialized) { - static::_loadRoutes(); - } - - $params = [ - 'plugin' => null, - 'controller' => null, - 'action' => 'index', - '_ext' => null, - ]; - $here = $base = $output = $frag = null; - - // In 4.x this should be replaced with state injected via setRequestContext - $request = static::getRequest(true); - if ($request) { - $params = $request->getAttribute('params'); - $here = $request->getRequestTarget(); - $base = $request->getAttribute('base'); - } else { - $base = Configure::read('App.base'); - if (isset(static::$_requestContext['_base'])) { - $base = static::$_requestContext['_base']; - } - } - - if (empty($url)) { - $output = $base . (isset($here) ? $here : '/'); - if ($full) { - $output = static::fullBaseUrl() . $output; - } - - return $output; - } - if (is_array($url)) { - if (isset($url['_ssl'])) { - $url['_scheme'] = ($url['_ssl'] === true) ? 'https' : 'http'; - } - - if (isset($url['_full']) && $url['_full'] === true) { - $full = true; - } - if (isset($url['#'])) { - $frag = '#' . $url['#']; - } - unset($url['_ssl'], $url['_full'], $url['#']); - - $url = static::_applyUrlFilters($url); - - if (!isset($url['_name'])) { - // Copy the current action if the controller is the current one. - if (empty($url['action']) && - (empty($url['controller']) || $params['controller'] === $url['controller']) - ) { - $url['action'] = $params['action']; - } - - // Keep the current prefix around if none set. - if (isset($params['prefix']) && !isset($url['prefix'])) { - $url['prefix'] = $params['prefix']; - } - - $url += [ - 'plugin' => $params['plugin'], - 'controller' => $params['controller'], - 'action' => 'index', - '_ext' => null - ]; - } - - // If a full URL is requested with a scheme the host should default - // to App.fullBaseUrl to avoid corrupt URLs - if ($full && isset($url['_scheme']) && !isset($url['_host'])) { - $url['_host'] = parse_url(static::fullBaseUrl(), PHP_URL_HOST); - } - - $output = static::$_collection->match($url, static::$_requestContext + ['params' => $params]); - } else { - $plainString = ( - strpos($url, 'javascript:') === 0 || - strpos($url, 'mailto:') === 0 || - strpos($url, 'tel:') === 0 || - strpos($url, 'sms:') === 0 || - strpos($url, '#') === 0 || - strpos($url, '?') === 0 || - strpos($url, '//') === 0 || - strpos($url, '://') !== false - ); - - if ($plainString) { - return $url; - } - $output = $base . $url; - } - $protocol = preg_match('#^[a-z][a-z0-9+\-.]*\://#i', $output); - if ($protocol === 0) { - $output = str_replace('//', '/', '/' . $output); - if ($full) { - $output = static::fullBaseUrl() . $output; - } - } - - return $output . $frag; - } - - /** - * Finds URL for specified action. - * - * Returns a bool if the url exists - * - * ### Usage - * - * @see Router::url() - * - * @param string|array|null $url An array specifying any of the following: - * 'controller', 'action', 'plugin' additionally, you can provide routed - * elements or query string parameters. If string it can be name any valid url - * string. - * @param bool $full If true, the full base URL will be prepended to the result. - * Default is false. - * @return bool - */ - public static function routeExists($url = null, $full = false) - { - try { - $route = static::url($url, $full); - - return true; - } catch (MissingRouteException $e) { - return false; - } - } - - /** - * Sets the full base URL that will be used as a prefix for generating - * fully qualified URLs for this application. If not parameters are passed, - * the currently configured value is returned. - * - * ### Note: - * - * If you change the configuration value `App.fullBaseUrl` during runtime - * and expect the router to produce links using the new setting, you are - * required to call this method passing such value again. - * - * @param string|null $base the prefix for URLs generated containing the domain. - * For example: `http://example.com` - * @return string - */ - public static function fullBaseUrl($base = null) - { - if ($base !== null) { - static::$_fullBaseUrl = $base; - Configure::write('App.fullBaseUrl', $base); - } - if (empty(static::$_fullBaseUrl)) { - static::$_fullBaseUrl = Configure::read('App.fullBaseUrl'); - } - - return static::$_fullBaseUrl; - } - - /** - * Reverses a parsed parameter array into an array. - * - * Works similarly to Router::url(), but since parsed URL's contain additional - * 'pass' as well as 'url.url' keys. Those keys need to be specially - * handled in order to reverse a params array into a string URL. - * - * This will strip out 'autoRender', 'bare', 'requested', and 'return' param names as those - * are used for CakePHP internals and should not normally be part of an output URL. - * - * @param \Cake\Http\ServerRequest|array $params The params array or - * Cake\Http\ServerRequest object that needs to be reversed. - * @return array The URL array ready to be used for redirect or HTML link. - */ - public static function reverseToArray($params) - { - $url = []; - if ($params instanceof ServerRequest) { - $url = $params->getQueryParams(); - $params = $params->getAttribute('params'); - } elseif (isset($params['url'])) { - $url = $params['url']; - } - $pass = isset($params['pass']) ? $params['pass'] : []; - - unset( - $params['pass'], - $params['paging'], - $params['models'], - $params['url'], - $url['url'], - $params['autoRender'], - $params['bare'], - $params['requested'], - $params['return'], - $params['_Token'], - $params['_matchedRoute'], - $params['_name'] - ); - $params = array_merge($params, $pass); - if (!empty($url)) { - $params['?'] = $url; - } - - return $params; - } - - /** - * Reverses a parsed parameter array into a string. - * - * Works similarly to Router::url(), but since parsed URL's contain additional - * 'pass' as well as 'url.url' keys. Those keys need to be specially - * handled in order to reverse a params array into a string URL. - * - * This will strip out 'autoRender', 'bare', 'requested', and 'return' param names as those - * are used for CakePHP internals and should not normally be part of an output URL. - * - * @param \Cake\Http\ServerRequest|array $params The params array or - * Cake\Network\Request object that needs to be reversed. - * @param bool $full Set to true to include the full URL including the - * protocol when reversing the URL. - * @return string The string that is the reversed result of the array - */ - public static function reverse($params, $full = false) - { - $params = static::reverseToArray($params); - - return static::url($params, $full); - } - - /** - * Normalizes a URL for purposes of comparison. - * - * Will strip the base path off and replace any double /'s. - * It will not unify the casing and underscoring of the input value. - * - * @param array|string $url URL to normalize Either an array or a string URL. - * @return string Normalized URL - */ - public static function normalize($url = '/') - { - if (is_array($url)) { - $url = static::url($url); - } - if (preg_match('/^[a-z\-]+:\/\//', $url)) { - return $url; - } - $request = static::getRequest(); - - if ($request) { - $base = $request->getAttribute('base'); - if (strlen($base) && stristr($url, $base)) { - $url = preg_replace('/^' . preg_quote($base, '/') . '/', '', $url, 1); - } - } - $url = '/' . $url; - - while (strpos($url, '//') !== false) { - $url = str_replace('//', '/', $url); - } - $url = preg_replace('/(?:(\/$))/', '', $url); - - if (empty($url)) { - return '/'; - } - - return $url; - } - - /** - * Get or set valid extensions for all routes connected later. - * - * Instructs the router to parse out file extensions - * from the URL. For example, http://example.com/posts.rss would yield a file - * extension of "rss". The file extension itself is made available in the - * controller as `$this->request->getParam('_ext')`, and is used by the RequestHandler - * component to automatically switch to alternate layouts and templates, and - * load helpers corresponding to the given content, i.e. RssHelper. Switching - * layouts and helpers requires that the chosen extension has a defined mime type - * in `Cake\Http\Response`. - * - * A string or an array of valid extensions can be passed to this method. - * If called without any parameters it will return current list of set extensions. - * - * @param array|string|null $extensions List of extensions to be added. - * @param bool $merge Whether to merge with or override existing extensions. - * Defaults to `true`. - * @return array Array of extensions Router is configured to parse. - */ - public static function extensions($extensions = null, $merge = true) - { - $collection = static::$_collection; - if ($extensions === null) { - if (!static::$initialized) { - static::_loadRoutes(); - } - - return array_unique(array_merge(static::$_defaultExtensions, $collection->getExtensions())); - } - $extensions = (array)$extensions; - if ($merge) { - $extensions = array_unique(array_merge(static::$_defaultExtensions, $extensions)); - } - - return static::$_defaultExtensions = $extensions; - } - - /** - * Provides legacy support for named parameters on incoming URLs. - * - * Checks the passed parameters for elements containing `$options['separator']` - * Those parameters are split and parsed as if they were old style named parameters. - * - * The parsed parameters will be moved from params['pass'] to params['named']. - * - * ### Options - * - * - `separator` The string to use as a separator. Defaults to `:`. - * - * @param \Cake\Http\ServerRequest $request The request object to modify. - * @param array $options The array of options. - * @return \Cake\Http\ServerRequest The modified request - * @deprecated 3.3.0 Named parameter backwards compatibility will be removed in 4.0. - */ - public static function parseNamedParams(ServerRequest $request, array $options = []) - { - deprecationWarning( - 'Router::parseNamedParams() is deprecated. ' . - '2.x backwards compatible named parameter support will be removed in 4.0' - ); - $options += ['separator' => ':']; - if (!$request->getParam('pass')) { - return $request->withParam('named', []); - } - $named = []; - $pass = $request->getParam('pass'); - foreach ((array)$pass as $key => $value) { - if (strpos($value, $options['separator']) === false) { - continue; - } - unset($pass[$key]); - list($key, $value) = explode($options['separator'], $value, 2); - - if (preg_match_all('/\[([A-Za-z0-9_-]+)?\]/', $key, $matches, PREG_SET_ORDER)) { - $matches = array_reverse($matches); - $parts = explode('[', $key); - $key = array_shift($parts); - $arr = $value; - foreach ($matches as $match) { - if (empty($match[1])) { - $arr = [$arr]; - } else { - $arr = [ - $match[1] => $arr - ]; - } - } - $value = $arr; - } - $named = array_merge_recursive($named, [$key => $value]); - } - - return $request - ->withParam('pass', $pass) - ->withParam('named', $named); - } - - /** - * Create a RouteBuilder for the provided path. - * - * @param string $path The path to set the builder to. - * @param array $options The options for the builder - * @return \Cake\Routing\RouteBuilder - */ - public static function createRouteBuilder($path, array $options = []) - { - $defaults = [ - 'routeClass' => static::defaultRouteClass(), - 'extensions' => static::$_defaultExtensions, - ]; - $options += $defaults; - - return new RouteBuilder(static::$_collection, $path, [], [ - 'routeClass' => $options['routeClass'], - 'extensions' => $options['extensions'], - ]); - } - - /** - * Create a routing scope. - * - * Routing scopes allow you to keep your routes DRY and avoid repeating - * common path prefixes, and or parameter sets. - * - * Scoped collections will be indexed by path for faster route parsing. If you - * re-open or re-use a scope the connected routes will be merged with the - * existing ones. - * - * ### Options - * - * The `$params` array allows you to define options for the routing scope. - * The options listed below *are not* available to be used as routing defaults - * - * - `routeClass` The route class to use in this scope. Defaults to - * `Router::defaultRouteClass()` - * - `extensions` The extensions to enable in this scope. Defaults to the globally - * enabled extensions set with `Router::extensions()` - * - * ### Example - * - * ``` - * Router::scope('/blog', ['plugin' => 'Blog'], function ($routes) { - * $routes->connect('/', ['controller' => 'Articles']); - * }); - * ``` - * - * The above would result in a `/blog/` route being created, with both the - * plugin & controller default parameters set. - * - * You can use `Router::plugin()` and `Router::prefix()` as shortcuts to creating - * specific kinds of scopes. - * - * @param string $path The path prefix for the scope. This path will be prepended - * to all routes connected in the scoped collection. - * @param array|callable $params An array of routing defaults to add to each connected route. - * If you have no parameters, this argument can be a callable. - * @param callable|null $callback The callback to invoke with the scoped collection. - * @throws \InvalidArgumentException When an invalid callable is provided. - * @return void - */ - public static function scope($path, $params = [], $callback = null) - { - $options = []; - if (is_array($params)) { - $options = $params; - unset($params['routeClass'], $params['extensions']); - } - $builder = static::createRouteBuilder('/', $options); - $builder->scope($path, $params, $callback); - } - - /** - * Create prefixed routes. - * - * This method creates a scoped route collection that includes - * relevant prefix information. - * - * The path parameter is used to generate the routing parameter name. - * For example a path of `admin` would result in `'prefix' => 'admin'` being - * applied to all connected routes. - * - * The prefix name will be inflected to the underscore version to create - * the routing path. If you want a custom path name, use the `path` option. - * - * You can re-open a prefix as many times as necessary, as well as nest prefixes. - * Nested prefixes will result in prefix values like `admin/api` which translates - * to the `Controller\Admin\Api\` namespace. - * - * @param string $name The prefix name to use. - * @param array|callable $params An array of routing defaults to add to each connected route. - * If you have no parameters, this argument can be a callable. - * @param callable|null $callback The callback to invoke that builds the prefixed routes. - * @return void - */ - public static function prefix($name, $params = [], $callback = null) - { - if ($callback === null) { - $callback = $params; - $params = []; - } - $name = Inflector::underscore($name); - - if (empty($params['path'])) { - $path = '/' . $name; - } else { - $path = $params['path']; - unset($params['path']); - } - - $params = array_merge($params, ['prefix' => $name]); - static::scope($path, $params, $callback); - } - - /** - * Add plugin routes. - * - * This method creates a scoped route collection that includes - * relevant plugin information. - * - * The plugin name will be inflected to the underscore version to create - * the routing path. If you want a custom path name, use the `path` option. - * - * Routes connected in the scoped collection will have the correct path segment - * prepended, and have a matching plugin routing key set. - * - * @param string $name The plugin name to build routes for - * @param array|callable $options Either the options to use, or a callback - * @param callable|null $callback The callback to invoke that builds the plugin routes. - * Only required when $options is defined - * @return void - */ - public static function plugin($name, $options = [], $callback = null) - { - if ($callback === null) { - $callback = $options; - $options = []; - } - $params = ['plugin' => $name]; - if (empty($options['path'])) { - $options['path'] = '/' . Inflector::underscore($name); - } - if (isset($options['_namePrefix'])) { - $params['_namePrefix'] = $options['_namePrefix']; - } - static::scope($options['path'], $params, $callback); - } - - /** - * Get the route scopes and their connected routes. - * - * @return \Cake\Routing\Route\Route[] - */ - public static function routes() - { - if (!static::$initialized) { - static::_loadRoutes(); - } - - return static::$_collection->routes(); - } - - /** - * Get the RouteCollection inside the Router - * - * @return \Cake\Routing\RouteCollection - */ - public static function getRouteCollection() - { - return static::$_collection; - } - - /** - * Set the RouteCollection inside the Router - * - * @param RouteCollection $routeCollection route collection - * @return void - */ - public static function setRouteCollection($routeCollection) - { - static::$_collection = $routeCollection; - static::$initialized = true; - } - - /** - * Loads route configuration - * - * @deprecated 3.5.0 Routes will be loaded via the Application::routes() hook in 4.0.0 - * @return void - */ - protected static function _loadRoutes() - { - static::$initialized = true; - include CONFIG . 'routes.php'; - } -} diff --git a/vendor/cakephp/cakephp/src/Shell/CacheShell.php b/vendor/cakephp/cakephp/src/Shell/CacheShell.php deleted file mode 100644 index 8a13fee..0000000 --- a/vendor/cakephp/cakephp/src/Shell/CacheShell.php +++ /dev/null @@ -1,118 +0,0 @@ -addSubcommand('list_prefixes', [ - 'help' => 'Show a list of all defined cache prefixes.', - ]); - $parser->addSubcommand('clear_all', [ - 'help' => 'Clear all caches.', - ]); - $parser->addSubcommand('clear', [ - 'help' => 'Clear the cache for a specified prefix.', - 'parser' => [ - 'description' => [ - 'Clear the cache for a particular prefix.', - 'For example, `cake cache clear _cake_model_` will clear the model cache', - 'Use `cake cache list_prefixes` to list available prefixes' - ], - 'arguments' => [ - 'prefix' => [ - 'help' => 'The cache prefix to be cleared.', - 'required' => true - ] - ] - ] - ]); - - return $parser; - } - - /** - * Clear metadata. - * - * @param string|null $prefix The cache prefix to be cleared. - * @throws \Cake\Console\Exception\StopException - * @return void - */ - public function clear($prefix = null) - { - try { - $engine = Cache::engine($prefix); - Cache::clear(false, $prefix); - if ($engine instanceof ApcuEngine) { - $this->warn("ApcuEngine detected: Cleared $prefix CLI cache successfully " . - "but $prefix web cache must be cleared separately."); - } elseif ($engine instanceof WincacheEngine) { - $this->warn("WincacheEngine detected: Cleared $prefix CLI cache successfully " . - "but $prefix web cache must be cleared separately."); - } else { - $this->out("Cleared $prefix cache"); - } - } catch (InvalidArgumentException $e) { - $this->abort($e->getMessage()); - } - } - - /** - * Clear metadata. - * - * @return void - */ - public function clearAll() - { - $prefixes = Cache::configured(); - foreach ($prefixes as $prefix) { - $this->clear($prefix); - } - } - - /** - * Show a list of all defined cache prefixes. - * - * @return void - */ - public function listPrefixes() - { - $prefixes = Cache::configured(); - foreach ($prefixes as $prefix) { - $this->out($prefix); - } - } -} diff --git a/vendor/cakephp/cakephp/src/Shell/CommandListShell.php b/vendor/cakephp/cakephp/src/Shell/CommandListShell.php deleted file mode 100644 index b08684f..0000000 --- a/vendor/cakephp/cakephp/src/Shell/CommandListShell.php +++ /dev/null @@ -1,171 +0,0 @@ -out(); - $this->out(sprintf('Welcome to CakePHP %s Console', 'v' . Configure::version())); - $this->hr(); - $this->out(sprintf('App : %s', APP_DIR)); - $this->out(sprintf('Path: %s', APP)); - $this->out(sprintf('PHP : %s', phpversion())); - $this->hr(); - } - - /** - * startup - * - * @return void - */ - public function startup() - { - if (!$this->param('xml') && !$this->param('version')) { - parent::startup(); - } - } - - /** - * Main function Prints out the list of shells. - * - * @return void - */ - public function main() - { - if (!$this->param('xml') && !$this->param('version')) { - $this->out('Current Paths:', 2); - $this->out('* app: ' . APP_DIR); - $this->out('* root: ' . rtrim(ROOT, DIRECTORY_SEPARATOR)); - $this->out('* core: ' . rtrim(CORE_PATH, DIRECTORY_SEPARATOR)); - $this->out(''); - - $this->out('Available Shells:', 2); - } - - if ($this->param('version')) { - $this->out(Configure::version()); - - return; - } - - $shellList = $this->Command->getShellList(); - if (!$shellList) { - return; - } - - if (!$this->param('xml')) { - $this->_asText($shellList); - } else { - $this->_asXml($shellList); - } - } - - /** - * Output text. - * - * @param array $shellList The shell list. - * @return void - */ - protected function _asText($shellList) - { - foreach ($shellList as $plugin => $commands) { - sort($commands); - $this->out(sprintf('[%s] %s', $plugin, implode(', ', $commands))); - $this->out(); - } - - $this->out('To run an app or core command, type `cake shell_name [args]`'); - $this->out('To run a plugin command, type `cake Plugin.shell_name [args]`'); - $this->out('To get help on a specific command, type `cake shell_name --help`', 2); - } - - /** - * Output as XML - * - * @param array $shellList The shell list. - * @return void - */ - protected function _asXml($shellList) - { - $plugins = Plugin::loaded(); - $shells = new SimpleXMLElement(''); - foreach ($shellList as $plugin => $commands) { - foreach ($commands as $command) { - $callable = $command; - if (in_array($plugin, $plugins)) { - $callable = Inflector::camelize($plugin) . '.' . $command; - } - - $shell = $shells->addChild('shell'); - $shell->addAttribute('name', $command); - $shell->addAttribute('call_as', $callable); - $shell->addAttribute('provider', $plugin); - $shell->addAttribute('help', $callable . ' -h'); - } - } - $this->_io->setOutputAs(ConsoleOutput::RAW); - $this->out($shells->saveXML()); - } - - /** - * Gets the option parser instance and configures it. - * - * @return \Cake\Console\ConsoleOptionParser - */ - public function getOptionParser() - { - $parser = parent::getOptionParser(); - - $parser->setDescription( - 'Get the list of available shells for this CakePHP application.' - )->addOption('xml', [ - 'help' => 'Get the listing as XML.', - 'boolean' => true - ])->addOption('version', [ - 'help' => 'Prints the currently installed version of CakePHP. (deprecated - use `cake --version` instead)', - 'boolean' => true - ]); - - return $parser; - } -} diff --git a/vendor/cakephp/cakephp/src/Shell/CompletionShell.php b/vendor/cakephp/cakephp/src/Shell/CompletionShell.php deleted file mode 100644 index 6cf4faa..0000000 --- a/vendor/cakephp/cakephp/src/Shell/CompletionShell.php +++ /dev/null @@ -1,173 +0,0 @@ -out($this->getOptionParser()->help()); - } - - /** - * list commands - * - * @return int|bool|null Returns the number of bytes returned from writing to stdout. - */ - public function commands() - { - $options = $this->Command->commands(); - - return $this->_output($options); - } - - /** - * list options for the named command - * - * @return int|bool|null Returns the number of bytes returned from writing to stdout. - */ - public function options() - { - $commandName = $subCommandName = ''; - if (!empty($this->args[0])) { - $commandName = $this->args[0]; - } - if (!empty($this->args[1])) { - $subCommandName = $this->args[1]; - } - $options = $this->Command->options($commandName, $subCommandName); - - return $this->_output($options); - } - - /** - * list subcommands for the named command - * - * @return int|bool|null Returns the number of bytes returned from writing to stdout. - */ - public function subcommands() - { - if (!$this->args) { - return $this->_output(); - } - - $options = $this->Command->subCommands($this->args[0]); - - return $this->_output($options); - } - - /** - * Guess autocomplete from the whole argument string - * - * @return int|bool|null Returns the number of bytes returned from writing to stdout. - */ - public function fuzzy() - { - return $this->_output(); - } - - /** - * Gets the option parser instance and configures it. - * - * @return \Cake\Console\ConsoleOptionParser - */ - public function getOptionParser() - { - $parser = parent::getOptionParser(); - - $parser->setDescription( - 'Used by shells like bash to autocomplete command name, options and arguments' - )->addSubcommand('commands', [ - 'help' => 'Output a list of available commands', - 'parser' => [ - 'description' => 'List all available', - ] - ])->addSubcommand('subcommands', [ - 'help' => 'Output a list of available subcommands', - 'parser' => [ - 'description' => 'List subcommands for a command', - 'arguments' => [ - 'command' => [ - 'help' => 'The command name', - 'required' => false, - ] - ] - ] - ])->addSubcommand('options', [ - 'help' => 'Output a list of available options', - 'parser' => [ - 'description' => 'List options', - 'arguments' => [ - 'command' => [ - 'help' => 'The command name', - 'required' => false, - ], - 'subcommand' => [ - 'help' => 'The subcommand name', - 'required' => false, - ] - ] - ] - ])->addSubcommand('fuzzy', [ - 'help' => 'Guess autocomplete' - ])->setEpilog([ - 'This command is not intended to be called manually', - ]); - - return $parser; - } - - /** - * Emit results as a string, space delimited - * - * @param array $options The options to output - * @return int|bool|null Returns the number of bytes returned from writing to stdout. - */ - protected function _output($options = []) - { - if ($options) { - return $this->out(implode($options, ' ')); - } - } -} diff --git a/vendor/cakephp/cakephp/src/Shell/Helper/ProgressHelper.php b/vendor/cakephp/cakephp/src/Shell/Helper/ProgressHelper.php deleted file mode 100644 index 9d92e54..0000000 --- a/vendor/cakephp/cakephp/src/Shell/Helper/ProgressHelper.php +++ /dev/null @@ -1,151 +0,0 @@ -helper('Progress')->output(['callback' => function ($progress) { - * // Do work - * $progress->increment(); - * }); - * ``` - */ -class ProgressHelper extends Helper -{ - - /** - * The current progress. - * - * @var int - */ - protected $_progress = 0; - - /** - * The total number of 'items' to progress through. - * - * @var int - */ - protected $_total = 0; - - /** - * The width of the bar. - * - * @var int - */ - protected $_width = 0; - - /** - * Output a progress bar. - * - * Takes a number of options to customize the behavior: - * - * - `total` The total number of items in the progress bar. Defaults - * to 100. - * - `width` The width of the progress bar. Defaults to 80. - * - `callback` The callback that will be called in a loop to advance the progress bar. - * - * @param array $args The arguments/options to use when outputing the progress bar. - * @return void - */ - public function output($args) - { - $args += ['callback' => null]; - if (isset($args[0])) { - $args['callback'] = $args[0]; - } - if (!$args['callback'] || !is_callable($args['callback'])) { - throw new RuntimeException('Callback option must be a callable.'); - } - $this->init($args); - - $callback = $args['callback']; - - $this->_io->out('', 0); - while ($this->_progress < $this->_total) { - $callback($this); - $this->draw(); - } - $this->_io->out(''); - } - - /** - * Initialize the progress bar for use. - * - * - `total` The total number of items in the progress bar. Defaults - * to 100. - * - `width` The width of the progress bar. Defaults to 80. - * - * @param array $args The initialization data. - * @return $this - */ - public function init(array $args = []) - { - $args += ['total' => 100, 'width' => 80]; - $this->_progress = 0; - $this->_width = $args['width']; - $this->_total = $args['total']; - - return $this; - } - - /** - * Increment the progress bar. - * - * @param int $num The amount of progress to advance by. - * @return $this - */ - public function increment($num = 1) - { - $this->_progress = min(max(0, $this->_progress + $num), $this->_total); - - return $this; - } - - /** - * Render the progress bar based on the current state. - * - * @return $this - */ - public function draw() - { - $numberLen = strlen(' 100%'); - $complete = round($this->_progress / $this->_total, 2); - $barLen = ($this->_width - $numberLen) * ($this->_progress / $this->_total); - $bar = ''; - if ($barLen > 1) { - $bar = str_repeat('=', $barLen - 1) . '>'; - } - - $pad = ceil($this->_width - $numberLen - $barLen); - if ($pad > 0) { - $bar .= str_repeat(' ', $pad); - } - $percent = ($complete * 100) . '%'; - $bar .= str_pad($percent, $numberLen, ' ', STR_PAD_LEFT); - - $this->_io->overwrite($bar, 0); - - return $this; - } -} diff --git a/vendor/cakephp/cakephp/src/Shell/Helper/TableHelper.php b/vendor/cakephp/cakephp/src/Shell/Helper/TableHelper.php deleted file mode 100644 index 60132ae..0000000 --- a/vendor/cakephp/cakephp/src/Shell/Helper/TableHelper.php +++ /dev/null @@ -1,149 +0,0 @@ - true, - 'rowSeparator' => false, - 'headerStyle' => 'info', - ]; - - /** - * Calculate the column widths - * - * @param array $rows The rows on which the columns width will be calculated on. - * @return array - */ - protected function _calculateWidths($rows) - { - $widths = []; - foreach ($rows as $line) { - foreach (array_values($line) as $k => $v) { - $columnLength = mb_strwidth($v); - if ($columnLength >= (isset($widths[$k]) ? $widths[$k] : 0)) { - $widths[$k] = $columnLength; - } - } - } - - return $widths; - } - - /** - * Output a row separator. - * - * @param array $widths The widths of each column to output. - * @return void - */ - protected function _rowSeparator($widths) - { - $out = ''; - foreach ($widths as $column) { - $out .= '+' . str_repeat('-', $column + 2); - } - $out .= '+'; - $this->_io->out($out); - } - - /** - * Output a row. - * - * @param array $row The row to output. - * @param array $widths The widths of each column to output. - * @param array $options Options to be passed. - * @return void - */ - protected function _render(array $row, $widths, $options = []) - { - if (count($row) === 0) { - return; - } - - $out = ''; - foreach (array_values($row) as $i => $column) { - $pad = $widths[$i] - mb_strwidth($column); - if (!empty($options['style'])) { - $column = $this->_addStyle($column, $options['style']); - } - $out .= '| ' . $column . str_repeat(' ', $pad) . ' '; - } - $out .= '|'; - $this->_io->out($out); - } - - /** - * Output a table. - * - * Data will be output based on the order of the values - * in the array. The keys will not be used to align data. - * - * @param array $rows The data to render out. - * @return void - */ - public function output($rows) - { - if (!is_array($rows) || count($rows) === 0) { - return; - } - - $config = $this->getConfig(); - $widths = $this->_calculateWidths($rows); - - $this->_rowSeparator($widths); - if ($config['headers'] === true) { - $this->_render(array_shift($rows), $widths, ['style' => $config['headerStyle']]); - $this->_rowSeparator($widths); - } - - if (!$rows) { - return; - } - - foreach ($rows as $line) { - $this->_render($line, $widths); - if ($config['rowSeparator'] === true) { - $this->_rowSeparator($widths); - } - } - if ($config['rowSeparator'] !== true) { - $this->_rowSeparator($widths); - } - } - - /** - * Add style tags - * - * @param string $text The text to be surrounded - * @param string $style The style to be applied - * @return string - */ - protected function _addStyle($text, $style) - { - return '<' . $style . '>' . $text . ''; - } -} diff --git a/vendor/cakephp/cakephp/src/Shell/I18nShell.php b/vendor/cakephp/cakephp/src/Shell/I18nShell.php deleted file mode 100644 index 40828f2..0000000 --- a/vendor/cakephp/cakephp/src/Shell/I18nShell.php +++ /dev/null @@ -1,168 +0,0 @@ -out('I18n Shell'); - $this->hr(); - $this->out('[E]xtract POT file from sources'); - $this->out('[I]nitialize a language from POT file'); - $this->out('[H]elp'); - $this->out('[Q]uit'); - - $choice = strtolower($this->in('What would you like to do?', ['E', 'I', 'H', 'Q'])); - switch ($choice) { - case 'e': - $this->Extract->main(); - break; - case 'i': - $this->init(); - break; - case 'h': - $this->out($this->OptionParser->help()); - break; - case 'q': - $this->_stop(); - - return; - default: - $this->out('You have made an invalid selection. Please choose a command to execute by entering E, I, H, or Q.'); - } - $this->hr(); - $this->main(); - } - - /** - * Inits PO file from POT file. - * - * @param string|null $language Language code to use. - * @return void - * @throws \Cake\Console\Exception\StopException - */ - public function init($language = null) - { - if (!$language) { - $language = $this->in('Please specify language code, e.g. `en`, `eng`, `en_US` etc.'); - } - if (strlen($language) < 2) { - $this->abort('Invalid language code. Valid is `en`, `eng`, `en_US` etc.'); - } - - $this->_paths = [APP]; - if ($this->param('plugin')) { - $plugin = Inflector::camelize($this->param('plugin')); - $this->_paths = [Plugin::classPath($plugin)]; - } - - $response = $this->in('What folder?', null, rtrim($this->_paths[0], DIRECTORY_SEPARATOR) . DIRECTORY_SEPARATOR . 'Locale'); - $sourceFolder = rtrim($response, DIRECTORY_SEPARATOR) . DIRECTORY_SEPARATOR; - $targetFolder = $sourceFolder . $language . DIRECTORY_SEPARATOR; - if (!is_dir($targetFolder)) { - mkdir($targetFolder, 0775, true); - } - - $count = 0; - $iterator = new DirectoryIterator($sourceFolder); - foreach ($iterator as $fileinfo) { - if (!$fileinfo->isFile()) { - continue; - } - $filename = $fileinfo->getFilename(); - $newFilename = $fileinfo->getBasename('.pot'); - $newFilename .= '.po'; - - $this->createFile($targetFolder . $newFilename, file_get_contents($sourceFolder . $filename)); - $count++; - } - - $this->out('Generated ' . $count . ' PO files in ' . $targetFolder); - } - - /** - * Gets the option parser instance and configures it. - * - * @return \Cake\Console\ConsoleOptionParser - * @throws \Cake\Console\Exception\ConsoleException - */ - public function getOptionParser() - { - $parser = parent::getOptionParser(); - $initParser = [ - 'options' => [ - 'plugin' => [ - 'help' => 'Plugin name.', - 'short' => 'p' - ], - 'force' => [ - 'help' => 'Force overwriting.', - 'short' => 'f', - 'boolean' => true - ] - ], - 'arguments' => [ - 'language' => [ - 'help' => 'Two-letter language code.' - ] - ] - ]; - - $parser->setDescription( - 'I18n Shell generates .pot files(s) with translations.' - )->addSubcommand('extract', [ - 'help' => 'Extract the po translations from your application', - 'parser' => $this->Extract->getOptionParser() - ]) - ->addSubcommand('init', [ - 'help' => 'Init PO language file from POT file', - 'parser' => $initParser - ]); - - return $parser; - } -} diff --git a/vendor/cakephp/cakephp/src/Shell/OrmCacheShell.php b/vendor/cakephp/cakephp/src/Shell/OrmCacheShell.php deleted file mode 100644 index 7d44482..0000000 --- a/vendor/cakephp/cakephp/src/Shell/OrmCacheShell.php +++ /dev/null @@ -1,31 +0,0 @@ -out($loaded); - } - - /** - * Gets the option parser instance and configures it. - * - * @return \Cake\Console\ConsoleOptionParser - */ - public function getOptionParser() - { - $parser = parent::getOptionParser(); - - $parser->setDescription('Plugin Shell perform various tasks related to plugin.') - ->addSubcommand('assets', [ - 'help' => 'Symlink / copy plugin assets to app\'s webroot', - 'parser' => $this->Assets->getOptionParser() - ]) - ->addSubcommand('loaded', [ - 'help' => 'Lists all loaded plugins', - 'parser' => $parser, - ]) - ->addSubcommand('load', [ - 'help' => 'Loads a plugin', - 'parser' => $this->Load->getOptionParser(), - ]) - ->addSubcommand('unload', [ - 'help' => 'Unloads a plugin', - 'parser' => $this->Unload->getOptionParser(), - ]); - - return $parser; - } -} diff --git a/vendor/cakephp/cakephp/src/Shell/RoutesShell.php b/vendor/cakephp/cakephp/src/Shell/RoutesShell.php deleted file mode 100644 index a633a57..0000000 --- a/vendor/cakephp/cakephp/src/Shell/RoutesShell.php +++ /dev/null @@ -1,154 +0,0 @@ -options['_name']) ? $route->options['_name'] : $route->getName(); - $output[] = [$name, $route->template, json_encode($route->defaults)]; - } - $this->helper('table')->output($output); - $this->out(); - } - - /** - * Checks a url for the route that will be applied. - * - * @param string $url The URL to parse - * @return bool Success - */ - public function check($url) - { - try { - $request = new ServerRequest(['url' => $url]); - $route = Router::parseRequest($request); - $name = null; - foreach (Router::routes() as $r) { - if ($r->match($route)) { - $name = isset($r->options['_name']) ? $r->options['_name'] : $r->getName(); - break; - } - } - - unset($route['_matchedRoute']); - - $output = [ - ['Route name', 'URI template', 'Defaults'], - [$name, $url, json_encode($route)] - ]; - $this->helper('table')->output($output); - $this->out(); - } catch (MissingRouteException $e) { - $this->warn("'$url' did not match any routes."); - $this->out(); - - return false; - } - - return true; - } - - /** - * Generate a URL based on a set of parameters - * - * Takes variadic arguments of key/value pairs. - * @return bool Success - */ - public function generate() - { - try { - $args = $this->_splitArgs($this->args); - $url = Router::url($args); - $this->out("> $url"); - $this->out(); - } catch (MissingRouteException $e) { - $this->err('The provided parameters do not match any routes.'); - $this->out(); - - return false; - } - - return true; - } - - /** - * Get the option parser. - * - * @return \Cake\Console\ConsoleOptionParser - */ - public function getOptionParser() - { - $parser = parent::getOptionParser(); - $parser->setDescription( - 'Get the list of routes connected in this application. ' . - 'This tool also lets you test URL generation and URL parsing.' - )->addSubcommand('check', [ - 'help' => 'Check a URL string against the routes. ' . - 'Will output the routing parameters the route resolves to.' - ])->addSubcommand('generate', [ - 'help' => 'Check a routing array against the routes. ' . - "Will output the URL if there is a match.\n\n" . - 'Routing parameters should be supplied in a key:value format. ' . - 'For example `controller:Articles action:view 2`' - ]); - - return $parser; - } - - /** - * Split the CLI arguments into a hash. - * - * @param array $args The arguments to split. - * @return array - */ - protected function _splitArgs($args) - { - $out = []; - foreach ($args as $arg) { - if (strpos($arg, ':') !== false) { - list($key, $value) = explode(':', $arg); - if (in_array($value, ['true', 'false'])) { - $value = $value === 'true'; - } - $out[$key] = $value; - } else { - $out[] = $arg; - } - } - - return $out; - } -} diff --git a/vendor/cakephp/cakephp/src/Shell/ServerShell.php b/vendor/cakephp/cakephp/src/Shell/ServerShell.php deleted file mode 100644 index 6bcdea1..0000000 --- a/vendor/cakephp/cakephp/src/Shell/ServerShell.php +++ /dev/null @@ -1,181 +0,0 @@ -param('host')) { - $this->_host = $this->param('host'); - } - if ($this->param('port')) { - $this->_port = $this->param('port'); - } - if ($this->param('document_root')) { - $this->_documentRoot = $this->param('document_root'); - } - if ($this->param('ini_path')) { - $this->_iniPath = $this->param('ini_path'); - } - - // For Windows - if (substr($this->_documentRoot, -1, 1) === DIRECTORY_SEPARATOR) { - $this->_documentRoot = substr($this->_documentRoot, 0, strlen($this->_documentRoot) - 1); - } - if (preg_match("/^([a-z]:)[\\\]+(.+)$/i", $this->_documentRoot, $m)) { - $this->_documentRoot = $m[1] . '\\' . $m[2]; - } - - $this->_iniPath = rtrim($this->_iniPath, DIRECTORY_SEPARATOR); - if (preg_match("/^([a-z]:)[\\\]+(.+)$/i", $this->_iniPath, $m)) { - $this->_iniPath = $m[1] . '\\' . $m[2]; - } - - parent::startup(); - } - - /** - * Displays a header for the shell - * - * @return void - */ - protected function _welcome() - { - $this->out(); - $this->out(sprintf('Welcome to CakePHP %s Console', 'v' . Configure::version())); - $this->hr(); - $this->out(sprintf('App : %s', APP_DIR)); - $this->out(sprintf('Path: %s', APP)); - $this->out(sprintf('DocumentRoot: %s', $this->_documentRoot)); - $this->out(sprintf('Ini Path: %s', $this->_iniPath)); - $this->hr(); - } - - /** - * Override main() to handle action - * - * @return void - */ - public function main() - { - $command = sprintf( - 'php -S %s:%d -t %s', - $this->_host, - $this->_port, - escapeshellarg($this->_documentRoot) - ); - - if (!empty($this->_iniPath)) { - $command = sprintf('%s -c %s', $command, $this->_iniPath); - } - - $command = sprintf('%s %s', $command, escapeshellarg($this->_documentRoot . '/index.php')); - - $port = ':' . $this->_port; - $this->out(sprintf('built-in server is running in http://%s%s/', $this->_host, $port)); - $this->out(sprintf('You can exit with `CTRL-C`')); - system($command); - } - - /** - * Gets the option parser instance and configures it. - * - * @return \Cake\Console\ConsoleOptionParser - */ - public function getOptionParser() - { - $parser = parent::getOptionParser(); - - $parser->setDescription([ - 'PHP Built-in Server for CakePHP', - '[WARN] Don\'t use this in a production environment', - ])->addOption('host', [ - 'short' => 'H', - 'help' => 'ServerHost' - ])->addOption('port', [ - 'short' => 'p', - 'help' => 'ListenPort' - ])->addOption('ini_path', [ - 'short' => 'I', - 'help' => 'php.ini path' - ])->addOption('document_root', [ - 'short' => 'd', - 'help' => 'DocumentRoot' - ]); - - return $parser; - } -} diff --git a/vendor/cakephp/cakephp/src/Shell/Task/AssetsTask.php b/vendor/cakephp/cakephp/src/Shell/Task/AssetsTask.php deleted file mode 100644 index de193e5..0000000 --- a/vendor/cakephp/cakephp/src/Shell/Task/AssetsTask.php +++ /dev/null @@ -1,339 +0,0 @@ -_process($this->_list($name)); - } - - /** - * Copying plugin assets to app's webroot. For vendor namespaced plugin, - * parent folder for vendor name are created if required. - * - * @param string|null $name Name of plugin for which to symlink assets. - * If null all plugins will be processed. - * @return void - */ - public function copy($name = null) - { - $this->_process($this->_list($name), true, $this->param('overwrite')); - } - - /** - * Remove plugin assets from app's webroot. - * - * @param string|null $name Name of plugin for which to remove assets. - * If null all plugins will be processed. - * @return void - * @since 3.5.12 - */ - public function remove($name = null) - { - $plugins = $this->_list($name); - - foreach ($plugins as $plugin => $config) { - $this->out(); - $this->out('For plugin: ' . $plugin); - $this->hr(); - - $this->_remove($config); - } - - $this->out(); - $this->out('Done'); - } - - /** - * Get list of plugins to process. Plugins without a webroot directory are skipped. - * - * @param string|null $name Name of plugin for which to symlink assets. - * If null all plugins will be processed. - * @return array List of plugins with meta data. - */ - protected function _list($name = null) - { - if ($name === null) { - $pluginsList = Plugin::loaded(); - } else { - if (!Plugin::loaded($name)) { - $this->err(sprintf('Plugin %s is not loaded.', $name)); - - return []; - } - $pluginsList = [$name]; - } - - $plugins = []; - - foreach ($pluginsList as $plugin) { - $path = Plugin::path($plugin) . 'webroot'; - if (!is_dir($path)) { - $this->verbose('', 1); - $this->verbose( - sprintf('Skipping plugin %s. It does not have webroot folder.', $plugin), - 2 - ); - continue; - } - - $link = Inflector::underscore($plugin); - $dir = WWW_ROOT; - $namespaced = false; - if (strpos($link, '/') !== false) { - $namespaced = true; - $parts = explode('/', $link); - $link = array_pop($parts); - $dir = WWW_ROOT . implode(DIRECTORY_SEPARATOR, $parts) . DIRECTORY_SEPARATOR; - } - - $plugins[$plugin] = [ - 'srcPath' => Plugin::path($plugin) . 'webroot', - 'destDir' => $dir, - 'link' => $link, - 'namespaced' => $namespaced - ]; - } - - return $plugins; - } - - /** - * Process plugins - * - * @param array $plugins List of plugins to process - * @param bool $copy Force copy mode. Default false. - * @param bool $overwrite Overwrite existing files. - * @return void - */ - protected function _process($plugins, $copy = false, $overwrite = false) - { - $overwrite = (bool)$this->param('overwrite'); - - foreach ($plugins as $plugin => $config) { - $this->out(); - $this->out('For plugin: ' . $plugin); - $this->hr(); - - if ($config['namespaced'] && - !is_dir($config['destDir']) && - !$this->_createDirectory($config['destDir']) - ) { - continue; - } - - $dest = $config['destDir'] . $config['link']; - - if (file_exists($dest)) { - if ($overwrite && !$this->_remove($config)) { - continue; - } elseif (!$overwrite) { - $this->verbose( - $dest . ' already exists', - 1 - ); - - continue; - } - } - - if (!$copy) { - $result = $this->_createSymlink( - $config['srcPath'], - $dest - ); - if ($result) { - continue; - } - } - - $this->_copyDirectory( - $config['srcPath'], - $dest - ); - } - - $this->out(); - $this->out('Done'); - } - - /** - * Remove folder/symlink. - * - * @param array $config Plugin config. - * @return bool - */ - protected function _remove($config) - { - if ($config['namespaced'] && !is_dir($config['destDir'])) { - $this->verbose( - $config['destDir'] . $config['link'] . ' does not exist', - 1 - ); - - return false; - } - - $dest = $config['destDir'] . $config['link']; - - if (!file_exists($dest)) { - $this->verbose( - $dest . ' does not exist', - 1 - ); - - return false; - } - - if (is_link($dest)) { - // @codingStandardsIgnoreLine - if (@unlink($dest)) { - $this->out('Unlinked ' . $dest); - - return true; - } else { - $this->err('Failed to unlink ' . $dest); - - return false; - } - } - - $folder = new Folder($dest); - if ($folder->delete()) { - $this->out('Deleted ' . $dest); - - return true; - } else { - $this->err('Failed to delete ' . $dest); - - return false; - } - } - - /** - * Create directory - * - * @param string $dir Directory name - * @return bool - */ - protected function _createDirectory($dir) - { - $old = umask(0); - // @codingStandardsIgnoreStart - $result = @mkdir($dir, 0755, true); - // @codingStandardsIgnoreEnd - umask($old); - - if ($result) { - $this->out('Created directory ' . $dir); - - return true; - } - - $this->err('Failed creating directory ' . $dir); - - return false; - } - - /** - * Create symlink - * - * @param string $target Target directory - * @param string $link Link name - * @return bool - */ - protected function _createSymlink($target, $link) - { - // @codingStandardsIgnoreStart - $result = @symlink($target, $link); - // @codingStandardsIgnoreEnd - - if ($result) { - $this->out('Created symlink ' . $link); - - return true; - } - - return false; - } - - /** - * Copy directory - * - * @param string $source Source directory - * @param string $destination Destination directory - * @return bool - */ - protected function _copyDirectory($source, $destination) - { - $folder = new Folder($source); - if ($folder->copy(['to' => $destination])) { - $this->out('Copied assets to directory ' . $destination); - - return true; - } - - $this->err('Error copying assets to directory ' . $destination); - - return false; - } - - /** - * Gets the option parser instance and configures it. - * - * @return \Cake\Console\ConsoleOptionParser - */ - public function getOptionParser() - { - $parser = parent::getOptionParser(); - - $parser->addSubcommand('symlink', [ - 'help' => 'Symlink (copy as fallback) plugin assets to app\'s webroot.' - ])->addSubcommand('copy', [ - 'help' => 'Copy plugin assets to app\'s webroot.' - ])->addSubcommand('remove', [ - 'help' => 'Remove plugin assets from app\'s webroot.' - ])->addArgument('name', [ - 'help' => 'A specific plugin you want to symlink assets for.', - 'optional' => true, - ])->addOption('overwrite', [ - 'help' => 'Overwrite existing symlink / folder / files.', - 'default' => false, - 'boolean' => true - ]); - - return $parser; - } -} diff --git a/vendor/cakephp/cakephp/src/Shell/Task/CommandTask.php b/vendor/cakephp/cakephp/src/Shell/Task/CommandTask.php deleted file mode 100644 index 92dda1f..0000000 --- a/vendor/cakephp/cakephp/src/Shell/Task/CommandTask.php +++ /dev/null @@ -1,289 +0,0 @@ - null, 'app' => null]; - - $appPath = App::path('Shell'); - $shellList = $this->_findShells($shellList, $appPath[0], 'app', $skipFiles); - - $appPath = App::path('Command'); - $shellList = $this->_findShells($shellList, $appPath[0], 'app', $skipFiles); - - $skipCore = array_merge($skipFiles, $hiddenCommands, $shellList['app']); - $corePath = dirname(__DIR__); - $shellList = $this->_findShells($shellList, $corePath, 'CORE', $skipCore); - - $corePath = dirname(dirname(__DIR__)) . DIRECTORY_SEPARATOR . 'Command'; - $shellList = $this->_findShells($shellList, $corePath, 'CORE', $skipCore); - - foreach ($plugins as $plugin) { - $pluginPath = Plugin::classPath($plugin) . 'Shell'; - $shellList = $this->_findShells($shellList, $pluginPath, $plugin, []); - } - - return array_filter($shellList); - } - - /** - * Find shells in $path and add them to $shellList - * - * @param array $shellList The shell listing array. - * @param string $path The path to look in. - * @param string $key The key to add shells to - * @param array $skip A list of commands to exclude. - * @return array The updated list of shells. - */ - protected function _findShells($shellList, $path, $key, $skip) - { - $shells = $this->_scanDir($path); - - return $this->_appendShells($key, $shells, $shellList, $skip); - } - - /** - * Scan the provided paths for shells, and append them into $shellList - * - * @param string $type The type of object. - * @param array $shells The shell name. - * @param array $shellList List of shells. - * @param array $skip List of command names to skip. - * @return array The updated $shellList - */ - protected function _appendShells($type, $shells, $shellList, $skip) - { - if (!isset($shellList[$type])) { - $shellList[$type] = []; - } - - foreach ($shells as $shell) { - $name = Inflector::underscore(preg_replace('/(Shell|Command)$/', '', $shell)); - if (!in_array($name, $skip, true)) { - $shellList[$type][] = $name; - } - } - sort($shellList[$type]); - - return $shellList; - } - - /** - * Scan a directory for .php files and return the class names that - * should be within them. - * - * @param string $dir The directory to read. - * @return array The list of shell classnames based on conventions. - */ - protected function _scanDir($dir) - { - $dir = new Folder($dir); - $contents = $dir->read(true, true); - if (empty($contents[1])) { - return []; - } - $shells = []; - foreach ($contents[1] as $file) { - if (substr($file, -4) !== '.php') { - continue; - } - $shells[] = substr($file, 0, -4); - } - - return $shells; - } - - /** - * Return a list of all commands - * - * @return array - */ - public function commands() - { - $shellList = $this->getShellList(); - $flatten = Hash::flatten($shellList); - $duplicates = array_intersect($flatten, array_unique(array_diff_key($flatten, array_unique($flatten)))); - $duplicates = Hash::expand($duplicates); - - $options = []; - foreach ($shellList as $type => $commands) { - foreach ($commands as $shell) { - $prefix = ''; - if (!in_array(strtolower($type), ['app', 'core']) && - isset($duplicates[$type]) && - in_array($shell, $duplicates[$type]) - ) { - $prefix = $type . '.'; - } - - $options[] = $prefix . $shell; - } - } - - return $options; - } - - /** - * Return a list of subcommands for a given command - * - * @param string $commandName The command you want subcommands from. - * @return array - */ - public function subCommands($commandName) - { - $Shell = $this->getShell($commandName); - - if (!$Shell) { - return []; - } - - $taskMap = $this->Tasks->normalizeArray((array)$Shell->tasks); - $return = array_keys($taskMap); - $return = array_map('Cake\Utility\Inflector::underscore', $return); - - $shellMethodNames = ['main', 'help', 'getOptionParser', 'initialize', 'runCommand']; - - $baseClasses = ['Object', 'Shell', 'AppShell']; - - $Reflection = new ReflectionClass($Shell); - $methods = $Reflection->getMethods(ReflectionMethod::IS_PUBLIC); - $methodNames = []; - foreach ($methods as $method) { - $declaringClass = $method->getDeclaringClass()->getShortName(); - if (!in_array($declaringClass, $baseClasses)) { - $methodNames[] = $method->getName(); - } - } - - $return = array_merge($return, array_diff($methodNames, $shellMethodNames)); - sort($return); - - return $return; - } - - /** - * Get Shell instance for the given command - * - * @param string $commandName The command you want. - * @return \Cake\Console\Shell|bool Shell instance if the command can be found, false otherwise. - */ - public function getShell($commandName) - { - list($pluginDot, $name) = pluginSplit($commandName, true); - - if (in_array(strtolower($pluginDot), ['app.', 'core.'])) { - $commandName = $name; - $pluginDot = ''; - } - - if (!in_array($commandName, $this->commands()) && (empty($pluginDot) && !in_array($name, $this->commands()))) { - return false; - } - - if (empty($pluginDot)) { - $shellList = $this->getShellList(); - - if (!in_array($commandName, $shellList['app']) && !in_array($commandName, $shellList['CORE'])) { - unset($shellList['CORE'], $shellList['app']); - foreach ($shellList as $plugin => $commands) { - if (in_array($commandName, $commands)) { - $pluginDot = $plugin . '.'; - break; - } - } - } - } - - $name = Inflector::camelize($name); - $pluginDot = Inflector::camelize($pluginDot); - $class = App::className($pluginDot . $name, 'Shell', 'Shell'); - if (!$class) { - return false; - } - - /* @var \Cake\Console\Shell $Shell */ - $Shell = new $class(); - $Shell->plugin = trim($pluginDot, '.'); - $Shell->initialize(); - - return $Shell; - } - - /** - * Get options list for the given command or subcommand - * - * @param string $commandName The command to get options for. - * @param string $subCommandName The subcommand to get options for. Can be empty to get options for the command. - * If this parameter is used, the subcommand must be a valid subcommand of the command passed - * @return array Options list for the given command or subcommand - */ - public function options($commandName, $subCommandName = '') - { - $Shell = $this->getShell($commandName); - - if (!$Shell) { - return []; - } - - $parser = $Shell->getOptionParser(); - - if (!empty($subCommandName)) { - $subCommandName = Inflector::camelize($subCommandName); - if ($Shell->hasTask($subCommandName)) { - $parser = $Shell->{$subCommandName}->getOptionParser(); - } else { - return []; - } - } - - $options = []; - $array = $parser->options(); - /* @var \Cake\Console\ConsoleInputOption $obj */ - foreach ($array as $name => $obj) { - $options[] = "--$name"; - $short = $obj->short(); - if ($short) { - $options[] = "-$short"; - } - } - - return $options; - } -} diff --git a/vendor/cakephp/cakephp/src/Shell/Task/ExtractTask.php b/vendor/cakephp/cakephp/src/Shell/Task/ExtractTask.php deleted file mode 100644 index 1912715..0000000 --- a/vendor/cakephp/cakephp/src/Shell/Task/ExtractTask.php +++ /dev/null @@ -1,756 +0,0 @@ -_paths) > 0 ? $this->_paths : ['None']; - $message = sprintf( - "Current paths: %s\nWhat is the path you would like to extract?\n[Q]uit [D]one", - implode(', ', $currentPaths) - ); - $response = $this->in($message, null, $defaultPath); - if (strtoupper($response) === 'Q') { - $this->err('Extract Aborted'); - $this->_stop(); - - return; - } - if (strtoupper($response) === 'D' && count($this->_paths)) { - $this->out(); - - return; - } - if (strtoupper($response) === 'D') { - $this->warn('No directories selected. Please choose a directory.'); - } elseif (is_dir($response)) { - $this->_paths[] = $response; - $defaultPath = 'D'; - } else { - $this->err('The directory path you supplied was not found. Please try again.'); - } - $this->out(); - } - } - - /** - * Execution method always used for tasks - * - * @return void - */ - public function main() - { - if (!empty($this->params['exclude'])) { - $this->_exclude = explode(',', $this->params['exclude']); - } - if (isset($this->params['files']) && !is_array($this->params['files'])) { - $this->_files = explode(',', $this->params['files']); - } - if (isset($this->params['paths'])) { - $this->_paths = explode(',', $this->params['paths']); - } elseif (isset($this->params['plugin'])) { - $plugin = Inflector::camelize($this->params['plugin']); - if (!Plugin::loaded($plugin)) { - Plugin::load($plugin); - } - $this->_paths = [Plugin::classPath($plugin)]; - $this->params['plugin'] = $plugin; - } else { - $this->_getPaths(); - } - - if (isset($this->params['extract-core'])) { - $this->_extractCore = !(strtolower($this->params['extract-core']) === 'no'); - } else { - $response = $this->in('Would you like to extract the messages from the CakePHP core?', ['y', 'n'], 'n'); - $this->_extractCore = strtolower($response) === 'y'; - } - - if (!empty($this->params['exclude-plugins']) && $this->_isExtractingApp()) { - $this->_exclude = array_merge($this->_exclude, App::path('Plugin')); - } - - if (!empty($this->params['validation-domain'])) { - $this->_validationDomain = $this->params['validation-domain']; - } - - if ($this->_extractCore) { - $this->_paths[] = CAKE; - } - - if (isset($this->params['output'])) { - $this->_output = $this->params['output']; - } elseif (isset($this->params['plugin'])) { - $this->_output = $this->_paths[0] . 'Locale'; - } else { - $message = "What is the path you would like to output?\n[Q]uit"; - while (true) { - $response = $this->in($message, null, rtrim($this->_paths[0], DIRECTORY_SEPARATOR) . DIRECTORY_SEPARATOR . 'Locale'); - if (strtoupper($response) === 'Q') { - $this->err('Extract Aborted'); - $this->_stop(); - - return; - } - if ($this->_isPathUsable($response)) { - $this->_output = $response . DIRECTORY_SEPARATOR; - break; - } - - $this->err(''); - $this->err( - 'The directory path you supplied was ' . - 'not found. Please try again.' - ); - $this->out(); - } - } - - if (isset($this->params['merge'])) { - $this->_merge = !(strtolower($this->params['merge']) === 'no'); - } else { - $this->out(); - $response = $this->in('Would you like to merge all domain strings into the default.pot file?', ['y', 'n'], 'n'); - $this->_merge = strtolower($response) === 'y'; - } - - if (empty($this->_files)) { - $this->_searchFiles(); - } - - $this->_output = rtrim($this->_output, DIRECTORY_SEPARATOR) . DIRECTORY_SEPARATOR; - if (!$this->_isPathUsable($this->_output)) { - $this->err(sprintf('The output directory %s was not found or writable.', $this->_output)); - $this->_stop(); - - return; - } - - $this->_extract(); - } - - /** - * Add a translation to the internal translations property - * - * Takes care of duplicate translations - * - * @param string $domain The domain - * @param string $msgid The message string - * @param array $details Context and plural form if any, file and line references - * @return void - */ - protected function _addTranslation($domain, $msgid, $details = []) - { - $context = isset($details['msgctxt']) ? $details['msgctxt'] : ''; - - if (empty($this->_translations[$domain][$msgid][$context])) { - $this->_translations[$domain][$msgid][$context] = [ - 'msgid_plural' => false - ]; - } - - if (isset($details['msgid_plural'])) { - $this->_translations[$domain][$msgid][$context]['msgid_plural'] = $details['msgid_plural']; - } - - if (isset($details['file'])) { - $line = isset($details['line']) ? $details['line'] : 0; - $this->_translations[$domain][$msgid][$context]['references'][$details['file']][] = $line; - } - } - - /** - * Extract text - * - * @return void - */ - protected function _extract() - { - $this->out(); - $this->out(); - $this->out('Extracting...'); - $this->hr(); - $this->out('Paths:'); - foreach ($this->_paths as $path) { - $this->out(' ' . $path); - } - $this->out('Output Directory: ' . $this->_output); - $this->hr(); - $this->_extractTokens(); - $this->_buildFiles(); - $this->_writeFiles(); - $this->_paths = $this->_files = $this->_storage = []; - $this->_translations = $this->_tokens = []; - $this->out(); - $this->out('Done.'); - } - - /** - * Gets the option parser instance and configures it. - * - * @return \Cake\Console\ConsoleOptionParser - */ - public function getOptionParser() - { - $parser = parent::getOptionParser(); - $parser->setDescription( - 'CakePHP Language String Extraction:' - )->addOption('app', [ - 'help' => 'Directory where your application is located.' - ])->addOption('paths', [ - 'help' => 'Comma separated list of paths.' - ])->addOption('merge', [ - 'help' => 'Merge all domain strings into the default.po file.', - 'choices' => ['yes', 'no'] - ])->addOption('output', [ - 'help' => 'Full path to output directory.' - ])->addOption('files', [ - 'help' => 'Comma separated list of files.' - ])->addOption('exclude-plugins', [ - 'boolean' => true, - 'default' => true, - 'help' => 'Ignores all files in plugins if this command is run inside from the same app directory.' - ])->addOption('plugin', [ - 'help' => 'Extracts tokens only from the plugin specified and puts the result in the plugin\'s Locale directory.' - ])->addOption('ignore-model-validation', [ - 'boolean' => true, - 'default' => false, - 'help' => 'Ignores validation messages in the $validate property.' . - ' If this flag is not set and the command is run from the same app directory,' . - ' all messages in model validation rules will be extracted as tokens.' - ])->addOption('validation-domain', [ - 'help' => 'If set to a value, the localization domain to be used for model validation messages.' - ])->addOption('exclude', [ - 'help' => 'Comma separated list of directories to exclude.' . - ' Any path containing a path segment with the provided values will be skipped. E.g. test,vendors' - ])->addOption('overwrite', [ - 'boolean' => true, - 'default' => false, - 'help' => 'Always overwrite existing .pot files.' - ])->addOption('extract-core', [ - 'help' => 'Extract messages from the CakePHP core libs.', - 'choices' => ['yes', 'no'] - ])->addOption('no-location', [ - 'boolean' => true, - 'default' => false, - 'help' => 'Do not write file locations for each extracted message.', - ]); - - return $parser; - } - - /** - * Extract tokens out of all files to be processed - * - * @return void - */ - protected function _extractTokens() - { - /** @var \Cake\Shell\Helper\ProgressHelper $progress */ - $progress = $this->helper('progress'); - $progress->init(['total' => count($this->_files)]); - $isVerbose = $this->param('verbose'); - - foreach ($this->_files as $file) { - $this->_file = $file; - if ($isVerbose) { - $this->out(sprintf('Processing %s...', $file), 1, Shell::VERBOSE); - } - - $code = file_get_contents($file); - $allTokens = token_get_all($code); - - $this->_tokens = []; - foreach ($allTokens as $token) { - if (!is_array($token) || ($token[0] !== T_WHITESPACE && $token[0] !== T_INLINE_HTML)) { - $this->_tokens[] = $token; - } - } - unset($allTokens); - $this->_parse('__', ['singular']); - $this->_parse('__n', ['singular', 'plural']); - $this->_parse('__d', ['domain', 'singular']); - $this->_parse('__dn', ['domain', 'singular', 'plural']); - $this->_parse('__x', ['context', 'singular']); - $this->_parse('__xn', ['context', 'singular', 'plural']); - $this->_parse('__dx', ['domain', 'context', 'singular']); - $this->_parse('__dxn', ['domain', 'context', 'singular', 'plural']); - - if (!$isVerbose) { - $progress->increment(1); - $progress->draw(); - } - } - } - - /** - * Parse tokens - * - * @param string $functionName Function name that indicates translatable string (e.g: '__') - * @param array $map Array containing what variables it will find (e.g: domain, singular, plural) - * @return void - */ - protected function _parse($functionName, $map) - { - $count = 0; - $tokenCount = count($this->_tokens); - - while (($tokenCount - $count) > 1) { - $countToken = $this->_tokens[$count]; - $firstParenthesis = $this->_tokens[$count + 1]; - if (!is_array($countToken)) { - $count++; - continue; - } - - list($type, $string, $line) = $countToken; - if (($type == T_STRING) && ($string === $functionName) && ($firstParenthesis === '(')) { - $position = $count; - $depth = 0; - - while (!$depth) { - if ($this->_tokens[$position] === '(') { - $depth++; - } elseif ($this->_tokens[$position] === ')') { - $depth--; - } - $position++; - } - - $mapCount = count($map); - $strings = $this->_getStrings($position, $mapCount); - - if ($mapCount === count($strings)) { - $singular = null; - extract(array_combine($map, $strings)); - $domain = isset($domain) ? $domain : 'default'; - $details = [ - 'file' => $this->_file, - 'line' => $line, - ]; - if (isset($plural)) { - $details['msgid_plural'] = $plural; - } - if (isset($context)) { - $details['msgctxt'] = $context; - } - $this->_addTranslation($domain, $singular, $details); - } elseif (strpos($this->_file, CAKE_CORE_INCLUDE_PATH) === false) { - $this->_markerError($this->_file, $line, $functionName, $count); - } - } - $count++; - } - } - - /** - * Build the translate template file contents out of obtained strings - * - * @return void - */ - protected function _buildFiles() - { - $paths = $this->_paths; - $paths[] = realpath(APP) . DIRECTORY_SEPARATOR; - - usort($paths, function ($a, $b) { - return strlen($a) - strlen($b); - }); - - foreach ($this->_translations as $domain => $translations) { - foreach ($translations as $msgid => $contexts) { - foreach ($contexts as $context => $details) { - $plural = $details['msgid_plural']; - $files = $details['references']; - $occurrences = []; - foreach ($files as $file => $lines) { - $lines = array_unique($lines); - $occurrences[] = $file . ':' . implode(';', $lines); - } - $occurrences = implode("\n#: ", $occurrences); - $header = ''; - if (!$this->param('no-location')) { - $header = '#: ' . str_replace(DIRECTORY_SEPARATOR, '/', str_replace($paths, '', $occurrences)) . "\n"; - } - - $sentence = ''; - if ($context !== '') { - $sentence .= "msgctxt \"{$context}\"\n"; - } - if ($plural === false) { - $sentence .= "msgid \"{$msgid}\"\n"; - $sentence .= "msgstr \"\"\n\n"; - } else { - $sentence .= "msgid \"{$msgid}\"\n"; - $sentence .= "msgid_plural \"{$plural}\"\n"; - $sentence .= "msgstr[0] \"\"\n"; - $sentence .= "msgstr[1] \"\"\n\n"; - } - - if ($domain !== 'default' && $this->_merge) { - $this->_store('default', $header, $sentence); - } else { - $this->_store($domain, $header, $sentence); - } - } - } - } - } - - /** - * Prepare a file to be stored - * - * @param string $domain The domain - * @param string $header The header content. - * @param string $sentence The sentence to store. - * @return void - */ - protected function _store($domain, $header, $sentence) - { - if (!isset($this->_storage[$domain])) { - $this->_storage[$domain] = []; - } - if (!isset($this->_storage[$domain][$sentence])) { - $this->_storage[$domain][$sentence] = $header; - } else { - $this->_storage[$domain][$sentence] .= $header; - } - } - - /** - * Write the files that need to be stored - * - * @return void - */ - protected function _writeFiles() - { - $overwriteAll = false; - if (!empty($this->params['overwrite'])) { - $overwriteAll = true; - } - foreach ($this->_storage as $domain => $sentences) { - $output = $this->_writeHeader(); - foreach ($sentences as $sentence => $header) { - $output .= $header . $sentence; - } - - // Remove vendor prefix if present. - $slashPosition = strpos($domain, '/'); - if ($slashPosition !== false) { - $domain = substr($domain, $slashPosition + 1); - } - - $filename = str_replace('/', '_', $domain) . '.pot'; - $File = new File($this->_output . $filename); - $response = ''; - while ($overwriteAll === false && $File->exists() && strtoupper($response) !== 'Y') { - $this->out(); - $response = $this->in( - sprintf('Error: %s already exists in this location. Overwrite? [Y]es, [N]o, [A]ll', $filename), - ['y', 'n', 'a'], - 'y' - ); - if (strtoupper($response) === 'N') { - $response = ''; - while (!$response) { - $response = $this->in('What would you like to name this file?', null, 'new_' . $filename); - $File = new File($this->_output . $response); - $filename = $response; - } - } elseif (strtoupper($response) === 'A') { - $overwriteAll = true; - } - } - $File->write($output); - $File->close(); - } - } - - /** - * Build the translation template header - * - * @return string Translation template header - */ - protected function _writeHeader() - { - $output = "# LANGUAGE translation of CakePHP Application\n"; - $output .= "# Copyright YEAR NAME \n"; - $output .= "#\n"; - $output .= "#, fuzzy\n"; - $output .= "msgid \"\"\n"; - $output .= "msgstr \"\"\n"; - $output .= "\"Project-Id-Version: PROJECT VERSION\\n\"\n"; - $output .= '"POT-Creation-Date: ' . date('Y-m-d H:iO') . "\\n\"\n"; - $output .= "\"PO-Revision-Date: YYYY-mm-DD HH:MM+ZZZZ\\n\"\n"; - $output .= "\"Last-Translator: NAME \\n\"\n"; - $output .= "\"Language-Team: LANGUAGE \\n\"\n"; - $output .= "\"MIME-Version: 1.0\\n\"\n"; - $output .= "\"Content-Type: text/plain; charset=utf-8\\n\"\n"; - $output .= "\"Content-Transfer-Encoding: 8bit\\n\"\n"; - $output .= "\"Plural-Forms: nplurals=INTEGER; plural=EXPRESSION;\\n\"\n\n"; - - return $output; - } - - /** - * Get the strings from the position forward - * - * @param int $position Actual position on tokens array - * @param int $target Number of strings to extract - * @return array Strings extracted - */ - protected function _getStrings(&$position, $target) - { - $strings = []; - $count = count($strings); - while ($count < $target && ($this->_tokens[$position] === ',' || $this->_tokens[$position][0] == T_CONSTANT_ENCAPSED_STRING || $this->_tokens[$position][0] == T_LNUMBER)) { - $count = count($strings); - if ($this->_tokens[$position][0] == T_CONSTANT_ENCAPSED_STRING && $this->_tokens[$position + 1] === '.') { - $string = ''; - while ($this->_tokens[$position][0] == T_CONSTANT_ENCAPSED_STRING || $this->_tokens[$position] === '.') { - if ($this->_tokens[$position][0] == T_CONSTANT_ENCAPSED_STRING) { - $string .= $this->_formatString($this->_tokens[$position][1]); - } - $position++; - } - $strings[] = $string; - } elseif ($this->_tokens[$position][0] == T_CONSTANT_ENCAPSED_STRING) { - $strings[] = $this->_formatString($this->_tokens[$position][1]); - } elseif ($this->_tokens[$position][0] == T_LNUMBER) { - $strings[] = $this->_tokens[$position][1]; - } - $position++; - } - - return $strings; - } - - /** - * Format a string to be added as a translatable string - * - * @param string $string String to format - * @return string Formatted string - */ - protected function _formatString($string) - { - $quote = substr($string, 0, 1); - $string = substr($string, 1, -1); - if ($quote === '"') { - $string = stripcslashes($string); - } else { - $string = strtr($string, ["\\'" => "'", '\\\\' => '\\']); - } - $string = str_replace("\r\n", "\n", $string); - - return addcslashes($string, "\0..\37\\\""); - } - - /** - * Indicate an invalid marker on a processed file - * - * @param string $file File where invalid marker resides - * @param int $line Line number - * @param string $marker Marker found - * @param int $count Count - * @return void - */ - protected function _markerError($file, $line, $marker, $count) - { - $this->err(sprintf("Invalid marker content in %s:%s\n* %s(", $file, $line, $marker)); - $count += 2; - $tokenCount = count($this->_tokens); - $parenthesis = 1; - - while ((($tokenCount - $count) > 0) && $parenthesis) { - if (is_array($this->_tokens[$count])) { - $this->err($this->_tokens[$count][1], false); - } else { - $this->err($this->_tokens[$count], false); - if ($this->_tokens[$count] === '(') { - $parenthesis++; - } - - if ($this->_tokens[$count] === ')') { - $parenthesis--; - } - } - $count++; - } - $this->err("\n", true); - } - - /** - * Search files that may contain translatable strings - * - * @return void - */ - protected function _searchFiles() - { - $pattern = false; - if (!empty($this->_exclude)) { - $exclude = []; - foreach ($this->_exclude as $e) { - if (DIRECTORY_SEPARATOR !== '\\' && $e[0] !== DIRECTORY_SEPARATOR) { - $e = DIRECTORY_SEPARATOR . $e; - } - $exclude[] = preg_quote($e, '/'); - } - $pattern = '/' . implode('|', $exclude) . '/'; - } - foreach ($this->_paths as $path) { - $path = realpath($path) . DIRECTORY_SEPARATOR; - $Folder = new Folder($path); - $files = $Folder->findRecursive('.*\.(php|ctp|thtml|inc|tpl)', true); - if (!empty($pattern)) { - $files = preg_grep($pattern, $files, PREG_GREP_INVERT); - $files = array_values($files); - } - $this->_files = array_merge($this->_files, $files); - } - $this->_files = array_unique($this->_files); - } - - /** - * Returns whether this execution is meant to extract string only from directories in folder represented by the - * APP constant, i.e. this task is extracting strings from same application. - * - * @return bool - */ - protected function _isExtractingApp() - { - return $this->_paths === [APP]; - } - - /** - * Checks whether or not a given path is usable for writing. - * - * @param string $path Path to folder - * @return bool true if it exists and is writable, false otherwise - */ - protected function _isPathUsable($path) - { - if (!is_dir($path)) { - mkdir($path, 0770, true); - } - - return is_dir($path) && is_writable($path); - } -} diff --git a/vendor/cakephp/cakephp/src/Shell/Task/LoadTask.php b/vendor/cakephp/cakephp/src/Shell/Task/LoadTask.php deleted file mode 100644 index 8fc005d..0000000 --- a/vendor/cakephp/cakephp/src/Shell/Task/LoadTask.php +++ /dev/null @@ -1,175 +0,0 @@ -params['cli']) { - $filename .= '_cli'; - } - - $this->bootstrap = ROOT . DIRECTORY_SEPARATOR . 'config' . DIRECTORY_SEPARATOR . $filename . '.php'; - - if (!$plugin) { - $this->err('You must provide a plugin name in CamelCase format.'); - $this->err('To load an "Example" plugin, run `cake plugin load Example`.'); - - return false; - } - - $options = $this->makeOptions(); - - $app = APP . 'Application.php'; - if (file_exists($app) && !$this->param('no_app')) { - $this->modifyApplication($app, $plugin, $options); - - return true; - } - - return $this->_modifyBootstrap($plugin, $options); - } - - /** - * Create options string for the load call. - * - * @return string - */ - protected function makeOptions() - { - $autoloadString = $this->param('autoload') ? "'autoload' => true" : ''; - $bootstrapString = $this->param('bootstrap') ? "'bootstrap' => true" : ''; - $routesString = $this->param('routes') ? "'routes' => true" : ''; - - return implode(', ', array_filter([$autoloadString, $bootstrapString, $routesString])); - } - - /** - * Modify the application class - * - * @param string $app The Application file to modify. - * @param string $plugin The plugin name to add. - * @param string $options The plugin options to add - * @return void - */ - protected function modifyApplication($app, $plugin, $options) - { - $file = new File($app, false); - $contents = $file->read(); - - $append = "\n \$this->addPlugin('%s', [%s]);\n"; - $insert = str_replace(', []', '', sprintf($append, $plugin, $options)); - - if (!preg_match('/function bootstrap\(\)/m', $contents)) { - $this->abort('Your Application class does not have a bootstrap() method. Please add one.'); - } else { - $contents = preg_replace('/(function bootstrap\(\)(?:\s+)\{)/m', '$1' . $insert, $contents); - } - $file->write($contents); - - $this->out(''); - $this->out(sprintf('%s modified', $app)); - } - - /** - * Update the applications bootstrap.php file. - * - * @param string $plugin Name of plugin. - * @param string $options The options string - * @return bool If modify passed. - */ - protected function _modifyBootstrap($plugin, $options) - { - $bootstrap = new File($this->bootstrap, false); - $contents = $bootstrap->read(); - if (!preg_match("@\n\s*Plugin::loadAll@", $contents)) { - $append = "\nPlugin::load('%s', [%s]);\n"; - - $bootstrap->append(str_replace(', []', '', sprintf($append, $plugin, $options))); - $this->out(''); - $this->out(sprintf('%s modified', $this->bootstrap)); - - return true; - } - - return false; - } - - /** - * GetOptionParser method. - * - * @return \Cake\Console\ConsoleOptionParser - */ - public function getOptionParser() - { - $parser = parent::getOptionParser(); - - $parser->addOption('bootstrap', [ - 'short' => 'b', - 'help' => 'Will load bootstrap.php from plugin.', - 'boolean' => true, - 'default' => false, - ]) - ->addOption('routes', [ - 'short' => 'r', - 'help' => 'Will load routes.php from plugin.', - 'boolean' => true, - 'default' => false, - ]) - ->addOption('autoload', [ - 'help' => 'Will autoload the plugin using CakePHP.' . - 'Set to true if you are not using composer to autoload your plugin.', - 'boolean' => true, - 'default' => false, - ]) - ->addOption('cli', [ - 'help' => 'Use the bootstrap_cli file.', - 'boolean' => true, - 'default' => false, - ]) - ->addOption('no_app', [ - 'help' => 'Do not update the Application if it exist. Forces config/bootstrap.php to be updated.', - 'boolean' => true, - 'default' => false, - ]) - ->addArgument('plugin', [ - 'help' => 'Name of the plugin to load.', - ]); - - return $parser; - } -} diff --git a/vendor/cakephp/cakephp/src/Shell/Task/UnloadTask.php b/vendor/cakephp/cakephp/src/Shell/Task/UnloadTask.php deleted file mode 100644 index 6139e71..0000000 --- a/vendor/cakephp/cakephp/src/Shell/Task/UnloadTask.php +++ /dev/null @@ -1,147 +0,0 @@ -params['cli']) { - $filename .= '_cli'; - } - - $this->bootstrap = ROOT . DIRECTORY_SEPARATOR . 'config' . DIRECTORY_SEPARATOR . $filename . '.php'; - - if (!$plugin) { - $this->err('You must provide a plugin name in CamelCase format.'); - $this->err('To unload an "Example" plugin, run `cake plugin unload Example`.'); - - return false; - } - - $app = APP . 'Application.php'; - if (file_exists($app) && !$this->param('no_app')) { - $this->modifyApplication($app, $plugin); - - return true; - } - - return (bool)$this->_modifyBootstrap($plugin); - } - - /** - * Update the applications bootstrap.php file. - * - * @param string $app Path to the application to update. - * @param string $plugin Name of plugin. - * @return bool If modify passed. - */ - protected function modifyApplication($app, $plugin) - { - $finder = "@\\\$this\-\>addPlugin\(\s*'$plugin'(.|.\n|)+\);+@"; - - $content = file_get_contents($app); - $newContent = preg_replace($finder, '', $content); - - if ($newContent === $content) { - return false; - } - - file_put_contents($app, $newContent); - - $this->out(''); - $this->out(sprintf('%s modified', $app)); - - return true; - } - - /** - * Update the applications bootstrap.php file. - * - * @param string $plugin Name of plugin. - * @return bool If modify passed. - */ - protected function _modifyBootstrap($plugin) - { - $finder = "@\nPlugin::load\((.|.\n|\n\s\s|\n\t|)+'$plugin'(.|.\n|)+\);\n@"; - - $bootstrap = new File($this->bootstrap, false); - $content = $bootstrap->read(); - - if (!preg_match("@\n\s*Plugin::loadAll@", $content)) { - $newContent = preg_replace($finder, '', $content); - - if ($newContent === $content) { - return false; - } - - $bootstrap->write($newContent); - - $this->out(''); - $this->out(sprintf('%s modified', $this->bootstrap)); - - return true; - } - - return false; - } - - /** - * GetOptionParser method. - * - * @return \Cake\Console\ConsoleOptionParser - */ - public function getOptionParser() - { - $parser = parent::getOptionParser(); - - $parser->addOption('cli', [ - 'help' => 'Use the bootstrap_cli file.', - 'boolean' => true, - 'default' => false, - ]) - ->addOption('no_app', [ - 'help' => 'Do not update the Application if it exist. Forces config/bootstrap.php to be updated.', - 'boolean' => true, - 'default' => false, - ]) - ->addArgument('plugin', [ - 'help' => 'Name of the plugin to load.', - ]); - - return $parser; - } -} diff --git a/vendor/cakephp/cakephp/src/Template/Element/auto_table_warning.ctp b/vendor/cakephp/cakephp/src/Template/Element/auto_table_warning.ctp deleted file mode 100644 index 16628f1..0000000 --- a/vendor/cakephp/cakephp/src/Template/Element/auto_table_warning.ctp +++ /dev/null @@ -1,42 +0,0 @@ -genericInstances(); -if (!$autoTables) { - return; -} -?> -

Could this be caused by using Auto-Tables?

-

-Some of the Table objects in your application were created by instantiating "Cake\ORM\Table" -instead of any other specific subclass. -

-

This could be the cause for this exception. Auto-Tables are created for you under the following circumstances:

-
    -
  • The class for the specified table does not exist.
  • -
  • The Table was created with a typo: $this->getTableLocator()->get('Atricles');
  • -
  • The class file has a typo in the name or incorrect namespace: class Atricles extends Table
  • -
  • The file containing the class has a typo or incorrect casing: Atricles.php
  • -
  • The Table was used using associations but the association has a typo: $this->belongsTo('Atricles')
  • -
  • The table class resides in a Plugin but no plugin notation was used in the association definition.
  • -
-
-

Please try correcting the issue for the following table aliases:

-
    - $table) : ?> -
  • - -
-
diff --git a/vendor/cakephp/cakephp/src/Template/Element/exception_stack_trace.ctp b/vendor/cakephp/cakephp/src/Template/Element/exception_stack_trace.ctp deleted file mode 100644 index 5b4bf7c..0000000 --- a/vendor/cakephp/cakephp/src/Template/Element/exception_stack_trace.ctp +++ /dev/null @@ -1,62 +0,0 @@ - - -getTrace() as $i => $stack): - $excerpt = $params = []; - - if (isset($stack['file'], $stack['line'])): - $excerpt = Debugger::excerpt($stack['file'], $stack['line'], 4); - endif; - - if (isset($stack['file'])): - $file = $stack['file']; - else: - $file = '[internal function]'; - endif; - - if ($stack['function']): - if (!empty($stack['args'])): - foreach ((array)$stack['args'] as $arg): - $params[] = Debugger::exportVar($arg, 4); - endforeach; - else: - $params[] = 'No arguments'; - endif; - endif; -?> - - diff --git a/vendor/cakephp/cakephp/src/Template/Element/exception_stack_trace_nav.ctp b/vendor/cakephp/cakephp/src/Template/Element/exception_stack_trace_nav.ctp deleted file mode 100644 index 859c089..0000000 --- a/vendor/cakephp/cakephp/src/Template/Element/exception_stack_trace_nav.ctp +++ /dev/null @@ -1,43 +0,0 @@ - -toggle vendor stack frames - - diff --git a/vendor/cakephp/cakephp/src/Template/Element/plugin_class_error.ctp b/vendor/cakephp/cakephp/src/Template/Element/plugin_class_error.ctp deleted file mode 100644 index aebe9e8..0000000 --- a/vendor/cakephp/cakephp/src/Template/Element/plugin_class_error.ctp +++ /dev/null @@ -1,33 +0,0 @@ -
'; - -if (!Plugin::loaded($plugin)): - echo sprintf('Make sure your plugin %s is in the %s directory and was loaded.', h($plugin), $pluginPath); -else: - echo sprintf('Make sure your plugin was loaded from %s and Composer is able to autoload its classes, see %s and %s', - 'config' . DIRECTORY_SEPARATOR . 'bootstrap.php', - 'Loading a plugin', - 'Plugins - autoloading plugin classes' - ); -endif; - -?> diff --git a/vendor/cakephp/cakephp/src/Template/Error/duplicate_named_route.ctp b/vendor/cakephp/cakephp/src/Template/Error/duplicate_named_route.ctp deleted file mode 100644 index 236fdb1..0000000 --- a/vendor/cakephp/cakephp/src/Template/Error/duplicate_named_route.ctp +++ /dev/null @@ -1,61 +0,0 @@ -layout = 'dev_error'; - -$this->assign('title', 'Duplicate Named Route'); -$this->assign('templateName', 'duplicate_named_route.ctp'); - -$attributes = $error->getAttributes(); - -$this->start('subheading'); -?> - Error: - getMessage(); ?> -end() ?> - -start('file') ?> -

Route names must be unique across your entire application. -The same _name option cannot be used twice, -even if the names occur in different routing scopes. -Remove duplicate route names in your route configuration.

- - -

The passed context was:

-
-
-
- - - -

Duplicate Route

- - - '; - printf( - '', - $other->template, - Debugger::exportVar($other->defaults), - Debugger::exportVar($other->options) - ); - echo ''; - ?> -
TemplateDefaultsOptions
%s%s%s
- -end() ?> diff --git a/vendor/cakephp/cakephp/src/Template/Error/fatal_error.ctp b/vendor/cakephp/cakephp/src/Template/Error/fatal_error.ctp deleted file mode 100644 index 2226274..0000000 --- a/vendor/cakephp/cakephp/src/Template/Error/fatal_error.ctp +++ /dev/null @@ -1,38 +0,0 @@ -layout = 'dev_error'; - -$this->assign('title', 'Fatal Error'); -$this->assign('templateName', 'fatal_error.ctp'); - -$this->start('subheading'); -?> - Error: - getMessage()) ?> -
- - File - getFile()) ?> -
- Line: - getLine()) ?> -end() ?> - -start('file'); -if (extension_loaded('xdebug')): - xdebug_print_function_stack(); -endif; -$this->end(); diff --git a/vendor/cakephp/cakephp/src/Template/Error/missing_action.ctp b/vendor/cakephp/cakephp/src/Template/Error/missing_action.ctp deleted file mode 100644 index 243e2c3..0000000 --- a/vendor/cakephp/cakephp/src/Template/Error/missing_action.ctp +++ /dev/null @@ -1,86 +0,0 @@ -layout = 'dev_error'; - -$this->assign('title', sprintf('Missing Method in %s', h($class))); -$this->assign( - 'subheading', - sprintf('The action %s is not defined in %s', h($action), h($class)) -); -$this->assign('templateName', 'missing_action.ctp'); - -$this->start('file'); -?> -

- Error: - %s::%s() in file: %s.', h($class), h($action), $path); ?> -

- - - -
-end() ?> diff --git a/vendor/cakephp/cakephp/src/Template/Error/missing_behavior.ctp b/vendor/cakephp/cakephp/src/Template/Error/missing_behavior.ctp deleted file mode 100644 index 37c6189..0000000 --- a/vendor/cakephp/cakephp/src/Template/Error/missing_behavior.ctp +++ /dev/null @@ -1,68 +0,0 @@ -layout = 'dev_error'; - -$this->assign('templateName', 'missing_behavior.ctp'); - -$this->assign('title', 'Missing Behavior'); - -$this->start('subheading'); -printf('%s could not be found.', h($pluginDot . $class)); -echo $this->element('plugin_class_error', ['pluginPath' => $pluginPath]); -$this->end(); - -$this->start('file'); -?> -

- Error: - %s below in file: %s', h($class), $filePath . 'Model' . DIRECTORY_SEPARATOR . 'Behavior' . DIRECTORY_SEPARATOR . h($class) . '.php'); ?> -

- - -
-end() ?> diff --git a/vendor/cakephp/cakephp/src/Template/Error/missing_cell_view.ctp b/vendor/cakephp/cakephp/src/Template/Error/missing_cell_view.ctp deleted file mode 100644 index ad59435..0000000 --- a/vendor/cakephp/cakephp/src/Template/Error/missing_cell_view.ctp +++ /dev/null @@ -1,43 +0,0 @@ -layout = 'dev_error'; - -$this->assign('templateName', 'missing_cell_view.ctp'); -$this->assign('title', 'Missing Cell View'); - -$this->start('subheading'); -printf('The view for %sCell was not be found.', h(Inflector::camelize($name))); -$this->end(); - -$this->start('file'); -?> -

- Confirm you have created the file: "_ext) ?>" - in one of the following paths: -

-
    -_paths($this->plugin); - foreach ($paths as $path): - if (strpos($path, CORE_PATH) !== false) { - continue; - } - echo sprintf('
  • %sCell/%s/%s
  • ', h($path), h($name), h($file . $this->_ext)); - endforeach; -?> -
-end(); ?> diff --git a/vendor/cakephp/cakephp/src/Template/Error/missing_component.ctp b/vendor/cakephp/cakephp/src/Template/Error/missing_component.ctp deleted file mode 100644 index d9ff8ef..0000000 --- a/vendor/cakephp/cakephp/src/Template/Error/missing_component.ctp +++ /dev/null @@ -1,64 +0,0 @@ -layout = 'dev_error'; -$this->assign('title', 'Missing Component'); -$this->assign('templateName', 'missing_component.ctp'); - -$this->start('subheading'); -printf('%s could not be found.', h($pluginDot . $class)); -echo $this->element('plugin_class_error', ['pluginPath' => $pluginPath]); -$this->end(); - -$this->start('file'); -?> -

- Error: - %s below in file: %s', h($class), $filePath . 'Controller' . DIRECTORY_SEPARATOR . 'Component' . DIRECTORY_SEPARATOR . h($class) . '.php'); ?> -

- -
-end() ?> diff --git a/vendor/cakephp/cakephp/src/Template/Error/missing_connection.ctp b/vendor/cakephp/cakephp/src/Template/Error/missing_connection.ctp deleted file mode 100644 index fe9ed4b..0000000 --- a/vendor/cakephp/cakephp/src/Template/Error/missing_connection.ctp +++ /dev/null @@ -1,32 +0,0 @@ -layout = 'dev_error'; - -$this->assign('templateName', 'missing_connection.ctp'); -$this->assign('title', 'Missing Database Connection'); - - -$this->start('subheading'); ?> -A Database connection using was missing or unable to connect. -
-end(); - -$this->start('file'); -echo $this->element('auto_table_warning'); -$this->end(); diff --git a/vendor/cakephp/cakephp/src/Template/Error/missing_controller.ctp b/vendor/cakephp/cakephp/src/Template/Error/missing_controller.ctp deleted file mode 100644 index 503b7e4..0000000 --- a/vendor/cakephp/cakephp/src/Template/Error/missing_controller.ctp +++ /dev/null @@ -1,91 +0,0 @@ -layout = 'dev_error'; - -$this->assign('title', 'Missing Controller'); -$this->assign('templateName', 'missing_controller.ctp'); - -?> -start('subheading');?> -Error: - - Your routing resulted in as a controller name. - - Controller could not be found. - -end() ?> - - -start('file'); ?> - -

The controller name has not been properly inflected, and - could not be resolved to a controller that exists in your application.

- -

Ensure that your URL request->getUri()->getPath()) ?> is - using the same inflection style as your routes do. By default applications use DashedRoute - and URLs should use - to separate multi-word controller names.

- -

- In the case you tried to access a plugin controller make sure you added it to your composer file or you use the autoload option for the plugin. -

-

- Error: - Create the class Controller below in file: -

- - -
- -end(); ?> diff --git a/vendor/cakephp/cakephp/src/Template/Error/missing_datasource.ctp b/vendor/cakephp/cakephp/src/Template/Error/missing_datasource.ctp deleted file mode 100644 index 2102d82..0000000 --- a/vendor/cakephp/cakephp/src/Template/Error/missing_datasource.ctp +++ /dev/null @@ -1,29 +0,0 @@ -layout = 'dev_error'; - -$this->assign('title', 'Missing Datasource'); -$this->assign('templateName', 'missing_datasource.ctp'); - -$this->start('subheading'); -?> -Error: -Datasource class could not be found. - - - -end() ?> diff --git a/vendor/cakephp/cakephp/src/Template/Error/missing_datasource_config.ctp b/vendor/cakephp/cakephp/src/Template/Error/missing_datasource_config.ctp deleted file mode 100644 index 05b0fa1..0000000 --- a/vendor/cakephp/cakephp/src/Template/Error/missing_datasource_config.ctp +++ /dev/null @@ -1,29 +0,0 @@ -layout = 'dev_error'; - -$this->assign('title', 'Missing Datasource Configuration'); -$this->assign('templateName', 'missing_datasource_config.ctp'); - -$this->start('subheading'); -?> - Error: - - The datasource configuration was not found in config. - - - -end() ?> diff --git a/vendor/cakephp/cakephp/src/Template/Error/missing_helper.ctp b/vendor/cakephp/cakephp/src/Template/Error/missing_helper.ctp deleted file mode 100644 index 1bbecba..0000000 --- a/vendor/cakephp/cakephp/src/Template/Error/missing_helper.ctp +++ /dev/null @@ -1,65 +0,0 @@ -layout = 'dev_error'; -$this->assign('title', 'Missing Helper'); -$this->assign('templateName', 'missing_helper.ctp'); - -$this->start('subheading'); -?> - Error: - could not be found. - element('plugin_class_error', ['pluginPath' => $pluginPath]) ?> -end() ?> - -start('file') ?> -

- Error: - %s below in file: %s', h($class), $filePath . 'View' . DIRECTORY_SEPARATOR . 'Helper' . DIRECTORY_SEPARATOR . h($class) . '.php'); ?> -

- -
-end() ?> diff --git a/vendor/cakephp/cakephp/src/Template/Error/missing_layout.ctp b/vendor/cakephp/cakephp/src/Template/Error/missing_layout.ctp deleted file mode 100644 index d53649b..0000000 --- a/vendor/cakephp/cakephp/src/Template/Error/missing_layout.ctp +++ /dev/null @@ -1,42 +0,0 @@ -layout = 'dev_error'; - -$this->assign('title', 'Missing Layout'); -$this->assign('templateName', 'missing_layout.ctp'); - -$this->start('subheading'); -?> - Error: - The layout file can not be found or does not exist. -end() ?> - -start('file') ?> -

- Confirm you have created the file: in one of the following paths: -

-
    -_paths($this->plugin); - foreach ($paths as $path): - if (strpos($path, CORE_PATH) !== false) { - continue; - } - echo sprintf('
  • %s%s
  • ', h($path), h($file)); - endforeach; -?> -
-end() ?> diff --git a/vendor/cakephp/cakephp/src/Template/Error/missing_plugin.ctp b/vendor/cakephp/cakephp/src/Template/Error/missing_plugin.ctp deleted file mode 100644 index ec6f900..0000000 --- a/vendor/cakephp/cakephp/src/Template/Error/missing_plugin.ctp +++ /dev/null @@ -1,55 +0,0 @@ -layout = 'dev_error'; - -$pluginPath = Configure::read('App.paths.plugins.0'); - -$this->assign('title', 'Missing Plugin'); -$this->assign('templateName', 'missing_plugin.ctp'); - -$this->start('subheading'); -?> - Error: - The application is trying to load a file from the plugin. -
-
- Make sure your plugin is in the directory and was loaded. -end() ?> - -start('file') ?> - -
- -

- Loading all plugins: - -

- - -
-end() ?> diff --git a/vendor/cakephp/cakephp/src/Template/Error/missing_route.ctp b/vendor/cakephp/cakephp/src/Template/Error/missing_route.ctp deleted file mode 100644 index 9f53979..0000000 --- a/vendor/cakephp/cakephp/src/Template/Error/missing_route.ctp +++ /dev/null @@ -1,59 +0,0 @@ -layout = 'dev_error'; - -$this->assign('title', 'Missing Route'); -$this->assign('templateName', 'missing_route.ctp'); - -$attributes = $error->getAttributes(); - -$this->start('subheading'); -?> - Error: - getMessage(); ?> -end() ?> - -start('file') ?> -

None of the currently connected routes match the provided parameters. -Add a matching route to

- - -

The passed context was:

-
-
-
- - -

Connected Routes

- - -'; - printf( - '', - $route->template, - Debugger::exportVar($route->defaults), - Debugger::exportVar($route->options) - ); - echo ''; -endforeach; -?> -
TemplateDefaultsOptions
%s%s%s
-end() ?> diff --git a/vendor/cakephp/cakephp/src/Template/Error/missing_template.ctp b/vendor/cakephp/cakephp/src/Template/Error/missing_template.ctp deleted file mode 100644 index d2529f6..0000000 --- a/vendor/cakephp/cakephp/src/Template/Error/missing_template.ctp +++ /dev/null @@ -1,55 +0,0 @@ -layout = 'dev_error'; - -$this->assign('title', 'Missing Template'); -$this->assign('templateName', 'missing_template.ctp'); - -$isEmail = strpos($file, 'Email/') === 0; - -$this->start('subheading'); -?> - - Error: - was not found.', h($file)); ?> - - Error: - %sController::%s() was not found.', - h(Inflector::camelize($this->request->getParam('controller'))), - h($this->request->getParam('action')) - ); ?> - -end() ?> - -start('file') ?> -

- - in one of the following paths: -

-
    -_paths($this->plugin); - foreach ($paths as $path): - if (strpos($path, CORE_PATH) !== false) { - continue; - } - echo sprintf('
  • %s%s
  • ', h($path), h($file)); - endforeach; -?> -
-end() ?> diff --git a/vendor/cakephp/cakephp/src/Template/Error/missing_view.ctp b/vendor/cakephp/cakephp/src/Template/Error/missing_view.ctp deleted file mode 100644 index 99d385f..0000000 --- a/vendor/cakephp/cakephp/src/Template/Error/missing_view.ctp +++ /dev/null @@ -1,67 +0,0 @@ -layout = 'dev_error'; -$this->assign('title', 'Missing View'); -$this->assign('templateName', 'missing_view.ctp'); - -$this->start('subheading'); -?> - Error: - could not be found. - - Make sure your plugin is in the directory and was loaded. - - element('plugin_class_error', ['pluginPath' => $pluginPath]) ?> - -end() ?> - -start('file') ?> -

- Error: - %s below in file: %s', h($class), $filePath . 'View' . DIRECTORY_SEPARATOR . h($class) . '.php'); ?> -

- -
-end() ?> diff --git a/vendor/cakephp/cakephp/src/Template/Error/pdo_error.ctp b/vendor/cakephp/cakephp/src/Template/Error/pdo_error.ctp deleted file mode 100644 index 154fb25..0000000 --- a/vendor/cakephp/cakephp/src/Template/Error/pdo_error.ctp +++ /dev/null @@ -1,44 +0,0 @@ -setLayout('dev_error'); - -$this->assign('title', 'Database Error'); -$this->assign('templateName', 'pdo_error.ctp'); - -$this->start('subheading'); -?> - Error: - -end() ?> - -start('file') ?> -

- If you are using SQL keywords as table column names, you can enable identifier - quoting for your database connection in config/app.php. -

-queryString)) : ?> -

- SQL Query: -

-
queryString); ?>
- -params)) : ?> - SQL Query Params: -
params)); ?>
- -element('auto_table_warning'); ?> -end() ?> diff --git a/vendor/cakephp/cakephp/src/Template/Layout/dev_error.ctp b/vendor/cakephp/cakephp/src/Template/Layout/dev_error.ctp deleted file mode 100644 index c747fd7..0000000 --- a/vendor/cakephp/cakephp/src/Template/Layout/dev_error.ctp +++ /dev/null @@ -1,297 +0,0 @@ - - - - - Html->charset() ?> - - - Error: <?= h($this->fetch('title')) ?> - - Html->meta('icon') ?> - - - -
-

- fetch('title')) ?> - -

- -
- -
- fetch('subheading')): ?> -

- fetch('subheading') ?> -

- - - element('exception_stack_trace'); ?> - -
- fetch('file') ?> -
- - fetch('templateName')): ?> -

- If you want to customize this error message, create - fetch('templateName') ?> -

- -
- -
- element('exception_stack_trace_nav') ?> -
- - - - diff --git a/vendor/cakephp/cakephp/src/TestSuite/Constraint/EventFired.php b/vendor/cakephp/cakephp/src/TestSuite/Constraint/EventFired.php deleted file mode 100644 index c3fe9e1..0000000 --- a/vendor/cakephp/cakephp/src/TestSuite/Constraint/EventFired.php +++ /dev/null @@ -1,65 +0,0 @@ -_eventManager = $eventManager; - - if ($this->_eventManager->getEventList() === null) { - throw new AssertionFailedError('The event manager you are asserting against is not configured to track events.'); - } - } - - /** - * Checks if event is in fired array - * - * @param mixed $other Constraint check - * @return bool - */ - public function matches($other) - { - return $this->_eventManager->getEventList()->hasEvent($other); - } - - /** - * Assertion message string - * - * @return string - */ - public function toString() - { - return 'was fired'; - } -} diff --git a/vendor/cakephp/cakephp/src/TestSuite/Constraint/EventFiredWith.php b/vendor/cakephp/cakephp/src/TestSuite/Constraint/EventFiredWith.php deleted file mode 100644 index b280082..0000000 --- a/vendor/cakephp/cakephp/src/TestSuite/Constraint/EventFiredWith.php +++ /dev/null @@ -1,116 +0,0 @@ -_eventManager = $eventManager; - $this->_dataKey = $dataKey; - $this->_dataValue = $dataValue; - - if ($this->_eventManager->getEventList() === null) { - throw new AssertionFailedError('The event manager you are asserting against is not configured to track events.'); - } - } - - /** - * Checks if event is in fired array - * - * @param mixed $other Constraint check - * @return bool - */ - public function matches($other) - { - $firedEvents = []; - $list = $this->_eventManager->getEventList(); - $totalEvents = count($list); - for ($e = 0; $e < $totalEvents; $e++) { - $firedEvents[] = $list[$e]; - } - - $eventGroup = collection($firedEvents) - ->groupBy(function (Event $event) { - return $event->getName(); - }) - ->toArray(); - - if (!array_key_exists($other, $eventGroup)) { - return false; - } - - $events = $eventGroup[$other]; - - if (count($events) > 1) { - throw new AssertionFailedError(sprintf('Event "%s" was fired %d times, cannot make data assertion', $other, count($events))); - } - - /* @var \Cake\Event\Event $event */ - $event = $events[0]; - - if (array_key_exists($this->_dataKey, $event->getData()) === false) { - return false; - } - - return $event->getData($this->_dataKey) === $this->_dataValue; - } - - /** - * Assertion message string - * - * @return string - */ - public function toString() - { - return 'was fired with ' . $this->_dataKey . ' matching ' . (string)$this->_dataValue; - } -} diff --git a/vendor/cakephp/cakephp/src/TestSuite/EmailAssertTrait.php b/vendor/cakephp/cakephp/src/TestSuite/EmailAssertTrait.php deleted file mode 100644 index d0353a7..0000000 --- a/vendor/cakephp/cakephp/src/TestSuite/EmailAssertTrait.php +++ /dev/null @@ -1,292 +0,0 @@ -email(true)->send($content); - } - - /** - * Creates an email instance overriding its transport for testing purposes. - * - * @param bool $new Tells if new instance should forcibly be created. - * @return \Cake\Mailer\Email - */ - public function email($new = false) - { - if ($new || !$this->_email) { - $this->_email = new Email(); - $this->_email->setProfile(['transport' => 'debug'] + $this->_email->getProfile()); - } - - return $this->_email; - } - - /** - * Generates mock for given mailer class. - * - * @param string $className The mailer's FQCN. - * @param array $methods The methods to mock on the mailer. - * @return \Cake\Mailer\Mailer|\PHPUnit_Framework_MockObject_MockObject - */ - public function getMockForMailer($className, array $methods = []) - { - $name = current(array_slice(explode('\\', $className), -1)); - - if (!in_array('profile', $methods)) { - $methods[] = 'profile'; - } - - $mailer = $this->getMockBuilder($className) - ->setMockClassName($name) - ->setMethods($methods) - ->setConstructorArgs([$this->email()]) - ->getMock(); - - $mailer->expects($this->any()) - ->method('profile') - ->willReturn($mailer); - - return $mailer; - } - - /** - * Asserts email content (both text and HTML) contains `$needle`. - * - * @param string $needle Text to look for. - * @param string|null $message The failure message to define. - * @return void - */ - public function assertEmailMessageContains($needle, $message = null) - { - $this->assertEmailHtmlMessageContains($needle, $message); - $this->assertEmailTextMessageContains($needle, $message); - } - - /** - * Asserts HTML email content contains `$needle`. - * - * @param string $needle Text to look for. - * @param string|null $message The failure message to define. - * @return void - */ - public function assertEmailHtmlMessageContains($needle, $message = null) - { - $haystack = $this->email()->message('html'); - $this->assertTextContains($needle, $haystack, $message); - } - - /** - * Asserts text email content contains `$needle`. - * - * @param string $needle Text to look for. - * @param string|null $message The failure message to define. - * @return void - */ - public function assertEmailTextMessageContains($needle, $message = null) - { - $haystack = $this->email()->message('text'); - $this->assertTextContains($needle, $haystack, $message); - } - - /** - * Asserts email's subject contains `$expected`. - * - * @param string $expected Email's subject. - * @param string|null $message The failure message to define. - * @return void - */ - public function assertEmailSubject($expected, $message = null) - { - $result = $this->email()->getSubject(); - $this->assertSame($expected, $result, $message); - } - - /** - * Asserts email's sender email address and optionally name. - * - * @param string $email Sender's email address. - * @param string|null $name Sender's name. - * @param string|null $message The failure message to define. - * @return void - */ - public function assertEmailFrom($email, $name = null, $message = null) - { - if ($name === null) { - $name = $email; - } - - $expected = [$email => $name]; - $result = $this->email()->getFrom(); - $this->assertSame($expected, $result, $message); - } - - /** - * Asserts email is CC'd to only one email address (and optionally name). - * - * @param string $email CC'd email address. - * @param string|null $name CC'd person name. - * @param string|null $message The failure message to define. - * @return void - */ - public function assertEmailCc($email, $name = null, $message = null) - { - if ($name === null) { - $name = $email; - } - - $expected = [$email => $name]; - $result = $this->email()->getCc(); - $this->assertSame($expected, $result, $message); - } - - /** - * Asserts email CC'd addresses contain given email address (and - * optionally name). - * - * @param string $email CC'd email address. - * @param string|null $name CC'd person name. - * @param string|null $message The failure message to define. - * @return void - */ - public function assertEmailCcContains($email, $name = null, $message = null) - { - $result = $this->email()->getCc(); - $this->assertNotEmpty($result[$email], $message); - if ($name !== null) { - $this->assertEquals($result[$email], $name, $message); - } - } - - /** - * Asserts email is BCC'd to only one email address (and optionally name). - * - * @param string $email BCC'd email address. - * @param string|null $name BCC'd person name. - * @param string|null $message The failure message to define. - * @return void - */ - public function assertEmailBcc($email, $name = null, $message = null) - { - if ($name === null) { - $name = $email; - } - - $expected = [$email => $name]; - $result = $this->email()->getBcc(); - $this->assertSame($expected, $result, $message); - } - - /** - * Asserts email BCC'd addresses contain given email address (and - * optionally name). - * - * @param string $email BCC'd email address. - * @param string|null $name BCC'd person name. - * @param string|null $message The failure message to define. - * @return void - */ - public function assertEmailBccContains($email, $name = null, $message = null) - { - $result = $this->email()->getBcc(); - $this->assertNotEmpty($result[$email], $message); - if ($name !== null) { - $this->assertEquals($result[$email], $name, $message); - } - } - - /** - * Asserts email is sent to only the given recipient's address (and - * optionally name). - * - * @param string $email Recipient's email address. - * @param string|null $name Recipient's name. - * @param string|null $message The failure message to define. - * @return void - */ - public function assertEmailTo($email, $name = null, $message = null) - { - if ($name === null) { - $name = $email; - } - - $expected = [$email => $name]; - $result = $this->email()->getTo(); - $this->assertSame($expected, $result, $message); - } - - /** - * Asserts email recipients' list contains given email address (and - * optionally name). - * - * @param string $email Recipient's email address. - * @param string|null $name Recipient's name. - * @param string|null $message The failure message to define. - * @return void - */ - public function assertEmailToContains($email, $name = null, $message = null) - { - $result = $this->email()->getTo(); - $this->assertNotEmpty($result[$email], $message); - if ($name !== null) { - $this->assertEquals($result[$email], $name, $message); - } - } - - /** - * Asserts the email attachments contain the given filename (and optionally - * file info). - * - * @param string $filename Expected attachment's filename. - * @param array|null $file Expected attachment's file info. - * @param string|null $message The failure message to define. - * @return void - */ - public function assertEmailAttachmentsContains($filename, array $file = null, $message = null) - { - $result = $this->email()->getAttachments(); - $this->assertNotEmpty($result[$filename], $message); - if ($file === null) { - return; - } - $this->assertContains($file, $result, $message); - $this->assertEquals($file, $result[$filename], $message); - } -} diff --git a/vendor/cakephp/cakephp/src/TestSuite/Fixture/FixtureInjector.php b/vendor/cakephp/cakephp/src/TestSuite/Fixture/FixtureInjector.php deleted file mode 100644 index 74edb48..0000000 --- a/vendor/cakephp/cakephp/src/TestSuite/Fixture/FixtureInjector.php +++ /dev/null @@ -1,115 +0,0 @@ -setDebug(in_array('--debug', $_SERVER['argv'])); - } - $this->_fixtureManager = $manager; - $this->_fixtureManager->shutDown(); - } - - /** - * Iterates the tests inside a test suite and creates the required fixtures as - * they were expressed inside each test case. - * - * @param \PHPUnit\Framework\TestSuite $suite The test suite - * @return void - */ - public function startTestSuite(TestSuite $suite) - { - if (empty($this->_first)) { - $this->_first = $suite; - } - } - - /** - * Destroys the fixtures created by the fixture manager at the end of the test - * suite run - * - * @param \PHPUnit\Framework\TestSuite $suite The test suite - * @return void - */ - public function endTestSuite(TestSuite $suite) - { - if ($this->_first === $suite) { - $this->_fixtureManager->shutDown(); - } - } - - /** - * Adds fixtures to a test case when it starts. - * - * @param \PHPUnit\Framework\Test $test The test case - * @return void - */ - public function startTest(Test $test) - { - $test->fixtureManager = $this->_fixtureManager; - if ($test instanceof TestCase) { - $this->_fixtureManager->fixturize($test); - $this->_fixtureManager->load($test); - } - } - - /** - * Unloads fixtures from the test case. - * - * @param \PHPUnit\Framework\Test $test The test case - * @param float $time current time - * @return void - */ - public function endTest(Test $test, $time) - { - if ($test instanceof TestCase) { - $this->_fixtureManager->unload($test); - } - } -} diff --git a/vendor/cakephp/cakephp/src/TestSuite/Fixture/FixtureManager.php b/vendor/cakephp/cakephp/src/TestSuite/Fixture/FixtureManager.php deleted file mode 100644 index 220ccc7..0000000 --- a/vendor/cakephp/cakephp/src/TestSuite/Fixture/FixtureManager.php +++ /dev/null @@ -1,500 +0,0 @@ -_debug = $debug; - } - - /** - * Inspects the test to look for unloaded fixtures and loads them - * - * @param \Cake\TestSuite\TestCase $test The test case to inspect. - * @return void - */ - public function fixturize($test) - { - $this->_initDb(); - if (empty($test->fixtures) || !empty($this->_processed[get_class($test)])) { - return; - } - if (!is_array($test->fixtures)) { - $test->fixtures = array_map('trim', explode(',', $test->fixtures)); - } - $this->_loadFixtures($test); - $this->_processed[get_class($test)] = true; - } - - /** - * Get the loaded fixtures. - * - * @return array - */ - public function loaded() - { - return $this->_loaded; - } - - /** - * Add aliases for all non test prefixed connections. - * - * This allows models to use the test connections without - * a pile of configuration work. - * - * @return void - */ - protected function _aliasConnections() - { - $connections = ConnectionManager::configured(); - ConnectionManager::alias('test', 'default'); - $map = []; - foreach ($connections as $connection) { - if ($connection === 'test' || $connection === 'default') { - continue; - } - if (isset($map[$connection])) { - continue; - } - if (strpos($connection, 'test_') === 0) { - $map[$connection] = substr($connection, 5); - } else { - $map['test_' . $connection] = $connection; - } - } - foreach ($map as $testConnection => $normal) { - ConnectionManager::alias($testConnection, $normal); - } - } - - /** - * Initializes this class with a DataSource object to use as default for all fixtures - * - * @return void - */ - protected function _initDb() - { - if ($this->_initialized) { - return; - } - $this->_aliasConnections(); - $this->_initialized = true; - } - - /** - * Looks for fixture files and instantiates the classes accordingly - * - * @param \Cake\TestSuite\TestCase $test The test suite to load fixtures for. - * @return void - * @throws \UnexpectedValueException when a referenced fixture does not exist. - */ - protected function _loadFixtures($test) - { - if (empty($test->fixtures)) { - return; - } - foreach ($test->fixtures as $fixture) { - if (isset($this->_loaded[$fixture])) { - continue; - } - - if (strpos($fixture, '.')) { - list($type, $pathName) = explode('.', $fixture, 2); - $path = explode('/', $pathName); - $name = array_pop($path); - $additionalPath = implode('\\', $path); - - if ($type === 'core') { - $baseNamespace = 'Cake'; - } elseif ($type === 'app') { - $baseNamespace = Configure::read('App.namespace'); - } elseif ($type === 'plugin') { - list($plugin, $name) = explode('.', $pathName); - // Flip vendored plugin separators - $path = implode('\\', explode('/', $plugin)); - $baseNamespace = Inflector::camelize(str_replace('\\', '\ ', $path)); - $additionalPath = null; - } else { - $baseNamespace = ''; - $name = $fixture; - } - - // Tweak subdirectory names, so camelize() can make the correct name - if (strpos($name, '/') > 0) { - $name = implode('\\ ', explode('/', $name)); - } - - $name = Inflector::camelize($name); - $nameSegments = [ - $baseNamespace, - 'Test\Fixture', - $additionalPath, - $name . 'Fixture' - ]; - $className = implode('\\', array_filter($nameSegments)); - } else { - $className = $fixture; - $name = preg_replace('/Fixture\z/', '', substr(strrchr($fixture, '\\'), 1)); - } - - if (class_exists($className)) { - $this->_loaded[$fixture] = new $className(); - $this->_fixtureMap[$name] = $this->_loaded[$fixture]; - } else { - $msg = sprintf( - 'Referenced fixture class "%s" not found. Fixture "%s" was referenced in test case "%s".', - $className, - $fixture, - get_class($test) - ); - throw new UnexpectedValueException($msg); - } - } - } - - /** - * Runs the drop and create commands on the fixtures if necessary. - * - * @param \Cake\Datasource\FixtureInterface $fixture the fixture object to create - * @param \Cake\Database\Connection $db The Connection object instance to use - * @param array $sources The existing tables in the datasource. - * @param bool $drop whether drop the fixture if it is already created or not - * @return void - */ - protected function _setupTable($fixture, $db, array $sources, $drop = true) - { - $configName = $db->configName(); - $isFixtureSetup = $this->isFixtureSetup($configName, $fixture); - if ($isFixtureSetup) { - return; - } - - $table = $fixture->sourceName(); - $exists = in_array($table, $sources); - - $hasSchema = $fixture instanceof TableSchemaAwareInterface && $fixture->getTableSchema() instanceof TableSchema; - - if (($drop && $exists) || ($exists && !$isFixtureSetup && $hasSchema)) { - $fixture->drop($db); - $fixture->create($db); - } elseif (!$exists) { - $fixture->create($db); - } else { - $fixture->truncate($db); - } - - $this->_insertionMap[$configName][] = $fixture; - } - - /** - * Creates the fixtures tables and inserts data on them. - * - * @param \Cake\TestSuite\TestCase $test The test to inspect for fixture loading. - * @return void - * @throws \Cake\Core\Exception\Exception When fixture records cannot be inserted. - */ - public function load($test) - { - if (empty($test->fixtures)) { - return; - } - - $fixtures = $test->fixtures; - if (empty($fixtures) || !$test->autoFixtures) { - return; - } - - try { - $createTables = function ($db, $fixtures) use ($test) { - $tables = $db->getSchemaCollection()->listTables(); - $configName = $db->configName(); - if (!isset($this->_insertionMap[$configName])) { - $this->_insertionMap[$configName] = []; - } - - foreach ($fixtures as $fixture) { - if (in_array($fixture->table, $tables)) { - try { - $fixture->dropConstraints($db); - } catch (PDOException $e) { - $msg = sprintf( - 'Unable to drop constraints for fixture "%s" in "%s" test case: ' . "\n" . '%s', - get_class($fixture), - get_class($test), - $e->getMessage() - ); - throw new Exception($msg, null, $e); - } - } - } - - foreach ($fixtures as $fixture) { - if (!in_array($fixture, $this->_insertionMap[$configName])) { - $this->_setupTable($fixture, $db, $tables, $test->dropTables); - } else { - $fixture->truncate($db); - } - } - - foreach ($fixtures as $fixture) { - try { - $fixture->createConstraints($db); - } catch (PDOException $e) { - $msg = sprintf( - 'Unable to create constraints for fixture "%s" in "%s" test case: ' . "\n" . '%s', - get_class($fixture), - get_class($test), - $e->getMessage() - ); - throw new Exception($msg, null, $e); - } - } - }; - $this->_runOperation($fixtures, $createTables); - - // Use a separate transaction because of postgres. - $insert = function ($db, $fixtures) use ($test) { - foreach ($fixtures as $fixture) { - try { - $fixture->insert($db); - } catch (PDOException $e) { - $msg = sprintf( - 'Unable to insert fixture "%s" in "%s" test case: ' . "\n" . '%s', - get_class($fixture), - get_class($test), - $e->getMessage() - ); - throw new Exception($msg, null, $e); - } - } - }; - $this->_runOperation($fixtures, $insert); - } catch (PDOException $e) { - $msg = sprintf( - 'Unable to insert fixtures for "%s" test case. %s', - get_class($test), - $e->getMessage() - ); - throw new Exception($msg, null, $e); - } - } - - /** - * Run a function on each connection and collection of fixtures. - * - * @param array $fixtures A list of fixtures to operate on. - * @param callable $operation The operation to run on each connection + fixture set. - * @return void - */ - protected function _runOperation($fixtures, $operation) - { - $dbs = $this->_fixtureConnections($fixtures); - foreach ($dbs as $connection => $fixtures) { - $db = ConnectionManager::get($connection); - $logQueries = $db->logQueries(); - if ($logQueries && !$this->_debug) { - $db->logQueries(false); - } - $db->transactional(function ($db) use ($fixtures, $operation) { - $db->disableConstraints(function ($db) use ($fixtures, $operation) { - $operation($db, $fixtures); - }); - }); - if ($logQueries) { - $db->logQueries(true); - } - } - } - - /** - * Get the unique list of connections that a set of fixtures contains. - * - * @param array $fixtures The array of fixtures a list of connections is needed from. - * @return array An array of connection names. - */ - protected function _fixtureConnections($fixtures) - { - $dbs = []; - foreach ($fixtures as $f) { - if (!empty($this->_loaded[$f])) { - $fixture = $this->_loaded[$f]; - $dbs[$fixture->connection()][$f] = $fixture; - } - } - - return $dbs; - } - - /** - * Truncates the fixtures tables - * - * @param \Cake\TestSuite\TestCase $test The test to inspect for fixture unloading. - * @return void - */ - public function unload($test) - { - if (empty($test->fixtures)) { - return; - } - $truncate = function ($db, $fixtures) { - $configName = $db->configName(); - - foreach ($fixtures as $name => $fixture) { - if ($this->isFixtureSetup($configName, $fixture)) { - $fixture->dropConstraints($db); - } - } - - foreach ($fixtures as $fixture) { - if ($this->isFixtureSetup($configName, $fixture)) { - $fixture->truncate($db); - } - } - }; - $this->_runOperation($test->fixtures, $truncate); - } - - /** - * Creates a single fixture table and loads data into it. - * - * @param string $name of the fixture - * @param \Cake\Datasource\ConnectionInterface|null $db Connection instance or leave null to get a Connection from the fixture - * @param bool $dropTables Whether or not tables should be dropped and re-created. - * @return void - * @throws \UnexpectedValueException if $name is not a previously loaded class - */ - public function loadSingle($name, $db = null, $dropTables = true) - { - if (!isset($this->_fixtureMap[$name])) { - throw new UnexpectedValueException(sprintf('Referenced fixture class %s not found', $name)); - } - - $fixture = $this->_fixtureMap[$name]; - if (!$db) { - $db = ConnectionManager::get($fixture->connection()); - } - - if (!$this->isFixtureSetup($db->configName(), $fixture)) { - $sources = $db->getSchemaCollection()->listTables(); - $this->_setupTable($fixture, $db, $sources, $dropTables); - } - - if (!$dropTables) { - $fixture->dropConstraints($db); - $fixture->truncate($db); - } - - $fixture->createConstraints($db); - $fixture->insert($db); - } - - /** - * Drop all fixture tables loaded by this class - * - * @return void - */ - public function shutDown() - { - $shutdown = function ($db, $fixtures) { - $connection = $db->configName(); - foreach ($fixtures as $fixture) { - if ($this->isFixtureSetup($connection, $fixture)) { - $fixture->drop($db); - $index = array_search($fixture, $this->_insertionMap[$connection]); - unset($this->_insertionMap[$connection][$index]); - } - } - }; - $this->_runOperation(array_keys($this->_loaded), $shutdown); - } - - /** - * Check whether or not a fixture has been inserted in a given connection name. - * - * @param string $connection The connection name. - * @param \Cake\Datasource\FixtureInterface $fixture The fixture to check. - * @return bool - */ - public function isFixtureSetup($connection, $fixture) - { - return isset($this->_insertionMap[$connection]) && in_array($fixture, $this->_insertionMap[$connection]); - } -} diff --git a/vendor/cakephp/cakephp/src/TestSuite/Fixture/TestFixture.php b/vendor/cakephp/cakephp/src/TestSuite/Fixture/TestFixture.php deleted file mode 100644 index 5a0ec61..0000000 --- a/vendor/cakephp/cakephp/src/TestSuite/Fixture/TestFixture.php +++ /dev/null @@ -1,475 +0,0 @@ -connection)) { - $connection = $this->connection; - if (strpos($connection, 'test') !== 0) { - $message = sprintf( - 'Invalid datasource name "%s" for "%s" fixture. Fixture datasource names must begin with "test".', - $connection, - $this->table - ); - throw new CakeException($message); - } - } - $this->init(); - } - - /** - * {@inheritDoc} - */ - public function connection() - { - return $this->connection; - } - - /** - * {@inheritDoc} - */ - public function sourceName() - { - return $this->table; - } - - /** - * Initialize the fixture. - * - * @return void - * @throws \Cake\ORM\Exception\MissingTableClassException When importing from a table that does not exist. - */ - public function init() - { - if ($this->table === null) { - $this->table = $this->_tableFromClass(); - } - - if (empty($this->import) && !empty($this->fields)) { - $this->_schemaFromFields(); - } - - if (!empty($this->import)) { - $this->_schemaFromImport(); - } - - if (empty($this->import) && empty($this->fields)) { - $this->_schemaFromReflection(); - } - } - - /** - * Returns the table name using the fixture class - * - * @return string - */ - protected function _tableFromClass() - { - list(, $class) = namespaceSplit(get_class($this)); - preg_match('/^(.*)Fixture$/', $class, $matches); - $table = $class; - - if (isset($matches[1])) { - $table = $matches[1]; - } - - return Inflector::tableize($table); - } - - /** - * Build the fixtures table schema from the fields property. - * - * @return void - */ - protected function _schemaFromFields() - { - $connection = ConnectionManager::get($this->connection()); - $this->_schema = new TableSchema($this->table); - foreach ($this->fields as $field => $data) { - if ($field === '_constraints' || $field === '_indexes' || $field === '_options') { - continue; - } - $this->_schema->addColumn($field, $data); - } - if (!empty($this->fields['_constraints'])) { - foreach ($this->fields['_constraints'] as $name => $data) { - if (!$connection->supportsDynamicConstraints() || $data['type'] !== TableSchema::CONSTRAINT_FOREIGN) { - $this->_schema->addConstraint($name, $data); - } else { - $this->_constraints[$name] = $data; - } - } - } - if (!empty($this->fields['_indexes'])) { - foreach ($this->fields['_indexes'] as $name => $data) { - $this->_schema->addIndex($name, $data); - } - } - if (!empty($this->fields['_options'])) { - $this->_schema->setOptions($this->fields['_options']); - } - } - - /** - * Build fixture schema from a table in another datasource. - * - * @return void - * @throws \Cake\Core\Exception\Exception when trying to import from an empty table. - */ - protected function _schemaFromImport() - { - if (!is_array($this->import)) { - return; - } - $import = $this->import + ['connection' => 'default', 'table' => null, 'model' => null]; - - if (!empty($import['model'])) { - if (!empty($import['table'])) { - throw new CakeException('You cannot define both table and model.'); - } - $import['table'] = $this->getTableLocator()->get($import['model'])->getTable(); - } - - if (empty($import['table'])) { - throw new CakeException('Cannot import from undefined table.'); - } - - $this->table = $import['table']; - - $db = ConnectionManager::get($import['connection'], false); - $schemaCollection = $db->getSchemaCollection(); - $table = $schemaCollection->describe($import['table']); - $this->_schema = $table; - } - - /** - * Build fixture schema directly from the datasource - * - * @return void - * @throws \Cake\Core\Exception\Exception when trying to reflect a table that does not exist - */ - protected function _schemaFromReflection() - { - $db = ConnectionManager::get($this->connection()); - $schemaCollection = $db->getSchemaCollection(); - $tables = $schemaCollection->listTables(); - - if (!in_array($this->table, $tables)) { - throw new CakeException( - sprintf( - 'Cannot describe schema for table `%s` for fixture `%s` : the table does not exist.', - $this->table, - get_class($this) - ) - ); - } - - $this->_schema = $schemaCollection->describe($this->table); - } - - /** - * Gets/Sets the TableSchema instance used by this fixture. - * - * @param \Cake\Database\Schema\TableSchema|null $schema The table to set. - * @return \Cake\Database\Schema\TableSchema|null - * @deprecated 3.5.0 Use getTableSchema/setTableSchema instead. - */ - public function schema(TableSchema $schema = null) - { - deprecationWarning( - 'TestFixture::schema() is deprecated. ' . - 'Use TestFixture::setTableSchema()/getTableSchema() instead.' - ); - if ($schema) { - $this->setTableSchema($schema); - } - - return $this->getTableSchema(); - } - - /** - * {@inheritDoc} - */ - public function create(ConnectionInterface $db) - { - if (empty($this->_schema)) { - return false; - } - - if (empty($this->import) && empty($this->fields)) { - return true; - } - - try { - $queries = $this->_schema->createSql($db); - foreach ($queries as $query) { - $stmt = $db->prepare($query); - $stmt->execute(); - $stmt->closeCursor(); - } - } catch (Exception $e) { - $msg = sprintf( - 'Fixture creation for "%s" failed "%s"', - $this->table, - $e->getMessage() - ); - Log::error($msg); - trigger_error($msg, E_USER_WARNING); - - return false; - } - - return true; - } - - /** - * {@inheritDoc} - */ - public function drop(ConnectionInterface $db) - { - if (empty($this->_schema)) { - return false; - } - - if (empty($this->import) && empty($this->fields)) { - return true; - } - - try { - $sql = $this->_schema->dropSql($db); - foreach ($sql as $stmt) { - $db->execute($stmt)->closeCursor(); - } - } catch (Exception $e) { - return false; - } - - return true; - } - - /** - * {@inheritDoc} - */ - public function insert(ConnectionInterface $db) - { - if (isset($this->records) && !empty($this->records)) { - list($fields, $values, $types) = $this->_getRecords(); - $query = $db->newQuery() - ->insert($fields, $types) - ->into($this->table); - - foreach ($values as $row) { - $query->values($row); - } - $statement = $query->execute(); - $statement->closeCursor(); - - return $statement; - } - - return true; - } - - /** - * {@inheritDoc} - */ - public function createConstraints(ConnectionInterface $db) - { - if (empty($this->_constraints)) { - return true; - } - - foreach ($this->_constraints as $name => $data) { - $this->_schema->addConstraint($name, $data); - } - - $sql = $this->_schema->addConstraintSql($db); - - if (empty($sql)) { - return true; - } - - foreach ($sql as $stmt) { - $db->execute($stmt)->closeCursor(); - } - - return true; - } - - /** - * {@inheritDoc} - */ - public function dropConstraints(ConnectionInterface $db) - { - if (empty($this->_constraints)) { - return true; - } - - $sql = $this->_schema->dropConstraintSql($db); - - if (empty($sql)) { - return true; - } - - foreach ($sql as $stmt) { - $db->execute($stmt)->closeCursor(); - } - - foreach ($this->_constraints as $name => $data) { - $this->_schema->dropConstraint($name); - } - - return true; - } - - /** - * Converts the internal records into data used to generate a query. - * - * @return array - */ - protected function _getRecords() - { - $fields = $values = $types = []; - $columns = $this->_schema->columns(); - foreach ($this->records as $record) { - $fields = array_merge($fields, array_intersect(array_keys($record), $columns)); - } - $fields = array_values(array_unique($fields)); - foreach ($fields as $field) { - $types[$field] = $this->_schema->getColumn($field)['type']; - } - $default = array_fill_keys($fields, null); - foreach ($this->records as $record) { - $values[] = array_merge($default, $record); - } - - return [$fields, $values, $types]; - } - - /** - * {@inheritDoc} - */ - public function truncate(ConnectionInterface $db) - { - $sql = $this->_schema->truncateSql($db); - foreach ($sql as $stmt) { - $db->execute($stmt)->closeCursor(); - } - - return true; - } - - /** - * {@inheritDoc} - */ - public function getTableSchema() - { - return $this->_schema; - } - - /** - * {@inheritDoc} - */ - public function setTableSchema(DatabaseTableSchemaInterface $schema) - { - $this->_schema = $schema; - - return $this; - } -} diff --git a/vendor/cakephp/cakephp/src/TestSuite/IntegrationTestCase.php b/vendor/cakephp/cakephp/src/TestSuite/IntegrationTestCase.php deleted file mode 100644 index 6654702..0000000 --- a/vendor/cakephp/cakephp/src/TestSuite/IntegrationTestCase.php +++ /dev/null @@ -1,1181 +0,0 @@ -_useHttpServer = class_exists($namespace . '\Application'); - } - - /** - * Clears the state used for requests. - * - * @return void - */ - public function tearDown() - { - parent::tearDown(); - $this->_request = []; - $this->_session = []; - $this->_cookie = []; - $this->_response = null; - $this->_exception = null; - $this->_controller = null; - $this->_viewName = null; - $this->_layoutName = null; - $this->_requestSession = null; - $this->_appClass = null; - $this->_appArgs = null; - $this->_securityToken = false; - $this->_csrfToken = false; - $this->_retainFlashMessages = false; - $this->_useHttpServer = false; - } - - /** - * Toggle whether or not you want to use the HTTP Server stack. - * - * @param bool $enable Enable/disable the usage of the HTTP Stack. - * @return void - */ - public function useHttpServer($enable) - { - $this->_useHttpServer = (bool)$enable; - } - - /** - * Configure the application class to use in integration tests. - * - * Combined with `useHttpServer()` to customize the class name and constructor arguments - * of your application class. - * - * @param string $class The application class name. - * @param array|null $constructorArgs The constructor arguments for your application class. - * @return void - */ - public function configApplication($class, $constructorArgs) - { - $this->_appClass = $class; - $this->_appArgs = $constructorArgs; - } - - /** - * Calling this method will enable a SecurityComponent - * compatible token to be added to request data. This - * lets you easily test actions protected by SecurityComponent. - * - * @return void - */ - public function enableSecurityToken() - { - $this->_securityToken = true; - } - - /** - * Calling this method will add a CSRF token to the request. - * - * Both the POST data and cookie will be populated when this option - * is enabled. The default parameter names will be used. - * - * @return void - */ - public function enableCsrfToken() - { - $this->_csrfToken = true; - } - - /** - * Calling this method will re-store flash messages into the test session - * after being removed by the FlashHelper - * - * @return void - */ - public function enableRetainFlashMessages() - { - $this->_retainFlashMessages = true; - } - - /** - * Configures the data for the *next* request. - * - * This data is cleared in the tearDown() method. - * - * You can call this method multiple times to append into - * the current state. - * - * @param array $data The request data to use. - * @return void - */ - public function configRequest(array $data) - { - $this->_request = $data + $this->_request; - } - - /** - * Sets session data. - * - * This method lets you configure the session data - * you want to be used for requests that follow. The session - * state is reset in each tearDown(). - * - * You can call this method multiple times to append into - * the current state. - * - * @param array $data The session data to use. - * @return void - */ - public function session(array $data) - { - $this->_session = $data + $this->_session; - } - - /** - * Sets a request cookie for future requests. - * - * This method lets you configure the session data - * you want to be used for requests that follow. The session - * state is reset in each tearDown(). - * - * You can call this method multiple times to append into - * the current state. - * - * @param string $name The cookie name to use. - * @param mixed $value The value of the cookie. - * @return void - */ - public function cookie($name, $value) - { - $this->_cookie[$name] = $value; - } - - /** - * Returns the encryption key to be used. - * - * @return string - */ - protected function _getCookieEncryptionKey() - { - if (isset($this->_cookieEncryptionKey)) { - return $this->_cookieEncryptionKey; - } - - return Security::getSalt(); - } - - /** - * Sets a encrypted request cookie for future requests. - * - * The difference from cookie() is this encrypts the cookie - * value like the CookieComponent. - * - * @param string $name The cookie name to use. - * @param mixed $value The value of the cookie. - * @param string|bool $encrypt Encryption mode to use. - * @param string|null $key Encryption key used. Defaults - * to Security.salt. - * @return void - * @see \Cake\Utility\CookieCryptTrait::_encrypt() - */ - public function cookieEncrypted($name, $value, $encrypt = 'aes', $key = null) - { - $this->_cookieEncryptionKey = $key; - $this->_cookie[$name] = $this->_encrypt($value, $encrypt); - } - - /** - * Performs a GET request using the current request data. - * - * The response of the dispatched request will be stored as - * a property. You can use various assert methods to check the - * response. - * - * @param string|array $url The URL to request. - * @return void - */ - public function get($url) - { - $this->_sendRequest($url, 'GET'); - } - - /** - * Performs a POST request using the current request data. - * - * The response of the dispatched request will be stored as - * a property. You can use various assert methods to check the - * response. - * - * @param string|array $url The URL to request. - * @param array $data The data for the request. - * @return void - */ - public function post($url, $data = []) - { - $this->_sendRequest($url, 'POST', $data); - } - - /** - * Performs a PATCH request using the current request data. - * - * The response of the dispatched request will be stored as - * a property. You can use various assert methods to check the - * response. - * - * @param string|array $url The URL to request. - * @param array $data The data for the request. - * @return void - */ - public function patch($url, $data = []) - { - $this->_sendRequest($url, 'PATCH', $data); - } - - /** - * Performs a PUT request using the current request data. - * - * The response of the dispatched request will be stored as - * a property. You can use various assert methods to check the - * response. - * - * @param string|array $url The URL to request. - * @param array $data The data for the request. - * @return void - */ - public function put($url, $data = []) - { - $this->_sendRequest($url, 'PUT', $data); - } - - /** - * Performs a DELETE request using the current request data. - * - * The response of the dispatched request will be stored as - * a property. You can use various assert methods to check the - * response. - * - * @param string|array $url The URL to request. - * @return void - */ - public function delete($url) - { - $this->_sendRequest($url, 'DELETE'); - } - - /** - * Performs a HEAD request using the current request data. - * - * The response of the dispatched request will be stored as - * a property. You can use various assert methods to check the - * response. - * - * @param string|array $url The URL to request. - * @return void - */ - public function head($url) - { - $this->_sendRequest($url, 'HEAD'); - } - - /** - * Performs an OPTIONS request using the current request data. - * - * The response of the dispatched request will be stored as - * a property. You can use various assert methods to check the - * response. - * - * @param string|array $url The URL to request. - * @return void - */ - public function options($url) - { - $this->_sendRequest($url, 'OPTIONS'); - } - - /** - * Creates and send the request into a Dispatcher instance. - * - * Receives and stores the response for future inspection. - * - * @param string|array $url The URL - * @param string $method The HTTP method - * @param array|null $data The request data. - * @return void - * @throws \Exception - */ - protected function _sendRequest($url, $method, $data = []) - { - $dispatcher = $this->_makeDispatcher(); - try { - $request = $this->_buildRequest($url, $method, $data); - $response = $dispatcher->execute($request); - $this->_requestSession = $request['session']; - if ($this->_retainFlashMessages && $this->_flashMessages) { - $this->_requestSession->write('Flash', $this->_flashMessages); - } - $this->_response = $response; - } catch (PhpUnitException $e) { - throw $e; - } catch (DatabaseException $e) { - throw $e; - } catch (LogicException $e) { - throw $e; - } catch (Exception $e) { - $this->_exception = $e; - $this->_handleError($e); - } - } - - /** - * Get the correct dispatcher instance. - * - * @return \Cake\TestSuite\MiddlewareDispatcher|\Cake\TestSuite\LegacyRequestDispatcher A dispatcher instance - */ - protected function _makeDispatcher() - { - if ($this->_useHttpServer) { - return new MiddlewareDispatcher($this, $this->_appClass, $this->_appArgs); - } - - return new LegacyRequestDispatcher($this); - } - - /** - * Adds additional event spies to the controller/view event manager. - * - * @param \Cake\Event\Event $event A dispatcher event. - * @param \Cake\Controller\Controller|null $controller Controller instance. - * @return void - */ - public function controllerSpy($event, $controller = null) - { - if (!$controller) { - /** @var \Cake\Controller\Controller $controller */ - $controller = $event->getSubject(); - } - $this->_controller = $controller; - $events = $controller->getEventManager(); - $events->on('View.beforeRender', function ($event, $viewFile) use ($controller) { - if (!$this->_viewName) { - $this->_viewName = $viewFile; - } - if ($this->_retainFlashMessages) { - $this->_flashMessages = $controller->request->getSession()->read('Flash'); - } - }); - $events->on('View.beforeLayout', function ($event, $viewFile) { - $this->_layoutName = $viewFile; - }); - } - - /** - * Attempts to render an error response for a given exception. - * - * This method will attempt to use the configured exception renderer. - * If that class does not exist, the built-in renderer will be used. - * - * @param \Exception $exception Exception to handle. - * @return void - * @throws \Exception - */ - protected function _handleError($exception) - { - $class = Configure::read('Error.exceptionRenderer'); - if (empty($class) || !class_exists($class)) { - $class = 'Cake\Error\ExceptionRenderer'; - } - /** @var \Cake\Error\ExceptionRenderer $instance */ - $instance = new $class($exception); - $this->_response = $instance->render(); - } - - /** - * Creates a request object with the configured options and parameters. - * - * @param string|array $url The URL - * @param string $method The HTTP method - * @param array|null $data The request data. - * @return array The request context - */ - protected function _buildRequest($url, $method, $data) - { - $sessionConfig = (array)Configure::read('Session') + [ - 'defaults' => 'php', - ]; - $session = Session::create($sessionConfig); - $session->write($this->_session); - list ($url, $query) = $this->_url($url); - $tokenUrl = $url; - - if ($query) { - $tokenUrl .= '?' . $query; - } - - parse_str($query, $queryData); - $props = [ - 'url' => $url, - 'session' => $session, - 'query' => $queryData - ]; - if (is_string($data)) { - $props['input'] = $data; - } - if (!isset($props['input'])) { - $props['post'] = $this->_addTokens($tokenUrl, $data); - } - $props['cookies'] = $this->_cookie; - - $env = [ - 'REQUEST_METHOD' => $method, - 'QUERY_STRING' => $query, - 'REQUEST_URI' => $url, - ]; - if (isset($this->_request['headers'])) { - foreach ($this->_request['headers'] as $k => $v) { - $name = strtoupper(str_replace('-', '_', $k)); - if (!in_array($name, ['CONTENT_LENGTH', 'CONTENT_TYPE'])) { - $name = 'HTTP_' . $name; - } - $env[$name] = $v; - } - unset($this->_request['headers']); - } - $props['environment'] = $env; - $props = Hash::merge($props, $this->_request); - - return $props; - } - - /** - * Add the CSRF and Security Component tokens if necessary. - * - * @param string $url The URL the form is being submitted on. - * @param array $data The request body data. - * @return array The request body with tokens added. - */ - protected function _addTokens($url, $data) - { - if ($this->_securityToken === true) { - $keys = array_map(function ($field) { - return preg_replace('/(\.\d+)+$/', '', $field); - }, array_keys(Hash::flatten($data))); - $tokenData = $this->_buildFieldToken($url, array_unique($keys)); - $data['_Token'] = $tokenData; - $data['_Token']['debug'] = 'SecurityComponent debug data would be added here'; - } - - if ($this->_csrfToken === true) { - if (!isset($this->_cookie['csrfToken'])) { - $this->_cookie['csrfToken'] = Text::uuid(); - } - if (!isset($data['_csrfToken'])) { - $data['_csrfToken'] = $this->_cookie['csrfToken']; - } - } - - return $data; - } - - /** - * Creates a valid request url and parameter array more like Request::_url() - * - * @param string|array $url The URL - * @return array Qualified URL and the query parameters - */ - protected function _url($url) - { - // re-create URL in ServerRequest's context so - // query strings are encoded as expected - $request = new ServerRequest(['url' => Router::url($url)]); - $url = $request->getRequestTarget(); - - $query = ''; - - $path = parse_url($url, PHP_URL_PATH); - if (strpos($url, '?') !== false) { - $query = parse_url($url, PHP_URL_QUERY); - } - - return [$path, $query]; - } - - /** - * Get the response body as string - * - * @return string The response body. - */ - protected function _getBodyAsString() - { - return (string)$this->_response->getBody(); - } - - /** - * Fetches a view variable by name. - * - * If the view variable does not exist, null will be returned. - * - * @param string $name The view variable to get. - * @return mixed The view variable if set. - */ - public function viewVariable($name) - { - if (empty($this->_controller->viewVars)) { - $this->fail('There are no view variables, perhaps you need to run a request?'); - } - if (isset($this->_controller->viewVars[$name])) { - return $this->_controller->viewVars[$name]; - } - - return null; - } - - /** - * Asserts that the response status code is in the 2xx range. - * - * @param string $message Custom message for failure. - * @return void - */ - public function assertResponseOk($message = null) - { - if (empty($message)) { - $message = 'Status code is not between 200 and 204'; - } - $this->_assertStatus(200, 204, $message); - } - - /** - * Asserts that the response status code is in the 2xx/3xx range. - * - * @param string $message Custom message for failure. - * @return void - */ - public function assertResponseSuccess($message = null) - { - if (empty($message)) { - $message = 'Status code is not between 200 and 308'; - } - $this->_assertStatus(200, 308, $message); - } - - /** - * Asserts that the response status code is in the 4xx range. - * - * @param string $message Custom message for failure. - * @return void - */ - public function assertResponseError($message = null) - { - if (empty($message)) { - $message = 'Status code is not between 400 and 429'; - } - $this->_assertStatus(400, 429, $message); - } - - /** - * Asserts that the response status code is in the 5xx range. - * - * @param string $message Custom message for failure. - * @return void - */ - public function assertResponseFailure($message = null) - { - if (empty($message)) { - $message = 'Status code is not between 500 and 505'; - } - $this->_assertStatus(500, 505, $message); - } - - /** - * Asserts a specific response status code. - * - * @param int $code Status code to assert. - * @param string $message Custom message for failure. - * @return void - */ - public function assertResponseCode($code, $message = null) - { - $actual = $this->_response->getStatusCode(); - - if (empty($message)) { - $message = 'Status code is not ' . $code . ' but ' . $actual; - } - - $this->_assertStatus($code, $code, $message); - } - - /** - * Helper method for status assertions. - * - * @param int $min Min status code. - * @param int $max Max status code. - * @param string $message The error message. - * @return void - */ - protected function _assertStatus($min, $max, $message) - { - if (!$this->_response) { - $this->fail('No response set, cannot assert status code.'); - } - $status = $this->_response->getStatusCode(); - - if ($this->_exception && ($status < $min || $status > $max)) { - $this->fail($this->_exception->getMessage()); - } - - $this->assertGreaterThanOrEqual($min, $status, $message); - $this->assertLessThanOrEqual($max, $status, $message); - } - - /** - * Asserts that the Location header is correct. - * - * @param string|array|null $url The URL you expected the client to go to. This - * can either be a string URL or an array compatible with Router::url(). Use null to - * simply check for the existence of this header. - * @param string $message The failure message that will be appended to the generated message. - * @return void - */ - public function assertRedirect($url = null, $message = '') - { - if (!$this->_response) { - $this->fail('No response set, cannot assert location header. ' . $message); - } - $result = $this->_response->getHeaderLine('Location'); - if ($url === null) { - $this->assertNotEmpty($result, $message); - - return; - } - if (empty($result)) { - $this->fail('No location header set. ' . $message); - } - $this->assertEquals(Router::url($url, ['_full' => true]), $result, $message); - } - - /** - * Asserts that the Location header contains a substring - * - * @param string $url The URL you expected the client to go to. - * @param string $message The failure message that will be appended to the generated message. - * @return void - */ - public function assertRedirectContains($url, $message = '') - { - if (!$this->_response) { - $this->fail('No response set, cannot assert location header. ' . $message); - } - $result = $this->_response->getHeaderLine('Location'); - if (empty($result)) { - $this->fail('No location header set. ' . $message); - } - $this->assertContains($url, $result, $message); - } - - /** - * Asserts that the Location header is not set. - * - * @param string $message The failure message that will be appended to the generated message. - * @return void - */ - public function assertNoRedirect($message = '') - { - if (!$this->_response) { - $this->fail('No response set, cannot assert location header. ' . $message); - } - $result = $this->_response->getHeaderLine('Location'); - if (!$message) { - $message = 'Redirect header set'; - } - if (!empty($result)) { - $message .= ': ' . $result; - } - $this->assertEmpty($result, $message); - } - - /** - * Asserts response headers - * - * @param string $header The header to check - * @param string $content The content to check for. - * @param string $message The failure message that will be appended to the generated message. - * @return void - */ - public function assertHeader($header, $content, $message = '') - { - if (!$this->_response) { - $this->fail('No response set, cannot assert headers. ' . $message); - } - if (!$this->_response->hasHeader($header)) { - $this->fail("The '$header' header is not set. " . $message); - } - $actual = $this->_response->getHeaderLine($header); - $this->assertEquals($content, $actual, $message); - } - - /** - * Asserts response header contains a string - * - * @param string $header The header to check - * @param string $content The content to check for. - * @param string $message The failure message that will be appended to the generated message. - * @return void - */ - public function assertHeaderContains($header, $content, $message = '') - { - if (!$this->_response) { - $this->fail('No response set, cannot assert headers. ' . $message); - } - if (!$this->_response->hasHeader($header)) { - $this->fail("The '$header' header is not set. " . $message); - } - $actual = $this->_response->getHeaderLine($header); - $this->assertContains($content, $actual, $message); - } - - /** - * Asserts content type - * - * @param string $type The content-type to check for. - * @param string $message The failure message that will be appended to the generated message. - * @return void - */ - public function assertContentType($type, $message = '') - { - if (!$this->_response) { - $this->fail('No response set, cannot assert content-type. ' . $message); - } - $alias = $this->_response->getMimeType($type); - if ($alias !== false) { - $type = $alias; - } - $result = $this->_response->getType(); - $this->assertEquals($type, $result, $message); - } - - /** - * Asserts content exists in the response body. - * - * @param mixed $content The content to check for. - * @param string $message The failure message that will be appended to the generated message. - * @return void - */ - public function assertResponseEquals($content, $message = '') - { - if (!$this->_response) { - $this->fail('No response set, cannot assert content. ' . $message); - } - $this->assertEquals($content, $this->_getBodyAsString(), $message); - } - - /** - * Asserts content exists in the response body. - * - * @param string $content The content to check for. - * @param string $message The failure message that will be appended to the generated message. - * @param bool $ignoreCase A flag to check whether we should ignore case or not. - * @return void - */ - public function assertResponseContains($content, $message = '', $ignoreCase = false) - { - if (!$this->_response) { - $this->fail('No response set, cannot assert content. ' . $message); - } - $this->assertContains($content, $this->_getBodyAsString(), $message, $ignoreCase); - } - - /** - * Asserts content does not exist in the response body. - * - * @param string $content The content to check for. - * @param string $message The failure message that will be appended to the generated message. - * @return void - */ - public function assertResponseNotContains($content, $message = '') - { - if (!$this->_response) { - $this->fail('No response set, cannot assert content. ' . $message); - } - $this->assertNotContains($content, $this->_getBodyAsString(), $message); - } - - /** - * Asserts that the response body matches a given regular expression. - * - * @param string $pattern The pattern to compare against. - * @param string $message The failure message that will be appended to the generated message. - * @return void - */ - public function assertResponseRegExp($pattern, $message = '') - { - if (!$this->_response) { - $this->fail('No response set, cannot assert content. ' . $message); - } - $this->assertRegExp($pattern, $this->_getBodyAsString(), $message); - } - - /** - * Asserts that the response body does not match a given regular expression. - * - * @param string $pattern The pattern to compare against. - * @param string $message The failure message that will be appended to the generated message. - * @return void - */ - public function assertResponseNotRegExp($pattern, $message = '') - { - if (!$this->_response) { - $this->fail('No response set, cannot assert content. ' . $message); - } - $this->assertNotRegExp($pattern, $this->_getBodyAsString(), $message); - } - - /** - * Assert response content is not empty. - * - * @param string $message The failure message that will be appended to the generated message. - * @return void - */ - public function assertResponseNotEmpty($message = '') - { - if (!$this->_response) { - $this->fail('No response set, cannot assert content. ' . $message); - } - $this->assertNotEmpty($this->_getBodyAsString(), $message); - } - /** - * Assert response content is empty. - * - * @param string $message The failure message that will be appended to the generated message. - * @return void - */ - public function assertResponseEmpty($message = '') - { - if (!$this->_response) { - $this->fail('No response set, cannot assert content. ' . $message); - } - $this->assertEmpty($this->_getBodyAsString(), $message); - } - - /** - * Asserts that the search string was in the template name. - * - * @param string $content The content to check for. - * @param string $message The failure message that will be appended to the generated message. - * @return void - */ - public function assertTemplate($content, $message = '') - { - if (!$this->_viewName) { - $this->fail('No view name stored. ' . $message); - } - $this->assertContains($content, $this->_viewName, $message); - } - - /** - * Asserts that the search string was in the layout name. - * - * @param string $content The content to check for. - * @param string $message The failure message that will be appended to the generated message. - * @return void - */ - public function assertLayout($content, $message = '') - { - if (!$this->_layoutName) { - $this->fail('No layout name stored. ' . $message); - } - $this->assertContains($content, $this->_layoutName, $message); - } - - /** - * Asserts session contents - * - * @param string $expected The expected contents. - * @param string $path The session data path. Uses Hash::get() compatible notation - * @param string $message The failure message that will be appended to the generated message. - * @return void - */ - public function assertSession($expected, $path, $message = '') - { - if (empty($this->_requestSession)) { - $this->fail('There is no stored session data. Perhaps you need to run a request?'); - } - $result = $this->_requestSession->read($path); - $this->assertEquals( - $expected, - $result, - 'Session content for "' . $path . '" differs. ' . $message - ); - } - - /** - * Asserts cookie values - * - * @param string $expected The expected contents. - * @param string $name The cookie name. - * @param string $message The failure message that will be appended to the generated message. - * @return void - */ - public function assertCookie($expected, $name, $message = '') - { - if (!$this->_response) { - $this->fail('Not response set, cannot assert cookies.'); - } - $result = $this->_response->getCookie($name); - $this->assertEquals( - $expected, - $result['value'], - 'Cookie "' . $name . '" data differs. ' . $message - ); - } - - /** - * Asserts a cookie has not been set in the response - * - * @param string $cookie The cookie name to check - * @param string $message The failure message that will be appended to the generated message. - * @return void - */ - public function assertCookieNotSet($cookie, $message = '') - { - if (!$this->_response) { - $this->fail('No response set, cannot assert cookies. ' . $message); - } - - $this->assertCookie(null, $cookie, "Cookie '{$cookie}' has been set. " . $message); - } - - /** - * Disable the error handler middleware. - * - * By using this function, exceptions are no longer caught by the ErrorHandlerMiddleware - * and are instead re-thrown by the TestExceptionRenderer. This can be helpful - * when trying to diagnose/debug unexpected failures in test cases. - * - * @return void - */ - public function disableErrorHandlerMiddleware() - { - Configure::write('Error.exceptionRenderer', TestExceptionRenderer::class); - } - - /** - * Asserts cookie values which are encrypted by the - * CookieComponent. - * - * The difference from assertCookie() is this decrypts the cookie - * value like the CookieComponent for this assertion. - * - * @param string $expected The expected contents. - * @param string $name The cookie name. - * @param string|bool $encrypt Encryption mode to use. - * @param string|null $key Encryption key used. Defaults - * to Security.salt. - * @param string $message The failure message that will be appended to the generated message. - * @return void - * @see \Cake\Utility\CookieCryptTrait::_encrypt() - */ - public function assertCookieEncrypted($expected, $name, $encrypt = 'aes', $key = null, $message = '') - { - if (!$this->_response) { - $this->fail('No response set, cannot assert cookies.'); - } - $result = $this->_response->getCookie($name); - $this->_cookieEncryptionKey = $key; - $result['value'] = $this->_decrypt($result['value'], $encrypt); - $this->assertEquals($expected, $result['value'], 'Cookie data differs. ' . $message); - } - - /** - * Asserts that a file with the given name was sent in the response - * - * @param string $expected The file name that should be sent in the response - * @param string $message The failure message that will be appended to the generated message. - * @return void - */ - public function assertFileResponse($expected, $message = '') - { - if ($this->_response === null) { - $this->fail('No response set, cannot assert file.'); - } - $actual = isset($this->_response->getFile()->path) ? $this->_response->getFile()->path : null; - - if ($actual === null) { - $this->fail('No file was sent in this response'); - } - $this->assertEquals($expected, $actual, $message); - } -} diff --git a/vendor/cakephp/cakephp/src/TestSuite/LegacyRequestDispatcher.php b/vendor/cakephp/cakephp/src/TestSuite/LegacyRequestDispatcher.php deleted file mode 100644 index 06640b2..0000000 --- a/vendor/cakephp/cakephp/src/TestSuite/LegacyRequestDispatcher.php +++ /dev/null @@ -1,63 +0,0 @@ -_test = $test; - } - - /** - * Run a request and get the response. - * - * @param array $request The request context to execute. - * @return string|null The generated response. - */ - public function execute($request) - { - $request = new ServerRequest($request); - $response = new Response(); - $dispatcher = DispatcherFactory::create(); - $dispatcher->getEventManager()->on( - 'Dispatcher.invokeController', - ['priority' => 999], - [$this->_test, 'controllerSpy'] - ); - - return $dispatcher->dispatch($request, $response); - } -} diff --git a/vendor/cakephp/cakephp/src/TestSuite/MiddlewareDispatcher.php b/vendor/cakephp/cakephp/src/TestSuite/MiddlewareDispatcher.php deleted file mode 100644 index e3a77cd..0000000 --- a/vendor/cakephp/cakephp/src/TestSuite/MiddlewareDispatcher.php +++ /dev/null @@ -1,128 +0,0 @@ -_test = $test; - $this->_class = $class ?: Configure::read('App.namespace') . '\Application'; - $this->_constructorArgs = $constructorArgs ?: [CONFIG]; - } - - /** - * Run a request and get the response. - * - * @param \Cake\Http\ServerRequest $request The request to execute. - * @return \Psr\Http\Message\ResponseInterface The generated response. - */ - public function execute($request) - { - try { - $reflect = new ReflectionClass($this->_class); - $app = $reflect->newInstanceArgs($this->_constructorArgs); - } catch (ReflectionException $e) { - throw new LogicException(sprintf( - 'Cannot load "%s" for use in integration testing.', - $this->_class - )); - } - - // Spy on the controller using the initialize hook instead - // of the dispatcher hooks as those will be going away one day. - EventManager::instance()->on( - 'Controller.initialize', - [$this->_test, 'controllerSpy'] - ); - - $server = new Server($app); - $psrRequest = $this->_createRequest($request); - - return $server->run($psrRequest); - } - - /** - * Create a PSR7 request from the request spec. - * - * @param array $spec The request spec. - * @return \Psr\Http\Message\RequestInterface - */ - protected function _createRequest($spec) - { - if (isset($spec['input'])) { - $spec['post'] = []; - } - $request = ServerRequestFactory::fromGlobals( - array_merge($_SERVER, $spec['environment'], ['REQUEST_URI' => $spec['url']]), - $spec['query'], - $spec['post'], - $spec['cookies'] - ); - $request = $request->withAttribute('session', $spec['session']); - - if (isset($spec['input'])) { - $stream = new Stream('php://memory', 'rw'); - $stream->write($spec['input']); - $stream->rewind(); - $request = $request->withBody($stream); - } - - return $request; - } -} diff --git a/vendor/cakephp/cakephp/src/TestSuite/StringCompareTrait.php b/vendor/cakephp/cakephp/src/TestSuite/StringCompareTrait.php deleted file mode 100644 index b6a9390..0000000 --- a/vendor/cakephp/cakephp/src/TestSuite/StringCompareTrait.php +++ /dev/null @@ -1,71 +0,0 @@ -_compareBasePath . $path; - } - - if ($this->_updateComparisons === null) { - $this->_updateComparisons = env('UPDATE_TEST_COMPARISON_FILES'); - } - - if ($this->_updateComparisons) { - $file = new File($path, true); - $file->write($result); - } - - $expected = file_get_contents($path); - $this->assertTextEquals($expected, $result); - } -} diff --git a/vendor/cakephp/cakephp/src/TestSuite/Stub/ConsoleOutput.php b/vendor/cakephp/cakephp/src/TestSuite/Stub/ConsoleOutput.php deleted file mode 100644 index f9c2b76..0000000 --- a/vendor/cakephp/cakephp/src/TestSuite/Stub/ConsoleOutput.php +++ /dev/null @@ -1,71 +0,0 @@ -_out[] = $line; - } - - $newlines--; - while ($newlines > 0) { - $this->_out[] = ''; - $newlines--; - } - } - - /** - * Get the buffered output. - * - * @return array - */ - public function messages() - { - return $this->_out; - } -} diff --git a/vendor/cakephp/cakephp/src/TestSuite/Stub/Response.php b/vendor/cakephp/cakephp/src/TestSuite/Stub/Response.php deleted file mode 100644 index 1d8b512..0000000 --- a/vendor/cakephp/cakephp/src/TestSuite/Stub/Response.php +++ /dev/null @@ -1,38 +0,0 @@ -hasHeader('Location') && $this->_status === 200) { - $this->statusCode(302); - } - $this->_setContentType(); - - return $this; - } -} diff --git a/vendor/cakephp/cakephp/src/TestSuite/TestCase.php b/vendor/cakephp/cakephp/src/TestSuite/TestCase.php deleted file mode 100644 index 541de8f..0000000 --- a/vendor/cakephp/cakephp/src/TestSuite/TestCase.php +++ /dev/null @@ -1,751 +0,0 @@ -markTestSkipped($message); - } - - return $shouldSkip; - } - - /** - * Helper method for tests that needs to use error_reporting() - * - * @param int $errorLevel value of error_reporting() that needs to use - * @param callable $callable callable function that will receive asserts - * @return void - */ - public function withErrorReporting($errorLevel, $callable) - { - $default = error_reporting(); - error_reporting($errorLevel); - try { - $callable(); - } finally { - error_reporting($default); - } - } - - /** - * Helper method for check deprecation methods - * - * @param callable $callable callable function that will receive asserts - * @return void - */ - public function deprecated($callable) - { - $errorLevel = error_reporting(); - error_reporting(E_ALL ^ E_USER_DEPRECATED); - try { - $callable(); - } finally { - error_reporting($errorLevel); - } - } - - /** - * Setup the test case, backup the static object values so they can be restored. - * Specifically backs up the contents of Configure and paths in App if they have - * not already been backed up. - * - * @return void - */ - public function setUp() - { - parent::setUp(); - - if (!$this->_configure) { - $this->_configure = Configure::read(); - } - if (class_exists('Cake\Routing\Router', false)) { - Router::reload(); - } - - EventManager::instance(new EventManager()); - } - - /** - * teardown any static object changes and restore them. - * - * @return void - */ - public function tearDown() - { - parent::tearDown(); - if ($this->_configure) { - Configure::clear(); - Configure::write($this->_configure); - } - $this->getTableLocator()->clear(); - } - - /** - * Chooses which fixtures to load for a given test - * - * Each parameter is a model name that corresponds to a fixture, i.e. 'Posts', 'Authors', etc. - * Passing no parameters will cause all fixtures on the test case to load. - * - * @return void - * @see \Cake\TestSuite\TestCase::$autoFixtures - * @throws \Exception when no fixture manager is available. - */ - public function loadFixtures() - { - if ($this->fixtureManager === null) { - throw new Exception('No fixture manager to load the test fixture'); - } - $args = func_get_args(); - foreach ($args as $class) { - $this->fixtureManager->loadSingle($class, null, $this->dropTables); - } - - if (empty($args)) { - $autoFixtures = $this->autoFixtures; - $this->autoFixtures = true; - $this->fixtureManager->load($this); - $this->autoFixtures = $autoFixtures; - } - } - - /** - * Asserts that a global event was fired. You must track events in your event manager for this assertion to work - * - * @param string $name Event name - * @param EventManager|null $eventManager Event manager to check, defaults to global event manager - * @param string $message Assertion failure message - * @return void - */ - public function assertEventFired($name, $eventManager = null, $message = '') - { - if (!$eventManager) { - $eventManager = EventManager::instance(); - } - $this->assertThat($name, new EventFired($eventManager), $message); - } - - /** - * Asserts an event was fired with data - * - * If a third argument is passed, that value is used to compare with the value in $dataKey - * - * @param string $name Event name - * @param string $dataKey Data key - * @param string $dataValue Data value - * @param EventManager|null $eventManager Event manager to check, defaults to global event manager - * @param string $message Assertion failure message - * @return void - */ - public function assertEventFiredWith($name, $dataKey, $dataValue, $eventManager = null, $message = '') - { - if (!$eventManager) { - $eventManager = EventManager::instance(); - } - $this->assertThat($name, new EventFiredWith($eventManager, $dataKey, $dataValue), $message); - } - - /** - * Assert text equality, ignoring differences in newlines. - * Helpful for doing cross platform tests of blocks of text. - * - * @param string $expected The expected value. - * @param string $result The actual value. - * @param string $message The message to use for failure. - * @return void - */ - public function assertTextNotEquals($expected, $result, $message = '') - { - $expected = str_replace(["\r\n", "\r"], "\n", $expected); - $result = str_replace(["\r\n", "\r"], "\n", $result); - $this->assertNotEquals($expected, $result, $message); - } - - /** - * Assert text equality, ignoring differences in newlines. - * Helpful for doing cross platform tests of blocks of text. - * - * @param string $expected The expected value. - * @param string $result The actual value. - * @param string $message The message to use for failure. - * @return void - */ - public function assertTextEquals($expected, $result, $message = '') - { - $expected = str_replace(["\r\n", "\r"], "\n", $expected); - $result = str_replace(["\r\n", "\r"], "\n", $result); - $this->assertEquals($expected, $result, $message); - } - - /** - * Asserts that a string starts with a given prefix, ignoring differences in newlines. - * Helpful for doing cross platform tests of blocks of text. - * - * @param string $prefix The prefix to check for. - * @param string $string The string to search in. - * @param string $message The message to use for failure. - * @return void - */ - public function assertTextStartsWith($prefix, $string, $message = '') - { - $prefix = str_replace(["\r\n", "\r"], "\n", $prefix); - $string = str_replace(["\r\n", "\r"], "\n", $string); - $this->assertStringStartsWith($prefix, $string, $message); - } - - /** - * Asserts that a string starts not with a given prefix, ignoring differences in newlines. - * Helpful for doing cross platform tests of blocks of text. - * - * @param string $prefix The prefix to not find. - * @param string $string The string to search. - * @param string $message The message to use for failure. - * @return void - */ - public function assertTextStartsNotWith($prefix, $string, $message = '') - { - $prefix = str_replace(["\r\n", "\r"], "\n", $prefix); - $string = str_replace(["\r\n", "\r"], "\n", $string); - $this->assertStringStartsNotWith($prefix, $string, $message); - } - - /** - * Asserts that a string ends with a given prefix, ignoring differences in newlines. - * Helpful for doing cross platform tests of blocks of text. - * - * @param string $suffix The suffix to find. - * @param string $string The string to search. - * @param string $message The message to use for failure. - * @return void - */ - public function assertTextEndsWith($suffix, $string, $message = '') - { - $suffix = str_replace(["\r\n", "\r"], "\n", $suffix); - $string = str_replace(["\r\n", "\r"], "\n", $string); - $this->assertStringEndsWith($suffix, $string, $message); - } - - /** - * Asserts that a string ends not with a given prefix, ignoring differences in newlines. - * Helpful for doing cross platform tests of blocks of text. - * - * @param string $suffix The suffix to not find. - * @param string $string The string to search. - * @param string $message The message to use for failure. - * @return void - */ - public function assertTextEndsNotWith($suffix, $string, $message = '') - { - $suffix = str_replace(["\r\n", "\r"], "\n", $suffix); - $string = str_replace(["\r\n", "\r"], "\n", $string); - $this->assertStringEndsNotWith($suffix, $string, $message); - } - - /** - * Assert that a string contains another string, ignoring differences in newlines. - * Helpful for doing cross platform tests of blocks of text. - * - * @param string $needle The string to search for. - * @param string $haystack The string to search through. - * @param string $message The message to display on failure. - * @param bool $ignoreCase Whether or not the search should be case-sensitive. - * @return void - */ - public function assertTextContains($needle, $haystack, $message = '', $ignoreCase = false) - { - $needle = str_replace(["\r\n", "\r"], "\n", $needle); - $haystack = str_replace(["\r\n", "\r"], "\n", $haystack); - $this->assertContains($needle, $haystack, $message, $ignoreCase); - } - - /** - * Assert that a text doesn't contain another text, ignoring differences in newlines. - * Helpful for doing cross platform tests of blocks of text. - * - * @param string $needle The string to search for. - * @param string $haystack The string to search through. - * @param string $message The message to display on failure. - * @param bool $ignoreCase Whether or not the search should be case-sensitive. - * @return void - */ - public function assertTextNotContains($needle, $haystack, $message = '', $ignoreCase = false) - { - $needle = str_replace(["\r\n", "\r"], "\n", $needle); - $haystack = str_replace(["\r\n", "\r"], "\n", $haystack); - $this->assertNotContains($needle, $haystack, $message, $ignoreCase); - } - - /** - * Asserts HTML tags. - * - * @param string $string An HTML/XHTML/XML string - * @param array $expected An array, see above - * @param bool $fullDebug Whether or not more verbose output should be used. - * @return void - * @deprecated 3.0. Use assertHtml() instead. - */ - public function assertTags($string, $expected, $fullDebug = false) - { - deprecationWarning('TestCase::assertTags() is deprecated. Use TestCase::assertHtml() instead.'); - $this->assertHtml($expected, $string, $fullDebug); - } - - /** - * Asserts HTML tags. - * - * Takes an array $expected and generates a regex from it to match the provided $string. - * Samples for $expected: - * - * Checks for an input tag with a name attribute (contains any non-empty value) and an id - * attribute that contains 'my-input': - * - * ``` - * ['input' => ['name', 'id' => 'my-input']] - * ``` - * - * Checks for two p elements with some text in them: - * - * ``` - * [ - * ['p' => true], - * 'textA', - * '/p', - * ['p' => true], - * 'textB', - * '/p' - * ] - * ``` - * - * You can also specify a pattern expression as part of the attribute values, or the tag - * being defined, if you prepend the value with preg: and enclose it with slashes, like so: - * - * ``` - * [ - * ['input' => ['name', 'id' => 'preg:/FieldName\d+/']], - * 'preg:/My\s+field/' - * ] - * ``` - * - * Important: This function is very forgiving about whitespace and also accepts any - * permutation of attribute order. It will also allow whitespace between specified tags. - * - * @param array $expected An array, see above - * @param string $string An HTML/XHTML/XML string - * @param bool $fullDebug Whether or not more verbose output should be used. - * @return bool - */ - public function assertHtml($expected, $string, $fullDebug = false) - { - $regex = []; - $normalized = []; - foreach ((array)$expected as $key => $val) { - if (!is_numeric($key)) { - $normalized[] = [$key => $val]; - } else { - $normalized[] = $val; - } - } - $i = 0; - foreach ($normalized as $tags) { - if (!is_array($tags)) { - $tags = (string)$tags; - } - $i++; - if (is_string($tags) && $tags{0} === '<') { - $tags = [substr($tags, 1) => []]; - } elseif (is_string($tags)) { - $tagsTrimmed = preg_replace('/\s+/m', '', $tags); - - if (preg_match('/^\*?\//', $tags, $match) && $tagsTrimmed !== '//') { - $prefix = [null, null]; - - if ($match[0] === '*/') { - $prefix = ['Anything, ', '.*?']; - } - $regex[] = [ - sprintf('%sClose %s tag', $prefix[0], substr($tags, strlen($match[0]))), - sprintf('%s\s*<[\s]*\/[\s]*%s[\s]*>[\n\r]*', $prefix[1], substr($tags, strlen($match[0]))), - $i, - ]; - continue; - } - if (!empty($tags) && preg_match('/^preg\:\/(.+)\/$/i', $tags, $matches)) { - $tags = $matches[1]; - $type = 'Regex matches'; - } else { - $tags = '\s*' . preg_quote($tags, '/'); - $type = 'Text equals'; - } - $regex[] = [ - sprintf('%s "%s"', $type, $tags), - $tags, - $i, - ]; - continue; - } - foreach ($tags as $tag => $attributes) { - $regex[] = [ - sprintf('Open %s tag', $tag), - sprintf('[\s]*<%s', preg_quote($tag, '/')), - $i, - ]; - if ($attributes === true) { - $attributes = []; - } - $attrs = []; - $explanations = []; - $i = 1; - foreach ($attributes as $attr => $val) { - if (is_numeric($attr) && preg_match('/^preg\:\/(.+)\/$/i', $val, $matches)) { - $attrs[] = $matches[1]; - $explanations[] = sprintf('Regex "%s" matches', $matches[1]); - continue; - } - - $quotes = '["\']'; - if (is_numeric($attr)) { - $attr = $val; - $val = '.+?'; - $explanations[] = sprintf('Attribute "%s" present', $attr); - } elseif (!empty($val) && preg_match('/^preg\:\/(.+)\/$/i', $val, $matches)) { - $val = str_replace( - ['.*', '.+'], - ['.*?', '.+?'], - $matches[1] - ); - $quotes = $val !== $matches[1] ? '["\']' : '["\']?'; - - $explanations[] = sprintf('Attribute "%s" matches "%s"', $attr, $val); - } else { - $explanations[] = sprintf('Attribute "%s" == "%s"', $attr, $val); - $val = preg_quote($val, '/'); - } - $attrs[] = '[\s]+' . preg_quote($attr, '/') . '=' . $quotes . $val . $quotes; - $i++; - } - if ($attrs) { - $regex[] = [ - 'explains' => $explanations, - 'attrs' => $attrs, - ]; - } - $regex[] = [ - sprintf('End %s tag', $tag), - '[\s]*\/?[\s]*>[\n\r]*', - $i, - ]; - } - } - foreach ($regex as $i => $assertion) { - $matches = false; - if (isset($assertion['attrs'])) { - $string = $this->_assertAttributes($assertion, $string, $fullDebug, $regex); - if ($fullDebug === true && $string === false) { - debug($string, true); - debug($regex, true); - } - continue; - } - - list($description, $expressions, $itemNum) = $assertion; - $expression = null; - foreach ((array)$expressions as $expression) { - $expression = sprintf('/^%s/s', $expression); - if (preg_match($expression, $string, $match)) { - $matches = true; - $string = substr($string, strlen($match[0])); - break; - } - } - if (!$matches) { - if ($fullDebug === true) { - debug($string); - debug($regex); - } - $this->assertRegExp($expression, $string, sprintf('Item #%d / regex #%d failed: %s', $itemNum, $i, $description)); - - return false; - } - } - - $this->assertTrue(true, '%s'); - - return true; - } - - /** - * Check the attributes as part of an assertTags() check. - * - * @param array $assertions Assertions to run. - * @param string $string The HTML string to check. - * @param bool $fullDebug Whether or not more verbose output should be used. - * @param array|string $regex Full regexp from `assertHtml` - * @return string|bool - */ - protected function _assertAttributes($assertions, $string, $fullDebug = false, $regex = '') - { - $asserts = $assertions['attrs']; - $explains = $assertions['explains']; - do { - $matches = false; - $j = null; - foreach ($asserts as $j => $assert) { - if (preg_match(sprintf('/^%s/s', $assert), $string, $match)) { - $matches = true; - $string = substr($string, strlen($match[0])); - array_splice($asserts, $j, 1); - array_splice($explains, $j, 1); - break; - } - } - if ($matches === false) { - if ($fullDebug === true) { - debug($string); - debug($regex); - } - $this->assertTrue(false, 'Attribute did not match. Was expecting ' . $explains[$j]); - } - $len = count($asserts); - } while ($len > 0); - - return $string; - } - - /** - * Normalize a path for comparison. - * - * @param string $path Path separated by "/" slash. - * @return string Normalized path separated by DIRECTORY_SEPARATOR. - */ - protected function _normalizePath($path) - { - return str_replace('/', DIRECTORY_SEPARATOR, $path); - } - -// @codingStandardsIgnoreStart - - /** - * Compatibility function to test if a value is between an acceptable range. - * - * @param float $expected - * @param float $result - * @param float $margin the rage of acceptation - * @param string $message the text to display if the assertion is not correct - * @return void - */ - protected static function assertWithinRange($expected, $result, $margin, $message = '') - { - $upper = $result + $margin; - $lower = $result - $margin; - static::assertTrue(($expected <= $upper) && ($expected >= $lower), $message); - } - - /** - * Compatibility function to test if a value is not between an acceptable range. - * - * @param float $expected - * @param float $result - * @param float $margin the rage of acceptation - * @param string $message the text to display if the assertion is not correct - * @return void - */ - protected static function assertNotWithinRange($expected, $result, $margin, $message = '') - { - $upper = $result + $margin; - $lower = $result - $margin; - static::assertTrue(($expected > $upper) || ($expected < $lower), $message); - } - - /** - * Compatibility function to test paths. - * - * @param string $expected - * @param string $result - * @param string $message the text to display if the assertion is not correct - * @return void - */ - protected static function assertPathEquals($expected, $result, $message = '') - { - $expected = str_replace(DIRECTORY_SEPARATOR, '/', $expected); - $result = str_replace(DIRECTORY_SEPARATOR, '/', $result); - static::assertEquals($expected, $result, $message); - } - - /** - * Compatibility function for skipping. - * - * @param bool $condition Condition to trigger skipping - * @param string $message Message for skip - * @return bool - */ - protected function skipUnless($condition, $message = '') - { - if (!$condition) { - $this->markTestSkipped($message); - } - - return $condition; - } - -// @codingStandardsIgnoreEnd - - /** - * Mock a model, maintain fixtures and table association - * - * @param string $alias The model to get a mock for. - * @param array $methods The list of methods to mock - * @param array $options The config data for the mock's constructor. - * @throws \Cake\ORM\Exception\MissingTableClassException - * @return \Cake\ORM\Table|\PHPUnit_Framework_MockObject_MockObject - */ - public function getMockForModel($alias, array $methods = [], array $options = []) - { - /** @var \Cake\ORM\Table $className */ - $className = $this->_getTableClassName($alias, $options); - $connectionName = $className::defaultConnectionName(); - $connection = ConnectionManager::get($connectionName); - - $locator = $this->getTableLocator(); - - list(, $baseClass) = pluginSplit($alias); - $options += ['alias' => $baseClass, 'connection' => $connection]; - $options += $locator->getConfig($alias); - - /** @var \Cake\ORM\Table|\PHPUnit_Framework_MockObject_MockObject $mock */ - $mock = $this->getMockBuilder($className) - ->setMethods($methods) - ->setConstructorArgs([$options]) - ->getMock(); - - if (empty($options['entityClass']) && $mock->getEntityClass() === Entity::class) { - $parts = explode('\\', $className); - $entityAlias = Inflector::singularize(substr(array_pop($parts), 0, -5)); - $entityClass = implode('\\', array_slice($parts, 0, -1)) . '\\Entity\\' . $entityAlias; - if (class_exists($entityClass)) { - $mock->setEntityClass($entityClass); - } - } - - if (stripos($mock->getTable(), 'mock') === 0) { - $mock->setTable(Inflector::tableize($baseClass)); - } - - $locator->set($baseClass, $mock); - $locator->set($alias, $mock); - - return $mock; - } - - /** - * Gets the class name for the table. - * - * @param string $alias The model to get a mock for. - * @param array $options The config data for the mock's constructor. - * @return string - * @throws \Cake\ORM\Exception\MissingTableClassException - */ - protected function _getTableClassName($alias, array $options) - { - if (empty($options['className'])) { - $class = Inflector::camelize($alias); - $className = App::className($class, 'Model/Table', 'Table'); - if (!$className) { - throw new MissingTableClassException([$alias]); - } - $options['className'] = $className; - } - - return $options['className']; - } - - /** - * Set the app namespace - * - * @param string $appNamespace The app namespace, defaults to "TestApp". - * @return void - */ - public static function setAppNamespace($appNamespace = 'TestApp') - { - Configure::write('App.namespace', $appNamespace); - } -} diff --git a/vendor/cakephp/cakephp/src/TestSuite/TestSuite.php b/vendor/cakephp/cakephp/src/TestSuite/TestSuite.php deleted file mode 100644 index 1c27a5b..0000000 --- a/vendor/cakephp/cakephp/src/TestSuite/TestSuite.php +++ /dev/null @@ -1,65 +0,0 @@ -read(true, true, true); - - foreach ($files as $file) { - if (substr($file, -4) === '.php') { - $this->addTestFile($file); - } - } - } - - /** - * Recursively adds all the files in a directory to the test suite. - * - * @param string $directory The directory subtree to add tests from. - * @return void - */ - public function addTestDirectoryRecursive($directory = '.') - { - $Folder = new Folder($directory); - $files = $Folder->tree(null, true, 'files'); - - foreach ($files as $file) { - if (substr($file, -4) === '.php') { - $this->addTestFile($file); - } - } - } -} diff --git a/vendor/cakephp/cakephp/src/Utility/CookieCryptTrait.php b/vendor/cakephp/cakephp/src/Utility/CookieCryptTrait.php deleted file mode 100644 index 77023b5..0000000 --- a/vendor/cakephp/cakephp/src/Utility/CookieCryptTrait.php +++ /dev/null @@ -1,182 +0,0 @@ -_implode($value); - } - if ($encrypt === false) { - return $value; - } - $this->_checkCipher($encrypt); - $prefix = 'Q2FrZQ==.'; - $cipher = null; - if ($key === null) { - $key = $this->_getCookieEncryptionKey(); - } - if ($encrypt === 'rijndael') { - $cipher = Security::rijndael($value, $key, 'encrypt'); - } - if ($encrypt === 'aes') { - $cipher = Security::encrypt($value, $key); - } - - return $prefix . base64_encode($cipher); - } - - /** - * Helper method for validating encryption cipher names. - * - * @param string $encrypt The cipher name. - * @return void - * @throws \RuntimeException When an invalid cipher is provided. - */ - protected function _checkCipher($encrypt) - { - if (!in_array($encrypt, $this->_validCiphers)) { - $msg = sprintf( - 'Invalid encryption cipher. Must be one of %s.', - implode(', ', $this->_validCiphers) - ); - throw new RuntimeException($msg); - } - } - - /** - * Decrypts $value using public $type method in Security class - * - * @param array $values Values to decrypt - * @param string|bool $mode Encryption mode - * @param string|null $key Used as the security salt if specified. - * @return string|array Decrypted values - */ - protected function _decrypt($values, $mode, $key = null) - { - if (is_string($values)) { - return $this->_decode($values, $mode, $key); - } - - $decrypted = []; - foreach ($values as $name => $value) { - $decrypted[$name] = $this->_decode($value, $mode, $key); - } - - return $decrypted; - } - - /** - * Decodes and decrypts a single value. - * - * @param string $value The value to decode & decrypt. - * @param string|false $encrypt The encryption cipher to use. - * @param string|null $key Used as the security salt if specified. - * @return string|array Decoded values. - */ - protected function _decode($value, $encrypt, $key) - { - if (!$encrypt) { - return $this->_explode($value); - } - $this->_checkCipher($encrypt); - $prefix = 'Q2FrZQ==.'; - $value = base64_decode(substr($value, strlen($prefix))); - if ($key === null) { - $key = $this->_getCookieEncryptionKey(); - } - if ($encrypt === 'rijndael') { - $value = Security::rijndael($value, $key, 'decrypt'); - } - if ($encrypt === 'aes') { - $value = Security::decrypt($value, $key); - } - - return $this->_explode($value); - } - - /** - * Implode method to keep keys are multidimensional arrays - * - * @param array $array Map of key and values - * @return string A json encoded string. - */ - protected function _implode(array $array) - { - return json_encode($array); - } - - /** - * Explode method to return array from string set in CookieComponent::_implode() - * Maintains reading backwards compatibility with 1.x CookieComponent::_implode(). - * - * @param string $string A string containing JSON encoded data, or a bare string. - * @return string|array Map of key and values - */ - protected function _explode($string) - { - $first = substr($string, 0, 1); - if ($first === '{' || $first === '[') { - $ret = json_decode($string, true); - - return ($ret !== null) ? $ret : $string; - } - $array = []; - foreach (explode(',', $string) as $pair) { - $key = explode('|', $pair); - if (!isset($key[1])) { - return $key[0]; - } - $array[$key[0]] = $key[1]; - } - - return $array; - } -} diff --git a/vendor/cakephp/cakephp/src/Utility/Crypto/Mcrypt.php b/vendor/cakephp/cakephp/src/Utility/Crypto/Mcrypt.php deleted file mode 100644 index b67c72e..0000000 --- a/vendor/cakephp/cakephp/src/Utility/Crypto/Mcrypt.php +++ /dev/null @@ -1,125 +0,0 @@ -`, `<`, `>=`, `<=` Value comparison. - * - `=/.../` Regular expression pattern match. - * - * Given a set of User array data, from a `$User->find('all')` call: - * - * - `1.User.name` Get the name of the user at index 1. - * - `{n}.User.name` Get the name of every user in the set of users. - * - `{n}.User[id].name` Get the name of every user with an id key. - * - `{n}.User[id>=2].name` Get the name of every user with an id key greater than or equal to 2. - * - `{n}.User[username=/^paul/]` Get User elements with username matching `^paul`. - * - `{n}.User[id=1].name` Get the Users name with id matching `1`. - * - * @param array|\ArrayAccess $data The data to extract from. - * @param string $path The path to extract. - * @return array|\ArrayAccess An array of the extracted values. Returns an empty array - * if there are no matches. - * @link https://book.cakephp.org/3.0/en/core-libraries/hash.html#Cake\Utility\Hash::extract - */ - public static function extract($data, $path) - { - if (!(is_array($data) || $data instanceof ArrayAccess)) { - throw new InvalidArgumentException( - 'Invalid data type, must be an array or \ArrayAccess instance.' - ); - } - - if (empty($path)) { - return $data; - } - - // Simple paths. - if (!preg_match('/[{\[]/', $path)) { - $data = static::get($data, $path); - if ($data !== null && !(is_array($data) || $data instanceof ArrayAccess)) { - return [$data]; - } - - return $data !== null ? (array)$data : []; - } - - if (strpos($path, '[') === false) { - $tokens = explode('.', $path); - } else { - $tokens = Text::tokenize($path, '.', '[', ']'); - } - - $_key = '__set_item__'; - - $context = [$_key => [$data]]; - - foreach ($tokens as $token) { - $next = []; - - list($token, $conditions) = self::_splitConditions($token); - - foreach ($context[$_key] as $item) { - if (is_object($item) && method_exists($item, 'toArray')) { - /** @var \Cake\Datasource\EntityInterface $item */ - $item = $item->toArray(); - } - foreach ((array)$item as $k => $v) { - if (static::_matchToken($k, $token)) { - $next[] = $v; - } - } - } - - // Filter for attributes. - if ($conditions) { - $filter = []; - foreach ($next as $item) { - if ((is_array($item) || $item instanceof ArrayAccess) && - static::_matches($item, $conditions) - ) { - $filter[] = $item; - } - } - $next = $filter; - } - $context = [$_key => $next]; - } - - return $context[$_key]; - } - - /** - * Split token conditions - * - * @param string $token the token being splitted. - * @return array [token, conditions] with token splitted - */ - protected static function _splitConditions($token) - { - $conditions = false; - $position = strpos($token, '['); - if ($position !== false) { - $conditions = substr($token, $position); - $token = substr($token, 0, $position); - } - - return [$token, $conditions]; - } - - /** - * Check a key against a token. - * - * @param string $key The key in the array being searched. - * @param string $token The token being matched. - * @return bool - */ - protected static function _matchToken($key, $token) - { - switch ($token) { - case '{n}': - return is_numeric($key); - case '{s}': - return is_string($key); - case '{*}': - return true; - default: - return is_numeric($token) ? ($key == $token) : $key === $token; - } - } - - /** - * Checks whether or not $data matches the attribute patterns - * - * @param array|\ArrayAccess $data Array of data to match. - * @param string $selector The patterns to match. - * @return bool Fitness of expression. - */ - protected static function _matches($data, $selector) - { - preg_match_all( - '/(\[ (?P[^=>[><]) \s* (?P(?:\/.*?\/ | [^\]]+)) )? \])/x', - $selector, - $conditions, - PREG_SET_ORDER - ); - - foreach ($conditions as $cond) { - $attr = $cond['attr']; - $op = isset($cond['op']) ? $cond['op'] : null; - $val = isset($cond['val']) ? $cond['val'] : null; - - // Presence test. - if (empty($op) && empty($val) && !isset($data[$attr])) { - return false; - } - - // Empty attribute = fail. - if (!(isset($data[$attr]) || array_key_exists($attr, $data))) { - return false; - } - - $prop = null; - if (isset($data[$attr])) { - $prop = $data[$attr]; - } - $isBool = is_bool($prop); - if ($isBool && is_numeric($val)) { - $prop = $prop ? '1' : '0'; - } elseif ($isBool) { - $prop = $prop ? 'true' : 'false'; - } elseif (is_numeric($prop)) { - $prop = (string)$prop; - } - - // Pattern matches and other operators. - if ($op === '=' && $val && $val[0] === '/') { - if (!preg_match($val, $prop)) { - return false; - } - } elseif (($op === '=' && $prop != $val) || - ($op === '!=' && $prop == $val) || - ($op === '>' && $prop <= $val) || - ($op === '<' && $prop >= $val) || - ($op === '>=' && $prop < $val) || - ($op === '<=' && $prop > $val) - ) { - return false; - } - } - - return true; - } - - /** - * Insert $values into an array with the given $path. You can use - * `{n}` and `{s}` elements to insert $data multiple times. - * - * @param array $data The data to insert into. - * @param string $path The path to insert at. - * @param array|null $values The values to insert. - * @return array The data with $values inserted. - * @link https://book.cakephp.org/3.0/en/core-libraries/hash.html#Cake\Utility\Hash::insert - */ - public static function insert(array $data, $path, $values = null) - { - $noTokens = strpos($path, '[') === false; - if ($noTokens && strpos($path, '.') === false) { - $data[$path] = $values; - - return $data; - } - - if ($noTokens) { - $tokens = explode('.', $path); - } else { - $tokens = Text::tokenize($path, '.', '[', ']'); - } - - if ($noTokens && strpos($path, '{') === false) { - return static::_simpleOp('insert', $data, $tokens, $values); - } - - $token = array_shift($tokens); - $nextPath = implode('.', $tokens); - - list($token, $conditions) = static::_splitConditions($token); - - foreach ($data as $k => $v) { - if (static::_matchToken($k, $token)) { - if (!$conditions || static::_matches($v, $conditions)) { - $data[$k] = $nextPath - ? static::insert($v, $nextPath, $values) - : array_merge($v, (array)$values); - } - } - } - - return $data; - } - - /** - * Perform a simple insert/remove operation. - * - * @param string $op The operation to do. - * @param array $data The data to operate on. - * @param array $path The path to work on. - * @param mixed $values The values to insert when doing inserts. - * @return array data. - */ - protected static function _simpleOp($op, $data, $path, $values = null) - { - $_list =& $data; - - $count = count($path); - $last = $count - 1; - foreach ($path as $i => $key) { - if ($op === 'insert') { - if ($i === $last) { - $_list[$key] = $values; - - return $data; - } - if (!isset($_list[$key])) { - $_list[$key] = []; - } - $_list =& $_list[$key]; - if (!is_array($_list)) { - $_list = []; - } - } elseif ($op === 'remove') { - if ($i === $last) { - if (is_array($_list)) { - unset($_list[$key]); - } - - return $data; - } - if (!isset($_list[$key])) { - return $data; - } - $_list =& $_list[$key]; - } - } - } - - /** - * Remove data matching $path from the $data array. - * You can use `{n}` and `{s}` to remove multiple elements - * from $data. - * - * @param array $data The data to operate on - * @param string $path A path expression to use to remove. - * @return array The modified array. - * @link https://book.cakephp.org/3.0/en/core-libraries/hash.html#Cake\Utility\Hash::remove - */ - public static function remove(array $data, $path) - { - $noTokens = strpos($path, '[') === false; - $noExpansion = strpos($path, '{') === false; - - if ($noExpansion && $noTokens && strpos($path, '.') === false) { - unset($data[$path]); - - return $data; - } - - $tokens = $noTokens ? explode('.', $path) : Text::tokenize($path, '.', '[', ']'); - - if ($noExpansion && $noTokens) { - return static::_simpleOp('remove', $data, $tokens); - } - - $token = array_shift($tokens); - $nextPath = implode('.', $tokens); - - list($token, $conditions) = self::_splitConditions($token); - - foreach ($data as $k => $v) { - $match = static::_matchToken($k, $token); - if ($match && is_array($v)) { - if ($conditions) { - if (static::_matches($v, $conditions)) { - if ($nextPath !== '') { - $data[$k] = static::remove($v, $nextPath); - } else { - unset($data[$k]); - } - } - } else { - $data[$k] = static::remove($v, $nextPath); - } - if (empty($data[$k])) { - unset($data[$k]); - } - } elseif ($match && $nextPath === '') { - unset($data[$k]); - } - } - - return $data; - } - - /** - * Creates an associative array using `$keyPath` as the path to build its keys, and optionally - * `$valuePath` as path to get the values. If `$valuePath` is not specified, all values will be initialized - * to null (useful for Hash::merge). You can optionally group the values by what is obtained when - * following the path specified in `$groupPath`. - * - * @param array $data Array from where to extract keys and values - * @param string $keyPath A dot-separated string. - * @param string|null $valuePath A dot-separated string. - * @param string|null $groupPath A dot-separated string. - * @return array Combined array - * @link https://book.cakephp.org/3.0/en/core-libraries/hash.html#Cake\Utility\Hash::combine - * @throws \RuntimeException When keys and values count is unequal. - */ - public static function combine(array $data, $keyPath, $valuePath = null, $groupPath = null) - { - if (empty($data)) { - return []; - } - - if (is_array($keyPath)) { - $format = array_shift($keyPath); - $keys = static::format($data, $keyPath, $format); - } else { - $keys = static::extract($data, $keyPath); - } - if (empty($keys)) { - return []; - } - - $vals = null; - if (!empty($valuePath) && is_array($valuePath)) { - $format = array_shift($valuePath); - $vals = static::format($data, $valuePath, $format); - } elseif (!empty($valuePath)) { - $vals = static::extract($data, $valuePath); - } - if (empty($vals)) { - $vals = array_fill(0, count($keys), null); - } - - if (count($keys) !== count($vals)) { - throw new RuntimeException( - 'Hash::combine() needs an equal number of keys + values.' - ); - } - - if ($groupPath !== null) { - $group = static::extract($data, $groupPath); - if (!empty($group)) { - $c = count($keys); - $out = []; - for ($i = 0; $i < $c; $i++) { - if (!isset($group[$i])) { - $group[$i] = 0; - } - if (!isset($out[$group[$i]])) { - $out[$group[$i]] = []; - } - $out[$group[$i]][$keys[$i]] = $vals[$i]; - } - - return $out; - } - } - if (empty($vals)) { - return []; - } - - return array_combine($keys, $vals); - } - - /** - * Returns a formatted series of values extracted from `$data`, using - * `$format` as the format and `$paths` as the values to extract. - * - * Usage: - * - * ``` - * $result = Hash::format($users, ['{n}.User.id', '{n}.User.name'], '%s : %s'); - * ``` - * - * The `$format` string can use any format options that `vsprintf()` and `sprintf()` do. - * - * @param array $data Source array from which to extract the data - * @param array $paths An array containing one or more Hash::extract()-style key paths - * @param string $format Format string into which values will be inserted, see sprintf() - * @return array|null An array of strings extracted from `$path` and formatted with `$format` - * @link https://book.cakephp.org/3.0/en/core-libraries/hash.html#Cake\Utility\Hash::format - * @see sprintf() - * @see \Cake\Utility\Hash::extract() - */ - public static function format(array $data, array $paths, $format) - { - $extracted = []; - $count = count($paths); - - if (!$count) { - return null; - } - - for ($i = 0; $i < $count; $i++) { - $extracted[] = static::extract($data, $paths[$i]); - } - $out = []; - $data = $extracted; - $count = count($data[0]); - - $countTwo = count($data); - for ($j = 0; $j < $count; $j++) { - $args = []; - for ($i = 0; $i < $countTwo; $i++) { - if (array_key_exists($j, $data[$i])) { - $args[] = $data[$i][$j]; - } - } - $out[] = vsprintf($format, $args); - } - - return $out; - } - - /** - * Determines if one array contains the exact keys and values of another. - * - * @param array $data The data to search through. - * @param array $needle The values to file in $data - * @return bool true If $data contains $needle, false otherwise - * @link https://book.cakephp.org/3.0/en/core-libraries/hash.html#Cake\Utility\Hash::contains - */ - public static function contains(array $data, array $needle) - { - if (empty($data) || empty($needle)) { - return false; - } - $stack = []; - - while (!empty($needle)) { - $key = key($needle); - $val = $needle[$key]; - unset($needle[$key]); - - if (array_key_exists($key, $data) && is_array($val)) { - $next = $data[$key]; - unset($data[$key]); - - if (!empty($val)) { - $stack[] = [$val, $next]; - } - } elseif (!array_key_exists($key, $data) || $data[$key] != $val) { - return false; - } - - if (empty($needle) && !empty($stack)) { - list($needle, $data) = array_pop($stack); - } - } - - return true; - } - - /** - * Test whether or not a given path exists in $data. - * This method uses the same path syntax as Hash::extract() - * - * Checking for paths that could target more than one element will - * make sure that at least one matching element exists. - * - * @param array $data The data to check. - * @param string $path The path to check for. - * @return bool Existence of path. - * @see \Cake\Utility\Hash::extract() - * @link https://book.cakephp.org/3.0/en/core-libraries/hash.html#Cake\Utility\Hash::check - */ - public static function check(array $data, $path) - { - $results = static::extract($data, $path); - if (!is_array($results)) { - return false; - } - - return count($results) > 0; - } - - /** - * Recursively filters a data set. - * - * @param array $data Either an array to filter, or value when in callback - * @param callable|array $callback A function to filter the data with. Defaults to - * `static::_filter()` Which strips out all non-zero empty values. - * @return array Filtered array - * @link https://book.cakephp.org/3.0/en/core-libraries/hash.html#Cake\Utility\Hash::filter - */ - public static function filter(array $data, $callback = ['self', '_filter']) - { - foreach ($data as $k => $v) { - if (is_array($v)) { - $data[$k] = static::filter($v, $callback); - } - } - - return array_filter($data, $callback); - } - - /** - * Callback function for filtering. - * - * @param mixed $var Array to filter. - * @return bool - */ - protected static function _filter($var) - { - return $var === 0 || $var === 0.0 || $var === '0' || !empty($var); - } - - /** - * Collapses a multi-dimensional array into a single dimension, using a delimited array path for - * each array element's key, i.e. [['Foo' => ['Bar' => 'Far']]] becomes - * ['0.Foo.Bar' => 'Far'].) - * - * @param array $data Array to flatten - * @param string $separator String used to separate array key elements in a path, defaults to '.' - * @return array - * @link https://book.cakephp.org/3.0/en/core-libraries/hash.html#Cake\Utility\Hash::flatten - */ - public static function flatten(array $data, $separator = '.') - { - $result = []; - $stack = []; - $path = null; - - reset($data); - while (!empty($data)) { - $key = key($data); - $element = $data[$key]; - unset($data[$key]); - - if (is_array($element) && !empty($element)) { - if (!empty($data)) { - $stack[] = [$data, $path]; - } - $data = $element; - reset($data); - $path .= $key . $separator; - } else { - $result[$path . $key] = $element; - } - - if (empty($data) && !empty($stack)) { - list($data, $path) = array_pop($stack); - reset($data); - } - } - - return $result; - } - - /** - * Expands a flat array to a nested array. - * - * For example, unflattens an array that was collapsed with `Hash::flatten()` - * into a multi-dimensional array. So, `['0.Foo.Bar' => 'Far']` becomes - * `[['Foo' => ['Bar' => 'Far']]]`. - * - * @param array $data Flattened array - * @param string $separator The delimiter used - * @return array - * @link https://book.cakephp.org/3.0/en/core-libraries/hash.html#Cake\Utility\Hash::expand - */ - public static function expand(array $data, $separator = '.') - { - $result = []; - foreach ($data as $flat => $value) { - $keys = explode($separator, $flat); - $keys = array_reverse($keys); - $child = [ - $keys[0] => $value - ]; - array_shift($keys); - foreach ($keys as $k) { - $child = [ - $k => $child - ]; - } - - $stack = [[$child, &$result]]; - static::_merge($stack, $result); - } - - return $result; - } - - /** - * This function can be thought of as a hybrid between PHP's `array_merge` and `array_merge_recursive`. - * - * The difference between this method and the built-in ones, is that if an array key contains another array, then - * Hash::merge() will behave in a recursive fashion (unlike `array_merge`). But it will not act recursively for - * keys that contain scalar values (unlike `array_merge_recursive`). - * - * Note: This function will work with an unlimited amount of arguments and typecasts non-array parameters into arrays. - * - * @param array $data Array to be merged - * @param mixed $merge Array to merge with. The argument and all trailing arguments will be array cast when merged - * @return array Merged array - * @link https://book.cakephp.org/3.0/en/core-libraries/hash.html#Cake\Utility\Hash::merge - */ - public static function merge(array $data, $merge) - { - $args = array_slice(func_get_args(), 1); - $return = $data; - $stack = []; - - foreach ($args as &$curArg) { - $stack[] = [(array)$curArg, &$return]; - } - unset($curArg); - static::_merge($stack, $return); - - return $return; - } - - /** - * Merge helper function to reduce duplicated code between merge() and expand(). - * - * @param array $stack The stack of operations to work with. - * @param array $return The return value to operate on. - * @return void - */ - protected static function _merge($stack, &$return) - { - while (!empty($stack)) { - foreach ($stack as $curKey => &$curMerge) { - foreach ($curMerge[0] as $key => &$val) { - $isArray = is_array($curMerge[1]); - if ($isArray && !empty($curMerge[1][$key]) && (array)$curMerge[1][$key] === $curMerge[1][$key] && (array)$val === $val) { - // Recurse into the current merge data as it is an array. - $stack[] = [&$val, &$curMerge[1][$key]]; - } elseif ((int)$key === $key && $isArray && isset($curMerge[1][$key])) { - $curMerge[1][] = $val; - } else { - $curMerge[1][$key] = $val; - } - } - unset($stack[$curKey]); - } - unset($curMerge); - } - } - - /** - * Checks to see if all the values in the array are numeric - * - * @param array $data The array to check. - * @return bool true if values are numeric, false otherwise - * @link https://book.cakephp.org/3.0/en/core-libraries/hash.html#Cake\Utility\Hash::numeric - */ - public static function numeric(array $data) - { - if (empty($data)) { - return false; - } - - return $data === array_filter($data, 'is_numeric'); - } - - /** - * Counts the dimensions of an array. - * Only considers the dimension of the first element in the array. - * - * If you have an un-even or heterogeneous array, consider using Hash::maxDimensions() - * to get the dimensions of the array. - * - * @param array $data Array to count dimensions on - * @return int The number of dimensions in $data - * @link https://book.cakephp.org/3.0/en/core-libraries/hash.html#Cake\Utility\Hash::dimensions - */ - public static function dimensions(array $data) - { - if (empty($data)) { - return 0; - } - reset($data); - $depth = 1; - while ($elem = array_shift($data)) { - if (is_array($elem)) { - $depth++; - $data = $elem; - } else { - break; - } - } - - return $depth; - } - - /** - * Counts the dimensions of *all* array elements. Useful for finding the maximum - * number of dimensions in a mixed array. - * - * @param array $data Array to count dimensions on - * @return int The maximum number of dimensions in $data - * @link https://book.cakephp.org/3.0/en/core-libraries/hash.html#Cake\Utility\Hash::maxDimensions - */ - public static function maxDimensions(array $data) - { - $depth = []; - if (is_array($data) && !empty($data)) { - foreach ($data as $value) { - if (is_array($value)) { - $depth[] = static::maxDimensions($value) + 1; - } else { - $depth[] = 1; - } - } - } - - return empty($depth) ? 0 : max($depth); - } - - /** - * Map a callback across all elements in a set. - * Can be provided a path to only modify slices of the set. - * - * @param array $data The data to map over, and extract data out of. - * @param string $path The path to extract for mapping over. - * @param callable $function The function to call on each extracted value. - * @return array An array of the modified values. - * @link https://book.cakephp.org/3.0/en/core-libraries/hash.html#Cake\Utility\Hash::map - */ - public static function map(array $data, $path, $function) - { - $values = (array)static::extract($data, $path); - - return array_map($function, $values); - } - - /** - * Reduce a set of extracted values using `$function`. - * - * @param array $data The data to reduce. - * @param string $path The path to extract from $data. - * @param callable $function The function to call on each extracted value. - * @return mixed The reduced value. - * @link https://book.cakephp.org/3.0/en/core-libraries/hash.html#Cake\Utility\Hash::reduce - */ - public static function reduce(array $data, $path, $function) - { - $values = (array)static::extract($data, $path); - - return array_reduce($values, $function); - } - - /** - * Apply a callback to a set of extracted values using `$function`. - * The function will get the extracted values as the first argument. - * - * ### Example - * - * You can easily count the results of an extract using apply(). - * For example to count the comments on an Article: - * - * ``` - * $count = Hash::apply($data, 'Article.Comment.{n}', 'count'); - * ``` - * - * You could also use a function like `array_sum` to sum the results. - * - * ``` - * $total = Hash::apply($data, '{n}.Item.price', 'array_sum'); - * ``` - * - * @param array $data The data to reduce. - * @param string $path The path to extract from $data. - * @param callable $function The function to call on each extracted value. - * @return mixed The results of the applied method. - * @link https://book.cakephp.org/3.0/en/core-libraries/hash.html#Cake\Utility\Hash::apply - */ - public static function apply(array $data, $path, $function) - { - $values = (array)static::extract($data, $path); - - return call_user_func($function, $values); - } - - /** - * Sorts an array by any value, determined by a Set-compatible path - * - * ### Sort directions - * - * - `asc` Sort ascending. - * - `desc` Sort descending. - * - * ### Sort types - * - * - `regular` For regular sorting (don't change types) - * - `numeric` Compare values numerically - * - `string` Compare values as strings - * - `locale` Compare items as strings, based on the current locale - * - `natural` Compare items as strings using "natural ordering" in a human friendly way - * Will sort foo10 below foo2 as an example. - * - * To do case insensitive sorting, pass the type as an array as follows: - * - * ``` - * Hash::sort($data, 'some.attribute', 'asc', ['type' => 'regular', 'ignoreCase' => true]); - * ``` - * - * When using the array form, `type` defaults to 'regular'. The `ignoreCase` option - * defaults to `false`. - * - * @param array $data An array of data to sort - * @param string $path A Set-compatible path to the array value - * @param string $dir See directions above. Defaults to 'asc'. - * @param array|string $type See direction types above. Defaults to 'regular'. - * @return array Sorted array of data - * @link https://book.cakephp.org/3.0/en/core-libraries/hash.html#Cake\Utility\Hash::sort - */ - public static function sort(array $data, $path, $dir = 'asc', $type = 'regular') - { - if (empty($data)) { - return []; - } - $originalKeys = array_keys($data); - $numeric = is_numeric(implode('', $originalKeys)); - if ($numeric) { - $data = array_values($data); - } - $sortValues = static::extract($data, $path); - $dataCount = count($data); - - // Make sortValues match the data length, as some keys could be missing - // the sorted value path. - $missingData = count($sortValues) < $dataCount; - if ($missingData && $numeric) { - // Get the path without the leading '{n}.' - $itemPath = substr($path, 4); - foreach ($data as $key => $value) { - $sortValues[$key] = static::get($value, $itemPath); - } - } elseif ($missingData) { - $sortValues = array_pad($sortValues, $dataCount, null); - } - $result = static::_squash($sortValues); - $keys = static::extract($result, '{n}.id'); - $values = static::extract($result, '{n}.value'); - - $dir = strtolower($dir); - $ignoreCase = false; - - // $type can be overloaded for case insensitive sort - if (is_array($type)) { - $type += ['ignoreCase' => false, 'type' => 'regular']; - $ignoreCase = $type['ignoreCase']; - $type = $type['type']; - } - $type = strtolower($type); - - if ($dir === 'asc') { - $dir = SORT_ASC; - } else { - $dir = SORT_DESC; - } - if ($type === 'numeric') { - $type = SORT_NUMERIC; - } elseif ($type === 'string') { - $type = SORT_STRING; - } elseif ($type === 'natural') { - $type = SORT_NATURAL; - } elseif ($type === 'locale') { - $type = SORT_LOCALE_STRING; - } else { - $type = SORT_REGULAR; - } - if ($ignoreCase) { - $values = array_map('mb_strtolower', $values); - } - array_multisort($values, $dir, $type, $keys, $dir, $type); - $sorted = []; - $keys = array_unique($keys); - - foreach ($keys as $k) { - if ($numeric) { - $sorted[] = $data[$k]; - continue; - } - if (isset($originalKeys[$k])) { - $sorted[$originalKeys[$k]] = $data[$originalKeys[$k]]; - } else { - $sorted[$k] = $data[$k]; - } - } - - return $sorted; - } - - /** - * Helper method for sort() - * Squashes an array to a single hash so it can be sorted. - * - * @param array $data The data to squash. - * @param string|null $key The key for the data. - * @return array - */ - protected static function _squash(array $data, $key = null) - { - $stack = []; - foreach ($data as $k => $r) { - $id = $k; - if ($key !== null) { - $id = $key; - } - if (is_array($r) && !empty($r)) { - $stack = array_merge($stack, static::_squash($r, $id)); - } else { - $stack[] = ['id' => $id, 'value' => $r]; - } - } - - return $stack; - } - - /** - * Computes the difference between two complex arrays. - * This method differs from the built-in array_diff() in that it will preserve keys - * and work on multi-dimensional arrays. - * - * @param array $data First value - * @param array $compare Second value - * @return array Returns the key => value pairs that are not common in $data and $compare - * The expression for this function is ($data - $compare) + ($compare - ($data - $compare)) - * @link https://book.cakephp.org/3.0/en/core-libraries/hash.html#Cake\Utility\Hash::diff - */ - public static function diff(array $data, array $compare) - { - if (empty($data)) { - return (array)$compare; - } - if (empty($compare)) { - return (array)$data; - } - $intersection = array_intersect_key($data, $compare); - while (($key = key($intersection)) !== null) { - if ($data[$key] == $compare[$key]) { - unset($data[$key], $compare[$key]); - } - next($intersection); - } - - return $data + $compare; - } - - /** - * Merges the difference between $data and $compare onto $data. - * - * @param array $data The data to append onto. - * @param array $compare The data to compare and append onto. - * @return array The merged array. - * @link https://book.cakephp.org/3.0/en/core-libraries/hash.html#Cake\Utility\Hash::mergeDiff - */ - public static function mergeDiff(array $data, array $compare) - { - if (empty($data) && !empty($compare)) { - return $compare; - } - if (empty($compare)) { - return $data; - } - foreach ($compare as $key => $value) { - if (!array_key_exists($key, $data)) { - $data[$key] = $value; - } elseif (is_array($value)) { - $data[$key] = static::mergeDiff($data[$key], $compare[$key]); - } - } - - return $data; - } - - /** - * Normalizes an array, and converts it to a standard format. - * - * @param array $data List to normalize - * @param bool $assoc If true, $data will be converted to an associative array. - * @return array - * @link https://book.cakephp.org/3.0/en/core-libraries/hash.html#Cake\Utility\Hash::normalize - */ - public static function normalize(array $data, $assoc = true) - { - $keys = array_keys($data); - $count = count($keys); - $numeric = true; - - if (!$assoc) { - for ($i = 0; $i < $count; $i++) { - if (!is_int($keys[$i])) { - $numeric = false; - break; - } - } - } - if (!$numeric || $assoc) { - $newList = []; - for ($i = 0; $i < $count; $i++) { - if (is_int($keys[$i])) { - $newList[$data[$keys[$i]]] = null; - } else { - $newList[$keys[$i]] = $data[$keys[$i]]; - } - } - $data = $newList; - } - - return $data; - } - - /** - * Takes in a flat array and returns a nested array - * - * ### Options: - * - * - `children` The key name to use in the resultset for children. - * - `idPath` The path to a key that identifies each entry. Should be - * compatible with Hash::extract(). Defaults to `{n}.$alias.id` - * - `parentPath` The path to a key that identifies the parent of each entry. - * Should be compatible with Hash::extract(). Defaults to `{n}.$alias.parent_id` - * - `root` The id of the desired top-most result. - * - * @param array $data The data to nest. - * @param array $options Options are: - * @return array of results, nested - * @see \Cake\Utility\Hash::extract() - * @throws \InvalidArgumentException When providing invalid data. - * @link https://book.cakephp.org/3.0/en/core-libraries/hash.html#Cake\Utility\Hash::nest - */ - public static function nest(array $data, array $options = []) - { - if (!$data) { - return $data; - } - - $alias = key(current($data)); - $options += [ - 'idPath' => "{n}.$alias.id", - 'parentPath' => "{n}.$alias.parent_id", - 'children' => 'children', - 'root' => null - ]; - - $return = $idMap = []; - $ids = static::extract($data, $options['idPath']); - - $idKeys = explode('.', $options['idPath']); - array_shift($idKeys); - - $parentKeys = explode('.', $options['parentPath']); - array_shift($parentKeys); - - foreach ($data as $result) { - $result[$options['children']] = []; - - $id = static::get($result, $idKeys); - $parentId = static::get($result, $parentKeys); - - if (isset($idMap[$id][$options['children']])) { - $idMap[$id] = array_merge($result, (array)$idMap[$id]); - } else { - $idMap[$id] = array_merge($result, [$options['children'] => []]); - } - if (!$parentId || !in_array($parentId, $ids)) { - $return[] =& $idMap[$id]; - } else { - $idMap[$parentId][$options['children']][] =& $idMap[$id]; - } - } - - if (!$return) { - throw new InvalidArgumentException('Invalid data array to nest.'); - } - - if ($options['root']) { - $root = $options['root']; - } else { - $root = static::get($return[0], $parentKeys); - } - - foreach ($return as $i => $result) { - $id = static::get($result, $idKeys); - $parentId = static::get($result, $parentKeys); - if ($id !== $root && $parentId != $root) { - unset($return[$i]); - } - } - - return array_values($return); - } -} diff --git a/vendor/cakephp/cakephp/src/Utility/Inflector.php b/vendor/cakephp/cakephp/src/Utility/Inflector.php deleted file mode 100644 index 4276ac3..0000000 --- a/vendor/cakephp/cakephp/src/Utility/Inflector.php +++ /dev/null @@ -1,773 +0,0 @@ - '\1tatuses', - '/(quiz)$/i' => '\1zes', - '/^(ox)$/i' => '\1\2en', - '/([m|l])ouse$/i' => '\1ice', - '/(matr|vert|ind)(ix|ex)$/i' => '\1ices', - '/(x|ch|ss|sh)$/i' => '\1es', - '/([^aeiouy]|qu)y$/i' => '\1ies', - '/(hive)$/i' => '\1s', - '/(chef)$/i' => '\1s', - '/(?:([^f])fe|([lre])f)$/i' => '\1\2ves', - '/sis$/i' => 'ses', - '/([ti])um$/i' => '\1a', - '/(p)erson$/i' => '\1eople', - '/(? '\1en', - '/(c)hild$/i' => '\1hildren', - '/(buffal|tomat)o$/i' => '\1\2oes', - '/(alumn|bacill|cact|foc|fung|nucle|radi|stimul|syllab|termin)us$/i' => '\1i', - '/us$/i' => 'uses', - '/(alias)$/i' => '\1es', - '/(ax|cris|test)is$/i' => '\1es', - '/s$/' => 's', - '/^$/' => '', - '/$/' => 's', - ]; - - /** - * Singular inflector rules - * - * @var array - */ - protected static $_singular = [ - '/(s)tatuses$/i' => '\1\2tatus', - '/^(.*)(menu)s$/i' => '\1\2', - '/(quiz)zes$/i' => '\\1', - '/(matr)ices$/i' => '\1ix', - '/(vert|ind)ices$/i' => '\1ex', - '/^(ox)en/i' => '\1', - '/(alias)(es)*$/i' => '\1', - '/(alumn|bacill|cact|foc|fung|nucle|radi|stimul|syllab|termin|viri?)i$/i' => '\1us', - '/([ftw]ax)es/i' => '\1', - '/(cris|ax|test)es$/i' => '\1is', - '/(shoe)s$/i' => '\1', - '/(o)es$/i' => '\1', - '/ouses$/' => 'ouse', - '/([^a])uses$/' => '\1us', - '/([m|l])ice$/i' => '\1ouse', - '/(x|ch|ss|sh)es$/i' => '\1', - '/(m)ovies$/i' => '\1\2ovie', - '/(s)eries$/i' => '\1\2eries', - '/([^aeiouy]|qu)ies$/i' => '\1y', - '/(tive)s$/i' => '\1', - '/(hive)s$/i' => '\1', - '/(drive)s$/i' => '\1', - '/([le])ves$/i' => '\1f', - '/([^rfoa])ves$/i' => '\1fe', - '/(^analy)ses$/i' => '\1sis', - '/(analy|diagno|^ba|(p)arenthe|(p)rogno|(s)ynop|(t)he)ses$/i' => '\1\2sis', - '/([ti])a$/i' => '\1um', - '/(p)eople$/i' => '\1\2erson', - '/(m)en$/i' => '\1an', - '/(c)hildren$/i' => '\1\2hild', - '/(n)ews$/i' => '\1\2ews', - '/eaus$/' => 'eau', - '/^(.*us)$/' => '\\1', - '/s$/i' => '' - ]; - - /** - * Irregular rules - * - * @var array - */ - protected static $_irregular = [ - 'atlas' => 'atlases', - 'beef' => 'beefs', - 'brief' => 'briefs', - 'brother' => 'brothers', - 'cafe' => 'cafes', - 'child' => 'children', - 'cookie' => 'cookies', - 'corpus' => 'corpuses', - 'cow' => 'cows', - 'criterion' => 'criteria', - 'ganglion' => 'ganglions', - 'genie' => 'genies', - 'genus' => 'genera', - 'graffito' => 'graffiti', - 'hoof' => 'hoofs', - 'loaf' => 'loaves', - 'man' => 'men', - 'money' => 'monies', - 'mongoose' => 'mongooses', - 'move' => 'moves', - 'mythos' => 'mythoi', - 'niche' => 'niches', - 'numen' => 'numina', - 'occiput' => 'occiputs', - 'octopus' => 'octopuses', - 'opus' => 'opuses', - 'ox' => 'oxen', - 'penis' => 'penises', - 'person' => 'people', - 'sex' => 'sexes', - 'soliloquy' => 'soliloquies', - 'testis' => 'testes', - 'trilby' => 'trilbys', - 'turf' => 'turfs', - 'potato' => 'potatoes', - 'hero' => 'heroes', - 'tooth' => 'teeth', - 'goose' => 'geese', - 'foot' => 'feet', - 'foe' => 'foes', - 'sieve' => 'sieves' - ]; - - /** - * Words that should not be inflected - * - * @var array - */ - protected static $_uninflected = [ - '.*[nrlm]ese', '.*data', '.*deer', '.*fish', '.*measles', '.*ois', - '.*pox', '.*sheep', 'people', 'feedback', 'stadia', '.*?media', - 'chassis', 'clippers', 'debris', 'diabetes', 'equipment', 'gallows', - 'graffiti', 'headquarters', 'information', 'innings', 'news', 'nexus', - 'pokemon', 'proceedings', 'research', 'sea[- ]bass', 'series', 'species', 'weather' - ]; - - /** - * Default map of accented and special characters to ASCII characters - * - * @var array - */ - protected static $_transliteration = [ - 'ä' => 'ae', - 'æ' => 'ae', - 'ǽ' => 'ae', - 'ö' => 'oe', - 'œ' => 'oe', - 'ü' => 'ue', - 'Ä' => 'Ae', - 'Ü' => 'Ue', - 'Ö' => 'Oe', - 'À' => 'A', - 'Á' => 'A', - 'Â' => 'A', - 'Ã' => 'A', - 'Å' => 'A', - 'Ǻ' => 'A', - 'Ā' => 'A', - 'Ă' => 'A', - 'Ą' => 'A', - 'Ǎ' => 'A', - 'à' => 'a', - 'á' => 'a', - 'â' => 'a', - 'ã' => 'a', - 'å' => 'a', - 'ǻ' => 'a', - 'ā' => 'a', - 'ă' => 'a', - 'ą' => 'a', - 'ǎ' => 'a', - 'ª' => 'a', - 'Ç' => 'C', - 'Ć' => 'C', - 'Ĉ' => 'C', - 'Ċ' => 'C', - 'Č' => 'C', - 'ç' => 'c', - 'ć' => 'c', - 'ĉ' => 'c', - 'ċ' => 'c', - 'č' => 'c', - 'Ð' => 'D', - 'Ď' => 'D', - 'Đ' => 'D', - 'ð' => 'd', - 'ď' => 'd', - 'đ' => 'd', - 'È' => 'E', - 'É' => 'E', - 'Ê' => 'E', - 'Ë' => 'E', - 'Ē' => 'E', - 'Ĕ' => 'E', - 'Ė' => 'E', - 'Ę' => 'E', - 'Ě' => 'E', - 'è' => 'e', - 'é' => 'e', - 'ê' => 'e', - 'ë' => 'e', - 'ē' => 'e', - 'ĕ' => 'e', - 'ė' => 'e', - 'ę' => 'e', - 'ě' => 'e', - 'Ĝ' => 'G', - 'Ğ' => 'G', - 'Ġ' => 'G', - 'Ģ' => 'G', - 'Ґ' => 'G', - 'ĝ' => 'g', - 'ğ' => 'g', - 'ġ' => 'g', - 'ģ' => 'g', - 'ґ' => 'g', - 'Ĥ' => 'H', - 'Ħ' => 'H', - 'ĥ' => 'h', - 'ħ' => 'h', - 'І' => 'I', - 'Ì' => 'I', - 'Í' => 'I', - 'Î' => 'I', - 'Ї' => 'Yi', - 'Ï' => 'I', - 'Ĩ' => 'I', - 'Ī' => 'I', - 'Ĭ' => 'I', - 'Ǐ' => 'I', - 'Į' => 'I', - 'İ' => 'I', - 'і' => 'i', - 'ì' => 'i', - 'í' => 'i', - 'î' => 'i', - 'ï' => 'i', - 'ї' => 'yi', - 'ĩ' => 'i', - 'ī' => 'i', - 'ĭ' => 'i', - 'ǐ' => 'i', - 'į' => 'i', - 'ı' => 'i', - 'Ĵ' => 'J', - 'ĵ' => 'j', - 'Ķ' => 'K', - 'ķ' => 'k', - 'Ĺ' => 'L', - 'Ļ' => 'L', - 'Ľ' => 'L', - 'Ŀ' => 'L', - 'Ł' => 'L', - 'ĺ' => 'l', - 'ļ' => 'l', - 'ľ' => 'l', - 'ŀ' => 'l', - 'ł' => 'l', - 'Ñ' => 'N', - 'Ń' => 'N', - 'Ņ' => 'N', - 'Ň' => 'N', - 'ñ' => 'n', - 'ń' => 'n', - 'ņ' => 'n', - 'ň' => 'n', - 'ʼn' => 'n', - 'Ò' => 'O', - 'Ó' => 'O', - 'Ô' => 'O', - 'Õ' => 'O', - 'Ō' => 'O', - 'Ŏ' => 'O', - 'Ǒ' => 'O', - 'Ő' => 'O', - 'Ơ' => 'O', - 'Ø' => 'O', - 'Ǿ' => 'O', - 'ò' => 'o', - 'ó' => 'o', - 'ô' => 'o', - 'õ' => 'o', - 'ō' => 'o', - 'ŏ' => 'o', - 'ǒ' => 'o', - 'ő' => 'o', - 'ơ' => 'o', - 'ø' => 'o', - 'ǿ' => 'o', - 'º' => 'o', - 'Ŕ' => 'R', - 'Ŗ' => 'R', - 'Ř' => 'R', - 'ŕ' => 'r', - 'ŗ' => 'r', - 'ř' => 'r', - 'Ś' => 'S', - 'Ŝ' => 'S', - 'Ş' => 'S', - 'Ș' => 'S', - 'Š' => 'S', - 'ẞ' => 'SS', - 'ś' => 's', - 'ŝ' => 's', - 'ş' => 's', - 'ș' => 's', - 'š' => 's', - 'ſ' => 's', - 'Ţ' => 'T', - 'Ț' => 'T', - 'Ť' => 'T', - 'Ŧ' => 'T', - 'ţ' => 't', - 'ț' => 't', - 'ť' => 't', - 'ŧ' => 't', - 'Ù' => 'U', - 'Ú' => 'U', - 'Û' => 'U', - 'Ũ' => 'U', - 'Ū' => 'U', - 'Ŭ' => 'U', - 'Ů' => 'U', - 'Ű' => 'U', - 'Ų' => 'U', - 'Ư' => 'U', - 'Ǔ' => 'U', - 'Ǖ' => 'U', - 'Ǘ' => 'U', - 'Ǚ' => 'U', - 'Ǜ' => 'U', - 'ù' => 'u', - 'ú' => 'u', - 'û' => 'u', - 'ũ' => 'u', - 'ū' => 'u', - 'ŭ' => 'u', - 'ů' => 'u', - 'ű' => 'u', - 'ų' => 'u', - 'ư' => 'u', - 'ǔ' => 'u', - 'ǖ' => 'u', - 'ǘ' => 'u', - 'ǚ' => 'u', - 'ǜ' => 'u', - 'Ý' => 'Y', - 'Ÿ' => 'Y', - 'Ŷ' => 'Y', - 'ý' => 'y', - 'ÿ' => 'y', - 'ŷ' => 'y', - 'Ŵ' => 'W', - 'ŵ' => 'w', - 'Ź' => 'Z', - 'Ż' => 'Z', - 'Ž' => 'Z', - 'ź' => 'z', - 'ż' => 'z', - 'ž' => 'z', - 'Æ' => 'AE', - 'Ǽ' => 'AE', - 'ß' => 'ss', - 'IJ' => 'IJ', - 'ij' => 'ij', - 'Œ' => 'OE', - 'ƒ' => 'f', - 'Þ' => 'TH', - 'þ' => 'th', - 'Є' => 'Ye', - 'є' => 'ye', - ]; - - /** - * Method cache array. - * - * @var array - */ - protected static $_cache = []; - - /** - * The initial state of Inflector so reset() works. - * - * @var array - */ - protected static $_initialState = []; - - /** - * Cache inflected values, and return if already available - * - * @param string $type Inflection type - * @param string $key Original value - * @param string|bool $value Inflected value - * @return string|false Inflected value on cache hit or false on cache miss. - */ - protected static function _cache($type, $key, $value = false) - { - $key = '_' . $key; - $type = '_' . $type; - if ($value !== false) { - static::$_cache[$type][$key] = $value; - - return $value; - } - if (!isset(static::$_cache[$type][$key])) { - return false; - } - - return static::$_cache[$type][$key]; - } - - /** - * Clears Inflectors inflected value caches. And resets the inflection - * rules to the initial values. - * - * @return void - */ - public static function reset() - { - if (empty(static::$_initialState)) { - static::$_initialState = get_class_vars(__CLASS__); - - return; - } - foreach (static::$_initialState as $key => $val) { - if ($key !== '_initialState') { - static::${$key} = $val; - } - } - } - - /** - * Adds custom inflection $rules, of either 'plural', 'singular', - * 'uninflected', 'irregular' or 'transliteration' $type. - * - * ### Usage: - * - * ``` - * Inflector::rules('plural', ['/^(inflect)or$/i' => '\1ables']); - * Inflector::rules('irregular', ['red' => 'redlings']); - * Inflector::rules('uninflected', ['dontinflectme']); - * Inflector::rules('transliteration', ['/å/' => 'aa']); - * ``` - * - * @param string $type The type of inflection, either 'plural', 'singular', - * 'uninflected' or 'transliteration'. - * @param array $rules Array of rules to be added. - * @param bool $reset If true, will unset default inflections for all - * new rules that are being defined in $rules. - * @return void - */ - public static function rules($type, $rules, $reset = false) - { - $var = '_' . $type; - - if ($reset) { - static::${$var} = $rules; - } elseif ($type === 'uninflected') { - static::$_uninflected = array_merge( - $rules, - static::$_uninflected - ); - } else { - static::${$var} = $rules + static::${$var}; - } - - static::$_cache = []; - } - - /** - * Return $word in plural form. - * - * @param string $word Word in singular - * @return string Word in plural - * @link https://book.cakephp.org/3.0/en/core-libraries/inflector.html#creating-plural-singular-forms - */ - public static function pluralize($word) - { - if (isset(static::$_cache['pluralize'][$word])) { - return static::$_cache['pluralize'][$word]; - } - - if (!isset(static::$_cache['irregular']['pluralize'])) { - static::$_cache['irregular']['pluralize'] = '(?:' . implode('|', array_keys(static::$_irregular)) . ')'; - } - - if (preg_match('/(.*?(?:\\b|_))(' . static::$_cache['irregular']['pluralize'] . ')$/i', $word, $regs)) { - static::$_cache['pluralize'][$word] = $regs[1] . substr($regs[2], 0, 1) . - substr(static::$_irregular[strtolower($regs[2])], 1); - - return static::$_cache['pluralize'][$word]; - } - - if (!isset(static::$_cache['uninflected'])) { - static::$_cache['uninflected'] = '(?:' . implode('|', static::$_uninflected) . ')'; - } - - if (preg_match('/^(' . static::$_cache['uninflected'] . ')$/i', $word, $regs)) { - static::$_cache['pluralize'][$word] = $word; - - return $word; - } - - foreach (static::$_plural as $rule => $replacement) { - if (preg_match($rule, $word)) { - static::$_cache['pluralize'][$word] = preg_replace($rule, $replacement, $word); - - return static::$_cache['pluralize'][$word]; - } - } - } - - /** - * Return $word in singular form. - * - * @param string $word Word in plural - * @return string Word in singular - * @link https://book.cakephp.org/3.0/en/core-libraries/inflector.html#creating-plural-singular-forms - */ - public static function singularize($word) - { - if (isset(static::$_cache['singularize'][$word])) { - return static::$_cache['singularize'][$word]; - } - - if (!isset(static::$_cache['irregular']['singular'])) { - static::$_cache['irregular']['singular'] = '(?:' . implode('|', static::$_irregular) . ')'; - } - - if (preg_match('/(.*?(?:\\b|_))(' . static::$_cache['irregular']['singular'] . ')$/i', $word, $regs)) { - static::$_cache['singularize'][$word] = $regs[1] . substr($regs[2], 0, 1) . - substr(array_search(strtolower($regs[2]), static::$_irregular), 1); - - return static::$_cache['singularize'][$word]; - } - - if (!isset(static::$_cache['uninflected'])) { - static::$_cache['uninflected'] = '(?:' . implode('|', static::$_uninflected) . ')'; - } - - if (preg_match('/^(' . static::$_cache['uninflected'] . ')$/i', $word, $regs)) { - static::$_cache['pluralize'][$word] = $word; - - return $word; - } - - foreach (static::$_singular as $rule => $replacement) { - if (preg_match($rule, $word)) { - static::$_cache['singularize'][$word] = preg_replace($rule, $replacement, $word); - - return static::$_cache['singularize'][$word]; - } - } - static::$_cache['singularize'][$word] = $word; - - return $word; - } - - /** - * Returns the input lower_case_delimited_string as a CamelCasedString. - * - * @param string $string String to camelize - * @param string $delimiter the delimiter in the input string - * @return string CamelizedStringLikeThis. - * @link https://book.cakephp.org/3.0/en/core-libraries/inflector.html#creating-camelcase-and-under-scored-forms - */ - public static function camelize($string, $delimiter = '_') - { - $cacheKey = __FUNCTION__ . $delimiter; - - $result = static::_cache($cacheKey, $string); - - if ($result === false) { - $result = str_replace(' ', '', static::humanize($string, $delimiter)); - static::_cache($cacheKey, $string, $result); - } - - return $result; - } - - /** - * Returns the input CamelCasedString as an underscored_string. - * - * Also replaces dashes with underscores - * - * @param string $string CamelCasedString to be "underscorized" - * @return string underscore_version of the input string - * @link https://book.cakephp.org/3.0/en/core-libraries/inflector.html#creating-camelcase-and-under-scored-forms - */ - public static function underscore($string) - { - return static::delimit(str_replace('-', '_', $string), '_'); - } - - /** - * Returns the input CamelCasedString as an dashed-string. - * - * Also replaces underscores with dashes - * - * @param string $string The string to dasherize. - * @return string Dashed version of the input string - */ - public static function dasherize($string) - { - return static::delimit(str_replace('_', '-', $string), '-'); - } - - /** - * Returns the input lower_case_delimited_string as 'A Human Readable String'. - * (Underscores are replaced by spaces and capitalized following words.) - * - * @param string $string String to be humanized - * @param string $delimiter the character to replace with a space - * @return string Human-readable string - * @link https://book.cakephp.org/3.0/en/core-libraries/inflector.html#creating-human-readable-forms - */ - public static function humanize($string, $delimiter = '_') - { - $cacheKey = __FUNCTION__ . $delimiter; - - $result = static::_cache($cacheKey, $string); - - if ($result === false) { - $result = explode(' ', str_replace($delimiter, ' ', $string)); - foreach ($result as &$word) { - $word = mb_strtoupper(mb_substr($word, 0, 1)) . mb_substr($word, 1); - } - $result = implode(' ', $result); - static::_cache($cacheKey, $string, $result); - } - - return $result; - } - - /** - * Expects a CamelCasedInputString, and produces a lower_case_delimited_string - * - * @param string $string String to delimit - * @param string $delimiter the character to use as a delimiter - * @return string delimited string - */ - public static function delimit($string, $delimiter = '_') - { - $cacheKey = __FUNCTION__ . $delimiter; - - $result = static::_cache($cacheKey, $string); - - if ($result === false) { - $result = mb_strtolower(preg_replace('/(?<=\\w)([A-Z])/', $delimiter . '\\1', $string)); - static::_cache($cacheKey, $string, $result); - } - - return $result; - } - - /** - * Returns corresponding table name for given model $className. ("people" for the model class "Person"). - * - * @param string $className Name of class to get database table name for - * @return string Name of the database table for given class - * @link https://book.cakephp.org/3.0/en/core-libraries/inflector.html#creating-table-and-class-name-forms - */ - public static function tableize($className) - { - $result = static::_cache(__FUNCTION__, $className); - - if ($result === false) { - $result = static::pluralize(static::underscore($className)); - static::_cache(__FUNCTION__, $className, $result); - } - - return $result; - } - - /** - * Returns Cake model class name ("Person" for the database table "people".) for given database table. - * - * @param string $tableName Name of database table to get class name for - * @return string Class name - * @link https://book.cakephp.org/3.0/en/core-libraries/inflector.html#creating-table-and-class-name-forms - */ - public static function classify($tableName) - { - $result = static::_cache(__FUNCTION__, $tableName); - - if ($result === false) { - $result = static::camelize(static::singularize($tableName)); - static::_cache(__FUNCTION__, $tableName, $result); - } - - return $result; - } - - /** - * Returns camelBacked version of an underscored string. - * - * @param string $string String to convert. - * @return string in variable form - * @link https://book.cakephp.org/3.0/en/core-libraries/inflector.html#creating-variable-names - */ - public static function variable($string) - { - $result = static::_cache(__FUNCTION__, $string); - - if ($result === false) { - $camelized = static::camelize(static::underscore($string)); - $replace = strtolower(substr($camelized, 0, 1)); - $result = $replace . substr($camelized, 1); - static::_cache(__FUNCTION__, $string, $result); - } - - return $result; - } - - /** - * Returns a string with all spaces converted to dashes (by default), accented - * characters converted to non-accented characters, and non word characters removed. - * - * @deprecated 3.2.7 Use Text::slug() instead. - * @param string $string the string you want to slug - * @param string $replacement will replace keys in map - * @return string - * @link https://book.cakephp.org/3.0/en/core-libraries/inflector.html#creating-url-safe-strings - */ - public static function slug($string, $replacement = '-') - { - deprecationWarning( - 'Inflector::slug() is deprecated. ' . - 'Use Text::slug() instead.' - ); - $quotedReplacement = preg_quote($replacement, '/'); - - $map = [ - '/[^\s\p{Zs}\p{Ll}\p{Lm}\p{Lo}\p{Lt}\p{Lu}\p{Nd}]/mu' => ' ', - '/[\s\p{Zs}]+/mu' => $replacement, - sprintf('/^[%s]+|[%s]+$/', $quotedReplacement, $quotedReplacement) => '', - ]; - - $string = str_replace( - array_keys(static::$_transliteration), - array_values(static::$_transliteration), - $string - ); - - return preg_replace(array_keys($map), array_values($map), $string); - } -} diff --git a/vendor/cakephp/cakephp/src/Utility/LICENSE.txt b/vendor/cakephp/cakephp/src/Utility/LICENSE.txt deleted file mode 100644 index 0c4b793..0000000 --- a/vendor/cakephp/cakephp/src/Utility/LICENSE.txt +++ /dev/null @@ -1,22 +0,0 @@ -The MIT License (MIT) - -CakePHP(tm) : The Rapid Development PHP Framework (https://cakephp.org) -Copyright (c) 2005-2016, Cake Software Foundation, Inc. (https://cakefoundation.org) - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. diff --git a/vendor/cakephp/cakephp/src/Utility/MergeVariablesTrait.php b/vendor/cakephp/cakephp/src/Utility/MergeVariablesTrait.php deleted file mode 100644 index 6f67651..0000000 --- a/vendor/cakephp/cakephp/src/Utility/MergeVariablesTrait.php +++ /dev/null @@ -1,116 +0,0 @@ -{$property}; - if ($thisValue === null || $thisValue === false) { - continue; - } - $this->_mergeProperty($property, $parents, $options); - } - } - - /** - * Merge a single property with the values declared in all parent classes. - * - * @param string $property The name of the property being merged. - * @param array $parentClasses An array of classes you want to merge with. - * @param array $options Options for merging the property, see _mergeVars() - * @return void - */ - protected function _mergeProperty($property, $parentClasses, $options) - { - $thisValue = $this->{$property}; - $isAssoc = false; - if (isset($options['associative']) && - in_array($property, (array)$options['associative']) - ) { - $isAssoc = true; - } - - if ($isAssoc) { - $thisValue = Hash::normalize($thisValue); - } - foreach ($parentClasses as $class) { - $parentProperties = get_class_vars($class); - if (empty($parentProperties[$property])) { - continue; - } - $parentProperty = $parentProperties[$property]; - if (!is_array($parentProperty)) { - continue; - } - $thisValue = $this->_mergePropertyData($thisValue, $parentProperty, $isAssoc); - } - $this->{$property} = $thisValue; - } - - /** - * Merge each of the keys in a property together. - * - * @param array $current The current merged value. - * @param array $parent The parent class' value. - * @param bool $isAssoc Whether or not the merging should be done in associative mode. - * @return mixed The updated value. - */ - protected function _mergePropertyData($current, $parent, $isAssoc) - { - if (!$isAssoc) { - return array_merge($parent, $current); - } - $parent = Hash::normalize($parent); - foreach ($parent as $key => $value) { - if (!isset($current[$key])) { - $current[$key] = $value; - } - } - - return $current; - } -} diff --git a/vendor/cakephp/cakephp/src/Utility/README.md b/vendor/cakephp/cakephp/src/Utility/README.md deleted file mode 100644 index 3183e00..0000000 --- a/vendor/cakephp/cakephp/src/Utility/README.md +++ /dev/null @@ -1,91 +0,0 @@ -[![Total Downloads](https://img.shields.io/packagist/dt/cakephp/utility.svg?style=flat-square)](https://packagist.org/packages/cakephp/utility) -[![License](https://img.shields.io/badge/license-MIT-blue.svg?style=flat-square)](LICENSE.txt) - -# CakePHP Utility Classes - -This library provides a range of utility classes that are used throughout the CakePHP framework - -## What's in the toolbox? - -### Hash - -A ``Hash`` (as in PHP arrays) class, capable of extracting data using an intuitive DSL: - -```php -$things = [ - ['name' => 'Mark', 'age' => 15], - ['name' => 'Susan', 'age' => 30], - ['name' => 'Lucy', 'age' => 25] -]; - -$bigPeople = Hash::extract($things, '{n}[age>21].name'); - -// $bigPeople will contain ['Susan', 'Lucy'] -``` - -Check the [official Hash class documentation](https://book.cakephp.org/3.0/en/core-libraries/hash.html) - -### Inflector - -The Inflector class takes a string and can manipulate it to handle word variations -such as pluralizations or camelizing. - -```php -echo Inflector::pluralize('Apple'); // echoes Apples - -echo Inflector::singularize('People'); // echoes Person -``` - -Check the [official Inflector class documentation](https://book.cakephp.org/3.0/en/core-libraries/inflector.html) - -### Text - -The Text class includes convenience methods for creating and manipulating strings. - -```php -Text::insert( - 'My name is :name and I am :age years old.', - ['name' => 'Bob', 'age' => '65'] -); -// Returns: "My name is Bob and I am 65 years old." - -$text = 'This is the song that never ends.'; -$result = Text::wrap($text, 22); - -// Returns -This is the song -that never ends. -``` - -Check the [official Text class documentation](https://book.cakephp.org/3.0/en/core-libraries/text.html) - -### Security - -The security library handles basic security measures such as providing methods for hashing and encrypting data. - -```php -$key = 'wt1U5MACWJFTXGenFoZoiLwQGrLgdbHA'; -$result = Security::encrypt($value, $key); - -Security::decrypt($result, $key); -``` - -Check the [official Security class documentation](https://book.cakephp.org/3.0/en/core-libraries/security.html) - -### Xml - -The Xml class allows you to easily transform arrays into SimpleXMLElement or DOMDocument objects -and back into arrays again - -```php -$data = [ - 'post' => [ - 'id' => 1, - 'title' => 'Best post', - 'body' => ' ... ' - ] -]; -$xml = Xml::build($data); -``` - -Check the [official Xml class documentation](https://book.cakephp.org/3.0/en/core-libraries/xml.html) diff --git a/vendor/cakephp/cakephp/src/Utility/Security.php b/vendor/cakephp/cakephp/src/Utility/Security.php deleted file mode 100644 index 3e14add..0000000 --- a/vendor/cakephp/cakephp/src/Utility/Security.php +++ /dev/null @@ -1,386 +0,0 @@ -rijndael($text, $key, $operation); - } - - /** - * Encrypt a value using AES-256. - * - * *Caveat* You cannot properly encrypt/decrypt data with trailing null bytes. - * Any trailing null bytes will be removed on decryption due to how PHP pads messages - * with nulls prior to encryption. - * - * @param string $plain The value to encrypt. - * @param string $key The 256 bit/32 byte key to use as a cipher key. - * @param string|null $hmacSalt The salt to use for the HMAC process. Leave null to use Security.salt. - * @return string Encrypted data. - * @throws \InvalidArgumentException On invalid data or key. - */ - public static function encrypt($plain, $key, $hmacSalt = null) - { - self::_checkKey($key, 'encrypt()'); - - if ($hmacSalt === null) { - $hmacSalt = static::$_salt; - } - // Generate the encryption and hmac key. - $key = mb_substr(hash('sha256', $key . $hmacSalt), 0, 32, '8bit'); - - $crypto = static::engine(); - $ciphertext = $crypto->encrypt($plain, $key); - $hmac = hash_hmac('sha256', $ciphertext, $key); - - return $hmac . $ciphertext; - } - - /** - * Check the encryption key for proper length. - * - * @param string $key Key to check. - * @param string $method The method the key is being checked for. - * @return void - * @throws \InvalidArgumentException When key length is not 256 bit/32 bytes - */ - protected static function _checkKey($key, $method) - { - if (mb_strlen($key, '8bit') < 32) { - throw new InvalidArgumentException( - sprintf('Invalid key for %s, key must be at least 256 bits (32 bytes) long.', $method) - ); - } - } - - /** - * Decrypt a value using AES-256. - * - * @param string $cipher The ciphertext to decrypt. - * @param string $key The 256 bit/32 byte key to use as a cipher key. - * @param string|null $hmacSalt The salt to use for the HMAC process. Leave null to use Security.salt. - * @return string|bool Decrypted data. Any trailing null bytes will be removed. - * @throws \InvalidArgumentException On invalid data or key. - */ - public static function decrypt($cipher, $key, $hmacSalt = null) - { - self::_checkKey($key, 'decrypt()'); - if (empty($cipher)) { - throw new InvalidArgumentException('The data to decrypt cannot be empty.'); - } - if ($hmacSalt === null) { - $hmacSalt = static::$_salt; - } - - // Generate the encryption and hmac key. - $key = mb_substr(hash('sha256', $key . $hmacSalt), 0, 32, '8bit'); - - // Split out hmac for comparison - $macSize = 64; - $hmac = mb_substr($cipher, 0, $macSize, '8bit'); - $cipher = mb_substr($cipher, $macSize, null, '8bit'); - - $compareHmac = hash_hmac('sha256', $cipher, $key); - if (!static::constantEquals($hmac, $compareHmac)) { - return false; - } - - $crypto = static::engine(); - - return $crypto->decrypt($cipher, $key); - } - - /** - * A timing attack resistant comparison that prefers native PHP implementations. - * - * @param string $original The original value. - * @param string $compare The comparison value. - * @return bool - * @see https://github.com/resonantcore/php-future/ - * @since 3.6.2 - */ - public static function constantEquals($original, $compare) - { - if (!is_string($original) || !is_string($compare)) { - return false; - } - if (function_exists('hash_equals')) { - return hash_equals($original, $compare); - } - $originalLength = mb_strlen($original, '8bit'); - $compareLength = mb_strlen($compare, '8bit'); - if ($originalLength !== $compareLength) { - return false; - } - $result = 0; - for ($i = 0; $i < $originalLength; $i++) { - $result |= (ord($original[$i]) ^ ord($compare[$i])); - } - - return $result === 0; - } - - /** - * Gets the HMAC salt to be used for encryption/decryption - * routines. - * - * @return string The currently configured salt - */ - public static function getSalt() - { - return static::$_salt; - } - - /** - * Sets the HMAC salt to be used for encryption/decryption - * routines. - * - * @param string $salt The salt to use for encryption routines. - * @return void - */ - public static function setSalt($salt) - { - static::$_salt = (string)$salt; - } - - /** - * Gets or sets the HMAC salt to be used for encryption/decryption - * routines. - * - * @deprecated 3.5.0 Use getSalt()/setSalt() instead. - * @param string|null $salt The salt to use for encryption routines. If null returns current salt. - * @return string The currently configured salt - */ - public static function salt($salt = null) - { - deprecationWarning( - 'Security::salt() is deprecated. ' . - 'Use Security::getSalt()/setSalt() instead.' - ); - if ($salt === null) { - return static::$_salt; - } - - return static::$_salt = (string)$salt; - } -} diff --git a/vendor/cakephp/cakephp/src/Utility/String.php b/vendor/cakephp/cakephp/src/Utility/String.php deleted file mode 100644 index e30ba9c..0000000 --- a/vendor/cakephp/cakephp/src/Utility/String.php +++ /dev/null @@ -1,6 +0,0 @@ - 'Bob', 'age' => '65']); - * ``` - * Returns: Bob is 65 years old. - * - * Available $options are: - * - * - before: The character or string in front of the name of the variable placeholder (Defaults to `:`) - * - after: The character or string after the name of the variable placeholder (Defaults to null) - * - escape: The character or string used to escape the before character / string (Defaults to `\`) - * - format: A regex to use for matching variable placeholders. Default is: `/(? val array where each key stands for a placeholder variable name - * to be replaced with val - * @param array $options An array of options, see description above - * @return string - */ - public static function insert($str, $data, array $options = []) - { - $defaults = [ - 'before' => ':', 'after' => null, 'escape' => '\\', 'format' => null, 'clean' => false - ]; - $options += $defaults; - $format = $options['format']; - $data = (array)$data; - if (empty($data)) { - return $options['clean'] ? static::cleanInsert($str, $options) : $str; - } - - if (!isset($format)) { - $format = sprintf( - '/(? $hashVal) { - $key = sprintf($format, preg_quote($key, '/')); - $str = preg_replace($key, $hashVal, $str); - } - $dataReplacements = array_combine($hashKeys, array_values($data)); - foreach ($dataReplacements as $tmpHash => $tmpValue) { - $tmpValue = is_array($tmpValue) ? '' : $tmpValue; - $str = str_replace($tmpHash, $tmpValue, $str); - } - - if (!isset($options['format']) && isset($options['before'])) { - $str = str_replace($options['escape'] . $options['before'], $options['before'], $str); - } - - return $options['clean'] ? static::cleanInsert($str, $options) : $str; - } - - /** - * Cleans up a Text::insert() formatted string with given $options depending on the 'clean' key in - * $options. The default method used is text but html is also available. The goal of this function - * is to replace all whitespace and unneeded markup around placeholders that did not get replaced - * by Text::insert(). - * - * @param string $str String to clean. - * @param array $options Options list. - * @return string - * @see \Cake\Utility\Text::insert() - */ - public static function cleanInsert($str, array $options) - { - $clean = $options['clean']; - if (!$clean) { - return $str; - } - if ($clean === true) { - $clean = ['method' => 'text']; - } - if (!is_array($clean)) { - $clean = ['method' => $options['clean']]; - } - switch ($clean['method']) { - case 'html': - $clean += [ - 'word' => '[\w,.]+', - 'andText' => true, - 'replacement' => '', - ]; - $kleenex = sprintf( - '/[\s]*[a-z]+=(")(%s%s%s[\s]*)+\\1/i', - preg_quote($options['before'], '/'), - $clean['word'], - preg_quote($options['after'], '/') - ); - $str = preg_replace($kleenex, $clean['replacement'], $str); - if ($clean['andText']) { - $options['clean'] = ['method' => 'text']; - $str = static::cleanInsert($str, $options); - } - break; - case 'text': - $clean += [ - 'word' => '[\w,.]+', - 'gap' => '[\s]*(?:(?:and|or)[\s]*)?', - 'replacement' => '', - ]; - - $kleenex = sprintf( - '/(%s%s%s%s|%s%s%s%s)/', - preg_quote($options['before'], '/'), - $clean['word'], - preg_quote($options['after'], '/'), - $clean['gap'], - $clean['gap'], - preg_quote($options['before'], '/'), - $clean['word'], - preg_quote($options['after'], '/') - ); - $str = preg_replace($kleenex, $clean['replacement'], $str); - break; - } - - return $str; - } - - /** - * Wraps text to a specific width, can optionally wrap at word breaks. - * - * ### Options - * - * - `width` The width to wrap to. Defaults to 72. - * - `wordWrap` Only wrap on words breaks (spaces) Defaults to true. - * - `indent` String to indent with. Defaults to null. - * - `indentAt` 0 based index to start indenting at. Defaults to 0. - * - * @param string $text The text to format. - * @param array|int $options Array of options to use, or an integer to wrap the text to. - * @return string Formatted text. - */ - public static function wrap($text, $options = []) - { - if (is_numeric($options)) { - $options = ['width' => $options]; - } - $options += ['width' => 72, 'wordWrap' => true, 'indent' => null, 'indentAt' => 0]; - if ($options['wordWrap']) { - $wrapped = self::wordWrap($text, $options['width'], "\n"); - } else { - $wrapped = trim(chunk_split($text, $options['width'] - 1, "\n")); - } - if (!empty($options['indent'])) { - $chunks = explode("\n", $wrapped); - for ($i = $options['indentAt'], $len = count($chunks); $i < $len; $i++) { - $chunks[$i] = $options['indent'] . $chunks[$i]; - } - $wrapped = implode("\n", $chunks); - } - - return $wrapped; - } - - /** - * Wraps a complete block of text to a specific width, can optionally wrap - * at word breaks. - * - * ### Options - * - * - `width` The width to wrap to. Defaults to 72. - * - `wordWrap` Only wrap on words breaks (spaces) Defaults to true. - * - `indent` String to indent with. Defaults to null. - * - `indentAt` 0 based index to start indenting at. Defaults to 0. - * - * @param string $text The text to format. - * @param array|int $options Array of options to use, or an integer to wrap the text to. - * @return string Formatted text. - */ - public static function wrapBlock($text, $options = []) - { - if (is_numeric($options)) { - $options = ['width' => $options]; - } - $options += ['width' => 72, 'wordWrap' => true, 'indent' => null, 'indentAt' => 0]; - - if (!empty($options['indentAt']) && $options['indentAt'] === 0) { - $indentLength = !empty($options['indent']) ? strlen($options['indent']) : 0; - $options['width'] -= $indentLength; - - return self::wrap($text, $options); - } - - $wrapped = self::wrap($text, $options); - - if (!empty($options['indent'])) { - $indentationLength = mb_strlen($options['indent']); - $chunks = explode("\n", $wrapped); - $count = count($chunks); - if ($count < 2) { - return $wrapped; - } - $toRewrap = ''; - for ($i = $options['indentAt']; $i < $count; $i++) { - $toRewrap .= mb_substr($chunks[$i], $indentationLength) . ' '; - unset($chunks[$i]); - } - $options['width'] -= $indentationLength; - $options['indentAt'] = 0; - $rewrapped = self::wrap($toRewrap, $options); - $newChunks = explode("\n", $rewrapped); - - $chunks = array_merge($chunks, $newChunks); - $wrapped = implode("\n", $chunks); - } - - return $wrapped; - } - - /** - * Unicode and newline aware version of wordwrap. - * - * @param string $text The text to format. - * @param int $width The width to wrap to. Defaults to 72. - * @param string $break The line is broken using the optional break parameter. Defaults to '\n'. - * @param bool $cut If the cut is set to true, the string is always wrapped at the specified width. - * @return string Formatted text. - */ - public static function wordWrap($text, $width = 72, $break = "\n", $cut = false) - { - $paragraphs = explode($break, $text); - foreach ($paragraphs as &$paragraph) { - $paragraph = static::_wordWrap($paragraph, $width, $break, $cut); - } - - return implode($break, $paragraphs); - } - - /** - * Unicode aware version of wordwrap as helper method. - * - * @param string $text The text to format. - * @param int $width The width to wrap to. Defaults to 72. - * @param string $break The line is broken using the optional break parameter. Defaults to '\n'. - * @param bool $cut If the cut is set to true, the string is always wrapped at the specified width. - * @return string Formatted text. - */ - protected static function _wordWrap($text, $width = 72, $break = "\n", $cut = false) - { - if ($cut) { - $parts = []; - while (mb_strlen($text) > 0) { - $part = mb_substr($text, 0, $width); - $parts[] = trim($part); - $text = trim(mb_substr($text, mb_strlen($part))); - } - - return implode($break, $parts); - } - - $parts = []; - while (mb_strlen($text) > 0) { - if ($width >= mb_strlen($text)) { - $parts[] = trim($text); - break; - } - - $part = mb_substr($text, 0, $width); - $nextChar = mb_substr($text, $width, 1); - if ($nextChar !== ' ') { - $breakAt = mb_strrpos($part, ' '); - if ($breakAt === false) { - $breakAt = mb_strpos($text, ' ', $width); - } - if ($breakAt === false) { - $parts[] = trim($text); - break; - } - $part = mb_substr($text, 0, $breakAt); - } - - $part = trim($part); - $parts[] = $part; - $text = trim(mb_substr($text, mb_strlen($part))); - } - - return implode($break, $parts); - } - - /** - * Highlights a given phrase in a text. You can specify any expression in highlighter that - * may include the \1 expression to include the $phrase found. - * - * ### Options: - * - * - `format` The piece of HTML with that the phrase will be highlighted - * - `html` If true, will ignore any HTML tags, ensuring that only the correct text is highlighted - * - `regex` A custom regex rule that is used to match words, default is '|$tag|iu' - * - `limit` A limit, optional, defaults to -1 (none) - * - * @param string $text Text to search the phrase in. - * @param string|array $phrase The phrase or phrases that will be searched. - * @param array $options An array of HTML attributes and options. - * @return string The highlighted text - * @link https://book.cakephp.org/3.0/en/core-libraries/text.html#highlighting-substrings - */ - public static function highlight($text, $phrase, array $options = []) - { - if (empty($phrase)) { - return $text; - } - - $defaults = [ - 'format' => '\1', - 'html' => false, - 'regex' => '|%s|iu', - 'limit' => -1, - ]; - $options += $defaults; - $html = $format = $ellipsis = $exact = $limit = null; - extract($options); - - if (is_array($phrase)) { - $replace = []; - $with = []; - - foreach ($phrase as $key => $segment) { - $segment = '(' . preg_quote($segment, '|') . ')'; - if ($html) { - $segment = "(?![^<]+>)$segment(?![^<]+>)"; - } - - $with[] = is_array($format) ? $format[$key] : $format; - $replace[] = sprintf($options['regex'], $segment); - } - - return preg_replace($replace, $with, $text, $limit); - } - - $phrase = '(' . preg_quote($phrase, '|') . ')'; - if ($html) { - $phrase = "(?![^<]+>)$phrase(?![^<]+>)"; - } - - return preg_replace(sprintf($options['regex'], $phrase), $format, $text, $limit); - } - - /** - * Strips given text of all links (]*)?(>|$)#i', '', $text, -1, $count); - } while ($count); - - return $text; - } - - /** - * Truncates text starting from the end. - * - * Cuts a string to the length of $length and replaces the first characters - * with the ellipsis if the text is longer than length. - * - * ### Options: - * - * - `ellipsis` Will be used as Beginning and prepended to the trimmed string - * - `exact` If false, $text will not be cut mid-word - * - * @param string $text String to truncate. - * @param int $length Length of returned string, including ellipsis. - * @param array $options An array of options. - * @return string Trimmed string. - */ - public static function tail($text, $length = 100, array $options = []) - { - $default = [ - 'ellipsis' => '...', 'exact' => true - ]; - $options += $default; - $exact = $ellipsis = null; - extract($options); - - if (mb_strlen($text) <= $length) { - return $text; - } - - $truncate = mb_substr($text, mb_strlen($text) - $length + mb_strlen($ellipsis)); - if (!$exact) { - $spacepos = mb_strpos($truncate, ' '); - $truncate = $spacepos === false ? '' : trim(mb_substr($truncate, $spacepos)); - } - - return $ellipsis . $truncate; - } - - /** - * Truncates text. - * - * Cuts a string to the length of $length and replaces the last characters - * with the ellipsis if the text is longer than length. - * - * ### Options: - * - * - `ellipsis` Will be used as ending and appended to the trimmed string - * - `exact` If false, $text will not be cut mid-word - * - `html` If true, HTML tags would be handled correctly - * - `trimWidth` If true, $text will be truncated with the width - * - * @param string $text String to truncate. - * @param int $length Length of returned string, including ellipsis. - * @param array $options An array of HTML attributes and options. - * @return string Trimmed string. - * @link https://book.cakephp.org/3.0/en/core-libraries/text.html#truncating-text - */ - public static function truncate($text, $length = 100, array $options = []) - { - $default = [ - 'ellipsis' => '...', 'exact' => true, 'html' => false, 'trimWidth' => false, - ]; - if (!empty($options['html']) && strtolower(mb_internal_encoding()) === 'utf-8') { - $default['ellipsis'] = "\xe2\x80\xa6"; - } - $options += $default; - - $prefix = ''; - $suffix = $options['ellipsis']; - - if ($options['html']) { - $ellipsisLength = self::_strlen(strip_tags($options['ellipsis']), $options); - - $truncateLength = 0; - $totalLength = 0; - $openTags = []; - $truncate = ''; - - preg_match_all('/(<\/?([\w+]+)[^>]*>)?([^<>]*)/', $text, $tags, PREG_SET_ORDER); - foreach ($tags as $tag) { - $contentLength = 0; - if (!in_array($tag[2], static::$_defaultHtmlNoCount, true)) { - $contentLength = self::_strlen($tag[3], $options); - } - - if ($truncate === '') { - if (!preg_match('/img|br|input|hr|area|base|basefont|col|frame|isindex|link|meta|param/i', $tag[2])) { - if (preg_match('/<[\w]+[^>]*>/', $tag[0])) { - array_unshift($openTags, $tag[2]); - } elseif (preg_match('/<\/([\w]+)[^>]*>/', $tag[0], $closeTag)) { - $pos = array_search($closeTag[1], $openTags); - if ($pos !== false) { - array_splice($openTags, $pos, 1); - } - } - } - - $prefix .= $tag[1]; - - if ($totalLength + $contentLength + $ellipsisLength > $length) { - $truncate = $tag[3]; - $truncateLength = $length - $totalLength; - } else { - $prefix .= $tag[3]; - } - } - - $totalLength += $contentLength; - if ($totalLength > $length) { - break; - } - } - - if ($totalLength <= $length) { - return $text; - } - - $text = $truncate; - $length = $truncateLength; - - foreach ($openTags as $tag) { - $suffix .= ''; - } - } else { - if (self::_strlen($text, $options) <= $length) { - return $text; - } - $ellipsisLength = self::_strlen($options['ellipsis'], $options); - } - - $result = self::_substr($text, 0, $length - $ellipsisLength, $options); - - if (!$options['exact']) { - if (self::_substr($text, $length - $ellipsisLength, 1, $options) !== ' ') { - $result = self::_removeLastWord($result); - } - - // If result is empty, then we don't need to count ellipsis in the cut. - if (!strlen($result)) { - $result = self::_substr($text, 0, $length, $options); - } - } - - return $prefix . $result . $suffix; - } - - /** - * Truncate text with specified width. - * - * @param string $text String to truncate. - * @param int $length Length of returned string, including ellipsis. - * @param array $options An array of HTML attributes and options. - * @return string Trimmed string. - * @see \Cake\Utility\Text::truncate() - */ - public static function truncateByWidth($text, $length = 100, array $options = []) - { - return static::truncate($text, $length, ['trimWidth' => true] + $options); - } - - /** - * Get string length. - * - * ### Options: - * - * - `html` If true, HTML entities will be handled as decoded characters. - * - `trimWidth` If true, the width will return. - * - * @param string $text The string being checked for length - * @param array $options An array of options. - * @return int - */ - protected static function _strlen($text, array $options) - { - if (empty($options['trimWidth'])) { - $strlen = 'mb_strlen'; - } else { - $strlen = 'mb_strwidth'; - } - - if (empty($options['html'])) { - return $strlen($text); - } - - $pattern = '/&[0-9a-z]{2,8};|&#[0-9]{1,7};|&#x[0-9a-f]{1,6};/i'; - $replace = preg_replace_callback( - $pattern, - function ($match) use ($strlen) { - $utf8 = html_entity_decode($match[0], ENT_HTML5 | ENT_QUOTES, 'UTF-8'); - - return str_repeat(' ', $strlen($utf8, 'UTF-8')); - }, - $text - ); - - return $strlen($replace); - } - - /** - * Return part of a string. - * - * ### Options: - * - * - `html` If true, HTML entities will be handled as decoded characters. - * - `trimWidth` If true, will be truncated with specified width. - * - * @param string $text The input string. - * @param int $start The position to begin extracting. - * @param int $length The desired length. - * @param array $options An array of options. - * @return string - */ - protected static function _substr($text, $start, $length, array $options) - { - if (empty($options['trimWidth'])) { - $substr = 'mb_substr'; - } else { - $substr = 'mb_strimwidth'; - } - - $maxPosition = self::_strlen($text, ['trimWidth' => false] + $options); - if ($start < 0) { - $start += $maxPosition; - if ($start < 0) { - $start = 0; - } - } - if ($start >= $maxPosition) { - return ''; - } - - if ($length === null) { - $length = self::_strlen($text, $options); - } - - if ($length < 0) { - $text = self::_substr($text, $start, null, $options); - $start = 0; - $length += self::_strlen($text, $options); - } - - if ($length <= 0) { - return ''; - } - - if (empty($options['html'])) { - return (string)$substr($text, $start, $length); - } - - $totalOffset = 0; - $totalLength = 0; - $result = ''; - - $pattern = '/(&[0-9a-z]{2,8};|&#[0-9]{1,7};|&#x[0-9a-f]{1,6};)/i'; - $parts = preg_split($pattern, $text, -1, PREG_SPLIT_DELIM_CAPTURE | PREG_SPLIT_NO_EMPTY); - foreach ($parts as $part) { - $offset = 0; - - if ($totalOffset < $start) { - $len = self::_strlen($part, ['trimWidth' => false] + $options); - if ($totalOffset + $len <= $start) { - $totalOffset += $len; - continue; - } - - $offset = $start - $totalOffset; - $totalOffset = $start; - } - - $len = self::_strlen($part, $options); - if ($offset !== 0 || $totalLength + $len > $length) { - if (strpos($part, '&') === 0 && preg_match($pattern, $part) - && $part !== html_entity_decode($part, ENT_HTML5 | ENT_QUOTES, 'UTF-8') - ) { - // Entities cannot be passed substr. - continue; - } - - $part = $substr($part, $offset, $length - $totalLength); - $len = self::_strlen($part, $options); - } - - $result .= $part; - $totalLength += $len; - if ($totalLength >= $length) { - break; - } - } - - return $result; - } - - /** - * Removes the last word from the input text. - * - * @param string $text The input text - * @return string - */ - protected static function _removeLastWord($text) - { - $spacepos = mb_strrpos($text, ' '); - - if ($spacepos !== false) { - $lastWord = mb_strrpos($text, $spacepos); - - // Some languages are written without word separation. - // We recognize a string as a word if it doesn't contain any full-width characters. - if (mb_strwidth($lastWord) === mb_strlen($lastWord)) { - $text = mb_substr($text, 0, $spacepos); - } - - return $text; - } - - return ''; - } - - /** - * Extracts an excerpt from the text surrounding the phrase with a number of characters on each side - * determined by radius. - * - * @param string $text String to search the phrase in - * @param string $phrase Phrase that will be searched for - * @param int $radius The amount of characters that will be returned on each side of the founded phrase - * @param string $ellipsis Ending that will be appended - * @return string Modified string - * @link https://book.cakephp.org/3.0/en/core-libraries/text.html#extracting-an-excerpt - */ - public static function excerpt($text, $phrase, $radius = 100, $ellipsis = '...') - { - if (empty($text) || empty($phrase)) { - return static::truncate($text, $radius * 2, ['ellipsis' => $ellipsis]); - } - - $append = $prepend = $ellipsis; - - $phraseLen = mb_strlen($phrase); - $textLen = mb_strlen($text); - - $pos = mb_strpos(mb_strtolower($text), mb_strtolower($phrase)); - if ($pos === false) { - return mb_substr($text, 0, $radius) . $ellipsis; - } - - $startPos = $pos - $radius; - if ($startPos <= 0) { - $startPos = 0; - $prepend = ''; - } - - $endPos = $pos + $phraseLen + $radius; - if ($endPos >= $textLen) { - $endPos = $textLen; - $append = ''; - } - - $excerpt = mb_substr($text, $startPos, $endPos - $startPos); - $excerpt = $prepend . $excerpt . $append; - - return $excerpt; - } - - /** - * Creates a comma separated list where the last two items are joined with 'and', forming natural language. - * - * @param array $list The list to be joined. - * @param string|null $and The word used to join the last and second last items together with. Defaults to 'and'. - * @param string $separator The separator used to join all the other items together. Defaults to ', '. - * @return string The glued together string. - * @link https://book.cakephp.org/3.0/en/core-libraries/text.html#converting-an-array-to-sentence-form - */ - public static function toList(array $list, $and = null, $separator = ', ') - { - if ($and === null) { - $and = __d('cake', 'and'); - } - if (count($list) > 1) { - return implode($separator, array_slice($list, null, -1)) . ' ' . $and . ' ' . array_pop($list); - } - - return array_pop($list); - } - - /** - * Check if the string contain multibyte characters - * - * @param string $string value to test - * @return bool - */ - public static function isMultibyte($string) - { - $length = strlen($string); - - for ($i = 0; $i < $length; $i++) { - $value = ord($string[$i]); - if ($value > 128) { - return true; - } - } - - return false; - } - - /** - * Converts a multibyte character string - * to the decimal value of the character - * - * @param string $string String to convert. - * @return array - */ - public static function utf8($string) - { - $map = []; - - $values = []; - $find = 1; - $length = strlen($string); - - for ($i = 0; $i < $length; $i++) { - $value = ord($string[$i]); - - if ($value < 128) { - $map[] = $value; - } else { - if (empty($values)) { - $find = ($value < 224) ? 2 : 3; - } - $values[] = $value; - - if (count($values) === $find) { - if ($find == 3) { - $map[] = (($values[0] % 16) * 4096) + (($values[1] % 64) * 64) + ($values[2] % 64); - } else { - $map[] = (($values[0] % 32) * 64) + ($values[1] % 64); - } - $values = []; - $find = 1; - } - } - } - - return $map; - } - - /** - * Converts the decimal value of a multibyte character string - * to a string - * - * @param array $array Array - * @return string - */ - public static function ascii(array $array) - { - $ascii = ''; - - foreach ($array as $utf8) { - if ($utf8 < 128) { - $ascii .= chr($utf8); - } elseif ($utf8 < 2048) { - $ascii .= chr(192 + (($utf8 - ($utf8 % 64)) / 64)); - $ascii .= chr(128 + ($utf8 % 64)); - } else { - $ascii .= chr(224 + (($utf8 - ($utf8 % 4096)) / 4096)); - $ascii .= chr(128 + ((($utf8 % 4096) - ($utf8 % 64)) / 64)); - $ascii .= chr(128 + ($utf8 % 64)); - } - } - - return $ascii; - } - - /** - * Converts filesize from human readable string to bytes - * - * @param string $size Size in human readable string like '5MB', '5M', '500B', '50kb' etc. - * @param mixed $default Value to be returned when invalid size was used, for example 'Unknown type' - * @return mixed Number of bytes as integer on success, `$default` on failure if not false - * @throws \InvalidArgumentException On invalid Unit type. - * @link https://book.cakephp.org/3.0/en/core-libraries/text.html#Cake\Utility\Text::parseFileSize - */ - public static function parseFileSize($size, $default = false) - { - if (ctype_digit($size)) { - return (int)$size; - } - $size = strtoupper($size); - - $l = -2; - $i = array_search(substr($size, -2), ['KB', 'MB', 'GB', 'TB', 'PB']); - if ($i === false) { - $l = -1; - $i = array_search(substr($size, -1), ['K', 'M', 'G', 'T', 'P']); - } - if ($i !== false) { - $size = substr($size, 0, $l); - - return $size * pow(1024, $i + 1); - } - - if (substr($size, -1) === 'B' && ctype_digit(substr($size, 0, -1))) { - $size = substr($size, 0, -1); - - return (int)$size; - } - - if ($default !== false) { - return $default; - } - throw new InvalidArgumentException('No unit type.'); - } - - /** - * Get default transliterator identifier string. - * - * @return string Transliterator identifier. - */ - public static function getTransliteratorId() - { - return static::$_defaultTransliteratorId; - } - - /** - * Set default transliterator identifier string. - * - * @param string $transliteratorId Transliterator identifier. - * @return void - */ - public static function setTransliteratorId($transliteratorId) - { - static::$_defaultTransliteratorId = $transliteratorId; - } - - /** - * Transliterate string. - * - * @param string $string String to transliterate. - * @param string|null $transliteratorId Transliterator identifier. If null - * Text::$_defaultTransliteratorId will be used. - * @return string - * @see https://secure.php.net/manual/en/transliterator.transliterate.php - */ - public static function transliterate($string, $transliteratorId = null) - { - $transliteratorId = $transliteratorId ?: static::$_defaultTransliteratorId; - - return transliterator_transliterate($transliteratorId, $string); - } - - /** - * Returns a string with all spaces converted to dashes (by default), - * characters transliterated to ASCII characters, and non word characters removed. - * - * ### Options: - * - * - `replacement`: Replacement string. Default '-'. - * - `transliteratorId`: A valid tranliterator id string. - * If default `null` Text::$_defaultTransliteratorId to be used. - * If `false` no transliteration will be done, only non words will be removed. - * - `preserve`: Specific non-word character to preserve. Default `null`. - * For e.g. this option can be set to '.' to generate clean file names. - * - * @param string $string the string you want to slug - * @param array $options If string it will be use as replacement character - * or an array of options. - * @return string - */ - public static function slug($string, $options = []) - { - if (is_string($options)) { - $options = ['replacement' => $options]; - } - $options += [ - 'replacement' => '-', - 'transliteratorId' => null, - 'preserve' => null - ]; - - if ($options['transliteratorId'] !== false) { - $string = static::transliterate($string, $options['transliteratorId']); - } - - $regex = '^\s\p{Ll}\p{Lm}\p{Lo}\p{Lt}\p{Lu}\p{Nd}'; - if ($options['preserve']) { - $regex .= preg_quote($options['preserve'], '/'); - } - $quotedReplacement = preg_quote($options['replacement'], '/'); - $map = [ - '/[' . $regex . ']/mu' => ' ', - '/[\s]+/mu' => $options['replacement'], - sprintf('/^[%s]+|[%s]+$/', $quotedReplacement, $quotedReplacement) => '', - ]; - $string = preg_replace(array_keys($map), $map, $string); - - return $string; - } -} diff --git a/vendor/cakephp/cakephp/src/Utility/Xml.php b/vendor/cakephp/cakephp/src/Utility/Xml.php deleted file mode 100644 index 01346d6..0000000 --- a/vendor/cakephp/cakephp/src/Utility/Xml.php +++ /dev/null @@ -1,441 +0,0 @@ -text'); - * ``` - * - * Building XML from string (output DOMDocument): - * - * ``` - * $xml = Xml::build('text', ['return' => 'domdocument']); - * ``` - * - * Building XML from a file path: - * - * ``` - * $xml = Xml::build('/path/to/an/xml/file.xml'); - * ``` - * - * Building XML from a remote URL: - * - * ``` - * use Cake\Http\Client; - * - * $http = new Client(); - * $response = $http->get('http://example.com/example.xml'); - * $xml = Xml::build($response->body()); - * ``` - * - * Building from an array: - * - * ``` - * $value = [ - * 'tags' => [ - * 'tag' => [ - * [ - * 'id' => '1', - * 'name' => 'defect' - * ], - * [ - * 'id' => '2', - * 'name' => 'enhancement' - * ] - * ] - * ] - * ]; - * $xml = Xml::build($value); - * ``` - * - * When building XML from an array ensure that there is only one top level element. - * - * ### Options - * - * - `return` Can be 'simplexml' to return object of SimpleXMLElement or 'domdocument' to return DOMDocument. - * - `loadEntities` Defaults to false. Set to true to enable loading of ` 'simplexml', - 'loadEntities' => false, - 'readFile' => true, - 'parseHuge' => false, - ]; - $options += $defaults; - - if (is_array($input) || is_object($input)) { - return static::fromArray($input, $options); - } - - if (strpos($input, '<') !== false) { - return static::_loadXml($input, $options); - } - - if ($options['readFile'] && file_exists($input)) { - return static::_loadXml(file_get_contents($input), $options); - } - - if (!is_string($input)) { - throw new XmlException('Invalid input.'); - } - - throw new XmlException('XML cannot be read.'); - } - - /** - * Parse the input data and create either a SimpleXmlElement object or a DOMDocument. - * - * @param string $input The input to load. - * @param array $options The options to use. See Xml::build() - * @return \SimpleXMLElement|\DOMDocument - * @throws \Cake\Utility\Exception\XmlException - */ - protected static function _loadXml($input, $options) - { - $hasDisable = function_exists('libxml_disable_entity_loader'); - $internalErrors = libxml_use_internal_errors(true); - if ($hasDisable && !$options['loadEntities']) { - libxml_disable_entity_loader(true); - } - $flags = 0; - if (!empty($options['parseHuge'])) { - $flags |= LIBXML_PARSEHUGE; - } - try { - if ($options['return'] === 'simplexml' || $options['return'] === 'simplexmlelement') { - $flags |= LIBXML_NOCDATA; - $xml = new SimpleXMLElement($input, $flags); - } else { - $xml = new DOMDocument(); - $xml->loadXML($input, $flags); - } - - return $xml; - } catch (Exception $e) { - throw new XmlException('Xml cannot be read. ' . $e->getMessage(), null, $e); - } finally { - if ($hasDisable && !$options['loadEntities']) { - libxml_disable_entity_loader(false); - } - libxml_use_internal_errors($internalErrors); - } - } - - /** - * Transform an array into a SimpleXMLElement - * - * ### Options - * - * - `format` If create childs ('tags') or attributes ('attributes'). - * - `pretty` Returns formatted Xml when set to `true`. Defaults to `false` - * - `version` Version of XML document. Default is 1.0. - * - `encoding` Encoding of XML document. If null remove from XML header. Default is the some of application. - * - `return` If return object of SimpleXMLElement ('simplexml') or DOMDocument ('domdocument'). Default is SimpleXMLElement. - * - * Using the following data: - * - * ``` - * $value = [ - * 'root' => [ - * 'tag' => [ - * 'id' => 1, - * 'value' => 'defect', - * '@' => 'description' - * ] - * ] - * ]; - * ``` - * - * Calling `Xml::fromArray($value, 'tags');` Will generate: - * - * `1defectdescription` - * - * And calling `Xml::fromArray($value, 'attributes');` Will generate: - * - * `description` - * - * @param array|\Cake\Collection\Collection $input Array with data or a collection instance. - * @param string|array $options The options to use or a string to use as format. - * @return \SimpleXMLElement|\DOMDocument SimpleXMLElement or DOMDocument - * @throws \Cake\Utility\Exception\XmlException - */ - public static function fromArray($input, $options = []) - { - if (is_object($input) && method_exists($input, 'toArray') && is_callable([$input, 'toArray'])) { - $input = call_user_func([$input, 'toArray']); - } - if (!is_array($input) || count($input) !== 1) { - throw new XmlException('Invalid input.'); - } - $key = key($input); - if (is_int($key)) { - throw new XmlException('The key of input must be alphanumeric'); - } - - if (!is_array($options)) { - $options = ['format' => (string)$options]; - } - $defaults = [ - 'format' => 'tags', - 'version' => '1.0', - 'encoding' => mb_internal_encoding(), - 'return' => 'simplexml', - 'pretty' => false - ]; - $options += $defaults; - - $dom = new DOMDocument($options['version'], $options['encoding']); - if ($options['pretty']) { - $dom->formatOutput = true; - } - self::_fromArray($dom, $dom, $input, $options['format']); - - $options['return'] = strtolower($options['return']); - if ($options['return'] === 'simplexml' || $options['return'] === 'simplexmlelement') { - return new SimpleXMLElement($dom->saveXML()); - } - - return $dom; - } - - /** - * Recursive method to create childs from array - * - * @param \DOMDocument $dom Handler to DOMDocument - * @param \DOMElement $node Handler to DOMElement (child) - * @param array $data Array of data to append to the $node. - * @param string $format Either 'attributes' or 'tags'. This determines where nested keys go. - * @return void - * @throws \Cake\Utility\Exception\XmlException - */ - protected static function _fromArray($dom, $node, &$data, $format) - { - if (empty($data) || !is_array($data)) { - return; - } - foreach ($data as $key => $value) { - if (is_string($key)) { - if (is_object($value) && method_exists($value, 'toArray') && is_callable([$value, 'toArray'])) { - $value = call_user_func([$value, 'toArray']); - } - - if (!is_array($value)) { - if (is_bool($value)) { - $value = (int)$value; - } elseif ($value === null) { - $value = ''; - } - $isNamespace = strpos($key, 'xmlns:'); - if ($isNamespace !== false) { - $node->setAttributeNS('http://www.w3.org/2000/xmlns/', $key, $value); - continue; - } - if ($key[0] !== '@' && $format === 'tags') { - if (!is_numeric($value)) { - // Escape special characters - // https://www.w3.org/TR/REC-xml/#syntax - // https://bugs.php.net/bug.php?id=36795 - $child = $dom->createElement($key, ''); - $child->appendChild(new DOMText($value)); - } else { - $child = $dom->createElement($key, $value); - } - $node->appendChild($child); - } else { - if ($key[0] === '@') { - $key = substr($key, 1); - } - $attribute = $dom->createAttribute($key); - $attribute->appendChild($dom->createTextNode($value)); - $node->appendChild($attribute); - } - } else { - if ($key[0] === '@') { - throw new XmlException('Invalid array'); - } - if (is_numeric(implode('', array_keys($value)))) { -// List - foreach ($value as $item) { - $itemData = compact('dom', 'node', 'key', 'format'); - $itemData['value'] = $item; - static::_createChild($itemData); - } - } else { -// Struct - static::_createChild(compact('dom', 'node', 'key', 'value', 'format')); - } - } - } else { - throw new XmlException('Invalid array'); - } - } - } - - /** - * Helper to _fromArray(). It will create childs of arrays - * - * @param array $data Array with information to create childs - * @return void - */ - protected static function _createChild($data) - { - $data += [ - 'dom' => null, - 'node' => null, - 'key' => null, - 'value' => null, - 'format' => null, - ]; - - $value = $data['value']; - $dom = $data['dom']; - $key = $data['key']; - $format = $data['format']; - $node = $data['node']; - - $childNS = $childValue = null; - if (is_object($value) && method_exists($value, 'toArray') && is_callable([$value, 'toArray'])) { - $value = call_user_func([$value, 'toArray']); - } - if (is_array($value)) { - if (isset($value['@'])) { - $childValue = (string)$value['@']; - unset($value['@']); - } - if (isset($value['xmlns:'])) { - $childNS = $value['xmlns:']; - unset($value['xmlns:']); - } - } elseif (!empty($value) || $value === 0 || $value === '0') { - $childValue = (string)$value; - } - - $child = $dom->createElement($key); - if ($childValue !== null) { - $child->appendChild($dom->createTextNode($childValue)); - } - if ($childNS) { - $child->setAttribute('xmlns', $childNS); - } - - static::_fromArray($dom, $child, $value, $format); - $node->appendChild($child); - } - - /** - * Returns this XML structure as an array. - * - * @param \SimpleXMLElement|\DOMDocument|\DOMNode $obj SimpleXMLElement, DOMDocument or DOMNode instance - * @return array Array representation of the XML structure. - * @throws \Cake\Utility\Exception\XmlException - */ - public static function toArray($obj) - { - if ($obj instanceof DOMNode) { - $obj = simplexml_import_dom($obj); - } - if (!($obj instanceof SimpleXMLElement)) { - throw new XmlException('The input is not instance of SimpleXMLElement, DOMDocument or DOMNode.'); - } - $result = []; - $namespaces = array_merge(['' => ''], $obj->getNamespaces(true)); - static::_toArray($obj, $result, '', array_keys($namespaces)); - - return $result; - } - - /** - * Recursive method to toArray - * - * @param \SimpleXMLElement $xml SimpleXMLElement object - * @param array $parentData Parent array with data - * @param string $ns Namespace of current child - * @param array $namespaces List of namespaces in XML - * @return void - */ - protected static function _toArray($xml, &$parentData, $ns, $namespaces) - { - $data = []; - - foreach ($namespaces as $namespace) { - foreach ($xml->attributes($namespace, true) as $key => $value) { - if (!empty($namespace)) { - $key = $namespace . ':' . $key; - } - $data['@' . $key] = (string)$value; - } - - foreach ($xml->children($namespace, true) as $child) { - static::_toArray($child, $data, $namespace, $namespaces); - } - } - - $asString = trim((string)$xml); - if (empty($data)) { - $data = $asString; - } elseif (strlen($asString) > 0) { - $data['@'] = $asString; - } - - if (!empty($ns)) { - $ns .= ':'; - } - $name = $ns . $xml->getName(); - if (isset($parentData[$name])) { - if (!is_array($parentData[$name]) || !isset($parentData[$name][0])) { - $parentData[$name] = [$parentData[$name]]; - } - $parentData[$name][] = $data; - } else { - $parentData[$name] = $data; - } - } -} diff --git a/vendor/cakephp/cakephp/src/Utility/bootstrap.php b/vendor/cakephp/cakephp/src/Utility/bootstrap.php deleted file mode 100644 index fbc8471..0000000 --- a/vendor/cakephp/cakephp/src/Utility/bootstrap.php +++ /dev/null @@ -1,18 +0,0 @@ -=5.6.0", - "cakephp/core": "^3.6.0" - }, - "suggest": { - "ext-intl": "To use Text::transliterate() or Text::slug()", - "lib-ICU": "To use Text::transliterate() or Text::slug()" - }, - "autoload": { - "psr-4": { - "Cake\\Utility\\": "." - }, - "files": [ - "bootstrap.php" - ] - } -} diff --git a/vendor/cakephp/cakephp/src/Validation/LICENSE.txt b/vendor/cakephp/cakephp/src/Validation/LICENSE.txt deleted file mode 100644 index 0c4b793..0000000 --- a/vendor/cakephp/cakephp/src/Validation/LICENSE.txt +++ /dev/null @@ -1,22 +0,0 @@ -The MIT License (MIT) - -CakePHP(tm) : The Rapid Development PHP Framework (https://cakephp.org) -Copyright (c) 2005-2016, Cake Software Foundation, Inc. (https://cakefoundation.org) - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. diff --git a/vendor/cakephp/cakephp/src/Validation/README.md b/vendor/cakephp/cakephp/src/Validation/README.md deleted file mode 100644 index 1796651..0000000 --- a/vendor/cakephp/cakephp/src/Validation/README.md +++ /dev/null @@ -1,37 +0,0 @@ -[![Total Downloads](https://img.shields.io/packagist/dt/cakephp/validation.svg?style=flat-square)](https://packagist.org/packages/cakephp/validation) -[![License](https://img.shields.io/badge/license-MIT-blue.svg?style=flat-square)](LICENSE.txt) - -# CakePHP Validation Library - -The validation library in CakePHP provides features to build validators that can validate arbitrary -arrays of data with ease. - -## Usage - -Validator objects define the rules that apply to a set of fields. Validator objects contain a mapping between -fields and validation sets. Creating a validator is simple: - -```php -use Cake\Validation\Validator; - -$validator = new Validator(); -$validator - ->requirePresence('email') - ->add('email', 'validFormat', [ - 'rule' => 'email', - 'message' => 'E-mail must be valid' - ]) - ->requirePresence('name') - ->notEmpty('name', 'We need your name.') - ->requirePresence('comment') - ->notEmpty('comment', 'You need to give a comment.'); - -$errors = $validator->errors($_POST); -if (!empty($errors)) { - // display errors. -} -``` - -## Documentation - -Please make sure you check the [official documentation](https://book.cakephp.org/3.0/en/core-libraries/validation.html) diff --git a/vendor/cakephp/cakephp/src/Validation/RulesProvider.php b/vendor/cakephp/cakephp/src/Validation/RulesProvider.php deleted file mode 100644 index e62ef56..0000000 --- a/vendor/cakephp/cakephp/src/Validation/RulesProvider.php +++ /dev/null @@ -1,74 +0,0 @@ -_class = $class; - $this->_reflection = new ReflectionClass($class); - } - - /** - * Proxies validation method calls to the Validation class. - * - * The last argument (context) will be sliced off, if the validation - * method's last parameter is not named 'context'. This lets - * the various wrapped validation methods to not receive the validation - * context unless they need it. - * - * @param string $method the validation method to call - * @param array $arguments the list of arguments to pass to the method - * @return bool whether or not the validation rule passed - */ - public function __call($method, $arguments) - { - $method = $this->_reflection->getMethod($method); - $argumentList = $method->getParameters(); - if (array_pop($argumentList)->getName() !== 'context') { - $arguments = array_slice($arguments, 0, -1); - } - $object = is_string($this->_class) ? null : $this->_class; - - return $method->invokeArgs($object, $arguments); - } -} diff --git a/vendor/cakephp/cakephp/src/Validation/ValidatableInterface.php b/vendor/cakephp/cakephp/src/Validation/ValidatableInterface.php deleted file mode 100644 index 3578082..0000000 --- a/vendor/cakephp/cakephp/src/Validation/ValidatableInterface.php +++ /dev/null @@ -1,31 +0,0 @@ -'; - - /** - * Greater than or equal to comparison operator. - */ - const COMPARE_GREATER_OR_EQUAL = '>='; - - /** - * Less than comparison operator. - */ - const COMPARE_LESS = '<'; - - /** - * Less than or equal to comparison operator. - */ - const COMPARE_LESS_OR_EQUAL = '<='; - - /** - * Some complex patterns needed in multiple places - * - * @var array - */ - protected static $_pattern = [ - 'hostname' => '(?:[_\p{L}0-9][-_\p{L}0-9]*\.)*(?:[\p{L}0-9][-\p{L}0-9]{0,62})\.(?:(?:[a-z]{2}\.)?[a-z]{2,})', - 'latitude' => '[-+]?([1-8]?\d(\.\d+)?|90(\.0+)?)', - 'longitude' => '[-+]?(180(\.0+)?|((1[0-7]\d)|([1-9]?\d))(\.\d+)?)', - ]; - - /** - * Holds an array of errors messages set in this class. - * These are used for debugging purposes - * - * @var array - */ - public static $errors = []; - - /** - * Backwards compatibility wrapper for Validation::notBlank(). - * - * @param string $check Value to check. - * @return bool Success. - * @deprecated 3.0.2 Use Validation::notBlank() instead. - * @see \Cake\Validation\Validation::notBlank() - */ - public static function notEmpty($check) - { - deprecationWarning( - 'Validation::notEmpty() is deprecated. ' . - 'Use Validation::notBlank() instead.' - ); - - return static::notBlank($check); - } - - /** - * Checks that a string contains something other than whitespace - * - * Returns true if string contains something other than whitespace - * - * @param string $check Value to check - * @return bool Success - */ - public static function notBlank($check) - { - if (empty($check) && !is_bool($check) && !is_numeric($check)) { - return false; - } - - return static::_check($check, '/[^\s]+/m'); - } - - /** - * Checks that a string contains only integer or letters - * - * Returns true if string contains only integer or letters - * - * @param string $check Value to check - * @return bool Success - */ - public static function alphaNumeric($check) - { - if (empty($check) && $check !== '0') { - return false; - } - - return self::_check($check, '/^[\p{Ll}\p{Lm}\p{Lo}\p{Lt}\p{Lu}\p{Nd}]+$/Du'); - } - - /** - * Checks that a string length is within specified range. - * Spaces are included in the character count. - * Returns true if string matches value min, max, or between min and max, - * - * @param string $check Value to check for length - * @param int $min Minimum value in range (inclusive) - * @param int $max Maximum value in range (inclusive) - * @return bool Success - */ - public static function lengthBetween($check, $min, $max) - { - if (!is_string($check)) { - return false; - } - $length = mb_strlen($check); - - return ($length >= $min && $length <= $max); - } - - /** - * Returns true if field is left blank -OR- only whitespace characters are present in its value - * Whitespace characters include Space, Tab, Carriage Return, Newline - * - * @param string $check Value to check - * @return bool Success - * @deprecated 3.0.2 Validation::blank() is deprecated. - */ - public static function blank($check) - { - deprecationWarning( - 'Validation::blank() is deprecated.' - ); - - return !static::_check($check, '/[^\\s]/'); - } - - /** - * Validation of credit card numbers. - * Returns true if $check is in the proper credit card format. - * - * @param string $check credit card number to validate - * @param string|array $type 'all' may be passed as a string, defaults to fast which checks format of most major credit cards - * if an array is used only the values of the array are checked. - * Example: ['amex', 'bankcard', 'maestro'] - * @param bool $deep set to true this will check the Luhn algorithm of the credit card. - * @param string|null $regex A custom regex can also be passed, this will be used instead of the defined regex values - * @return bool Success - * @see \Cake\Validation\Validation::luhn() - */ - public static function cc($check, $type = 'fast', $deep = false, $regex = null) - { - if (!is_scalar($check)) { - return false; - } - - $check = str_replace(['-', ' '], '', $check); - if (mb_strlen($check) < 13) { - return false; - } - - if ($regex !== null) { - if (static::_check($check, $regex)) { - return !$deep || static::luhn($check); - } - } - $cards = [ - 'all' => [ - 'amex' => '/^3[47]\\d{13}$/', - 'bankcard' => '/^56(10\\d\\d|022[1-5])\\d{10}$/', - 'diners' => '/^(?:3(0[0-5]|[68]\\d)\\d{11})|(?:5[1-5]\\d{14})$/', - 'disc' => '/^(?:6011|650\\d)\\d{12}$/', - 'electron' => '/^(?:417500|4917\\d{2}|4913\\d{2})\\d{10}$/', - 'enroute' => '/^2(?:014|149)\\d{11}$/', - 'jcb' => '/^(3\\d{4}|2131|1800)\\d{11}$/', - 'maestro' => '/^(?:5020|6\\d{3})\\d{12}$/', - 'mc' => '/^(5[1-5]\\d{14})|(2(?:22[1-9]|2[3-9][0-9]|[3-6][0-9]{2}|7[0-1][0-9]|720)\\d{12})$/', - 'solo' => '/^(6334[5-9][0-9]|6767[0-9]{2})\\d{10}(\\d{2,3})?$/', - 'switch' => '/^(?:49(03(0[2-9]|3[5-9])|11(0[1-2]|7[4-9]|8[1-2])|36[0-9]{2})\\d{10}(\\d{2,3})?)|(?:564182\\d{10}(\\d{2,3})?)|(6(3(33[0-4][0-9])|759[0-9]{2})\\d{10}(\\d{2,3})?)$/', - 'visa' => '/^4\\d{12}(\\d{3})?$/', - 'voyager' => '/^8699[0-9]{11}$/' - ], - 'fast' => '/^(?:4[0-9]{12}(?:[0-9]{3})?|5[1-5][0-9]{14}|6011[0-9]{12}|3(?:0[0-5]|[68][0-9])[0-9]{11}|3[47][0-9]{13})$/' - ]; - - if (is_array($type)) { - foreach ($type as $value) { - $regex = $cards['all'][strtolower($value)]; - - if (static::_check($check, $regex)) { - return static::luhn($check); - } - } - } elseif ($type === 'all') { - foreach ($cards['all'] as $value) { - $regex = $value; - - if (static::_check($check, $regex)) { - return static::luhn($check); - } - } - } else { - $regex = $cards['fast']; - - if (static::_check($check, $regex)) { - return static::luhn($check); - } - } - - return false; - } - - /** - * Used to check the count of a given value of type array or Countable. - * - * @param array|\Countable $check The value to check the count on. - * @param string $operator Can be either a word or operand - * is greater >, is less <, greater or equal >= - * less or equal <=, is less <, equal to ==, not equal != - * @param int $expectedCount The expected count value. - * @return bool Success - */ - public static function numElements($check, $operator, $expectedCount) - { - if (!is_array($check) && !$check instanceof \Countable) { - return false; - } - - return self::comparison(count($check), $operator, $expectedCount); - } - - /** - * Used to compare 2 numeric values. - * - * @param string $check1 The left value to compare. - * @param string $operator Can be either a word or operand - * is greater >, is less <, greater or equal >= - * less or equal <=, is less <, equal to ==, not equal != - * @param int $check2 The right value to compare. - * @return bool Success - */ - public static function comparison($check1, $operator, $check2) - { - if ((float)$check1 != $check1) { - return false; - } - - $message = 'Operator `%s` is deprecated, use constant `Validation::%s` instead.'; - - $operator = str_replace([' ', "\t", "\n", "\r", "\0", "\x0B"], '', strtolower($operator)); - switch ($operator) { - case 'isgreater': - /* - * @deprecated 3.6.0 Use Validation::COMPARE_GREATER instead. - */ - deprecationWarning(sprintf($message, $operator, 'COMPARE_GREATER')); - // no break - case static::COMPARE_GREATER: - if ($check1 > $check2) { - return true; - } - break; - case 'isless': - /* - * @deprecated 3.6.0 Use Validation::COMPARE_LESS instead. - */ - deprecationWarning(sprintf($message, $operator, 'COMPARE_LESS')); - // no break - case static::COMPARE_LESS: - if ($check1 < $check2) { - return true; - } - break; - case 'greaterorequal': - /* - * @deprecated 3.6.0 Use Validation::COMPARE_GREATER_OR_EQUAL instead. - */ - deprecationWarning(sprintf($message, $operator, 'COMPARE_GREATER_OR_EQUAL')); - // no break - case static::COMPARE_GREATER_OR_EQUAL: - if ($check1 >= $check2) { - return true; - } - break; - case 'lessorequal': - /* - * @deprecated 3.6.0 Use Validation::COMPARE_LESS_OR_EQUAL instead. - */ - deprecationWarning(sprintf($message, $operator, 'COMPARE_LESS_OR_EQUAL')); - // no break - case static::COMPARE_LESS_OR_EQUAL: - if ($check1 <= $check2) { - return true; - } - break; - case 'equalto': - /* - * @deprecated 3.6.0 Use Validation::COMPARE_EQUAL instead. - */ - deprecationWarning(sprintf($message, $operator, 'COMPARE_EQUAL')); - // no break - case static::COMPARE_EQUAL: - if ($check1 == $check2) { - return true; - } - break; - case 'notequal': - /* - * @deprecated 3.6.0 Use Validation::COMPARE_NOT_EQUAL instead. - */ - deprecationWarning(sprintf($message, $operator, 'COMPARE_NOT_EQUAL')); - // no break - case static::COMPARE_NOT_EQUAL: - if ($check1 != $check2) { - return true; - } - break; - case static::COMPARE_SAME: - if ($check1 === $check2) { - return true; - } - break; - case static::COMPARE_NOT_SAME: - if ($check1 !== $check2) { - return true; - } - break; - default: - static::$errors[] = 'You must define the $operator parameter for Validation::comparison()'; - } - - return false; - } - - /** - * Compare one field to another. - * - * If both fields have exactly the same value this method will return true. - * - * @param mixed $check The value to find in $field. - * @param string $field The field to check $check against. This field must be present in $context. - * @param array $context The validation context. - * @return bool - */ - public static function compareWith($check, $field, $context) - { - return self::compareFields($check, $field, static::COMPARE_SAME, $context); - } - - /** - * Compare one field to another. - * - * Return true if the comparison matches the expected result. - * - * @param mixed $check The value to find in $field. - * @param string $field The field to check $check against. This field must be present in $context. - * @param string $operator Comparison operator. - * @param array $context The validation context. - * @return bool - * @since 3.6.0 - */ - public static function compareFields($check, $field, $operator, $context) - { - if (!isset($context['data'][$field])) { - return false; - } - - return static::comparison($check, $operator, $context['data'][$field]); - } - - /** - * Checks if a string contains one or more non-alphanumeric characters. - * - * Returns true if string contains at least the specified number of non-alphanumeric characters - * - * @param string $check Value to check - * @param int $count Number of non-alphanumerics to check for - * @return bool Success - */ - public static function containsNonAlphaNumeric($check, $count = 1) - { - if (!is_scalar($check)) { - return false; - } - - $matches = preg_match_all('/[^a-zA-Z0-9]/', $check); - - return $matches >= $count; - } - - /** - * Used when a custom regular expression is needed. - * - * @param string $check The value to check. - * @param string|null $regex If $check is passed as a string, $regex must also be set to valid regular expression - * @return bool Success - */ - public static function custom($check, $regex = null) - { - if ($regex === null) { - static::$errors[] = 'You must define a regular expression for Validation::custom()'; - - return false; - } - - return static::_check($check, $regex); - } - - /** - * Date validation, determines if the string passed is a valid date. - * keys that expect full month, day and year will validate leap years. - * - * Years are valid from 1800 to 2999. - * - * ### Formats: - * - * - `dmy` 27-12-2006 or 27-12-06 separators can be a space, period, dash, forward slash - * - `mdy` 12-27-2006 or 12-27-06 separators can be a space, period, dash, forward slash - * - `ymd` 2006-12-27 or 06-12-27 separators can be a space, period, dash, forward slash - * - `dMy` 27 December 2006 or 27 Dec 2006 - * - `Mdy` December 27, 2006 or Dec 27, 2006 comma is optional - * - `My` December 2006 or Dec 2006 - * - `my` 12/2006 or 12/06 separators can be a space, period, dash, forward slash - * - `ym` 2006/12 or 06/12 separators can be a space, period, dash, forward slash - * - `y` 2006 just the year without any separators - * - * @param string|\DateTimeInterface $check a valid date string/object - * @param string|array $format Use a string or an array of the keys above. - * Arrays should be passed as ['dmy', 'mdy', etc] - * @param string|null $regex If a custom regular expression is used this is the only validation that will occur. - * @return bool Success - */ - public static function date($check, $format = 'ymd', $regex = null) - { - if ($check instanceof DateTimeInterface) { - return true; - } - if (is_object($check)) { - return false; - } - if (is_array($check)) { - $check = static::_getDateString($check); - $format = 'ymd'; - } - - if ($regex !== null) { - return static::_check($check, $regex); - } - $month = '(0[123456789]|10|11|12)'; - $separator = '([- /.])'; - $fourDigitYear = '(([1][8-9][0-9][0-9])|([2][0-9][0-9][0-9]))'; - $twoDigitYear = '([0-9]{2})'; - $year = '(?:' . $fourDigitYear . '|' . $twoDigitYear . ')'; - - $regex['dmy'] = '%^(?:(?:31(\\/|-|\\.|\\x20)(?:0?[13578]|1[02]))\\1|(?:(?:29|30)' . - $separator . '(?:0?[1,3-9]|1[0-2])\\2))(?:(?:1[6-9]|[2-9]\\d)?\\d{2})$|^(?:29' . - $separator . '0?2\\3(?:(?:(?:1[6-9]|[2-9]\\d)?(?:0[48]|[2468][048]|[13579][26])|(?:(?:16|[2468][048]|[3579][26])00))))$|^(?:0?[1-9]|1\\d|2[0-8])' . - $separator . '(?:(?:0?[1-9])|(?:1[0-2]))\\4(?:(?:1[6-9]|[2-9]\\d)?\\d{2})$%'; - - $regex['mdy'] = '%^(?:(?:(?:0?[13578]|1[02])(\\/|-|\\.|\\x20)31)\\1|(?:(?:0?[13-9]|1[0-2])' . - $separator . '(?:29|30)\\2))(?:(?:1[6-9]|[2-9]\\d)?\\d{2})$|^(?:0?2' . $separator . '29\\3(?:(?:(?:1[6-9]|[2-9]\\d)?(?:0[48]|[2468][048]|[13579][26])|(?:(?:16|[2468][048]|[3579][26])00))))$|^(?:(?:0?[1-9])|(?:1[0-2]))' . - $separator . '(?:0?[1-9]|1\\d|2[0-8])\\4(?:(?:1[6-9]|[2-9]\\d)?\\d{2})$%'; - - $regex['ymd'] = '%^(?:(?:(?:(?:(?:1[6-9]|[2-9]\\d)?(?:0[48]|[2468][048]|[13579][26])|(?:(?:16|[2468][048]|[3579][26])00)))' . - $separator . '(?:0?2\\1(?:29)))|(?:(?:(?:1[6-9]|[2-9]\\d)?\\d{2})' . - $separator . '(?:(?:(?:0?[13578]|1[02])\\2(?:31))|(?:(?:0?[1,3-9]|1[0-2])\\2(29|30))|(?:(?:0?[1-9])|(?:1[0-2]))\\2(?:0?[1-9]|1\\d|2[0-8]))))$%'; - - $regex['dMy'] = '/^((31(?!\\ (Feb(ruary)?|Apr(il)?|June?|(Sep(?=\\b|t)t?|Nov)(ember)?)))|((30|29)(?!\\ Feb(ruary)?))|(29(?=\\ Feb(ruary)?\\ (((1[6-9]|[2-9]\\d)(0[48]|[2468][048]|[13579][26])|((16|[2468][048]|[3579][26])00)))))|(0?[1-9])|1\\d|2[0-8])\\ (Jan(uary)?|Feb(ruary)?|Ma(r(ch)?|y)|Apr(il)?|Ju((ly?)|(ne?))|Aug(ust)?|Oct(ober)?|(Sep(?=\\b|t)t?|Nov|Dec)(ember)?)\\ ((1[6-9]|[2-9]\\d)\\d{2})$/'; - - $regex['Mdy'] = '/^(?:(((Jan(uary)?|Ma(r(ch)?|y)|Jul(y)?|Aug(ust)?|Oct(ober)?|Dec(ember)?)\\ 31)|((Jan(uary)?|Ma(r(ch)?|y)|Apr(il)?|Ju((ly?)|(ne?))|Aug(ust)?|Oct(ober)?|(Sep)(tember)?|(Nov|Dec)(ember)?)\\ (0?[1-9]|([12]\\d)|30))|(Feb(ruary)?\\ (0?[1-9]|1\\d|2[0-8]|(29(?=,?\\ ((1[6-9]|[2-9]\\d)(0[48]|[2468][048]|[13579][26])|((16|[2468][048]|[3579][26])00)))))))\\,?\\ ((1[6-9]|[2-9]\\d)\\d{2}))$/'; - - $regex['My'] = '%^(Jan(uary)?|Feb(ruary)?|Ma(r(ch)?|y)|Apr(il)?|Ju((ly?)|(ne?))|Aug(ust)?|Oct(ober)?|(Sep(?=\\b|t)t?|Nov|Dec)(ember)?)' . - $separator . '((1[6-9]|[2-9]\\d)\\d{2})$%'; - - $regex['my'] = '%^(' . $month . $separator . $year . ')$%'; - $regex['ym'] = '%^(' . $year . $separator . $month . ')$%'; - $regex['y'] = '%^(' . $fourDigitYear . ')$%'; - - $format = is_array($format) ? array_values($format) : [$format]; - foreach ($format as $key) { - if (static::_check($check, $regex[$key]) === true) { - return true; - } - } - - return false; - } - - /** - * Validates a datetime value - * - * All values matching the "date" core validation rule, and the "time" one will be valid - * - * @param string|\DateTimeInterface $check Value to check - * @param string|array $dateFormat Format of the date part. See Validation::date() for more information. - * @param string|null $regex Regex for the date part. If a custom regular expression is used this is the only validation that will occur. - * @return bool True if the value is valid, false otherwise - * @see \Cake\Validation\Validation::date() - * @see \Cake\Validation\Validation::time() - */ - public static function datetime($check, $dateFormat = 'ymd', $regex = null) - { - if ($check instanceof DateTimeInterface) { - return true; - } - if (is_object($check)) { - return false; - } - $valid = false; - if (is_array($check)) { - $check = static::_getDateString($check); - $dateFormat = 'ymd'; - } - $parts = explode(' ', $check); - if (!empty($parts) && count($parts) > 1) { - $date = rtrim(array_shift($parts), ','); - $time = implode(' ', $parts); - $valid = static::date($date, $dateFormat, $regex) && static::time($time); - } - - return $valid; - } - - /** - * Time validation, determines if the string passed is a valid time. - * Validates time as 24hr (HH:MM) or am/pm ([H]H:MM[a|p]m) - * Does not allow/validate seconds. - * - * @param string|\DateTimeInterface $check a valid time string/object - * @return bool Success - */ - public static function time($check) - { - if ($check instanceof DateTimeInterface) { - return true; - } - if (is_array($check)) { - $check = static::_getDateString($check); - } - - return static::_check($check, '%^((0?[1-9]|1[012])(:[0-5]\d){0,2} ?([AP]M|[ap]m))$|^([01]\d|2[0-3])(:[0-5]\d){0,2}$%'); - } - - /** - * Date and/or time string validation. - * Uses `I18n::Time` to parse the date. This means parsing is locale dependent. - * - * @param string|\DateTime $check a date string or object (will always pass) - * @param string $type Parser type, one out of 'date', 'time', and 'datetime' - * @param string|int|null $format any format accepted by IntlDateFormatter - * @return bool Success - * @throws \InvalidArgumentException when unsupported $type given - * @see \Cake\I18n\Time::parseDate(), \Cake\I18n\Time::parseTime(), \Cake\I18n\Time::parseDateTime() - */ - public static function localizedTime($check, $type = 'datetime', $format = null) - { - if ($check instanceof DateTimeInterface) { - return true; - } - if (is_object($check)) { - return false; - } - static $methods = [ - 'date' => 'parseDate', - 'time' => 'parseTime', - 'datetime' => 'parseDateTime', - ]; - if (empty($methods[$type])) { - throw new InvalidArgumentException('Unsupported parser type given.'); - } - $method = $methods[$type]; - - return (Time::$method($check, $format) !== null); - } - - /** - * Validates if passed value is boolean-like. - * - * The list of what is considered to be boolean values, may be set via $booleanValues. - * - * @param bool|int|string $check Value to check. - * @param array $booleanValues List of valid boolean values, defaults to `[true, false, 0, 1, '0', '1']`. - * @return bool Success. - */ - public static function boolean($check, array $booleanValues = []) - { - if (!$booleanValues) { - $booleanValues = [true, false, 0, 1, '0', '1']; - } - - return in_array($check, $booleanValues, true); - } - - /** - * Validates if given value is truthy. - * - * The list of what is considered to be truthy values, may be set via $truthyValues. - * - * @param bool|int|string $check Value to check. - * @param array $truthyValues List of valid truthy values, defaults to `[true, 1, '1']`. - * @return bool Success. - */ - public static function truthy($check, array $truthyValues = []) - { - if (!$truthyValues) { - $truthyValues = [true, 1, '1']; - } - - return in_array($check, $truthyValues, true); - } - - /** - * Validates if given value is falsey. - * - * The list of what is considered to be falsey values, may be set via $falseyValues. - * - * @param bool|int|string $check Value to check. - * @param array $falseyValues List of valid falsey values, defaults to `[false, 0, '0']`. - * @return bool Success. - */ - public static function falsey($check, array $falseyValues = []) - { - if (!$falseyValues) { - $falseyValues = [false, 0, '0']; - } - - return in_array($check, $falseyValues, true); - } - - /** - * Checks that a value is a valid decimal. Both the sign and exponent are optional. - * - * Valid Places: - * - * - null => Any number of decimal places, including none. The '.' is not required. - * - true => Any number of decimal places greater than 0, or a float|double. The '.' is required. - * - 1..N => Exactly that many number of decimal places. The '.' is required. - * - * @param float $check The value the test for decimal. - * @param int|bool|null $places Decimal places. - * @param string|null $regex If a custom regular expression is used, this is the only validation that will occur. - * @return bool Success - */ - public static function decimal($check, $places = null, $regex = null) - { - if ($regex === null) { - $lnum = '[0-9]+'; - $dnum = "[0-9]*[\.]{$lnum}"; - $sign = '[+-]?'; - $exp = "(?:[eE]{$sign}{$lnum})?"; - - if ($places === null) { - $regex = "/^{$sign}(?:{$lnum}|{$dnum}){$exp}$/"; - } elseif ($places === true) { - if (is_float($check) && floor($check) === $check) { - $check = sprintf('%.1f', $check); - } - $regex = "/^{$sign}{$dnum}{$exp}$/"; - } elseif (is_numeric($places)) { - $places = '[0-9]{' . $places . '}'; - $dnum = "(?:[0-9]*[\.]{$places}|{$lnum}[\.]{$places})"; - $regex = "/^{$sign}{$dnum}{$exp}$/"; - } - } - - // account for localized floats. - $locale = ini_get('intl.default_locale') ?: static::DEFAULT_LOCALE; - $formatter = new NumberFormatter($locale, NumberFormatter::DECIMAL); - $decimalPoint = $formatter->getSymbol(NumberFormatter::DECIMAL_SEPARATOR_SYMBOL); - $groupingSep = $formatter->getSymbol(NumberFormatter::GROUPING_SEPARATOR_SYMBOL); - - $check = str_replace($groupingSep, '', $check); - $check = str_replace($decimalPoint, '.', $check); - - return static::_check($check, $regex); - } - - /** - * Validates for an email address. - * - * Only uses getmxrr() checking for deep validation, or - * any PHP version on a non-windows distribution - * - * @param string $check Value to check - * @param bool $deep Perform a deeper validation (if true), by also checking availability of host - * @param string|null $regex Regex to use (if none it will use built in regex) - * @return bool Success - */ - public static function email($check, $deep = false, $regex = null) - { - if (!is_string($check)) { - return false; - } - - if ($regex === null) { - $regex = '/^[\p{L}0-9!#$%&\'*+\/=?^_`{|}~-]+(?:\.[\p{L}0-9!#$%&\'*+\/=?^_`{|}~-]+)*@' . self::$_pattern['hostname'] . '$/ui'; - } - $return = static::_check($check, $regex); - if ($deep === false || $deep === null) { - return $return; - } - - if ($return === true && preg_match('/@(' . static::$_pattern['hostname'] . ')$/i', $check, $regs)) { - if (function_exists('getmxrr') && getmxrr($regs[1], $mxhosts)) { - return true; - } - if (function_exists('checkdnsrr') && checkdnsrr($regs[1], 'MX')) { - return true; - } - - return is_array(gethostbynamel($regs[1] . '.')); - } - - return false; - } - - /** - * Checks that value is exactly $comparedTo. - * - * @param mixed $check Value to check - * @param mixed $comparedTo Value to compare - * @return bool Success - */ - public static function equalTo($check, $comparedTo) - { - return ($check === $comparedTo); - } - - /** - * Checks that value has a valid file extension. - * - * @param string|array $check Value to check - * @param array $extensions file extensions to allow. By default extensions are 'gif', 'jpeg', 'png', 'jpg' - * @return bool Success - */ - public static function extension($check, $extensions = ['gif', 'jpeg', 'png', 'jpg']) - { - if (is_array($check)) { - $check = isset($check['name']) ? $check['name'] : array_shift($check); - - return static::extension($check, $extensions); - } - $extension = strtolower(pathinfo($check, PATHINFO_EXTENSION)); - foreach ($extensions as $value) { - if ($extension === strtolower($value)) { - return true; - } - } - - return false; - } - - /** - * Validation of an IP address. - * - * @param string $check The string to test. - * @param string $type The IP Protocol version to validate against - * @return bool Success - */ - public static function ip($check, $type = 'both') - { - $type = strtolower($type); - $flags = 0; - if ($type === 'ipv4') { - $flags = FILTER_FLAG_IPV4; - } - if ($type === 'ipv6') { - $flags = FILTER_FLAG_IPV6; - } - - return (bool)filter_var($check, FILTER_VALIDATE_IP, ['flags' => $flags]); - } - - /** - * Checks whether the length of a string (in characters) is greater or equal to a minimal length. - * - * @param string $check The string to test - * @param int $min The minimal string length - * @return bool Success - */ - public static function minLength($check, $min) - { - return mb_strlen($check) >= $min; - } - - /** - * Checks whether the length of a string (in characters) is smaller or equal to a maximal length. - * - * @param string $check The string to test - * @param int $max The maximal string length - * @return bool Success - */ - public static function maxLength($check, $max) - { - return mb_strlen($check) <= $max; - } - - /** - * Checks whether the length of a string (in bytes) is greater or equal to a minimal length. - * - * @param string $check The string to test - * @param int $min The minimal string length (in bytes) - * @return bool Success - */ - public static function minLengthBytes($check, $min) - { - return strlen($check) >= $min; - } - - /** - * Checks whether the length of a string (in bytes) is smaller or equal to a maximal length. - * - * @param string $check The string to test - * @param int $max The maximal string length - * @return bool Success - */ - public static function maxLengthBytes($check, $max) - { - return strlen($check) <= $max; - } - - /** - * Checks that a value is a monetary amount. - * - * @param string $check Value to check - * @param string $symbolPosition Where symbol is located (left/right) - * @return bool Success - */ - public static function money($check, $symbolPosition = 'left') - { - $money = '(?!0,?\d)(?:\d{1,3}(?:([, .])\d{3})?(?:\1\d{3})*|(?:\d+))((?!\1)[,.]\d{1,2})?'; - if ($symbolPosition === 'right') { - $regex = '/^' . $money . '(? provide a list of choices that selections must be made from - * - max => maximum number of non-zero choices that can be made - * - min => minimum number of non-zero choices that can be made - * - * @param array $check Value to check - * @param array $options Options for the check. - * @param bool $caseInsensitive Set to true for case insensitive comparison. - * @return bool Success - */ - public static function multiple($check, array $options = [], $caseInsensitive = false) - { - $defaults = ['in' => null, 'max' => null, 'min' => null]; - $options += $defaults; - - $check = array_filter((array)$check, function ($value) { - return ($value || is_numeric($value)); - }); - if (empty($check)) { - return false; - } - if ($options['max'] && count($check) > $options['max']) { - return false; - } - if ($options['min'] && count($check) < $options['min']) { - return false; - } - if ($options['in'] && is_array($options['in'])) { - if ($caseInsensitive) { - $options['in'] = array_map('mb_strtolower', $options['in']); - } - foreach ($check as $val) { - $strict = !is_numeric($val); - if ($caseInsensitive) { - $val = mb_strtolower($val); - } - if (!in_array((string)$val, $options['in'], $strict)) { - return false; - } - } - } - - return true; - } - - /** - * Checks if a value is numeric. - * - * @param string $check Value to check - * @return bool Success - */ - public static function numeric($check) - { - return is_numeric($check); - } - - /** - * Checks if a value is a natural number. - * - * @param string $check Value to check - * @param bool $allowZero Set true to allow zero, defaults to false - * @return bool Success - * @see https://en.wikipedia.org/wiki/Natural_number - */ - public static function naturalNumber($check, $allowZero = false) - { - $regex = $allowZero ? '/^(?:0|[1-9][0-9]*)$/' : '/^[1-9][0-9]*$/'; - - return static::_check($check, $regex); - } - - /** - * Validates that a number is in specified range. - * - * If $lower and $upper are set, the range is inclusive. - * If they are not set, will return true if $check is a - * legal finite on this platform. - * - * @param string $check Value to check - * @param int|float|null $lower Lower limit - * @param int|float|null $upper Upper limit - * @return bool Success - */ - public static function range($check, $lower = null, $upper = null) - { - if (!is_numeric($check)) { - return false; - } - if ((float)$check != $check) { - return false; - } - if (isset($lower, $upper)) { - return ($check >= $lower && $check <= $upper); - } - - return is_finite($check); - } - - /** - * Checks that a value is a valid URL according to https://www.w3.org/Addressing/URL/url-spec.txt - * - * The regex checks for the following component parts: - * - * - a valid, optional, scheme - * - a valid ip address OR - * a valid domain name as defined by section 2.3.1 of https://www.ietf.org/rfc/rfc1035.txt - * with an optional port number - * - an optional valid path - * - an optional query string (get parameters) - * - an optional fragment (anchor tag) as defined in RFC 3986 - * - * @param string $check Value to check - * @param bool $strict Require URL to be prefixed by a valid scheme (one of http(s)/ftp(s)/file/news/gopher) - * @return bool Success - * @link https://tools.ietf.org/html/rfc3986 - */ - public static function url($check, $strict = false) - { - static::_populateIp(); - - $emoji = '\x{1F190}-\x{1F9EF}'; - $alpha = '0-9\p{L}\p{N}' . $emoji; - $hex = '(%[0-9a-f]{2})'; - $subDelimiters = preg_quote('/!"$&\'()*+,-.@_:;=~[]', '/'); - $path = '([' . $subDelimiters . $alpha . ']|' . $hex . ')'; - $fragmentAndQuery = '([\?' . $subDelimiters . $alpha . ']|' . $hex . ')'; - $regex = '/^(?:(?:https?|ftps?|sftp|file|news|gopher):\/\/)' . (!empty($strict) ? '' : '?') . - '(?:' . static::$_pattern['IPv4'] . '|\[' . static::$_pattern['IPv6'] . '\]|' . static::$_pattern['hostname'] . ')(?::[1-9][0-9]{0,4})?' . - '(?:\/' . $path . '*)?' . - '(?:\?' . $fragmentAndQuery . '*)?' . - '(?:#' . $fragmentAndQuery . '*)?$/iu'; - - return static::_check($check, $regex); - } - - /** - * Checks if a value is in a given list. Comparison is case sensitive by default. - * - * @param string $check Value to check. - * @param array $list List to check against. - * @param bool $caseInsensitive Set to true for case insensitive comparison. - * @return bool Success. - */ - public static function inList($check, array $list, $caseInsensitive = false) - { - if ($caseInsensitive) { - $list = array_map('mb_strtolower', $list); - $check = mb_strtolower($check); - } else { - $list = array_map('strval', $list); - } - - return in_array((string)$check, $list, true); - } - - /** - * Runs an user-defined validation. - * - * @param string|array $check value that will be validated in user-defined methods. - * @param object $object class that holds validation method - * @param string $method class method name for validation to run - * @param array|null $args arguments to send to method - * @return mixed user-defined class class method returns - * @deprecated 3.0.2 You can just set a callable for `rule` key when adding validators. - */ - public static function userDefined($check, $object, $method, $args = null) - { - deprecationWarning( - 'Validation::userDefined() is deprecated. ' . - 'You can just set a callable for `rule` key when adding validators.' - ); - - return $object->$method($check, $args); - } - - /** - * Checks that a value is a valid UUID - https://tools.ietf.org/html/rfc4122 - * - * @param string $check Value to check - * @return bool Success - */ - public static function uuid($check) - { - $regex = '/^[a-fA-F0-9]{8}-[a-fA-F0-9]{4}-[0-5][a-fA-F0-9]{3}-[089aAbB][a-fA-F0-9]{3}-[a-fA-F0-9]{12}$/'; - - return self::_check($check, $regex); - } - - /** - * Runs a regular expression match. - * - * @param string $check Value to check against the $regex expression - * @param string $regex Regular expression - * @return bool Success of match - */ - protected static function _check($check, $regex) - { - return is_string($regex) && is_scalar($check) && preg_match($regex, $check); - } - - /** - * Luhn algorithm - * - * @param string|array $check Value to check. - * @return bool Success - * @see https://en.wikipedia.org/wiki/Luhn_algorithm - */ - public static function luhn($check) - { - if (!is_scalar($check) || (int)$check === 0) { - return false; - } - $sum = 0; - $length = strlen($check); - - for ($position = 1 - ($length % 2); $position < $length; $position += 2) { - $sum += $check[$position]; - } - - for ($position = ($length % 2); $position < $length; $position += 2) { - $number = $check[$position] * 2; - $sum += ($number < 10) ? $number : $number - 9; - } - - return ($sum % 10 === 0); - } - - /** - * Checks the mime type of a file. - * - * Will check the mimetype of files/UploadedFileInterface instances - * by checking the using finfo on the file, not relying on the content-type - * sent by the client. - * - * @param string|array|\Psr\Http\Message\UploadedFileInterface $check Value to check. - * @param array|string $mimeTypes Array of mime types or regex pattern to check. - * @return bool Success - * @throws \RuntimeException when mime type can not be determined. - * @throws \LogicException when ext/fileinfo is missing - */ - public static function mimeType($check, $mimeTypes = []) - { - $file = static::getFilename($check); - if ($file === false) { - return false; - } - - if (!function_exists('finfo_open')) { - throw new LogicException('ext/fileinfo is required for validating file mime types'); - } - - if (!is_file($file)) { - throw new RuntimeException('Cannot validate mimetype for a missing file'); - } - - $finfo = finfo_open(FILEINFO_MIME); - $finfo = finfo_file($finfo, $file); - - if (!$finfo) { - throw new RuntimeException('Can not determine the mimetype.'); - } - - list($mime) = explode(';', $finfo); - - if (is_string($mimeTypes)) { - return self::_check($mime, $mimeTypes); - } - - foreach ($mimeTypes as $key => $val) { - $mimeTypes[$key] = strtolower($val); - } - - return in_array($mime, $mimeTypes); - } - - /** - * Helper for reading the file out of the various file implementations - * we accept. - * - * @param string|array|\Psr\Http\Message\UploadedFileInterface $check The data to read a filename out of. - * @return string|bool Either the filename or false on failure. - */ - protected static function getFilename($check) - { - if ($check instanceof UploadedFileInterface) { - try { - // Uploaded files throw exceptions on upload errors. - return $check->getStream()->getMetadata('uri'); - } catch (RuntimeException $e) { - return false; - } - } - if (is_array($check) && isset($check['tmp_name'])) { - return $check['tmp_name']; - } - - if (is_string($check)) { - return $check; - } - - return false; - } - - /** - * Checks the filesize - * - * Will check the filesize of files/UploadedFileInterface instances - * by checking the filesize() on disk and not relying on the length - * reported by the client. - * - * @param string|array|\Psr\Http\Message\UploadedFileInterface $check Value to check. - * @param string|null $operator See `Validation::comparison()`. - * @param int|string|null $size Size in bytes or human readable string like '5MB'. - * @return bool Success - */ - public static function fileSize($check, $operator = null, $size = null) - { - $file = static::getFilename($check); - if ($file === false) { - return false; - } - - if (is_string($size)) { - $size = Text::parseFileSize($size); - } - $filesize = filesize($file); - - return static::comparison($filesize, $operator, $size); - } - - /** - * Checking for upload errors - * - * @param string|array|\Psr\Http\Message\UploadedFileInterface $check Value to check. - * @param bool $allowNoFile Set to true to allow UPLOAD_ERR_NO_FILE as a pass. - * @return bool - * @see https://secure.php.net/manual/en/features.file-upload.errors.php - */ - public static function uploadError($check, $allowNoFile = false) - { - if ($check instanceof UploadedFileInterface) { - $code = $check->getError(); - } elseif (is_array($check) && isset($check['error'])) { - $code = $check['error']; - } else { - $code = $check; - } - if ($allowNoFile) { - return in_array((int)$code, [UPLOAD_ERR_OK, UPLOAD_ERR_NO_FILE], true); - } - - return (int)$code === UPLOAD_ERR_OK; - } - - /** - * Validate an uploaded file. - * - * Helps join `uploadError`, `fileSize` and `mimeType` into - * one higher level validation method. - * - * ### Options - * - * - `types` - An array of valid mime types. If empty all types - * will be accepted. The `type` will not be looked at, instead - * the file type will be checked with ext/finfo. - * - `minSize` - The minimum file size in bytes. Defaults to not checking. - * - `maxSize` - The maximum file size in bytes. Defaults to not checking. - * - `optional` - Whether or not this file is optional. Defaults to false. - * If true a missing file will pass the validator regardless of other constraints. - * - * @param array $file The uploaded file data from PHP. - * @param array $options An array of options for the validation. - * @return bool - */ - public static function uploadedFile($file, array $options = []) - { - $options += [ - 'minSize' => null, - 'maxSize' => null, - 'types' => null, - 'optional' => false, - ]; - if (!is_array($file) && !($file instanceof UploadedFileInterface)) { - return false; - } - $error = $isUploaded = false; - if ($file instanceof UploadedFileInterface) { - $error = $file->getError(); - $isUploaded = true; - } - if (is_array($file)) { - $keys = ['error', 'name', 'size', 'tmp_name', 'type']; - ksort($file); - if (array_keys($file) != $keys) { - return false; - } - $error = (int)$file['error']; - $isUploaded = is_uploaded_file($file['tmp_name']); - } - - if (!static::uploadError($file, $options['optional'])) { - return false; - } - if ($options['optional'] && $error === UPLOAD_ERR_NO_FILE) { - return true; - } - if (isset($options['minSize']) && !static::fileSize($file, static::COMPARE_GREATER_OR_EQUAL, $options['minSize'])) { - return false; - } - if (isset($options['maxSize']) && !static::fileSize($file, static::COMPARE_LESS_OR_EQUAL, $options['maxSize'])) { - return false; - } - if (isset($options['types']) && !static::mimeType($file, $options['types'])) { - return false; - } - - return $isUploaded; - } - - /** - * Validates the size of an uploaded image. - * - * @param array $file The uploaded file data from PHP. - * @param array $options Options to validate width and height. - * @return bool - */ - public static function imageSize($file, $options) - { - if (!isset($options['height']) && !isset($options['width'])) { - throw new InvalidArgumentException('Invalid image size validation parameters! Missing `width` and / or `height`.'); - } - - if ($file instanceof UploadedFileInterface) { - $file = $file->getStream()->getContents(); - } elseif (is_array($file) && isset($file['tmp_name'])) { - $file = $file['tmp_name']; - } - - list($width, $height) = getimagesize($file); - - if (isset($options['height'])) { - $validHeight = self::comparison($height, $options['height'][0], $options['height'][1]); - } - if (isset($options['width'])) { - $validWidth = self::comparison($width, $options['width'][0], $options['width'][1]); - } - if (isset($validHeight, $validWidth)) { - return ($validHeight && $validWidth); - } - if (isset($validHeight)) { - return $validHeight; - } - if (isset($validWidth)) { - return $validWidth; - } - - throw new InvalidArgumentException('The 2nd argument is missing the `width` and / or `height` options.'); - } - - /** - * Validates the image width. - * - * @param array $file The uploaded file data from PHP. - * @param string $operator Comparision operator. - * @param int $width Min or max width. - * @return bool - */ - public static function imageWidth($file, $operator, $width) - { - return self::imageSize($file, [ - 'width' => [ - $operator, - $width - ] - ]); - } - - /** - * Validates the image width. - * - * @param array $file The uploaded file data from PHP. - * @param string $operator Comparision operator. - * @param int $height Min or max width. - * @return bool - */ - public static function imageHeight($file, $operator, $height) - { - return self::imageSize($file, [ - 'height' => [ - $operator, - $height - ] - ]); - } - - /** - * Validates a geographic coordinate. - * - * Supported formats: - * - * - `, ` Example: `-25.274398, 133.775136` - * - * ### Options - * - * - `type` - A string of the coordinate format, right now only `latLong`. - * - `format` - By default `both`, can be `long` and `lat` as well to validate - * only a part of the coordinate. - * - * @param string $value Geographic location as string - * @param array $options Options for the validation logic. - * @return bool - */ - public static function geoCoordinate($value, array $options = []) - { - $options += [ - 'format' => 'both', - 'type' => 'latLong' - ]; - if ($options['type'] !== 'latLong') { - throw new RuntimeException(sprintf( - 'Unsupported coordinate type "%s". Use "latLong" instead.', - $options['type'] - )); - } - $pattern = '/^' . self::$_pattern['latitude'] . ',\s*' . self::$_pattern['longitude'] . '$/'; - if ($options['format'] === 'long') { - $pattern = '/^' . self::$_pattern['longitude'] . '$/'; - } - if ($options['format'] === 'lat') { - $pattern = '/^' . self::$_pattern['latitude'] . '$/'; - } - - return (bool)preg_match($pattern, $value); - } - - /** - * Convenience method for latitude validation. - * - * @param string $value Latitude as string - * @param array $options Options for the validation logic. - * @return bool - * @link https://en.wikipedia.org/wiki/Latitude - * @see \Cake\Validation\Validation::geoCoordinate() - */ - public static function latitude($value, array $options = []) - { - $options['format'] = 'lat'; - - return self::geoCoordinate($value, $options); - } - - /** - * Convenience method for longitude validation. - * - * @param string $value Latitude as string - * @param array $options Options for the validation logic. - * @return bool - * @link https://en.wikipedia.org/wiki/Longitude - * @see \Cake\Validation\Validation::geoCoordinate() - */ - public static function longitude($value, array $options = []) - { - $options['format'] = 'long'; - - return self::geoCoordinate($value, $options); - } - - /** - * Check that the input value is within the ascii byte range. - * - * This method will reject all non-string values. - * - * @param string $value The value to check - * @return bool - */ - public static function ascii($value) - { - if (!is_string($value)) { - return false; - } - - return strlen($value) <= mb_strlen($value, 'utf-8'); - } - - /** - * Check that the input value is a utf8 string. - * - * This method will reject all non-string values. - * - * # Options - * - * - `extended` - Disallow bytes higher within the basic multilingual plane. - * MySQL's older utf8 encoding type does not allow characters above - * the basic multilingual plane. Defaults to false. - * - * @param string $value The value to check - * @param array $options An array of options. See above for the supported options. - * @return bool - */ - public static function utf8($value, array $options = []) - { - if (!is_string($value)) { - return false; - } - $options += ['extended' => false]; - if ($options['extended']) { - return true; - } - - return preg_match('/[\x{10000}-\x{10FFFF}]/u', $value) === 0; - } - - /** - * Check that the input value is an integer - * - * This method will accept strings that contain only integer data - * as well. - * - * @param string $value The value to check - * @return bool - */ - public static function isInteger($value) - { - if (!is_scalar($value) || is_float($value)) { - return false; - } - if (is_int($value)) { - return true; - } - - return (bool)preg_match('/^-?[0-9]+$/', $value); - } - - /** - * Check that the input value is an array. - * - * @param array $value The value to check - * @return bool - */ - public static function isArray($value) - { - return is_array($value); - } - - /** - * Check that the input value is a scalar. - * - * This method will accept integers, floats, strings and booleans, but - * not accept arrays, objects, resources and nulls. - * - * @param mixed $value The value to check - * @return bool - */ - public static function isScalar($value) - { - return is_scalar($value); - } - - /** - * Check that the input value is a 6 digits hex color. - * - * @param string|array $check The value to check - * @return bool Success - */ - public static function hexColor($check) - { - return static::_check($check, '/^#[0-9a-f]{6}$/iD'); - } - - /** - * Converts an array representing a date or datetime into a ISO string. - * The arrays are typically sent for validation from a form generated by - * the CakePHP FormHelper. - * - * @param array $value The array representing a date or datetime. - * @return string - */ - protected static function _getDateString($value) - { - $formatted = ''; - if (isset($value['year'], $value['month'], $value['day']) && - (is_numeric($value['year']) && is_numeric($value['month']) && is_numeric($value['day'])) - ) { - $formatted .= sprintf('%d-%02d-%02d ', $value['year'], $value['month'], $value['day']); - } - - if (isset($value['hour'])) { - if (isset($value['meridian']) && (int)$value['hour'] === 12) { - $value['hour'] = 0; - } - if (isset($value['meridian'])) { - $value['hour'] = strtolower($value['meridian']) === 'am' ? $value['hour'] : $value['hour'] + 12; - } - $value += ['minute' => 0, 'second' => 0]; - if (is_numeric($value['hour']) && is_numeric($value['minute']) && is_numeric($value['second'])) { - $formatted .= sprintf('%02d:%02d:%02d', $value['hour'], $value['minute'], $value['second']); - } - } - - return trim($formatted); - } - - /** - * Lazily populate the IP address patterns used for validations - * - * @return void - */ - protected static function _populateIp() - { - if (!isset(static::$_pattern['IPv6'])) { - $pattern = '((([0-9A-Fa-f]{1,4}:){7}(([0-9A-Fa-f]{1,4})|:))|(([0-9A-Fa-f]{1,4}:){6}'; - $pattern .= '(:|((25[0-5]|2[0-4]\d|[01]?\d{1,2})(\.(25[0-5]|2[0-4]\d|[01]?\d{1,2})){3})'; - $pattern .= '|(:[0-9A-Fa-f]{1,4})))|(([0-9A-Fa-f]{1,4}:){5}((:((25[0-5]|2[0-4]\d|[01]?\d{1,2})'; - $pattern .= '(\.(25[0-5]|2[0-4]\d|[01]?\d{1,2})){3})?)|((:[0-9A-Fa-f]{1,4}){1,2})))|(([0-9A-Fa-f]{1,4}:)'; - $pattern .= '{4}(:[0-9A-Fa-f]{1,4}){0,1}((:((25[0-5]|2[0-4]\d|[01]?\d{1,2})(\.(25[0-5]|2[0-4]\d|[01]?\d{1,2}))'; - $pattern .= '{3})?)|((:[0-9A-Fa-f]{1,4}){1,2})))|(([0-9A-Fa-f]{1,4}:){3}(:[0-9A-Fa-f]{1,4}){0,2}'; - $pattern .= '((:((25[0-5]|2[0-4]\d|[01]?\d{1,2})(\.(25[0-5]|2[0-4]\d|[01]?\d{1,2})){3})?)|'; - $pattern .= '((:[0-9A-Fa-f]{1,4}){1,2})))|(([0-9A-Fa-f]{1,4}:){2}(:[0-9A-Fa-f]{1,4}){0,3}'; - $pattern .= '((:((25[0-5]|2[0-4]\d|[01]?\d{1,2})(\.(25[0-5]|2[0-4]\d|[01]?\d{1,2}))'; - $pattern .= '{3})?)|((:[0-9A-Fa-f]{1,4}){1,2})))|(([0-9A-Fa-f]{1,4}:)(:[0-9A-Fa-f]{1,4})'; - $pattern .= '{0,4}((:((25[0-5]|2[0-4]\d|[01]?\d{1,2})(\.(25[0-5]|2[0-4]\d|[01]?\d{1,2})){3})?)'; - $pattern .= '|((:[0-9A-Fa-f]{1,4}){1,2})))|(:(:[0-9A-Fa-f]{1,4}){0,5}((:((25[0-5]|2[0-4]'; - $pattern .= '\d|[01]?\d{1,2})(\.(25[0-5]|2[0-4]\d|[01]?\d{1,2})){3})?)|((:[0-9A-Fa-f]{1,4})'; - $pattern .= '{1,2})))|(((25[0-5]|2[0-4]\d|[01]?\d{1,2})(\.(25[0-5]|2[0-4]\d|[01]?\d{1,2})){3})))(%.+)?'; - - static::$_pattern['IPv6'] = $pattern; - } - if (!isset(static::$_pattern['IPv4'])) { - $pattern = '(?:(?:25[0-5]|2[0-4][0-9]|(?:(?:1[0-9])?|[1-9]?)[0-9])\.){3}(?:25[0-5]|2[0-4][0-9]|(?:(?:1[0-9])?|[1-9]?)[0-9])'; - static::$_pattern['IPv4'] = $pattern; - } - } - - /** - * Reset internal variables for another validation run. - * - * @return void - */ - protected static function _reset() - { - static::$errors = []; - } -} diff --git a/vendor/cakephp/cakephp/src/Validation/ValidationRule.php b/vendor/cakephp/cakephp/src/Validation/ValidationRule.php deleted file mode 100644 index e5dd4e5..0000000 --- a/vendor/cakephp/cakephp/src/Validation/ValidationRule.php +++ /dev/null @@ -1,215 +0,0 @@ -_addValidatorProps($validator); - } - - /** - * Returns whether this rule should break validation process for associated field - * after it fails - * - * @return bool - */ - public function isLast() - { - return (bool)$this->_last; - } - - /** - * Dispatches the validation rule to the given validator method and returns - * a boolean indicating whether the rule passed or not. If a string is returned - * it is assumed that the rule failed and the error message was given as a result. - * - * @param mixed $value The data to validate - * @param array $providers associative array with objects or class names that will - * be passed as the last argument for the validation method - * @param array $context A key value list of data that could be used as context - * during validation. Recognized keys are: - * - newRecord: (boolean) whether or not the data to be validated belongs to a - * new record - * - data: The full data that was passed to the validation process - * - field: The name of the field that is being processed - * @return bool|string - * @throws \InvalidArgumentException when the supplied rule is not a valid - * callable for the configured scope - */ - public function process($value, array $providers, array $context = []) - { - $context += ['data' => [], 'newRecord' => true, 'providers' => $providers]; - - if ($this->_skip($context)) { - return true; - } - - if (!is_string($this->_rule) && is_callable($this->_rule)) { - $callable = $this->_rule; - $isCallable = true; - } else { - $provider = $providers[$this->_provider]; - $callable = [$provider, $this->_rule]; - $isCallable = is_callable($callable); - } - - if (!$isCallable) { - $message = 'Unable to call method "%s" in "%s" provider for field "%s"'; - throw new InvalidArgumentException( - sprintf($message, $this->_rule, $this->_provider, $context['field']) - ); - } - - if ($this->_pass) { - $args = array_values(array_merge([$value], $this->_pass, [$context])); - $result = $callable(...$args); - } else { - $result = $callable($value, $context); - } - - if ($result === false) { - return $this->_message ?: false; - } - - return $result; - } - - /** - * Checks if the validation rule should be skipped - * - * @param array $context A key value list of data that could be used as context - * during validation. Recognized keys are: - * - newRecord: (boolean) whether or not the data to be validated belongs to a - * new record - * - data: The full data that was passed to the validation process - * - providers associative array with objects or class names that will - * be passed as the last argument for the validation method - * @return bool True if the ValidationRule should be skipped - */ - protected function _skip($context) - { - if (!is_string($this->_on) && is_callable($this->_on)) { - $function = $this->_on; - - return !$function($context); - } - - $newRecord = $context['newRecord']; - if (!empty($this->_on)) { - if (($this->_on === 'create' && !$newRecord) || ($this->_on === 'update' && $newRecord)) { - return true; - } - } - - return false; - } - - /** - * Sets the rule properties from the rule entry in validate - * - * @param array $validator [optional] - * @return void - */ - protected function _addValidatorProps($validator = []) - { - foreach ($validator as $key => $value) { - if (!isset($value) || empty($value)) { - continue; - } - if ($key === 'rule' && is_array($value) && !is_callable($value)) { - $this->_pass = array_slice($value, 1); - $value = array_shift($value); - } - if (in_array($key, ['rule', 'on', 'message', 'last', 'provider', 'pass'])) { - $this->{"_$key"} = $value; - } - } - } - - /** - * Returns the value of a property by name - * - * @param string $property The name of the property to retrieve. - * @return mixed - */ - public function get($property) - { - $property = '_' . $property; - if (isset($this->{$property})) { - return $this->{$property}; - } - } -} diff --git a/vendor/cakephp/cakephp/src/Validation/ValidationSet.php b/vendor/cakephp/cakephp/src/Validation/ValidationSet.php deleted file mode 100644 index de4aa44..0000000 --- a/vendor/cakephp/cakephp/src/Validation/ValidationSet.php +++ /dev/null @@ -1,256 +0,0 @@ -_validatePresent; - } - - deprecationWarning( - 'ValidationSet::isPresenceRequired() is deprecated as a setter. ' . - 'Use ValidationSet::requirePresence() instead.' - ); - - return $this->requirePresence($validatePresent); - } - - /** - * Sets whether a field is required to be present in data array. - * - * @param bool|string|callable $validatePresent Valid values are true, false, 'create', 'update' or a callable. - * @return $this - */ - public function requirePresence($validatePresent) - { - $this->_validatePresent = $validatePresent; - - return $this; - } - - /** - * Sets whether a field value is allowed to be empty. - * - * If no argument is passed the currently set `allowEmpty` value will be returned. - * - * @param bool|string|callable|null $allowEmpty Deprecated since 3.6.0 ValidationSet::isEmptyAllowed() is deprecated as a setter. - * Use ValidationSet::allowEmpty() instead. - * @return bool|string|callable - */ - public function isEmptyAllowed($allowEmpty = null) - { - if ($allowEmpty === null) { - return $this->_allowEmpty; - } - - deprecationWarning( - 'ValidationSet::isEmptyAllowed() is deprecated as a setter. ' . - 'Use ValidationSet::allowEmpty() instead.' - ); - - return $this->allowEmpty($allowEmpty); - } - - /** - * Sets whether a field value is allowed to be empty. - * - * @param bool|string|callable $allowEmpty Valid values are true, false, - * 'create', 'update' or a callable. - * @return $this - */ - public function allowEmpty($allowEmpty) - { - $this->_allowEmpty = $allowEmpty; - - return $this; - } - - /** - * Gets a rule for a given name if exists - * - * @param string $name The name under which the rule is set. - * @return \Cake\Validation\ValidationRule|null - */ - public function rule($name) - { - if (!empty($this->_rules[$name])) { - return $this->_rules[$name]; - } - } - - /** - * Returns all rules for this validation set - * - * @return \Cake\Validation\ValidationRule[] - */ - public function rules() - { - return $this->_rules; - } - - /** - * Sets a ValidationRule $rule with a $name - * - * ### Example: - * - * ``` - * $set - * ->add('notBlank', ['rule' => 'notBlank']) - * ->add('inRange', ['rule' => ['between', 4, 10]) - * ``` - * - * @param string $name The name under which the rule should be set - * @param \Cake\Validation\ValidationRule|array $rule The validation rule to be set - * @return $this - */ - public function add($name, $rule) - { - if (!($rule instanceof ValidationRule)) { - $rule = new ValidationRule($rule); - } - $this->_rules[$name] = $rule; - - return $this; - } - - /** - * Removes a validation rule from the set - * - * ### Example: - * - * ``` - * $set - * ->remove('notBlank') - * ->remove('inRange') - * ``` - * - * @param string $name The name under which the rule should be unset - * @return $this - */ - public function remove($name) - { - unset($this->_rules[$name]); - - return $this; - } - - /** - * Returns whether an index exists in the rule set - * - * @param string $index name of the rule - * @return bool - */ - public function offsetExists($index) - { - return isset($this->_rules[$index]); - } - - /** - * Returns a rule object by its index - * - * @param string $index name of the rule - * @return \Cake\Validation\ValidationRule - */ - public function offsetGet($index) - { - return $this->_rules[$index]; - } - - /** - * Sets or replace a validation rule - * - * @param string $index name of the rule - * @param \Cake\Validation\ValidationRule|array $rule Rule to add to $index - * @return void - */ - public function offsetSet($index, $rule) - { - $this->add($index, $rule); - } - - /** - * Unsets a validation rule - * - * @param string $index name of the rule - * @return void - */ - public function offsetUnset($index) - { - unset($this->_rules[$index]); - } - - /** - * Returns an iterator for each of the rules to be applied - * - * @return \ArrayIterator - */ - public function getIterator() - { - return new ArrayIterator($this->_rules); - } - - /** - * Returns the number of rules in this set - * - * @return int - */ - public function count() - { - return count($this->_rules); - } -} diff --git a/vendor/cakephp/cakephp/src/Validation/Validator.php b/vendor/cakephp/cakephp/src/Validation/Validator.php deleted file mode 100644 index 77f6b76..0000000 --- a/vendor/cakephp/cakephp/src/Validation/Validator.php +++ /dev/null @@ -1,2102 +0,0 @@ -_useI18n = function_exists('__d'); - $this->_providers = self::$_defaultProviders; - } - - /** - * Returns an array of fields that have failed validation. On the current model. This method will - * actually run validation rules over data, not just return the messages. - * - * @param array $data The data to be checked for errors - * @param bool $newRecord whether the data to be validated is new or to be updated. - * @return array Array of invalid fields - */ - public function errors(array $data, $newRecord = true) - { - $errors = []; - - $requiredMessage = 'This field is required'; - $emptyMessage = 'This field cannot be left empty'; - - if ($this->_useI18n) { - $requiredMessage = __d('cake', 'This field is required'); - $emptyMessage = __d('cake', 'This field cannot be left empty'); - } - - foreach ($this->_fields as $name => $field) { - $keyPresent = array_key_exists($name, $data); - - $providers = $this->_providers; - $context = compact('data', 'newRecord', 'field', 'providers'); - - if (!$keyPresent && !$this->_checkPresence($field, $context)) { - $errors[$name]['_required'] = isset($this->_presenceMessages[$name]) - ? $this->_presenceMessages[$name] - : $requiredMessage; - continue; - } - if (!$keyPresent) { - continue; - } - - $canBeEmpty = $this->_canBeEmpty($field, $context); - $isEmpty = $this->_fieldIsEmpty($data[$name]); - - if (!$canBeEmpty && $isEmpty) { - $errors[$name]['_empty'] = isset($this->_allowEmptyMessages[$name]) - ? $this->_allowEmptyMessages[$name] - : $emptyMessage; - continue; - } - - if ($isEmpty) { - continue; - } - - $result = $this->_processRules($name, $field, $data, $newRecord); - if ($result) { - $errors[$name] = $result; - } - } - - return $errors; - } - - /** - * Returns a ValidationSet object containing all validation rules for a field, if - * passed a ValidationSet as second argument, it will replace any other rule set defined - * before - * - * @param string $name [optional] The fieldname to fetch. - * @param \Cake\Validation\ValidationSet|null $set The set of rules for field - * @return \Cake\Validation\ValidationSet - */ - public function field($name, ValidationSet $set = null) - { - if (empty($this->_fields[$name])) { - $set = $set ?: new ValidationSet(); - $this->_fields[$name] = $set; - } - - return $this->_fields[$name]; - } - - /** - * Check whether or not a validator contains any rules for the given field. - * - * @param string $name The field name to check. - * @return bool - */ - public function hasField($name) - { - return isset($this->_fields[$name]); - } - - /** - * Associates an object to a name so it can be used as a provider. Providers are - * objects or class names that can contain methods used during validation of for - * deciding whether a validation rule can be applied. All validation methods, - * when called will receive the full list of providers stored in this validator. - * - * @param string $name The name under which the provider should be set. - * @param object|string $object Provider object or class name. - * @return $this - */ - public function setProvider($name, $object) - { - $this->_providers[$name] = $object; - - return $this; - } - - /** - * Returns the provider stored under that name if it exists. - * - * @param string $name The name under which the provider should be set. - * @return object|string|null - */ - public function getProvider($name) - { - if (isset($this->_providers[$name])) { - return $this->_providers[$name]; - } - if ($name !== 'default') { - return null; - } - - $this->_providers[$name] = new RulesProvider(); - - return $this->_providers[$name]; - } - - /** - * Returns the default provider stored under that name if it exists. - * - * @param string $name The name under which the provider should be retrieved. - * @return object|string|null - */ - public static function getDefaultProvider($name) - { - if (!isset(self::$_defaultProviders[$name])) { - return null; - } - - return self::$_defaultProviders[$name]; - } - - /** - * Associates an object to a name so it can be used as a default provider. - * - * @param string $name The name under which the provider should be set. - * @param object|string $object Provider object or class name. - * @return void - */ - public static function addDefaultProvider($name, $object) - { - self::$_defaultProviders[$name] = $object; - } - - /** - * Get the list of default providers. - * - * @return array - */ - public static function getDefaultProviders() - { - return array_keys(self::$_defaultProviders); - } - - /** - * Associates an object to a name so it can be used as a provider. Providers are - * objects or class names that can contain methods used during validation of for - * deciding whether a validation rule can be applied. All validation methods, - * when called will receive the full list of providers stored in this validator. - * - * If called with no arguments, it will return the provider stored under that name if - * it exists, otherwise it returns this instance of chaining. - * - * @deprecated 3.4.0 Use setProvider()/getProvider() instead. - * @param string $name The name under which the provider should be set. - * @param null|object|string $object Provider object or class name. - * @return $this|object|string|null - */ - public function provider($name, $object = null) - { - deprecationWarning( - 'Validator::provider() is deprecated. ' . - 'Use Validator::setProvider()/getProvider() instead.' - ); - if ($object !== null) { - return $this->setProvider($name, $object); - } - - return $this->getProvider($name); - } - - /** - * Get the list of providers in this validator. - * - * @return array - */ - public function providers() - { - return array_keys($this->_providers); - } - - /** - * Returns whether a rule set is defined for a field or not - * - * @param string $field name of the field to check - * @return bool - */ - public function offsetExists($field) - { - return isset($this->_fields[$field]); - } - - /** - * Returns the rule set for a field - * - * @param string $field name of the field to check - * @return \Cake\Validation\ValidationSet - */ - public function offsetGet($field) - { - return $this->field($field); - } - - /** - * Sets the rule set for a field - * - * @param string $field name of the field to set - * @param array|\Cake\Validation\ValidationSet $rules set of rules to apply to field - * @return void - */ - public function offsetSet($field, $rules) - { - if (!$rules instanceof ValidationSet) { - $set = new ValidationSet(); - foreach ((array)$rules as $name => $rule) { - $set->add($name, $rule); - } - } - $this->_fields[$field] = $rules; - } - - /** - * Unsets the rule set for a field - * - * @param string $field name of the field to unset - * @return void - */ - public function offsetUnset($field) - { - unset($this->_fields[$field]); - } - - /** - * Returns an iterator for each of the fields to be validated - * - * @return \ArrayIterator - */ - public function getIterator() - { - return new ArrayIterator($this->_fields); - } - - /** - * Returns the number of fields having validation rules - * - * @return int - */ - public function count() - { - return count($this->_fields); - } - - /** - * Adds a new rule to a field's rule set. If second argument is an array - * then rules list for the field will be replaced with second argument and - * third argument will be ignored. - * - * ### Example: - * - * ``` - * $validator - * ->add('title', 'required', ['rule' => 'notBlank']) - * ->add('user_id', 'valid', ['rule' => 'numeric', 'message' => 'Invalid User']) - * - * $validator->add('password', [ - * 'size' => ['rule' => ['lengthBetween', 8, 20]], - * 'hasSpecialCharacter' => ['rule' => 'validateSpecialchar', 'message' => 'not valid'] - * ]); - * ``` - * - * @param string $field The name of the field from which the rule will be added - * @param array|string $name The alias for a single rule or multiple rules array - * @param array|\Cake\Validation\ValidationRule $rule the rule to add - * @return $this - */ - public function add($field, $name, $rule = []) - { - $field = $this->field($field); - - if (!is_array($name)) { - $rules = [$name => $rule]; - } else { - $rules = $name; - } - - foreach ($rules as $name => $rule) { - if (is_array($rule)) { - $rule += ['rule' => $name]; - } - $field->add($name, $rule); - } - - return $this; - } - - /** - * Adds a nested validator. - * - * Nesting validators allows you to define validators for array - * types. For example, nested validators are ideal when you want to validate a - * sub-document, or complex array type. - * - * This method assumes that the sub-document has a 1:1 relationship with the parent. - * - * The providers of the parent validator will be synced into the nested validator, when - * errors are checked. This ensures that any validation rule providers connected - * in the parent will have the same values in the nested validator when rules are evaluated. - * - * @param string $field The root field for the nested validator. - * @param \Cake\Validation\Validator $validator The nested validator. - * @param string|null $message The error message when the rule fails. - * @param string|callable|null $when Either 'create' or 'update' or a callable that returns - * true when the validation rule should be applied. - * @return $this - */ - public function addNested($field, Validator $validator, $message = null, $when = null) - { - $extra = array_filter(['message' => $message, 'on' => $when]); - - $field = $this->field($field); - $field->add(static::NESTED, $extra + ['rule' => function ($value, $context) use ($validator, $message) { - if (!is_array($value)) { - return false; - } - foreach ($this->providers() as $provider) { - $validator->setProvider($provider, $this->getProvider($provider)); - } - $errors = $validator->errors($value, $context['newRecord']); - - $message = $message ? [static::NESTED => $message] : []; - - return empty($errors) ? true : $errors + $message; - }]); - - return $this; - } - - /** - * Adds a nested validator. - * - * Nesting validators allows you to define validators for array - * types. For example, nested validators are ideal when you want to validate many - * similar sub-documents or complex array types. - * - * This method assumes that the sub-document has a 1:N relationship with the parent. - * - * The providers of the parent validator will be synced into the nested validator, when - * errors are checked. This ensures that any validation rule providers connected - * in the parent will have the same values in the nested validator when rules are evaluated. - * - * @param string $field The root field for the nested validator. - * @param \Cake\Validation\Validator $validator The nested validator. - * @param string|null $message The error message when the rule fails. - * @param string|callable|null $when Either 'create' or 'update' or a callable that returns - * true when the validation rule should be applied. - * @return $this - */ - public function addNestedMany($field, Validator $validator, $message = null, $when = null) - { - $extra = array_filter(['message' => $message, 'on' => $when]); - - $field = $this->field($field); - $field->add(static::NESTED, $extra + ['rule' => function ($value, $context) use ($validator, $message) { - if (!is_array($value)) { - return false; - } - foreach ($this->providers() as $provider) { - $validator->setProvider($provider, $this->getProvider($provider)); - } - $errors = []; - foreach ($value as $i => $row) { - if (!is_array($row)) { - return false; - } - $check = $validator->errors($row, $context['newRecord']); - if (!empty($check)) { - $errors[$i] = $check; - } - } - - $message = $message ? [static::NESTED => $message] : []; - - return empty($errors) ? true : $errors + $message; - }]); - - return $this; - } - - /** - * Removes a rule from the set by its name - * - * ### Example: - * - * ``` - * $validator - * ->remove('title', 'required') - * ->remove('user_id') - * ``` - * - * @param string $field The name of the field from which the rule will be removed - * @param string|null $rule the name of the rule to be removed - * @return $this - */ - public function remove($field, $rule = null) - { - if ($rule === null) { - unset($this->_fields[$field]); - } else { - $this->field($field)->remove($rule); - } - - return $this; - } - - /** - * Sets whether a field is required to be present in data array. - * You can also pass array. Using an array will let you provide the following - * keys: - * - * - `mode` individual mode for field - * - `message` individual error message for field - * - * You can also set mode and message for all passed fields, the individual - * setting takes precedence over group settings. - * - * @param string|array $field the name of the field or list of fields. - * @param bool|string|callable $mode Valid values are true, false, 'create', 'update'. - * If a callable is passed then the field will be required only when the callback - * returns true. - * @param string|null $message The message to show if the field presence validation fails. - * @return $this - */ - public function requirePresence($field, $mode = true, $message = null) - { - $defaults = [ - 'mode' => $mode, - 'message' => $message - ]; - - if (!is_array($field)) { - $field = $this->_convertValidatorToArray($field, $defaults); - } - - foreach ($field as $fieldName => $setting) { - $settings = $this->_convertValidatorToArray($fieldName, $defaults, $setting); - $fieldName = current(array_keys($settings)); - - $this->field($fieldName)->requirePresence($settings[$fieldName]['mode']); - if ($settings[$fieldName]['message']) { - $this->_presenceMessages[$fieldName] = $settings[$fieldName]['message']; - } - } - - return $this; - } - - /** - * Allows a field to be empty. You can also pass array. - * Using an array will let you provide the following keys: - * - * - `when` individual when condition for field - * - 'message' individual message for field - * - * You can also set when and message for all passed fields, the individual setting - * takes precedence over group settings. - * - * This is the opposite of notEmpty() which requires a field to not be empty. - * By using $mode equal to 'create' or 'update', you can allow fields to be empty - * when records are first created, or when they are updated. - * - * ### Example: - * - * ``` - * // Email can be empty - * $validator->allowEmpty('email'); - * - * // Email can be empty on create - * $validator->allowEmpty('email', 'create'); - * - * // Email can be empty on update - * $validator->allowEmpty('email', 'update'); - * - * // Email and subject can be empty on update - * $validator->allowEmpty(['email', 'subject'], 'update'); - * - * // Email can be always empty, subject and content can be empty on update. - * $validator->allowEmpty( - * [ - * 'email' => [ - * 'when' => true - * ], - * 'content' => [ - * 'message' => 'Content cannot be empty' - * ], - * 'subject' - * ], - * 'update' - * ); - * ``` - * - * It is possible to conditionally allow emptiness on a field by passing a callback - * as a second argument. The callback will receive the validation context array as - * argument: - * - * ``` - * $validator->allowEmpty('email', function ($context) { - * return !$context['newRecord'] || $context['data']['role'] === 'admin'; - * }); - * ``` - * - * This method will correctly detect empty file uploads and date/time/datetime fields. - * - * Because this and `notEmpty()` modify the same internal state, the last - * method called will take precedence. - * - * @param string|array $field the name of the field or a list of fields - * @param bool|string|callable $when Indicates when the field is allowed to be empty - * Valid values are true (always), 'create', 'update'. If a callable is passed then - * the field will allowed to be empty only when the callback returns true. - * @param string|null $message The message to show if the field is not - * @return $this - */ - public function allowEmpty($field, $when = true, $message = null) - { - $settingsDefault = [ - 'when' => $when, - 'message' => $message - ]; - - if (!is_array($field)) { - $field = $this->_convertValidatorToArray($field, $settingsDefault); - } - - foreach ($field as $fieldName => $setting) { - $settings = $this->_convertValidatorToArray($fieldName, $settingsDefault, $setting); - $fieldName = current(array_keys($settings)); - - $this->field($fieldName)->allowEmpty($settings[$fieldName]['when']); - if ($settings[$fieldName]['message']) { - $this->_allowEmptyMessages[$fieldName] = $settings[$fieldName]['message']; - } - } - - return $this; - } - - /** - * Converts validator to fieldName => $settings array - * - * @param int|string $fieldName name of field - * @param array $defaults default settings - * @param string|array $settings settings from data - * @return array - */ - protected function _convertValidatorToArray($fieldName, $defaults = [], $settings = []) - { - if (is_string($settings)) { - $fieldName = $settings; - $settings = []; - } - if (!is_array($settings)) { - throw new InvalidArgumentException( - sprintf('Invalid settings for "%s". Settings must be an array.', $fieldName) - ); - } - $settings += $defaults; - - return [$fieldName => $settings]; - } - - /** - * Sets a field to require a non-empty value. You can also pass array. - * Using an array will let you provide the following keys: - * - * - `when` individual when condition for field - * - `message` individual error message for field - * - * You can also set `when` and `message` for all passed fields, the individual setting - * takes precedence over group settings. - * - * This is the opposite of `allowEmpty()` which allows a field to be empty. - * By using $mode equal to 'create' or 'update', you can make fields required - * when records are first created, or when they are updated. - * - * ### Example: - * - * ``` - * $message = 'This field cannot be empty'; - * - * // Email cannot be empty - * $validator->notEmpty('email'); - * - * // Email can be empty on update, but not create - * $validator->notEmpty('email', $message, 'create'); - * - * // Email can be empty on create, but required on update. - * $validator->notEmpty('email', $message, 'update'); - * - * // Email and title can be empty on create, but are required on update. - * $validator->notEmpty(['email', 'title'], $message, 'update'); - * - * // Email can be empty on create, title must always be not empty - * $validator->notEmpty( - * [ - * 'email', - * 'title' => [ - * 'when' => true, - * 'message' => 'Title cannot be empty' - * ] - * ], - * $message, - * 'update' - * ); - * ``` - * - * It is possible to conditionally disallow emptiness on a field by passing a callback - * as the third argument. The callback will receive the validation context array as - * argument: - * - * ``` - * $validator->notEmpty('email', 'Email is required', function ($context) { - * return $context['newRecord'] && $context['data']['role'] !== 'admin'; - * }); - * ``` - * - * Because this and `allowEmpty()` modify the same internal state, the last - * method called will take precedence. - * - * @param string|array $field the name of the field or list of fields - * @param string|null $message The message to show if the field is not - * @param bool|string|callable $when Indicates when the field is not allowed - * to be empty. Valid values are true (always), 'create', 'update'. If a - * callable is passed then the field will allowed to be empty only when - * the callback returns false. - * @return $this - */ - public function notEmpty($field, $message = null, $when = false) - { - $defaults = [ - 'when' => $when, - 'message' => $message - ]; - - if (!is_array($field)) { - $field = $this->_convertValidatorToArray($field, $defaults); - } - - foreach ($field as $fieldName => $setting) { - $settings = $this->_convertValidatorToArray($fieldName, $defaults, $setting); - $fieldName = current(array_keys($settings)); - $whenSetting = $settings[$fieldName]['when']; - - if ($whenSetting === 'create' || $whenSetting === 'update') { - $whenSetting = $whenSetting === 'create' ? 'update' : 'create'; - } elseif (is_callable($whenSetting)) { - $whenSetting = function ($context) use ($whenSetting) { - return !$whenSetting($context); - }; - } - - $this->field($fieldName)->allowEmpty($whenSetting); - if ($settings[$fieldName]['message']) { - $this->_allowEmptyMessages[$fieldName] = $settings[$fieldName]['message']; - } - } - - return $this; - } - - /** - * Add a notBlank rule to a field. - * - * @param string $field The field you want to apply the rule to. - * @param string|null $message The error message when the rule fails. - * @param string|callable|null $when Either 'create' or 'update' or a callable that returns - * true when the validation rule should be applied. - * @see \Cake\Validation\Validation::notBlank() - * @return $this - */ - public function notBlank($field, $message = null, $when = null) - { - $extra = array_filter(['on' => $when, 'message' => $message]); - - return $this->add($field, 'notBlank', $extra + [ - 'rule' => 'notBlank', - ]); - } - - /** - * Add an alphanumeric rule to a field. - * - * @param string $field The field you want to apply the rule to. - * @param string|null $message The error message when the rule fails. - * @param string|callable|null $when Either 'create' or 'update' or a callable that returns - * true when the validation rule should be applied. - * @see \Cake\Validation\Validation::alphaNumeric() - * @return $this - */ - public function alphaNumeric($field, $message = null, $when = null) - { - $extra = array_filter(['on' => $when, 'message' => $message]); - - return $this->add($field, 'alphaNumeric', $extra + [ - 'rule' => 'alphaNumeric', - ]); - } - - /** - * Add an rule that ensures a string length is within a range. - * - * @param string $field The field you want to apply the rule to. - * @param array $range The inclusive minimum and maximum length you want permitted. - * @param string|null $message The error message when the rule fails. - * @param string|callable|null $when Either 'create' or 'update' or a callable that returns - * true when the validation rule should be applied. - * @see \Cake\Validation\Validation::alphaNumeric() - * @return $this - */ - public function lengthBetween($field, array $range, $message = null, $when = null) - { - if (count($range) !== 2) { - throw new InvalidArgumentException('The $range argument requires 2 numbers'); - } - $extra = array_filter(['on' => $when, 'message' => $message]); - - return $this->add($field, 'lengthBetween', $extra + [ - 'rule' => ['lengthBetween', array_shift($range), array_shift($range)], - ]); - } - - /** - * Add a credit card rule to a field. - * - * @param string $field The field you want to apply the rule to. - * @param string $type The type of cards you want to allow. Defaults to 'all'. - * You can also supply an array of accepted card types. e.g `['mastercard', 'visa', 'amex']` - * @param string|null $message The error message when the rule fails. - * @param string|callable|null $when Either 'create' or 'update' or a callable that returns - * true when the validation rule should be applied. - * @see \Cake\Validation\Validation::cc() - * @return $this - */ - public function creditCard($field, $type = 'all', $message = null, $when = null) - { - $extra = array_filter(['on' => $when, 'message' => $message]); - - return $this->add($field, 'creditCard', $extra + [ - 'rule' => ['cc', $type, true], - ]); - } - - /** - * Add a greater than comparison rule to a field. - * - * @param string $field The field you want to apply the rule to. - * @param int|float $value The value user data must be greater than. - * @param string|null $message The error message when the rule fails. - * @param string|callable|null $when Either 'create' or 'update' or a callable that returns - * true when the validation rule should be applied. - * @see \Cake\Validation\Validation::comparison() - * @return $this - */ - public function greaterThan($field, $value, $message = null, $when = null) - { - $extra = array_filter(['on' => $when, 'message' => $message]); - - return $this->add($field, 'greaterThan', $extra + [ - 'rule' => ['comparison', Validation::COMPARE_GREATER, $value] - ]); - } - - /** - * Add a greater than or equal to comparison rule to a field. - * - * @param string $field The field you want to apply the rule to. - * @param int|float $value The value user data must be greater than or equal to. - * @param string|null $message The error message when the rule fails. - * @param string|callable|null $when Either 'create' or 'update' or a callable that returns - * true when the validation rule should be applied. - * @see \Cake\Validation\Validation::comparison() - * @return $this - */ - public function greaterThanOrEqual($field, $value, $message = null, $when = null) - { - $extra = array_filter(['on' => $when, 'message' => $message]); - - return $this->add($field, 'greaterThanOrEqual', $extra + [ - 'rule' => ['comparison', Validation::COMPARE_GREATER_OR_EQUAL, $value] - ]); - } - - /** - * Add a less than comparison rule to a field. - * - * @param string $field The field you want to apply the rule to. - * @param int|float $value The value user data must be less than. - * @param string|null $message The error message when the rule fails. - * @param string|callable|null $when Either 'create' or 'update' or a callable that returns - * true when the validation rule should be applied. - * @see \Cake\Validation\Validation::comparison() - * @return $this - */ - public function lessThan($field, $value, $message = null, $when = null) - { - $extra = array_filter(['on' => $when, 'message' => $message]); - - return $this->add($field, 'lessThan', $extra + [ - 'rule' => ['comparison', Validation::COMPARE_LESS, $value] - ]); - } - - /** - * Add a less than or equal comparison rule to a field. - * - * @param string $field The field you want to apply the rule to. - * @param int|float $value The value user data must be less than or equal to. - * @param string|null $message The error message when the rule fails. - * @param string|callable|null $when Either 'create' or 'update' or a callable that returns - * true when the validation rule should be applied. - * @see \Cake\Validation\Validation::comparison() - * @return $this - */ - public function lessThanOrEqual($field, $value, $message = null, $when = null) - { - $extra = array_filter(['on' => $when, 'message' => $message]); - - return $this->add($field, 'lessThanOrEqual', $extra + [ - 'rule' => ['comparison', Validation::COMPARE_LESS_OR_EQUAL, $value] - ]); - } - - /** - * Add a equal to comparison rule to a field. - * - * @param string $field The field you want to apply the rule to. - * @param int|float $value The value user data must be equal to. - * @param string|null $message The error message when the rule fails. - * @param string|callable|null $when Either 'create' or 'update' or a callable that returns - * true when the validation rule should be applied. - * @see \Cake\Validation\Validation::comparison() - * @return $this - */ - public function equals($field, $value, $message = null, $when = null) - { - $extra = array_filter(['on' => $when, 'message' => $message]); - - return $this->add($field, 'equals', $extra + [ - 'rule' => ['comparison', Validation::COMPARE_EQUAL, $value] - ]); - } - - /** - * Add a not equal to comparison rule to a field. - * - * @param string $field The field you want to apply the rule to. - * @param int|float $value The value user data must be not be equal to. - * @param string|null $message The error message when the rule fails. - * @param string|callable|null $when Either 'create' or 'update' or a callable that returns - * true when the validation rule should be applied. - * @see \Cake\Validation\Validation::comparison() - * @return $this - */ - public function notEquals($field, $value, $message = null, $when = null) - { - $extra = array_filter(['on' => $when, 'message' => $message]); - - return $this->add($field, 'notEquals', $extra + [ - 'rule' => ['comparison', Validation::COMPARE_NOT_EQUAL, $value] - ]); - } - - /** - * Add a rule to compare two fields to each other. - * - * If both fields have the exact same value the rule will pass. - * - * @param string $field The field you want to apply the rule to. - * @param string $secondField The field you want to compare against. - * @param string|null $message The error message when the rule fails. - * @param string|callable|null $when Either 'create' or 'update' or a callable that returns - * true when the validation rule should be applied. - * @see \Cake\Validation\Validation::compareFields() - * @return $this - */ - public function sameAs($field, $secondField, $message = null, $when = null) - { - $extra = array_filter(['on' => $when, 'message' => $message]); - - return $this->add($field, 'sameAs', $extra + [ - 'rule' => ['compareFields', $secondField, Validation::COMPARE_SAME] - ]); - } - - /** - * Add a rule to compare that two fields have different values. - * - * @param string $field The field you want to apply the rule to. - * @param string $secondField The field you want to compare against. - * @param string|null $message The error message when the rule fails. - * @param string|callable|null $when Either 'create' or 'update' or a callable that returns - * true when the validation rule should be applied. - * @see \Cake\Validation\Validation::compareFields() - * @return $this - * @since 3.6.0 - */ - public function notSameAs($field, $secondField, $message = null, $when = null) - { - $extra = array_filter(['on' => $when, 'message' => $message]); - - return $this->add($field, 'notSameAs', $extra + [ - 'rule' => ['compareFields', $secondField, Validation::COMPARE_NOT_SAME] - ]); - } - - /** - * Add a rule to compare one field is equal to another. - * - * @param string $field The field you want to apply the rule to. - * @param string $secondField The field you want to compare against. - * @param string|null $message The error message when the rule fails. - * @param string|callable|null $when Either 'create' or 'update' or a callable that returns - * true when the validation rule should be applied. - * @see \Cake\Validation\Validation::compareFields() - * @return $this - * @since 3.6.0 - */ - public function equalToField($field, $secondField, $message = null, $when = null) - { - $extra = array_filter(['on' => $when, 'message' => $message]); - - return $this->add($field, 'equalToField', $extra + [ - 'rule' => ['compareFields', $secondField, Validation::COMPARE_EQUAL] - ]); - } - - /** - * Add a rule to compare one field is not equal to another. - * - * @param string $field The field you want to apply the rule to. - * @param string $secondField The field you want to compare against. - * @param string|null $message The error message when the rule fails. - * @param string|callable|null $when Either 'create' or 'update' or a callable that returns - * true when the validation rule should be applied. - * @see \Cake\Validation\Validation::compareFields() - * @return $this - * @since 3.6.0 - */ - public function notEqualToField($field, $secondField, $message = null, $when = null) - { - $extra = array_filter(['on' => $when, 'message' => $message]); - - return $this->add($field, 'notEqualToField', $extra + [ - 'rule' => ['compareFields', $secondField, Validation::COMPARE_NOT_EQUAL] - ]); - } - - /** - * Add a rule to compare one field is greater than another. - * - * @param string $field The field you want to apply the rule to. - * @param string $secondField The field you want to compare against. - * @param string|null $message The error message when the rule fails. - * @param string|callable|null $when Either 'create' or 'update' or a callable that returns - * true when the validation rule should be applied. - * @see \Cake\Validation\Validation::compareFields() - * @return $this - * @since 3.6.0 - */ - public function greaterThanField($field, $secondField, $message = null, $when = null) - { - $extra = array_filter(['on' => $when, 'message' => $message]); - - return $this->add($field, 'greaterThanField', $extra + [ - 'rule' => ['compareFields', $secondField, Validation::COMPARE_GREATER] - ]); - } - - /** - * Add a rule to compare one field is greater than or equal to another. - * - * @param string $field The field you want to apply the rule to. - * @param string $secondField The field you want to compare against. - * @param string|null $message The error message when the rule fails. - * @param string|callable|null $when Either 'create' or 'update' or a callable that returns - * true when the validation rule should be applied. - * @see \Cake\Validation\Validation::compareFields() - * @return $this - * @since 3.6.0 - */ - public function greaterThanOrEqualToField($field, $secondField, $message = null, $when = null) - { - $extra = array_filter(['on' => $when, 'message' => $message]); - - return $this->add($field, 'greaterThanOrEqualToField', $extra + [ - 'rule' => ['compareFields', $secondField, Validation::COMPARE_GREATER_OR_EQUAL] - ]); - } - - /** - * Add a rule to compare one field is less than another. - * - * @param string $field The field you want to apply the rule to. - * @param string $secondField The field you want to compare against. - * @param string|null $message The error message when the rule fails. - * @param string|callable|null $when Either 'create' or 'update' or a callable that returns - * true when the validation rule should be applied. - * @see \Cake\Validation\Validation::compareFields() - * @return $this - * @since 3.6.0 - */ - public function lessThanField($field, $secondField, $message = null, $when = null) - { - $extra = array_filter(['on' => $when, 'message' => $message]); - - return $this->add($field, 'lessThanField', $extra + [ - 'rule' => ['compareFields', $secondField, Validation::COMPARE_LESS] - ]); - } - - /** - * Add a rule to compare one field is less than or equal to another. - * - * @param string $field The field you want to apply the rule to. - * @param string $secondField The field you want to compare against. - * @param string|null $message The error message when the rule fails. - * @param string|callable|null $when Either 'create' or 'update' or a callable that returns - * true when the validation rule should be applied. - * @see \Cake\Validation\Validation::compareFields() - * @return $this - * @since 3.6.0 - */ - public function lessThanOrEqualToField($field, $secondField, $message = null, $when = null) - { - $extra = array_filter(['on' => $when, 'message' => $message]); - - return $this->add($field, 'lessThanOrEqualToField', $extra + [ - 'rule' => ['compareFields', $secondField, Validation::COMPARE_LESS_OR_EQUAL] - ]); - } - - /** - * Add a rule to check if a field contains non alpha numeric characters. - * - * @param string $field The field you want to apply the rule to. - * @param int $limit The minimum number of non-alphanumeric fields required. - * @param string|null $message The error message when the rule fails. - * @param string|callable|null $when Either 'create' or 'update' or a callable that returns - * true when the validation rule should be applied. - * @see \Cake\Validation\Validation::containsNonAlphaNumeric() - * @return $this - */ - public function containsNonAlphaNumeric($field, $limit = 1, $message = null, $when = null) - { - $extra = array_filter(['on' => $when, 'message' => $message]); - - return $this->add($field, 'containsNonAlphaNumeric', $extra + [ - 'rule' => ['containsNonAlphaNumeric', $limit] - ]); - } - - /** - * Add a date format validation rule to a field. - * - * @param string $field The field you want to apply the rule to. - * @param array $formats A list of accepted date formats. - * @param string|null $message The error message when the rule fails. - * @param string|callable|null $when Either 'create' or 'update' or a callable that returns - * true when the validation rule should be applied. - * @see \Cake\Validation\Validation::date() - * @return $this - */ - public function date($field, $formats = ['ymd'], $message = null, $when = null) - { - $extra = array_filter(['on' => $when, 'message' => $message]); - - return $this->add($field, 'date', $extra + [ - 'rule' => ['date', $formats] - ]); - } - - /** - * Add a date time format validation rule to a field. - * - * @param string $field The field you want to apply the rule to. - * @param array $formats A list of accepted date formats. - * @param string|null $message The error message when the rule fails. - * @param string|callable|null $when Either 'create' or 'update' or a callable that returns - * true when the validation rule should be applied. - * @see \Cake\Validation\Validation::datetime() - * @return $this - */ - public function dateTime($field, $formats = ['ymd'], $message = null, $when = null) - { - $extra = array_filter(['on' => $when, 'message' => $message]); - - return $this->add($field, 'dateTime', $extra + [ - 'rule' => ['datetime', $formats] - ]); - } - - /** - * Add a time format validation rule to a field. - * - * @param string $field The field you want to apply the rule to. - * @param string|null $message The error message when the rule fails. - * @param string|callable|null $when Either 'create' or 'update' or a callable that returns - * true when the validation rule should be applied. - * @see \Cake\Validation\Validation::time() - * @return $this - */ - public function time($field, $message = null, $when = null) - { - $extra = array_filter(['on' => $when, 'message' => $message]); - - return $this->add($field, 'time', $extra + [ - 'rule' => 'time' - ]); - } - - /** - * Add a localized time, date or datetime format validation rule to a field. - * - * @param string $field The field you want to apply the rule to. - * @param string $type Parser type, one out of 'date', 'time', and 'datetime' - * @param string|null $message The error message when the rule fails. - * @param string|callable|null $when Either 'create' or 'update' or a callable that returns - * true when the validation rule should be applied. - * @see \Cake\Validation\Validation::localizedTime() - * @return $this - */ - public function localizedTime($field, $type = 'datetime', $message = null, $when = null) - { - $extra = array_filter(['on' => $when, 'message' => $message]); - - return $this->add($field, 'localizedTime', $extra + [ - 'rule' => ['localizedTime', $type] - ]); - } - - /** - * Add a boolean validation rule to a field. - * - * @param string $field The field you want to apply the rule to. - * @param string|null $message The error message when the rule fails. - * @param string|callable|null $when Either 'create' or 'update' or a callable that returns - * true when the validation rule should be applied. - * @see \Cake\Validation\Validation::boolean() - * @return $this - */ - public function boolean($field, $message = null, $when = null) - { - $extra = array_filter(['on' => $when, 'message' => $message]); - - return $this->add($field, 'boolean', $extra + [ - 'rule' => 'boolean' - ]); - } - - /** - * Add a decimal validation rule to a field. - * - * @param string $field The field you want to apply the rule to. - * @param int|null $places The number of decimal places to require. - * @param string|null $message The error message when the rule fails. - * @param string|callable|null $when Either 'create' or 'update' or a callable that returns - * true when the validation rule should be applied. - * @see \Cake\Validation\Validation::decimal() - * @return $this - */ - public function decimal($field, $places = null, $message = null, $when = null) - { - $extra = array_filter(['on' => $when, 'message' => $message]); - - return $this->add($field, 'decimal', $extra + [ - 'rule' => ['decimal', $places] - ]); - } - - /** - * Add an email validation rule to a field. - * - * @param string $field The field you want to apply the rule to. - * @param bool $checkMX Whether or not to check the MX records. - * @param string|null $message The error message when the rule fails. - * @param string|callable|null $when Either 'create' or 'update' or a callable that returns - * true when the validation rule should be applied. - * @see \Cake\Validation\Validation::email() - * @return $this - */ - public function email($field, $checkMX = false, $message = null, $when = null) - { - $extra = array_filter(['on' => $when, 'message' => $message]); - - return $this->add($field, 'email', $extra + [ - 'rule' => ['email', $checkMX] - ]); - } - - /** - * Add an IP validation rule to a field. - * - * This rule will accept both IPv4 and IPv6 addresses. - * - * @param string $field The field you want to apply the rule to. - * @param string|null $message The error message when the rule fails. - * @param string|callable|null $when Either 'create' or 'update' or a callable that returns - * true when the validation rule should be applied. - * @see \Cake\Validation\Validation::ip() - * @return $this - */ - public function ip($field, $message = null, $when = null) - { - $extra = array_filter(['on' => $when, 'message' => $message]); - - return $this->add($field, 'ip', $extra + [ - 'rule' => 'ip' - ]); - } - - /** - * Add an IPv4 validation rule to a field. - * - * @param string $field The field you want to apply the rule to. - * @param string|null $message The error message when the rule fails. - * @param string|callable|null $when Either 'create' or 'update' or a callable that returns - * true when the validation rule should be applied. - * @see \Cake\Validation\Validation::ip() - * @return $this - */ - public function ipv4($field, $message = null, $when = null) - { - $extra = array_filter(['on' => $when, 'message' => $message]); - - return $this->add($field, 'ipv4', $extra + [ - 'rule' => ['ip', 'ipv4'] - ]); - } - - /** - * Add an IPv6 validation rule to a field. - * - * @param string $field The field you want to apply the rule to. - * @param string|null $message The error message when the rule fails. - * @param string|callable|null $when Either 'create' or 'update' or a callable that returns - * true when the validation rule should be applied. - * @see \Cake\Validation\Validation::ip() - * @return $this - */ - public function ipv6($field, $message = null, $when = null) - { - $extra = array_filter(['on' => $when, 'message' => $message]); - - return $this->add($field, 'ipv6', $extra + [ - 'rule' => ['ip', 'ipv6'] - ]); - } - - /** - * Add a string length validation rule to a field. - * - * @param string $field The field you want to apply the rule to. - * @param int $min The minimum length required. - * @param string|null $message The error message when the rule fails. - * @param string|callable|null $when Either 'create' or 'update' or a callable that returns - * true when the validation rule should be applied. - * @see \Cake\Validation\Validation::minLength() - * @return $this - */ - public function minLength($field, $min, $message = null, $when = null) - { - $extra = array_filter(['on' => $when, 'message' => $message]); - - return $this->add($field, 'minLength', $extra + [ - 'rule' => ['minLength', $min] - ]); - } - - /** - * Add a string length validation rule to a field. - * - * @param string $field The field you want to apply the rule to. - * @param int $min The minimum length required. - * @param string|null $message The error message when the rule fails. - * @param string|callable|null $when Either 'create' or 'update' or a callable that returns - * true when the validation rule should be applied. - * @see \Cake\Validation\Validation::minLengthBytes() - * @return $this - */ - public function minLengthBytes($field, $min, $message = null, $when = null) - { - $extra = array_filter(['on' => $when, 'message' => $message]); - - return $this->add($field, 'minLengthBytes', $extra + [ - 'rule' => ['minLengthBytes', $min] - ]); - } - - /** - * Add a string length validation rule to a field. - * - * @param string $field The field you want to apply the rule to. - * @param int $max The maximum length allowed. - * @param string|null $message The error message when the rule fails. - * @param string|callable|null $when Either 'create' or 'update' or a callable that returns - * true when the validation rule should be applied. - * @see \Cake\Validation\Validation::maxLength() - * @return $this - */ - public function maxLength($field, $max, $message = null, $when = null) - { - $extra = array_filter(['on' => $when, 'message' => $message]); - - return $this->add($field, 'maxLength', $extra + [ - 'rule' => ['maxLength', $max] - ]); - } - - /** - * Add a string length validation rule to a field. - * - * @param string $field The field you want to apply the rule to. - * @param int $max The maximum length allowed. - * @param string|null $message The error message when the rule fails. - * @param string|callable|null $when Either 'create' or 'update' or a callable that returns - * true when the validation rule should be applied. - * @see \Cake\Validation\Validation::maxLengthBytes() - * @return $this - */ - public function maxLengthBytes($field, $max, $message = null, $when = null) - { - $extra = array_filter(['on' => $when, 'message' => $message]); - - return $this->add($field, 'maxLengthBytes', $extra + [ - 'rule' => ['maxLengthBytes', $max] - ]); - } - - /** - * Add a numeric value validation rule to a field. - * - * @param string $field The field you want to apply the rule to. - * @param string|null $message The error message when the rule fails. - * @param string|callable|null $when Either 'create' or 'update' or a callable that returns - * true when the validation rule should be applied. - * @see \Cake\Validation\Validation::numeric() - * @return $this - */ - public function numeric($field, $message = null, $when = null) - { - $extra = array_filter(['on' => $when, 'message' => $message]); - - return $this->add($field, 'numeric', $extra + [ - 'rule' => 'numeric' - ]); - } - - /** - * Add a natural number validation rule to a field. - * - * @param string $field The field you want to apply the rule to. - * @param string|null $message The error message when the rule fails. - * @param string|callable|null $when Either 'create' or 'update' or a callable that returns - * true when the validation rule should be applied. - * @see \Cake\Validation\Validation::naturalNumber() - * @return $this - */ - public function naturalNumber($field, $message = null, $when = null) - { - $extra = array_filter(['on' => $when, 'message' => $message]); - - return $this->add($field, 'naturalNumber', $extra + [ - 'rule' => ['naturalNumber', false] - ]); - } - - /** - * Add a validation rule to ensure a field is a non negative integer. - * - * @param string $field The field you want to apply the rule to. - * @param string|null $message The error message when the rule fails. - * @param string|callable|null $when Either 'create' or 'update' or a callable that returns - * true when the validation rule should be applied. - * @see \Cake\Validation\Validation::naturalNumber() - * @return $this - */ - public function nonNegativeInteger($field, $message = null, $when = null) - { - $extra = array_filter(['on' => $when, 'message' => $message]); - - return $this->add($field, 'nonNegativeInteger', $extra + [ - 'rule' => ['naturalNumber', true] - ]); - } - - /** - * Add a validation rule to ensure a field is within a numeric range - * - * @param string $field The field you want to apply the rule to. - * @param array $range The inclusive upper and lower bounds of the valid range. - * @param string|null $message The error message when the rule fails. - * @param string|callable|null $when Either 'create' or 'update' or a callable that returns - * true when the validation rule should be applied. - * @see \Cake\Validation\Validation::range() - * @return $this - */ - public function range($field, array $range, $message = null, $when = null) - { - if (count($range) !== 2) { - throw new InvalidArgumentException('The $range argument requires 2 numbers'); - } - $extra = array_filter(['on' => $when, 'message' => $message]); - - return $this->add($field, 'range', $extra + [ - 'rule' => ['range', array_shift($range), array_shift($range)] - ]); - } - - /** - * Add a validation rule to ensure a field is a URL. - * - * This validator does not require a protocol. - * - * @param string $field The field you want to apply the rule to. - * @param string|null $message The error message when the rule fails. - * @param string|callable|null $when Either 'create' or 'update' or a callable that returns - * true when the validation rule should be applied. - * @see \Cake\Validation\Validation::url() - * @return $this - */ - public function url($field, $message = null, $when = null) - { - $extra = array_filter(['on' => $when, 'message' => $message]); - - return $this->add($field, 'url', $extra + [ - 'rule' => ['url', false] - ]); - } - - /** - * Add a validation rule to ensure a field is a URL. - * - * This validator requires the URL to have a protocol. - * - * @param string $field The field you want to apply the rule to. - * @param string|null $message The error message when the rule fails. - * @param string|callable|null $when Either 'create' or 'update' or a callable that returns - * true when the validation rule should be applied. - * @see \Cake\Validation\Validation::url() - * @return $this - */ - public function urlWithProtocol($field, $message = null, $when = null) - { - $extra = array_filter(['on' => $when, 'message' => $message]); - - return $this->add($field, 'urlWithProtocol', $extra + [ - 'rule' => ['url', true] - ]); - } - - /** - * Add a validation rule to ensure the field value is within a whitelist. - * - * @param string $field The field you want to apply the rule to. - * @param array $list The list of valid options. - * @param string|null $message The error message when the rule fails. - * @param string|callable|null $when Either 'create' or 'update' or a callable that returns - * true when the validation rule should be applied. - * @see \Cake\Validation\Validation::inList() - * @return $this - */ - public function inList($field, array $list, $message = null, $when = null) - { - $extra = array_filter(['on' => $when, 'message' => $message]); - - return $this->add($field, 'inList', $extra + [ - 'rule' => ['inList', $list] - ]); - } - - /** - * Add a validation rule to ensure the field is a UUID - * - * @param string $field The field you want to apply the rule to. - * @param string|null $message The error message when the rule fails. - * @param string|callable|null $when Either 'create' or 'update' or a callable that returns - * true when the validation rule should be applied. - * @see \Cake\Validation\Validation::uuid() - * @return $this - */ - public function uuid($field, $message = null, $when = null) - { - $extra = array_filter(['on' => $when, 'message' => $message]); - - return $this->add($field, 'uuid', $extra + [ - 'rule' => 'uuid' - ]); - } - - /** - * Add a validation rule to ensure the field is an uploaded file - * - * For options see Cake\Validation\Validation::uploadedFile() - * - * @param string $field The field you want to apply the rule to. - * @param array $options An array of options. - * @param string|null $message The error message when the rule fails. - * @param string|callable|null $when Either 'create' or 'update' or a callable that returns - * true when the validation rule should be applied. - * @see \Cake\Validation\Validation::uploadedFile() - * @return $this - */ - public function uploadedFile($field, array $options, $message = null, $when = null) - { - $extra = array_filter(['on' => $when, 'message' => $message]); - - return $this->add($field, 'uploadedFile', $extra + [ - 'rule' => ['uploadedFile', $options] - ]); - } - - /** - * Add a validation rule to ensure the field is a lat/long tuple. - * - * e.g. `, ` - * - * @param string $field The field you want to apply the rule to. - * @param string|null $message The error message when the rule fails. - * @param string|callable|null $when Either 'create' or 'update' or a callable that returns - * true when the validation rule should be applied. - * @see \Cake\Validation\Validation::uuid() - * @return $this - */ - public function latLong($field, $message = null, $when = null) - { - $extra = array_filter(['on' => $when, 'message' => $message]); - - return $this->add($field, 'latLong', $extra + [ - 'rule' => 'geoCoordinate' - ]); - } - - /** - * Add a validation rule to ensure the field is a latitude. - * - * @param string $field The field you want to apply the rule to. - * @param string|null $message The error message when the rule fails. - * @param string|callable|null $when Either 'create' or 'update' or a callable that returns - * true when the validation rule should be applied. - * @see \Cake\Validation\Validation::latitude() - * @return $this - */ - public function latitude($field, $message = null, $when = null) - { - $extra = array_filter(['on' => $when, 'message' => $message]); - - return $this->add($field, 'latitude', $extra + [ - 'rule' => 'latitude' - ]); - } - - /** - * Add a validation rule to ensure the field is a longitude. - * - * @param string $field The field you want to apply the rule to. - * @param string|null $message The error message when the rule fails. - * @param string|callable|null $when Either 'create' or 'update' or a callable that returns - * true when the validation rule should be applied. - * @see \Cake\Validation\Validation::longitude() - * @return $this - */ - public function longitude($field, $message = null, $when = null) - { - $extra = array_filter(['on' => $when, 'message' => $message]); - - return $this->add($field, 'longitude', $extra + [ - 'rule' => 'longitude' - ]); - } - - /** - * Add a validation rule to ensure a field contains only ascii bytes - * - * @param string $field The field you want to apply the rule to. - * @param string|null $message The error message when the rule fails. - * @param string|callable|null $when Either 'create' or 'update' or a callable that returns - * true when the validation rule should be applied. - * @see \Cake\Validation\Validation::ascii() - * @return $this - */ - public function ascii($field, $message = null, $when = null) - { - $extra = array_filter(['on' => $when, 'message' => $message]); - - return $this->add($field, 'ascii', $extra + [ - 'rule' => 'ascii' - ]); - } - - /** - * Add a validation rule to ensure a field contains only BMP utf8 bytes - * - * @param string $field The field you want to apply the rule to. - * @param string|null $message The error message when the rule fails. - * @param string|callable|null $when Either 'create' or 'update' or a callable that returns - * true when the validation rule should be applied. - * @see \Cake\Validation\Validation::utf8() - * @return $this - */ - public function utf8($field, $message = null, $when = null) - { - $extra = array_filter(['on' => $when, 'message' => $message]); - - return $this->add($field, 'utf8', $extra + [ - 'rule' => ['utf8', ['extended' => false]] - ]); - } - - /** - * Add a validation rule to ensure a field contains only utf8 bytes. - * - * This rule will accept 3 and 4 byte UTF8 sequences, which are necessary for emoji. - * - * @param string $field The field you want to apply the rule to. - * @param string|null $message The error message when the rule fails. - * @param string|callable|null $when Either 'create' or 'update' or a callable that returns - * true when the validation rule should be applied. - * @see \Cake\Validation\Validation::utf8() - * @return $this - */ - public function utf8Extended($field, $message = null, $when = null) - { - $extra = array_filter(['on' => $when, 'message' => $message]); - - return $this->add($field, 'utf8Extended', $extra + [ - 'rule' => ['utf8', ['extended' => true]] - ]); - } - - /** - * Add a validation rule to ensure a field is an integer value. - * - * @param string $field The field you want to apply the rule to. - * @param string|null $message The error message when the rule fails. - * @param string|callable|null $when Either 'create' or 'update' or a callable that returns - * true when the validation rule should be applied. - * @see \Cake\Validation\Validation::isInteger() - * @return $this - */ - public function integer($field, $message = null, $when = null) - { - $extra = array_filter(['on' => $when, 'message' => $message]); - - return $this->add($field, 'integer', $extra + [ - 'rule' => 'isInteger' - ]); - } - - /** - * Add a validation rule to ensure that a field contains an array. - * - * @param string $field The field you want to apply the rule to. - * @param string|null $message The error message when the rule fails. - * @param string|callable|null $when Either 'create' or 'update' or a callable that returns - * true when the validation rule should be applied. - * @see \Cake\Validation\Validation::isArray() - * @return $this - */ - public function isArray($field, $message = null, $when = null) - { - $extra = array_filter(['on' => $when, 'message' => $message]); - - return $this->add($field, 'isArray', $extra + [ - 'rule' => 'isArray' - ]); - } - - /** - * Add a validation rule to ensure that a field contains a scalar. - * - * @param string $field The field you want to apply the rule to. - * @param string|null $message The error message when the rule fails. - * @param string|callable|null $when Either 'create' or 'update' or a callable that returns - * true when the validation rule should be applied. - * @see \Cake\Validation\Validation::isScalar() - * @return $this - */ - public function scalar($field, $message = null, $when = null) - { - $extra = array_filter(['on' => $when, 'message' => $message]); - - return $this->add($field, 'scalar', $extra + [ - 'rule' => 'isScalar' - ]); - } - - /** - * Add a validation rule to ensure a field is a 6 digits hex color value. - * - * @param string $field The field you want to apply the rule to. - * @param string|null $message The error message when the rule fails. - * @param string|callable|null $when Either 'create' or 'update' or a callable that returns - * true when the validation rule should be applied. - * @see \Cake\Validation\Validation::hexColor() - * @return $this - */ - public function hexColor($field, $message = null, $when = null) - { - $extra = array_filter(['on' => $when, 'message' => $message]); - - return $this->add($field, 'hexColor', $extra + [ - 'rule' => 'hexColor', - ]); - } - - /** - * Add a validation rule for a multiple select. Comparison is case sensitive by default. - * - * @param string $field The field you want to apply the rule to. - * @param array $options The options for the validator. Includes the options defined in - * \Cake\Validation\Validation::multiple() and the `caseInsensitive` parameter. - * @param string|null $message The error message when the rule fails. - * @param string|callable|null $when Either 'create' or 'update' or a callable that returns - * true when the validation rule should be applied. - * @see \Cake\Validation\Validation::multiple() - * @return $this - */ - public function multipleOptions($field, array $options = [], $message = null, $when = null) - { - $extra = array_filter(['on' => $when, 'message' => $message]); - $caseInsensitive = isset($options['caseInsensitive']) ? $options['caseInsensitive'] : false; - unset($options['caseInsensitive']); - - return $this->add($field, 'multipleOptions', $extra + [ - 'rule' => ['multiple', $options, $caseInsensitive] - ]); - } - - /** - * Add a validation rule to ensure that a field is an array containing at least - * the specified amount of elements - * - * @param string $field The field you want to apply the rule to. - * @param int $count The number of elements the array should at least have - * @param string|null $message The error message when the rule fails. - * @param string|callable|null $when Either 'create' or 'update' or a callable that returns - * true when the validation rule should be applied. - * @see \Cake\Validation\Validation::numElements() - * @return $this - */ - public function hasAtLeast($field, $count, $message = null, $when = null) - { - $extra = array_filter(['on' => $when, 'message' => $message]); - - return $this->add($field, 'hasAtLeast', $extra + [ - 'rule' => function ($value) use ($count) { - if (is_array($value) && isset($value['_ids'])) { - $value = $value['_ids']; - } - - return Validation::numElements($value, Validation::COMPARE_GREATER_OR_EQUAL, $count); - } - ]); - } - - /** - * Add a validation rule to ensure that a field is an array containing at most - * the specified amount of elements - * - * @param string $field The field you want to apply the rule to. - * @param int $count The number maximum amount of elements the field should have - * @param string|null $message The error message when the rule fails. - * @param string|callable|null $when Either 'create' or 'update' or a callable that returns - * true when the validation rule should be applied. - * @see \Cake\Validation\Validation::numElements() - * @return $this - */ - public function hasAtMost($field, $count, $message = null, $when = null) - { - $extra = array_filter(['on' => $when, 'message' => $message]); - - return $this->add($field, 'hasAtMost', $extra + [ - 'rule' => function ($value) use ($count) { - if (is_array($value) && isset($value['_ids'])) { - $value = $value['_ids']; - } - - return Validation::numElements($value, Validation::COMPARE_LESS_OR_EQUAL, $count); - } - ]); - } - - /** - * Returns whether or not a field can be left empty for a new or already existing - * record. - * - * @param string $field Field name. - * @param bool $newRecord whether the data to be validated is new or to be updated. - * @return bool - */ - public function isEmptyAllowed($field, $newRecord) - { - $providers = $this->_providers; - $data = []; - $context = compact('data', 'newRecord', 'field', 'providers'); - - return $this->_canBeEmpty($this->field($field), $context); - } - - /** - * Returns whether or not a field can be left out for a new or already existing - * record. - * - * @param string $field Field name. - * @param bool $newRecord Whether the data to be validated is new or to be updated. - * @return bool - */ - public function isPresenceRequired($field, $newRecord) - { - $providers = $this->_providers; - $data = []; - $context = compact('data', 'newRecord', 'field', 'providers'); - - return !$this->_checkPresence($this->field($field), $context); - } - - /** - * Returns whether or not a field matches against a regular expression. - * - * @param string $field Field name. - * @param string $regex Regular expression. - * @param string|null $message The error message when the rule fails. - * @param string|callable|null $when Either 'create' or 'update' or a callable that returns - * true when the validation rule should be applied. - * @return $this - */ - public function regex($field, $regex, $message = null, $when = null) - { - $extra = array_filter(['on' => $when, 'message' => $message]); - - return $this->add($field, 'regex', $extra + [ - 'rule' => ['custom', $regex] - ]); - } - - /** - * Returns false if any validation for the passed rule set should be stopped - * due to the field missing in the data array - * - * @param \Cake\Validation\ValidationSet $field The set of rules for a field. - * @param array $context A key value list of data containing the validation context. - * @return bool - */ - protected function _checkPresence($field, $context) - { - $required = $field->isPresenceRequired(); - - if (!is_string($required) && is_callable($required)) { - return !$required($context); - } - - $newRecord = $context['newRecord']; - if (in_array($required, ['create', 'update'], true)) { - return ( - ($required === 'create' && !$newRecord) || - ($required === 'update' && $newRecord) - ); - } - - return !$required; - } - - /** - * Returns whether the field can be left blank according to `allowEmpty` - * - * @param \Cake\Validation\ValidationSet $field the set of rules for a field - * @param array $context a key value list of data containing the validation context. - * @return bool - */ - protected function _canBeEmpty($field, $context) - { - $allowed = $field->isEmptyAllowed(); - - if (!is_string($allowed) && is_callable($allowed)) { - return $allowed($context); - } - - $newRecord = $context['newRecord']; - if (in_array($allowed, ['create', 'update'], true)) { - $allowed = ( - ($allowed === 'create' && $newRecord) || - ($allowed === 'update' && !$newRecord) - ); - } - - return $allowed; - } - - /** - * Returns true if the field is empty in the passed data array - * - * @param mixed $data value to check against - * @return bool - */ - protected function _fieldIsEmpty($data) - { - if (empty($data) && !is_bool($data) && !is_numeric($data)) { - return true; - } - $isArray = is_array($data); - if ($isArray && (isset($data['year']) || isset($data['hour']))) { - $value = implode('', $data); - - return strlen($value) === 0; - } - if ($isArray && isset($data['name'], $data['type'], $data['tmp_name'], $data['error'])) { - return (int)$data['error'] === UPLOAD_ERR_NO_FILE; - } - - return false; - } - - /** - * Iterates over each rule in the validation set and collects the errors resulting - * from executing them - * - * @param string $field The name of the field that is being processed - * @param \Cake\Validation\ValidationSet $rules the list of rules for a field - * @param array $data the full data passed to the validator - * @param bool $newRecord whether is it a new record or an existing one - * @return array - */ - protected function _processRules($field, ValidationSet $rules, $data, $newRecord) - { - $errors = []; - // Loading default provider in case there is none - $this->getProvider('default'); - $message = 'The provided value is invalid'; - - if ($this->_useI18n) { - $message = __d('cake', 'The provided value is invalid'); - } - - foreach ($rules as $name => $rule) { - $result = $rule->process($data[$field], $this->_providers, compact('newRecord', 'data', 'field')); - if ($result === true) { - continue; - } - - $errors[$name] = $message; - if (is_array($result) && $name === static::NESTED) { - $errors = $result; - } - if (is_string($result)) { - $errors[$name] = $result; - } - - if ($rule->isLast()) { - break; - } - } - - return $errors; - } - - /** - * Get the printable version of this object. - * - * @return array - */ - public function __debugInfo() - { - $fields = []; - foreach ($this->_fields as $name => $fieldSet) { - $fields[$name] = [ - 'isPresenceRequired' => $fieldSet->isPresenceRequired(), - 'isEmptyAllowed' => $fieldSet->isEmptyAllowed(), - 'rules' => array_keys($fieldSet->rules()), - ]; - } - - return [ - '_presenceMessages' => $this->_presenceMessages, - '_allowEmptyMessages' => $this->_allowEmptyMessages, - '_useI18n' => $this->_useI18n, - '_providers' => array_keys($this->_providers), - '_fields' => $fields - ]; - } -} diff --git a/vendor/cakephp/cakephp/src/Validation/ValidatorAwareTrait.php b/vendor/cakephp/cakephp/src/Validation/ValidatorAwareTrait.php deleted file mode 100644 index 0b11f1b..0000000 --- a/vendor/cakephp/cakephp/src/Validation/ValidatorAwareTrait.php +++ /dev/null @@ -1,256 +0,0 @@ -add('email', 'valid-email', ['rule' => 'email']) - * ->add('password', 'valid', ['rule' => 'notBlank']) - * ->requirePresence('username'); - * } - * ``` - * - * Otherwise, you can build the object by yourself and store it in the Table object: - * - * ``` - * $validator = new \Cake\Validation\Validator($table); - * $validator - * ->add('email', 'valid-email', ['rule' => 'email']) - * ->add('password', 'valid', ['rule' => 'notBlank']) - * ->allowEmpty('bio'); - * $table->setValidator('forSubscription', $validator); - * ``` - * - * You can implement the method in `validationDefault` in your Table subclass - * should you wish to have a validation set that applies in cases where no other - * set is specified. - * - * @param string|null $name the name of the validation set to return - * @param \Cake\Validation\Validator|null $validator The validator instance to store, - * use null to get a validator. - * @return \Cake\Validation\Validator - * @throws \RuntimeException - * @deprecated 3.5.0 Use getValidator/setValidator instead. - */ - public function validator($name = null, Validator $validator = null) - { - deprecationWarning( - 'ValidatorAwareTrait::validator() is deprecated. ' . - 'Use ValidatorAwareTrait::getValidator()/setValidator() instead.' - ); - if ($validator !== null) { - $name = $name ?: self::DEFAULT_VALIDATOR; - $this->setValidator($name, $validator); - } - - return $this->getValidator($name); - } - - /** - * Returns the validation rules tagged with $name. It is possible to have - * multiple different named validation sets, this is useful when you need - * to use varying rules when saving from different routines in your system. - * - * If a validator has not been set earlier, this method will build a valiator - * using a method inside your class. - * - * For example, if you wish to create a validation set called 'forSubscription', - * you will need to create a method in your Table subclass as follows: - * - * ``` - * public function validationForSubscription($validator) - * { - * return $validator - * ->add('email', 'valid-email', ['rule' => 'email']) - * ->add('password', 'valid', ['rule' => 'notBlank']) - * ->requirePresence('username'); - * } - * $validator = $this->getValidator('forSubscription'); - * ``` - * - * You can implement the method in `validationDefault` in your Table subclass - * should you wish to have a validation set that applies in cases where no other - * set is specified. - * - * If a $name argument has not been provided, the default validator will be returned. - * You can configure your default validator name in a `DEFAULT_VALIDATOR` - * class constant. - * - * @param string|null $name The name of the validation set to return. - * @return \Cake\Validation\Validator - */ - public function getValidator($name = null) - { - $name = $name ?: self::DEFAULT_VALIDATOR; - if (!isset($this->_validators[$name])) { - $validator = $this->createValidator($name); - $this->setValidator($name, $validator); - } - - return $this->_validators[$name]; - } - - /** - * Creates a validator using a custom method inside your class. - * - * This method is used only to build a new validator and it does not store - * it in your object. If you want to build and reuse validators, - * use getValidator() method instead. - * - * @param string $name The name of the validation set to create. - * @return \Cake\Validation\Validator - * @throws \RuntimeException - */ - protected function createValidator($name) - { - $method = 'validation' . ucfirst($name); - if (!$this->validationMethodExists($method)) { - $message = sprintf('The %s::%s() validation method does not exists.', __CLASS__, $method); - throw new RuntimeException($message); - } - - $validator = new $this->_validatorClass; - $validator = $this->$method($validator); - if ($this instanceof EventDispatcherInterface) { - $event = defined(self::class . '::BUILD_VALIDATOR_EVENT') ? self::BUILD_VALIDATOR_EVENT : 'Model.buildValidator'; - $this->dispatchEvent($event, compact('validator', 'name')); - } - - if (!$validator instanceof Validator) { - throw new RuntimeException(sprintf('The %s::%s() validation method must return an instance of %s.', __CLASS__, $method, Validator::class)); - } - - return $validator; - } - - /** - * This method stores a custom validator under the given name. - * - * You can build the object by yourself and store it in your object: - * - * ``` - * $validator = new \Cake\Validation\Validator($table); - * $validator - * ->add('email', 'valid-email', ['rule' => 'email']) - * ->add('password', 'valid', ['rule' => 'notBlank']) - * ->allowEmpty('bio'); - * $this->setValidator('forSubscription', $validator); - * ``` - * - * @param string $name The name of a validator to be set. - * @param \Cake\Validation\Validator $validator Validator object to be set. - * @return $this - */ - public function setValidator($name, Validator $validator) - { - $validator->setProvider(self::VALIDATOR_PROVIDER_NAME, $this); - $this->_validators[$name] = $validator; - - return $this; - } - - /** - * Checks whether or not a validator has been set. - * - * @param string $name The name of a validator. - * @return bool - */ - public function hasValidator($name) - { - $method = 'validation' . ucfirst($name); - if ($this->validationMethodExists($method)) { - return true; - } - - return isset($this->_validators[$name]); - } - - /** - * Checks if validation method exists. - * - * @param string $name Validation method name. - * @return bool - */ - protected function validationMethodExists($name) - { - return method_exists($this, $name); - } - - /** - * Returns the default validator object. Subclasses can override this function - * to add a default validation set to the validator object. - * - * @param \Cake\Validation\Validator $validator The validator that can be modified to - * add some rules to it. - * @return \Cake\Validation\Validator - */ - public function validationDefault(Validator $validator) - { - return $validator; - } -} diff --git a/vendor/cakephp/cakephp/src/Validation/composer.json b/vendor/cakephp/cakephp/src/Validation/composer.json deleted file mode 100644 index e4de56a..0000000 --- a/vendor/cakephp/cakephp/src/Validation/composer.json +++ /dev/null @@ -1,38 +0,0 @@ -{ - "name": "cakephp/validation", - "description": "CakePHP Validation library", - "type": "library", - "keywords": [ - "cakephp", - "validation", - "data validation" - ], - "homepage": "https://cakephp.org", - "license": "MIT", - "authors": [ - { - "name": "CakePHP Community", - "homepage": "https://github.com/cakephp/validation/graphs/contributors" - } - ], - "support": { - "issues": "https://github.com/cakephp/cakephp/issues", - "forum": "https://stackoverflow.com/tags/cakephp", - "irc": "irc://irc.freenode.org/cakephp", - "source": "https://github.com/cakephp/validation" - }, - "require": { - "php": ">=5.6.0", - "cakephp/core": "^3.6.0", - "cakephp/utility": "^3.6.0", - "psr/http-message": "^1.0.0" - }, - "suggest": { - "cakephp/i18n": "If you want to use Validation::localizedTime()" - }, - "autoload": { - "psr-4": { - "Cake\\Validation\\": "." - } - } -} diff --git a/vendor/cakephp/cakephp/src/View/AjaxView.php b/vendor/cakephp/cakephp/src/View/AjaxView.php deleted file mode 100644 index b63412a..0000000 --- a/vendor/cakephp/cakephp/src/View/AjaxView.php +++ /dev/null @@ -1,55 +0,0 @@ -withType('ajax'); - } - - parent::__construct($request, $response, $eventManager, $viewOptions); - } -} diff --git a/vendor/cakephp/cakephp/src/View/Cell.php b/vendor/cakephp/cakephp/src/View/Cell.php deleted file mode 100644 index cdc6c5b..0000000 --- a/vendor/cakephp/cakephp/src/View/Cell.php +++ /dev/null @@ -1,312 +0,0 @@ -setEventManager($eventManager); - } - $this->request = $request; - $this->response = $response; - $this->modelFactory('Table', [$this->getTableLocator(), 'get']); - - $this->_validCellOptions = array_merge(['action', 'args'], $this->_validCellOptions); - foreach ($this->_validCellOptions as $var) { - if (isset($cellOptions[$var])) { - $this->{$var} = $cellOptions[$var]; - } - } - if (!empty($cellOptions['cache'])) { - $this->_cache = $cellOptions['cache']; - } - - $this->initialize(); - } - - /** - * Initialization hook method. - * - * Implement this method to avoid having to overwrite - * the constructor and calling parent::__construct(). - * - * @return void - */ - public function initialize() - { - } - - /** - * Render the cell. - * - * @param string|null $template Custom template name to render. If not provided (null), the last - * value will be used. This value is automatically set by `CellTrait::cell()`. - * @return string The rendered cell. - * @throws \Cake\View\Exception\MissingCellViewException When a MissingTemplateException is raised during rendering. - */ - public function render($template = null) - { - $cache = []; - if ($this->_cache) { - $cache = $this->_cacheConfig($this->action, $template); - } - - $render = function () use ($template) { - try { - $reflect = new ReflectionMethod($this, $this->action); - $reflect->invokeArgs($this, $this->args); - } catch (ReflectionException $e) { - throw new BadMethodCallException(sprintf( - 'Class %s does not have a "%s" method.', - get_class($this), - $this->action - )); - } - - $builder = $this->viewBuilder(); - - if ($template !== null && - strpos($template, '/') === false && - strpos($template, '.') === false - ) { - $template = Inflector::underscore($template); - } - if ($template === null) { - $template = $builder->getTemplate() ?: $this->template; - } - $builder->setLayout(false) - ->setTemplate($template); - - $className = get_class($this); - $namePrefix = '\View\Cell\\'; - $name = substr($className, strpos($className, $namePrefix) + strlen($namePrefix)); - $name = substr($name, 0, -4); - if (!$builder->getTemplatePath()) { - $builder->setTemplatePath('Cell' . DIRECTORY_SEPARATOR . str_replace('\\', DIRECTORY_SEPARATOR, $name)); - } - - $this->View = $this->createView(); - try { - return $this->View->render($template); - } catch (MissingTemplateException $e) { - throw new MissingCellViewException(['file' => $template, 'name' => $name], null, $e); - } - }; - - if ($cache) { - return Cache::remember($cache['key'], $render, $cache['config']); - } - - return $render(); - } - - /** - * Generate the cache key to use for this cell. - * - * If the key is undefined, the cell class and action name will be used. - * - * @param string $action The action invoked. - * @param string|null $template The name of the template to be rendered. - * @return array The cache configuration. - */ - protected function _cacheConfig($action, $template = null) - { - if (empty($this->_cache)) { - return []; - } - $template = $template ?: 'default'; - $key = 'cell_' . Inflector::underscore(get_class($this)) . '_' . $action . '_' . $template; - $key = str_replace('\\', '_', $key); - $default = [ - 'config' => 'default', - 'key' => $key - ]; - if ($this->_cache === true) { - return $default; - } - - return $this->_cache + $default; - } - - /** - * Magic method. - * - * Starts the rendering process when Cell is echoed. - * - * *Note* This method will trigger an error when view rendering has a problem. - * This is because PHP will not allow a __toString() method to throw an exception. - * - * @return string Rendered cell - * @throws \Error Include error details for PHP 7 fatal errors. - */ - public function __toString() - { - try { - return $this->render(); - } catch (Exception $e) { - trigger_error(sprintf('Could not render cell - %s [%s, line %d]', $e->getMessage(), $e->getFile(), $e->getLine()), E_USER_WARNING); - - return ''; - } catch (Error $e) { - throw new Error(sprintf('Could not render cell - %s [%s, line %d]', $e->getMessage(), $e->getFile(), $e->getLine())); - } - } - - /** - * Debug info. - * - * @return array - */ - public function __debugInfo() - { - return [ - 'plugin' => $this->plugin, - 'action' => $this->action, - 'args' => $this->args, - 'template' => $this->template, - 'viewClass' => $this->viewClass, - 'request' => $this->request, - 'response' => $this->response, - ]; - } -} diff --git a/vendor/cakephp/cakephp/src/View/CellTrait.php b/vendor/cakephp/cakephp/src/View/CellTrait.php deleted file mode 100644 index cee1eff..0000000 --- a/vendor/cakephp/cakephp/src/View/CellTrait.php +++ /dev/null @@ -1,131 +0,0 @@ -cell('Taxonomy.TagCloud::smallList', ['limit' => 10]); - * - * // App\View\Cell\TagCloudCell::smallList() - * $cell = $this->cell('TagCloud::smallList', ['limit' => 10]); - * ``` - * - * The `display` action will be used by default when no action is provided: - * - * ``` - * // Taxonomy\View\Cell\TagCloudCell::display() - * $cell = $this->cell('Taxonomy.TagCloud'); - * ``` - * - * Cells are not rendered until they are echoed. - * - * @param string $cell You must indicate cell name, and optionally a cell action. e.g.: `TagCloud::smallList` - * will invoke `View\Cell\TagCloudCell::smallList()`, `display` action will be invoked by default when none is provided. - * @param array $data Additional arguments for cell method. e.g.: - * `cell('TagCloud::smallList', ['a1' => 'v1', 'a2' => 'v2'])` maps to `View\Cell\TagCloud::smallList(v1, v2)` - * @param array $options Options for Cell's constructor - * @return \Cake\View\Cell The cell instance - * @throws \Cake\View\Exception\MissingCellException If Cell class was not found. - * @throws \BadMethodCallException If Cell class does not specified cell action. - */ - protected function cell($cell, array $data = [], array $options = []) - { - $parts = explode('::', $cell); - - if (count($parts) === 2) { - list($pluginAndCell, $action) = [$parts[0], $parts[1]]; - } else { - list($pluginAndCell, $action) = [$parts[0], 'display']; - } - - list($plugin) = pluginSplit($pluginAndCell); - $className = App::className($pluginAndCell, 'View/Cell', 'Cell'); - - if (!$className) { - throw new MissingCellException(['className' => $pluginAndCell . 'Cell']); - } - - if (!empty($data)) { - $data = array_values($data); - } - $options = ['action' => $action, 'args' => $data] + $options; - $cell = $this->_createCell($className, $action, $plugin, $options); - - return $cell; - } - - /** - * Create and configure the cell instance. - * - * @param string $className The cell classname. - * @param string $action The action name. - * @param string $plugin The plugin name. - * @param array $options The constructor options for the cell. - * @return \Cake\View\Cell - */ - protected function _createCell($className, $action, $plugin, $options) - { - /* @var \Cake\View\Cell $instance */ - $instance = new $className($this->request, $this->response, $this->getEventManager(), $options); - $instance->template = Inflector::underscore($action); - - $builder = $instance->viewBuilder(); - if (!empty($plugin)) { - $builder->setPlugin($plugin); - } - if (!empty($this->helpers)) { - $builder->setHelpers($this->helpers); - $instance->helpers = $this->helpers; - } - - if ($this instanceof View) { - if (!empty($this->theme)) { - $builder->setTheme($this->theme); - } - - $class = get_class($this); - $builder->setClassName($class); - $instance->viewClass = $class; - - return $instance; - } - - if (method_exists($this, 'viewBuilder')) { - $builder->setTheme($this->viewBuilder()->getTheme()); - } - - if (isset($this->viewClass)) { - $builder->setClassName($this->viewClass); - $instance->viewClass = $this->viewClass; - } - - return $instance; - } -} diff --git a/vendor/cakephp/cakephp/src/View/Exception/MissingCellException.php b/vendor/cakephp/cakephp/src/View/Exception/MissingCellException.php deleted file mode 100644 index 1c2a4a2..0000000 --- a/vendor/cakephp/cakephp/src/View/Exception/MissingCellException.php +++ /dev/null @@ -1,26 +0,0 @@ - [ - * 'id' => ['type' => 'integer'], - * 'title' => ['type' => 'string', 'length' => 255], - * '_constraints' => [ - * 'primary' => ['type' => 'primary', 'columns' => ['id']] - * ] - * ], - * 'defaults' => [ - * 'id' => 1, - * 'title' => 'First post!', - * ] - * ]; - * ``` - */ -class ArrayContext implements ContextInterface -{ - - /** - * The request object. - * - * @var \Cake\Http\ServerRequest - */ - protected $_request; - - /** - * Context data for this object. - * - * @var array - */ - protected $_context; - - /** - * Constructor. - * - * @param \Cake\Http\ServerRequest $request The request object. - * @param array $context Context info. - */ - public function __construct(ServerRequest $request, array $context) - { - $this->_request = $request; - $context += [ - 'schema' => [], - 'required' => [], - 'defaults' => [], - 'errors' => [], - ]; - $this->_context = $context; - } - - /** - * Get the fields used in the context as a primary key. - * - * @return array - */ - public function primaryKey() - { - if (empty($this->_context['schema']['_constraints']) || - !is_array($this->_context['schema']['_constraints']) - ) { - return []; - } - foreach ($this->_context['schema']['_constraints'] as $data) { - if (isset($data['type']) && $data['type'] === 'primary') { - return isset($data['columns']) ? (array)$data['columns'] : []; - } - } - - return []; - } - - /** - * {@inheritDoc} - */ - public function isPrimaryKey($field) - { - $primaryKey = $this->primaryKey(); - - return in_array($field, $primaryKey); - } - - /** - * Returns whether or not this form is for a create operation. - * - * For this method to return true, both the primary key constraint - * must be defined in the 'schema' data, and the 'defaults' data must - * contain a value for all fields in the key. - * - * @return bool - */ - public function isCreate() - { - $primary = $this->primaryKey(); - foreach ($primary as $column) { - if (!empty($this->_context['defaults'][$column])) { - return false; - } - } - - return true; - } - - /** - * Get the current value for a given field. - * - * This method will coalesce the current request data and the 'defaults' - * array. - * - * @param string $field A dot separated path to the field a value - * is needed for. - * @param array $options Options: - * - `default`: Default value to return if no value found in request - * data or context record. - * - `schemaDefault`: Boolean indicating whether default value from - * context's schema should be used if it's not explicitly provided. - * @return mixed - */ - public function val($field, $options = []) - { - $options += [ - 'default' => null, - 'schemaDefault' => true - ]; - - $val = $this->_request->getData($field); - if ($val !== null) { - return $val; - } - if ($options['default'] !== null || !$options['schemaDefault']) { - return $options['default']; - } - if (empty($this->_context['defaults']) || !is_array($this->_context['defaults'])) { - return null; - } - - // Using Hash::check here incase the default value is actually null - if (Hash::check($this->_context['defaults'], $field)) { - return Hash::get($this->_context['defaults'], $field); - } - - return Hash::get($this->_context['defaults'], $this->stripNesting($field)); - } - - /** - * Check if a given field is 'required'. - * - * In this context class, this is simply defined by the 'required' array. - * - * @param string $field A dot separated path to check required-ness for. - * @return bool - */ - public function isRequired($field) - { - if (!is_array($this->_context['required'])) { - return false; - } - $required = Hash::get($this->_context['required'], $field); - if ($required === null) { - $required = Hash::get($this->_context['required'], $this->stripNesting($field)); - } - - return (bool)$required; - } - - /** - * {@inheritDoc} - */ - public function fieldNames() - { - $schema = $this->_context['schema']; - unset($schema['_constraints'], $schema['_indexes']); - - return array_keys($schema); - } - - /** - * Get the abstract field type for a given field name. - * - * @param string $field A dot separated path to get a schema type for. - * @return null|string An abstract data type or null. - * @see \Cake\Database\Type - */ - public function type($field) - { - if (!is_array($this->_context['schema'])) { - return null; - } - - $schema = Hash::get($this->_context['schema'], $field); - if ($schema === null) { - $schema = Hash::get($this->_context['schema'], $this->stripNesting($field)); - } - - return isset($schema['type']) ? $schema['type'] : null; - } - - /** - * Get an associative array of other attributes for a field name. - * - * @param string $field A dot separated path to get additional data on. - * @return array An array of data describing the additional attributes on a field. - */ - public function attributes($field) - { - if (!is_array($this->_context['schema'])) { - return []; - } - $schema = Hash::get($this->_context['schema'], $field); - if ($schema === null) { - $schema = Hash::get($this->_context['schema'], $this->stripNesting($field)); - } - $whitelist = ['length' => null, 'precision' => null]; - - return array_intersect_key((array)$schema, $whitelist); - } - - /** - * Check whether or not a field has an error attached to it - * - * @param string $field A dot separated path to check errors on. - * @return bool Returns true if the errors for the field are not empty. - */ - public function hasError($field) - { - if (empty($this->_context['errors'])) { - return false; - } - - return (bool)Hash::check($this->_context['errors'], $field); - } - - /** - * Get the errors for a given field - * - * @param string $field A dot separated path to check errors on. - * @return array An array of errors, an empty array will be returned when the - * context has no errors. - */ - public function error($field) - { - if (empty($this->_context['errors'])) { - return []; - } - - return Hash::get($this->_context['errors'], $field); - } - - /** - * Strips out any numeric nesting - * - * For example users.0.age will output as users.age - * - * @param string $field A dot separated path - * @return string A string with stripped numeric nesting - */ - protected function stripNesting($field) - { - return preg_replace('/\.\d*\./', '.', $field); - } -} diff --git a/vendor/cakephp/cakephp/src/View/Form/ContextInterface.php b/vendor/cakephp/cakephp/src/View/Form/ContextInterface.php deleted file mode 100644 index 3daa8f5..0000000 --- a/vendor/cakephp/cakephp/src/View/Form/ContextInterface.php +++ /dev/null @@ -1,113 +0,0 @@ -validators when - * dealing with associated forms. - */ -class EntityContext implements ContextInterface -{ - use LocatorAwareTrait; - - /** - * The request object. - * - * @var \Cake\Http\ServerRequest - */ - protected $_request; - - /** - * Context data for this object. - * - * @var array - */ - protected $_context; - - /** - * The name of the top level entity/table object. - * - * @var string - */ - protected $_rootName; - - /** - * Boolean to track whether or not the entity is a - * collection. - * - * @var bool - */ - protected $_isCollection = false; - - /** - * A dictionary of tables - * - * @var array - */ - protected $_tables = []; - - /** - * Dictionary of validators. - * - * @var \Cake\Validation\Validator[] - */ - protected $_validator = []; - - /** - * Constructor. - * - * @param \Cake\Http\ServerRequest $request The request object. - * @param array $context Context info. - */ - public function __construct(ServerRequest $request, array $context) - { - $this->_request = $request; - $context += [ - 'entity' => null, - 'table' => null, - 'validator' => [], - ]; - $this->_context = $context; - $this->_prepare(); - } - - /** - * Prepare some additional data from the context. - * - * If the table option was provided to the constructor and it - * was a string, TableLocator will be used to get the correct table instance. - * - * If an object is provided as the table option, it will be used as is. - * - * If no table option is provided, the table name will be derived based on - * naming conventions. This inference will work with a number of common objects - * like arrays, Collection objects and ResultSets. - * - * @return void - * @throws \RuntimeException When a table object cannot be located/inferred. - */ - protected function _prepare() - { - $table = $this->_context['table']; - $entity = $this->_context['entity']; - if (empty($table)) { - if (is_array($entity) || $entity instanceof Traversable) { - foreach ($entity as $e) { - $entity = $e; - break; - } - } - $isEntity = $entity instanceof EntityInterface; - - if ($isEntity) { - $table = $entity->getSource(); - } - if (!$table && $isEntity && get_class($entity) !== 'Cake\ORM\Entity') { - list(, $entityClass) = namespaceSplit(get_class($entity)); - $table = Inflector::pluralize($entityClass); - } - } - if (is_string($table)) { - $table = $this->getTableLocator()->get($table); - } - - if (!($table instanceof RepositoryInterface)) { - throw new RuntimeException( - 'Unable to find table class for current entity' - ); - } - $this->_isCollection = ( - is_array($entity) || - $entity instanceof Traversable - ); - - $alias = $this->_rootName = $table->getAlias(); - $this->_tables[$alias] = $table; - } - - /** - * Get the primary key data for the context. - * - * Gets the primary key columns from the root entity's schema. - * - * @return array - */ - public function primaryKey() - { - return (array)$this->_tables[$this->_rootName]->getPrimaryKey(); - } - - /** - * {@inheritDoc} - */ - public function isPrimaryKey($field) - { - $parts = explode('.', $field); - $table = $this->_getTable($parts); - $primaryKey = (array)$table->getPrimaryKey(); - - return in_array(array_pop($parts), $primaryKey); - } - - /** - * Check whether or not this form is a create or update. - * - * If the context is for a single entity, the entity's isNew() method will - * be used. If isNew() returns null, a create operation will be assumed. - * - * If the context is for a collection or array the first object in the - * collection will be used. - * - * @return bool - */ - public function isCreate() - { - $entity = $this->_context['entity']; - if (is_array($entity) || $entity instanceof Traversable) { - foreach ($entity as $e) { - $entity = $e; - break; - } - } - if ($entity instanceof EntityInterface) { - return $entity->isNew() !== false; - } - - return true; - } - - /** - * Get the value for a given path. - * - * Traverses the entity data and finds the value for $path. - * - * @param string $field The dot separated path to the value. - * @param array $options Options: - * - `default`: Default value to return if no value found in request - * data or entity. - * - `schemaDefault`: Boolean indicating whether default value from table - * schema should be used if it's not explicitly provided. - * @return mixed The value of the field or null on a miss. - */ - public function val($field, $options = []) - { - $options += [ - 'default' => null, - 'schemaDefault' => true - ]; - - $val = $this->_request->getData($field); - if ($val !== null) { - return $val; - } - if (empty($this->_context['entity'])) { - return $options['default']; - } - $parts = explode('.', $field); - $entity = $this->entity($parts); - - if (end($parts) === '_ids' && !empty($entity)) { - return $this->_extractMultiple($entity, $parts); - } - - if ($entity instanceof EntityInterface) { - $part = array_pop($parts); - $val = $entity->get($part); - if ($val !== null) { - return $val; - } - if ($options['default'] !== null - || !$options['schemaDefault'] - || !$entity->isNew() - ) { - return $options['default']; - } - - return $this->_schemaDefault($part, $entity); - } - if (is_array($entity) || $entity instanceof ArrayAccess) { - $key = array_pop($parts); - - return isset($entity[$key]) ? $entity[$key] : $options['default']; - } - - return null; - } - - /** - * Get default value from table schema for given entity field. - * - * @param string $field Field name. - * @param \Cake\Datasource\EntityInterface $entity The entity. - * @return mixed - */ - protected function _schemaDefault($field, $entity) - { - $table = $this->_getTable($entity); - if ($table === false) { - return null; - } - $defaults = $table->getSchema()->defaultValues(); - if (!array_key_exists($field, $defaults)) { - return null; - } - - return $defaults[$field]; - } - - /** - * Helper method used to extract all the primary key values out of an array, The - * primary key column is guessed out of the provided $path array - * - * @param array|\Traversable $values The list from which to extract primary keys from - * @param array $path Each one of the parts in a path for a field name - * @return array|null - */ - protected function _extractMultiple($values, $path) - { - if (!(is_array($values) || $values instanceof Traversable)) { - return null; - } - $table = $this->_getTable($path, false); - $primary = $table ? (array)$table->getPrimaryKey() : ['id']; - - return (new Collection($values))->extract($primary[0])->toArray(); - } - - /** - * Fetch the leaf entity for the given path. - * - * This method will traverse the given path and find the leaf - * entity. If the path does not contain a leaf entity false - * will be returned. - * - * @param array|null $path Each one of the parts in a path for a field name - * or null to get the entity passed in constructor context. - * @return \Cake\Datasource\EntityInterface|\Traversable|array|bool - * @throws \RuntimeException When properties cannot be read. - */ - public function entity($path = null) - { - if ($path === null) { - return $this->_context['entity']; - } - - $oneElement = count($path) === 1; - if ($oneElement && $this->_isCollection) { - return false; - } - $entity = $this->_context['entity']; - if ($oneElement) { - return $entity; - } - - if ($path[0] === $this->_rootName) { - $path = array_slice($path, 1); - } - - $len = count($path); - $last = $len - 1; - for ($i = 0; $i < $len; $i++) { - $prop = $path[$i]; - $next = $this->_getProp($entity, $prop); - $isLast = ($i === $last); - - if (!$isLast && $next === null && $prop !== '_ids') { - $table = $this->_getTable($path); - - return $table->newEntity(); - } - - $isTraversable = ( - is_array($next) || - $next instanceof Traversable || - $next instanceof EntityInterface - ); - if ($isLast || !$isTraversable) { - return $entity; - } - $entity = $next; - } - throw new RuntimeException(sprintf( - 'Unable to fetch property "%s"', - implode('.', $path) - )); - } - - /** - * Read property values or traverse arrays/iterators. - * - * @param mixed $target The entity/array/collection to fetch $field from. - * @param string $field The next field to fetch. - * @return mixed - */ - protected function _getProp($target, $field) - { - if (is_array($target) && isset($target[$field])) { - return $target[$field]; - } - if ($target instanceof EntityInterface) { - return $target->get($field); - } - if ($target instanceof Traversable) { - foreach ($target as $i => $val) { - if ($i == $field) { - return $val; - } - } - - return false; - } - } - - /** - * Check if a field should be marked as required. - * - * @param string $field The dot separated path to the field you want to check. - * @return bool - */ - public function isRequired($field) - { - $parts = explode('.', $field); - $entity = $this->entity($parts); - - $isNew = true; - if ($entity instanceof EntityInterface) { - $isNew = $entity->isNew(); - } - - $validator = $this->_getValidator($parts); - $fieldName = array_pop($parts); - if (!$validator->hasField($fieldName)) { - return false; - } - if ($this->type($field) !== 'boolean') { - return $validator->isEmptyAllowed($fieldName, $isNew) === false; - } - - return false; - } - - /** - * Get the field names from the top level entity. - * - * If the context is for an array of entities, the 0th index will be used. - * - * @return array Array of fieldnames in the table/entity. - */ - public function fieldNames() - { - $table = $this->_getTable('0'); - - return $table->getSchema()->columns(); - } - - /** - * Get the validator associated to an entity based on naming - * conventions. - * - * @param array $parts Each one of the parts in a path for a field name - * @return \Cake\Validation\Validator - */ - protected function _getValidator($parts) - { - $keyParts = array_filter(array_slice($parts, 0, -1), function ($part) { - return !is_numeric($part); - }); - $key = implode('.', $keyParts); - $entity = $this->entity($parts) ?: null; - - if (isset($this->_validator[$key])) { - $this->_validator[$key]->setProvider('entity', $entity); - - return $this->_validator[$key]; - } - - $table = $this->_getTable($parts); - $alias = $table->getAlias(); - - $method = 'default'; - if (is_string($this->_context['validator'])) { - $method = $this->_context['validator']; - } elseif (isset($this->_context['validator'][$alias])) { - $method = $this->_context['validator'][$alias]; - } - - $validator = $table->getValidator($method); - $validator->setProvider('entity', $entity); - - return $this->_validator[$key] = $validator; - } - - /** - * Get the table instance from a property path - * - * @param array $parts Each one of the parts in a path for a field name - * @param bool $fallback Whether or not to fallback to the last found table - * when a non-existent field/property is being encountered. - * @return \Cake\ORM\Table|bool Table instance or false - */ - protected function _getTable($parts, $fallback = true) - { - if (!is_array($parts) || count($parts) === 1) { - return $this->_tables[$this->_rootName]; - } - - $normalized = array_slice(array_filter($parts, function ($part) { - return !is_numeric($part); - }), 0, -1); - - $path = implode('.', $normalized); - if (isset($this->_tables[$path])) { - return $this->_tables[$path]; - } - - if (current($normalized) === $this->_rootName) { - $normalized = array_slice($normalized, 1); - } - - $table = $this->_tables[$this->_rootName]; - $assoc = null; - foreach ($normalized as $part) { - if ($part === '_joinData') { - if ($assoc) { - $table = $assoc->junction(); - $assoc = null; - continue; - } - } else { - $assoc = $table->associations()->getByProperty($part); - } - - if (!$assoc && $fallback) { - break; - } - if (!$assoc && !$fallback) { - return false; - } - - $table = $assoc->getTarget(); - } - - return $this->_tables[$path] = $table; - } - - /** - * Get the abstract field type for a given field name. - * - * @param string $field A dot separated path to get a schema type for. - * @return null|string An abstract data type or null. - * @see \Cake\Database\Type - */ - public function type($field) - { - $parts = explode('.', $field); - $table = $this->_getTable($parts); - - return $table->getSchema()->baseColumnType(array_pop($parts)); - } - - /** - * Get an associative array of other attributes for a field name. - * - * @param string $field A dot separated path to get additional data on. - * @return array An array of data describing the additional attributes on a field. - */ - public function attributes($field) - { - $parts = explode('.', $field); - $table = $this->_getTable($parts); - $column = (array)$table->getSchema()->getColumn(array_pop($parts)); - $whitelist = ['length' => null, 'precision' => null]; - - return array_intersect_key($column, $whitelist); - } - - /** - * Check whether or not a field has an error attached to it - * - * @param string $field A dot separated path to check errors on. - * @return bool Returns true if the errors for the field are not empty. - */ - public function hasError($field) - { - return $this->error($field) !== []; - } - - /** - * Get the errors for a given field - * - * @param string $field A dot separated path to check errors on. - * @return array An array of errors. - */ - public function error($field) - { - $parts = explode('.', $field); - $entity = $this->entity($parts); - - if ($entity instanceof EntityInterface) { - return $entity->getError(array_pop($parts)); - } - - return []; - } -} diff --git a/vendor/cakephp/cakephp/src/View/Form/FormContext.php b/vendor/cakephp/cakephp/src/View/Form/FormContext.php deleted file mode 100644 index e161601..0000000 --- a/vendor/cakephp/cakephp/src/View/Form/FormContext.php +++ /dev/null @@ -1,181 +0,0 @@ -_request = $request; - $context += [ - 'entity' => null, - ]; - $this->_form = $context['entity']; - } - - /** - * {@inheritDoc} - */ - public function primaryKey() - { - return []; - } - - /** - * {@inheritDoc} - */ - public function isPrimaryKey($field) - { - return false; - } - - /** - * {@inheritDoc} - */ - public function isCreate() - { - return true; - } - - /** - * {@inheritDoc} - */ - public function val($field, $options = []) - { - $options += [ - 'default' => null, - 'schemaDefault' => true - ]; - - $val = $this->_request->getData($field); - if ($val !== null) { - return $val; - } - - if ($options['default'] !== null || !$options['schemaDefault']) { - return $options['default']; - } - - return $this->_schemaDefault($field); - } - - /** - * Get default value from form schema for given field. - * - * @param string $field Field name. - - * @return mixed - */ - protected function _schemaDefault($field) - { - $field = $this->_form->schema()->field($field); - if ($field) { - return $field['default']; - } - - return null; - } - - /** - * {@inheritDoc} - */ - public function isRequired($field) - { - $validator = $this->_form->getValidator(); - if (!$validator->hasField($field)) { - return false; - } - if ($this->type($field) !== 'boolean') { - return $validator->isEmptyAllowed($field, $this->isCreate()) === false; - } - - return false; - } - - /** - * {@inheritDoc} - */ - public function fieldNames() - { - return $this->_form->schema()->fields(); - } - - /** - * {@inheritDoc} - */ - public function type($field) - { - return $this->_form->schema()->fieldType($field); - } - - /** - * {@inheritDoc} - */ - public function attributes($field) - { - $column = (array)$this->_form->schema()->field($field); - $whiteList = ['length' => null, 'precision' => null]; - - return array_intersect_key($column, $whiteList); - } - - /** - * {@inheritDoc} - */ - public function hasError($field) - { - $errors = $this->error($field); - - return count($errors) > 0; - } - - /** - * {@inheritDoc} - */ - public function error($field) - { - return array_values((array)Hash::get($this->_form->errors(), $field, [])); - } -} diff --git a/vendor/cakephp/cakephp/src/View/Form/NullContext.php b/vendor/cakephp/cakephp/src/View/Form/NullContext.php deleted file mode 100644 index f2e38b1..0000000 --- a/vendor/cakephp/cakephp/src/View/Form/NullContext.php +++ /dev/null @@ -1,125 +0,0 @@ -_request = $request; - } - - /** - * {@inheritDoc} - */ - public function primaryKey() - { - return []; - } - - /** - * {@inheritDoc} - */ - public function isPrimaryKey($field) - { - return false; - } - - /** - * {@inheritDoc} - */ - public function isCreate() - { - return true; - } - - /** - * {@inheritDoc} - */ - public function val($field) - { - return $this->_request->getData($field); - } - - /** - * {@inheritDoc} - */ - public function isRequired($field) - { - return false; - } - - /** - * {@inheritDoc} - */ - public function fieldNames() - { - return []; - } - - /** - * {@inheritDoc} - */ - public function type($field) - { - return null; - } - - /** - * {@inheritDoc} - */ - public function attributes($field) - { - return []; - } - - /** - * {@inheritDoc} - */ - public function hasError($field) - { - return false; - } - - /** - * {@inheritDoc} - */ - public function error($field) - { - return []; - } -} diff --git a/vendor/cakephp/cakephp/src/View/Helper.php b/vendor/cakephp/cakephp/src/View/Helper.php deleted file mode 100644 index 9f0e9b3..0000000 --- a/vendor/cakephp/cakephp/src/View/Helper.php +++ /dev/null @@ -1,273 +0,0 @@ - ['type' => 'string', 'length' => 100]], - * primaryKey and validates ['field_name'] - * - * @var array - */ - public $fieldset = []; - - /** - * Holds tag templates. - * - * @var array - */ - public $tags = []; - - /** - * The View instance this helper is attached to - * - * @var \Cake\View\View - */ - protected $_View; - - /** - * Default Constructor - * - * @param \Cake\View\View $View The View this helper is being attached to. - * @param array $config Configuration settings for the helper. - */ - public function __construct(View $View, array $config = []) - { - $this->_View = $View; - $this->request = $View->request; - - $this->setConfig($config); - - if (!empty($this->helpers)) { - $this->_helperMap = $View->helpers()->normalizeArray($this->helpers); - } - - $this->initialize($config); - } - - /** - * Provide non fatal errors on missing method calls. - * - * @param string $method Method to invoke - * @param array $params Array of params for the method. - * @return void - */ - public function __call($method, $params) - { - trigger_error(sprintf('Method %1$s::%2$s does not exist', get_class($this), $method), E_USER_WARNING); - } - - /** - * Lazy loads helpers. - * - * @param string $name Name of the property being accessed. - * @return \Cake\View\Helper|null Helper instance if helper with provided name exists - */ - public function __get($name) - { - if (isset($this->_helperMap[$name]) && !isset($this->{$name})) { - $config = ['enabled' => false] + (array)$this->_helperMap[$name]['config']; - $this->{$name} = $this->_View->loadHelper($this->_helperMap[$name]['class'], $config); - - return $this->{$name}; - } - } - - /** - * Get the view instance this helper is bound to. - * - * @return \Cake\View\View The bound view instance. - */ - public function getView() - { - return $this->_View; - } - - /** - * Returns a string to be used as onclick handler for confirm dialogs. - * - * @param string $message Message to be displayed - * @param string $okCode Code to be executed after user chose 'OK' - * @param string $cancelCode Code to be executed after user chose 'Cancel' - * @param array $options Array of options - * @return string onclick JS code - */ - protected function _confirm($message, $okCode, $cancelCode = '', $options = []) - { - $message = str_replace('\\\n', '\n', json_encode($message)); - $confirm = "if (confirm({$message})) { {$okCode} } {$cancelCode}"; - // We cannot change the key here in 3.x, but the behavior is inverted in this case - $escape = isset($options['escape']) && $options['escape'] === false; - if ($escape) { - /** @var string $confirm */ - $confirm = h($confirm); - } - - return $confirm; - } - - /** - * Adds the given class to the element options - * - * @param array $options Array options/attributes to add a class to - * @param string|null $class The class name being added. - * @param string $key the key to use for class. - * @return array Array of options with $key set. - */ - public function addClass(array $options = [], $class = null, $key = 'class') - { - if (isset($options[$key]) && is_array($options[$key])) { - $options[$key][] = $class; - } elseif (isset($options[$key]) && trim($options[$key])) { - $options[$key] .= ' ' . $class; - } else { - $options[$key] = $class; - } - - return $options; - } - - /** - * Get the View callbacks this helper is interested in. - * - * By defining one of the callback methods a helper is assumed - * to be interested in the related event. - * - * Override this method if you need to add non-conventional event listeners. - * Or if you want helpers to listen to non-standard events. - * - * @return array - */ - public function implementedEvents() - { - $eventMap = [ - 'View.beforeRenderFile' => 'beforeRenderFile', - 'View.afterRenderFile' => 'afterRenderFile', - 'View.beforeRender' => 'beforeRender', - 'View.afterRender' => 'afterRender', - 'View.beforeLayout' => 'beforeLayout', - 'View.afterLayout' => 'afterLayout' - ]; - $events = []; - foreach ($eventMap as $event => $method) { - if (method_exists($this, $method)) { - $events[$event] = $method; - } - } - - return $events; - } - - /** - * Constructor hook method. - * - * Implement this method to avoid having to overwrite the constructor and call parent. - * - * @param array $config The configuration settings provided to this helper. - * @return void - */ - public function initialize(array $config) - { - } - - /** - * Returns an array that can be used to describe the internal state of this - * object. - * - * @return array - */ - public function __debugInfo() - { - return [ - 'helpers' => $this->helpers, - 'theme' => $this->theme, - 'plugin' => $this->plugin, - 'fieldset' => $this->fieldset, - 'tags' => $this->tags, - 'implementedEvents' => $this->implementedEvents(), - '_config' => $this->getConfig(), - ]; - } -} diff --git a/vendor/cakephp/cakephp/src/View/Helper/FlashHelper.php b/vendor/cakephp/cakephp/src/View/Helper/FlashHelper.php deleted file mode 100644 index 555c20f..0000000 --- a/vendor/cakephp/cakephp/src/View/Helper/FlashHelper.php +++ /dev/null @@ -1,104 +0,0 @@ -Flash->render('somekey'); - * Will default to flash if no param is passed - * - * You can pass additional information into the flash message generation. This allows you - * to consolidate all the parameters for a given type of flash message into the view. - * - * ``` - * echo $this->Flash->render('flash', ['params' => ['name' => $user['User']['name']]]); - * ``` - * - * This would pass the current user's name into the flash message, so you could create personalized - * messages without the controller needing access to that data. - * - * Lastly you can choose the element that is used for rendering the flash message. Using - * custom elements allows you to fully customize how flash messages are generated. - * - * ``` - * echo $this->Flash->render('flash', ['element' => 'my_custom_element']); - * ``` - * - * If you want to use an element from a plugin for rendering your flash message - * you can use the dot notation for the plugin's element name: - * - * ``` - * echo $this->Flash->render('flash', [ - * 'element' => 'MyPlugin.my_custom_element', - * ]); - * ``` - * - * If you have several messages stored in the Session, each message will be rendered in its own - * element. - * - * @param string $key The [Flash.]key you are rendering in the view. - * @param array $options Additional options to use for the creation of this flash message. - * Supports the 'params', and 'element' keys that are used in the helper. - * @return string|null Rendered flash message or null if flash key does not exist - * in session. - * @throws \UnexpectedValueException If value for flash settings key is not an array. - */ - public function render($key = 'flash', array $options = []) - { - if (!$this->request->getSession()->check("Flash.$key")) { - return null; - } - - $flash = $this->request->getSession()->read("Flash.$key"); - if (!is_array($flash)) { - throw new UnexpectedValueException(sprintf( - 'Value for flash setting key "%s" must be an array.', - $key - )); - } - $this->request->getSession()->delete("Flash.$key"); - - $out = ''; - foreach ($flash as $message) { - $message = $options + $message; - $out .= $this->_View->element($message['element'], $message); - } - - return $out; - } - - /** - * Event listeners. - * - * @return array - */ - public function implementedEvents() - { - return []; - } -} diff --git a/vendor/cakephp/cakephp/src/View/Helper/FormHelper.php b/vendor/cakephp/cakephp/src/View/Helper/FormHelper.php deleted file mode 100644 index 29eb52a..0000000 --- a/vendor/cakephp/cakephp/src/View/Helper/FormHelper.php +++ /dev/null @@ -1,2935 +0,0 @@ - null, - 'errorClass' => 'form-error', - 'typeMap' => [ - 'string' => 'text', - 'text' => 'textarea', - 'uuid' => 'string', - 'datetime' => 'datetime', - 'timestamp' => 'datetime', - 'date' => 'date', - 'time' => 'time', - 'boolean' => 'checkbox', - 'float' => 'number', - 'integer' => 'number', - 'tinyinteger' => 'number', - 'smallinteger' => 'number', - 'decimal' => 'number', - 'binary' => 'file', - ], - 'templates' => [ - // Used for button elements in button(). - 'button' => '{{text}}', - // Used for checkboxes in checkbox() and multiCheckbox(). - 'checkbox' => '', - // Input group wrapper for checkboxes created via control(). - 'checkboxFormGroup' => '{{label}}', - // Wrapper container for checkboxes. - 'checkboxWrapper' => '
{{label}}
', - // Widget ordering for date/time/datetime pickers. - 'dateWidget' => '{{year}}{{month}}{{day}}{{hour}}{{minute}}{{second}}{{meridian}}', - // Error message wrapper elements. - 'error' => '
{{content}}
', - // Container for error items. - 'errorList' => '
    {{content}}
', - // Error item wrapper. - 'errorItem' => '
  • {{text}}
  • ', - // File input used by file(). - 'file' => '', - // Fieldset element used by allControls(). - 'fieldset' => '{{content}}', - // Open tag used by create(). - 'formStart' => '', - // Close tag used by end(). - 'formEnd' => '', - // General grouping container for control(). Defines input/label ordering. - 'formGroup' => '{{label}}{{input}}', - // Wrapper content used to hide other content. - 'hiddenBlock' => '
    {{content}}
    ', - // Generic input element. - 'input' => '', - // Submit input element. - 'inputSubmit' => '', - // Container element used by control(). - 'inputContainer' => '
    {{content}}
    ', - // Container element used by control() when a field has an error. - 'inputContainerError' => '
    {{content}}{{error}}
    ', - // Label element when inputs are not nested inside the label. - 'label' => '{{text}}', - // Label element used for radio and multi-checkbox inputs. - 'nestingLabel' => '{{hidden}}{{input}}{{text}}', - // Legends created by allControls() - 'legend' => '{{text}}', - // Multi-Checkbox input set title element. - 'multicheckboxTitle' => '{{text}}', - // Multi-Checkbox wrapping container. - 'multicheckboxWrapper' => '{{content}}', - // Option element used in select pickers. - 'option' => '', - // Option group element used in select pickers. - 'optgroup' => '{{content}}', - // Select element, - 'select' => '', - // Multi-select element, - 'selectMultiple' => '', - // Radio input element, - 'radio' => '', - // Wrapping container for radio input/label, - 'radioWrapper' => '{{label}}', - // Textarea input element, - 'textarea' => '', - // Container for submit buttons. - 'submitContainer' => '
    {{content}}
    ', - ] - ]; - - /** - * Default widgets - * - * @var array - */ - protected $_defaultWidgets = [ - 'button' => ['Button'], - 'checkbox' => ['Checkbox'], - 'file' => ['File'], - 'label' => ['Label'], - 'nestingLabel' => ['NestingLabel'], - 'multicheckbox' => ['MultiCheckbox', 'nestingLabel'], - 'radio' => ['Radio', 'nestingLabel'], - 'select' => ['SelectBox'], - 'textarea' => ['Textarea'], - 'datetime' => ['DateTime', 'select'], - '_default' => ['Basic'], - ]; - - /** - * List of fields created, used with secure forms. - * - * @var array - */ - public $fields = []; - - /** - * Constant used internally to skip the securing process, - * and neither add the field to the hash or to the unlocked fields. - * - * @var string - */ - const SECURE_SKIP = 'skip'; - - /** - * Defines the type of form being created. Set by FormHelper::create(). - * - * @var string|null - */ - public $requestType; - - /** - * An array of field names that have been excluded from - * the Token hash used by SecurityComponent's validatePost method - * - * @see \Cake\View\Helper\FormHelper::_secure() - * @see \Cake\Controller\Component\SecurityComponent::validatePost() - * @var array - */ - protected $_unlockedFields = []; - - /** - * Locator for input widgets. - * - * @var \Cake\View\Widget\WidgetLocator - */ - protected $_locator; - - /** - * Context for the current form. - * - * @var \Cake\View\Form\ContextInterface|null - */ - protected $_context; - - /** - * Context factory. - * - * @var \Cake\View\Form\ContextFactory - */ - protected $_contextFactory; - - /** - * The action attribute value of the last created form. - * Used to make form/request specific hashes for SecurityComponent. - * - * @var string - */ - protected $_lastAction = ''; - - /** - * The sources to be used when retrieving prefilled input values. - * - * @var array - */ - protected $_valueSources = ['context']; - - /** - * Grouped input types. - * - * @var array - */ - protected $_groupedInputTypes = ['radio', 'multicheckbox', 'date', 'time', 'datetime']; - - /** - * Construct the widgets and binds the default context providers - * - * @param \Cake\View\View $View The View this helper is being attached to. - * @param array $config Configuration settings for the helper. - */ - public function __construct(View $View, array $config = []) - { - $locator = null; - $widgets = $this->_defaultWidgets; - if (isset($config['registry'])) { - deprecationWarning('`registry` config key is deprecated in FormHelper, use `locator` instead.'); - $config['locator'] = $config['registry']; - unset($config['registry']); - } - if (isset($config['locator'])) { - $locator = $config['locator']; - unset($config['locator']); - } - if (isset($config['widgets'])) { - if (is_string($config['widgets'])) { - $config['widgets'] = (array)$config['widgets']; - } - $widgets = $config['widgets'] + $widgets; - unset($config['widgets']); - } - - if (isset($config['groupedInputTypes'])) { - $this->_groupedInputTypes = $config['groupedInputTypes']; - unset($config['groupedInputTypes']); - } - - parent::__construct($View, $config); - - if (!$locator) { - $locator = new WidgetLocator($this->templater(), $this->_View, $widgets); - } - $this->setWidgetLocator($locator); - $this->_idPrefix = $this->getConfig('idPrefix'); - } - - /** - * Set the widget registry the helper will use. - * - * @param \Cake\View\Widget\WidgetRegistry|null $instance The registry instance to set. - * @param array $widgets An array of widgets - * @return \Cake\View\Widget\WidgetRegistry - * @deprecated 3.6.0 Use FormHelper::widgetLocator() instead. - */ - public function widgetRegistry(WidgetRegistry $instance = null, $widgets = []) - { - deprecationWarning('widgetRegistry is deprecated, use widgetLocator instead.'); - - if ($instance) { - $instance->add($widgets); - $this->setWidgetLocator($instance); - } - - return $this->getWidgetLocator(); - } - - /** - * Get the widget locator currently used by the helper. - * - * @return \Cake\View\Widget\WidgetLocator Current locator instance - * @since 3.6.0 - */ - public function getWidgetLocator() - { - return $this->_locator; - } - - /** - * Set the widget locator the helper will use. - * - * @param \Cake\View\Widget\WidgetLocator $instance The locator instance to set. - * @return $this - * @since 3.6.0 - */ - public function setWidgetLocator(WidgetLocator $instance) - { - $this->_locator = $instance; - - return $this; - } - - /** - * Set the context factory the helper will use. - * - * @param \Cake\View\Form\ContextFactory|null $instance The context factory instance to set. - * @param array $contexts An array of context providers. - * @return \Cake\View\Form\ContextFactory - */ - public function contextFactory(ContextFactory $instance = null, array $contexts = []) - { - if ($instance === null) { - if ($this->_contextFactory === null) { - $this->_contextFactory = ContextFactory::createWithDefaults($contexts); - } - - return $this->_contextFactory; - } - $this->_contextFactory = $instance; - - return $this->_contextFactory; - } - - /** - * Returns an HTML form element. - * - * ### Options: - * - * - `type` Form method defaults to autodetecting based on the form context. If - * the form context's isCreate() method returns false, a PUT request will be done. - * - `method` Set the form's method attribute explicitly. - * - `action` The controller action the form submits to, (optional). Use this option if you - * don't need to change the controller from the current request's controller. Deprecated since 3.2, use `url`. - * - `url` The URL the form submits to. Can be a string or a URL array. If you use 'url' - * you should leave 'action' undefined. - * - `encoding` Set the accept-charset encoding for the form. Defaults to `Configure::read('App.encoding')` - * - `enctype` Set the form encoding explicitly. By default `type => file` will set `enctype` - * to `multipart/form-data`. - * - `templates` The templates you want to use for this form. Any templates will be merged on top of - * the already loaded templates. This option can either be a filename in /config that contains - * the templates you want to load, or an array of templates to use. - * - `context` Additional options for the context class. For example the EntityContext accepts a 'table' - * option that allows you to set the specific Table class the form should be based on. - * - `idPrefix` Prefix for generated ID attributes. - * - `valueSources` The sources that values should be read from. See FormHelper::setValueSources() - * - `templateVars` Provide template variables for the formStart template. - * - * @param mixed $context The context for which the form is being defined. - * Can be a ContextInterface instance, ORM entity, ORM resultset, or an - * array of meta data. You can use false or null to make a context-less form. - * @param array $options An array of html attributes and options. - * @return string An formatted opening FORM tag. - * @link https://book.cakephp.org/3.0/en/views/helpers/form.html#Cake\View\Helper\FormHelper::create - */ - public function create($context = null, array $options = []) - { - $append = ''; - - if ($context instanceof ContextInterface) { - $this->context($context); - } else { - if (empty($options['context'])) { - $options['context'] = []; - } - $options['context']['entity'] = $context; - $context = $this->_getContext($options['context']); - unset($options['context']); - } - - $isCreate = $context->isCreate(); - - $options += [ - 'type' => $isCreate ? 'post' : 'put', - 'action' => null, - 'url' => null, - 'encoding' => strtolower(Configure::read('App.encoding')), - 'templates' => null, - 'idPrefix' => null, - 'valueSources' => null, - ]; - - if (isset($options['action'])) { - trigger_error('Using key `action` is deprecated, use `url` directly instead.', E_USER_DEPRECATED); - } - - if (isset($options['valueSources'])) { - $this->setValueSources($options['valueSources']); - unset($options['valueSources']); - } - - if ($options['idPrefix'] !== null) { - $this->_idPrefix = $options['idPrefix']; - } - $templater = $this->templater(); - - if (!empty($options['templates'])) { - $templater->push(); - $method = is_string($options['templates']) ? 'load' : 'add'; - $templater->{$method}($options['templates']); - } - unset($options['templates']); - - if ($options['action'] === false || $options['url'] === false) { - $url = $this->request->getRequestTarget(); - $action = null; - } else { - $url = $this->_formUrl($context, $options); - $action = $this->Url->build($url); - } - - $this->_lastAction($url); - unset($options['url'], $options['action'], $options['idPrefix']); - - $htmlAttributes = []; - switch (strtolower($options['type'])) { - case 'get': - $htmlAttributes['method'] = 'get'; - break; - // Set enctype for form - case 'file': - $htmlAttributes['enctype'] = 'multipart/form-data'; - $options['type'] = $isCreate ? 'post' : 'put'; - // Move on - case 'post': - // Move on - case 'put': - // Move on - case 'delete': - // Set patch method - case 'patch': - $append .= $this->hidden('_method', [ - 'name' => '_method', - 'value' => strtoupper($options['type']), - 'secure' => static::SECURE_SKIP - ]); - // Default to post method - default: - $htmlAttributes['method'] = 'post'; - } - if (isset($options['method'])) { - $htmlAttributes['method'] = strtolower($options['method']); - } - if (isset($options['enctype'])) { - $htmlAttributes['enctype'] = strtolower($options['enctype']); - } - - $this->requestType = strtolower($options['type']); - - if (!empty($options['encoding'])) { - $htmlAttributes['accept-charset'] = $options['encoding']; - } - unset($options['type'], $options['encoding']); - - $htmlAttributes += $options; - - $this->fields = []; - if ($this->requestType !== 'get') { - $append .= $this->_csrfField(); - } - - if (!empty($append)) { - $append = $templater->format('hiddenBlock', ['content' => $append]); - } - - $actionAttr = $templater->formatAttributes(['action' => $action, 'escape' => false]); - - return $this->formatTemplate('formStart', [ - 'attrs' => $templater->formatAttributes($htmlAttributes) . $actionAttr, - 'templateVars' => isset($options['templateVars']) ? $options['templateVars'] : [] - ]) . $append; - } - - /** - * Create the URL for a form based on the options. - * - * @param \Cake\View\Form\ContextInterface $context The context object to use. - * @param array $options An array of options from create() - * @return string|array The action attribute for the form. - */ - protected function _formUrl($context, $options) - { - if ($options['action'] === null && $options['url'] === null) { - return $this->request->getRequestTarget(); - } - - if (is_string($options['url']) || - (is_array($options['url']) && isset($options['url']['_name'])) - ) { - return $options['url']; - } - - if (isset($options['action']) && empty($options['url']['action'])) { - $options['url']['action'] = $options['action']; - } - - $actionDefaults = [ - 'plugin' => $this->plugin, - 'controller' => $this->request->getParam('controller'), - 'action' => $this->request->getParam('action'), - ]; - - $action = (array)$options['url'] + $actionDefaults; - - $pk = $context->primaryKey(); - if (count($pk)) { - $id = $this->getSourceValue($pk[0]); - } - if (empty($action[0]) && isset($id)) { - $action[0] = $id; - } - - return $action; - } - - /** - * Correctly store the last created form action URL. - * - * @param string|array $url The URL of the last form. - * @return void - */ - protected function _lastAction($url) - { - $action = Router::url($url, true); - $query = parse_url($action, PHP_URL_QUERY); - $query = $query ? '?' . $query : ''; - $this->_lastAction = parse_url($action, PHP_URL_PATH) . $query; - } - - /** - * Return a CSRF input if the request data is present. - * Used to secure forms in conjunction with CsrfComponent & - * SecurityComponent - * - * @return string - */ - protected function _csrfField() - { - if ($this->request->getParam('_Token.unlockedFields')) { - foreach ((array)$this->request->getParam('_Token.unlockedFields') as $unlocked) { - $this->_unlockedFields[] = $unlocked; - } - } - if (!$this->request->getParam('_csrfToken')) { - return ''; - } - - return $this->hidden('_csrfToken', [ - 'value' => $this->request->getParam('_csrfToken'), - 'secure' => static::SECURE_SKIP, - 'autocomplete' => 'off', - ]); - } - - /** - * Closes an HTML form, cleans up values set by FormHelper::create(), and writes hidden - * input fields where appropriate. - * - * Resets some parts of the state, shared among multiple FormHelper::create() calls, to defaults. - * - * @param array $secureAttributes Secure attributes which will be passed as HTML attributes - * into the hidden input elements generated for the Security Component. - * @return string A closing FORM tag. - * @link https://book.cakephp.org/3.0/en/views/helpers/form.html#closing-the-form - */ - public function end(array $secureAttributes = []) - { - $out = ''; - - if ($this->requestType !== 'get' && $this->request->getParam('_Token')) { - $out .= $this->secure($this->fields, $secureAttributes); - $this->fields = []; - $this->_unlockedFields = []; - } - $out .= $this->formatTemplate('formEnd', []); - - $this->templater()->pop(); - $this->requestType = null; - $this->_context = null; - $this->_valueSources = ['context']; - $this->_idPrefix = $this->getConfig('idPrefix'); - - return $out; - } - - /** - * Generates a hidden field with a security hash based on the fields used in - * the form. - * - * If $secureAttributes is set, these HTML attributes will be merged into - * the hidden input tags generated for the Security Component. This is - * especially useful to set HTML5 attributes like 'form'. - * - * @param array $fields If set specifies the list of fields to use when - * generating the hash, else $this->fields is being used. - * @param array $secureAttributes will be passed as HTML attributes into the hidden - * input elements generated for the Security Component. - * @return string A hidden input field with a security hash, or empty string when - * secured forms are not in use. - */ - public function secure(array $fields = [], array $secureAttributes = []) - { - if (!$this->request->getParam('_Token')) { - return ''; - } - $debugSecurity = Configure::read('debug'); - if (isset($secureAttributes['debugSecurity'])) { - $debugSecurity = $debugSecurity && $secureAttributes['debugSecurity']; - unset($secureAttributes['debugSecurity']); - } - $secureAttributes['secure'] = static::SECURE_SKIP; - $secureAttributes['autocomplete'] = 'off'; - - $tokenData = $this->_buildFieldToken( - $this->_lastAction, - $fields, - $this->_unlockedFields - ); - $tokenFields = array_merge($secureAttributes, [ - 'value' => $tokenData['fields'], - ]); - $out = $this->hidden('_Token.fields', $tokenFields); - $tokenUnlocked = array_merge($secureAttributes, [ - 'value' => $tokenData['unlocked'], - ]); - $out .= $this->hidden('_Token.unlocked', $tokenUnlocked); - if ($debugSecurity) { - $tokenDebug = array_merge($secureAttributes, [ - 'value' => urlencode(json_encode([ - $this->_lastAction, - $fields, - $this->_unlockedFields - ])), - ]); - $out .= $this->hidden('_Token.debug', $tokenDebug); - } - - return $this->formatTemplate('hiddenBlock', ['content' => $out]); - } - - /** - * Add to or get the list of fields that are currently unlocked. - * Unlocked fields are not included in the field hash used by SecurityComponent - * unlocking a field once its been added to the list of secured fields will remove - * it from the list of fields. - * - * @param string|null $name The dot separated name for the field. - * @return array|null Either null, or the list of fields. - * @link https://book.cakephp.org/3.0/en/views/helpers/form.html#working-with-securitycomponent - */ - public function unlockField($name = null) - { - if ($name === null) { - return $this->_unlockedFields; - } - if (!in_array($name, $this->_unlockedFields)) { - $this->_unlockedFields[] = $name; - } - $index = array_search($name, $this->fields); - if ($index !== false) { - unset($this->fields[$index]); - } - unset($this->fields[$name]); - } - - /** - * Determine which fields of a form should be used for hash. - * Populates $this->fields - * - * @param bool $lock Whether this field should be part of the validation - * or excluded as part of the unlockedFields. - * @param string|array $field Reference to field to be secured. Can be dot - * separated string to indicate nesting or array of fieldname parts. - * @param mixed $value Field value, if value should not be tampered with. - * @return void - */ - protected function _secure($lock, $field, $value = null) - { - if (empty($field) && $field !== '0') { - return; - } - - if (is_string($field)) { - $field = Hash::filter(explode('.', $field)); - } - - foreach ($this->_unlockedFields as $unlockField) { - $unlockParts = explode('.', $unlockField); - if (array_values(array_intersect($field, $unlockParts)) === $unlockParts) { - return; - } - } - - $field = implode('.', $field); - $field = preg_replace('/(\.\d+)+$/', '', $field); - - if ($lock) { - if (!in_array($field, $this->fields)) { - if ($value !== null) { - $this->fields[$field] = $value; - - return; - } - if (isset($this->fields[$field]) && $value === null) { - unset($this->fields[$field]); - } - $this->fields[] = $field; - } - } else { - $this->unlockField($field); - } - } - - /** - * Returns true if there is an error for the given field, otherwise false - * - * @param string $field This should be "modelname.fieldname" - * @return bool If there are errors this method returns true, else false. - * @link https://book.cakephp.org/3.0/en/views/helpers/form.html#displaying-and-checking-errors - */ - public function isFieldError($field) - { - return $this->_getContext()->hasError($field); - } - - /** - * Returns a formatted error message for given form field, '' if no errors. - * - * Uses the `error`, `errorList` and `errorItem` templates. The `errorList` and - * `errorItem` templates are used to format multiple error messages per field. - * - * ### Options: - * - * - `escape` boolean - Whether or not to html escape the contents of the error. - * - * @param string $field A field name, like "modelname.fieldname" - * @param string|array|null $text Error message as string or array of messages. If an array, - * it should be a hash of key names => messages. - * @param array $options See above. - * @return string Formatted errors or ''. - * @link https://book.cakephp.org/3.0/en/views/helpers/form.html#displaying-and-checking-errors - */ - public function error($field, $text = null, array $options = []) - { - if (substr($field, -5) === '._ids') { - $field = substr($field, 0, -5); - } - $options += ['escape' => true]; - - $context = $this->_getContext(); - if (!$context->hasError($field)) { - return ''; - } - $error = (array)$context->error($field); - - if (is_array($text)) { - $tmp = []; - foreach ($error as $k => $e) { - if (isset($text[$k])) { - $tmp[] = $text[$k]; - } elseif (isset($text[$e])) { - $tmp[] = $text[$e]; - } else { - $tmp[] = $e; - } - } - $text = $tmp; - } - - if ($text !== null) { - $error = $text; - } - - if ($options['escape']) { - $error = h($error); - unset($options['escape']); - } - - if (is_array($error)) { - if (count($error) > 1) { - $errorText = []; - foreach ($error as $err) { - $errorText[] = $this->formatTemplate('errorItem', ['text' => $err]); - } - $error = $this->formatTemplate('errorList', [ - 'content' => implode('', $errorText) - ]); - } else { - $error = array_pop($error); - } - } - - return $this->formatTemplate('error', ['content' => $error]); - } - - /** - * Returns a formatted LABEL element for HTML forms. - * - * Will automatically generate a `for` attribute if one is not provided. - * - * ### Options - * - * - `for` - Set the for attribute, if its not defined the for attribute - * will be generated from the $fieldName parameter using - * FormHelper::_domId(). - * - * Examples: - * - * The text and for attribute are generated off of the fieldname - * - * ``` - * echo $this->Form->label('published'); - * - * ``` - * - * Custom text: - * - * ``` - * echo $this->Form->label('published', 'Publish'); - * - * ``` - * - * Custom attributes: - * - * ``` - * echo $this->Form->label('published', 'Publish', [ - * 'for' => 'post-publish' - * ]); - * - * ``` - * - * Nesting an input tag: - * - * ``` - * echo $this->Form->label('published', 'Publish', [ - * 'for' => 'published', - * 'input' => $this->text('published'), - * ]); - * - * ``` - * - * If you want to nest inputs in the labels, you will need to modify the default templates. - * - * @param string $fieldName This should be "modelname.fieldname" - * @param string|null $text Text that will appear in the label field. If - * $text is left undefined the text will be inflected from the - * fieldName. - * @param array $options An array of HTML attributes. - * @return string The formatted LABEL element - * @link https://book.cakephp.org/3.0/en/views/helpers/form.html#creating-labels - */ - public function label($fieldName, $text = null, array $options = []) - { - if ($text === null) { - $text = $fieldName; - if (substr($text, -5) === '._ids') { - $text = substr($text, 0, -5); - } - if (strpos($text, '.') !== false) { - $fieldElements = explode('.', $text); - $text = array_pop($fieldElements); - } - if (substr($text, -3) === '_id') { - $text = substr($text, 0, -3); - } - $text = __(Inflector::humanize(Inflector::underscore($text))); - } - - if (isset($options['for'])) { - $labelFor = $options['for']; - unset($options['for']); - } else { - $labelFor = $this->_domId($fieldName); - } - $attrs = $options + [ - 'for' => $labelFor, - 'text' => $text, - ]; - if (isset($options['input'])) { - if (is_array($options['input'])) { - $attrs = $options['input'] + $attrs; - } - - return $this->widget('nestingLabel', $attrs); - } - - return $this->widget('label', $attrs); - } - - /** - * Generate a set of controls for `$fields`. If $fields is empty the fields - * of current model will be used. - * - * You can customize individual controls through `$fields`. - * ``` - * $this->Form->allControls([ - * 'name' => ['label' => 'custom label'] - * ]); - * ``` - * - * You can exclude fields by specifying them as `false`: - * - * ``` - * $this->Form->allControls(['title' => false]); - * ``` - * - * In the above example, no field would be generated for the title field. - * - * @param array $fields An array of customizations for the fields that will be - * generated. This array allows you to set custom types, labels, or other options. - * @param array $options Options array. Valid keys are: - * - `fieldset` Set to false to disable the fieldset. You can also pass an array of params to be - * applied as HTML attributes to the fieldset tag. If you pass an empty array, the fieldset will - * be enabled - * - `legend` Set to false to disable the legend for the generated control set. Or supply a string - * to customize the legend text. - * @return string Completed form controls. - * @link https://book.cakephp.org/3.0/en/views/helpers/form.html#generating-entire-forms - */ - public function allControls(array $fields = [], array $options = []) - { - $context = $this->_getContext(); - - $modelFields = $context->fieldNames(); - - $fields = array_merge( - Hash::normalize($modelFields), - Hash::normalize($fields) - ); - - return $this->controls($fields, $options); - } - - /** - * Generate a set of controls for `$fields`. If $fields is empty the fields - * of current model will be used. - * - * @param array $fields An array of customizations for the fields that will be - * generated. This array allows you to set custom types, labels, or other options. - * @param array $options Options array. Valid keys are: - * - `fieldset` Set to false to disable the fieldset. You can also pass an array of params to be - * applied as HTML attributes to the fieldset tag. If you pass an empty array, the fieldset will - * be enabled - * - `legend` Set to false to disable the legend for the generated control set. Or supply a string - * to customize the legend text. - * @return string Completed form controls. - * @link https://book.cakephp.org/3.0/en/views/helpers/form.html#generating-entire-forms - * @deprecated 3.4.0 Use FormHelper::allControls() instead. - */ - public function allInputs(array $fields = [], array $options = []) - { - deprecationWarning( - 'FormHelper::allInputs() is deprecated. ' . - 'Use FormHelper::allControls() instead.' - ); - - return $this->allControls($fields, $options); - } - - /** - * Generate a set of controls for `$fields` wrapped in a fieldset element. - * - * You can customize individual controls through `$fields`. - * ``` - * $this->Form->controls([ - * 'name' => ['label' => 'custom label'], - * 'email' - * ]); - * ``` - * - * @param array $fields An array of the fields to generate. This array allows - * you to set custom types, labels, or other options. - * @param array $options Options array. Valid keys are: - * - `fieldset` Set to false to disable the fieldset. You can also pass an - * array of params to be applied as HTML attributes to the fieldset tag. - * If you pass an empty array, the fieldset will be enabled. - * - `legend` Set to false to disable the legend for the generated input set. - * Or supply a string to customize the legend text. - * @return string Completed form inputs. - * @link https://book.cakephp.org/3.0/en/views/helpers/form.html#generating-entire-forms - */ - public function controls(array $fields, array $options = []) - { - $fields = Hash::normalize($fields); - - $out = ''; - foreach ($fields as $name => $opts) { - if ($opts === false) { - continue; - } - - $out .= $this->control($name, (array)$opts); - } - - return $this->fieldset($out, $options); - } - - /** - * Generate a set of controls for `$fields` wrapped in a fieldset element. - * - * @param array $fields An array of the fields to generate. This array allows - * you to set custom types, labels, or other options. - * @param array $options Options array. Valid keys are: - * - `fieldset` Set to false to disable the fieldset. You can also pass an - * array of params to be applied as HTML attributes to the fieldset tag. - * If you pass an empty array, the fieldset will be enabled. - * - `legend` Set to false to disable the legend for the generated input set. - * Or supply a string to customize the legend text. - * @return string Completed form inputs. - * @link https://book.cakephp.org/3.0/en/views/helpers/form.html#generating-entire-forms - * @deprecated 3.4.0 Use FormHelper::controls() instead. - */ - public function inputs(array $fields, array $options = []) - { - deprecationWarning( - 'FormHelper::inputs() is deprecated. ' . - 'Use FormHelper::controls() instead.' - ); - - return $this->controls($fields, $options); - } - - /** - * Wrap a set of inputs in a fieldset - * - * @param string $fields the form inputs to wrap in a fieldset - * @param array $options Options array. Valid keys are: - * - `fieldset` Set to false to disable the fieldset. You can also pass an array of params to be - * applied as HTML attributes to the fieldset tag. If you pass an empty array, the fieldset will - * be enabled - * - `legend` Set to false to disable the legend for the generated input set. Or supply a string - * to customize the legend text. - * @return string Completed form inputs. - */ - public function fieldset($fields = '', array $options = []) - { - $fieldset = $legend = true; - $context = $this->_getContext(); - $out = $fields; - - if (isset($options['legend'])) { - $legend = $options['legend']; - } - if (isset($options['fieldset'])) { - $fieldset = $options['fieldset']; - } - - if ($legend === true) { - $isCreate = $context->isCreate(); - $modelName = Inflector::humanize(Inflector::singularize($this->request->getParam('controller'))); - if (!$isCreate) { - $legend = __d('cake', 'Edit {0}', $modelName); - } else { - $legend = __d('cake', 'New {0}', $modelName); - } - } - - if ($fieldset !== false) { - if ($legend) { - $out = $this->formatTemplate('legend', ['text' => $legend]) . $out; - } - - $fieldsetParams = ['content' => $out, 'attrs' => '']; - if (is_array($fieldset) && !empty($fieldset)) { - $fieldsetParams['attrs'] = $this->templater()->formatAttributes($fieldset); - } - $out = $this->formatTemplate('fieldset', $fieldsetParams); - } - - return $out; - } - - /** - * Generates a form control element complete with label and wrapper div. - * - * ### Options - * - * See each field type method for more information. Any options that are part of - * $attributes or $options for the different **type** methods can be included in `$options` for input(). - * Additionally, any unknown keys that are not in the list below, or part of the selected type's options - * will be treated as a regular HTML attribute for the generated input. - * - * - `type` - Force the type of widget you want. e.g. `type => 'select'` - * - `label` - Either a string label, or an array of options for the label. See FormHelper::label(). - * - `options` - For widgets that take options e.g. radio, select. - * - `error` - Control the error message that is produced. Set to `false` to disable any kind of error reporting (field - * error and error messages). - * - `empty` - String or boolean to enable empty select box options. - * - `nestedInput` - Used with checkbox and radio inputs. Set to false to render inputs outside of label - * elements. Can be set to true on any input to force the input inside the label. If you - * enable this option for radio buttons you will also need to modify the default `radioWrapper` template. - * - `templates` - The templates you want to use for this input. Any templates will be merged on top of - * the already loaded templates. This option can either be a filename in /config that contains - * the templates you want to load, or an array of templates to use. - * - `labelOptions` - Either `false` to disable label around nestedWidgets e.g. radio, multicheckbox or an array - * of attributes for the label tag. `selected` will be added to any classes e.g. `class => 'myclass'` where - * widget is checked - * - * @param string $fieldName This should be "modelname.fieldname" - * @param array $options Each type of input takes different options. - * @return string Completed form widget. - * @link https://book.cakephp.org/3.0/en/views/helpers/form.html#creating-form-inputs - */ - public function control($fieldName, array $options = []) - { - $options += [ - 'type' => null, - 'label' => null, - 'error' => null, - 'required' => null, - 'options' => null, - 'templates' => [], - 'templateVars' => [], - 'labelOptions' => true - ]; - $options = $this->_parseOptions($fieldName, $options); - $options += ['id' => $this->_domId($fieldName)]; - - $templater = $this->templater(); - $newTemplates = $options['templates']; - - if ($newTemplates) { - $templater->push(); - $templateMethod = is_string($options['templates']) ? 'load' : 'add'; - $templater->{$templateMethod}($options['templates']); - } - unset($options['templates']); - - $error = null; - $errorSuffix = ''; - if ($options['type'] !== 'hidden' && $options['error'] !== false) { - if (is_array($options['error'])) { - $error = $this->error($fieldName, $options['error'], $options['error']); - } else { - $error = $this->error($fieldName, $options['error']); - } - $errorSuffix = empty($error) ? '' : 'Error'; - unset($options['error']); - } - - $label = $options['label']; - unset($options['label']); - - $labelOptions = $options['labelOptions']; - unset($options['labelOptions']); - - $nestedInput = false; - if ($options['type'] === 'checkbox') { - $nestedInput = true; - } - $nestedInput = isset($options['nestedInput']) ? $options['nestedInput'] : $nestedInput; - unset($options['nestedInput']); - - if ($nestedInput === true && $options['type'] === 'checkbox' && !array_key_exists('hiddenField', $options) && $label !== false) { - $options['hiddenField'] = '_split'; - } - - $input = $this->_getInput($fieldName, $options + ['labelOptions' => $labelOptions]); - if ($options['type'] === 'hidden' || $options['type'] === 'submit') { - if ($newTemplates) { - $templater->pop(); - } - - return $input; - } - - $label = $this->_getLabel($fieldName, compact('input', 'label', 'error', 'nestedInput') + $options); - if ($nestedInput) { - $result = $this->_groupTemplate(compact('label', 'error', 'options')); - } else { - $result = $this->_groupTemplate(compact('input', 'label', 'error', 'options')); - } - $result = $this->_inputContainerTemplate([ - 'content' => $result, - 'error' => $error, - 'errorSuffix' => $errorSuffix, - 'options' => $options - ]); - - if ($newTemplates) { - $templater->pop(); - } - - return $result; - } - - /** - * Generates a form control element complete with label and wrapper div. - * - * @param string $fieldName This should be "modelname.fieldname" - * @param array $options Each type of input takes different options. - * @return string Completed form widget. - * @link https://book.cakephp.org/3.0/en/views/helpers/form.html#creating-form-inputs - * @deprecated 3.4.0 Use FormHelper::control() instead. - */ - public function input($fieldName, array $options = []) - { - deprecationWarning( - 'FormHelper::input() is deprecated. ' . - 'Use FormHelper::control() instead.' - ); - - return $this->control($fieldName, $options); - } - - /** - * Generates an group template element - * - * @param array $options The options for group template - * @return string The generated group template - */ - protected function _groupTemplate($options) - { - $groupTemplate = $options['options']['type'] . 'FormGroup'; - if (!$this->templater()->get($groupTemplate)) { - $groupTemplate = 'formGroup'; - } - - return $this->formatTemplate($groupTemplate, [ - 'input' => isset($options['input']) ? $options['input'] : [], - 'label' => $options['label'], - 'error' => $options['error'], - 'templateVars' => isset($options['options']['templateVars']) ? $options['options']['templateVars'] : [] - ]); - } - - /** - * Generates an input container template - * - * @param array $options The options for input container template - * @return string The generated input container template - */ - protected function _inputContainerTemplate($options) - { - $inputContainerTemplate = $options['options']['type'] . 'Container' . $options['errorSuffix']; - if (!$this->templater()->get($inputContainerTemplate)) { - $inputContainerTemplate = 'inputContainer' . $options['errorSuffix']; - } - - return $this->formatTemplate($inputContainerTemplate, [ - 'content' => $options['content'], - 'error' => $options['error'], - 'required' => $options['options']['required'] ? ' required' : '', - 'type' => $options['options']['type'], - 'templateVars' => isset($options['options']['templateVars']) ? $options['options']['templateVars'] : [] - ]); - } - - /** - * Generates an input element - * - * @param string $fieldName the field name - * @param array $options The options for the input element - * @return string The generated input element - */ - protected function _getInput($fieldName, $options) - { - $label = $options['labelOptions']; - unset($options['labelOptions']); - switch (strtolower($options['type'])) { - case 'select': - $opts = $options['options']; - unset($options['options']); - - return $this->select($fieldName, $opts, $options + ['label' => $label]); - case 'radio': - $opts = $options['options']; - unset($options['options']); - - return $this->radio($fieldName, $opts, $options + ['label' => $label]); - case 'multicheckbox': - $opts = $options['options']; - unset($options['options']); - - return $this->multiCheckbox($fieldName, $opts, $options + ['label' => $label]); - case 'input': - throw new RuntimeException("Invalid type 'input' used for field '$fieldName'"); - - default: - return $this->{$options['type']}($fieldName, $options); - } - } - - /** - * Generates input options array - * - * @param string $fieldName The name of the field to parse options for. - * @param array $options Options list. - * @return array Options - */ - protected function _parseOptions($fieldName, $options) - { - $needsMagicType = false; - if (empty($options['type'])) { - $needsMagicType = true; - $options['type'] = $this->_inputType($fieldName, $options); - } - - $options = $this->_magicOptions($fieldName, $options, $needsMagicType); - - return $options; - } - - /** - * Returns the input type that was guessed for the provided fieldName, - * based on the internal type it is associated too, its name and the - * variables that can be found in the view template - * - * @param string $fieldName the name of the field to guess a type for - * @param array $options the options passed to the input method - * @return string - */ - protected function _inputType($fieldName, $options) - { - $context = $this->_getContext(); - - if ($context->isPrimaryKey($fieldName)) { - return 'hidden'; - } - - if (substr($fieldName, -3) === '_id') { - return 'select'; - } - - $internalType = $context->type($fieldName); - $map = $this->_config['typeMap']; - $type = isset($map[$internalType]) ? $map[$internalType] : 'text'; - $fieldName = array_slice(explode('.', $fieldName), -1)[0]; - - switch (true) { - case isset($options['checked']): - return 'checkbox'; - case isset($options['options']): - return 'select'; - case in_array($fieldName, ['passwd', 'password']): - return 'password'; - case in_array($fieldName, ['tel', 'telephone', 'phone']): - return 'tel'; - case $fieldName === 'email': - return 'email'; - case isset($options['rows']) || isset($options['cols']): - return 'textarea'; - } - - return $type; - } - - /** - * Selects the variable containing the options for a select field if present, - * and sets the value to the 'options' key in the options array. - * - * @param string $fieldName The name of the field to find options for. - * @param array $options Options list. - * @return array - */ - protected function _optionsOptions($fieldName, $options) - { - if (isset($options['options'])) { - return $options; - } - - $pluralize = true; - if (substr($fieldName, -5) === '._ids') { - $fieldName = substr($fieldName, 0, -5); - $pluralize = false; - } elseif (substr($fieldName, -3) === '_id') { - $fieldName = substr($fieldName, 0, -3); - } - $fieldName = array_slice(explode('.', $fieldName), -1)[0]; - - $varName = Inflector::variable( - $pluralize ? Inflector::pluralize($fieldName) : $fieldName - ); - $varOptions = $this->_View->get($varName); - if (!is_array($varOptions) && !($varOptions instanceof Traversable)) { - return $options; - } - if ($options['type'] !== 'radio') { - $options['type'] = 'select'; - } - $options['options'] = $varOptions; - - return $options; - } - - /** - * Magically set option type and corresponding options - * - * @param string $fieldName The name of the field to generate options for. - * @param array $options Options list. - * @param bool $allowOverride Whether or not it is allowed for this method to - * overwrite the 'type' key in options. - * @return array - */ - protected function _magicOptions($fieldName, $options, $allowOverride) - { - $context = $this->_getContext(); - - if (!isset($options['required']) && $options['type'] !== 'hidden') { - $options['required'] = $context->isRequired($fieldName); - } - - $type = $context->type($fieldName); - $fieldDef = $context->attributes($fieldName); - - if ($options['type'] === 'number' && !isset($options['step'])) { - if ($type === 'decimal' && isset($fieldDef['precision'])) { - $decimalPlaces = $fieldDef['precision']; - $options['step'] = sprintf('%.' . $decimalPlaces . 'F', pow(10, -1 * $decimalPlaces)); - } elseif ($type === 'float') { - $options['step'] = 'any'; - } - } - - $typesWithOptions = ['text', 'number', 'radio', 'select']; - $magicOptions = (in_array($options['type'], ['radio', 'select']) || $allowOverride); - if ($magicOptions && in_array($options['type'], $typesWithOptions)) { - $options = $this->_optionsOptions($fieldName, $options); - } - - if ($allowOverride && substr($fieldName, -5) === '._ids') { - $options['type'] = 'select'; - if ((!isset($options['multiple']) || ($options['multiple'] && $options['multiple'] != 'checkbox'))) { - $options['multiple'] = true; - } - } - - if ($options['type'] === 'select' && array_key_exists('step', $options)) { - unset($options['step']); - } - - $autoLength = !array_key_exists('maxlength', $options) - && !empty($fieldDef['length']) - && $options['type'] !== 'select'; - - $allowedTypes = ['text', 'textarea', 'email', 'tel', 'url', 'search']; - if ($autoLength && in_array($options['type'], $allowedTypes)) { - $options['maxlength'] = min($fieldDef['length'], 100000); - } - - if (in_array($options['type'], ['datetime', 'date', 'time', 'select'])) { - $options += ['empty' => false]; - } - - return $options; - } - - /** - * Generate label for input - * - * @param string $fieldName The name of the field to generate label for. - * @param array $options Options list. - * @return bool|string false or Generated label element - */ - protected function _getLabel($fieldName, $options) - { - if ($options['type'] === 'hidden') { - return false; - } - - $label = null; - if (isset($options['label'])) { - $label = $options['label']; - } - - if ($label === false && $options['type'] === 'checkbox') { - return $options['input']; - } - if ($label === false) { - return false; - } - - return $this->_inputLabel($fieldName, $label, $options); - } - - /** - * Extracts a single option from an options array. - * - * @param string $name The name of the option to pull out. - * @param array $options The array of options you want to extract. - * @param mixed $default The default option value - * @return mixed the contents of the option or default - */ - protected function _extractOption($name, $options, $default = null) - { - if (array_key_exists($name, $options)) { - return $options[$name]; - } - - return $default; - } - - /** - * Generate a label for an input() call. - * - * $options can contain a hash of id overrides. These overrides will be - * used instead of the generated values if present. - * - * @param string $fieldName The name of the field to generate label for. - * @param string $label Label text. - * @param array $options Options for the label element. - * @return string Generated label element - */ - protected function _inputLabel($fieldName, $label, $options) - { - $options += ['id' => null, 'input' => null, 'nestedInput' => false, 'templateVars' => []]; - $labelAttributes = ['templateVars' => $options['templateVars']]; - if (is_array($label)) { - $labelText = null; - if (isset($label['text'])) { - $labelText = $label['text']; - unset($label['text']); - } - $labelAttributes = array_merge($labelAttributes, $label); - } else { - $labelText = $label; - } - - $labelAttributes['for'] = $options['id']; - if (in_array($options['type'], $this->_groupedInputTypes, true)) { - $labelAttributes['for'] = false; - } - if ($options['nestedInput']) { - $labelAttributes['input'] = $options['input']; - } - if (isset($options['escape'])) { - $labelAttributes['escape'] = $options['escape']; - } - - return $this->label($fieldName, $labelText, $labelAttributes); - } - - /** - * Creates a checkbox input widget. - * - * ### Options: - * - * - `value` - the value of the checkbox - * - `checked` - boolean indicate that this checkbox is checked. - * - `hiddenField` - boolean to indicate if you want the results of checkbox() to include - * a hidden input with a value of ''. - * - `disabled` - create a disabled input. - * - `default` - Set the default value for the checkbox. This allows you to start checkboxes - * as checked, without having to check the POST data. A matching POST data value, will overwrite - * the default value. - * - * @param string $fieldName Name of a field, like this "modelname.fieldname" - * @param array $options Array of HTML attributes. - * @return string|array An HTML text input element. - * @link https://book.cakephp.org/3.0/en/views/helpers/form.html#creating-checkboxes - */ - public function checkbox($fieldName, array $options = []) - { - $options += ['hiddenField' => true, 'value' => 1]; - - // Work around value=>val translations. - $value = $options['value']; - unset($options['value']); - $options = $this->_initInputField($fieldName, $options); - $options['value'] = $value; - - $output = ''; - if ($options['hiddenField']) { - $hiddenOptions = [ - 'name' => $options['name'], - 'value' => $options['hiddenField'] !== true && $options['hiddenField'] !== '_split' ? $options['hiddenField'] : '0', - 'form' => isset($options['form']) ? $options['form'] : null, - 'secure' => false - ]; - if (isset($options['disabled']) && $options['disabled']) { - $hiddenOptions['disabled'] = 'disabled'; - } - $output = $this->hidden($fieldName, $hiddenOptions); - } - - if ($options['hiddenField'] === '_split') { - unset($options['hiddenField'], $options['type']); - - return ['hidden' => $output, 'input' => $this->widget('checkbox', $options)]; - } - unset($options['hiddenField'], $options['type']); - - return $output . $this->widget('checkbox', $options); - } - - /** - * Creates a set of radio widgets. - * - * ### Attributes: - * - * - `value` - Indicates the value when this radio button is checked. - * - `label` - Either `false` to disable label around the widget or an array of attributes for - * the label tag. `selected` will be added to any classes e.g. `'class' => 'myclass'` where widget - * is checked - * - `hiddenField` - boolean to indicate if you want the results of radio() to include - * a hidden input with a value of ''. This is useful for creating radio sets that are non-continuous. - * - `disabled` - Set to `true` or `disabled` to disable all the radio buttons. Use an array of - * values to disable specific radio buttons. - * - `empty` - Set to `true` to create an input with the value '' as the first option. When `true` - * the radio label will be 'empty'. Set this option to a string to control the label value. - * - * @param string $fieldName Name of a field, like this "modelname.fieldname" - * @param array|\Traversable $options Radio button options array. - * @param array $attributes Array of attributes. - * @return string Completed radio widget set. - * @link https://book.cakephp.org/3.0/en/views/helpers/form.html#creating-radio-buttons - */ - public function radio($fieldName, $options = [], array $attributes = []) - { - $attributes['options'] = $options; - $attributes['idPrefix'] = $this->_idPrefix; - $attributes = $this->_initInputField($fieldName, $attributes); - - $hiddenField = isset($attributes['hiddenField']) ? $attributes['hiddenField'] : true; - unset($attributes['hiddenField']); - - $radio = $this->widget('radio', $attributes); - - $hidden = ''; - if ($hiddenField) { - $hidden = $this->hidden($fieldName, [ - 'value' => $hiddenField === true ? '' : $hiddenField, - 'form' => isset($attributes['form']) ? $attributes['form'] : null, - 'name' => $attributes['name'], - ]); - } - - return $hidden . $radio; - } - - /** - * Missing method handler - implements various simple input types. Is used to create inputs - * of various types. e.g. `$this->Form->text();` will create `` while - * `$this->Form->range();` will create `` - * - * ### Usage - * - * ``` - * $this->Form->search('User.query', ['value' => 'test']); - * ``` - * - * Will make an input like: - * - * `` - * - * The first argument to an input type should always be the fieldname, in `Model.field` format. - * The second argument should always be an array of attributes for the input. - * - * @param string $method Method name / input type to make. - * @param array $params Parameters for the method call - * @return string Formatted input method. - * @throws \Cake\Core\Exception\Exception When there are no params for the method call. - */ - public function __call($method, $params) - { - $options = []; - if (empty($params)) { - throw new Exception(sprintf('Missing field name for FormHelper::%s', $method)); - } - if (isset($params[1])) { - $options = $params[1]; - } - if (!isset($options['type'])) { - $options['type'] = $method; - } - $options = $this->_initInputField($params[0], $options); - - return $this->widget($options['type'], $options); - } - - /** - * Creates a textarea widget. - * - * ### Options: - * - * - `escape` - Whether or not the contents of the textarea should be escaped. Defaults to true. - * - * @param string $fieldName Name of a field, in the form "modelname.fieldname" - * @param array $options Array of HTML attributes, and special options above. - * @return string A generated HTML text input element - * @link https://book.cakephp.org/3.0/en/views/helpers/form.html#creating-textareas - */ - public function textarea($fieldName, array $options = []) - { - $options = $this->_initInputField($fieldName, $options); - unset($options['type']); - - return $this->widget('textarea', $options); - } - - /** - * Creates a hidden input field. - * - * @param string $fieldName Name of a field, in the form of "modelname.fieldname" - * @param array $options Array of HTML attributes. - * @return string A generated hidden input - * @link https://book.cakephp.org/3.0/en/views/helpers/form.html#creating-hidden-inputs - */ - public function hidden($fieldName, array $options = []) - { - $options += ['required' => false, 'secure' => true]; - - $secure = $options['secure']; - unset($options['secure']); - - $options = $this->_initInputField($fieldName, array_merge( - $options, - ['secure' => static::SECURE_SKIP] - )); - - if ($secure === true) { - $this->_secure(true, $this->_secureFieldName($options['name']), (string)$options['val']); - } - - $options['type'] = 'hidden'; - - return $this->widget('hidden', $options); - } - - /** - * Creates file input widget. - * - * @param string $fieldName Name of a field, in the form "modelname.fieldname" - * @param array $options Array of HTML attributes. - * @return string A generated file input. - * @link https://book.cakephp.org/3.0/en/views/helpers/form.html#creating-file-inputs - */ - public function file($fieldName, array $options = []) - { - $options += ['secure' => true]; - $options = $this->_initInputField($fieldName, $options); - - unset($options['type']); - - return $this->widget('file', $options); - } - - /** - * Creates a `