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
-
-[](https://scrutinizer-ci.com/g/auraphp/Aura.Intl/)
-[](https://scrutinizer-ci.com/g/auraphp/Aura.Intl/)
-[](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 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
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 wraptags 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 @@ -[](https://packagist.org/packages/cakephp/database) -[](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 @@ -[](https://packagist.org/packages/cakephp/datasource) -[](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', - 'context' => '{:trace}
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 = '{:context}
'; - $e .= '{:error} ({:code}): {:description} '; - $e .= '[{:path}, line {:line}]'; - - $e .= ''; - $this->_templates['js']['error'] = $e; - - $t = ' '; - $e .= ' '; - $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'] .= ''; - } - - /** - * 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{:context}
'], - '', - $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 @@ -[](https://packagist.org/packages/cakephp/filesystem) -[](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 @@ -[](https://packagist.org/packages/cakephp/i18n) -[](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%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 @@ -[](https://packagist.org/packages/cakephp/orm) -[](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 . '' . $style . '>'; - } -} 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) : ?> -
-- = $alias ?>
- -
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 - --getTrace() as $i => $stack): ?> - -
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 @@ -- - - - - 〉 = h($stack['class'] . $stack['type'] . $stack['function']) ?> - - 〉 = h($stack['function']) ?> - - - - = h(Debugger::trimPath($stack['file'])) ?>, line = $stack['line'] ?> - - [internal function] - - - - - 〉 [internal function] - -
- -
'; - -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: - = $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:
--= Debugger::exportVar($attributes['context']); ?> -- - - -Duplicate Route
--
- -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: - = h($error->getMessage()) ?> -- '; - printf( - ' Template Defaults Options %s %s %s ', - $other->template, - Debugger::exportVar($other->defaults), - Debugger::exportVar($other->options) - ); - echo ''; - ?> -
- - File - = h($error->getFile()) ?> -
- Line: - = h($error->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: - = sprintf('Create %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: - = sprintf('Create the class %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: "= h($file . $this->_ext) ?>" - in one of the following paths: -
--_paths($this->plugin); - foreach ($paths as $path): - if (strpos($path, CORE_PATH) !== false) { - continue; - } - echo sprintf('
-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'); -?> -- %sCell/%s/%s
', h($path), h($name), h($file . $this->_ext)); - endforeach; -?> -- Error: - = sprintf('Create the class %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 = h($originalClass) ?> as a controller name. - - = h($pluginDot . $class) ?>Controller could not be found. - -end() ?> - - -start('file'); ?> - -The controller name = h($originalClass) ?> has not been properly inflected, and - could not be resolved to a controller that exists in your application.
- -Ensure that your URL = h($this->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 = h($class) ?>Controller below in file: = h($path) ?> -
- - - - -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 = h($pluginDot . $class) ?> could not be found. - - = h($message); ?> - -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 = h($name) ?> was not found in config= DIRECTORY_SEPARATOR . 'app.php' ?>. - - = h($message) ?> - -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: - = h($pluginDot . $class) ?> could not be found. - = $this->element('plugin_class_error', ['pluginPath' => $pluginPath]) ?> -end() ?> - -start('file') ?> -- Error: - = sprintf('Create the class %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 = h($file) ?> can not be found or does not exist. -end() ?> - -start('file') ?> -- Confirm you have created the file: = h($file) ?> in one of the following paths: -
--_paths($this->plugin); - foreach ($paths as $path): - if (strpos($path, CORE_PATH) !== false) { - continue; - } - echo sprintf('
-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 = h($plugin) ?> plugin. -- %s%s
', h($path), h($file)); - endforeach; -?> -
-
- Make sure your plugin = h($plugin) ?> is in the = h($pluginPath) ?> directory and was loaded. -end() ?> - -start('file') ?> - - - -- Loading all plugins: - = sprintf('If you wish to load all plugins at once, use the following line in your %s file', 'config' . DIRECTORY_SEPARATOR . 'bootstrap.php'); ?> -
- - - -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: - = $error->getMessage(); ?> -end() ?> - -start('file') ?> -None of the currently connected routes match the provided parameters. -Add a matching route to = 'config' . DIRECTORY_SEPARATOR . 'routes.php' ?>
- - -The passed context was:
--= Debugger::exportVar($attributes['context']); ?> -- - -Connected Routes
--
-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: - = sprintf('The template %s was not found.', h($file)); ?> - - Error: - = sprintf( - 'The view for %sController::%s() was not found.', - h(Inflector::camelize($this->request->getParam('controller'))), - h($this->request->getParam('action')) - ); ?> - -end() ?> - -start('file') ?> --'; - printf( - ' Template Defaults Options %s %s %s ', - $route->template, - Debugger::exportVar($route->defaults), - Debugger::exportVar($route->options) - ); - echo ''; -endforeach; -?> -- = sprintf('Confirm you have created the file: "%s"', h($file)) ?> - in one of the following paths: -
--_paths($this->plugin); - foreach ($paths as $path): - if (strpos($path, CORE_PATH) !== false) { - continue; - } - echo sprintf('
-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: - = h($pluginDot . $class) ?> could not be found. - - Make sure your plugin = h($plugin) ?> is in the = h($pluginPath) ?> directory and was loaded. - - = $this->element('plugin_class_error', ['pluginPath' => $pluginPath]) ?> - -end() ?> - -start('file') ?> -- %s%s
', h($path), h($file)); - endforeach; -?> -- Error: - = sprintf('Create the class %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: - = h($message); ?> -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: -
-= h($error->queryString); ?>- -params)) : ?> - SQL Query Params: -= h(Debugger::dump($error->params)); ?>- -= $this->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 @@ - - - - - = $this->Html->charset() ?> - -- Error: = h($this->fetch('title')) ?> - - = $this->Html->meta('icon') ?> - - - -- - -- = h($this->fetch('title')) ?> - = get_class($error) ?> -
-- Documentation - API --- fetch('subheading')): ?> -- -- = $this->fetch('subheading') ?> -
- - - = $this->element('exception_stack_trace'); ?> - -- = $this->fetch('file') ?> -- - fetch('templateName')): ?> -- If you want to customize this error message, create - = APP_DIR . DIRECTORY_SEPARATOR . 'Template' . DIRECTORY_SEPARATOR . 'Error' . DIRECTORY_SEPARATOR . $this->fetch('templateName') ?> -
- -- = $this->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 @@ -[](https://packagist.org/packages/cakephp/utility) -[](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 .= '' . $tag . '>'; - } - } 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};|[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};|[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: - * - * `` - * - * And calling `Xml::fromArray($value, 'attributes');` Will generate: - * - * ` 1 defect 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 @@ -[](https://packagist.org/packages/cakephp/validation) -[](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: - * - * - ` description , ` 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' => '', - // 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' => ' ', - // Container for error items. - 'errorList' => '{{content}}
', - // Error item wrapper. - 'errorItem' => '{{text}} ', - // File input used by file(). - 'file' => '', - // Fieldset element used by allControls(). - 'fieldset' => '', - // Open tag used by create(). - 'formStart' => '', - // General grouping container for control(). Defines input/label ordering. - 'formGroup' => '{{label}}{{input}}', - // Wrapper content used to hide other content. - 'hiddenBlock' => ' ', - // 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' => '', - // Label element used for radio and multi-checkbox inputs. - 'nestingLabel' => '{{hidden}}', - // Legends created by allControls() - 'legend' => '', - // Multi-Checkbox input set title element. - 'multicheckboxTitle' => '', - // Multi-Checkbox wrapping container. - 'multicheckboxWrapper' => '', - // Option element used in select pickers. - 'option' => '', - // Option group element used in select pickers. - 'optgroup' => '', - // 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 `