diff --git a/LICENSE b/LICENSE
deleted file mode 100644
index 81ddccc..0000000
--- a/LICENSE
+++ /dev/null
@@ -1,21 +0,0 @@
-MIT License
-
-Copyright (c) 2018 CodeIgniter 4 web framework
-
-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/README.md b/README.md
index 03626c7..275f015 100644
--- a/README.md
+++ b/README.md
@@ -9,8 +9,6 @@
including the user guide. It has been built from the
[development repository](https://github.com/codeigniter4/CodeIgniter4).
-**This is pre-release code and should not be used in production sites.**
-
More information about the plans for version 4 can be found in [the announcement](http://forum.codeigniter.com/thread-62615.html) on the forums.
The user guide corresponding to this version of the framework can be found
diff --git a/app/Config/Kint.php b/app/Config/Kint.php
index 9562447..09db83d 100644
--- a/app/Config/Kint.php
+++ b/app/Config/Kint.php
@@ -1,7 +1,7 @@
0644,
+
+ /*
+ * Logging Directory Path
+ *
+ * By default, logs are written to WRITEPATH . 'logs/'
+ * Specify a different destination here, if desired.
+ */
+ 'path' => '',
],
/**
diff --git a/app/Config/Mimes.php b/app/Config/Mimes.php
index a570ef5..41014d4 100644
--- a/app/Config/Mimes.php
+++ b/app/Config/Mimes.php
@@ -516,11 +516,7 @@
foreach (static::$mimes as $ext => $types)
{
- if (is_string($types) && $types === $type)
- {
- return $ext;
- }
- else if (is_array($types) && in_array($type, $types))
+ if ((is_string($types) && $types === $type) || (is_array($types) && in_array($type, $types)))
{
return $ext;
}
diff --git a/app/Config/Routes.php b/app/Config/Routes.php
index 4832736..a2a9654 100644
--- a/app/Config/Routes.php
+++ b/app/Config/Routes.php
@@ -1,7 +1,7 @@
+ } ?>
$= $var ?>
@@ -235,7 +235,7 @@
+ } ?>
@@ -287,15 +287,15 @@
- $value) : ?>
+
+ } ?>
+ } ?>
= esc($h->getName(), 'html') ?>
diff --git a/composer.json b/composer.json
index d8adb48..a8045d3 100644
--- a/composer.json
+++ b/composer.json
@@ -9,6 +9,7 @@
"ext-curl": "*",
"ext-intl": "*",
"ext-json": "*",
+ "ext-mbstring": "*",
"kint-php/kint": "^3.3",
"psr/log": "^1.1",
"laminas/laminas-escaper": "^2.6"
diff --git a/contributing.md b/contributing.md
deleted file mode 100644
index f0cf482..0000000
--- a/contributing.md
+++ /dev/null
@@ -1,94 +0,0 @@
-# Contributing to CodeIgniter4
-
-
-## Contributions
-
-We expect all contributions to conform to our [style guide](https://github.com/codeigniter4/CodeIgniter4/blob/develop/contributing/styleguide.rst), be commented (inside the PHP source files),
-be documented (in the [user guide](https://codeigniter4.github.io/userguide/)), and unit tested (in the [test folder](https://github.com/codeigniter4/CodeIgniter4/tree/develop/tests)).
-There is a [Contributing to CodeIgniter](./contributing/README.rst) section in the repository which describes the contribution process; this page is an overview.
-
-Note, we expect all code changes or bug-fixes to be accompanied by one or more tests added to our test suite to prove the code works. If pull requests are not accompanied by relevant tests, they will likely be closed. Since we are a team of volunteers, we don't have any more time to work on the framework than you do. Please make it as painless for your contributions to be included as possible. If you need help with getting tests running on your local machines, ask for help on the forums. We would be happy to help out.
-
-The [Open Source Guide](https://opensource.guide/) is a good first read for those new to contributing to open source!
-## Issues
-
-Issues are a quick way to point out a bug. If you find a bug or documentation error in CodeIgniter then please make sure that:
-
-1. There is not already an open [Issue](https://github.com/codeigniter4/CodeIgniter4/issues)
-2. The Issue has not already been fixed (check the develop branch or look for [closed Issues](https://github.com/codeigniter4/CodeIgniter4/issues?q=is%3Aissue+is%3Aclosed))
-3. It's not something really obvious that you can fix yourself
-
-Reporting Issues is helpful, but an even [better approach](./contributing/workflow.rst) is to send a [Pull Request](https://help.github.com/en/articles/creating-a-pull-request), which is done by [Forking](https://help.github.com/en/articles/fork-a-repo) the main repository and making a [Commit](https://help.github.com/en/desktop/contributing-to-projects/committing-and-reviewing-changes-to-your-project) to your own copy of the project. This will require you to use the version control system called [Git](https://git-scm.com/).
-
-## Guidelines
-
-Before we look into how to contribute to CodeIgniter4, here are some guidelines. If your Pull Requests fail
-to pass these guidelines, they will be declined, and you will need to re-submit
-when you’ve made the changes. This might sound a bit tough, but it is required
-for us to maintain the quality of the codebase.
-
-### PHP Style
-
-All code must meet the [Style Guide](./contributing/styleguide.rst).
-This makes certain that all submitted code is of the same format as the existing code and ensures that the codebase will be as readable as possible.
-
-### Documentation
-
-If you change anything that requires a change to documentation, then you will need to add to the documentation. New classes, methods, parameters, changing default values, etc. are all changes that require a change to documentation. Also, the [changelog](https://codeigniter4.github.io/CodeIgniter4/changelogs/index.html) must be updated for every change, and [PHPDoc](https://github.com/codeigniter4/CodeIgniter4/blob/develop/phpdoc.dist.xml) blocks must be maintained.
-
-### Compatibility
-
-CodeIgniter4 requires [PHP 7.2](https://php.net/releases/7_2_0.php).
-
-### Branching
-
-CodeIgniter4 uses the [Git-Flow](http://nvie.com/posts/a-successful-git-branching-model/) branching model which requires all
-Pull Requests to be sent to the "develop" branch; this is where the next planned version will be developed.
-The "master" branch will always contain the latest stable version and is kept clean so a "hotfix" (e.g. an
-emergency security patch) can be applied to the "master" branch to create a new version, without worrying
-about other features holding it up. For this reason, all commits need to be made to the "develop" branch,
-and any sent to the "master" branch will be closed automatically. If you have multiple changes to submit,
-please place all changes into their own branch on your fork.
-
-**One thing at a time:** A pull request should only contain one change. That does not mean only one commit,
-but one change - however many commits it took. The reason for this is that if you change X and Y,
-but send a pull request for both at the same time, we might really want X but disagree with Y,
-meaning we cannot merge the request. Using the Git-Flow branching model you can create new
-branches for both of these features and send two requests.
-
-A reminder: **please use separate branches for each of your PRs** - it will make it easier for you to keep changes separate from
-each other and from whatever else you are doing with your repository!
-
-### Signing
-
-You must [GPG-sign](./contributing/signing.rst) your work, certifying that you either wrote the work or otherwise have the right to pass it on to an open-source project. This is *not* just a "signed-off-by" commit, but instead, a digitally signed one.
-
-## How-to Guide
-
-The best way to contribute is to fork the CodeIgniter4 repository, and "clone" that to your development area. That sounds like some jargon, but "forking" on GitHub means "making a copy of that repo to your account" and "cloning" means "copying that code to your environment so you can work on it".
-
-1. Set up Git ([Windows](https://git-scm.com/download/win), [Mac](https://git-scm.com/download/mac), & [Linux](https://git-scm.com/download/linux)).
-2. Go to the [CodeIgniter4 repository](https://github.com/codeigniter4/CodeIgniter4).
-3. [Fork](https://help.github.com/en/articles/fork-a-repo) it (to your Github account).
-4. [Clone](https://help.github.com/en/articles/cloning-a-repository) your CodeIgniter repository: `git@github.com:\/CodeIgniter4.git`
-5. Create a new [branch](https://help.github.com/en/articles/about-branches) in your project for each set of changes you want to make.
-6. Fix existing bugs on the [Issue tracker](https://github.com/codeigniter4/CodeIgniter4/issues) after confirming that no one else is working on them.
-7. [Commit](https://help.github.com/en/desktop/contributing-to-projects/committing-and-reviewing-changes-to-your-project) the changed files in your contribution branch.
-8. [Push](https://help.github.com/en/articles/pushing-to-a-remote) your contribution branch to your fork.
-9. Send a [pull request](http://help.github.com/send-pull-requests/).
-
-The codebase maintainers will now be alerted to the submission and someone from the team will respond. If your change fails to meet the guidelines, it will be rejected or feedback will be provided to help you improve it.
-
-Once the maintainer handling your pull request is satisfied with it they will approve the pull request and merge it into the "develop" branch; your patch will now be part of the next release!
-
-### Keeping your fork up-to-date
-
-Unlike systems like Subversion, Git can have multiple remotes. A remote is the name for the URL of a Git repository. By default, your fork will have a remote named "origin", which points to your fork, but you can add another remote named "codeigniter", which points to `git://github.com/codeigniter4/CodeIgniter4.git`. This is a read-only remote, but you can pull from this develop branch to update your own.
-
-If you are using the command-line, you can do the following to update your fork to the latest changes:
-
-1. `git remote add codeigniter git://github.com/codeigniter4/CodeIgniter4.git`
-2. `git pull codeigniter develop`
-3. `git push origin develop`
-
-Your fork is now up to date. This should be done regularly and, at the least, before you submit a pull request.
diff --git a/public/index.php b/public/index.php
index 5b9e912..3eaa592 100644
--- a/public/index.php
+++ b/public/index.php
@@ -13,7 +13,7 @@
// Location of the Paths config file.
// This is the line that might need to be changed, depending on your folder structure.
-$pathsPath = FCPATH . '../app/Config/Paths.php';
+$pathsPath = realpath(FCPATH . '../app/Config/Paths.php');
// ^^^ Change this if you move your application folder
/*
diff --git a/system/API/ResponseTrait.php b/system/API/ResponseTrait.php
index f16b284..49248eb 100644
--- a/system/API/ResponseTrait.php
+++ b/system/API/ResponseTrait.php
@@ -39,8 +39,8 @@
namespace CodeIgniter\API;
-use Config\Format;
use CodeIgniter\HTTP\Response;
+use Config\Format;
/**
* Response trait.
@@ -56,7 +56,6 @@
*/
trait ResponseTrait
{
-
/**
* Allows child classes to override the
* status code that is used in their API.
@@ -66,6 +65,7 @@
protected $codes = [
'created' => 201,
'deleted' => 200,
+ 'updated' => 200,
'no_content' => 204,
'invalid_request' => 400,
'unsupported_response_type' => 400,
@@ -93,6 +93,15 @@
'not_implemented' => 501,
];
+ /**
+ * How to format the response data.
+ * Either 'json' or 'xml'. If blank will be
+ * determine through content negotiation.
+ *
+ * @var string
+ */
+ protected $format = 'json';
+
//--------------------------------------------------------------------
/**
@@ -190,6 +199,19 @@
return $this->respond($data, $this->codes['deleted'], $message);
}
+ /**
+ * Used after a resource has been successfully updated.
+ *
+ * @param mixed $data Data.
+ * @param string $message Message.
+ *
+ * @return mixed
+ */
+ public function respondUpdated($data = null, string $message = '')
+ {
+ return $this->respond($data, $this->codes['updated'], $message);
+ }
+
//--------------------------------------------------------------------
/**
@@ -364,9 +386,14 @@
return $data;
}
- // Determine correct response type through content negotiation
$config = new Format();
- $format = $this->request->negotiate('media', $config->supportedResponseFormats, false);
+ $format = "application/$this->format";
+
+ // Determine correct response type through content negotiation if not explicitly declared
+ if (empty($this->format) || ! in_array($this->format, ['json', 'xml']))
+ {
+ $format = $this->request->negotiate('media', $config->supportedResponseFormats, false);
+ }
$this->response->setContentType($format);
@@ -387,4 +414,17 @@
return $this->formatter->format($data);
}
+ /**
+ * Sets the format the response should be in.
+ *
+ * @param string $format
+ *
+ * @return $this
+ */
+ public function setResponseFormat(string $format = null)
+ {
+ $this->format = strtolower($format);
+
+ return $this;
+ }
}
diff --git a/system/Autoloader/Autoloader.php b/system/Autoloader/Autoloader.php
index 4663107..fa5c9a2 100644
--- a/system/Autoloader/Autoloader.php
+++ b/system/Autoloader/Autoloader.php
@@ -392,7 +392,7 @@
// be a path.
// http://pubs.opengroup.org/onlinepubs/9699919799/basedefs/V1_chap03.html#tag_03_278
// Modified to allow backslash and colons for on Windows machines.
- $filename = preg_replace('/[^a-zA-Z0-9\s\/\-\_\.\:\\\\]/', '', $filename);
+ $filename = preg_replace('/[^0-9\p{L}\s\/\-\_\.\:\\\\]/u', '', $filename);
// Clean up our filename edges.
$filename = trim($filename, '.-_');
diff --git a/system/Autoloader/FileLocator.php b/system/Autoloader/FileLocator.php
index 0b78e9c..5aa217e 100644
--- a/system/Autoloader/FileLocator.php
+++ b/system/Autoloader/FileLocator.php
@@ -353,7 +353,11 @@
// Remove the file extension (.php)
$className = mb_substr($className, 0, -4);
- return $className;
+ // Check if this exists
+ if (class_exists($className))
+ {
+ return $className;
+ }
}
}
diff --git a/system/CLI/CLI.php b/system/CLI/CLI.php
index e60036c..476c08d 100644
--- a/system/CLI/CLI.php
+++ b/system/CLI/CLI.php
@@ -437,7 +437,7 @@
// Do it once or more, write with empty string gives us a new line
for ($i = 0; $i < $num; $i ++)
{
- static::write('');
+ static::write();
}
}
@@ -504,9 +504,7 @@
$string .= "\033[4m";
}
- $string .= $text . "\033[0m";
-
- return $string;
+ return $string . ($text . "\033[0m");
}
//--------------------------------------------------------------------
@@ -702,24 +700,17 @@
*/
protected static function parseCommandLine()
{
- $optionsFound = false;
-
// start picking segments off from #1, ignoring the invoking program
for ($i = 1; $i < $_SERVER['argc']; $i ++)
{
// If there's no '-' at the beginning of the argument
// then add it to our segments.
- if (! $optionsFound && mb_strpos($_SERVER['argv'][$i], '-') === false)
+ if (mb_strpos($_SERVER['argv'][$i], '-') === false)
{
static::$segments[] = $_SERVER['argv'][$i];
continue;
}
- // We set $optionsFound here so that we know to
- // skip the next argument since it's likely the
- // value belonging to this option.
- $optionsFound = true;
-
$arg = str_replace('-', '', $_SERVER['argv'][$i]);
$value = null;
@@ -731,10 +722,6 @@
}
static::$options[$arg] = $value;
-
- // Reset $optionsFound so it can collect segments
- // past any options.
- $optionsFound = false;
}
}
@@ -958,7 +945,7 @@
}
}
- fwrite(STDOUT, $table);
+ static::write($table);
}
//--------------------------------------------------------------------
diff --git a/system/CLI/CommandRunner.php b/system/CLI/CommandRunner.php
index b1e6103..2e1a8e1 100644
--- a/system/CLI/CommandRunner.php
+++ b/system/CLI/CommandRunner.php
@@ -40,8 +40,8 @@
namespace CodeIgniter\CLI;
-use Config\Services;
use CodeIgniter\Controller;
+use Config\Services;
/**
* Command runner
@@ -104,7 +104,7 @@
if (is_null($command))
{
- $command = 'help';
+ $command = 'list';
}
return $this->runCommand($command, $params);
diff --git a/system/Cache/Handlers/FileHandler.php b/system/Cache/Handlers/FileHandler.php
index 737db09..86e7090 100644
--- a/system/Cache/Handlers/FileHandler.php
+++ b/system/Cache/Handlers/FileHandler.php
@@ -154,7 +154,7 @@
{
$key = $this->prefix . $key;
- return is_file($this->path . $key) ? unlink($this->path . $key) : false;
+ return is_file($this->path . $key) && unlink($this->path . $key);
}
//--------------------------------------------------------------------
diff --git a/system/CodeIgniter.php b/system/CodeIgniter.php
index 26a6803..c708a27 100644
--- a/system/CodeIgniter.php
+++ b/system/CodeIgniter.php
@@ -39,20 +39,20 @@
namespace CodeIgniter;
use Closure;
+use CodeIgniter\Debug\Timer;
+use CodeIgniter\Events\Events;
+use CodeIgniter\Exceptions\PageNotFoundException;
+use CodeIgniter\HTTP\CLIRequest;
use CodeIgniter\HTTP\DownloadResponse;
use CodeIgniter\HTTP\RedirectResponse;
use CodeIgniter\HTTP\Request;
-use CodeIgniter\HTTP\ResponseInterface;
-use Config\Services;
-use Config\Cache;
-use CodeIgniter\HTTP\URI;
-use CodeIgniter\Debug\Timer;
-use CodeIgniter\Events\Events;
use CodeIgniter\HTTP\Response;
-use CodeIgniter\HTTP\CLIRequest;
+use CodeIgniter\HTTP\ResponseInterface;
+use CodeIgniter\HTTP\URI;
use CodeIgniter\Router\Exceptions\RedirectException;
use CodeIgniter\Router\RouteCollectionInterface;
-use CodeIgniter\Exceptions\PageNotFoundException;
+use Config\Cache;
+use Config\Services;
use Exception;
/**
@@ -66,7 +66,7 @@
/**
* The current version of CodeIgniter Framework
*/
- const CI_VERSION = '4.0.2';
+ const CI_VERSION = '4.0.3';
/**
* App startup time.
@@ -194,7 +194,9 @@
if (! CI_DEBUG)
{
+ // @codeCoverageIgnoreStart
\Kint::$enabled_mode = false;
+ // @codeCoverageIgnoreEnd
}
}
@@ -496,9 +498,11 @@
}
else
{
+ // @codeCoverageIgnoreStart
header('HTTP/1.1 503 Service Unavailable.', true, 503);
echo 'The application environment is not set correctly.';
exit(1); // EXIT_ERROR
+ // @codeCoverageIgnoreEnd
}
}
@@ -550,9 +554,11 @@
return;
}
- if (is_cli() && ! (ENVIRONMENT === 'testing'))
+ if (is_cli() && ENVIRONMENT !== 'testing')
{
+ // @codeCoverageIgnoreStart
$this->request = Services::clirequest($this->config);
+ // @codeCoverageIgnoreEnd
}
else
{
@@ -747,9 +753,7 @@
{
$this->totalTime = $this->benchmark->getElapsedTime('total_execution');
- $output = str_replace('{elapsed_time}', $this->totalTime, $output);
-
- return $output;
+ return str_replace('{elapsed_time}', $this->totalTime, $output);
}
//--------------------------------------------------------------------
@@ -958,10 +962,12 @@
if (ENVIRONMENT !== 'testing')
{
+ // @codeCoverageIgnoreStart
if (ob_get_level() > 0)
{
ob_end_flush();
}
+ // @codeCoverageIgnoreEnd
}
else
{
@@ -972,7 +978,7 @@
}
}
- throw PageNotFoundException::forPageNotFound($e->getMessage());
+ throw PageNotFoundException::forPageNotFound(ENVIRONMENT !== 'production' || is_cli() ? $e->getMessage() : '');
}
//--------------------------------------------------------------------
@@ -1110,7 +1116,9 @@
*/
protected function callExit($code)
{
+ // @codeCoverageIgnoreStart
exit($code);
+ // @codeCoverageIgnoreEnd
}
//--------------------------------------------------------------------
diff --git a/system/Commands/Database/CreateMigration.php b/system/Commands/Database/CreateMigration.php
index 19d87a4..3983d67 100644
--- a/system/Commands/Database/CreateMigration.php
+++ b/system/Commands/Database/CreateMigration.php
@@ -40,8 +40,7 @@
use CodeIgniter\CLI\BaseCommand;
use CodeIgniter\CLI\CLI;
-use Config\Autoload;
-use Config\Migrations;
+use Config\Services;
/**
* Creates a new migration file.
@@ -124,15 +123,14 @@
if (! empty($ns))
{
- // Get all namespaces from PSR4 paths.
- $config = new Autoload();
- $namespaces = $config->psr4;
+ // Get all namespaces
+ $namespaces = Services::autoloader()->getNamespace();
foreach ($namespaces as $namespace => $path)
{
if ($namespace === $ns)
{
- $homepath = realpath($path);
+ $homepath = realpath(reset($path));
break;
}
}
@@ -178,7 +176,7 @@
helper('filesystem');
if (! write_file($path, $template))
{
- CLI::error(lang('Migrations.writeError'));
+ CLI::error(lang('Migrations.writeError', [$path]));
return;
}
diff --git a/system/Commands/Database/MigrateRefresh.php b/system/Commands/Database/MigrateRefresh.php
index e0ec669..bf6b4f8 100644
--- a/system/Commands/Database/MigrateRefresh.php
+++ b/system/Commands/Database/MigrateRefresh.php
@@ -40,6 +40,7 @@
namespace CodeIgniter\Commands\Database;
use CodeIgniter\CLI\BaseCommand;
+use CodeIgniter\CLI\CLI;
/**
* Does a rollback followed by a latest to refresh the current state
@@ -95,6 +96,7 @@
'-n' => 'Set migration namespace',
'-g' => 'Set database group',
'-all' => 'Set latest for all namespace, will ignore (-n) option',
+ '-f' => 'Force command - this option allows you to bypass the confirmation question when running this command in a production environment',
];
/**
@@ -105,7 +107,20 @@
*/
public function run(array $params = [])
{
- $this->call('migrate:rollback', ['-b' => 0]);
+ $params = ['-b' => 0];
+
+ if (ENVIRONMENT === 'production')
+ {
+ $force = $params['-f'] ?? CLI::getOption('f');
+ if (is_null($force) && CLI::prompt(lang('Migrations.refreshConfirm'), ['y', 'n']) === 'n')
+ {
+ return;
+ }
+
+ $params['-f'] = '';
+ }
+
+ $this->call('migrate:rollback', $params);
$this->call('migrate');
}
diff --git a/system/Commands/Database/MigrateRollback.php b/system/Commands/Database/MigrateRollback.php
index ba25989..b2dca1c 100644
--- a/system/Commands/Database/MigrateRollback.php
+++ b/system/Commands/Database/MigrateRollback.php
@@ -42,7 +42,6 @@
use CodeIgniter\CLI\BaseCommand;
use CodeIgniter\CLI\CLI;
use Config\Services;
-use Config\Autoload;
/**
* Runs all of the migrations in reverse order, until they have
@@ -97,6 +96,7 @@
protected $options = [
'-b' => 'Specify a batch to roll back to; e.g. "3" to return to batch #3 or "-2" to roll back twice',
'-g' => 'Set database group',
+ '-f' => 'Force command - this option allows you to bypass the confirmation question when running this command in a production environment',
];
/**
@@ -107,6 +107,15 @@
*/
public function run(array $params = [])
{
+ if (ENVIRONMENT === 'production')
+ {
+ $force = $params['-f'] ?? CLI::getOption('f');
+ if (is_null($force) && CLI::prompt(lang('Migrations.rollBackConfirm'), ['y', 'n']) === 'n')
+ {
+ return;
+ }
+ }
+
$runner = Services::migrations();
$group = $params['-g'] ?? CLI::getOption('g');
diff --git a/system/Commands/Database/MigrateStatus.php b/system/Commands/Database/MigrateStatus.php
index 8e71436..94ad3ea 100644
--- a/system/Commands/Database/MigrateStatus.php
+++ b/system/Commands/Database/MigrateStatus.php
@@ -42,7 +42,6 @@
use CodeIgniter\CLI\BaseCommand;
use CodeIgniter\CLI\CLI;
use Config\Services;
-use Config\Autoload;
/**
* Displays a list of all migrations and whether they've been run or not.
@@ -106,6 +105,10 @@
'CodeIgniter',
'Config',
'Tests\Support',
+ 'Kint',
+ 'Laminas\ZendFrameworkBridge',
+ 'Laminas\Escaper',
+ 'Psr\Log',
];
/**
@@ -124,9 +127,11 @@
$runner->setGroup($group);
}
- // Get all namespaces from PSR4 paths.
- $config = new Autoload();
- $namespaces = $config->psr4;
+ // Get all namespaces
+ $namespaces = Services::autoloader()->getNamespace();
+
+ // Determines whether any migrations were found
+ $found = false;
// Loop for all $namespaces
foreach ($namespaces as $namespace => $path)
@@ -138,16 +143,17 @@
$runner->setNamespace($namespace);
$migrations = $runner->findMigrations();
- $history = $runner->getHistory();
-
- CLI::write($namespace);
if (empty($migrations))
{
- CLI::error(lang('Migrations.noneFound'));
continue;
}
+ $found = true;
+ $history = $runner->getHistory();
+
+ CLI::write($namespace);
+
ksort($migrations);
$max = 0;
@@ -176,6 +182,11 @@
CLI::write(str_pad(' ' . $migration->name, $max + 6) . ($date ? $date : '---'));
}
}
+
+ if (! $found)
+ {
+ CLI::error(lang('Migrations.noneFound'));
+ }
}
}
diff --git a/system/Commands/ListCommands.php b/system/Commands/ListCommands.php
index bae8e73..c20fe32 100644
--- a/system/Commands/ListCommands.php
+++ b/system/Commands/ListCommands.php
@@ -188,9 +188,8 @@
$max += $extra + $indent;
$item = str_repeat(' ', $indent) . $item;
- $item = str_pad($item, $max);
- return $item;
+ return str_pad($item, $max);
}
//--------------------------------------------------------------------
diff --git a/system/Commands/Server/Serve.php b/system/Commands/Server/Serve.php
index 9fb68fe..9e65862 100644
--- a/system/Commands/Server/Serve.php
+++ b/system/Commands/Server/Serve.php
@@ -97,14 +97,14 @@
/**
* The current port offset.
*
- * @var int
+ * @var integer
*/
protected $portOffset = 0;
/**
* The max number of ports to attempt to serve from
*
- * @var int
+ * @var integer
*/
protected $tries = 10;
@@ -131,12 +131,14 @@
// Valid PHP Version?
if (phpversion() < $this->minPHPVersion)
{
+ // @codeCoverageIgnoreStart
die('Your PHP version must be ' . $this->minPHPVersion .
' or higher to run CodeIgniter. Current version: ' . phpversion());
+ // @codeCoverageIgnoreEnd
}
// Collect any user-supplied options and apply them.
- $php = CLI::getOption('php') ?? PHP_BINARY;
+ $php = escapeshellarg(CLI::getOption('php') ?? PHP_BINARY);
$host = CLI::getOption('host') ?? 'localhost';
$port = (int) (CLI::getOption('port') ?? '8080') + $this->portOffset;
@@ -155,7 +157,8 @@
// to ensure our environment is set and it simulates basic mod_rewrite.
passthru($php . ' -S ' . $host . ':' . $port . ' -t ' . $docroot . ' ' . $rewrite, $status);
- if ($status && $this->portOffset < $this->tries) {
+ if ($status && $this->portOffset < $this->tries)
+ {
$this->portOffset += 1;
$this->run($params);
diff --git a/system/Commands/Sessions/CreateMigration.php b/system/Commands/Sessions/CreateMigration.php
index 15c7476..ca26bfa 100644
--- a/system/Commands/Sessions/CreateMigration.php
+++ b/system/Commands/Sessions/CreateMigration.php
@@ -126,7 +126,7 @@
helper('filesystem');
if (! write_file($path, $template))
{
- CLI::error(lang('Migrations.migWriteError'));
+ CLI::error(lang('Migrations.writeError', [$path]));
return;
}
diff --git a/system/Common.php b/system/Common.php
index a14bc66..2e3fcd7 100644
--- a/system/Common.php
+++ b/system/Common.php
@@ -37,19 +37,20 @@
* @filesource
*/
-use Config\App;
-use Config\Logger;
-use Config\Database;
-use Config\Services;
-use CodeIgniter\HTTP\URI;
-use Laminas\Escaper\Escaper;
use CodeIgniter\Config\Config;
-use CodeIgniter\Test\TestLogger;
+use CodeIgniter\Database\ConnectionInterface;
+use CodeIgniter\Files\Exceptions\FileNotFoundException;
use CodeIgniter\HTTP\RedirectResponse;
use CodeIgniter\HTTP\RequestInterface;
use CodeIgniter\HTTP\ResponseInterface;
-use CodeIgniter\Database\ConnectionInterface;
-use CodeIgniter\Files\Exceptions\FileNotFoundException;
+use CodeIgniter\HTTP\URI;
+use CodeIgniter\Test\TestLogger;
+use Config\App;
+use Config\Database;
+use Config\Logger;
+use Config\Services;
+use Config\View;
+use Laminas\Escaper\Escaper;
/**
* Common Functions
@@ -246,9 +247,11 @@
*/
function dd(...$vars)
{
+ // @codeCoverageIgnoreStart
Kint::$aliases[] = 'dd';
Kint::dump(...$vars);
exit;
+ // @codeCoverageIgnoreEnd
}
}
@@ -319,7 +322,7 @@
{
if (is_array($data))
{
- foreach ($data as $key => &$value)
+ foreach ($data as &$value)
{
$value = esc($value, $context);
}
@@ -384,10 +387,7 @@
* @param RequestInterface $request
* @param ResponseInterface $response
*
- * Not testable, as it will exit!
- *
- * @throws \CodeIgniter\HTTP\Exceptions\HTTPException
- * @codeCoverageIgnore
+ * @throws \CodeIgniter\HTTP\Exceptions\HTTPException
*/
function force_https(int $duration = 31536000, RequestInterface $request = null, ResponseInterface $response = null)
{
@@ -400,25 +400,33 @@
$response = Services::response(null, true);
}
- if (is_cli() || $request->isSecure())
+ if (ENVIRONMENT !== 'testing' && (is_cli() || $request->isSecure()))
{
+ // @codeCoverageIgnoreStart
return;
+ // @codeCoverageIgnoreEnd
}
- // If the session library is loaded, we should regenerate
+ // If the session status is active, we should regenerate
// the session ID for safety sake.
- if (class_exists('Session', false))
+ if (ENVIRONMENT !== 'testing' && session_status() === PHP_SESSION_ACTIVE)
{
+ // @codeCoverageIgnoreStart
Services::session(null, true)
->regenerate();
+ // @codeCoverageIgnoreEnd
}
- $uri = $request->uri;
- $uri->setScheme('https');
+ $baseURL = config(App::class)->baseURL;
+
+ if (strpos($baseURL, 'http://') === 0)
+ {
+ $baseURL = (string) substr($baseURL, strlen('http://'));
+ }
$uri = URI::createURIString(
- $uri->getScheme(), $uri->getAuthority(true), $uri->getPath(), // Absolute URIs should use a "/" for an empty path
- $uri->getQuery(), $uri->getFragment()
+ 'https', $baseURL, $request->uri->getPath(), // Absolute URIs should use a "/" for an empty path
+ $request->uri->getQuery(), $request->uri->getFragment()
);
// Set an HSTS header
@@ -426,7 +434,12 @@
$response->redirect($uri);
$response->sendHeaders();
- exit();
+ if (ENVIRONMENT !== 'testing')
+ {
+ // @codeCoverageIgnoreStart
+ exit();
+ // @codeCoverageIgnoreEnd
+ }
}
}
@@ -747,7 +760,9 @@
// Ensure the session is loaded
if (session_status() === PHP_SESSION_NONE && ENVIRONMENT !== 'testing')
{
+ // @codeCoverageIgnoreStart
session();
+ // @codeCoverageIgnoreEnd
}
$request = Services::request();
@@ -1060,8 +1075,9 @@
*/
$renderer = Services::renderer();
- $saveData = true;
- if (array_key_exists('saveData', $options) && $options['saveData'] === true)
+ $saveData = config(View::class)->saveData;
+
+ if (array_key_exists('saveData', $options))
{
$saveData = (bool) $options['saveData'];
unset($options['saveData']);
diff --git a/system/ComposerScripts.php b/system/ComposerScripts.php
index d53108f..6ebb122 100644
--- a/system/ComposerScripts.php
+++ b/system/ComposerScripts.php
@@ -90,7 +90,9 @@
if (empty($source))
{
+ // @codeCoverageIgnoreStart
die('Cannot move file. Source path invalid.');
+ // @codeCoverageIgnoreEnd
}
if (! is_file($source))
@@ -203,7 +205,9 @@
{
if (! static::moveFile($source, $dest))
{
+ // @codeCoverageIgnoreStart
die('Error moving: ' . $source);
+ // @codeCoverageIgnoreEnd
}
}
}
diff --git a/system/Config/BaseConfig.php b/system/Config/BaseConfig.php
index 9a0100f..ceec8ba 100644
--- a/system/Config/BaseConfig.php
+++ b/system/Config/BaseConfig.php
@@ -164,16 +164,12 @@
{
case array_key_exists("{$shortPrefix}.{$property}", $_ENV):
return $_ENV["{$shortPrefix}.{$property}"];
- break;
case array_key_exists("{$shortPrefix}.{$property}", $_SERVER):
return $_SERVER["{$shortPrefix}.{$property}"];
- break;
case array_key_exists("{$prefix}.{$property}", $_ENV):
return $_ENV["{$prefix}.{$property}"];
- break;
case array_key_exists("{$prefix}.{$property}", $_SERVER):
return $_SERVER["{$prefix}.{$property}"];
- break;
default:
$value = getenv($property);
return $value === false ? null : $value;
diff --git a/system/Config/DotEnv.php b/system/Config/DotEnv.php
index 541334a..4220d77 100644
--- a/system/Config/DotEnv.php
+++ b/system/Config/DotEnv.php
@@ -128,7 +128,7 @@
if (strpos($line, '=') !== false)
{
list($name, $value) = $this->normaliseVariable($line);
- $vars[$name] = $value;
+ $vars[$name] = $value;
}
}
@@ -314,10 +314,8 @@
{
case array_key_exists($name, $_ENV):
return $_ENV[$name];
- break;
case array_key_exists($name, $_SERVER):
return $_SERVER[$name];
- break;
default:
$value = getenv($name);
diff --git a/system/Config/Services.php b/system/Config/Services.php
index 6f166a6..afb6512 100644
--- a/system/Config/Services.php
+++ b/system/Config/Services.php
@@ -39,6 +39,8 @@
namespace CodeIgniter\Config;
use CodeIgniter\Cache\CacheFactory;
+use CodeIgniter\Database\ConnectionInterface;
+use CodeIgniter\Database\MigrationRunner;
use CodeIgniter\Debug\Exceptions;
use CodeIgniter\Debug\Iterator;
use CodeIgniter\Debug\Timer;
@@ -70,10 +72,8 @@
use CodeIgniter\Validation\Validation;
use CodeIgniter\View\Cell;
use CodeIgniter\View\Parser;
-use Config\App;
-use CodeIgniter\Database\ConnectionInterface;
-use CodeIgniter\Database\MigrationRunner;
use CodeIgniter\View\RendererInterface;
+use Config\App;
use Config\Cache;
use Config\Images;
use Config\Logger;
@@ -207,8 +207,7 @@
{
$config = new \Config\Email();
}
- $email = new \CodeIgniter\Email\Email($config);
- return $email;
+ return new \CodeIgniter\Email\Email($config);
}
/**
@@ -232,8 +231,7 @@
}
$encryption = new Encryption($config);
- $encrypter = $encryption->initialize($config);
- return $encrypter;
+ return $encryption->initialize($config);
}
//--------------------------------------------------------------------
@@ -502,7 +500,7 @@
if (empty($config))
{
- $config = new \Config\Pager();
+ $config = config('Pager');
}
if (! $view instanceof RendererInterface)
@@ -542,7 +540,7 @@
$viewPath = $paths->viewDirectory;
}
- return new Parser($config, $viewPath, static::locator(true), CI_DEBUG, static::logger(true));
+ return new Parser($config, $viewPath, static::locator(), CI_DEBUG, static::logger());
}
//--------------------------------------------------------------------
@@ -577,7 +575,7 @@
$viewPath = $paths->viewDirectory;
}
- return new \CodeIgniter\View\View($config, $viewPath, static::locator(true), CI_DEBUG, static::logger(true));
+ return new \CodeIgniter\View\View($config, $viewPath, static::locator(), CI_DEBUG, static::logger());
}
//--------------------------------------------------------------------
@@ -705,7 +703,7 @@
if (empty($routes))
{
- $routes = static::routes(true);
+ $routes = static::routes();
}
return new Router($routes, $request);
@@ -759,7 +757,7 @@
$config = config(App::class);
}
- $logger = static::logger(true);
+ $logger = static::logger();
$driverName = $config->sessionDriver;
$driver = new $driverName($config, static::request()->getIpAddress());
diff --git a/system/Controller.php b/system/Controller.php
index 172104e..985d828 100644
--- a/system/Controller.php
+++ b/system/Controller.php
@@ -39,11 +39,11 @@
namespace CodeIgniter;
-use Config\Services;
use CodeIgniter\HTTP\RequestInterface;
use CodeIgniter\HTTP\ResponseInterface;
-use CodeIgniter\Validation\Validation;
use CodeIgniter\Validation\Exceptions\ValidationException;
+use CodeIgniter\Validation\Validation;
+use Config\Services;
use Psr\Log\LoggerInterface;
/**
@@ -117,7 +117,6 @@
$this->request = $request;
$this->response = $response;
$this->logger = $logger;
- $this->logger->info('Controller "' . get_class($this) . '" loaded.');
if ($this->forceHTTPS > 0)
{
@@ -195,7 +194,7 @@
// If you replace the $rules array with the name of the group
if (is_string($rules))
{
- $validation = new \Config\Validation();
+ $validation = config('Validation');
// If the rule wasn't found in the \Config\Validation, we
// should throw an exception so the developer can find it.
@@ -214,12 +213,10 @@
$rules = $validation->$rules;
}
- $success = $this->validator
+ return $this->validator
->withRequest($this->request)
->setRules($rules, $messages)
->run();
-
- return $success;
}
//--------------------------------------------------------------------
diff --git a/system/Database/BaseBuilder.php b/system/Database/BaseBuilder.php
index 800247f..33e7004 100644
--- a/system/Database/BaseBuilder.php
+++ b/system/Database/BaseBuilder.php
@@ -39,9 +39,9 @@
namespace CodeIgniter\Database;
+use Closure;
use CodeIgniter\Database\Exceptions\DatabaseException;
use CodeIgniter\Database\Exceptions\DataException;
-use Closure;
/**
* Class BaseBuilder
@@ -103,7 +103,7 @@
*
* @var array
*/
- protected $QBGroupBy = [];
+ public $QBGroupBy = [];
/**
* QB HAVING data
@@ -214,6 +214,14 @@
protected $binds = [];
/**
+ * Collects the key count for named parameters
+ * in the Query object.
+ *
+ * @var array
+ */
+ protected $bindsKeyCount = [];
+
+ /**
* Some databases, like SQLite, do not by default
* allow limiting of delete clauses.
*
@@ -388,7 +396,7 @@
*/
public function selectMax(string $select = '', string $alias = '')
{
- return $this->maxMinAvgSum($select, $alias, 'MAX');
+ return $this->maxMinAvgSum($select, $alias);
}
//--------------------------------------------------------------------
@@ -973,20 +981,38 @@
* @used-by whereNotIn()
* @used-by orWhereNotIn()
*
- * @param string $key The field to search
- * @param array|Closure $values The values searched on, or anonymous function with subquery
- * @param boolean $not If the statement would be IN or NOT IN
- * @param string $type
- * @param boolean $escape
- * @param string $clause (Internal use only)
+ * @param string $key The field to search
+ * @param array|Closure $values The values searched on, or anonymous function with subquery
+ * @param boolean $not If the statement would be IN or NOT IN
+ * @param string $type
+ * @param boolean $escape
+ * @param string $clause (Internal use only)
+ * @throws InvalidArgumentException
*
* @return BaseBuilder
*/
protected function _whereIn(string $key = null, $values = null, bool $not = false, string $type = 'AND ', bool $escape = null, string $clause = 'QBWhere')
{
- if ($key === null || $values === null || (! is_array($values) && ! ($values instanceof Closure)))
+ if (empty($key) || ! is_string($key))
{
+ if (CI_DEBUG)
+ {
+ throw new \InvalidArgumentException(sprintf('%s() expects $key to be a non-empty string', debug_backtrace(0, 2)[1]['function']));
+ }
+ // @codeCoverageIgnoreStart
return $this;
+ // @codeCoverageIgnoreEnd
+ }
+
+ if ($values === null || (! is_array($values) && ! ($values instanceof Closure)))
+ {
+ if (CI_DEBUG)
+ {
+ throw new \InvalidArgumentException(sprintf('%s() expects $values to be of type array or closure', debug_backtrace(0, 2)[1]['function']));
+ }
+ // @codeCoverageIgnoreStart
+ return $this;
+ // @codeCoverageIgnoreEnd
}
is_bool($escape) || $escape = $this->db->protectIdentifiers;
@@ -1301,7 +1327,7 @@
*/
public function groupStart()
{
- return $this->groupStartPrepare('', 'AND ', 'QBWhere');
+ return $this->groupStartPrepare();
}
//--------------------------------------------------------------------
@@ -1313,7 +1339,7 @@
*/
public function orGroupStart()
{
- return $this->groupStartPrepare('', 'OR ', 'QBWhere');
+ return $this->groupStartPrepare('', 'OR ');
}
//--------------------------------------------------------------------
@@ -1325,7 +1351,7 @@
*/
public function notGroupStart()
{
- return $this->groupStartPrepare('NOT ', 'AND ', 'QBWhere');
+ return $this->groupStartPrepare('NOT ');
}
//--------------------------------------------------------------------
@@ -1337,7 +1363,7 @@
*/
public function orNotGroupStart()
{
- return $this->groupStartPrepare('NOT ', 'OR ', 'QBWhere');
+ return $this->groupStartPrepare('NOT ', 'OR ');
}
//--------------------------------------------------------------------
@@ -1349,7 +1375,7 @@
*/
public function groupEnd()
{
- return $this->groupEndPrepare('QBWhere');
+ return $this->groupEndPrepare();
}
// --------------------------------------------------------------------
@@ -1682,9 +1708,9 @@
*
* @return string
*/
- protected function _limit(string $sql): string
+ protected function _limit(string $sql, bool $offsetIgnore = false): string
{
- return $sql . ' LIMIT ' . ($this->QBOffset ? $this->QBOffset . ', ' : '') . $this->QBLimit;
+ return $sql . ' LIMIT ' . (false === $offsetIgnore && $this->QBOffset ? $this->QBOffset . ', ' : '') . $this->QBLimit;
}
//--------------------------------------------------------------------
@@ -1897,7 +1923,7 @@
$limit = $this->QBLimit;
$this->QBLimit = false;
- $sql = ($this->QBDistinct === true)
+ $sql = ($this->QBDistinct === true || ! empty($this->QBGroupBy))
?
$this->countString . $this->db->protectIdentifiers('numrows') . "\nFROM (\n" . $this->compileSelect() . "\n) CI_count_all_results"
:
@@ -2012,8 +2038,9 @@
{
throw new DatabaseException('You must use the "set" method to update an entry.');
}
-
+ // @codeCoverageIgnoreStart
return false;
+ // @codeCoverageIgnoreEnd
}
}
else
@@ -2024,8 +2051,9 @@
{
throw new DatabaseException('insertBatch() called with no data');
}
-
+ // @codeCoverageIgnoreStart
return false;
+ // @codeCoverageIgnoreEnd
}
$this->setInsertBatch($set, '', $escape);
@@ -2234,8 +2262,9 @@
{
throw new DatabaseException('You must use the "set" method to update an entry.');
}
-
+ // @codeCoverageIgnoreStart
return false;
+ // @codeCoverageIgnoreEnd
}
return true;
@@ -2284,7 +2313,9 @@
{
throw new DatabaseException('You must use the "set" method to update an entry.');
}
+ // @codeCoverageIgnoreStart
return false;
+ // @codeCoverageIgnoreEnd
}
$table = $this->QBFrom[0];
@@ -2445,7 +2476,7 @@
return 'UPDATE ' . $this->compileIgnore('update') . $table . ' SET ' . implode(', ', $valStr)
. $this->compileWhereHaving('QBWhere')
. $this->compileOrderBy()
- . ($this->QBLimit ? $this->_limit(' ') : '');
+ . ($this->QBLimit ? $this->_limit(' ', true) : '');
}
//--------------------------------------------------------------------
@@ -2468,8 +2499,9 @@
{
throw new DatabaseException('You must use the "set" method to update an entry.');
}
-
+ // @codeCoverageIgnoreStart
return false;
+ // @codeCoverageIgnoreEnd
}
return true;
@@ -2497,8 +2529,9 @@
{
throw new DatabaseException('You must specify an index to match on for batch updates.');
}
-
+ // @codeCoverageIgnoreStart
return false;
+ // @codeCoverageIgnoreEnd
}
if ($set === null)
@@ -2509,7 +2542,9 @@
{
throw new DatabaseException('You must use the "set" method to update an entry.');
}
+ // @codeCoverageIgnoreStart
return false;
+ // @codeCoverageIgnoreEnd
}
}
else
@@ -2520,7 +2555,9 @@
{
throw new DatabaseException('updateBatch() called with no data');
}
+ // @codeCoverageIgnoreStart
return false;
+ // @codeCoverageIgnoreEnd
}
$this->setUpdateBatch($set, $index);
@@ -2573,7 +2610,7 @@
$ids = [];
$final = [];
- foreach ($values as $key => $val)
+ foreach ($values as $val)
{
$ids[] = $val[$index];
@@ -2622,7 +2659,7 @@
is_bool($escape) || $escape = $this->db->protectIdentifiers;
- foreach ($key as $k => $v)
+ foreach ($key as $v)
{
$index_set = false;
$clean = [];
@@ -2769,8 +2806,9 @@
{
throw new DatabaseException('Deletes are not allowed unless they contain a "where" or "like" clause.');
}
-
+ // @codeCoverageIgnoreStart
return false;
+ // @codeCoverageIgnoreEnd
}
$sql = $this->_delete($table);
@@ -2787,7 +2825,7 @@
throw new DatabaseException('SQLite3 does not allow LIMITs on DELETE queries.');
}
- $sql = $this->_limit($sql);
+ $sql = $this->_limit($sql, true);
}
if ($reset_data)
@@ -2849,8 +2887,7 @@
*/
protected function _delete(string $table): string
{
- return 'DELETE ' . $this->compileIgnore('delete') . 'FROM ' . $table . $this->compileWhereHaving('QBWhere')
- . ($this->QBLimit ? ' LIMIT ' . $this->QBLimit : '');
+ return 'DELETE ' . $this->compileIgnore('delete') . 'FROM ' . $table . $this->compileWhereHaving('QBWhere');
}
//--------------------------------------------------------------------
@@ -3304,6 +3341,12 @@
{
$this->db->setAliasedTables([]);
}
+
+ // Reset QBFrom part
+ if (! empty($this->QBFrom))
+ {
+ $this->from(array_shift($this->QBFrom), true);
+ }
}
//--------------------------------------------------------------------
@@ -3402,12 +3445,11 @@
return $key;
}
- $count = 0;
-
- while (array_key_exists($key . $count, $this->binds))
+ if (! array_key_exists($key, $this->bindsKeyCount))
{
- ++$count;
+ $this->bindsKeyCount[$key] = 0;
}
+ $count = $this->bindsKeyCount[$key]++;
$this->binds[$key . $count] = [
$value,
diff --git a/system/Database/BaseConnection.php b/system/Database/BaseConnection.php
index de9d510..844cf7b 100644
--- a/system/Database/BaseConnection.php
+++ b/system/Database/BaseConnection.php
@@ -39,8 +39,8 @@
namespace CodeIgniter\Database;
-use CodeIgniter\Events\Events;
use CodeIgniter\Database\Exceptions\DatabaseException;
+use CodeIgniter\Events\Events;
/**
* Class BaseConnection
@@ -1002,7 +1002,7 @@
$this->initialize();
}
- $this->pretend(true);
+ $this->pretend();
$sql = $func($this);
@@ -1381,9 +1381,7 @@
{
if (is_array($str))
{
- $str = array_map([&$this, 'escape'], $str);
-
- return $str;
+ return array_map([&$this, 'escape'], $str);
}
else if (is_string($str) || ( is_object($str) && method_exists($str, '__toString')))
{
diff --git a/system/Database/BaseResult.php b/system/Database/BaseResult.php
index b9d586a..5e6abe3 100644
--- a/system/Database/BaseResult.php
+++ b/system/Database/BaseResult.php
@@ -39,6 +39,8 @@
namespace CodeIgniter\Database;
+use CodeIgniter\Entity;
+
/**
* Class BaseResult
*/
@@ -187,12 +189,12 @@
return $this->customResultObject[$className];
}
- is_null($this->rowData) || $this->dataSeek(0);
+ is_null($this->rowData) || $this->dataSeek();
$this->customResultObject[$className] = [];
while ($row = $this->fetchObject($className))
{
- if (method_exists($row, 'syncOriginal'))
+ if (! is_subclass_of($row, Entity::class) && method_exists($row, 'syncOriginal'))
{
$row->syncOriginal();
}
@@ -237,7 +239,7 @@
return $this->resultArray;
}
- is_null($this->rowData) || $this->dataSeek(0);
+ is_null($this->rowData) || $this->dataSeek();
while ($row = $this->fetchAssoc())
{
$this->resultArray[] = $row;
@@ -280,10 +282,10 @@
return $this->resultObject;
}
- is_null($this->rowData) || $this->dataSeek(0);
+ is_null($this->rowData) || $this->dataSeek();
while ($row = $this->fetchObject())
{
- if (method_exists($row, 'syncOriginal'))
+ if (! is_subclass_of($row, Entity::class) && method_exists($row, 'syncOriginal'))
{
$row->syncOriginal();
}
@@ -312,7 +314,7 @@
if (! is_numeric($n))
{
// We cache the row data for subsequent uses
- is_array($this->rowData) || $this->rowData = $this->getRowArray(0);
+ is_array($this->rowData) || $this->rowData = $this->getRowArray();
// array_key_exists() instead of isset() to allow for NULL values
if (empty($this->rowData) || ! array_key_exists($n, $this->rowData))
@@ -433,7 +435,7 @@
// We cache the row data for subsequent uses
if (! is_array($this->rowData))
{
- $this->rowData = $this->getRowArray(0);
+ $this->rowData = $this->getRowArray();
}
if (is_array($key))
diff --git a/system/Database/BaseUtils.php b/system/Database/BaseUtils.php
index a2ba2b0..e9a4dd6 100644
--- a/system/Database/BaseUtils.php
+++ b/system/Database/BaseUtils.php
@@ -356,7 +356,7 @@
'tables' => [],
'ignore' => [],
'filename' => '',
- 'format' => 'gzip', // gzip, zip, txt
+ 'format' => 'gzip', // gzip, txt
'add_drop' => true,
'add_insert' => true,
'newline' => "\n",
@@ -383,15 +383,14 @@
}
// Validate the format
- if (! in_array($prefs['format'], ['gzip', 'zip', 'txt'], true))
+ if (! in_array($prefs['format'], ['gzip', 'txt'], true))
{
$prefs['format'] = 'txt';
}
// Is the encoder supported? If not, we'll either issue an
// error or use plain text depending on the debug settings
- if (($prefs['format'] === 'gzip' && ! function_exists('gzencode'))
- || ( $prefs['format'] === 'zip' && ! function_exists('gzcompress')))
+ if ($prefs['format'] === 'gzip' && ! function_exists('gzencode'))
{
if ($this->db->DBDebug)
{
@@ -401,46 +400,12 @@
$prefs['format'] = 'txt';
}
- // Was a Zip file requested?
- if ($prefs['format'] === 'zip')
- {
- // Set the filename if not provided (only needed with Zip files)
- if ($prefs['filename'] === '')
- {
- $prefs['filename'] = (count($prefs['tables']) === 1 ? $prefs['tables'] : $this->db->database)
- . date('Y-m-d_H-i', time()) . '.sql';
- }
- else
- {
- // If they included the .zip file extension we'll remove it
- if (preg_match('|.+?\.zip$|', $prefs['filename']))
- {
- $prefs['filename'] = str_replace('.zip', '', $prefs['filename']);
- }
-
- // Tack on the ".sql" file extension if needed
- if (! preg_match('|.+?\.sql$|', $prefs['filename']))
- {
- $prefs['filename'] .= '.sql';
- }
- }
-
- // Load the Zip class and output it
- // $CI =& get_instance();
- // $CI->load->library('zip');
- // $CI->zip->add_data($prefs['filename'], $this->_backup($prefs));
- // return $CI->zip->get_zip();
- }
- elseif ($prefs['format'] === 'txt') // Was a text file requested?
+ if ($prefs['format'] === 'txt') // Was a text file requested?
{
return $this->_backup($prefs);
}
- elseif ($prefs['format'] === 'gzip') // Was a Gzip file requested?
- {
- return gzencode($this->_backup($prefs));
- }
- return;
+ return gzencode($this->_backup($prefs));
}
//--------------------------------------------------------------------
diff --git a/system/Database/Database.php b/system/Database/Database.php
index a8d26b1..adb0063 100644
--- a/system/Database/Database.php
+++ b/system/Database/Database.php
@@ -109,9 +109,7 @@
$db->initialize();
}
- $class = new $className($db);
-
- return $class;
+ return new $className($db);
}
//--------------------------------------------------------------------
@@ -133,9 +131,7 @@
$db->initialize();
}
- $class = new $className($db);
-
- return $class;
+ return new $className($db);
}
//--------------------------------------------------------------------
diff --git a/system/Database/Forge.php b/system/Database/Forge.php
index b40dc5e..e38d505 100644
--- a/system/Database/Forge.php
+++ b/system/Database/Forge.php
@@ -110,14 +110,14 @@
*
* @var string
*/
- protected $createDatabaseIfStr = null;
+ protected $createDatabaseIfStr;
/**
* CHECK DATABASE EXIST statement
*
* @var string
*/
- protected $checkDatabaseExistStr = null;
+ protected $checkDatabaseExistStr;
/**
* DROP DATABASE statement
@@ -717,9 +717,7 @@
}
}
- $sql = $sql . ' ' . $this->db->escapeIdentifiers($table);
-
- return $sql;
+ return $sql . ' ' . $this->db->escapeIdentifiers($table);
}
//--------------------------------------------------------------------
diff --git a/system/Database/MigrationRunner.php b/system/Database/MigrationRunner.php
index 6d4f0e2..55350c8 100644
--- a/system/Database/MigrationRunner.php
+++ b/system/Database/MigrationRunner.php
@@ -38,10 +38,10 @@
namespace CodeIgniter\Database;
-use Config\Services;
use CodeIgniter\CLI\CLI;
use CodeIgniter\Config\BaseConfig;
use CodeIgniter\Exceptions\ConfigException;
+use Config\Services;
/**
* Class MigrationRunner
@@ -1027,6 +1027,15 @@
// Determine DBGroup to use
$group = $instance->getDBGroup() ?? config('Database')->defaultGroup;
+ // Skip tests db group when not running in testing environment
+ if (ENVIRONMENT !== 'testing' && $group === 'tests' && $this->groupFilter !== 'tests')
+ {
+ // @codeCoverageIgnoreStart
+ $this->groupSkip = true;
+ return true;
+ // @codeCoverageIgnoreEnd
+ }
+
// Skip migration if group filtering was set
if ($direction === 'up' && ! is_null($this->groupFilter) && $this->groupFilter !== $group)
{
diff --git a/system/Database/ModelFactory.php b/system/Database/ModelFactory.php
index 6b7d514..b2b4362 100644
--- a/system/Database/ModelFactory.php
+++ b/system/Database/ModelFactory.php
@@ -13,14 +13,6 @@
static private $instances = [];
/**
- * The Database connection to use,
- * if other than default.
- *
- * @var ConnectionInterface
- */
- static private $connection = null;
-
- /**
* Create new configuration instances or return
* a shared instance
*
diff --git a/system/Database/MySQLi/Connection.php b/system/Database/MySQLi/Connection.php
index 26b213c..9bda5b0 100644
--- a/system/Database/MySQLi/Connection.php
+++ b/system/Database/MySQLi/Connection.php
@@ -326,8 +326,19 @@
$res->free();
}
}
-
- return $this->connID->query($this->prepQuery($sql));
+ try
+ {
+ return $this->connID->query($this->prepQuery($sql));
+ }
+ catch (\mysqli_sql_exception $e)
+ {
+ log_message('error', $e);
+ if ($this->DBDebug)
+ {
+ throw $e;
+ }
+ }
+ return false;
}
//--------------------------------------------------------------------
@@ -424,8 +435,6 @@
'\\' . '_',
], $str
);
-
- return $str;
}
//--------------------------------------------------------------------
diff --git a/system/Database/MySQLi/PreparedQuery.php b/system/Database/MySQLi/PreparedQuery.php
index 35d87b1..3ef4104 100644
--- a/system/Database/MySQLi/PreparedQuery.php
+++ b/system/Database/MySQLi/PreparedQuery.php
@@ -39,8 +39,8 @@
namespace CodeIgniter\Database\MySQLi;
-use CodeIgniter\Database\PreparedQueryInterface;
use CodeIgniter\Database\BasePreparedQuery;
+use CodeIgniter\Database\PreparedQueryInterface;
/**
* Prepared query for MySQLi
@@ -116,9 +116,7 @@
// Bind it
$this->statement->bind_param($bindTypes, ...$data);
- $success = $this->statement->execute();
-
- return $success;
+ return $this->statement->execute();
}
//--------------------------------------------------------------------
diff --git a/system/Database/Postgre/Builder.php b/system/Database/Postgre/Builder.php
index bf20a3d..fa45c45 100644
--- a/system/Database/Postgre/Builder.php
+++ b/system/Database/Postgre/Builder.php
@@ -40,7 +40,6 @@
use CodeIgniter\Database\BaseBuilder;
use CodeIgniter\Database\Exceptions\DatabaseException;
-use http\Encoding\Stream\Inflate;
/**
* Builder for Postgre
@@ -196,7 +195,9 @@
{
throw new DatabaseException('You must use the "set" method to update an entry.');
}
+ // @codeCoverageIgnoreStart
return false;
+ // @codeCoverageIgnoreEnd
}
$table = $this->QBFrom[0];
@@ -269,7 +270,7 @@
*
* @return string
*/
- protected function _limit(string $sql): string
+ protected function _limit(string $sql, bool $offsetIgnore = false): string
{
return $sql . ' LIMIT ' . $this->QBLimit . ($this->QBOffset ? " OFFSET {$this->QBOffset}" : '');
}
@@ -316,7 +317,7 @@
protected function _updateBatch(string $table, array $values, string $index): string
{
$ids = [];
- foreach ($values as $key => $val)
+ foreach ($values as $val)
{
$ids[] = $val[$index];
diff --git a/system/Database/Postgre/Connection.php b/system/Database/Postgre/Connection.php
index b239232..c3d6db6 100644
--- a/system/Database/Postgre/Connection.php
+++ b/system/Database/Postgre/Connection.php
@@ -187,11 +187,23 @@
*
* @param string $sql
*
- * @return resource
+ * @return mixed
*/
public function execute(string $sql)
{
- return pg_query($this->connID, $sql);
+ try
+ {
+ return pg_query($this->connID, $sql);
+ }
+ catch (\ErrorException $e)
+ {
+ log_message('error', $e);
+ if ($this->DBDebug)
+ {
+ throw $e;
+ }
+ }
+ return false;
}
//--------------------------------------------------------------------
diff --git a/system/Database/Postgre/PreparedQuery.php b/system/Database/Postgre/PreparedQuery.php
index 7b3bff3..27e3da2 100644
--- a/system/Database/Postgre/PreparedQuery.php
+++ b/system/Database/Postgre/PreparedQuery.php
@@ -39,8 +39,8 @@
namespace CodeIgniter\Database\Postgre;
-use CodeIgniter\Database\PreparedQueryInterface;
use CodeIgniter\Database\BasePreparedQuery;
+use CodeIgniter\Database\PreparedQueryInterface;
/**
* Prepared query for Postgre
@@ -148,12 +148,10 @@
// Track our current value
$count = 0;
- $sql = preg_replace_callback('/\?/', function ($matches) use (&$count) {
+ return preg_replace_callback('/\?/', function ($matches) use (&$count) {
$count ++;
return "\${$count}";
}, $sql);
-
- return $sql;
}
//--------------------------------------------------------------------
diff --git a/system/Database/Query.php b/system/Database/Query.php
index 301185b..dae2eeb 100644
--- a/system/Database/Query.php
+++ b/system/Database/Query.php
@@ -368,7 +368,7 @@
{
$sql = $this->finalQueryString;
- $hasNamedBinds = strpos($sql, ':') !== false;
+ $hasNamedBinds = strpos($sql, ':') !== false && strpos($sql, ':=') === false;
if (empty($this->binds) || empty($this->bindMarker) ||
(strpos($sql, $this->bindMarker) === false &&
@@ -440,9 +440,7 @@
$replacers[":{$placeholder}:"] = $escapedValue;
}
- $sql = strtr($sql, $replacers);
-
- return $sql;
+ return strtr($sql, $replacers);
}
//--------------------------------------------------------------------
diff --git a/system/Database/SQLite3/Connection.php b/system/Database/SQLite3/Connection.php
index ae83cfc..d3ac1cb 100644
--- a/system/Database/SQLite3/Connection.php
+++ b/system/Database/SQLite3/Connection.php
@@ -165,9 +165,21 @@
*/
public function execute(string $sql)
{
- return $this->isWriteType($sql)
- ? $this->connID->exec($sql)
- : $this->connID->query($sql);
+ try
+ {
+ return $this->isWriteType($sql)
+ ? $this->connID->exec($sql)
+ : $this->connID->query($sql);
+ }
+ catch (\ErrorException $e)
+ {
+ log_message('error', $e);
+ if ($this->DBDebug)
+ {
+ throw $e;
+ }
+ }
+ return false;
}
//--------------------------------------------------------------------
@@ -323,8 +335,8 @@
$retVal[$i]->type = $query[$i]->type;
$retVal[$i]->max_length = null;
$retVal[$i]->default = $query[$i]->dflt_value;
- $retVal[$i]->primary_key = isset($query[$i]->pk) ? (bool)$query[$i]->pk : false;
- $retVal[$i]->nullable = isset($query[$i]->notnull) ? ! (bool)$query[$i]->notnull : false;
+ $retVal[$i]->primary_key = isset($query[$i]->pk) && (bool)$query[$i]->pk;
+ $retVal[$i]->nullable = isset($query[$i]->notnull) && ! (bool)$query[$i]->notnull;
}
return $retVal;
diff --git a/system/Database/SQLite3/Forge.php b/system/Database/SQLite3/Forge.php
index 338c6e4..bb6f482 100644
--- a/system/Database/SQLite3/Forge.php
+++ b/system/Database/SQLite3/Forge.php
@@ -167,7 +167,6 @@
->run();
return '';
- break;
case 'CHANGE':
$sqlTable = new Table($this->db, $this);
@@ -176,7 +175,6 @@
->run();
return null;
- break;
default:
return parent::_alterTable($alter_type, $table, $field);
}
diff --git a/system/Database/SQLite3/PreparedQuery.php b/system/Database/SQLite3/PreparedQuery.php
index fbd6fea..22202c3 100644
--- a/system/Database/SQLite3/PreparedQuery.php
+++ b/system/Database/SQLite3/PreparedQuery.php
@@ -39,8 +39,8 @@
namespace CodeIgniter\Database\SQLite3;
-use CodeIgniter\Database\PreparedQueryInterface;
use CodeIgniter\Database\BasePreparedQuery;
+use CodeIgniter\Database\PreparedQueryInterface;
/**
* Prepared query for SQLite3
diff --git a/system/Database/Seeder.php b/system/Database/Seeder.php
index 682b7ce..97eb414 100644
--- a/system/Database/Seeder.php
+++ b/system/Database/Seeder.php
@@ -122,6 +122,8 @@
}
$this->db = & $db;
+
+ $this->forge = \Config\Database::forge($this->DBGroup);
}
//--------------------------------------------------------------------
diff --git a/system/Debug/Exceptions.php b/system/Debug/Exceptions.php
index 7cc3043..7f7ca2c 100644
--- a/system/Debug/Exceptions.php
+++ b/system/Debug/Exceptions.php
@@ -142,6 +142,7 @@
*/
public function exceptionHandler(Throwable $exception)
{
+ // @codeCoverageIgnoreStart
$codes = $this->determineCodes($exception);
$statusCode = $codes[0];
$exitCode = $codes[1];
@@ -171,6 +172,7 @@
$this->render($exception, $statusCode);
exit($exitCode);
+ // @codeCoverageIgnoreEnd
}
//--------------------------------------------------------------------
@@ -186,11 +188,10 @@
* @param string $message
* @param string|null $file
* @param integer|null $line
- * @param null $context
*
* @throws \ErrorException
*/
- public function errorHandler(int $severity, string $message, string $file = null, int $line = null, $context = null)
+ public function errorHandler(int $severity, string $message, string $file = null, int $line = null)
{
if (! (error_reporting() & $severity))
{
@@ -371,17 +372,20 @@
*/
public static function cleanPath(string $file): string
{
- if (strpos($file, APPPATH) === 0)
+ switch (true)
{
- $file = 'APPPATH/' . substr($file, strlen(APPPATH));
- }
- elseif (strpos($file, SYSTEMPATH) === 0)
- {
- $file = 'SYSTEMPATH/' . substr($file, strlen(SYSTEMPATH));
- }
- elseif (strpos($file, FCPATH) === 0)
- {
- $file = 'FCPATH/' . substr($file, strlen(FCPATH));
+ case strpos($file, APPPATH) === 0:
+ $file = 'APPPATH' . DIRECTORY_SEPARATOR . substr($file, strlen(APPPATH));
+ break;
+ case strpos($file, SYSTEMPATH) === 0:
+ $file = 'SYSTEMPATH' . DIRECTORY_SEPARATOR . substr($file, strlen(SYSTEMPATH));
+ break;
+ case strpos($file, FCPATH) === 0:
+ $file = 'FCPATH' . DIRECTORY_SEPARATOR . substr($file, strlen(FCPATH));
+ break;
+ case defined('VENDORPATH') && strpos($file, VENDORPATH) === 0;
+ $file = 'VENDORPATH' . DIRECTORY_SEPARATOR . substr($file, strlen(VENDORPATH));
+ break;
}
return $file;
diff --git a/system/Debug/Toolbar.php b/system/Debug/Toolbar.php
index 02e50fc..ff2be35 100644
--- a/system/Debug/Toolbar.php
+++ b/system/Debug/Toolbar.php
@@ -118,7 +118,7 @@
$data['startTime'] = $startTime;
$data['totalTime'] = $totalTime * 1000;
$data['totalMemory'] = number_format((memory_get_peak_usage()) / 1024 / 1024, 3);
- $data['segmentDuration'] = $this->roundTo($data['totalTime'] / 7, 5);
+ $data['segmentDuration'] = $this->roundTo($data['totalTime'] / 7);
$data['segmentCount'] = (int) ceil($data['totalTime'] / $data['segmentDuration']);
$data['CI_VERSION'] = \CodeIgniter\CodeIgniter::CI_VERSION;
$data['collectors'] = [];
@@ -167,7 +167,7 @@
$data['vars']['post'][esc($name)] = is_array($value) ? '' . esc(print_r($value, true)) . ' ' : esc($value);
}
- foreach ($request->getHeaders() as $header => $value)
+ foreach ($request->getHeaders() as $value)
{
if (empty($value))
{
@@ -415,6 +415,7 @@
return;
}
+ // @codeCoverageIgnoreStart
$request = Services::request();
// If the request contains '?debugbar then we're
@@ -459,6 +460,7 @@
http_response_code(404);
exit; // Exit here is needed to avoid load the index page
}
+ // @codeCoverageIgnoreEnd
}
/**
diff --git a/system/Debug/Toolbar/Collectors/Config.php b/system/Debug/Toolbar/Collectors/Config.php
index 1ae809c..82ef634 100644
--- a/system/Debug/Toolbar/Collectors/Config.php
+++ b/system/Debug/Toolbar/Collectors/Config.php
@@ -39,9 +39,9 @@
namespace CodeIgniter\Debug\Toolbar\Collectors;
+use CodeIgniter\CodeIgniter;
use Config\App;
use Config\Services;
-use CodeIgniter\CodeIgniter;
/**
* Debug toolbar configuration
diff --git a/system/Debug/Toolbar/Collectors/Events.php b/system/Debug/Toolbar/Collectors/Events.php
index 285d87d..41c9f00 100644
--- a/system/Debug/Toolbar/Collectors/Events.php
+++ b/system/Debug/Toolbar/Collectors/Events.php
@@ -39,8 +39,8 @@
namespace CodeIgniter\Debug\Toolbar\Collectors;
-use Config\Services;
use CodeIgniter\View\RendererInterface;
+use Config\Services;
/**
* Views collector
@@ -111,7 +111,7 @@
$rows = $this->viewer->getPerformanceData();
- foreach ($rows as $name => $info)
+ foreach ($rows as $info)
{
$data[] = [
'name' => 'View: ' . $info['view'],
diff --git a/system/Debug/Toolbar/Collectors/Views.php b/system/Debug/Toolbar/Collectors/Views.php
index 8bcec56..bf0c110 100644
--- a/system/Debug/Toolbar/Collectors/Views.php
+++ b/system/Debug/Toolbar/Collectors/Views.php
@@ -39,8 +39,8 @@
namespace CodeIgniter\Debug\Toolbar\Collectors;
-use Config\Services;
use CodeIgniter\View\RendererInterface;
+use Config\Services;
/**
* Views collector
@@ -126,7 +126,7 @@
$rows = $this->viewer->getPerformanceData();
- foreach ($rows as $name => $info)
+ foreach ($rows as $info)
{
$data[] = [
'name' => 'View: ' . $info['view'],
diff --git a/system/Debug/Toolbar/Views/toolbarloader.js.php b/system/Debug/Toolbar/Views/toolbarloader.js.php
index 4ecdeeb..af69338 100644
--- a/system/Debug/Toolbar/Views/toolbarloader.js.php
+++ b/system/Debug/Toolbar/Views/toolbarloader.js.php
@@ -75,9 +75,11 @@
var debugbarTime = realXHR.getResponseHeader('Debugbar-Time');
if (debugbarTime) {
var h2 = document.querySelector('#ci-history > h2');
- h2.innerHTML = 'History You have new debug data. Update ';
- var badge = document.querySelector('a[data-tab="ci-history"] > span > .badge');
- badge.className += ' active';
+ if(h2) {
+ h2.innerHTML = 'History You have new debug data. Update ';
+ var badge = document.querySelector('a[data-tab="ci-history"] > span > .badge');
+ badge.className += ' active';
+ }
}
}
}, false);
diff --git a/system/Encryption/Encryption.php b/system/Encryption/Encryption.php
index 1f047f6..4c2d333 100644
--- a/system/Encryption/Encryption.php
+++ b/system/Encryption/Encryption.php
@@ -38,10 +38,8 @@
namespace CodeIgniter\Encryption;
-use Config\Encryption as EncryptionConfig;
-use CodeIgniter\Encryption\Exceptions\EncryptionException;
use CodeIgniter\Config\BaseConfig;
-use Config\Services;
+use CodeIgniter\Encryption\Exceptions\EncryptionException;
/**
* CodeIgniter Encryption Manager
diff --git a/system/Encryption/Handlers/OpenSSLHandler.php b/system/Encryption/Handlers/OpenSSLHandler.php
index 72b6023..50622d1 100644
--- a/system/Encryption/Handlers/OpenSSLHandler.php
+++ b/system/Encryption/Handlers/OpenSSLHandler.php
@@ -64,7 +64,7 @@
*
* @param BaseConfig $config
*
- * @throws \CodeIgniter\Encryption\EncryptionException
+ * @throws \CodeIgniter\Encryption\Exceptions\EncryptionException
*/
public function __construct(BaseConfig $config = null)
{
@@ -77,7 +77,7 @@
* @param string $data Input data
* @param array $params Over-ridden parameters, specifically the key
* @return string
- * @throws \CodeIgniter\Encryption\EncryptionException
+ * @throws \CodeIgniter\Encryption\Exceptions\EncryptionException
*/
public function encrypt($data, $params = null)
{
@@ -114,9 +114,8 @@
$result = $iv . $data;
$hmacKey = \hash_hmac($this->digest, $result, $secret, true);
- $result = $hmacKey . $result;
- return $result;
+ return $hmacKey . $result;
}
// --------------------------------------------------------------------
@@ -127,7 +126,7 @@
* @param string $data Encrypted data
* @param array $params Over-ridden parameters, specifically the key
* @return string
- * @throws \CodeIgniter\Encryption\EncryptionException
+ * @throws \CodeIgniter\Encryption\Exceptions\EncryptionException
*/
public function decrypt($data, $params = null)
{
@@ -145,7 +144,7 @@
}
if (empty($this->key))
{
- throw EncryptionException::forStarterKeyNeeded();
+ throw EncryptionException::forNeedsStarterKey();
}
// derive a secret key
diff --git a/system/Entity.php b/system/Entity.php
index 94153d0..1ccd6d2 100644
--- a/system/Entity.php
+++ b/system/Entity.php
@@ -39,14 +39,13 @@
namespace CodeIgniter;
-use CodeIgniter\Exceptions\EntityException;
-use CodeIgniter\I18n\Time;
use CodeIgniter\Exceptions\CastException;
+use CodeIgniter\I18n\Time;
/**
* Entity encapsulation, for use with CodeIgniter\Model
*/
-class Entity
+class Entity implements \JsonSerializable
{
/**
* Maps names used in sets and gets against unique
@@ -165,7 +164,7 @@
// allow our magic methods a chance to do their thing.
foreach ($this->attributes as $key => $value)
{
- if (substr($key, 0, 1) === '_')
+ if (strpos($key, '_') === 0)
{
continue;
}
@@ -353,7 +352,7 @@
if (array_key_exists($key, $this->casts))
{
- $isNullable = substr($this->casts[$key], 0, 1) === '?';
+ $isNullable = strpos($this->casts[$key], '?') === 0;
$castTo = $isNullable ? substr($this->casts[$key], 1) : $this->casts[$key];
}
@@ -530,7 +529,7 @@
protected function castAs($value, string $type)
{
- if (substr($type, 0, 1) === '?')
+ if (strpos($type, '?') === 0)
{
if ($value === null)
{
@@ -570,17 +569,15 @@
$value = (array)$value;
break;
case 'json':
- $value = $this->castAsJson($value, false);
+ $value = $this->castAsJson($value);
break;
case 'json-array':
$value = $this->castAsJson($value, true);
break;
case 'datetime':
- return new \DateTime($value);
- break;
+ return $this->mutateDate($value);
case 'timestamp':
return strtotime($value);
- break;
}
return $value;
@@ -614,4 +611,15 @@
}
return $tmp;
}
+
+ /**
+ * Support for json_encode()
+ *
+ * @return array|mixed
+ * @throws \Exception
+ */
+ public function jsonSerialize()
+ {
+ return $this->toArray();
+ }
}
diff --git a/system/Exceptions/CastException.php b/system/Exceptions/CastException.php
index a5bb065..ddcb717 100644
--- a/system/Exceptions/CastException.php
+++ b/system/Exceptions/CastException.php
@@ -19,22 +19,17 @@
switch($error)
{
case JSON_ERROR_DEPTH:
- throw new static(lang('Cast.jsonErrorDepth'));
- break;
+ return new static(lang('Cast.jsonErrorDepth'));
case JSON_ERROR_STATE_MISMATCH:
- throw new static(lang('Cast.jsonErrorStateMismatch'));
- break;
+ return new static(lang('Cast.jsonErrorStateMismatch'));
case JSON_ERROR_CTRL_CHAR:
- throw new static(lang('Cast.jsonErrorCtrlChar'));
- break;
+ return new static(lang('Cast.jsonErrorCtrlChar'));
case JSON_ERROR_SYNTAX:
- throw new static(lang('Cast.jsonErrorSyntax'));
- break;
+ return new static(lang('Cast.jsonErrorSyntax'));
case JSON_ERROR_UTF8:
- throw new static(lang('Cast.jsonErrorUtf8'));
- break;
+ return new static(lang('Cast.jsonErrorUtf8'));
default:
- throw new static(lang('Cast.jsonErrorUnknown'));
+ return new static(lang('Cast.jsonErrorUnknown'));
}
}
diff --git a/system/Exceptions/ConfigException.php b/system/Exceptions/ConfigException.php
index dc36377..964c521 100644
--- a/system/Exceptions/ConfigException.php
+++ b/system/Exceptions/ConfigException.php
@@ -16,6 +16,6 @@
public static function forDisabledMigrations()
{
- throw new static(lang('Migrations.disabled'));
+ return new static(lang('Migrations.disabled'));
}
}
diff --git a/system/Files/File.php b/system/Files/File.php
index 8b5fc2e..1f59795 100644
--- a/system/Files/File.php
+++ b/system/Files/File.php
@@ -39,9 +39,9 @@
namespace CodeIgniter\Files;
-use SplFileInfo;
use CodeIgniter\Files\Exceptions\FileException;
use CodeIgniter\Files\Exceptions\FileNotFoundException;
+use SplFileInfo;
/**
* Wrapper for PHP's built-in SplFileInfo, with goodies.
diff --git a/system/Filters/Filters.php b/system/Filters/Filters.php
index 853e135..451a2da 100644
--- a/system/Filters/Filters.php
+++ b/system/Filters/Filters.php
@@ -39,9 +39,9 @@
namespace CodeIgniter\Filters;
use CodeIgniter\Config\BaseConfig;
+use CodeIgniter\Filters\Exceptions\FilterException;
use CodeIgniter\HTTP\RequestInterface;
use CodeIgniter\HTTP\ResponseInterface;
-use CodeIgniter\Filters\Exceptions\FilterException;
/**
* Filters
@@ -150,47 +150,59 @@
throw FilterException::forNoAlias($alias);
}
- $class = new $this->config->aliases[$alias]();
-
- if (! $class instanceof FilterInterface)
+ if (is_array($this->config->aliases[$alias]))
{
- throw FilterException::forIncorrectInterface(get_class($class));
+ $classNames = $this->config->aliases[$alias];
+ }
+ else
+ {
+ $classNames = [$this->config->aliases[$alias]];
}
- if ($position === 'before')
+ foreach ($classNames as $className)
{
- $result = $class->before($this->request, $this->arguments[$alias] ?? null);
+ $class = new $className();
- if ($result instanceof RequestInterface)
+ if (! $class instanceof FilterInterface)
{
- $this->request = $result;
- continue;
+ throw FilterException::forIncorrectInterface(get_class($class));
}
- // If the response object was sent back,
- // then send it and quit.
- if ($result instanceof ResponseInterface)
+ if ($position === 'before')
{
- // short circuit - bypass any other filters
+ $result = $class->before($this->request, $this->arguments[$alias] ?? null);
+
+ if ($result instanceof RequestInterface)
+ {
+ $this->request = $result;
+ continue;
+ }
+
+ // If the response object was sent back,
+ // then send it and quit.
+ if ($result instanceof ResponseInterface)
+ {
+ // short circuit - bypass any other filters
+ return $result;
+ }
+
+ // Ignore an empty result
+ if (empty($result))
+ {
+ continue;
+ }
+
return $result;
}
-
- // Ignore an empty result
- if (empty($result))
+ elseif ($position === 'after')
{
- continue;
- }
+ $result = $class->after($this->request, $this->response);
- return $result;
- }
- elseif ($position === 'after')
- {
- $result = $class->after($this->request, $this->response);
-
- if ($result instanceof ResponseInterface)
- {
- $this->response = $result;
- continue;
+ if ($result instanceof ResponseInterface)
+ {
+ $this->response = $result;
+ continue;
+ }
}
}
}
diff --git a/system/Filters/Honeypot.php b/system/Filters/Honeypot.php
index aea08c3..a5807e4 100644
--- a/system/Filters/Honeypot.php
+++ b/system/Filters/Honeypot.php
@@ -38,10 +38,10 @@
namespace CodeIgniter\Filters;
+use CodeIgniter\Honeypot\Exceptions\HoneypotException;
use CodeIgniter\HTTP\RequestInterface;
use CodeIgniter\HTTP\ResponseInterface;
use Config\Services;
-use CodeIgniter\Honeypot\Exceptions\HoneypotException;
/**
* Honeypot filter
diff --git a/system/Format/JSONFormatter.php b/system/Format/JSONFormatter.php
index 50caf39..823f3ca 100644
--- a/system/Format/JSONFormatter.php
+++ b/system/Format/JSONFormatter.php
@@ -56,13 +56,13 @@
*/
public function format($data)
{
- $options = JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES;
+ $options = JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES | JSON_PARTIAL_OUTPUT_ON_ERROR;
$options = ENVIRONMENT === 'production' ? $options : $options | JSON_PRETTY_PRINT;
$result = json_encode($data, $options, 512);
- if (json_last_error() !== JSON_ERROR_NONE)
+ if ( ! in_array(json_last_error(), [JSON_ERROR_NONE, JSON_ERROR_RECURSION]))
{
throw FormatException::forInvalidJSON(json_last_error_msg());
}
diff --git a/system/HTTP/CURLRequest.php b/system/HTTP/CURLRequest.php
index c5506ac..d1a8e94 100644
--- a/system/HTTP/CURLRequest.php
+++ b/system/HTTP/CURLRequest.php
@@ -536,9 +536,7 @@
// Have content?
if ($size === null || $size > 0)
{
- $curl_options = $this->applyBody($curl_options);
-
- return $curl_options;
+ return $this->applyBody($curl_options);
}
if ($method === 'PUT' || $method === 'POST')
diff --git a/system/HTTP/ContentSecurityPolicy.php b/system/HTTP/ContentSecurityPolicy.php
index 713312f..910f700 100644
--- a/system/HTTP/ContentSecurityPolicy.php
+++ b/system/HTTP/ContentSecurityPolicy.php
@@ -136,7 +136,7 @@
*
* @var string
*/
- protected $reportURI = null;
+ protected $reportURI;
/**
* Used for security enforcement
diff --git a/system/HTTP/IncomingRequest.php b/system/HTTP/IncomingRequest.php
index 0b363cd..b7c04df 100755
--- a/system/HTTP/IncomingRequest.php
+++ b/system/HTTP/IncomingRequest.php
@@ -427,7 +427,7 @@
// Use $_POST directly here, since filter_has_var only
// checks the initial POST data, not anything that might
// have been added since.
- return isset($_POST[$index]) ? $this->getPost($index, $filter, $flags) : $this->getGet($index, $filter, $flags);
+ return isset($_POST[$index]) ? $this->getPost($index, $filter, $flags) : (isset($_GET[$index]) ? $this->getGet($index, $filter, $flags) : $this->getPost());
}
//--------------------------------------------------------------------
@@ -446,7 +446,7 @@
// Use $_GET directly here, since filter_has_var only
// checks the initial GET data, not anything that might
// have been added since.
- return isset($_GET[$index]) ? $this->getGet($index, $filter, $flags) : $this->getPost($index, $filter, $flags);
+ return isset($_GET[$index]) ? $this->getGet($index, $filter, $flags) : (isset($_POST[$index]) ? $this->getPost($index, $filter, $flags) : $this->getGet());
}
//--------------------------------------------------------------------
@@ -616,7 +616,6 @@
$this->uri->setScheme(parse_url($baseURL, PHP_URL_SCHEME));
$this->uri->setHost(parse_url($baseURL, PHP_URL_HOST));
$this->uri->setPort(parse_url($baseURL, PHP_URL_PORT));
- $this->uri->resolveRelativeURI(parse_url($baseURL, PHP_URL_PATH));
// Ensure we have any query vars
$this->uri->setQuery($_SERVER['QUERY_STRING'] ?? '');
@@ -722,7 +721,7 @@
$query = $parts['query'] ?? '';
$uri = $parts['path'] ?? '';
- if (isset($_SERVER['SCRIPT_NAME'][0]))
+ if (isset($_SERVER['SCRIPT_NAME'][0]) && pathinfo($_SERVER['SCRIPT_NAME'], PATHINFO_EXTENSION) === 'php')
{
// strip the script name from the beginning of the URI
if (strpos($uri, $_SERVER['SCRIPT_NAME']) === 0)
diff --git a/system/HTTP/Message.php b/system/HTTP/Message.php
index 1afb1d5..6d7a5cc 100644
--- a/system/HTTP/Message.php
+++ b/system/HTTP/Message.php
@@ -316,7 +316,9 @@
{
$orig_name = $this->getHeaderName($name);
- $this->headers[$orig_name]->appendValue($value);
+ array_key_exists($orig_name, $this->headers)
+ ? $this->headers[$orig_name]->appendValue($value)
+ : $this->setHeader($name, $value);
return $this;
}
diff --git a/system/HTTP/Negotiate.php b/system/HTTP/Negotiate.php
index 6ac2d06..74aa470 100644
--- a/system/HTTP/Negotiate.php
+++ b/system/HTTP/Negotiate.php
@@ -179,7 +179,7 @@
*/
public function language(array $supported): string
{
- return $this->getBestMatch($supported, $this->request->getHeaderLine('accept-language'));
+ return $this->getBestMatch($supported, $this->request->getHeaderLine('accept-language'), false, false, true);
}
//--------------------------------------------------------------------
@@ -198,10 +198,11 @@
* @param boolean $enforceTypes If TRUE, will compare media types and sub-types.
* @param boolean $strictMatch If TRUE, will return empty string on no match.
* If FALSE, will return the first supported element.
+ * @param boolean $matchLocales If TRUE, will match locale sub-types to a broad type (fr-FR = fr)
*
* @return string Best match
*/
- protected function getBestMatch(array $supported, string $header = null, bool $enforceTypes = false, bool $strictMatch = false): string
+ protected function getBestMatch(array $supported, string $header = null, bool $enforceTypes = false, bool $strictMatch = false, bool $matchLocales = false): string
{
if (empty($supported))
{
@@ -232,7 +233,7 @@
// If an acceptable value is supported, return it
foreach ($supported as $available)
{
- if ($this->match($accept, $available, $enforceTypes))
+ if ($this->match($accept, $available, $enforceTypes, $matchLocales))
{
return $available;
}
@@ -337,12 +338,14 @@
/**
* Match-maker
*
- * @param array $acceptable
- * @param string $supported
- * @param boolean $enforceTypes
+ * @param array $acceptable
+ * @param string $supported
+ * @param boolean $enforceTypes
+ * @param boolean $matchLocales
+ *
* @return boolean
*/
- protected function match(array $acceptable, string $supported, bool $enforceTypes = false): bool
+ protected function match(array $acceptable, string $supported, bool $enforceTypes = false, $matchLocales = false): bool
{
$supported = $this->parseHeader($supported);
if (is_array($supported) && count($supported) === 1)
@@ -363,6 +366,12 @@
return $this->matchTypes($acceptable, $supported);
}
+ // Do we need to match locales against broader locales?
+ if ($matchLocales)
+ {
+ return $this->matchLocales($acceptable, $supported);
+ }
+
return false;
}
@@ -409,8 +418,14 @@
*/
public function matchTypes(array $acceptable, array $supported): bool
{
- list($aType, $aSubType) = explode('/', $acceptable['value']);
- list($sType, $sSubType) = explode('/', $supported['value']);
+ [
+ $aType,
+ $aSubType,
+ ] = explode('/', $acceptable['value']);
+ [
+ $sType,
+ $sSubType,
+ ] = explode('/', $supported['value']);
// If the types don't match, we're done.
if ($aType !== $sType)
@@ -429,4 +444,25 @@
}
//--------------------------------------------------------------------
+
+ /**
+ * Will match locales against their broader pairs, so that fr-FR would
+ * match a supported localed of fr
+ *
+ * @param array $acceptable
+ * @param array $supported
+ *
+ * @return boolean
+ */
+ public function matchLocales(array $acceptable, array $supported): bool
+ {
+ $aBroad = mb_strpos($acceptable['value'], '-') > 0
+ ? mb_substr($acceptable['value'], 0, mb_strpos($acceptable['value'], '-'))
+ : $acceptable['value'];
+ $sBroad = mb_strpos($supported['value'], '-') > 0
+ ? mb_substr($supported['value'], 0, mb_strpos($supported['value'], '-'))
+ : $supported['value'];
+
+ return strtolower($aBroad) === strtolower($sBroad);
+ }
}
diff --git a/system/HTTP/Response.php b/system/HTTP/Response.php
index a6d3c5e..0d8320b 100644
--- a/system/HTTP/Response.php
+++ b/system/HTTP/Response.php
@@ -40,10 +40,10 @@
namespace CodeIgniter\HTTP;
-use Config\App;
-use Config\Format;
use CodeIgniter\HTTP\Exceptions\HTTPException;
use CodeIgniter\Pager\PagerInterface;
+use Config\App;
+use Config\Format;
/**
* Representation of an outgoing, getServer-side response.
@@ -986,6 +986,7 @@
$name = $prefix . $name;
+ $cookieHasFlag = false;
foreach ($this->cookies as &$cookie)
{
if ($cookie['name'] === $name)
@@ -1000,11 +1001,16 @@
}
$cookie['value'] = '';
$cookie['expires'] = '';
-
+ $cookieHasFlag = true;
break;
}
}
+ if (! $cookieHasFlag)
+ {
+ $this->setCookie($name, '', '', $domain, $path, $prefix);
+ }
+
return $this;
}
diff --git a/system/HTTP/URI.php b/system/HTTP/URI.php
index 001b0a9..09aa3cd 100644
--- a/system/HTTP/URI.php
+++ b/system/HTTP/URI.php
@@ -566,7 +566,7 @@
$uri .= $authority;
}
- if ($path)
+ if ($path !== '')
{
$uri .= substr($uri, -1, 1) !== '/' ? '/' . ltrim($path, '/') : $path;
}
@@ -597,7 +597,12 @@
{
$parts = parse_url($str);
- if (empty($parts['host']) && ! empty($parts['path']))
+ if (! isset($parts['path']))
+ {
+ $parts['path'] = $this->getPath();
+ }
+
+ if (empty($parts['host']) && $parts['path'] !== '')
{
$parts['host'] = $parts['path'];
unset($parts['path']);
@@ -705,7 +710,9 @@
{
$this->path = $this->filterPath($path);
- $this->segments = explode('/', $this->path);
+ $tempPath = trim($this->path, '/');
+
+ $this->segments = ($tempPath === '') ? [] : explode('/', $tempPath);
return $this;
}
@@ -721,7 +728,9 @@
{
$this->path = $this->filterPath(implode('/', $this->segments));
- $this->segments = explode('/', $this->path);
+ $tempPath = trim($this->path, '/');
+
+ $this->segments = ($tempPath === '') ? [] : explode('/', $tempPath);
return $this;
}
@@ -913,7 +922,7 @@
{
$this->user = $parts['user'];
}
- if (! empty($parts['path']))
+ if (isset($parts['path']) && $parts['path'] !== '')
{
$this->path = $this->filterPath($parts['path']);
}
@@ -953,9 +962,11 @@
}
// Populate our segments array
- if (! empty($parts['path']))
+ if (isset($parts['path']) && $parts['path'] !== '')
{
- $this->segments = explode('/', trim($parts['path'], '/'));
+ $tempPath = trim($parts['path'], '/');
+
+ $this->segments = ($tempPath === '') ? [] : explode('/', $tempPath);
}
}
@@ -1048,14 +1059,14 @@
*/
protected function mergePaths(URI $base, URI $reference): string
{
- if (! empty($base->getAuthority()) && empty($base->getPath()))
+ if (! empty($base->getAuthority()) && $base->getPath() === '')
{
return '/' . ltrim($reference->getPath(), '/ ');
}
$path = explode('/', $base->getPath());
- if (empty($path[0]))
+ if ($path[0] === '')
{
unset($path[0]);
}
@@ -1082,7 +1093,7 @@
*/
public function removeDotSegments(string $path): string
{
- if (empty($path) || $path === '/')
+ if ($path === '' || $path === '/')
{
return $path;
}
@@ -1091,7 +1102,7 @@
$input = explode('/', $path);
- if (empty($input[0]))
+ if ($input[0] === '')
{
unset($input[0]);
$input = array_values($input);
diff --git a/system/HTTP/UserAgent.php b/system/HTTP/UserAgent.php
index 6e5b596..c6873fd 100644
--- a/system/HTTP/UserAgent.php
+++ b/system/HTTP/UserAgent.php
@@ -51,7 +51,7 @@
*
* @var string
*/
- protected $agent = null;
+ protected $agent;
/**
* Flag for if the user-agent belongs to a browser
diff --git a/system/Helpers/array_helper.php b/system/Helpers/array_helper.php
index 9c5d8f6..c114df9 100644
--- a/system/Helpers/array_helper.php
+++ b/system/Helpers/array_helper.php
@@ -79,7 +79,7 @@
? array_shift($indexes)
: null;
- if (empty($currentIndex) || (! isset($array[$currentIndex]) && $currentIndex !== '*'))
+ if ((empty($currentIndex) && intval($currentIndex) !== 0) || (! isset($array[$currentIndex]) && $currentIndex !== '*'))
{
return null;
}
@@ -90,7 +90,7 @@
// If $array has more than 1 item, we have to loop over each.
if (is_array($array))
{
- foreach ($array as $key => $value)
+ foreach ($array as $value)
{
$answer = _array_search_dot($indexes, $value);
diff --git a/system/Helpers/cookie_helper.php b/system/Helpers/cookie_helper.php
index d85f644..50ab392 100755
--- a/system/Helpers/cookie_helper.php
+++ b/system/Helpers/cookie_helper.php
@@ -96,9 +96,8 @@
$request = \Config\Services::request();
$filter = true === $xssClean ? FILTER_SANITIZE_STRING : null;
- $cookie = $request->getCookie($prefix . $index, $filter);
- return $cookie;
+ return $request->getCookie($prefix . $index, $filter);
}
}
diff --git a/system/Helpers/date_helper.php b/system/Helpers/date_helper.php
index 6cf362a..1951d25 100644
--- a/system/Helpers/date_helper.php
+++ b/system/Helpers/date_helper.php
@@ -96,8 +96,7 @@
$selected = ($timezone === $default) ? 'selected' : '';
$buffer .= "{$timezone} " . PHP_EOL;
}
- $buffer .= '' . PHP_EOL;
- return $buffer;
+ return $buffer . ('' . PHP_EOL);
}
}
diff --git a/system/Helpers/filesystem_helper.php b/system/Helpers/filesystem_helper.php
index 1ead233..2556e86 100644
--- a/system/Helpers/filesystem_helper.php
+++ b/system/Helpers/filesystem_helper.php
@@ -209,45 +209,54 @@
* Reads the specified directory and builds an array containing the filenames.
* Any sub-folders contained within the specified path are read as well.
*
- * @param string $source_dir Path to source
- * @param boolean $include_path Whether to include the path as part of the filename
- * @param boolean $recursion Internal variable to determine recursion status - do not use in calls
+ * @param string $source_dir Path to source
+ * @param boolean|null $include_path Whether to include the path as part of the filename; false for no path, null for a relative path, true for full path
+ * @param boolean $hidden Whether to include hidden files (files beginning with a period)
*
* @return array
*/
- function get_filenames(string $source_dir, bool $include_path = false, bool $recursion = false): array
+ function get_filenames(string $source_dir, ?bool $include_path = false, bool $hidden = false): array
{
- static $fileData = [];
+ $files = [];
+
+ $source_dir = realpath($source_dir) ?: $source_dir;
+ $source_dir = rtrim($source_dir, DIRECTORY_SEPARATOR) . DIRECTORY_SEPARATOR;
try
{
- $fp = opendir($source_dir);
- // reset the array and make sure $source_dir has a trailing slash on the initial call
- if ($recursion === false)
+ foreach (new RecursiveIteratorIterator(
+ new RecursiveDirectoryIterator($source_dir, RecursiveDirectoryIterator::SKIP_DOTS),
+ RecursiveIteratorIterator::SELF_FIRST
+ ) as $name => $object)
{
- $fileData = [];
- $source_dir = rtrim(realpath($source_dir), DIRECTORY_SEPARATOR) . DIRECTORY_SEPARATOR;
- }
+ $basename = pathinfo($name, PATHINFO_BASENAME);
- while (false !== ($file = readdir($fp)))
- {
- if (is_dir($source_dir . $file) && $file[0] !== '.')
+ if (! $hidden && $basename[0] === '.')
{
- get_filenames($source_dir . $file . DIRECTORY_SEPARATOR, $include_path, true);
+ continue;
}
- elseif ($file[0] !== '.')
+ elseif ($include_path === false)
{
- $fileData[] = ($include_path === true) ? $source_dir . $file : $file;
+ $files[] = $basename;
+ }
+ elseif (is_null($include_path))
+ {
+ $files[] = str_replace($source_dir, '', $name);
+ }
+ else
+ {
+ $files[] = $name;
}
}
-
- closedir($fp);
- return $fileData;
}
- catch (\Exception $fe)
+ catch (\Throwable $e)
{
return [];
}
+
+ sort($files);
+
+ return $files;
}
}
diff --git a/system/Helpers/form_helper.php b/system/Helpers/form_helper.php
index 82c809c..e505e65 100644
--- a/system/Helpers/form_helper.php
+++ b/system/Helpers/form_helper.php
@@ -69,6 +69,12 @@
} // If an action is not a full URL then turn it into one
elseif (strpos($action, '://') === false)
{
+ // If an action has {locale}
+ if (strpos($action, '{locale}') !== false)
+ {
+ $action = str_replace('{locale}', Services::request()->getLocale(), $action);
+ }
+
$action = site_url($action);
}
@@ -180,7 +186,7 @@
if (! is_array($value))
{
- $form .= ' \n";
+ $form .= ' \n";
}
else
{
@@ -408,7 +414,7 @@
{
$sel = in_array($optgroup_key, $selected) ? ' selected="selected"' : '';
$form .= ''
- . (string) $optgroup_val . " \n";
+ . $optgroup_val . "\n";
}
$form .= "\n";
}
@@ -416,7 +422,7 @@
{
$form .= ''
- . (string) $val . " \n";
+ . $val . "\n";
}
}
@@ -645,9 +651,7 @@
$out .= "" . "\n";
}
- $out .= '' . "\n";
-
- return $out;
+ return $out . ('' . "\n");
}
}
@@ -741,7 +745,7 @@
$value = $request->getPost($field) ?? $default;
}
- return ($html_escape) ? esc($value, 'html') : $value;
+ return ($html_escape) ? esc($value) : $value;
}
}
@@ -839,7 +843,7 @@
}
// Unchecked checkbox and radio inputs are not even submitted by browsers ...
- if (! empty($request->getPost()) || ! empty(old($field)))
+ if (intval($input) === 0 || ! empty($request->getPost()) || ! empty(old($field)))
{
return ($input === $value) ? ' checked="checked"' : '';
}
@@ -891,7 +895,7 @@
// Unchecked checkbox and radio inputs are not even submitted by browsers ...
$result = '';
- if (! empty($input = $request->getPost($field)) || ! empty($input = old($field)))
+ if (intval($input) === 0 || ! empty($input = $request->getPost($field)) || ! empty($input = old($field)))
{
$result = ($input === $value) ? ' checked="checked"' : '';
}
@@ -944,7 +948,7 @@
{
if ($key === 'value')
{
- $val = esc($val, 'html');
+ $val = esc($val);
}
elseif ($key === 'name' && ! strlen($default['name']))
{
diff --git a/system/Helpers/html_helper.php b/system/Helpers/html_helper.php
index 3084771..373cec3 100755
--- a/system/Helpers/html_helper.php
+++ b/system/Helpers/html_helper.php
@@ -382,9 +382,7 @@
. "\n";
}
- $video .= "\n";
-
- return $video;
+ return $video . "\n";
}
}
@@ -447,9 +445,7 @@
$audio .= "\n" . _space_indent() . $unsupportedMessage . "\n";
}
- $audio .= "\n";
-
- return $audio;
+ return $audio . "\n";
}
}
@@ -501,9 +497,7 @@
$media .= _space_indent() . $unsupportedMessage . "\n";
}
- $media .= '' . $name . ">\n";
-
- return $media;
+ return $media . ('' . $name . ">\n");
}
}
@@ -545,9 +539,7 @@
$source .= ' ' . $attributes;
}
- $source .= ' />';
-
- return $source;
+ return $source . ' />';
}
}
@@ -623,9 +615,7 @@
$object .= _space_indent() . $param . "\n";
}
- $object .= "\n";
-
- return $object;
+ return $object . "\n";
}
}
diff --git a/system/Helpers/inflector_helper.php b/system/Helpers/inflector_helper.php
index cca140d..bf869df 100755
--- a/system/Helpers/inflector_helper.php
+++ b/system/Helpers/inflector_helper.php
@@ -180,10 +180,9 @@
*/
function counted(int $count, string $string): string
{
- $result = "{$count} ";
- $result .= $count === 1 ? singular($string) : plural($string);
+ $result = "{$count} ";
- return $result;
+ return $result . ($count === 1 ? singular($string) : plural($string));
}
}
@@ -263,12 +262,11 @@
function humanize(string $string, string $separator = '_'): string
{
$replacement = trim($string);
- $upperCased = ucwords
+
+ return ucwords
(
preg_replace('/[' . $separator . ']+/', ' ', $replacement)
);
-
- return $upperCased;
}
}
diff --git a/system/Helpers/number_helper.php b/system/Helpers/number_helper.php
index d1baf76..f535198 100644
--- a/system/Helpers/number_helper.php
+++ b/system/Helpers/number_helper.php
@@ -179,17 +179,19 @@
if (! function_exists('number_to_currency'))
{
/**
- * @param float $num
- * @param string $currency
- * @param string $locale
+ * @param float $num
+ * @param string $currency
+ * @param string $locale
+ * @param integer $fraction
*
* @return string
*/
- function number_to_currency(float $num, string $currency, string $locale = null): string
+ function number_to_currency(float $num, string $currency, string $locale = null, int $fraction = null): string
{
return format_number($num, 1, $locale, [
'type' => NumberFormatter::CURRENCY,
'currency' => $currency,
+ 'fraction' => $fraction,
]);
}
}
@@ -217,19 +219,20 @@
// Type can be any of the NumberFormatter options, but provide a default.
$type = (int) ($options['type'] ?? NumberFormatter::DECIMAL);
- // In order to specify a precision, we'll have to modify
- // the pattern used by NumberFormatter.
- $pattern = '#,##0.' . str_repeat('#', $precision);
-
$formatter = new NumberFormatter($locale, $type);
// Try to format it per the locale
if ($type === NumberFormatter::CURRENCY)
{
+ $formatter->setAttribute(NumberFormatter::FRACTION_DIGITS, $options['fraction']);
$output = $formatter->formatCurrency($num, $options['currency']);
}
else
{
+ // In order to specify a precision, we'll have to modify
+ // the pattern used by NumberFormatter.
+ $pattern = '#,##0.' . str_repeat('#', $precision);
+
$formatter->setPattern($pattern);
$output = $formatter->format($num);
}
diff --git a/system/Helpers/text_helper.php b/system/Helpers/text_helper.php
index e4c5e2c..b028897 100755
--- a/system/Helpers/text_helper.php
+++ b/system/Helpers/text_helper.php
@@ -854,7 +854,7 @@
$post = ' ';
$count = 0;
- foreach (array_reverse($pre) as $pr => $e)
+ foreach (array_reverse($pre) as $e)
{
if ((strlen($e) + $count + 1) < $radius)
{
@@ -865,7 +865,7 @@
$count = 0;
- foreach ($pos as $po => $s)
+ foreach ($pos as $s)
{
if ((strlen($s) + $count + 1) < $radius)
{
diff --git a/system/Helpers/url_helper.php b/system/Helpers/url_helper.php
index 2959333..ece4e38 100644
--- a/system/Helpers/url_helper.php
+++ b/system/Helpers/url_helper.php
@@ -475,13 +475,11 @@
$output .= 'l[' . $i . "] = '" . $x[$i] . "';";
}
- $output .= 'for (var i = l.length-1; i >= 0; i=i-1) {'
+ return $output . ('for (var i = l.length-1; i >= 0; i=i-1) {'
. "if (l[i].substring(0, 1) === '|') document.write(\"\"+unescape(l[i].substring(1))+\";\");"
. 'else document.write(unescape(l[i]));'
. '}'
- . '';
-
- return $output;
+ . '');
}
}
@@ -603,7 +601,6 @@
$str = strip_tags($str);
foreach ($trans as $key => $val)
{
- // $str = preg_replace('#'.$key.'#i'.( UTF8_ENABLED ? 'u' : ''), $val, $str);
$str = preg_replace('#' . $key . '#iu', $val, $str);
}
diff --git a/system/Honeypot/Honeypot.php b/system/Honeypot/Honeypot.php
index 406e43c..a8d908a 100644
--- a/system/Honeypot/Honeypot.php
+++ b/system/Honeypot/Honeypot.php
@@ -39,9 +39,9 @@
namespace CodeIgniter\Honeypot;
use CodeIgniter\Config\BaseConfig;
+use CodeIgniter\Honeypot\Exceptions\HoneypotException;
use CodeIgniter\HTTP\RequestInterface;
use CodeIgniter\HTTP\ResponseInterface;
-use CodeIgniter\Honeypot\Exceptions\HoneypotException;
/**
* class Honeypot
diff --git a/system/I18n/Time.php b/system/I18n/Time.php
index a11d7e1..8645d35 100644
--- a/system/I18n/Time.php
+++ b/system/I18n/Time.php
@@ -40,12 +40,12 @@
namespace CodeIgniter\I18n;
use CodeIgniter\I18n\Exceptions\I18nException;
-use IntlCalendar;
-use Locale;
-use DateTime;
use DateInterval;
+use DateTime;
use DateTimeZone;
+use IntlCalendar;
use IntlDateFormatter;
+use Locale;
/**
* Class Time
@@ -423,7 +423,7 @@
*/
public function getYear(): string
{
- return $this->toLocalizedString('Y');
+ return $this->toLocalizedString('y');
}
//--------------------------------------------------------------------
diff --git a/system/Images/Handlers/BaseHandler.php b/system/Images/Handlers/BaseHandler.php
index 990ad23..5ec903b 100644
--- a/system/Images/Handlers/BaseHandler.php
+++ b/system/Images/Handlers/BaseHandler.php
@@ -60,12 +60,12 @@
*
* @var \CodeIgniter\Images\Image
*/
- protected $image = null;
+ protected $image;
/**
* Whether the image file has been confirmed.
*
- * @var bool
+ * @var boolean
*/
protected $verified = false;
@@ -531,28 +531,21 @@
{
case 2:
return $this->flip('horizontal');
- break;
case 3:
return $this->rotate(180);
- break;
case 4:
return $this->rotate(180)
->flip('horizontal');
- break;
case 5:
return $this->rotate(270)
->flip('horizontal');
- break;
case 6:
return $this->rotate(270);
- break;
case 7:
return $this->rotate(90)
->flip('horizontal');
- break;
case 8:
return $this->rotate(90);
- break;
default:
return $this;
}
diff --git a/system/Images/Handlers/GDHandler.php b/system/Images/Handlers/GDHandler.php
index 0ef75aa..d57034c 100644
--- a/system/Images/Handlers/GDHandler.php
+++ b/system/Images/Handlers/GDHandler.php
@@ -357,7 +357,6 @@
break;
default:
throw ImageException::forInvalidImageCreate();
- break;
}
imagedestroy($this->resource);
@@ -519,7 +518,7 @@
$this->textOverlay($text, $options, true);
}
- $this->textOverlay($text, $options, false);
+ $this->textOverlay($text, $options);
}
//--------------------------------------------------------------------
diff --git a/system/Language/Language.php b/system/Language/Language.php
index 65cf58d..9235610 100644
--- a/system/Language/Language.php
+++ b/system/Language/Language.php
@@ -149,7 +149,19 @@
$parsedLine,
] = $this->parseLine($line, $this->locale);
- $output = $this->language[$this->locale][$file][$parsedLine] ?? null;
+ foreach (explode('.', $parsedLine) as $row)
+ {
+ if (! isset($current))
+ {
+ $current = $this->language[$this->locale][$file] ?? null;
+ }
+
+ $output = $current[$row] ?? null;
+ if (is_array($output))
+ {
+ $current = $output;
+ }
+ }
if ($output === null && strpos($this->locale, '-'))
{
diff --git a/system/Language/en/Migrations.php b/system/Language/en/Migrations.php
index efbac6d..d148927 100644
--- a/system/Language/en/Migrations.php
+++ b/system/Language/en/Migrations.php
@@ -35,8 +35,10 @@
'migCreate' => "\tCreates a new migration named [name]",
'nameMigration' => 'Name the migration file',
'badCreateName' => 'You must provide a migration file name.',
- 'writeError' => 'Error trying to create file.',
+ 'writeError' => 'Error trying to create {0} file, check if the directory is writable.',
'migNumberError' => 'Migration number must be three digits, and there must not be any gaps in the sequence.',
+ 'rollBackConfirm' => 'Are you sure you want to rollback?',
+ 'refreshConfirm' => 'Are you sure you want to refresh?',
'latest' => 'Running all new migrations...',
'generalFault' => 'Migration failed!',
diff --git a/system/Language/en/Validation.php b/system/Language/en/Validation.php
index 3b15241..73a38c2 100644
--- a/system/Language/en/Validation.php
+++ b/system/Language/en/Validation.php
@@ -53,6 +53,7 @@
'required' => 'The {field} field is required.',
'required_with' => 'The {field} field is required when {param} is present.',
'required_without' => 'The {field} field is required when {param} is not present.',
+ 'string' => 'The {field} field must be a valid string.',
'timezone' => 'The {field} field must be a valid timezone.',
'valid_base64' => 'The {field} field must be a valid base64 string.',
'valid_email' => 'The {field} field must contain a valid email address.',
diff --git a/system/Log/Handlers/ChromeLoggerHandler.php b/system/Log/Handlers/ChromeLoggerHandler.php
index bdcd318..9a293e1 100644
--- a/system/Log/Handlers/ChromeLoggerHandler.php
+++ b/system/Log/Handlers/ChromeLoggerHandler.php
@@ -39,7 +39,6 @@
namespace CodeIgniter\Log\Handlers;
-use CodeIgniter\Events\Events;
use CodeIgniter\HTTP\ResponseInterface;
use Config\Services;
@@ -123,7 +122,6 @@
$this->json['request_uri'] = (string) $request->uri;
- Events::on('post_controller', [$this, 'sendLogs'], EVENT_PRIORITY_HIGH);
}
//--------------------------------------------------------------------
@@ -163,11 +161,13 @@
}
$this->json['rows'][] = [
- $message,
+ [$message],
$backtraceMessage,
$type,
];
+ $this->sendLogs();
+
return true;
}
diff --git a/system/Log/Handlers/FileHandler.php b/system/Log/Handlers/FileHandler.php
index 78a3218..41df096 100644
--- a/system/Log/Handlers/FileHandler.php
+++ b/system/Log/Handlers/FileHandler.php
@@ -77,7 +77,7 @@
{
parent::__construct($config);
- $this->path = $config['path'] ?? WRITEPATH . 'logs/';
+ $this->path = empty($config['path']) ? WRITEPATH . 'logs/' : $config['path'];
$this->fileExtension = empty($config['fileExtension']) ? 'log' : $config['fileExtension'];
$this->fileExtension = ltrim($this->fileExtension, '.');
diff --git a/system/Log/Logger.php b/system/Log/Logger.php
index 5e95ffd..45f2eca 100644
--- a/system/Log/Logger.php
+++ b/system/Log/Logger.php
@@ -39,8 +39,8 @@
namespace CodeIgniter\Log;
-use Psr\Log\LoggerInterface;
use CodeIgniter\Log\Exceptions\LogException;
+use Psr\Log\LoggerInterface;
/**
* The CodeIgntier Logger
@@ -60,13 +60,6 @@
{
/**
- * Path to save log files to.
- *
- * @var string
- */
- protected $logPath;
-
- /**
* Used by the logThreshold Config setting to define
* which errors to show.
*
@@ -474,37 +467,51 @@
return strtr($message, $replace);
}
- //--------------------------------------------------------------------
-
/**
- * Determines the current file/line that the log method was called from.
- * by analyzing the backtrace.
+ * Determines the file and line that the logging call
+ * was made from by analyzing the backtrace.
+ * Find the earliest stack frame that is part of our logging system.
*
* @return array
*/
public function determineFile(): array
{
- // Determine the file and line by finding the first
- // backtrace that is not part of our logging system.
- $trace = debug_backtrace();
- $file = null;
- $line = null;
+ $logFunctions = [
+ 'log_message',
+ 'log',
+ 'error',
+ 'debug',
+ 'info',
+ 'warning',
+ 'critical',
+ 'emergency',
+ 'alert',
+ 'notice',
+ ];
- foreach ($trace as $row)
+ // Generate Backtrace info
+ $trace = \debug_backtrace(false);
+
+ // So we search from the bottom (earliest) of the stack frames
+ $stackFrames = \array_reverse($trace);
+
+ // Find the first reference to a Logger class method
+ foreach ($stackFrames as $frame)
{
- if (in_array($row['function'], ['interpolate', 'determineFile', 'log', 'log_message']))
+ if (\in_array($frame['function'], $logFunctions))
{
- continue;
+ $file = isset($frame['file']) ? $this->cleanFileNames($frame['file']) : 'unknown';
+ $line = $frame['line'] ?? 'unknown';
+ return [
+ $file,
+ $line,
+ ];
}
-
- $file = $row['file'] ?? isset($row['object']) ? get_class($row['object']) : 'unknown';
- $line = $row['line'] ?? $row['function'] ?? 'unknown';
- break;
}
return [
- $file,
- $line,
+ 'unknown',
+ 'unknown',
];
}
@@ -526,9 +533,8 @@
{
$file = str_replace(APPPATH, 'APPPATH/', $file);
$file = str_replace(SYSTEMPATH, 'SYSTEMPATH/', $file);
- $file = str_replace(FCPATH, 'FCPATH/', $file);
- return $file;
+ return str_replace(FCPATH, 'FCPATH/', $file);
}
//--------------------------------------------------------------------
diff --git a/system/Model.php b/system/Model.php
index 8d02e78..4814217 100644
--- a/system/Model.php
+++ b/system/Model.php
@@ -40,16 +40,16 @@
namespace CodeIgniter;
use Closure;
-use CodeIgniter\Exceptions\ModelException;
-use Config\Database;
-use CodeIgniter\I18n\Time;
-use CodeIgniter\Pager\Pager;
use CodeIgniter\Database\BaseBuilder;
use CodeIgniter\Database\BaseConnection;
use CodeIgniter\Database\ConnectionInterface;
-use CodeIgniter\Validation\ValidationInterface;
-use CodeIgniter\Database\Exceptions\DataException;
use CodeIgniter\Database\Exceptions\DatabaseException;
+use CodeIgniter\Database\Exceptions\DataException;
+use CodeIgniter\Exceptions\ModelException;
+use CodeIgniter\I18n\Time;
+use CodeIgniter\Pager\Pager;
+use CodeIgniter\Validation\ValidationInterface;
+use Config\Database;
use ReflectionClass;
use ReflectionProperty;
use stdClass;
@@ -430,7 +430,7 @@
* @param integer $limit
* @param integer $offset
*
- * @return array|null
+ * @return array
*/
public function findAll(int $limit = 0, int $offset = 0)
{
@@ -470,22 +470,30 @@
{
$builder->where($this->table . '.' . $this->deletedField, null);
}
+ else
+ {
+ if ($this->useSoftDeletes === true && empty($builder->QBGroupBy) && ! empty($this->primaryKey))
+ {
+ $builder->groupBy($this->table . '.' . $this->primaryKey);
+ }
+ }
// Some databases, like PostgreSQL, need order
// information to consistently return correct results.
- if (empty($builder->QBOrderBy) && ! empty($this->primaryKey))
+ if (! empty($builder->QBGroupBy) && empty($builder->QBOrderBy) && ! empty($this->primaryKey))
{
$builder->orderBy($this->table . '.' . $this->primaryKey, 'asc');
}
$row = $builder->limit(1, 0)
- ->get();
+ ->get();
$row = $row->getFirstRow($this->tempReturnType);
$eventData = $this->trigger('afterFind', ['data' => $row]);
- $this->tempReturnType = $this->returnType;
+ $this->tempReturnType = $this->returnType;
+ $this->tempUseSoftDeletes = $this->useSoftDeletes;
return $eventData['data'];
}
@@ -493,14 +501,13 @@
//--------------------------------------------------------------------
/**
-
* Captures the builder's set() method so that we can validate the
* data here. This allows it to be used with any of the other
* builder methods and still get validated data, like replace.
*
- * @param mixed $key Field name, or an array of field/value pairs
- * @param string $value Field value, if $key is a single field
- * @param boolean $escape Whether to escape values and identifiers
+ * @param mixed $key Field name, or an array of field/value pairs
+ * @param string $value Field value, if $key is a single field
+ * @param boolean $escape Whether to escape values and identifiers
*
* @return $this
*/
@@ -691,7 +698,7 @@
// Validate data before saving.
if ($this->skipValidation === false)
{
- if ($this->cleanRules(false)->validate($data) === false)
+ if ($this->cleanRules()->validate($data) === false)
{
return false;
}
@@ -759,7 +766,7 @@
{
foreach ($set as $row)
{
- if ($this->cleanRules(false)->validate($row) === false)
+ if ($this->cleanRules()->validate($row) === false)
{
return false;
}
@@ -818,6 +825,12 @@
$data = (array) $data;
}
+ // If it's still empty here, means $data is no change or is empty object
+ if (empty($data))
+ {
+ throw DataException::forEmptyDataset('update');
+ }
+
// Validate data before saving.
if ($this->skipValidation === false)
{
@@ -892,15 +905,15 @@
* Deletes a single record from $this->table where $id matches
* the table's primaryKey
*
- * @param integer|array|null $id The rows primary key(s)
- * @param boolean $purge Allows overriding the soft deletes setting.
+ * @param integer|string|array|null $id The rows primary key(s)
+ * @param boolean $purge Allows overriding the soft deletes setting.
*
* @return mixed
* @throws \CodeIgniter\Database\Exceptions\DatabaseException
*/
public function delete($id = null, bool $purge = false)
{
- if (! empty($id) && is_numeric($id))
+ if (! empty($id) && (is_numeric($id) || is_string($id)))
{
$id = [$id];
}
@@ -921,7 +934,9 @@
{
throw new DatabaseException('Deletes are not allowed unless they contain a "where" or "like" clause.');
}
+ // @codeCoverageIgnoreStart
return false;
+ // @codeCoverageIgnoreEnd
}
$set[$this->deletedField] = $this->setDate();
@@ -1118,10 +1133,11 @@
* @param string $group Will be used by the pagination library
* to identify a unique pagination set.
* @param integer $page Optional page number (useful when the page number is provided in different way)
+ * @param integer $segment Optional URI segment number (if page number is provided by URI segment)
*
* @return array|null
*/
- public function paginate(int $perPage = 20, string $group = 'default', int $page = 0)
+ public function paginate(int $perPage = null, string $group = 'default', int $page = 0, int $segment = 0)
{
$pager = \Config\Services::pager(null, null, false);
$page = $page >= 1 ? $page : $pager->getCurrentPage($group);
@@ -1130,9 +1146,9 @@
// Store it in the Pager library so it can be
// paginated in the views.
- $this->pager = $pager->store($group, $page, $perPage, $total);
-
- $offset = ($page - 1) * $perPage;
+ $this->pager = $pager->store($group, $page, $perPage, $total, $segment);
+ $perPage = $this->pager->getPerPage($group);
+ $offset = ($page - 1) * $perPage;
return $this->findAll($perPage, $offset);
}
@@ -1258,13 +1274,10 @@
{
case 'int':
return $currentDate;
- break;
case 'datetime':
return date('Y-m-d H:i:s', $currentDate);
- break;
case 'date':
return date('Y-m-d', $currentDate);
- break;
default:
throw ModelException::forNoDateFormat(get_class($this));
}
@@ -1426,10 +1439,6 @@
return true;
}
- // Replace any placeholders (i.e. {id}) in the rules with
- // the value found in $data, if exists.
- $rules = $this->fillPlaceholders($rules, $data);
-
$this->validation->setRules($rules, $this->validationMessages);
$valid = $this->validation->run($data, null, $this->DBGroup);
@@ -1482,6 +1491,10 @@
*
* 'required|is_unique[users,email,id,13]'
*
+ * @codeCoverageIgnore
+ *
+ * @deprecated use fillPlaceholders($rules, $data) from Validation instead
+ *
* @param array $rules
* @param array $data
*
@@ -1578,8 +1591,9 @@
{
$this->builder()->where($this->table . '.' . $this->deletedField, null);
}
+ $this->tempUseSoftDeletes = $this->useSoftDeletes;
- return $this->builder()->countAllResults($reset, $test);
+ return $this->builder()->testMode($test)->countAllResults($reset);
}
/**
@@ -1707,6 +1721,11 @@
// and break intermingling of model and builder methods.
if ($name !== 'builder' && empty($result))
{
+ if (! method_exists($this->builder(), $name))
+ {
+ $className = get_class($this);
+ throw new \BadMethodCallException("Call to undefined method $className::$name");
+ }
return $result;
}
if ($name !== 'builder' && ! $result instanceof BaseBuilder)
diff --git a/system/Pager/Pager.php b/system/Pager/Pager.php
index 8aecd5f..12a3a3e 100644
--- a/system/Pager/Pager.php
+++ b/system/Pager/Pager.php
@@ -40,7 +40,6 @@
namespace CodeIgniter\Pager;
use CodeIgniter\Pager\Exceptions\PagerException;
-use Config\Services;
use CodeIgniter\View\RendererInterface;
/**
@@ -145,22 +144,22 @@
* Allows for a simple, manual, form of pagination where all of the data
* is provided by the user. The URL is the current URI.
*
- * @param integer $page
- * @param integer $perPage
- * @param integer $total
- * @param string $template The output template alias to render.
- * @param integer $segment (if page number is provided by URI segment)
+ * @param integer $page
+ * @param integer $perPage
+ * @param integer $total
+ * @param string $template The output template alias to render.
+ * @param integer $segment (if page number is provided by URI segment)
*
- * @param string|null $group optional group (i.e. if we'd like to define custom path)
+ * @param string $group optional group (i.e. if we'd like to define custom path)
* @return string
*/
- public function makeLinks(int $page, int $perPage, int $total, string $template = 'default_full', int $segment = 0, ?string $group = null): string
+ public function makeLinks(int $page, int $perPage = null, int $total, string $template = 'default_full', int $segment = 0, ?string $group = 'default'): string
{
- $name = time();
+ $group = $group === '' ? 'default' : $group;
- $this->store($group ?? $name, $page, $perPage, $total, $segment);
+ $this->store($group, $page, $perPage ?? $this->config->perPage, $total, $segment);
- return $this->displayLinks($group ?? $name, $template);
+ return $this->displayLinks($group, $template);
}
//--------------------------------------------------------------------
@@ -201,16 +200,19 @@
*
* @return $this
*/
- public function store(string $group, int $page, int $perPage, int $total, int $segment = 0)
+ public function store(string $group, int $page, int $perPage = null, int $total, int $segment = 0)
{
$this->segment[$group] = $segment;
- $this->ensureGroup($group);
+ $this->ensureGroup($group, $perPage);
+ $perPage = $perPage ?? $this->config->perPage;
+ $pageCount = (int)ceil($total / $perPage);
+ $page = $page > $pageCount ? $pageCount : $page;
$this->groups[$group]['currentPage'] = $page;
$this->groups[$group]['perPage'] = $perPage;
$this->groups[$group]['total'] = $total;
- $this->groups[$group]['pageCount'] = (int)ceil($total / $perPage);
+ $this->groups[$group]['pageCount'] = $pageCount;
return $this;
}
@@ -493,9 +495,10 @@
/**
* Ensures that an array exists for the group specified.
*
- * @param string $group
+ * @param string $group
+ * @param integer $perPage
*/
- protected function ensureGroup(string $group)
+ protected function ensureGroup(string $group, int $perPage = null)
{
if (array_key_exists($group, $this->groups))
{
@@ -506,7 +509,7 @@
'uri' => clone current_url(true),
'hasMore' => false,
'total' => null,
- 'perPage' => $this->config->perPage,
+ 'perPage' => $perPage ?? $this->config->perPage,
'pageCount' => 1,
'pageSelector' => $group === 'default' ? 'page' : 'page_' . $group,
];
diff --git a/system/Pager/PagerRenderer.php b/system/Pager/PagerRenderer.php
index 1712ddf..ed95c1b 100644
--- a/system/Pager/PagerRenderer.php
+++ b/system/Pager/PagerRenderer.php
@@ -343,4 +343,78 @@
}
//--------------------------------------------------------------------
+
+ /**
+ * Checks to see if there is a "previous" page before our "first" page.
+ *
+ * @return boolean
+ */
+ public function hasPreviousPage(): bool
+ {
+ return $this->current > 1;
+ }
+
+ //--------------------------------------------------------------------
+
+ /**
+ * Returns a URL to the "previous" page.
+ *
+ * You MUST call hasPreviousPage() first, or this value may be invalid.
+ *
+ * @return string|null
+ */
+ public function getPreviousPage()
+ {
+ if (!$this->hasPreviousPage()) {
+ return null;
+ }
+
+ $uri = clone $this->uri;
+
+ if ($this->segment === 0) {
+ $uri->addQuery($this->pageSelector, $this->current - 1);
+ } else {
+ $uri->setSegment($this->segment, $this->current - 1);
+ }
+
+ return (string) $uri;
+ }
+
+ //--------------------------------------------------------------------
+
+ /**
+ * Checks to see if there is a "next" page after our "last" page.
+ *
+ * @return boolean
+ */
+ public function hasNextPage(): bool
+ {
+ return $this->current < $this->last;
+ }
+
+ //--------------------------------------------------------------------
+
+ /**
+ * Returns a URL to the "next" page.
+ *
+ * You MUST call hasNextPage() first, or this value may be invalid.
+ *
+ * @return string|null
+ */
+ public function getNextPage()
+ {
+ if (!$this->hasNextPage()) {
+ return null;
+ }
+
+ $uri = clone $this->uri;
+
+ if ($this->segment === 0) {
+ $uri->addQuery($this->pageSelector, $this->current + 1);
+ } else {
+ $uri->setSegment($this->segment, $this->current + 1);
+ }
+
+ return (string) $uri;
+ }
}
diff --git a/system/Pager/Views/default_full.php b/system/Pager/Views/default_full.php
index cc1b8e5..ef446e9 100644
--- a/system/Pager/Views/default_full.php
+++ b/system/Pager/Views/default_full.php
@@ -1,4 +1,5 @@
- «
+ = lang('Pager.previous') ?>
@@ -32,7 +33,7 @@
hasNext()) : ?>
- »
+ = lang('Pager.next') ?>
diff --git a/system/RESTful/ResourceController.php b/system/RESTful/ResourceController.php
index 4aaec7c..a3b7586 100644
--- a/system/RESTful/ResourceController.php
+++ b/system/RESTful/ResourceController.php
@@ -58,19 +58,13 @@
*
* @var string Name of the model class managing this resource's data
*/
- protected $modelName = null;
+ protected $modelName;
/**
*
* @var \CodeIgniter\Model the model holding this resource's data
*/
- protected $model = null;
-
- /**
- *
- * @var string the representation format to return resource data in (json/xml)
- */
- protected $format = 'json';
+ protected $model;
//--------------------------------------------------------------------
diff --git a/system/RESTful/ResourcePresenter.php b/system/RESTful/ResourcePresenter.php
index 2d970e3..d594c14 100644
--- a/system/RESTful/ResourcePresenter.php
+++ b/system/RESTful/ResourcePresenter.php
@@ -55,13 +55,13 @@
*
* @var string Name of the model class managing this resource's data
*/
- protected $modelName = null;
+ protected $modelName;
/**
*
* @var \CodeIgniter\Model the model holding this resource's data
*/
- protected $model = null;
+ protected $model;
//--------------------------------------------------------------------
@@ -99,7 +99,6 @@
/**
* Present a view to present a new single resource object
*
- * @param type $id
* @return string
*/
public function new()
diff --git a/system/Router/RouteCollection.php b/system/Router/RouteCollection.php
index 53a27e7..cdb1007 100644
--- a/system/Router/RouteCollection.php
+++ b/system/Router/RouteCollection.php
@@ -38,10 +38,10 @@
namespace CodeIgniter\Router;
-use CodeIgniter\HTTP\Request;
-use Config\Services;
use CodeIgniter\Autoloader\FileLocator;
+use CodeIgniter\HTTP\Request;
use CodeIgniter\Router\Exceptions\RouterException;
+use Config\Services;
/**
* Class RouteCollection
@@ -186,14 +186,14 @@
*
* @var string
*/
- protected $group = null;
+ protected $group;
/**
* The current subdomain.
*
* @var string
*/
- protected $currentSubdomain = null;
+ protected $currentSubdomain;
/**
* Stores copy of current options being
@@ -201,7 +201,7 @@
*
* @var null
*/
- protected $currentOptions = null;
+ protected $currentOptions;
/**
* A little performance booster.
@@ -1214,17 +1214,18 @@
public function reverseRoute(string $search, ...$params)
{
// Named routes get higher priority.
- foreach ($this->routes as $verb => $collection)
+ foreach ($this->routes as $collection)
{
if (array_key_exists($search, $collection))
{
- return $this->fillRouteParams(key($collection[$search]['route']), $params);
+ $route = $this->fillRouteParams(key($collection[$search]['route']), $params);
+ return $this->localizeRoute($route);
}
}
// If it's not a named route, then loop over
// all routes to find a match.
- foreach ($this->routes as $verb => $collection)
+ foreach ($this->routes as $collection)
{
foreach ($collection as $route)
{
@@ -1256,7 +1257,8 @@
continue;
}
- return $this->fillRouteParams($from, $params);
+ $route = $this->fillRouteParams($from, $params);
+ return $this->localizeRoute($route);
}
}
@@ -1267,6 +1269,20 @@
//--------------------------------------------------------------------
/**
+ * Replaces the {locale} tag with the current application locale
+ *
+ * @param string $route
+ *
+ * @return string
+ */
+ protected function localizeRoute(string $route) :string
+ {
+ return strtr($route, ['{locale}' => Services::language()->getLocale()]);
+ }
+
+ //--------------------------------------------------------------------
+
+ /**
* Checks a route (using the "from") to see if it's filtered or not.
*
* @param string $search
diff --git a/system/Router/Router.php b/system/Router/Router.php
index 14f24c6..3c6e6e0 100644
--- a/system/Router/Router.php
+++ b/system/Router/Router.php
@@ -39,8 +39,8 @@
namespace CodeIgniter\Router;
-use CodeIgniter\HTTP\Request;
use CodeIgniter\Exceptions\PageNotFoundException;
+use CodeIgniter\HTTP\Request;
use CodeIgniter\Router\Exceptions\RedirectException;
use CodeIgniter\Router\Exceptions\RouterException;
@@ -107,21 +107,21 @@
*
* @var array|null
*/
- protected $matchedRoute = null;
+ protected $matchedRoute;
/**
* The options set for the matched route.
*
* @var array|null
*/
- protected $matchedRouteOptions = null;
+ protected $matchedRouteOptions;
/**
* The locale that was detected in a route.
*
* @var string
*/
- protected $detectedLocale = null;
+ protected $detectedLocale;
/**
* The filter info from Route Collection
@@ -164,7 +164,7 @@
// If we cannot find a URI to match against, then
// everything runs off of it's default settings.
- if (empty($uri))
+ if ($uri === null || $uri === '')
{
return strpos($this->controller, '\\') === false
? $this->collection->getDefaultNamespace() . $this->controller
@@ -542,6 +542,32 @@
$this->params = $segments;
}
+ if ($this->collection->getHTTPVerb() !== 'cli')
+ {
+ $controller = '\\' . $this->collection->getDefaultNamespace();
+ $controller .= $this->directory ? str_replace('/', '\\', $this->directory) : '';
+ $controller .= $this->controllerName();
+ $controller = strtolower($controller);
+ $methodName = strtolower($this->methodName());
+
+ foreach ($this->collection->getRoutes('cli') as $route)
+ {
+ if (is_string($route))
+ {
+ $route = strtolower($route);
+ if (strpos($route, $controller . '::' . $methodName) === 0)
+ {
+ throw new PageNotFoundException();
+ }
+
+ if ($route === $controller)
+ {
+ throw new PageNotFoundException();
+ }
+ }
+ }
+ }
+
// Load the file so that it's available for CodeIgniter.
$file = APPPATH . 'Controllers/' . $this->directory . $this->controllerName() . '.php';
if (is_file($file))
@@ -553,7 +579,7 @@
// We have to check for a length over 1, since by default it will be '\'
if (strpos($this->controller, '\\') === false && strlen($this->collection->getDefaultNamespace()) > 1)
{
- $this->controller = str_replace('/', '\\', $this->collection->getDefaultNamespace() . $this->directory . $this->controllerName());
+ $this->controller = '\\' . ltrim(str_replace('/', '\\', $this->collection->getDefaultNamespace() . $this->directory . $this->controllerName()), '\\');
}
}
@@ -603,10 +629,11 @@
* @param string|null $dir
* @param boolean|false $append
*/
- protected function setDirectory(string $dir = null, bool $append = false)
+ public function setDirectory(string $dir = null, bool $append = false)
{
if (empty($dir))
{
+ $this->directory = null;
return;
}
diff --git a/system/Session/Handlers/ArrayHandler.php b/system/Session/Handlers/ArrayHandler.php
index 90eb920..15e6324 100644
--- a/system/Session/Handlers/ArrayHandler.php
+++ b/system/Session/Handlers/ArrayHandler.php
@@ -39,9 +39,6 @@
namespace CodeIgniter\Session\Handlers;
-use CodeIgniter\Session\Exceptions\SessionException;
-use CodeIgniter\Config\BaseConfig;
-use CodeIgniter\Database\BaseConnection;
use Config\Database;
/**
diff --git a/system/Session/Handlers/DatabaseHandler.php b/system/Session/Handlers/DatabaseHandler.php
index 3290a3a..71ecbde 100644
--- a/system/Session/Handlers/DatabaseHandler.php
+++ b/system/Session/Handlers/DatabaseHandler.php
@@ -39,9 +39,9 @@
namespace CodeIgniter\Session\Handlers;
-use CodeIgniter\Session\Exceptions\SessionException;
use CodeIgniter\Config\BaseConfig;
use CodeIgniter\Database\BaseConnection;
+use CodeIgniter\Session\Exceptions\SessionException;
use Config\Database;
/**
diff --git a/system/Session/Session.php b/system/Session/Session.php
index ff40a47..8e84546 100644
--- a/system/Session/Session.php
+++ b/system/Session/Session.php
@@ -94,7 +94,7 @@
*
* @var string
*/
- protected $sessionSavePath = null;
+ protected $sessionSavePath;
/**
* Whether to match the user's IP address when reading the session data.
@@ -199,9 +199,11 @@
{
if (is_cli() && ENVIRONMENT !== 'testing')
{
+ // @codeCoverageIgnoreStart
$this->logger->debug('Session: Initialization under CLI aborted.');
return;
+ // @codeCoverageIgnoreEnd
}
elseif ((bool) ini_get('session.auto_start'))
{
@@ -497,13 +499,13 @@
*/
public function get(string $key = null)
{
- if (! empty($key) && ! is_null($value = dot_array_search($key, $_SESSION ?? [])))
+ if (! empty($key) && (! is_null($value = isset($_SESSION[$key]) ? $_SESSION[$key] : null) || ! is_null($value = dot_array_search($key, $_SESSION ?? []))))
{
return $value;
}
elseif (empty($_SESSION))
{
- return [];
+ return $key === null ? [] : null;
}
if (! empty($key))
@@ -999,7 +1001,9 @@
return;
}
+ // @codeCoverageIgnoreStart
session_start();
+ // @codeCoverageIgnoreEnd
}
//--------------------------------------------------------------------
diff --git a/system/Test/CIDatabaseTestCase.php b/system/Test/CIDatabaseTestCase.php
index 1ce43a3..b1354ec 100644
--- a/system/Test/CIDatabaseTestCase.php
+++ b/system/Test/CIDatabaseTestCase.php
@@ -38,14 +38,12 @@
namespace CodeIgniter\Test;
-use CodeIgniter\Config\Config;
-use Config\Autoload;
-use Config\Database;
-use Config\Migrations;
-use Config\Services;
use CodeIgniter\Database\BaseConnection;
use CodeIgniter\Database\MigrationRunner;
use CodeIgniter\Exceptions\ConfigException;
+use Config\Database;
+use Config\Migrations;
+use Config\Services;
/**
* CIDatabaseTestCase
@@ -169,29 +167,13 @@
if ($this->refresh === true)
{
- // Delete all of the tables to ensure we're at a clean start.
- $tables = $this->db->listTables();
-
- if (is_array($tables))
- {
- $forge = Database::forge('tests');
-
- foreach ($tables as $table)
- {
- if ($table === $this->db->DBPrefix . 'migrations')
- {
- $this->db->table($table)->truncate();
- continue;
- }
-
- $forge->dropTable($table, true);
- }
- }
-
- // If no namespace was specified then migrate all
+ // If no namespace was specified then rollback/migrate all
if (empty($this->namespace))
{
$this->migrations->setNamespace(null);
+
+ $this->migrations->regress(0, 'tests');
+
$this->migrations->latest('tests');
}
@@ -199,6 +181,13 @@
else
{
$namespaces = is_array($this->namespace) ? $this->namespace : [$this->namespace];
+
+ foreach ($namespaces as $namespace)
+ {
+ $this->migrations->setNamespace($namespace);
+ $this->migrations->regress(0, 'tests');
+ }
+
foreach ($namespaces as $namespace)
{
$this->migrations->setNamespace($namespace);
@@ -228,8 +217,10 @@
* Takes care of any required cleanup after the test, like
* removing any rows inserted via $this->hasInDatabase()
*/
- public function tearDown(): void
+ protected function tearDown(): void
{
+ parent::tearDown();
+
if (! empty($this->insertCache))
{
foreach ($this->insertCache as $row)
diff --git a/system/Test/CIUnitTestCase.php b/system/Test/CIUnitTestCase.php
index 7599d39..6e84295 100644
--- a/system/Test/CIUnitTestCase.php
+++ b/system/Test/CIUnitTestCase.php
@@ -39,10 +39,9 @@
namespace CodeIgniter\Test;
-use Config\Paths;
use CodeIgniter\Events\Events;
+use Config\Paths;
use PHPUnit\Framework\TestCase;
-use CodeIgniter\Test\TestLogger;
/**
* PHPunit test case.
diff --git a/system/Test/ControllerTester.php b/system/Test/ControllerTester.php
index d6dc0b6..89d4431 100644
--- a/system/Test/ControllerTester.php
+++ b/system/Test/ControllerTester.php
@@ -41,9 +41,9 @@
namespace CodeIgniter\Test;
use CodeIgniter\HTTP\IncomingRequest;
-use CodeIgniter\HTTP\UserAgent;
use CodeIgniter\HTTP\Response;
use CodeIgniter\HTTP\URI;
+use CodeIgniter\HTTP\UserAgent;
use Config\App;
use Config\Services;
use InvalidArgumentException;
@@ -251,6 +251,9 @@
{
$this->request = $request;
+ // Make sure it's available for other classes
+ Services::injectMock('request', $request);
+
return $this;
}
diff --git a/system/Test/DOMParser.php b/system/Test/DOMParser.php
index 1872a68..343ef75 100644
--- a/system/Test/DOMParser.php
+++ b/system/Test/DOMParser.php
@@ -298,9 +298,7 @@
$xpath = new \DOMXPath($this->dom);
- $result = $xpath->query($path);
-
- return $result;
+ return $xpath->query($path);
}
/**
diff --git a/system/Test/FeatureTestCase.php b/system/Test/FeatureTestCase.php
index 6308988..cf981df 100644
--- a/system/Test/FeatureTestCase.php
+++ b/system/Test/FeatureTestCase.php
@@ -38,11 +38,11 @@
namespace CodeIgniter\Test;
-use CodeIgniter\HTTP\URI;
-use CodeIgniter\HTTP\Request;
use CodeIgniter\Events\Events;
-use CodeIgniter\HTTP\UserAgent;
use CodeIgniter\HTTP\IncomingRequest;
+use CodeIgniter\HTTP\Request;
+use CodeIgniter\HTTP\URI;
+use CodeIgniter\HTTP\UserAgent;
use Config\App;
use Config\Services;
@@ -151,6 +151,15 @@
*/
public function call(string $method, string $path, array $params = null)
{
+ // Clean up any open output buffers
+ // not relevant to unit testing
+ // @codeCoverageIgnoreStart
+ if (\ob_get_level() > 0 && $this->clean)
+ {
+ \ob_end_clean();
+ }
+ // @codeCoverageIgnoreEnd
+
// Simulate having a blank session
$_SESSION = [];
$_SERVER['REQUEST_METHOD'] = $method;
@@ -178,19 +187,10 @@
$response->setBody($output);
}
- // Clean up any open output buffers
- // not relevant to unit testing
- // @codeCoverageIgnoreStart
+ // Reset directory if it has been set
+ Services::router()->setDirectory(null);
- if (ob_get_level() > 0 && $this->clean)
- {
- ob_end_clean();
- }
- // @codeCoverageIgnoreEnd
-
- $featureResponse = new FeatureResponse($response);
-
- return $featureResponse;
+ return new FeatureResponse($response);
}
/**
diff --git a/system/Test/Mock/MockChromeLogger.php b/system/Test/Mock/MockChromeLogger.php
deleted file mode 100644
index 3bb64b1..0000000
--- a/system/Test/Mock/MockChromeLogger.php
+++ /dev/null
@@ -1,25 +0,0 @@
-json['rows'][0];
- }
-
-}
diff --git a/system/Test/Mock/MockConnection.php b/system/Test/Mock/MockConnection.php
index e909ce6..ba112fa 100644
--- a/system/Test/Mock/MockConnection.php
+++ b/system/Test/Mock/MockConnection.php
@@ -255,7 +255,6 @@
*/
protected function _close()
{
- return;
}
//--------------------------------------------------------------------
diff --git a/system/Test/Mock/MockEmail.php b/system/Test/Mock/MockEmail.php
new file mode 100644
index 0000000..fdbd14f
--- /dev/null
+++ b/system/Test/Mock/MockEmail.php
@@ -0,0 +1,24 @@
+clear();
+ }
+
+ $this->archive = get_object_vars($this);
+ return true;
+ }
+}
diff --git a/system/Test/Mock/MockLogger.php b/system/Test/Mock/MockLogger.php
index 837c366..239dab5 100644
--- a/system/Test/Mock/MockLogger.php
+++ b/system/Test/Mock/MockLogger.php
@@ -35,16 +35,6 @@
/*
|--------------------------------------------------------------------------
- | Error Logging Directory Path
- |--------------------------------------------------------------------------
- |
- |
- |
- */
- public $path = '';
-
- /*
- |--------------------------------------------------------------------------
| Date Format for Logs
|--------------------------------------------------------------------------
|
@@ -97,6 +87,11 @@
'notice',
'warning',
],
+
+ /*
+ * Logging Directory Path
+ */
+ 'path' => '',
],
];
diff --git a/system/Test/Mock/MockSecurity.php b/system/Test/Mock/MockSecurity.php
index 4bce37c..f9d5c9c 100644
--- a/system/Test/Mock/MockSecurity.php
+++ b/system/Test/Mock/MockSecurity.php
@@ -1,7 +1,7 @@
appDirectory) . DIRECTORY_SEPARATOR);
-defined('WRITEPATH') || define('WRITEPATH', realpath($paths->writableDirectory) . DIRECTORY_SEPARATOR);
-defined('SYSTEMPATH') || define('SYSTEMPATH', realpath($paths->systemDirectory) . DIRECTORY_SEPARATOR);
-defined('ROOTPATH') || define('ROOTPATH', realpath(APPPATH . '../') . DIRECTORY_SEPARATOR);
-defined('CIPATH') || define('CIPATH', realpath(SYSTEMPATH . '../') . DIRECTORY_SEPARATOR);
-defined('FCPATH') || define('FCPATH', realpath(PUBLICPATH) . DIRECTORY_SEPARATOR);
-defined('TESTPATH') || define('TESTPATH', realpath(HOMEPATH . 'tests/') . DIRECTORY_SEPARATOR);
-defined('SUPPORTPATH') || define('SUPPORTPATH', realpath(TESTPATH . '_support/') . DIRECTORY_SEPARATOR);
+defined('APPPATH') || define('APPPATH', realpath($paths->appDirectory) . DIRECTORY_SEPARATOR);
+defined('WRITEPATH') || define('WRITEPATH', realpath($paths->writableDirectory) . DIRECTORY_SEPARATOR);
+defined('SYSTEMPATH') || define('SYSTEMPATH', realpath($paths->systemDirectory) . DIRECTORY_SEPARATOR);
+defined('ROOTPATH') || define('ROOTPATH', realpath(APPPATH . '../') . DIRECTORY_SEPARATOR);
+defined('CIPATH') || define('CIPATH', realpath(SYSTEMPATH . '../') . DIRECTORY_SEPARATOR);
+defined('FCPATH') || define('FCPATH', realpath(PUBLICPATH) . DIRECTORY_SEPARATOR);
+defined('TESTPATH') || define('TESTPATH', realpath(HOMEPATH . 'tests/') . DIRECTORY_SEPARATOR);
+defined('SUPPORTPATH') || define('SUPPORTPATH', realpath(TESTPATH . '_support/') . DIRECTORY_SEPARATOR);
defined('COMPOSER_PATH') || define('COMPOSER_PATH', realpath(HOMEPATH . 'vendor/autoload.php'));
+defined('VENDORPATH') || define('VENDORPATH', realpath(HOMEPATH . 'vendor') . DIRECTORY_SEPARATOR);
// Load Common.php from App then System
if (file_exists(APPPATH . 'Common.php'))
@@ -58,3 +59,6 @@
// Register the loader with the SPL autoloader stack.
$loader->register();
+
+require_once APPPATH . 'Config/Routes.php';
+$routes->getRoutes('*');
diff --git a/system/ThirdParty/Kint/Kint.php b/system/ThirdParty/Kint/Kint.php
new file mode 100644
index 0000000..e0ce963
--- /dev/null
+++ b/system/ThirdParty/Kint/Kint.php
@@ -0,0 +1,756 @@
+ ' ',
+ * app_path() => '',
+ * config_path() => '',
+ * database_path() => '',
+ * public_path() => '',
+ * resource_path() => '',
+ * storage_path() => '',
+ * ];
+ *
+ * Defaults to [$_SERVER['DOCUMENT_ROOT'] => '']
+ */
+ public static $app_root_dirs = array();
+
+ /**
+ * @var int max array/object levels to go deep, if zero no limits are applied
+ */
+ public static $max_depth = 6;
+
+ /**
+ * @var bool expand all trees by default for rich view
+ */
+ public static $expanded = false;
+
+ /**
+ * @var bool enable detection when Kint is command line.
+ *
+ * Formats output with whitespace only; does not HTML-escape it
+ */
+ public static $cli_detection = true;
+
+ /**
+ * @var array Kint aliases. Add debug functions in Kint wrappers here to fix modifiers and backtraces
+ */
+ public static $aliases = array(
+ array('Kint\\Kint', 'dump'),
+ array('Kint\\Kint', 'trace'),
+ array('Kint\\Kint', 'dumpArray'),
+ );
+
+ /**
+ * @var array Array of modes to renderer class names
+ */
+ public static $renderers = array(
+ self::MODE_RICH => 'Kint\\Renderer\\RichRenderer',
+ self::MODE_PLAIN => 'Kint\\Renderer\\PlainRenderer',
+ self::MODE_TEXT => 'Kint\\Renderer\\TextRenderer',
+ self::MODE_CLI => 'Kint\\Renderer\\CliRenderer',
+ );
+
+ public static $plugins = array(
+ 'Kint\\Parser\\ArrayObjectPlugin',
+ 'Kint\\Parser\\Base64Plugin',
+ 'Kint\\Parser\\BlacklistPlugin',
+ 'Kint\\Parser\\ClassMethodsPlugin',
+ 'Kint\\Parser\\ClassStaticsPlugin',
+ 'Kint\\Parser\\ClosurePlugin',
+ 'Kint\\Parser\\ColorPlugin',
+ 'Kint\\Parser\\DateTimePlugin',
+ 'Kint\\Parser\\FsPathPlugin',
+ 'Kint\\Parser\\IteratorPlugin',
+ 'Kint\\Parser\\JsonPlugin',
+ 'Kint\\Parser\\MicrotimePlugin',
+ 'Kint\\Parser\\SimpleXMLElementPlugin',
+ 'Kint\\Parser\\SplFileInfoPlugin',
+ 'Kint\\Parser\\SplObjectStoragePlugin',
+ 'Kint\\Parser\\StreamPlugin',
+ 'Kint\\Parser\\TablePlugin',
+ 'Kint\\Parser\\ThrowablePlugin',
+ 'Kint\\Parser\\TimestampPlugin',
+ 'Kint\\Parser\\TracePlugin',
+ 'Kint\\Parser\\XmlPlugin',
+ );
+
+ protected static $plugin_pool = array();
+
+ protected $parser;
+ protected $renderer;
+
+ public function __construct(Parser $p, Renderer $r)
+ {
+ $this->parser = $p;
+ $this->renderer = $r;
+ }
+
+ public function setParser(Parser $p)
+ {
+ $this->parser = $p;
+ }
+
+ public function getParser()
+ {
+ return $this->parser;
+ }
+
+ public function setRenderer(Renderer $r)
+ {
+ $this->renderer = $r;
+ }
+
+ public function getRenderer()
+ {
+ return $this->renderer;
+ }
+
+ public function setStatesFromStatics(array $statics)
+ {
+ $this->renderer->setStatics($statics);
+
+ $this->parser->setDepthLimit(isset($statics['max_depth']) ? $statics['max_depth'] : false);
+ $this->parser->clearPlugins();
+
+ if (!isset($statics['plugins'])) {
+ return;
+ }
+
+ $plugins = array();
+
+ foreach ($statics['plugins'] as $plugin) {
+ if ($plugin instanceof Plugin) {
+ $plugins[] = $plugin;
+ } elseif (\is_string($plugin) && \is_subclass_of($plugin, 'Kint\\Parser\\Plugin')) {
+ if (!isset(self::$plugin_pool[$plugin])) {
+ $p = new $plugin();
+ self::$plugin_pool[$plugin] = $p;
+ }
+ $plugins[] = self::$plugin_pool[$plugin];
+ }
+ }
+
+ $plugins = $this->renderer->filterParserPlugins($plugins);
+
+ foreach ($plugins as $plugin) {
+ $this->parser->addPlugin($plugin);
+ }
+ }
+
+ public function setStatesFromCallInfo(array $info)
+ {
+ $this->renderer->setCallInfo($info);
+
+ if (isset($info['modifiers']) && \is_array($info['modifiers']) && \in_array('+', $info['modifiers'], true)) {
+ $this->parser->setDepthLimit(false);
+ }
+
+ $this->parser->setCallerClass(isset($info['caller']['class']) ? $info['caller']['class'] : null);
+ }
+
+ /**
+ * Renders a list of vars including the pre and post renders.
+ *
+ * @param array $vars Data to dump
+ * @param BasicObject[] $base Base objects
+ *
+ * @return string
+ */
+ public function dumpAll(array $vars, array $base)
+ {
+ if (\array_keys($vars) !== \array_keys($base)) {
+ throw new InvalidArgumentException('Kint::dumpAll requires arrays of identical size and keys as arguments');
+ }
+
+ $output = $this->renderer->preRender();
+
+ if ($vars === array()) {
+ $output .= $this->renderer->renderNothing();
+ }
+
+ foreach ($vars as $key => $arg) {
+ if (!$base[$key] instanceof BasicObject) {
+ throw new InvalidArgumentException('Kint::dumpAll requires all elements of the second argument to be BasicObject instances');
+ }
+ $output .= $this->dumpVar($arg, $base[$key]);
+ }
+
+ $output .= $this->renderer->postRender();
+
+ return $output;
+ }
+
+ /**
+ * Dumps and renders a var.
+ *
+ * @param mixed $var Data to dump
+ * @param BasicObject $base Base object
+ *
+ * @return string
+ */
+ public function dumpVar(&$var, BasicObject $base)
+ {
+ return $this->renderer->render(
+ $this->parser->parse($var, $base)
+ );
+ }
+
+ /**
+ * Gets all static settings at once.
+ *
+ * @return array Current static settings
+ */
+ public static function getStatics()
+ {
+ return array(
+ 'aliases' => self::$aliases,
+ 'app_root_dirs' => self::$app_root_dirs,
+ 'cli_detection' => self::$cli_detection,
+ 'display_called_from' => self::$display_called_from,
+ 'enabled_mode' => self::$enabled_mode,
+ 'expanded' => self::$expanded,
+ 'file_link_format' => self::$file_link_format,
+ 'max_depth' => self::$max_depth,
+ 'mode_default' => self::$mode_default,
+ 'mode_default_cli' => self::$mode_default_cli,
+ 'plugins' => self::$plugins,
+ 'renderers' => self::$renderers,
+ 'return' => self::$return,
+ );
+ }
+
+ /**
+ * Creates a Kint instances based on static settings.
+ *
+ * Also calls setStatesFromStatics for you
+ *
+ * @param array $statics array of statics as returned by getStatics
+ *
+ * @return null|\Kint\Kint
+ */
+ public static function createFromStatics(array $statics)
+ {
+ $mode = false;
+
+ if (isset($statics['enabled_mode'])) {
+ $mode = $statics['enabled_mode'];
+
+ if (true === $statics['enabled_mode'] && isset($statics['mode_default'])) {
+ $mode = $statics['mode_default'];
+
+ if (PHP_SAPI === 'cli' && !empty($statics['cli_detection']) && isset($statics['mode_default_cli'])) {
+ $mode = $statics['mode_default_cli'];
+ }
+ }
+ }
+
+ if (!$mode) {
+ return null;
+ }
+
+ if (!isset($statics['renderers'][$mode])) {
+ $renderer = new TextRenderer();
+ } else {
+ /** @var Renderer */
+ $renderer = new $statics['renderers'][$mode]();
+ }
+
+ return new self(new Parser(), $renderer);
+ }
+
+ /**
+ * Creates base objects given parameter info.
+ *
+ * @param array $params Parameters as returned from getCallInfo
+ * @param int $argc Number of arguments the helper was called with
+ *
+ * @return BasicObject[] Base objects for the arguments
+ */
+ public static function getBasesFromParamInfo(array $params, $argc)
+ {
+ static $blacklist = array(
+ 'null',
+ 'true',
+ 'false',
+ 'array(...)',
+ 'array()',
+ '[...]',
+ '[]',
+ '(...)',
+ '()',
+ '"..."',
+ 'b"..."',
+ "'...'",
+ "b'...'",
+ );
+
+ $params = \array_values($params);
+ $bases = array();
+
+ for ($i = 0; $i < $argc; ++$i) {
+ if (isset($params[$i])) {
+ $param = $params[$i];
+ } else {
+ $param = null;
+ }
+
+ if (!isset($param['name']) || \is_numeric($param['name'])) {
+ $name = null;
+ } elseif (\in_array(\strtolower($param['name']), $blacklist, true)) {
+ $name = null;
+ } else {
+ $name = $param['name'];
+ }
+
+ if (isset($param['path'])) {
+ $access_path = $param['path'];
+
+ if (!empty($param['expression'])) {
+ $access_path = '('.$access_path.')';
+ }
+ } else {
+ $access_path = '$'.$i;
+ }
+
+ $bases[] = BasicObject::blank($name, $access_path);
+ }
+
+ return $bases;
+ }
+
+ /**
+ * Gets call info from the backtrace, alias, and argument count.
+ *
+ * Aliases must be normalized beforehand (Utils::normalizeAliases)
+ *
+ * @param array $aliases Call aliases as found in Kint::$aliases
+ * @param array[] $trace Backtrace
+ * @param int $argc Number of arguments
+ *
+ * @return array{params:null|array, modifiers:array, callee:null|array, caller:null|array, trace:array[]} Call info
+ */
+ public static function getCallInfo(array $aliases, array $trace, $argc)
+ {
+ $found = false;
+ $callee = null;
+ $caller = null;
+ $miniTrace = array();
+
+ foreach ($trace as $index => $frame) {
+ if (Utils::traceFrameIsListed($frame, $aliases)) {
+ $found = true;
+ $miniTrace = array();
+ }
+
+ if (!Utils::traceFrameIsListed($frame, array('spl_autoload_call'))) {
+ $miniTrace[] = $frame;
+ }
+ }
+
+ if ($found) {
+ $callee = \reset($miniTrace) ?: null;
+
+ /** @var null|array Psalm bug workaround */
+ $caller = \next($miniTrace) ?: null;
+ }
+
+ foreach ($miniTrace as $index => $frame) {
+ if ((0 === $index && $callee === $frame) || isset($frame['file'], $frame['line'])) {
+ unset($frame['object'], $frame['args']);
+ $miniTrace[$index] = $frame;
+ } else {
+ unset($miniTrace[$index]);
+ }
+ }
+
+ $miniTrace = \array_values($miniTrace);
+
+ $call = self::getSingleCall($callee ?: array(), $argc);
+
+ $ret = array(
+ 'params' => null,
+ 'modifiers' => array(),
+ 'callee' => $callee,
+ 'caller' => $caller,
+ 'trace' => $miniTrace,
+ );
+
+ if ($call) {
+ $ret['params'] = $call['parameters'];
+ $ret['modifiers'] = $call['modifiers'];
+ }
+
+ return $ret;
+ }
+
+ /**
+ * Dumps a backtrace.
+ *
+ * Functionally equivalent to Kint::dump(1) or Kint::dump(debug_backtrace(true))
+ *
+ * @return int|string
+ */
+ public static function trace()
+ {
+ if (!self::$enabled_mode) {
+ return 0;
+ }
+
+ Utils::normalizeAliases(self::$aliases);
+
+ $args = \func_get_args();
+
+ $call_info = self::getCallInfo(self::$aliases, \debug_backtrace(DEBUG_BACKTRACE_IGNORE_ARGS), \count($args));
+
+ $statics = self::getStatics();
+
+ if (\in_array('~', $call_info['modifiers'], true)) {
+ $statics['enabled_mode'] = self::MODE_TEXT;
+ }
+
+ $kintstance = self::createFromStatics($statics);
+ if (!$kintstance) {
+ // Should never happen
+ return 0; // @codeCoverageIgnore
+ }
+
+ if (\in_array('-', $call_info['modifiers'], true)) {
+ while (\ob_get_level()) {
+ \ob_end_clean();
+ }
+ }
+
+ $kintstance->setStatesFromStatics($statics);
+ $kintstance->setStatesFromCallInfo($call_info);
+
+ $trimmed_trace = array();
+ $trace = \debug_backtrace(true);
+
+ foreach ($trace as $frame) {
+ if (Utils::traceFrameIsListed($frame, self::$aliases)) {
+ $trimmed_trace = array();
+ }
+
+ $trimmed_trace[] = $frame;
+ }
+
+ $output = $kintstance->dumpAll(
+ array($trimmed_trace),
+ array(BasicObject::blank('Kint\\Kint::trace()', 'debug_backtrace(true)'))
+ );
+
+ if (self::$return || \in_array('@', $call_info['modifiers'], true)) {
+ return $output;
+ }
+
+ echo $output;
+
+ if (\in_array('-', $call_info['modifiers'], true)) {
+ \flush(); // @codeCoverageIgnore
+ }
+
+ return 0;
+ }
+
+ /**
+ * Dumps some data.
+ *
+ * Functionally equivalent to Kint::dump(1) or Kint::dump(debug_backtrace(true))
+ *
+ * @return int|string
+ */
+ public static function dump()
+ {
+ if (!self::$enabled_mode) {
+ return 0;
+ }
+
+ Utils::normalizeAliases(self::$aliases);
+
+ $args = \func_get_args();
+
+ $call_info = self::getCallInfo(self::$aliases, \debug_backtrace(DEBUG_BACKTRACE_IGNORE_ARGS), \count($args));
+
+ $statics = self::getStatics();
+
+ if (\in_array('~', $call_info['modifiers'], true)) {
+ $statics['enabled_mode'] = self::MODE_TEXT;
+ }
+
+ $kintstance = self::createFromStatics($statics);
+ if (!$kintstance) {
+ // Should never happen
+ return 0; // @codeCoverageIgnore
+ }
+
+ if (\in_array('-', $call_info['modifiers'], true)) {
+ while (\ob_get_level()) {
+ \ob_end_clean();
+ }
+ }
+
+ $kintstance->setStatesFromStatics($statics);
+ $kintstance->setStatesFromCallInfo($call_info);
+
+ // If the call is Kint::dump(1) then dump a backtrace instead
+ if ($args === array(1) && (!isset($call_info['params'][0]['name']) || '1' === $call_info['params'][0]['name'])) {
+ $args = \debug_backtrace(true);
+ $trace = array();
+
+ foreach ($args as $index => $frame) {
+ if (Utils::traceFrameIsListed($frame, self::$aliases)) {
+ $trace = array();
+ }
+
+ $trace[] = $frame;
+ }
+
+ if (isset($call_info['callee']['function'])) {
+ $tracename = $call_info['callee']['function'].'(1)';
+ if (isset($call_info['callee']['class'], $call_info['callee']['type'])) {
+ $tracename = $call_info['callee']['class'].$call_info['callee']['type'].$tracename;
+ }
+ } else {
+ $tracename = 'Kint\\Kint::dump(1)';
+ }
+
+ $tracebase = BasicObject::blank($tracename, 'debug_backtrace(true)');
+
+ $output = $kintstance->dumpAll(array($trace), array($tracebase));
+ } else {
+ $bases = self::getBasesFromParamInfo(
+ isset($call_info['params']) ? $call_info['params'] : array(),
+ \count($args)
+ );
+ $output = $kintstance->dumpAll($args, $bases);
+ }
+
+ if (self::$return || \in_array('@', $call_info['modifiers'], true)) {
+ return $output;
+ }
+
+ echo $output;
+
+ if (\in_array('-', $call_info['modifiers'], true)) {
+ \flush(); // @codeCoverageIgnore
+ }
+
+ return 0;
+ }
+
+ /**
+ * generic path display callback, can be configured in app_root_dirs; purpose is
+ * to show relevant path info and hide as much of the path as possible.
+ *
+ * @param string $file
+ *
+ * @return string
+ */
+ public static function shortenPath($file)
+ {
+ $file = \array_values(\array_filter(\explode('/', \str_replace('\\', '/', $file)), 'strlen'));
+
+ $longest_match = 0;
+ $match = '/';
+
+ foreach (self::$app_root_dirs as $path => $alias) {
+ if (empty($path)) {
+ continue;
+ }
+
+ $path = \array_values(\array_filter(\explode('/', \str_replace('\\', '/', $path)), 'strlen'));
+
+ if (\array_slice($file, 0, \count($path)) === $path && \count($path) > $longest_match) {
+ $longest_match = \count($path);
+ $match = $alias;
+ }
+ }
+
+ if ($longest_match) {
+ $file = \array_merge(array($match), \array_slice($file, $longest_match));
+
+ return \implode('/', $file);
+ }
+
+ // fallback to find common path with Kint dir
+ $kint = \array_values(\array_filter(\explode('/', \str_replace('\\', '/', KINT_DIR)), 'strlen'));
+
+ foreach ($file as $i => $part) {
+ if (!isset($kint[$i]) || $kint[$i] !== $part) {
+ return ($i ? '.../' : '/').\implode('/', \array_slice($file, $i));
+ }
+ }
+
+ return '/'.\implode('/', $file);
+ }
+
+ public static function getIdeLink($file, $line)
+ {
+ return \str_replace(array('%f', '%l'), array($file, $line), self::$file_link_format);
+ }
+
+ /**
+ * Returns specific function call info from a stack trace frame, or null if no match could be found.
+ *
+ * @param array $frame The stack trace frame in question
+ * @param int $argc The amount of arguments received
+ *
+ * @return null|array{parameters:array, modifiers:array} params and modifiers, or null if a specific call could not be determined
+ */
+ protected static function getSingleCall(array $frame, $argc)
+ {
+ if (!isset($frame['file'], $frame['line'], $frame['function']) || !\is_readable($frame['file'])) {
+ return null;
+ }
+
+ if (empty($frame['class'])) {
+ $callfunc = $frame['function'];
+ } else {
+ $callfunc = array($frame['class'], $frame['function']);
+ }
+
+ $calls = CallFinder::getFunctionCalls(
+ \file_get_contents($frame['file']),
+ $frame['line'],
+ $callfunc
+ );
+
+ $return = null;
+
+ foreach ($calls as $call) {
+ $is_unpack = false;
+
+ // Handle argument unpacking as a last resort
+ if (KINT_PHP56) {
+ foreach ($call['parameters'] as $i => &$param) {
+ if (0 === \strpos($param['name'], '...')) {
+ if ($i < $argc && $i === \count($call['parameters']) - 1) {
+ for ($j = 1; $j + $i < $argc; ++$j) {
+ $call['parameters'][] = array(
+ 'name' => 'array_values('.\substr($param['name'], 3).')['.$j.']',
+ 'path' => 'array_values('.\substr($param['path'], 3).')['.$j.']',
+ 'expression' => false,
+ );
+ }
+
+ $param['name'] = 'reset('.\substr($param['name'], 3).')';
+ $param['path'] = 'reset('.\substr($param['path'], 3).')';
+ $param['expression'] = false;
+ } else {
+ $call['parameters'] = \array_slice($call['parameters'], 0, $i);
+ }
+
+ $is_unpack = true;
+ break;
+ }
+
+ if ($i >= $argc) {
+ continue 2;
+ }
+ }
+ }
+
+ if ($is_unpack || \count($call['parameters']) === $argc) {
+ if (null === $return) {
+ $return = $call;
+ } else {
+ // If we have multiple calls on the same line with the same amount of arguments,
+ // we can't be sure which it is so just return null and let them figure it out
+ return null;
+ }
+ }
+ }
+
+ return $return;
+ }
+}
diff --git a/system/ThirdParty/Kint/kint.php b/system/ThirdParty/Kint/kint.php
deleted file mode 100644
index e0ce963..0000000
--- a/system/ThirdParty/Kint/kint.php
+++ /dev/null
@@ -1,756 +0,0 @@
- ' ',
- * app_path() => '',
- * config_path() => '',
- * database_path() => '',
- * public_path() => '',
- * resource_path() => '',
- * storage_path() => '',
- * ];
- *
- * Defaults to [$_SERVER['DOCUMENT_ROOT'] => '']
- */
- public static $app_root_dirs = array();
-
- /**
- * @var int max array/object levels to go deep, if zero no limits are applied
- */
- public static $max_depth = 6;
-
- /**
- * @var bool expand all trees by default for rich view
- */
- public static $expanded = false;
-
- /**
- * @var bool enable detection when Kint is command line.
- *
- * Formats output with whitespace only; does not HTML-escape it
- */
- public static $cli_detection = true;
-
- /**
- * @var array Kint aliases. Add debug functions in Kint wrappers here to fix modifiers and backtraces
- */
- public static $aliases = array(
- array('Kint\\Kint', 'dump'),
- array('Kint\\Kint', 'trace'),
- array('Kint\\Kint', 'dumpArray'),
- );
-
- /**
- * @var array Array of modes to renderer class names
- */
- public static $renderers = array(
- self::MODE_RICH => 'Kint\\Renderer\\RichRenderer',
- self::MODE_PLAIN => 'Kint\\Renderer\\PlainRenderer',
- self::MODE_TEXT => 'Kint\\Renderer\\TextRenderer',
- self::MODE_CLI => 'Kint\\Renderer\\CliRenderer',
- );
-
- public static $plugins = array(
- 'Kint\\Parser\\ArrayObjectPlugin',
- 'Kint\\Parser\\Base64Plugin',
- 'Kint\\Parser\\BlacklistPlugin',
- 'Kint\\Parser\\ClassMethodsPlugin',
- 'Kint\\Parser\\ClassStaticsPlugin',
- 'Kint\\Parser\\ClosurePlugin',
- 'Kint\\Parser\\ColorPlugin',
- 'Kint\\Parser\\DateTimePlugin',
- 'Kint\\Parser\\FsPathPlugin',
- 'Kint\\Parser\\IteratorPlugin',
- 'Kint\\Parser\\JsonPlugin',
- 'Kint\\Parser\\MicrotimePlugin',
- 'Kint\\Parser\\SimpleXMLElementPlugin',
- 'Kint\\Parser\\SplFileInfoPlugin',
- 'Kint\\Parser\\SplObjectStoragePlugin',
- 'Kint\\Parser\\StreamPlugin',
- 'Kint\\Parser\\TablePlugin',
- 'Kint\\Parser\\ThrowablePlugin',
- 'Kint\\Parser\\TimestampPlugin',
- 'Kint\\Parser\\TracePlugin',
- 'Kint\\Parser\\XmlPlugin',
- );
-
- protected static $plugin_pool = array();
-
- protected $parser;
- protected $renderer;
-
- public function __construct(Parser $p, Renderer $r)
- {
- $this->parser = $p;
- $this->renderer = $r;
- }
-
- public function setParser(Parser $p)
- {
- $this->parser = $p;
- }
-
- public function getParser()
- {
- return $this->parser;
- }
-
- public function setRenderer(Renderer $r)
- {
- $this->renderer = $r;
- }
-
- public function getRenderer()
- {
- return $this->renderer;
- }
-
- public function setStatesFromStatics(array $statics)
- {
- $this->renderer->setStatics($statics);
-
- $this->parser->setDepthLimit(isset($statics['max_depth']) ? $statics['max_depth'] : false);
- $this->parser->clearPlugins();
-
- if (!isset($statics['plugins'])) {
- return;
- }
-
- $plugins = array();
-
- foreach ($statics['plugins'] as $plugin) {
- if ($plugin instanceof Plugin) {
- $plugins[] = $plugin;
- } elseif (\is_string($plugin) && \is_subclass_of($plugin, 'Kint\\Parser\\Plugin')) {
- if (!isset(self::$plugin_pool[$plugin])) {
- $p = new $plugin();
- self::$plugin_pool[$plugin] = $p;
- }
- $plugins[] = self::$plugin_pool[$plugin];
- }
- }
-
- $plugins = $this->renderer->filterParserPlugins($plugins);
-
- foreach ($plugins as $plugin) {
- $this->parser->addPlugin($plugin);
- }
- }
-
- public function setStatesFromCallInfo(array $info)
- {
- $this->renderer->setCallInfo($info);
-
- if (isset($info['modifiers']) && \is_array($info['modifiers']) && \in_array('+', $info['modifiers'], true)) {
- $this->parser->setDepthLimit(false);
- }
-
- $this->parser->setCallerClass(isset($info['caller']['class']) ? $info['caller']['class'] : null);
- }
-
- /**
- * Renders a list of vars including the pre and post renders.
- *
- * @param array $vars Data to dump
- * @param BasicObject[] $base Base objects
- *
- * @return string
- */
- public function dumpAll(array $vars, array $base)
- {
- if (\array_keys($vars) !== \array_keys($base)) {
- throw new InvalidArgumentException('Kint::dumpAll requires arrays of identical size and keys as arguments');
- }
-
- $output = $this->renderer->preRender();
-
- if ($vars === array()) {
- $output .= $this->renderer->renderNothing();
- }
-
- foreach ($vars as $key => $arg) {
- if (!$base[$key] instanceof BasicObject) {
- throw new InvalidArgumentException('Kint::dumpAll requires all elements of the second argument to be BasicObject instances');
- }
- $output .= $this->dumpVar($arg, $base[$key]);
- }
-
- $output .= $this->renderer->postRender();
-
- return $output;
- }
-
- /**
- * Dumps and renders a var.
- *
- * @param mixed $var Data to dump
- * @param BasicObject $base Base object
- *
- * @return string
- */
- public function dumpVar(&$var, BasicObject $base)
- {
- return $this->renderer->render(
- $this->parser->parse($var, $base)
- );
- }
-
- /**
- * Gets all static settings at once.
- *
- * @return array Current static settings
- */
- public static function getStatics()
- {
- return array(
- 'aliases' => self::$aliases,
- 'app_root_dirs' => self::$app_root_dirs,
- 'cli_detection' => self::$cli_detection,
- 'display_called_from' => self::$display_called_from,
- 'enabled_mode' => self::$enabled_mode,
- 'expanded' => self::$expanded,
- 'file_link_format' => self::$file_link_format,
- 'max_depth' => self::$max_depth,
- 'mode_default' => self::$mode_default,
- 'mode_default_cli' => self::$mode_default_cli,
- 'plugins' => self::$plugins,
- 'renderers' => self::$renderers,
- 'return' => self::$return,
- );
- }
-
- /**
- * Creates a Kint instances based on static settings.
- *
- * Also calls setStatesFromStatics for you
- *
- * @param array $statics array of statics as returned by getStatics
- *
- * @return null|\Kint\Kint
- */
- public static function createFromStatics(array $statics)
- {
- $mode = false;
-
- if (isset($statics['enabled_mode'])) {
- $mode = $statics['enabled_mode'];
-
- if (true === $statics['enabled_mode'] && isset($statics['mode_default'])) {
- $mode = $statics['mode_default'];
-
- if (PHP_SAPI === 'cli' && !empty($statics['cli_detection']) && isset($statics['mode_default_cli'])) {
- $mode = $statics['mode_default_cli'];
- }
- }
- }
-
- if (!$mode) {
- return null;
- }
-
- if (!isset($statics['renderers'][$mode])) {
- $renderer = new TextRenderer();
- } else {
- /** @var Renderer */
- $renderer = new $statics['renderers'][$mode]();
- }
-
- return new self(new Parser(), $renderer);
- }
-
- /**
- * Creates base objects given parameter info.
- *
- * @param array $params Parameters as returned from getCallInfo
- * @param int $argc Number of arguments the helper was called with
- *
- * @return BasicObject[] Base objects for the arguments
- */
- public static function getBasesFromParamInfo(array $params, $argc)
- {
- static $blacklist = array(
- 'null',
- 'true',
- 'false',
- 'array(...)',
- 'array()',
- '[...]',
- '[]',
- '(...)',
- '()',
- '"..."',
- 'b"..."',
- "'...'",
- "b'...'",
- );
-
- $params = \array_values($params);
- $bases = array();
-
- for ($i = 0; $i < $argc; ++$i) {
- if (isset($params[$i])) {
- $param = $params[$i];
- } else {
- $param = null;
- }
-
- if (!isset($param['name']) || \is_numeric($param['name'])) {
- $name = null;
- } elseif (\in_array(\strtolower($param['name']), $blacklist, true)) {
- $name = null;
- } else {
- $name = $param['name'];
- }
-
- if (isset($param['path'])) {
- $access_path = $param['path'];
-
- if (!empty($param['expression'])) {
- $access_path = '('.$access_path.')';
- }
- } else {
- $access_path = '$'.$i;
- }
-
- $bases[] = BasicObject::blank($name, $access_path);
- }
-
- return $bases;
- }
-
- /**
- * Gets call info from the backtrace, alias, and argument count.
- *
- * Aliases must be normalized beforehand (Utils::normalizeAliases)
- *
- * @param array $aliases Call aliases as found in Kint::$aliases
- * @param array[] $trace Backtrace
- * @param int $argc Number of arguments
- *
- * @return array{params:null|array, modifiers:array, callee:null|array, caller:null|array, trace:array[]} Call info
- */
- public static function getCallInfo(array $aliases, array $trace, $argc)
- {
- $found = false;
- $callee = null;
- $caller = null;
- $miniTrace = array();
-
- foreach ($trace as $index => $frame) {
- if (Utils::traceFrameIsListed($frame, $aliases)) {
- $found = true;
- $miniTrace = array();
- }
-
- if (!Utils::traceFrameIsListed($frame, array('spl_autoload_call'))) {
- $miniTrace[] = $frame;
- }
- }
-
- if ($found) {
- $callee = \reset($miniTrace) ?: null;
-
- /** @var null|array Psalm bug workaround */
- $caller = \next($miniTrace) ?: null;
- }
-
- foreach ($miniTrace as $index => $frame) {
- if ((0 === $index && $callee === $frame) || isset($frame['file'], $frame['line'])) {
- unset($frame['object'], $frame['args']);
- $miniTrace[$index] = $frame;
- } else {
- unset($miniTrace[$index]);
- }
- }
-
- $miniTrace = \array_values($miniTrace);
-
- $call = self::getSingleCall($callee ?: array(), $argc);
-
- $ret = array(
- 'params' => null,
- 'modifiers' => array(),
- 'callee' => $callee,
- 'caller' => $caller,
- 'trace' => $miniTrace,
- );
-
- if ($call) {
- $ret['params'] = $call['parameters'];
- $ret['modifiers'] = $call['modifiers'];
- }
-
- return $ret;
- }
-
- /**
- * Dumps a backtrace.
- *
- * Functionally equivalent to Kint::dump(1) or Kint::dump(debug_backtrace(true))
- *
- * @return int|string
- */
- public static function trace()
- {
- if (!self::$enabled_mode) {
- return 0;
- }
-
- Utils::normalizeAliases(self::$aliases);
-
- $args = \func_get_args();
-
- $call_info = self::getCallInfo(self::$aliases, \debug_backtrace(DEBUG_BACKTRACE_IGNORE_ARGS), \count($args));
-
- $statics = self::getStatics();
-
- if (\in_array('~', $call_info['modifiers'], true)) {
- $statics['enabled_mode'] = self::MODE_TEXT;
- }
-
- $kintstance = self::createFromStatics($statics);
- if (!$kintstance) {
- // Should never happen
- return 0; // @codeCoverageIgnore
- }
-
- if (\in_array('-', $call_info['modifiers'], true)) {
- while (\ob_get_level()) {
- \ob_end_clean();
- }
- }
-
- $kintstance->setStatesFromStatics($statics);
- $kintstance->setStatesFromCallInfo($call_info);
-
- $trimmed_trace = array();
- $trace = \debug_backtrace(true);
-
- foreach ($trace as $frame) {
- if (Utils::traceFrameIsListed($frame, self::$aliases)) {
- $trimmed_trace = array();
- }
-
- $trimmed_trace[] = $frame;
- }
-
- $output = $kintstance->dumpAll(
- array($trimmed_trace),
- array(BasicObject::blank('Kint\\Kint::trace()', 'debug_backtrace(true)'))
- );
-
- if (self::$return || \in_array('@', $call_info['modifiers'], true)) {
- return $output;
- }
-
- echo $output;
-
- if (\in_array('-', $call_info['modifiers'], true)) {
- \flush(); // @codeCoverageIgnore
- }
-
- return 0;
- }
-
- /**
- * Dumps some data.
- *
- * Functionally equivalent to Kint::dump(1) or Kint::dump(debug_backtrace(true))
- *
- * @return int|string
- */
- public static function dump()
- {
- if (!self::$enabled_mode) {
- return 0;
- }
-
- Utils::normalizeAliases(self::$aliases);
-
- $args = \func_get_args();
-
- $call_info = self::getCallInfo(self::$aliases, \debug_backtrace(DEBUG_BACKTRACE_IGNORE_ARGS), \count($args));
-
- $statics = self::getStatics();
-
- if (\in_array('~', $call_info['modifiers'], true)) {
- $statics['enabled_mode'] = self::MODE_TEXT;
- }
-
- $kintstance = self::createFromStatics($statics);
- if (!$kintstance) {
- // Should never happen
- return 0; // @codeCoverageIgnore
- }
-
- if (\in_array('-', $call_info['modifiers'], true)) {
- while (\ob_get_level()) {
- \ob_end_clean();
- }
- }
-
- $kintstance->setStatesFromStatics($statics);
- $kintstance->setStatesFromCallInfo($call_info);
-
- // If the call is Kint::dump(1) then dump a backtrace instead
- if ($args === array(1) && (!isset($call_info['params'][0]['name']) || '1' === $call_info['params'][0]['name'])) {
- $args = \debug_backtrace(true);
- $trace = array();
-
- foreach ($args as $index => $frame) {
- if (Utils::traceFrameIsListed($frame, self::$aliases)) {
- $trace = array();
- }
-
- $trace[] = $frame;
- }
-
- if (isset($call_info['callee']['function'])) {
- $tracename = $call_info['callee']['function'].'(1)';
- if (isset($call_info['callee']['class'], $call_info['callee']['type'])) {
- $tracename = $call_info['callee']['class'].$call_info['callee']['type'].$tracename;
- }
- } else {
- $tracename = 'Kint\\Kint::dump(1)';
- }
-
- $tracebase = BasicObject::blank($tracename, 'debug_backtrace(true)');
-
- $output = $kintstance->dumpAll(array($trace), array($tracebase));
- } else {
- $bases = self::getBasesFromParamInfo(
- isset($call_info['params']) ? $call_info['params'] : array(),
- \count($args)
- );
- $output = $kintstance->dumpAll($args, $bases);
- }
-
- if (self::$return || \in_array('@', $call_info['modifiers'], true)) {
- return $output;
- }
-
- echo $output;
-
- if (\in_array('-', $call_info['modifiers'], true)) {
- \flush(); // @codeCoverageIgnore
- }
-
- return 0;
- }
-
- /**
- * generic path display callback, can be configured in app_root_dirs; purpose is
- * to show relevant path info and hide as much of the path as possible.
- *
- * @param string $file
- *
- * @return string
- */
- public static function shortenPath($file)
- {
- $file = \array_values(\array_filter(\explode('/', \str_replace('\\', '/', $file)), 'strlen'));
-
- $longest_match = 0;
- $match = '/';
-
- foreach (self::$app_root_dirs as $path => $alias) {
- if (empty($path)) {
- continue;
- }
-
- $path = \array_values(\array_filter(\explode('/', \str_replace('\\', '/', $path)), 'strlen'));
-
- if (\array_slice($file, 0, \count($path)) === $path && \count($path) > $longest_match) {
- $longest_match = \count($path);
- $match = $alias;
- }
- }
-
- if ($longest_match) {
- $file = \array_merge(array($match), \array_slice($file, $longest_match));
-
- return \implode('/', $file);
- }
-
- // fallback to find common path with Kint dir
- $kint = \array_values(\array_filter(\explode('/', \str_replace('\\', '/', KINT_DIR)), 'strlen'));
-
- foreach ($file as $i => $part) {
- if (!isset($kint[$i]) || $kint[$i] !== $part) {
- return ($i ? '.../' : '/').\implode('/', \array_slice($file, $i));
- }
- }
-
- return '/'.\implode('/', $file);
- }
-
- public static function getIdeLink($file, $line)
- {
- return \str_replace(array('%f', '%l'), array($file, $line), self::$file_link_format);
- }
-
- /**
- * Returns specific function call info from a stack trace frame, or null if no match could be found.
- *
- * @param array $frame The stack trace frame in question
- * @param int $argc The amount of arguments received
- *
- * @return null|array{parameters:array, modifiers:array} params and modifiers, or null if a specific call could not be determined
- */
- protected static function getSingleCall(array $frame, $argc)
- {
- if (!isset($frame['file'], $frame['line'], $frame['function']) || !\is_readable($frame['file'])) {
- return null;
- }
-
- if (empty($frame['class'])) {
- $callfunc = $frame['function'];
- } else {
- $callfunc = array($frame['class'], $frame['function']);
- }
-
- $calls = CallFinder::getFunctionCalls(
- \file_get_contents($frame['file']),
- $frame['line'],
- $callfunc
- );
-
- $return = null;
-
- foreach ($calls as $call) {
- $is_unpack = false;
-
- // Handle argument unpacking as a last resort
- if (KINT_PHP56) {
- foreach ($call['parameters'] as $i => &$param) {
- if (0 === \strpos($param['name'], '...')) {
- if ($i < $argc && $i === \count($call['parameters']) - 1) {
- for ($j = 1; $j + $i < $argc; ++$j) {
- $call['parameters'][] = array(
- 'name' => 'array_values('.\substr($param['name'], 3).')['.$j.']',
- 'path' => 'array_values('.\substr($param['path'], 3).')['.$j.']',
- 'expression' => false,
- );
- }
-
- $param['name'] = 'reset('.\substr($param['name'], 3).')';
- $param['path'] = 'reset('.\substr($param['path'], 3).')';
- $param['expression'] = false;
- } else {
- $call['parameters'] = \array_slice($call['parameters'], 0, $i);
- }
-
- $is_unpack = true;
- break;
- }
-
- if ($i >= $argc) {
- continue 2;
- }
- }
- }
-
- if ($is_unpack || \count($call['parameters']) === $argc) {
- if (null === $return) {
- $return = $call;
- } else {
- // If we have multiple calls on the same line with the same amount of arguments,
- // we can't be sure which it is so just return null and let them figure it out
- return null;
- }
- }
- }
-
- return $return;
- }
-}
diff --git a/system/Validation/CreditCardRules.php b/system/Validation/CreditCardRules.php
index bca1d69..53234e9 100644
--- a/system/Validation/CreditCardRules.php
+++ b/system/Validation/CreditCardRules.php
@@ -205,11 +205,10 @@
*
* @param string $ccNumber
* @param string $type
- * @param array $data
*
* @return boolean
*/
- public function valid_cc_number(string $ccNumber = null, string $type, array $data): bool
+ public function valid_cc_number(string $ccNumber = null, string $type): bool
{
$type = strtolower($type);
$info = null;
diff --git a/system/Validation/FileRules.php b/system/Validation/FileRules.php
index 6e7a7d7..c929088 100644
--- a/system/Validation/FileRules.php
+++ b/system/Validation/FileRules.php
@@ -79,11 +79,10 @@
*
* @param string $blank
* @param string $name
- * @param array $data
*
* @return boolean
*/
- public function uploaded(string $blank = null, string $name, array $data): bool
+ public function uploaded(string $blank = null, string $name): bool
{
$file = $this->request->getFile($name);
@@ -110,11 +109,10 @@
*
* @param string|null $blank
* @param string $params
- * @param array $data
*
* @return boolean
*/
- public function max_size(string $blank = null, string $params, array $data): bool
+ public function max_size(string $blank = null, string $params): bool
{
// Grab the file name off the top of the $params
// after we split it.
@@ -155,11 +153,10 @@
*
* @param string|null $blank
* @param string $params
- * @param array $data
*
* @return boolean
*/
- public function is_image(string $blank = null, string $params, array $data): bool
+ public function is_image(string $blank = null, string $params): bool
{
// Grab the file name off the top of the $params
// after we split it.
@@ -203,11 +200,10 @@
*
* @param string|null $blank
* @param string $params
- * @param array $data
*
* @return boolean
*/
- public function mime_in(string $blank = null, string $params, array $data): bool
+ public function mime_in(string $blank = null, string $params): bool
{
// Grab the file name off the top of the $params
// after we split it.
@@ -247,11 +243,10 @@
*
* @param string|null $blank
* @param string $params
- * @param array $data
*
* @return boolean
*/
- public function ext_in(string $blank = null, string $params, array $data): bool
+ public function ext_in(string $blank = null, string $params): bool
{
// Grab the file name off the top of the $params
// after we split it.
@@ -292,11 +287,10 @@
*
* @param string|null $blank
* @param string $params
- * @param array $data
*
* @return boolean
*/
- public function max_dims(string $blank = null, string $params, array $data): bool
+ public function max_dims(string $blank = null, string $params): bool
{
// Grab the file name off the top of the $params
// after we split it.
diff --git a/system/Validation/FormatRules.php b/system/Validation/FormatRules.php
index d143c6f..f121b70 100644
--- a/system/Validation/FormatRules.php
+++ b/system/Validation/FormatRules.php
@@ -152,7 +152,7 @@
*/
public function decimal(string $str = null): bool
{
- return (bool) preg_match('/^[\-+]?[0-9]+(|\.[0-9]+)$/', $str);
+ return (bool) preg_match('/^[-+]?[0-9]{0,}\.?[0-9]+$/', $str);
}
/**
@@ -218,11 +218,10 @@
*
* @param string $str
* @param string $pattern
- * @param array $data Other field/value pairs
*
* @return boolean
*/
- public function regex_match(string $str = null, string $pattern, array $data): bool
+ public function regex_match(string $str = null, string $pattern): bool
{
if (strpos($pattern, '/') !== 0)
{
@@ -329,8 +328,8 @@
* @return boolean
*/
public function valid_ip(string $ip = null, string $which = null): bool
- {
- if(empty($ip))
+ {
+ if (empty($ip))
{
return false;
}
@@ -347,7 +346,7 @@
break;
}
- return (bool) filter_var($ip, FILTER_VALIDATE_IP, $which) || (!ctype_print($ip) && (bool) filter_var(inet_ntop($ip), FILTER_VALIDATE_IP, $which));
+ return (bool) filter_var($ip, FILTER_VALIDATE_IP, $which) || (! ctype_print($ip) && (bool) filter_var(inet_ntop($ip), FILTER_VALIDATE_IP, $which));
}
/**
diff --git a/system/Validation/Rules.php b/system/Validation/Rules.php
index fb09e7b..371634b 100644
--- a/system/Validation/Rules.php
+++ b/system/Validation/Rules.php
@@ -61,7 +61,7 @@
*/
public function differs(string $str = null, string $field, array $data): bool
{
- return array_key_exists($field, $data) ? ($str !== $data[$field]) : false;
+ return array_key_exists($field, $data) && $str !== $data[$field];
}
//--------------------------------------------------------------------
@@ -87,11 +87,10 @@
*
* @param string $str
* @param string $val
- * @param array $data
*
* @return boolean
*/
- public function exact_length(string $str = null, string $val, array $data): bool
+ public function exact_length(string $str = null, string $val): bool
{
$val = explode(',', $val);
foreach ($val as $tmp)
@@ -112,13 +111,12 @@
*
* @param string $str
* @param string $min
- * @param array $data
*
* @return boolean
*/
- public function greater_than(string $str = null, string $min, array $data): bool
+ public function greater_than(string $str = null, string $min): bool
{
- return is_numeric($str) ? ($str > $min) : false;
+ return is_numeric($str) && $str > $min;
}
//--------------------------------------------------------------------
@@ -128,13 +126,12 @@
*
* @param string $str
* @param string $min
- * @param array $data
*
* @return boolean
*/
- public function greater_than_equal_to(string $str = null, string $min, array $data): bool
+ public function greater_than_equal_to(string $str = null, string $min): bool
{
- return is_numeric($str) ? ($str >= $min) : false;
+ return is_numeric($str) && $str >= $min;
}
//--------------------------------------------------------------------
@@ -183,12 +180,12 @@
/**
* Value should be within an array of values
*
- * @param string $value
- * @param string $list
- * @param array $data
+ * @param string $value
+ * @param string $list
+ *
* @return boolean
*/
- public function in_list(string $value = null, string $list, array $data): bool
+ public function in_list(string $value = null, string $list): bool
{
$list = explode(',', $list);
$list = array_map(function ($value) {
@@ -250,7 +247,7 @@
*/
public function less_than(string $str = null, string $max): bool
{
- return is_numeric($str) ? ($str < $max) : false;
+ return is_numeric($str) && $str < $max;
}
//--------------------------------------------------------------------
@@ -265,7 +262,7 @@
*/
public function less_than_equal_to(string $str = null, string $max): bool
{
- return is_numeric($str) ? ($str <= $max) : false;
+ return is_numeric($str) && $str <= $max;
}
//--------------------------------------------------------------------
@@ -281,7 +278,7 @@
*/
public function matches(string $str = null, string $field, array $data): bool
{
- return array_key_exists($field, $data) ? ($str === $data[$field]) : false;
+ return array_key_exists($field, $data) && $str === $data[$field];
}
//--------------------------------------------------------------------
@@ -291,11 +288,10 @@
*
* @param string $str
* @param string $val
- * @param array $data
*
* @return boolean
*/
- public function max_length(string $str = null, string $val, array $data): bool
+ public function max_length(string $str = null, string $val): bool
{
return ($val >= mb_strlen($str));
}
@@ -307,11 +303,10 @@
*
* @param string $str
* @param string $val
- * @param array $data
*
* @return boolean
*/
- public function min_length(string $str = null, string $val, array $data): bool
+ public function min_length(string $str = null, string $val): bool
{
return ($val <= mb_strlen($str));
}
diff --git a/system/Validation/Validation.php b/system/Validation/Validation.php
index 484b1e6..e425608 100644
--- a/system/Validation/Validation.php
+++ b/system/Validation/Validation.php
@@ -155,6 +155,10 @@
return false;
}
+ // Replace any placeholders (i.e. {id}) in the rules with
+ // the value found in $data, if exists.
+ $this->rules = $this->fillPlaceholders($this->rules, $data);
+
// Need this for searching arrays in validation.
helper('array');
@@ -170,9 +174,20 @@
$rules = $this->splitRules($rules);
}
- $value = dot_array_search($rField, $data);
+ $value = dot_array_search($rField, $data);
+ $fieldNameToken = explode('.', $rField);
- $this->processRules($rField, $rSetup['label'] ?? $rField, $value ?? null, $rules, $data);
+ if (is_array($value) && end($fieldNameToken) === '*')
+ {
+ foreach ($value as $val)
+ {
+ $this->processRules($rField, $rSetup['label'] ?? $rField, $val ?? null, $rules, $data);
+ }
+ }
+ else
+ {
+ $this->processRules($rField, $rSetup['label'] ?? $rField, $value ?? null, $rules, $data);
+ }
}
return ! empty($this->getErrors()) ? false : true;
@@ -474,8 +489,8 @@
*/
public function setRuleGroup(string $group)
{
- $rules = $this->getRuleGroup($group);
- $this->rules = $rules;
+ $rules = $this->getRuleGroup($group);
+ $this->setRules($rules);
$errorName = $group . '_errors';
if (isset($this->config->$errorName))
@@ -593,6 +608,64 @@
}
//--------------------------------------------------------------------
+
+ /**
+ * Replace any placeholders within the rules with the values that
+ * match the 'key' of any properties being set. For example, if
+ * we had the following $data array:
+ *
+ * [ 'id' => 13 ]
+ *
+ * and the following rule:
+ *
+ * 'required|is_unique[users,email,id,{id}]'
+ *
+ * The value of {id} would be replaced with the actual id in the form data:
+ *
+ * 'required|is_unique[users,email,id,13]'
+ *
+ * @param array $rules
+ * @param array $data
+ *
+ * @return array
+ */
+ protected function fillPlaceholders(array $rules, array $data): array
+ {
+ $replacements = [];
+
+ foreach ($data as $key => $value)
+ {
+ $replacements["{{$key}}"] = $value;
+ }
+
+ if (! empty($replacements))
+ {
+ foreach ($rules as &$rule)
+ {
+ if (is_array($rule))
+ {
+ foreach ($rule as &$row)
+ {
+ // Should only be an `errors` array
+ // which doesn't take placeholders.
+ if (is_array($row))
+ {
+ continue;
+ }
+
+ $row = strtr($row, $replacements);
+ }
+ continue;
+ }
+
+ $rule = strtr($rule, $replacements);
+ }
+ }
+
+ return $rules;
+ }
+
+ //--------------------------------------------------------------------
//--------------------------------------------------------------------
// Errors
//--------------------------------------------------------------------
@@ -698,7 +771,7 @@
// Check if custom message has been defined by user
if (isset($this->customErrors[$field][$rule]))
{
- $message = $this->customErrors[$field][$rule];
+ $message = lang($this->customErrors[$field][$rule]);
}
else
{
@@ -708,11 +781,10 @@
$message = lang('Validation.' . $rule);
}
- $message = str_replace('{field}', $label ?? $field, $message);
- $message = str_replace('{param}', $this->rules[$param]['label'] ?? $param, $message);
- $message = str_replace('{value}', $value, $message);
+ $message = str_replace('{field}', empty($label) ? $field : lang($label), $message);
+ $message = str_replace('{param}', empty($this->rules[$param]['label']) ? $param : lang($this->rules[$param]['label']), $message);
- return $message;
+ return str_replace('{value}', $value, $message);
}
/**
diff --git a/system/View/Cell.php b/system/View/Cell.php
index a7e79e9..d3cc6bc 100644
--- a/system/View/Cell.php
+++ b/system/View/Cell.php
@@ -40,8 +40,8 @@
use CodeIgniter\Cache\CacheInterface;
use CodeIgniter\View\Exceptions\ViewException;
-use ReflectionMethod;
use Config\Services;
+use ReflectionMethod;
/**
* Class Cell
@@ -110,7 +110,9 @@
list($class, $method) = $this->determineClass($library);
// Is it cached?
- $cacheName = ! empty($cacheName) ? $cacheName : $class . $method . md5(serialize($params));
+ $cacheName = ! empty($cacheName)
+ ? $cacheName
+ : str_replace(['\\', '/'], '', $class) . $method . md5(serialize($params));
if (! empty($this->cache) && $output = $this->cache->get($cacheName))
{
diff --git a/system/View/Filters.php b/system/View/Filters.php
index ad18ec8..8d8ed74 100644
--- a/system/View/Filters.php
+++ b/system/View/Filters.php
@@ -256,16 +256,18 @@
* @param $value
* @param string $currency
* @param string|null $locale
+ * @param integer $fraction
*
* @return string
*/
- public static function local_currency($value, string $currency, string $locale = null): string
+ public static function local_currency($value, string $currency, string $locale = null, $fraction = null): string
{
helper('number');
$options = [
'type' => NumberFormatter::CURRENCY,
'currency' => $currency,
+ 'fraction' => $fraction,
];
return format_number($value, 2, $locale, $options);
@@ -330,13 +332,10 @@
{
case 'common':
return round($value, $precision);
- break;
case 'ceil':
return ceil($value);
- break;
case 'floor':
return floor($value);
- break;
}
// Still here, just return the value.
diff --git a/system/View/Parser.php b/system/View/Parser.php
index 1e7bc30..d5b0de1 100644
--- a/system/View/Parser.php
+++ b/system/View/Parser.php
@@ -39,8 +39,8 @@
namespace CodeIgniter\View;
-use CodeIgniter\Log\Logger;
use CodeIgniter\View\Exceptions\ViewException;
+use Psr\Log\LoggerInterface;
/**
* Class Parser
@@ -93,13 +93,13 @@
/**
* Constructor
*
- * @param \Config\View $config
- * @param string $viewPath
- * @param mixed $loader
- * @param boolean $debug
- * @param Logger $logger
+ * @param \Config\View $config
+ * @param string $viewPath
+ * @param mixed $loader
+ * @param boolean $debug
+ * @param LoggerInterface $logger
*/
- public function __construct($config, string $viewPath = null, $loader = null, bool $debug = null, Logger $logger = null)
+ public function __construct($config, string $viewPath = null, $loader = null, bool $debug = null, LoggerInterface $logger = null)
{
// Ensure user plugins override core plugins.
$this->plugins = $config->plugins ?? [];
@@ -157,20 +157,25 @@
throw ViewException::forInvalidFile($file);
}
+ if (is_null($this->tempData))
+ {
+ $this->tempData = $this->data;
+ }
+
$template = file_get_contents($file);
- $output = $this->parse($template, $this->data, $options);
+ $output = $this->parse($template, $this->tempData, $options);
$this->logPerformance($start, microtime(true), $view);
- if (! $saveData)
+ if ($saveData)
{
- $this->data = [];
+ $this->data = $this->tempData;
}
// Should we cache?
if (isset($options['cache']))
{
cache()->save($cacheName, $output, (int) $options['cache']);
}
-
+ $this->tempData = null;
return $output;
}
@@ -196,14 +201,22 @@
$saveData = $this->config->saveData;
}
- $output = $this->parse($template, $this->data, $options);
+ if (is_null($this->tempData))
+ {
+ $this->tempData = $this->data;
+ }
+
+ $output = $this->parse($template, $this->tempData, $options);
$this->logPerformance($start, microtime(true), $this->excerpt($template));
- if (! $saveData)
+ if ($saveData)
{
- $this->data = [];
+ $this->data = $this->tempData;
}
+
+ $this->tempData = null;
+
return $output;
}
@@ -243,7 +256,8 @@
}
}
- $this->data = array_merge($this->data, $data);
+ $this->tempData = $this->tempData ?? $this->data;
+ $this->tempData = array_merge($this->tempData, $data);
return $this;
}
@@ -256,9 +270,10 @@
* Parses pseudo-variables contained in the specified template,
* replacing them with the data in the second param
*
- * @param string $template
- * @param array $data
- * @param array $options Future options
+ * @param string $template
+ * @param array $data
+ * @param array $options Future options
+ *
* @return string
*/
protected function parse(string $template, array $data = [], array $options = null): string
@@ -304,9 +319,7 @@
}
}
- $template = $this->insertNoparse($template);
-
- return $template;
+ return $this->insertNoparse($template);
}
//--------------------------------------------------------------------
@@ -320,7 +333,7 @@
*/
protected function parseSingle(string $key, string $val): array
{
- $pattern = '#' . $this->leftDelimiter . '!?\s*' . preg_quote($key) . '\s*\|*\s*([|a-zA-Z0-9<>=\(\),:_\-\s\+]+)*\s*!?' . $this->rightDelimiter . '#ms';
+ $pattern = '#' . $this->leftDelimiter . '!?\s*' . preg_quote($key) . '\s*\|*\s*([|\w<>=\(\),:.\-\s\+\\\\/]+)*\s*!?' . $this->rightDelimiter . '#ms';
return [$pattern => $val];
}
@@ -402,7 +415,7 @@
$val = 'Resource';
}
- $temp['#' . $this->leftDelimiter . '!?\s*' . preg_quote($key) . '\s*\|*\s*([|\w<>=\(\),:_\-\s\+]+)*\s*!?' . $this->rightDelimiter . '#s'] = $val;
+ $temp['#' . $this->leftDelimiter . '!?\s*' . preg_quote($key) . '\s*\|*\s*([|\w<>=\(\),:.\-\s\+\\\\/]+)*\s*!?' . $this->rightDelimiter . '#s'] = $val;
}
// Now replace our placeholders with the new content.
@@ -533,7 +546,14 @@
// Parse the PHP itself, or insert an error so they can debug
ob_start();
- extract($this->data);
+
+ if (is_null($this->tempData))
+ {
+ $this->tempData = $this->data;
+ }
+
+ extract($this->tempData);
+
try
{
eval('?>' . $template . '', 'applyFilters($replace, $filters);
-
- return $replace;
+ return $this->applyFilters($replace, $filters);
}
//--------------------------------------------------------------------
@@ -686,7 +705,7 @@
foreach ($filters as $filter)
{
// Grab any parameter we might need to send
- preg_match('/\([a-zA-Z0-9\-:_ +,<>=]+\)/', $filter, $param);
+ preg_match('/\([\w<>=\/\\\,:.\-\s\+]+\)/', $filter, $param);
// Remove the () and spaces to we have just the parameter left
$param = ! empty($param) ? trim($param[0], '() ') : null;
diff --git a/system/View/Plugins.php b/system/View/Plugins.php
index 30095fa..bc88334 100644
--- a/system/View/Plugins.php
+++ b/system/View/Plugins.php
@@ -48,11 +48,9 @@
/**
* Wrap helper function to use as view plugin.
*
- * @param array $params
- *
* @return string|\CodeIgniter\HTTP\URI
*/
- public static function currentURL(array $params = [])
+ public static function currentURL()
{
return current_url();
}
@@ -62,11 +60,9 @@
/**
* Wrap helper function to use as view plugin.
*
- * @param array $params
- *
* @return \CodeIgniter\HTTP\URI|mixed|string
*/
- public static function previousURL(array $params = [])
+ public static function previousURL()
{
return previous_url();
}
diff --git a/system/View/Table.php b/system/View/Table.php
index 1aaef57..1447132 100644
--- a/system/View/Table.php
+++ b/system/View/Table.php
@@ -87,14 +87,14 @@
*
* @var string
*/
- public $caption = null;
+ public $caption;
/**
* Table layout template
*
* @var array
*/
- public $template = null;
+ public $template;
/**
* Newline setting
@@ -115,7 +115,7 @@
*
* @var function
*/
- public $function = null;
+ public $function;
/**
* Set the template from the table config file if it exists
@@ -158,10 +158,9 @@
*
* Can be passed as an array or discreet params
*
- * @param mixed
* @return Table
*/
- public function setHeading($args = [])
+ public function setHeading()
{
$this->heading = $this->_prepArgs(func_get_args());
return $this;
@@ -172,10 +171,9 @@
*
* Can be passed as an array or discreet params
*
- * @param mixed
* @return Table
*/
- public function setFooting($args = [])
+ public function setFooting()
{
$this->footing = $this->_prepArgs(func_get_args());
return $this;
@@ -252,10 +250,9 @@
*
* Can be passed as an array or discreet params
*
- * @param mixed
* @return Table
*/
- public function addRow($args = [])
+ public function addRow()
{
$this->rows[] = $this->_prepArgs(func_get_args());
return $this;
diff --git a/system/View/View.php b/system/View/View.php
index 01241dd..ff138dd 100644
--- a/system/View/View.php
+++ b/system/View/View.php
@@ -59,6 +59,11 @@
protected $data = [];
/**
+ * Merge savedData and userData
+ */
+ protected $tempData = null;
+
+ /**
* The base directory to look in for our Views.
*
* @var string
@@ -189,11 +194,10 @@
// Store the results here so even if
// multiple views are called in a view, it won't
// clean it unless we mean it to.
- if ($saveData !== null)
+ if (is_null($saveData))
{
- $this->saveData = $saveData;
+ $saveData = $this->saveData;
}
-
$fileExt = pathinfo($view, PATHINFO_EXTENSION);
$realPath = empty($fileExt) ? $view . '.php' : $view; // allow Views as .html, .tpl, etc (from CI3)
$this->renderVars['view'] = $realPath;
@@ -225,11 +229,17 @@
}
// Make our view data available to the view.
- extract($this->data);
- if (! $this->saveData)
+ if (is_null($this->tempData))
{
- $this->data = [];
+ $this->tempData = $this->data;
+ }
+
+ extract($this->tempData);
+
+ if ($saveData)
+ {
+ $this->data = $this->tempData;
}
ob_start();
@@ -277,6 +287,8 @@
cache()->save($this->renderVars['cacheName'], $output, (int) $this->renderVars['options']['cache']);
}
+ $this->tempData = null;
+
return $output;
}
@@ -300,16 +312,22 @@
public function renderString(string $view, array $options = null, bool $saveData = null): string
{
$start = microtime(true);
+
if (is_null($saveData))
{
- $saveData = $this->config->saveData;
+ $saveData = $this->saveData;
}
- extract($this->data);
-
- if (! $saveData)
+ if (is_null($this->tempData))
{
- $this->data = [];
+ $this->tempData = $this->data;
+ }
+
+ extract($this->tempData);
+
+ if ($saveData)
+ {
+ $this->data = $this->tempData;
}
ob_start();
@@ -320,6 +338,8 @@
$this->logPerformance($start, microtime(true), $this->excerpt($view));
+ $this->tempData = null;
+
return $output;
}
@@ -355,7 +375,8 @@
$data = \esc($data, $context);
}
- $this->data = array_merge($this->data, $data);
+ $this->tempData = $this->tempData ?? $this->data;
+ $this->tempData = array_merge($this->tempData, $data);
return $this;
}
@@ -379,7 +400,8 @@
$value = \esc($value, $context);
}
- $this->data[$name] = $value;
+ $this->tempData = $this->tempData ?? $this->data;
+ $this->tempData[$name] = $value;
return $this;
}
@@ -407,7 +429,7 @@
*/
public function getData(): array
{
- return $this->data;
+ return is_null($this->tempData) ? $this->data : $this->tempData;
}
//--------------------------------------------------------------------
diff --git a/system/bootstrap.php b/system/bootstrap.php
index 33ab455..e014ad0 100644
--- a/system/bootstrap.php
+++ b/system/bootstrap.php
@@ -139,6 +139,16 @@
// Now load Composer's if it's available
if (is_file(COMPOSER_PATH))
{
+ /**
+ * The path to the vendor directory.
+ *
+ * We do not want to enforce this, so set the constant if Composer was used.
+ */
+ if (! defined('VENDORPATH'))
+ {
+ define('VENDORPATH', realpath(ROOTPATH . 'vendor') . DIRECTORY_SEPARATOR);
+ }
+
require_once COMPOSER_PATH;
}
diff --git a/tests/_support/Autoloader/UnnamespacedClass.php b/tests/_support/Autoloader/UnnamespacedClass.php
deleted file mode 100644
index 67b1ed3..0000000
--- a/tests/_support/Autoloader/UnnamespacedClass.php
+++ /dev/null
@@ -1,5 +0,0 @@
-prefix . $key;
-
- return array_key_exists($key, $this->cache)
- ? $this->cache[$key]
- : null;
- }
-
- //--------------------------------------------------------------------
-
- /**
- * Saves an item to the cache store.
- *
- * The $raw parameter is only utilized by Mamcache in order to
- * allow usage of increment() and decrement().
- *
- * @param string $key Cache item name
- * @param $value the data to save
- * @param null $ttl Time To Live, in seconds (default 60)
- * @param boolean $raw Whether to store the raw value.
- *
- * @return mixed
- */
- public function save(string $key, $value, int $ttl = 60, bool $raw = false)
- {
- $key = $this->prefix . $key;
-
- $this->cache[$key] = $value;
-
- return true;
- }
-
- //--------------------------------------------------------------------
-
- /**
- * Deletes a specific item from the cache store.
- *
- * @param string $key Cache item name
- *
- * @return mixed
- */
- public function delete(string $key)
- {
- unset($this->cache[$key]);
- }
-
- //--------------------------------------------------------------------
-
- /**
- * Performs atomic incrementation of a raw stored value.
- *
- * @param string $key Cache ID
- * @param integer $offset Step/value to increase by
- *
- * @return mixed
- */
- public function increment(string $key, int $offset = 1)
- {
- $key = $this->prefix . $key;
-
- $data = $this->cache[$key] ?: null;
-
- if (empty($data))
- {
- $data = 0;
- }
- elseif (! is_int($data))
- {
- return false;
- }
-
- return $this->save($key, $data + $offset);
- }
-
- //--------------------------------------------------------------------
-
- /**
- * Performs atomic decrementation of a raw stored value.
- *
- * @param string $key Cache ID
- * @param integer $offset Step/value to increase by
- *
- * @return mixed
- */
- public function decrement(string $key, int $offset = 1)
- {
- $key = $this->prefix . $key;
-
- $data = $this->cache[$key] ?: null;
-
- if (empty($data))
- {
- $data = 0;
- }
- elseif (! is_int($data))
- {
- return false;
- }
-
- return $this->save($key, $data - $offset);
- }
-
- //--------------------------------------------------------------------
-
- /**
- * Will delete all items in the entire cache.
- *
- * @return mixed
- */
- public function clean()
- {
- $this->cache = [];
- }
-
- //--------------------------------------------------------------------
-
- /**
- * Returns information on the entire cache.
- *
- * The information returned and the structure of the data
- * varies depending on the handler.
- *
- * @return mixed
- */
- public function getCacheInfo()
- {
- return [];
- }
-
- //--------------------------------------------------------------------
-
- /**
- * Returns detailed information about the specific item in the cache.
- *
- * @param string $key Cache item name.
- *
- * @return mixed
- */
- public function getMetaData(string $key)
- {
- return false;
- }
-
- //--------------------------------------------------------------------
-
- /**
- * Determines if the driver is supported on this system.
- *
- * @return boolean
- */
- public function isSupported(): bool
- {
- return true;
- }
-
- //--------------------------------------------------------------------
-
-}
diff --git a/tests/_support/Commands/AbstractInfo.php b/tests/_support/Commands/AbstractInfo.php
deleted file mode 100644
index 2ca684e..0000000
--- a/tests/_support/Commands/AbstractInfo.php
+++ /dev/null
@@ -1,13 +0,0 @@
-showError($oops);
- }
- }
-
- public function helpme()
- {
- $this->call('help');
- }
-}
diff --git a/tests/_support/Config/BadRegistrar.php b/tests/_support/Config/BadRegistrar.php
deleted file mode 100644
index a651d11..0000000
--- a/tests/_support/Config/BadRegistrar.php
+++ /dev/null
@@ -1,18 +0,0 @@
- [
- /*
- * The log levels that this handler will handle.
- */
- 'handles' => [
- 'critical',
- 'alert',
- 'emergency',
- 'debug',
- 'error',
- 'info',
- 'notice',
- 'warning',
- ],
- ],
- ];
-
-}
diff --git a/tests/_support/Config/MockServices.php b/tests/_support/Config/MockServices.php
deleted file mode 100644
index 0bd6400..0000000
--- a/tests/_support/Config/MockServices.php
+++ /dev/null
@@ -1,28 +0,0 @@
- TESTPATH . '_support/',
- ];
- public $classmap = [];
-
- //--------------------------------------------------------------------
-
- public function __construct()
- {
- // Don't call the parent since we don't want the default mappings.
- // parent::__construct();
- }
-
- //--------------------------------------------------------------------
- public static function locator(bool $getShared = true)
- {
- return new \CodeIgniter\Autoloader\FileLocator(static::autoloader());
- }
-
-}
diff --git a/tests/_support/Config/Registrar.php b/tests/_support/Config/Registrar.php
deleted file mode 100644
index 9d00c6a..0000000
--- a/tests/_support/Config/Registrar.php
+++ /dev/null
@@ -1,27 +0,0 @@
- [
- 'first',
- 'second',
- ],
- 'format' => 'nice',
- 'fruit' => [
- 'apple',
- 'banana',
- ],
- ];
- }
-
-}
diff --git a/tests/_support/Config/Routes.php b/tests/_support/Config/Routes.php
deleted file mode 100644
index 2369e33..0000000
--- a/tests/_support/Config/Routes.php
+++ /dev/null
@@ -1,7 +0,0 @@
-add('testing', 'TestController::index');
diff --git a/tests/_support/Controllers/Popcorn.php b/tests/_support/Controllers/Popcorn.php
deleted file mode 100644
index 8af998d..0000000
--- a/tests/_support/Controllers/Popcorn.php
+++ /dev/null
@@ -1,77 +0,0 @@
-respond('Oops', 567, 'Surprise');
- }
-
- public function popper()
- {
- throw new \RuntimeException('Surprise', 500);
- }
-
- public function weasel()
- {
- $this->respond('', 200);
- }
-
- public function oops()
- {
- $this->failUnauthorized();
- }
-
- public function goaway()
- {
- return redirect()->to('/');
- }
-
- // @see https://github.com/codeigniter4/CodeIgniter4/issues/1834
- public function index3()
- {
- $response = $this->response->setJSON([
- 'lang' => $this->request->getLocale(),
- ]);
-
- // echo var_dump($this->response->getBody());
- return $response;
- }
-
- public function canyon()
- {
- echo 'Hello-o-o';
- }
-
- public function cat()
- {
- }
-
- public function json()
- {
- $this->responsd(['answer' => 42]);
- }
-
- public function xml()
- {
- $this->respond('cat ');
- }
-
-}
diff --git a/tests/_support/Database/Migrations/20160428212500_Create_test_tables.php b/tests/_support/Database/Migrations/20160428212500_Create_test_tables.php
deleted file mode 100644
index f0f7eea..0000000
--- a/tests/_support/Database/Migrations/20160428212500_Create_test_tables.php
+++ /dev/null
@@ -1,148 +0,0 @@
-db->DBDriver === 'SQLite3' ? 'unique' : 'auto_increment';
-
- // User Table
- $this->forge->addField([
- 'id' => [
- 'type' => 'INTEGER',
- 'constraint' => 3,
- $unique_or_auto => true,
- ],
- 'name' => [
- 'type' => 'VARCHAR',
- 'constraint' => 80,
- ],
- 'email' => [
- 'type' => 'VARCHAR',
- 'constraint' => 100,
- ],
- 'country' => [
- 'type' => 'VARCHAR',
- 'constraint' => 40,
- ],
- 'created_at' => [
- 'type' => 'DATETIME',
- 'null' => true,
- ],
- 'updated_at' => [
- 'type' => 'DATETIME',
- 'null' => true,
- ],
- 'deleted_at' => [
- 'type' => 'DATETIME',
- 'null' => true,
- ],
- ]);
- $this->forge->addKey('id', true);
- $this->forge->createTable('user', true);
-
- // Job Table
- $this->forge->addField([
- 'id' => [
- 'type' => 'INTEGER',
- 'constraint' => 3,
- $unique_or_auto => true,
- ],
- 'name' => [
- 'type' => 'VARCHAR',
- 'constraint' => 40,
- ],
- 'description' => [
- 'type' => 'TEXT',
- 'null' => true,
- ],
- 'created_at' => [
- 'type' => 'INTEGER',
- 'constraint' => 11,
- 'null' => true,
- ],
- 'updated_at' => [
- 'type' => 'INTEGER',
- 'constraint' => 11,
- 'null' => true,
- ],
- 'deleted_at' => [
- 'type' => 'INTEGER',
- 'constraint' => 11,
- 'null' => true,
- ],
- ]);
- $this->forge->addKey('id', true);
- $this->forge->createTable('job', true);
-
- // Misc Table
- $this->forge->addField([
- 'id' => [
- 'type' => 'INTEGER',
- 'constraint' => 3,
- $unique_or_auto => true,
- ],
- 'key' => [
- 'type' => 'VARCHAR',
- 'constraint' => 40,
- ],
- 'value' => ['type' => 'TEXT'],
- ]);
- $this->forge->addKey('id', true);
- $this->forge->createTable('misc', true);
-
- // Empty Table
- $this->forge->addField([
- 'id' => [
- 'type' => 'INTEGER',
- 'constraint' => 3,
- $unique_or_auto => true,
- ],
- 'name' => [
- 'type' => 'VARCHAR',
- 'constraint' => 40,
- ],
- 'created_at' => [
- 'type' => 'DATE',
- 'null' => true,
- ],
- 'updated_at' => [
- 'type' => 'DATE',
- 'null' => true,
- ],
- ]);
- $this->forge->addKey('id', true);
- $this->forge->createTable('empty', true);
-
- // Secondary Table
- $this->forge->addField([
- 'id' => [
- 'type' => 'INTEGER',
- 'constraint' => 3,
- $unique_or_auto => true,
- ],
- 'key' => [
- 'type' => 'VARCHAR',
- 'constraint' => 40,
- ],
- 'value' => ['type' => 'TEXT'],
- ]);
- $this->forge->addKey('id', true);
- $this->forge->createTable('secondary', true);
- }
-
- //--------------------------------------------------------------------
-
- public function down()
- {
- $this->forge->dropTable('user', true);
- $this->forge->dropTable('job', true);
- $this->forge->dropTable('misc', true);
- $this->forge->dropTable('empty', true);
- $this->forge->dropTable('secondary', true);
- }
-
- //--------------------------------------------------------------------
-
-}
diff --git a/tests/_support/Database/MockBuilder.php b/tests/_support/Database/MockBuilder.php
deleted file mode 100644
index 98c7fb6..0000000
--- a/tests/_support/Database/MockBuilder.php
+++ /dev/null
@@ -1,15 +0,0 @@
-returnValues[$method] = $return;
-
- return $this;
- }
-
- //--------------------------------------------------------------------
-
- /**
- * Orchestrates a query against the database. Queries must use
- * Database\Statement objects to store the query and build it.
- * This method works with the cache.
- *
- * Should automatically handle different connections for read/write
- * queries if needed.
- *
- * @param string $sql
- * @param mixed ...$binds
- * @param boolean $setEscapeFlags
- * @param string $queryClass
- *
- * @return \CodeIgniter\Database\BaseResult|\CodeIgniter\Database\Query|false
- */
-
- public function query(string $sql, $binds = null, bool $setEscapeFlags = true, string $queryClass = 'CodeIgniter\\Database\\Query')
- {
- $queryClass = str_replace('Connection', 'Query', get_class($this));
-
- $query = new $queryClass($this);
-
- $query->setQuery($sql, $binds, $setEscapeFlags);
-
- if (! empty($this->swapPre) && ! empty($this->DBPrefix))
- {
- $query->swapPrefix($this->DBPrefix, $this->swapPre);
- }
-
- $startTime = microtime(true);
-
- $this->lastQuery = $query;
-
- // Run the query
- if (false === ($this->resultID = $this->simpleQuery($query->getQuery())))
- {
- $query->setDuration($startTime, $startTime);
-
- // @todo deal with errors
-
- return false;
- }
-
- $query->setDuration($startTime);
-
- $resultClass = str_replace('Connection', 'Result', get_class($this));
-
- return new $resultClass($this->connID, $this->resultID);
- }
-
- //--------------------------------------------------------------------
-
- /**
- * Connect to the database.
- *
- * @param boolean $persistent
- *
- * @return mixed
- */
- public function connect(bool $persistent = false)
- {
- $return = $this->returnValues['connect'] ?? true;
-
- if (is_array($return))
- {
- // By removing the top item here, we can
- // get a different value for, say, testing failover connections.
- $return = array_shift($this->returnValues['connect']);
- }
-
- return $return;
- }
-
- //--------------------------------------------------------------------
-
- /**
- * Keep or establish the connection if no queries have been sent for
- * a length of time exceeding the server's idle timeout.
- *
- * @return boolean
- */
- public function reconnect(): bool
- {
- return true;
- }
-
- //--------------------------------------------------------------------
-
- /**
- * Select a specific database table to use.
- *
- * @param string $databaseName
- *
- * @return mixed
- */
- public function setDatabase(string $databaseName)
- {
- $this->database = $databaseName;
-
- return $this;
- }
-
- //--------------------------------------------------------------------
-
- /**
- * Returns a string containing the version of the database being used.
- *
- * @return string
- */
- public function getVersion(): string
- {
- return CodeIgniter::CI_VERSION;
- }
-
- //--------------------------------------------------------------------
-
- /**
- * Executes the query against the database.
- *
- * @param string $sql
- *
- * @return mixed
- */
- protected function execute(string $sql)
- {
- return $this->returnValues['execute'];
- }
-
- //--------------------------------------------------------------------
-
- /**
- * Returns the total number of rows affected by this query.
- *
- * @return integer
- */
- public function affectedRows(): int
- {
- return 1;
- }
-
- //--------------------------------------------------------------------
-
- /**
- * Returns the last error code and message.
- *
- * Must return an array with keys 'code' and 'message':
- *
- * return ['code' => null, 'message' => null);
- *
- * @return array
- */
- public function error(): array
- {
- return [
- 'code' => null,
- 'message' => null,
- ];
- }
-
- //--------------------------------------------------------------------
-
- /**
- * Insert ID
- *
- * @return integer
- */
- public function insertID(): int
- {
- return $this->connID->insert_id;
- }
-
- //--------------------------------------------------------------------
-
- /**
- * Generates the SQL for listing tables in a platform-dependent manner.
- *
- * @param boolean $constrainByPrefix
- *
- * @return string
- */
- protected function _listTables(bool $constrainByPrefix = false): string
- {
- return '';
- }
-
- //--------------------------------------------------------------------
-
- /**
- * Generates a platform-specific query string so that the column names can be fetched.
- *
- * @param string $table
- *
- * @return string
- */
- protected function _listColumns(string $table = ''): string
- {
- return '';
- }
-
- /**
- * @param string $table
- * @return array
- */
- protected function _fieldData(string $table): array
- {
- return [];
- }
-
- /**
- * @param string $table
- * @return array
- */
- protected function _indexData(string $table): array
- {
- return [];
- }
-
- /**
- * @param string $table
- * @return array
- */
- protected function _foreignKeyData(string $table): array
- {
- return [];
- }
-
- //--------------------------------------------------------------------
-
- /**
- * Close the connection.
- */
- protected function _close()
- {
- return;
- }
-
- //--------------------------------------------------------------------
-
- /**
- * Begin Transaction
- *
- * @return boolean
- */
- protected function _transBegin(): bool
- {
- return true;
- }
-
- //--------------------------------------------------------------------
-
- /**
- * Commit Transaction
- *
- * @return boolean
- */
- protected function _transCommit(): bool
- {
- return true;
- }
-
- //--------------------------------------------------------------------
-
- /**
- * Rollback Transaction
- *
- * @return boolean
- */
- protected function _transRollback(): bool
- {
- return true;
- }
-
- //--------------------------------------------------------------------
-}
diff --git a/tests/_support/Database/MockQuery.php b/tests/_support/Database/MockQuery.php
deleted file mode 100644
index 0008104..0000000
--- a/tests/_support/Database/MockQuery.php
+++ /dev/null
@@ -1,8 +0,0 @@
- 'Jerome Lohan',
- 'email' => 'jlo@lohanenterprises.com',
- 'country' => 'UK',
- ];
-
- $this->db->table('user')->insert($row);
- }
-}
diff --git a/tests/_support/Database/Seeds/CITestSeeder.php b/tests/_support/Database/Seeds/CITestSeeder.php
deleted file mode 100644
index 02dde78..0000000
--- a/tests/_support/Database/Seeds/CITestSeeder.php
+++ /dev/null
@@ -1,78 +0,0 @@
- [
- [
- 'name' => 'Derek Jones',
- 'email' => 'derek@world.com',
- 'country' => 'US',
- ],
- [
- 'name' => 'Ahmadinejad',
- 'email' => 'ahmadinejad@world.com',
- 'country' => 'Iran',
- ],
- [
- 'name' => 'Richard A Causey',
- 'email' => 'richard@world.com',
- 'country' => 'US',
- ],
- [
- 'name' => 'Chris Martin',
- 'email' => 'chris@world.com',
- 'country' => 'UK',
- ],
- ],
- 'job' => [
- [
- 'name' => 'Developer',
- 'description' => 'Awesome job, but sometimes makes you bored',
- ],
- [
- 'name' => 'Politician',
- 'description' => 'This is not really a job',
- ],
- [
- 'name' => 'Accountant',
- 'description' => 'Boring job, but you will get free snack at lunch',
- ],
- [
- 'name' => 'Musician',
- 'description' => 'Only Coldplay can actually called Musician',
- ],
- ],
- 'misc' => [
- [
- 'key' => '\\xxxfoo456',
- 'value' => 'Entry with \\xxx',
- ],
- [
- 'key' => '\\%foo456',
- 'value' => 'Entry with \\%',
- ],
- [
- 'key' => 'spaces and tabs',
- 'value' => ' One two three tab',
- ],
- ],
- ];
-
- foreach ($data as $table => $dummy_data)
- {
- $this->db->table($table)->truncate();
-
- foreach ($dummy_data as $single_dummy_data)
- {
- $this->db->table($table)->insert($single_dummy_data);
- }
- }
- }
-
- //--------------------------------------------------------------------
-
-}
diff --git a/tests/_support/Database/SupportMigrations/001_Some_migration.php b/tests/_support/Database/SupportMigrations/001_Some_migration.php
deleted file mode 100644
index e2ace64..0000000
--- a/tests/_support/Database/SupportMigrations/001_Some_migration.php
+++ /dev/null
@@ -1,24 +0,0 @@
-forge->addField([
- 'key' => [
- 'type' => 'VARCHAR',
- 'constraint' => 255,
- ],
- ]);
- $this->forge->createTable('foo', true);
-
- $this->db->table('foo')->insert([
- 'key' => 'foobar',
- ]);
- }
-
- public function down()
- {
- $this->forge->dropTable('foo', true);
- }
-}
diff --git a/tests/_support/DatabaseTestMigrations/Database/Migrations/20160428212500_Create_test_tables.php b/tests/_support/DatabaseTestMigrations/Database/Migrations/20160428212500_Create_test_tables.php
deleted file mode 100644
index 8514ba4..0000000
--- a/tests/_support/DatabaseTestMigrations/Database/Migrations/20160428212500_Create_test_tables.php
+++ /dev/null
@@ -1,148 +0,0 @@
-db->DBDriver === 'SQLite3' ? 'unique' : 'auto_increment';
-
- // User Table
- $this->forge->addField([
- 'id' => [
- 'type' => 'INTEGER',
- 'constraint' => 3,
- $unique_or_auto => true,
- ],
- 'name' => [
- 'type' => 'VARCHAR',
- 'constraint' => 80,
- ],
- 'email' => [
- 'type' => 'VARCHAR',
- 'constraint' => 100,
- ],
- 'country' => [
- 'type' => 'VARCHAR',
- 'constraint' => 40,
- ],
- 'created_at' => [
- 'type' => 'DATETIME',
- 'null' => true,
- ],
- 'updated_at' => [
- 'type' => 'DATETIME',
- 'null' => true,
- ],
- 'deleted_at' => [
- 'type' => 'DATETIME',
- 'null' => true,
- ],
- ]);
- $this->forge->addKey('id', true);
- $this->forge->createTable('user', true);
-
- // Job Table
- $this->forge->addField([
- 'id' => [
- 'type' => 'INTEGER',
- 'constraint' => 3,
- $unique_or_auto => true,
- ],
- 'name' => [
- 'type' => 'VARCHAR',
- 'constraint' => 40,
- ],
- 'description' => [
- 'type' => 'TEXT',
- 'null' => true,
- ],
- 'created_at' => [
- 'type' => 'INTEGER',
- 'constraint' => 11,
- 'null' => true,
- ],
- 'updated_at' => [
- 'type' => 'INTEGER',
- 'constraint' => 11,
- 'null' => true,
- ],
- 'deleted_at' => [
- 'type' => 'INTEGER',
- 'constraint' => 11,
- 'null' => true,
- ],
- ]);
- $this->forge->addKey('id', true);
- $this->forge->createTable('job', true);
-
- // Misc Table
- $this->forge->addField([
- 'id' => [
- 'type' => 'INTEGER',
- 'constraint' => 3,
- $unique_or_auto => true,
- ],
- 'key' => [
- 'type' => 'VARCHAR',
- 'constraint' => 40,
- ],
- 'value' => ['type' => 'TEXT'],
- ]);
- $this->forge->addKey('id', true);
- $this->forge->createTable('misc', true);
-
- // Empty Table
- $this->forge->addField([
- 'id' => [
- 'type' => 'INTEGER',
- 'constraint' => 3,
- $unique_or_auto => true,
- ],
- 'name' => [
- 'type' => 'VARCHAR',
- 'constraint' => 40,
- ],
- 'created_at' => [
- 'type' => 'DATE',
- 'null' => true,
- ],
- 'updated_at' => [
- 'type' => 'DATE',
- 'null' => true,
- ],
- ]);
- $this->forge->addKey('id', true);
- $this->forge->createTable('empty', true);
-
- // Secondary Table
- $this->forge->addField([
- 'id' => [
- 'type' => 'INTEGER',
- 'constraint' => 3,
- $unique_or_auto => true,
- ],
- 'key' => [
- 'type' => 'VARCHAR',
- 'constraint' => 40,
- ],
- 'value' => ['type' => 'TEXT'],
- ]);
- $this->forge->addKey('id', true);
- $this->forge->createTable('secondary', true);
- }
-
- //--------------------------------------------------------------------
-
- public function down()
- {
- $this->forge->dropTable('user', true);
- $this->forge->dropTable('job', true);
- $this->forge->dropTable('misc', true);
- $this->forge->dropTable('empty', true);
- $this->forge->dropTable('secondary', true);
- }
-
- //--------------------------------------------------------------------
-
-}
diff --git a/tests/_support/Events/MockEvents.php b/tests/_support/Events/MockEvents.php
deleted file mode 100644
index eb9186b..0000000
--- a/tests/_support/Events/MockEvents.php
+++ /dev/null
@@ -1,66 +0,0 @@
-output = $output;
-
- return $this;
- }
-
- //--------------------------------------------------------------------
-
- protected function sendRequest(array $curl_options = []): string
- {
- // Save so we can access later.
- $this->curl_options = $curl_options;
-
- return $this->output;
- }
-
- //--------------------------------------------------------------------
- // for testing purposes only
- public function getBaseURI()
- {
- return $this->baseURI;
- }
-
- // for testing purposes only
- public function getDelay()
- {
- return $this->delay;
- }
-
-}
diff --git a/tests/_support/HTTP/MockIncomingRequest.php b/tests/_support/HTTP/MockIncomingRequest.php
deleted file mode 100644
index 627fc9a..0000000
--- a/tests/_support/HTTP/MockIncomingRequest.php
+++ /dev/null
@@ -1,17 +0,0 @@
-pretend;
- }
-
- // artificial error for testing
- public function misbehave()
- {
- $this->statusCode = 0;
- }
-
-}
diff --git a/tests/_support/Images/EXIFsamples/down-mirrored.jpg b/tests/_support/Images/EXIFsamples/down-mirrored.jpg
deleted file mode 100644
index 34a7b1d..0000000
--- a/tests/_support/Images/EXIFsamples/down-mirrored.jpg
+++ /dev/null
Binary files differ
diff --git a/tests/_support/Images/EXIFsamples/down.jpg b/tests/_support/Images/EXIFsamples/down.jpg
deleted file mode 100644
index 9077a7c..0000000
--- a/tests/_support/Images/EXIFsamples/down.jpg
+++ /dev/null
Binary files differ
diff --git a/tests/_support/Images/EXIFsamples/left-mirrored.jpg b/tests/_support/Images/EXIFsamples/left-mirrored.jpg
deleted file mode 100644
index 1832702..0000000
--- a/tests/_support/Images/EXIFsamples/left-mirrored.jpg
+++ /dev/null
Binary files differ
diff --git a/tests/_support/Images/EXIFsamples/left.jpg b/tests/_support/Images/EXIFsamples/left.jpg
deleted file mode 100644
index ad1f898..0000000
--- a/tests/_support/Images/EXIFsamples/left.jpg
+++ /dev/null
Binary files differ
diff --git a/tests/_support/Images/EXIFsamples/right-mirrored.jpg b/tests/_support/Images/EXIFsamples/right-mirrored.jpg
deleted file mode 100644
index cc8a29a..0000000
--- a/tests/_support/Images/EXIFsamples/right-mirrored.jpg
+++ /dev/null
Binary files differ
diff --git a/tests/_support/Images/EXIFsamples/right.jpg b/tests/_support/Images/EXIFsamples/right.jpg
deleted file mode 100644
index 183ffeb..0000000
--- a/tests/_support/Images/EXIFsamples/right.jpg
+++ /dev/null
Binary files differ
diff --git a/tests/_support/Images/EXIFsamples/up-mirrored.jpg b/tests/_support/Images/EXIFsamples/up-mirrored.jpg
deleted file mode 100644
index e1865a5..0000000
--- a/tests/_support/Images/EXIFsamples/up-mirrored.jpg
+++ /dev/null
Binary files differ
diff --git a/tests/_support/Images/EXIFsamples/up.jpg b/tests/_support/Images/EXIFsamples/up.jpg
deleted file mode 100644
index 70fc26f..0000000
--- a/tests/_support/Images/EXIFsamples/up.jpg
+++ /dev/null
Binary files differ
diff --git a/tests/_support/Images/Steveston_dusk.JPG b/tests/_support/Images/Steveston_dusk.JPG
deleted file mode 100644
index c3b9b12..0000000
--- a/tests/_support/Images/Steveston_dusk.JPG
+++ /dev/null
Binary files differ
diff --git a/tests/_support/Images/ci-logo.gif b/tests/_support/Images/ci-logo.gif
deleted file mode 100644
index 3001b2f..0000000
--- a/tests/_support/Images/ci-logo.gif
+++ /dev/null
Binary files differ
diff --git a/tests/_support/Images/ci-logo.jpeg b/tests/_support/Images/ci-logo.jpeg
deleted file mode 100644
index 1b0178b..0000000
--- a/tests/_support/Images/ci-logo.jpeg
+++ /dev/null
Binary files differ
diff --git a/tests/_support/Images/ci-logo.png b/tests/_support/Images/ci-logo.png
deleted file mode 100644
index 34fb010..0000000
--- a/tests/_support/Images/ci-logo.png
+++ /dev/null
Binary files differ
diff --git a/tests/_support/Language/MockLanguage.php b/tests/_support/Language/MockLanguage.php
deleted file mode 100644
index 49301db..0000000
--- a/tests/_support/Language/MockLanguage.php
+++ /dev/null
@@ -1,61 +0,0 @@
-language[$locale ?? $this->locale][$file] = $data;
-
- return $this;
- }
-
- //--------------------------------------------------------------------
-
- /**
- * Provides an override that allows us to set custom
- * data to be returned easily during testing.
- *
- * @param string $path
- *
- * @return array|mixed
- */
- protected function requireFile(string $path): array
- {
- return $this->data ?? [];
- }
-
- //--------------------------------------------------------------------
-
- /**
- * Arbitrarily turnoff internationalization support for testing
- */
- public function disableIntlSupport()
- {
- $this->intlSupport = false;
- }
-
-}
diff --git a/tests/_support/Language/SecondMockLanguage.php b/tests/_support/Language/SecondMockLanguage.php
deleted file mode 100644
index 7142885..0000000
--- a/tests/_support/Language/SecondMockLanguage.php
+++ /dev/null
@@ -1,27 +0,0 @@
-load($file, $locale, $return);
- }
-
- //--------------------------------------------------------------------
-
- /**
- * Expose the loaded language files
- */
- public function loaded(string $locale = 'en')
- {
- return $this->loadedFiles[$locale];
- }
-
-}
diff --git a/tests/_support/Language/ab-CD/Allin.php b/tests/_support/Language/ab-CD/Allin.php
deleted file mode 100644
index 3b15388..0000000
--- a/tests/_support/Language/ab-CD/Allin.php
+++ /dev/null
@@ -1,8 +0,0 @@
- 'Pyramid of Giza',
- 'tre' => 'Colossus of Rhodes',
- 'fiv' => 'Temple of Artemis',
- 'sev' => 'Hanging Gardens of Babylon',
-];
diff --git a/tests/_support/Language/ab/Allin.php b/tests/_support/Language/ab/Allin.php
deleted file mode 100644
index 6912075..0000000
--- a/tests/_support/Language/ab/Allin.php
+++ /dev/null
@@ -1,8 +0,0 @@
- 'gluttony',
- 'tre' => 'greed',
- 'six' => 'envy',
- 'sev' => 'pride',
-];
diff --git a/tests/_support/Language/en-ZZ/More.php b/tests/_support/Language/en-ZZ/More.php
deleted file mode 100644
index 6681020..0000000
--- a/tests/_support/Language/en-ZZ/More.php
+++ /dev/null
@@ -1,6 +0,0 @@
- 'These are not the droids you are looking for',
- 'notaMoon' => "It's made of cheese",
- 'wisdom' => 'There is no try',
-];
diff --git a/tests/_support/Language/en/Allin.php b/tests/_support/Language/en/Allin.php
deleted file mode 100644
index 6a10dcc..0000000
--- a/tests/_support/Language/en/Allin.php
+++ /dev/null
@@ -1,8 +0,0 @@
- 'four calling birds',
- 'fiv' => 'five golden rings',
- 'six' => 'six geese a laying',
- 'sev' => 'seven swans a swimming',
-];
diff --git a/tests/_support/Language/en/Core.php b/tests/_support/Language/en/Core.php
deleted file mode 100644
index b2fc4c1..0000000
--- a/tests/_support/Language/en/Core.php
+++ /dev/null
@@ -1,20 +0,0 @@
- '{0} extension could not be found.',
- 'bazillion' => 'billions and billions', // adds a new setting
-];
diff --git a/tests/_support/Language/en/More.php b/tests/_support/Language/en/More.php
deleted file mode 100644
index 5b4eaea..0000000
--- a/tests/_support/Language/en/More.php
+++ /dev/null
@@ -1,7 +0,0 @@
- 'These are not the droids you are looking for',
- 'notaMoon' => "That's no moon... it's a space station",
- 'cannotMove' => 'I have a very bad feeling about this',
-];
diff --git a/tests/_support/Language/ru/Language.php b/tests/_support/Language/ru/Language.php
deleted file mode 100644
index d6c6632..0000000
--- a/tests/_support/Language/ru/Language.php
+++ /dev/null
@@ -1,5 +0,0 @@
- 'Whatever this would be, translated',
-];
diff --git a/tests/_support/Log/Handlers/MockChromeHandler.php b/tests/_support/Log/Handlers/MockChromeHandler.php
deleted file mode 100644
index 1a64b22..0000000
--- a/tests/_support/Log/Handlers/MockChromeHandler.php
+++ /dev/null
@@ -1,25 +0,0 @@
-json['rows'][0];
- }
-
-}
diff --git a/tests/_support/Log/Handlers/MockFileHandler.php b/tests/_support/Log/Handlers/MockFileHandler.php
deleted file mode 100644
index efd72a9..0000000
--- a/tests/_support/Log/Handlers/MockFileHandler.php
+++ /dev/null
@@ -1,25 +0,0 @@
-handles = $config['handles'] ?? [];
- $this->destination = $this->path . 'log-' . date('Y-m-d') . '.' . $this->fileExtension;
- }
-
-}
diff --git a/tests/_support/Log/Handlers/TestHandler.php b/tests/_support/Log/Handlers/TestHandler.php
deleted file mode 100644
index e22559c..0000000
--- a/tests/_support/Log/Handlers/TestHandler.php
+++ /dev/null
@@ -1,64 +0,0 @@
-handles = $config['handles'] ?? [];
- $this->destination = $this->path . 'log-' . date('Y-m-d') . '.' . $this->fileExtension;
-
- self::$logs = [];
- }
-
- //--------------------------------------------------------------------
-
- /**
- * Handles logging the message.
- * If the handler returns false, then execution of handlers
- * will stop. Any handlers that have not run, yet, will not
- * be run.
- *
- * @param $level
- * @param $message
- *
- * @return boolean
- */
- public function handle($level, $message): bool
- {
- $date = date($this->dateFormat);
-
- self::$logs[] = strtoupper($level) . ' - ' . $date . ' --> ' . $message;
-
- return true;
- }
-
- //--------------------------------------------------------------------
-
- public static function getLogs()
- {
- return self::$logs;
- }
-
- //--------------------------------------------------------------------
-}
diff --git a/tests/_support/Log/TestLogger.php b/tests/_support/Log/TestLogger.php
deleted file mode 100644
index a88eb62..0000000
--- a/tests/_support/Log/TestLogger.php
+++ /dev/null
@@ -1,82 +0,0 @@
-assertLogged() methods.
- *
- * @param string $level
- * @param string $message
- * @param array $context
- *
- * @return boolean
- */
- public function log($level, $message, array $context = []): bool
- {
- // While this requires duplicate work, we want to ensure
- // we have the final message to test against.
- $log_message = $this->interpolate($message, $context);
-
- // Determine the file and line by finding the first
- // backtrace that is not part of our logging system.
- $trace = debug_backtrace();
- $file = null;
-
- foreach ($trace as $row)
- {
- if (! in_array($row['function'], ['log', 'log_message']))
- {
- $file = basename($row['file'] ?? '');
- break;
- }
- }
-
- self::$op_logs[] = [
- 'level' => $level,
- 'message' => $log_message,
- 'file' => $file,
- ];
-
- // Let the parent do it's thing.
- return parent::log($level, $message, $context);
- }
-
- //--------------------------------------------------------------------
-
- /**
- * Used by CIUnitTestCase class to provide ->assertLogged() methods.
- *
- * @param string $level
- * @param string $message
- *
- * @return boolean
- */
- public static function didLog(string $level, $message)
- {
- foreach (self::$op_logs as $log)
- {
- if (strtolower($log['level']) === strtolower($level) && $message === $log['message'])
- {
- return true;
- }
- }
-
- return false;
- }
-
- //--------------------------------------------------------------------
- // Expose cleanFileNames()
- public function cleanup($file)
- {
- return $this->cleanFileNames($file);
- }
-
-}
diff --git a/tests/_support/MigrationTestMigrations/Database/Migrations/2018-01-24-102300_Another_migration.py b/tests/_support/MigrationTestMigrations/Database/Migrations/2018-01-24-102300_Another_migration.py
deleted file mode 100644
index 908a6dd..0000000
--- a/tests/_support/MigrationTestMigrations/Database/Migrations/2018-01-24-102300_Another_migration.py
+++ /dev/null
@@ -1,24 +0,0 @@
-forge->addField([
- 'key' => [
- 'type' => 'VARCHAR',
- 'constraint' => 255,
- ],
- ]);
- $this->forge->createTable('foo', true);
-
- $this->db->table('foo')->insert([
- 'key' => 'foobar',
- ]);
- }
-
- public function down()
- {
- $this->forge->dropTable('foo', true);
- }
-}
diff --git a/tests/_support/MigrationTestMigrations/Database/Migrations/2018-01-24-102301_Some_migration.php b/tests/_support/MigrationTestMigrations/Database/Migrations/2018-01-24-102301_Some_migration.php
deleted file mode 100644
index e7763a8..0000000
--- a/tests/_support/MigrationTestMigrations/Database/Migrations/2018-01-24-102301_Some_migration.php
+++ /dev/null
@@ -1,24 +0,0 @@
-forge->addField([
- 'key' => [
- 'type' => 'VARCHAR',
- 'constraint' => 255,
- ],
- ]);
- $this->forge->createTable('foo', true);
-
- $this->db->table('foo')->insert([
- 'key' => 'foobar',
- ]);
- }
-
- public function down()
- {
- $this->forge->dropTable('foo', true);
- }
-}
diff --git a/tests/_support/MigrationTestMigrations/Database/Migrations/2018-01-24-102302_Another_migration.php b/tests/_support/MigrationTestMigrations/Database/Migrations/2018-01-24-102302_Another_migration.php
deleted file mode 100644
index 797aae7..0000000
--- a/tests/_support/MigrationTestMigrations/Database/Migrations/2018-01-24-102302_Another_migration.php
+++ /dev/null
@@ -1,28 +0,0 @@
- [
- 'type' => 'VARCHAR',
- 'constraint' => 255,
- ],
- ];
- $this->forge->addColumn('foo', $fields);
-
- $this->db->table('foo')->insert([
- 'key' => 'foobar',
- 'value' => 'raboof',
- ]);
- }
-
- public function down()
- {
- if ($this->db->tableExists('foo'))
- {
- $this->forge->dropColumn('foo', 'value');
- }
- }
-}
diff --git a/tests/_support/MockCodeIgniter.php b/tests/_support/MockCodeIgniter.php
deleted file mode 100644
index 3e31d00..0000000
--- a/tests/_support/MockCodeIgniter.php
+++ /dev/null
@@ -1,11 +0,0 @@
-tokens[] = 'beforeInsert';
-
- return $data;
- }
-
- protected function afterInsertMethod(array $data)
- {
- $this->tokens[] = 'afterInsert';
-
- return $data;
- }
-
- protected function beforeUpdateMethod(array $data)
- {
- $this->tokens[] = 'beforeUpdate';
-
- return $data;
- }
-
- protected function afterUpdateMethod(array $data)
- {
- $this->tokens[] = 'afterUpdate';
-
- return $data;
- }
-
- protected function afterFindMethod(array $data)
- {
- $this->tokens[] = 'afterFind';
-
- return $data;
- }
-
- protected function afterDeleteMethod(array $data)
- {
- $this->tokens[] = 'afterDelete';
-
- return $data;
- }
-
- public function hasToken(string $token)
- {
- return in_array($token, $this->tokens);
- }
-
-}
diff --git a/tests/_support/Models/JobModel.php b/tests/_support/Models/JobModel.php
deleted file mode 100644
index 98c4ad2..0000000
--- a/tests/_support/Models/JobModel.php
+++ /dev/null
@@ -1,23 +0,0 @@
- [
- 'required',
- 'min_length[10]',
- 'errors' => [
- 'min_length' => 'Minimum Length Error',
- ]
- ],
- 'token' => 'in_list[{id}]',
- ];
-}
diff --git a/tests/_support/Models/ValidModel.php b/tests/_support/Models/ValidModel.php
deleted file mode 100644
index dc9ec7c..0000000
--- a/tests/_support/Models/ValidModel.php
+++ /dev/null
@@ -1,34 +0,0 @@
- [
- 'required',
- 'min_length[3]',
- ],
- 'token' => 'permit_empty|in_list[{id}]',
- ];
-
- protected $validationMessages = [
- 'name' => [
- 'required' => 'You forgot to name the baby.',
- 'min_length' => 'Too short, man!',
- ],
- ];
-}
diff --git a/tests/_support/RESTful/MockResourceController.php b/tests/_support/RESTful/MockResourceController.php
deleted file mode 100644
index 21f4343..0000000
--- a/tests/_support/RESTful/MockResourceController.php
+++ /dev/null
@@ -1,24 +0,0 @@
-model;
- }
-
- public function getModelName()
- {
- return $this->modelName;
- }
-
- public function getFormat()
- {
- return $this->format;
- }
-
-}
diff --git a/tests/_support/RESTful/MockResourcePresenter.php b/tests/_support/RESTful/MockResourcePresenter.php
deleted file mode 100644
index d9b0951..0000000
--- a/tests/_support/RESTful/MockResourcePresenter.php
+++ /dev/null
@@ -1,24 +0,0 @@
-model;
- }
-
- public function getModelName()
- {
- return $this->modelName;
- }
-
- public function getFormat()
- {
- return $this->format;
- }
-
-}
diff --git a/tests/_support/RESTful/Worker.php b/tests/_support/RESTful/Worker.php
deleted file mode 100644
index 973543f..0000000
--- a/tests/_support/RESTful/Worker.php
+++ /dev/null
@@ -1,11 +0,0 @@
-CSRFHash;
-
- return $this;
- }
-
- //--------------------------------------------------------------------
-
-}
diff --git a/tests/_support/Services.php b/tests/_support/Services.php
deleted file mode 100644
index 48e8283..0000000
--- a/tests/_support/Services.php
+++ /dev/null
@@ -1,70 +0,0 @@
-driver, true);
- }
-
- //--------------------------------------------------------------------
-
- /**
- * Starts the session.
- * Extracted for testing reasons.
- */
- protected function startSession()
- {
- // session_start();
- }
-
- //--------------------------------------------------------------------
-
- /**
- * Takes care of setting the cookie on the client side.
- * Extracted for testing reasons.
- */
- protected function setCookie()
- {
- $this->cookies[] = [
- $this->sessionCookieName,
- session_id(),
- (empty($this->sessionExpiration) ? 0 : time() + $this->sessionExpiration),
- $this->cookiePath,
- $this->cookieDomain,
- $this->cookieSecure,
- true,
- ];
- }
-
- //--------------------------------------------------------------------
-
- public function regenerate(bool $destroy = false)
- {
- $this->didRegenerate = true;
- $_SESSION['__ci_last_regenerate'] = time();
- }
-
- //--------------------------------------------------------------------
-}
diff --git a/tests/_support/SomeEntity.php b/tests/_support/SomeEntity.php
deleted file mode 100644
index 3d22993..0000000
--- a/tests/_support/SomeEntity.php
+++ /dev/null
@@ -1,14 +0,0 @@
- null,
- 'bar' => null,
- ];
-
-}
diff --git a/tests/_support/Validation/TestRules.php b/tests/_support/Validation/TestRules.php
deleted file mode 100644
index 2c40f32..0000000
--- a/tests/_support/Validation/TestRules.php
+++ /dev/null
@@ -1,14 +0,0 @@
-= $testString ?>
\ No newline at end of file
diff --git a/tests/_support/View/Views/simpler.php b/tests/_support/View/Views/simpler.php
deleted file mode 100644
index 0588b62..0000000
--- a/tests/_support/View/Views/simpler.php
+++ /dev/null
@@ -1 +0,0 @@
-{testString}
\ No newline at end of file
diff --git a/tests/_support/_bootstrap.php b/tests/_support/_bootstrap.php
deleted file mode 100644
index 65dd9a1..0000000
--- a/tests/_support/_bootstrap.php
+++ /dev/null
@@ -1,32 +0,0 @@
-