diff --git a/_support/Config/BadRegistrar.php b/_support/Config/BadRegistrar.php
index 877d7be..a651d11 100644
--- a/_support/Config/BadRegistrar.php
+++ b/_support/Config/BadRegistrar.php
@@ -10,7 +10,7 @@
class BadRegistrar
{
- public static function RegistrarConfig2()
+ public static function RegistrarConfig()
{
return 'I am not worthy';
}
diff --git a/_support/Config/MockServices.php b/_support/Config/MockServices.php
new file mode 100644
index 0000000..0bd6400
--- /dev/null
+++ b/_support/Config/MockServices.php
@@ -0,0 +1,28 @@
+ 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/_support/Controllers/Popcorn.php b/_support/Controllers/Popcorn.php
new file mode 100644
index 0000000..b3826d3
--- /dev/null
+++ b/_support/Controllers/Popcorn.php
@@ -0,0 +1,58 @@
+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;
+ }
+
+}
diff --git a/_support/Database/Migrations/20160428212500_Create_test_tables.php b/_support/Database/Migrations/20160428212500_Create_test_tables.php
index 8d4a93a..d81ab34 100644
--- a/_support/Database/Migrations/20160428212500_Create_test_tables.php
+++ b/_support/Database/Migrations/20160428212500_Create_test_tables.php
@@ -86,14 +86,20 @@
$this->forge->addKey('id', true);
$this->forge->createTable('empty', true);
- //No Primary Key
+ // 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);
}
diff --git a/_support/Models/SecondaryModel.php b/_support/Models/SecondaryModel.php
index 19d8228..6088bd6 100644
--- a/_support/Models/SecondaryModel.php
+++ b/_support/Models/SecondaryModel.php
@@ -6,7 +6,7 @@
{
protected $table = 'secondary';
- protected $primaryKey = null;
+ protected $primaryKey = 'id';
protected $returnType = 'object';
diff --git a/app/Config/Events.php b/app/Config/Events.php
index 97c732a..cfdb537 100644
--- a/app/Config/Events.php
+++ b/app/Config/Events.php
@@ -19,23 +19,25 @@
* Events::on('create', [$myInstance, 'myMethod']);
*/
-/*
- * --------------------------------------------------------------------
- * Debug Toolbar Listeners.
- * --------------------------------------------------------------------
- * If you delete, they will no longer be collected.
- */
-if (ENVIRONMENT !== 'production')
-{
- Events::on('DBQuery', 'CodeIgniter\Debug\Toolbar\Collectors\Database::collect');
+Events::on('pre_system', function () {
+ while (\ob_get_level() > 0)
+ {
+ \ob_end_flush();
+ }
- Events::on('pre_system', function () {
- if (ENVIRONMENT !== 'testing')
- {
- \ob_start(function ($buffer) {
- return $buffer;
- });
- }
- Services::toolbar()->respond();
+ \ob_start(function ($buffer) {
+ return $buffer;
});
-}
+
+ /*
+ * --------------------------------------------------------------------
+ * Debug Toolbar Listeners.
+ * --------------------------------------------------------------------
+ * If you delete, they will no longer be collected.
+ */
+ if (ENVIRONMENT !== 'production')
+ {
+ Events::on('DBQuery', 'CodeIgniter\Debug\Toolbar\Collectors\Database::collect');
+ Services::toolbar()->respond();
+ }
+});
diff --git a/app/Controllers/BaseController.php b/app/Controllers/BaseController.php
new file mode 100644
index 0000000..abffc56
--- /dev/null
+++ b/app/Controllers/BaseController.php
@@ -0,0 +1,46 @@
+session = \Config\Services::session();
+
+ }
+}
diff --git a/app/Controllers/Home.php b/app/Controllers/Home.php
index 84b7135..b87de40 100644
--- a/app/Controllers/Home.php
+++ b/app/Controllers/Home.php
@@ -2,7 +2,7 @@
use CodeIgniter\Controller;
-class Home extends Controller
+class Home extends BaseController
{
public function index()
{
diff --git a/contributing.md b/contributing.md
index 78593e2..09dff38 100644
--- a/contributing.md
+++ b/contributing.md
@@ -5,7 +5,7 @@
We expect all contributions to conform to our style guide, be commented (inside the PHP source files),
be documented (in the user guide), and unit tested (in the test folder).
-There is a [Contributing to CodeIgniter](./contributing/index.rst) section in the repository which describes the contribution process; this page is an overview.
+There is a [Contributing to CodeIgniter](./contributing/README.rst) section in the repository which describes the contribution process; this page is an overview.
## Issues
@@ -15,7 +15,7 @@
2. The issue has already been fixed (check the develop branch, or look for closed Issues)
3. Is it something really obvious that you can fix yourself?
-Reporting issues is helpful but an even [better approach](https://codeigniter4.github.io/CodeIgniter4/contributing/workflow.html) is to send a Pull Request, which is done by "Forking" the main repository and committing to your own copy. This will require you to use the version control system called Git.
+Reporting issues is helpful but an even [better approach](./contributing/workflow.rst) is to send a Pull Request, which is done by "Forking" the main repository and committing to your own copy. This will require you to use the version control system called Git.
## Guidelines
@@ -26,7 +26,7 @@
### PHP Style
-All code must meet the [Style Guide](https://codeigniter4.github.io/CodeIgniter4/contributing/styleguide.html).
+All code must meet the [Style Guide](./contributing/styleguide.rst).
This makes certain that all code is the same format as the existing code and means it will be as readable as possible.
### Documentation
@@ -46,7 +46,7 @@
### Signing
-You must [GPG-sign](https://codeigniter4.github.io/CodeIgniter4/contributing/signing.html) 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.
+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
diff --git a/public/.htaccess b/public/.htaccess
index 3a3f07d..adfbcd5 100644
--- a/public/.htaccess
+++ b/public/.htaccess
@@ -5,6 +5,9 @@
# Sets the environment that CodeIgniter runs under.
# SetEnv CI_ENVIRONMENT development
+# Disable directory browsing
+Options All -Indexes
+
# ----------------------------------------------------------------------
# UTF-8 encoding
# ----------------------------------------------------------------------
@@ -18,6 +21,16 @@
# ----------------------------------------------------------------------
+# Activate CORS
+# ----------------------------------------------------------------------
+
+
+
+ Header set Access-Control-Allow-Origin "*"
+
+
+
+# ----------------------------------------------------------------------
# Rewrite engine
# ----------------------------------------------------------------------
@@ -47,6 +60,12 @@
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)$ index.php/$1 [L]
+ # Disable image hotlinkiing start
+ RewriteCond %{HTTP_REFERER} !^$
+ RewriteCond %{HTTP_REFERER} !^http(s)?://(www\.)?example.com [NC]
+ RewriteRule \.(jpg|jpeg|png|gif)$ – [NC,F,L]
+ # Disable image hotlinkiing end
+
# Ensure Authorization header is passed along
RewriteCond %{HTTP:Authorization} .
RewriteRule .* - [E=HTTP_AUTHORIZATION:%{HTTP:Authorization}]
@@ -58,10 +77,58 @@
ErrorDocument 404 index.php
+# Disable server signature start
+ ServerSignature Off
+# Disable server signature end
+
+# BEGIN Expires
+
+ ExpiresActive On
+ ExpiresByType text/css "access 1 month"
+ ExpiresByType text/html "access 1 month"
+ ExpiresByType image/gif "access 1 year"
+ ExpiresByType image/png "access 1 year"
+ ExpiresByType image/jpg "access 1 year"
+ ExpiresByType image/jpeg "access 1 year"
+ ExpiresByType image/x-icon "access 1 year"
+ ExpiresByType image/svg+xml "access plus 1 month"
+ ExpiresByType audio/ogg "access plus 1 year"
+ ExpiresByType video/mp4 "access plus 1 year"
+ ExpiresByType video/ogg "access plus 1 year"
+ ExpiresByType video/webm "access plus 1 year"
+ ExpiresByType application/atom+xml "access plus 1 hour"
+ ExpiresByType application/rss+xml "access plus 1 hour"
+ ExpiresByType application/pdf "access 1 month"
+ ExpiresByType application/javascript "access 1 month"
+ ExpiresByType text/x-javascript "access 1 month"
+ ExpiresByType text/x-component "access plus 1 month"
+ ExpiresByType application/x-shockwave-flash "access 1 month"
+ ExpiresByType font/opentype "access plus 1 month"
+ ExpiresByType application/vnd.ms-fontobject "access plus 1 month"
+ ExpiresByType application/x-font-ttf "access plus 1 month"
+ ExpiresByType application/font-woff "access plus 1 month"
+ ExpiresByType application/font-woff2 "access plus 1 month"
+ ExpiresDefault "access 1 month"
+
+# END Expires
+
# ----------------------------------------------------------------------
# Gzip compression
# ----------------------------------------------------------------------
+# Start gzip compression
+
+ mod_gzip_on Yes
+ mod_gzip_dechunk Yes
+ mod_gzip_item_include file \.(html?|txt|css|js|php|pl)$
+ mod_gzip_item_include handler ^cgi-script$
+ mod_gzip_item_include mime ^text/.*
+ mod_gzip_item_include mime ^application/x-javascript.*
+ mod_gzip_item_exclude mime ^image/.*
+ mod_gzip_item_exclude rspheader ^Content-Encoding:.*gzip.*
+
+# End gzip compression
+
# Force deflate for mangled headers developer.yahoo.com/blogs/ydn/posts/2010/12/pushing-beyond-gzipping/
@@ -85,13 +152,31 @@
application/x-font-ttf \
application/xhtml+xml \
application/xml \
+ application/x-javascript \
+ application/x-font \
+ application/x-font-truetype \
+ application/x-font-otf \
+ application/x-font-woff \
+ application/x-font-woff2 \
+ application/x-font-opentype \
font/opentype \
- image/svg+xml \
+ font/ttf \
+ font/otf \
+ font/eot \
+ font/woff \
+ font/woff2 \
+ image/svg+xml svg svgz \
image/x-icon \
text/css \
text/html \
text/plain \
text/x-component \
- text/xml
+ text/xml \
+ text/javascript \
+
+ # For Olders Browsers Which Can't Handle Compression
+ BrowserMatch ^Mozilla/4 gzip-only-text/html
+ BrowserMatch ^Mozilla/4\.0[678] no-gzip
+ BrowserMatch \bMSIE !no-gzip !gzip-only-text/html
diff --git a/system/API/ResponseTrait.php b/system/API/ResponseTrait.php
index 8ad5add..c168e37 100644
--- a/system/API/ResponseTrait.php
+++ b/system/API/ResponseTrait.php
@@ -1,4 +1,4 @@
-getNamespace($prefix) returns an array of paths for that namespace
+ foreach ($this->autoloader->getNamespace($prefix) as $namespacePath)
+ {
+ $fullPath = realpath($namespacePath . $path);
+
+ if (! is_dir($fullPath))
+ {
+ continue;
+ }
+
+ $tempFiles = get_filenames($fullPath, true);
+
+ if (! empty($tempFiles))
+ {
+ $files = array_merge($files, $tempFiles);
+ }
+ }
+
+ return $files;
+ }
+
+ //--------------------------------------------------------------------
+
+ /**
* Checks the application folder to see if the file can be found.
* Only for use with filenames that DO NOT include namespacing.
*
diff --git a/system/CLI/BaseCommand.php b/system/CLI/BaseCommand.php
index 5b46d7d..154a028 100644
--- a/system/CLI/BaseCommand.php
+++ b/system/CLI/BaseCommand.php
@@ -1,5 +1,4 @@
-setRule($field, null, $rules);
@@ -289,7 +300,27 @@
//--------------------------------------------------------------------
/**
- * Outputs a string to the cli.
+ * Outputs a string to the CLI without any surrounding newlines.
+ * Useful for showing repeating elements on a single line.
+ *
+ * @param string $text
+ * @param string|null $foreground
+ * @param string|null $background
+ */
+ public static function print(string $text = '', string $foreground = null, string $background = null)
+ {
+ if ($foreground || $background)
+ {
+ $text = static::color($text, $foreground, $background);
+ }
+
+ static::$lastWrite = null;
+
+ fwrite(STDOUT, $text);
+ }
+
+ /**
+ * Outputs a string to the cli on it's own line.
*
* @param string $text The text to output
* @param string $foreground
@@ -302,6 +333,12 @@
$text = static::color($text, $foreground, $background);
}
+ if (static::$lastWrite !== 'write')
+ {
+ $text = PHP_EOL . $text;
+ static::$lastWrite = 'write';
+ }
+
fwrite(STDOUT, $text . PHP_EOL);
}
@@ -380,10 +417,12 @@
/**
* if operating system === windows
+ *
+ * @return boolean
*/
- public static function isWindows()
+ public static function isWindows(): bool
{
- return stripos(PHP_OS, 'WIN') === 0;
+ return stripos(PHP_OS, 'WIN') === 0;
}
//--------------------------------------------------------------------
@@ -436,7 +475,7 @@
*
* @return string The color coded string
*/
- public static function color(string $text, string $foreground, string $background = null, string $format = null)
+ public static function color(string $text, string $foreground, string $background = null, string $format = null): string
{
if (static::isWindows() && ! isset($_SERVER['ANSICON']))
{
@@ -482,8 +521,12 @@
*
* @return integer
*/
- public static function strlen(string $string): int
+ public static function strlen(?string $string): int
{
+ if (is_null($string))
+ {
+ return 0;
+ }
foreach (static::$foreground_colors as $color)
{
$string = strtr($string, ["\033[" . $color . 'm' => '']);
@@ -655,7 +698,7 @@
* Parses the command line it was called from and collects all
* options and valid segments.
*
- * I tried to use getopt but had it fail occassionally to find any
+ * I tried to use getopt but had it fail occasionally to find any
* options but argc has always had our back. We don't have all of the power
* of getopt but this does us just fine.
*/
@@ -706,7 +749,7 @@
*
* @return string
*/
- public static function getURI()
+ public static function getURI(): string
{
return implode('/', static::$segments);
}
@@ -743,7 +786,7 @@
*
* @return array
*/
- public static function getSegments()
+ public static function getSegments(): array
{
return static::$segments;
}
@@ -779,7 +822,7 @@
*
* @return array
*/
- public static function getOptions()
+ public static function getOptions(): array
{
return static::$options;
}
@@ -819,12 +862,12 @@
//--------------------------------------------------------------------
/**
- * Returns a well formated table
+ * Returns a well formatted table
*
* @param array $tbody List of rows
* @param array $thead List of columns
*
- * @return string
+ * @return void
*/
public static function table(array $tbody, array $thead = [])
{
diff --git a/system/CLI/CommandRunner.php b/system/CLI/CommandRunner.php
index 012c037..3e273db 100644
--- a/system/CLI/CommandRunner.php
+++ b/system/CLI/CommandRunner.php
@@ -1,5 +1,5 @@
getItem($key);
- return is_array($data) ? $data['data'] : false;
+ return is_array($data) ? $data['data'] : null;
}
//--------------------------------------------------------------------
diff --git a/system/Cache/Handlers/MemcachedHandler.php b/system/Cache/Handlers/MemcachedHandler.php
index 704a8a7..8950257 100644
--- a/system/Cache/Handlers/MemcachedHandler.php
+++ b/system/Cache/Handlers/MemcachedHandler.php
@@ -1,5 +1,4 @@
-prefix . $key;
- $data = $this->memcached->get($key);
+ if ($this->memcached instanceof \Memcached)
+ {
+ $data = $this->memcached->get($key);
+
+ // check for unmatched key
+ if ($this->memcached->getResultCode()==\Memcached::RES_NOTFOUND)
+ {
+ return null;
+ }
+ }
+ elseif ($this->memcached instanceof \Memcache)
+ {
+ $flags = false;
+ $data = $this->memcached->get($key, $flags);
+
+ // check for unmatched key (i.e. $flags is untouched)
+ if ($flags===false)
+ {
+ return null;
+ }
+ }
return is_array($data) ? $data[0] : $data;
}
diff --git a/system/Cache/Handlers/PredisHandler.php b/system/Cache/Handlers/PredisHandler.php
index f1b1c00..0f643e0 100644
--- a/system/Cache/Handlers/PredisHandler.php
+++ b/system/Cache/Handlers/PredisHandler.php
@@ -1,5 +1,4 @@
-config;
$this->redis = new \Redis();
-
- try
+ if (! $this->redis->connect($config['host'], ($config['host'][0] === '/' ? 0 : $config['port']), $config['timeout']))
{
- if (! $this->redis->connect($config['host'], ($config['host'][0] === '/' ? 0 : $config['port']), $config['timeout'])
- )
- {
- // log_message('error', 'Cache: Redis connection failed. Check your configuration.');
- }
-
- if (isset($config['password']) && ! $this->redis->auth($config['password']))
- {
- log_message('error', 'Cache: Redis authentication failed.');
- }
-
- if (isset($config['database']) && ! $this->redis->select($config['database']))
- {
- log_message('error', 'Cache: Redis select database failed.');
- }
+ log_message('error', 'Cache: Redis connection failed. Check your configuration.');
}
- catch (\RedisException $e)
+
+ if (isset($config['password']) && ! $this->redis->auth($config['password']))
{
- throw new CriticalError('Cache: Redis connection refused (' . $e->getMessage() . ')');
+ log_message('error', 'Cache: Redis authentication failed.');
+ }
+
+ if (isset($config['database']) && ! $this->redis->select($config['database']))
+ {
+ log_message('error', 'Cache: Redis select database failed.');
}
}
@@ -148,7 +143,7 @@
if (! isset($data['__ci_type'], $data['__ci_value']) || $data['__ci_value'] === false)
{
- return false;
+ return null;
}
switch ($data['__ci_type'])
@@ -161,10 +156,10 @@
case 'double': // Yes, 'double' is returned and NOT 'float'
case 'string':
case 'NULL':
- return settype($data['__ci_value'], $data['__ci_type']) ? $data['__ci_value'] : false;
+ return settype($data['__ci_value'], $data['__ci_type']) ? $data['__ci_value'] : null;
case 'resource':
default:
- return false;
+ return null;
}
}
@@ -304,7 +299,7 @@
$value = $this->get($key);
- if ($value !== false)
+ if ($value !== null)
{
$time = time();
return [
@@ -314,7 +309,7 @@
];
}
- return false;
+ return null;
}
//--------------------------------------------------------------------
diff --git a/system/Cache/Handlers/WincacheHandler.php b/system/Cache/Handlers/WincacheHandler.php
index 3040a51..c619f26 100644
--- a/system/Cache/Handlers/WincacheHandler.php
+++ b/system/Cache/Handlers/WincacheHandler.php
@@ -1,4 +1,5 @@
-handleRequest($routes, $cacheConfig, $returnResponse);
}
- catch (Router\RedirectException $e)
+ catch (FilterException $e)
{
$logger = Services::logger();
$logger->info('REDIRECTED ROUTE at ' . $e->getMessage());
@@ -278,7 +281,7 @@
* @param boolean $returnResponse
*
* @return \CodeIgniter\HTTP\RequestInterface|\CodeIgniter\HTTP\Response|\CodeIgniter\HTTP\ResponseInterface|mixed
- * @throws \CodeIgniter\Filters\Exceptions\FilterException
+ * @throws \CodeIgniter\Router\RedirectException
*/
protected function handleRequest(RouteCollectionInterface $routes = null, $cacheConfig, bool $returnResponse = false)
{
@@ -533,7 +536,7 @@
*
* @throws \Exception
*
- * @return boolean
+ * @return boolean|\CodeIgniter\HTTP\ResponseInterface
*/
public function displayCache($config)
{
@@ -564,7 +567,9 @@
$this->response->setBody($output);
return $this->response;
- };
+ }
+
+ return false;
}
//--------------------------------------------------------------------
@@ -574,7 +579,7 @@
*
* @param integer $time
*
- * @return $this
+ * @return void
*/
public static function cache(int $time)
{
@@ -611,7 +616,7 @@
*
* @return array
*/
- public function getPerformanceStats()
+ public function getPerformanceStats(): array
{
return [
'startTime' => $this->startTime,
@@ -682,6 +687,7 @@
* of the config file.
*
* @return string
+ * @throws \CodeIgniter\Router\RedirectException
*/
protected function tryToRouteIt(RouteCollectionInterface $routes = null)
{
@@ -845,7 +851,7 @@
{
if ($override instanceof \Closure)
{
- echo $override();
+ echo $override($e->getMessage());
}
else if (is_array($override))
{
diff --git a/system/Commands/Database/CreateMigration.php b/system/Commands/Database/CreateMigration.php
index 5a3a75b..dcebb41 100644
--- a/system/Commands/Database/CreateMigration.php
+++ b/system/Commands/Database/CreateMigration.php
@@ -1,5 +1,4 @@
- 'The PHP Binary [default: "PHP_BINARY"]',
'-host' => 'The HTTP Host [default: "localhost"]',
'-port' => 'The HTTP Host Port [default: "8080"]',
];
+ /**
+ * Run the server
+ *
+ * @param array $params Parameters
+ *
+ * @return void
+ */
public function run(array $params)
{
// Valid PHP Version?
if (phpversion() < $this->minPHPVersion)
{
- die("You PHP version must be {$this->minPHPVersion} or higher to run CodeIgniter. Current version: " . phpversion());
+ die('Your PHP version must be ' . $this->minPHPVersion .
+ ' or higher to run CodeIgniter. Current version: ' . phpversion());
}
- // Collect any user-supplied options and apply them
+ // Collect any user-supplied options and apply them.
$php = CLI::getOption('php') ?? PHP_BINARY;
$host = CLI::getOption('host') ?? 'localhost';
$port = CLI::getOption('port') ?? '8080';
- // Get the party started
- CLI::write("CodeIgniter development server started on http://{$host}:{$port}", 'green');
+ // Get the party started.
+ CLI::write('CodeIgniter development server started on http://' . $host . ':' . $port, 'green');
CLI::write('Press Control-C to stop.');
- // Set the Front Controller path as Document Root
- $docroot = FCPATH;
+ // Set the Front Controller path as Document Root.
+ $docroot = escapeshellarg(FCPATH);
- // Mimic Apache's mod_rewrite functionality with user settings
- $rewrite = __DIR__ . '/rewrite.php';
+ // Mimic Apache's mod_rewrite functionality with user settings.
+ $rewrite = escapeshellarg(__DIR__ . '/rewrite.php');
// Call PHP's built-in webserver, making sure to set our
// base path to the public folder, and to use the rewrite file
// to ensure our environment is set and it simulates basic mod_rewrite.
- passthru("{$php} -S {$host}:{$port} -t {$docroot} {$rewrite}");
+ passthru($php . ' -S ' . $host . ':' . $port . ' -t ' . $docroot . ' ' . $rewrite);
}
}
diff --git a/system/Commands/Sessions/CreateMigration.php b/system/Commands/Sessions/CreateMigration.php
index 0a9391e..ac8a90b 100644
--- a/system/Commands/Sessions/CreateMigration.php
+++ b/system/Commands/Sessions/CreateMigration.php
@@ -1,4 +1,4 @@
- $to)
{
- $tbody[] = [
- $from,
- $method,
- $to,
- ];
+ // filter for strings, as callbacks aren't displayable
+ if (is_string($to))
+ {
+ $tbody[] = [
+ $from,
+ $method,
+ $to,
+ ];
+ }
}
}
diff --git a/system/Common.php b/system/Common.php
index 4291e60..f0907f7 100644
--- a/system/Common.php
+++ b/system/Common.php
@@ -36,6 +36,7 @@
* @filesource
*/
+use CodeIgniter\HTTP\RedirectResponse;
use CodeIgniter\HTTP\RequestInterface;
use CodeIgniter\HTTP\ResponseInterface;
use Config\Services;
@@ -148,7 +149,7 @@
*
* @return string
*/
- function view(string $name, array $data = [], array $options = [])
+ function view(string $name, array $data = [], array $options = []): string
{
/**
* @var CodeIgniter\View\View $renderer
@@ -182,7 +183,7 @@
*
* @return string
*/
- function view_cell(string $library, $params = null, int $ttl = 0, string $cacheName = null)
+ function view_cell(string $library, $params = null, int $ttl = 0, string $cacheName = null): string
{
return Services::viewcell()
->render($library, $params, $ttl, $cacheName);
@@ -254,8 +255,9 @@
* @param string $encoding
*
* @return string|array
+ * @throws \InvalidArgumentException
*/
- function esc($data, $context = 'html', $encoding = null)
+ function esc($data, string $context = 'html', string $encoding = null)
{
if (is_array($data))
{
@@ -325,7 +327,7 @@
*
* @return \CodeIgniter\Session\Session|mixed|null
*/
- function session($val = null)
+ function session(string $val = null)
{
$session = Services::session();
@@ -431,7 +433,7 @@
*
* @return string
*/
- function lang(string $line, array $args = [], string $locale = null)
+ function lang(string $line, array $args = [], string $locale = null): string
{
return Services::language($locale)
->getLine($line, $args);
@@ -492,7 +494,7 @@
*
* @return boolean
*/
- function is_cli()
+ function is_cli(): bool
{
return (PHP_SAPI === 'cli' || defined('STDIN'));
}
@@ -515,7 +517,7 @@
*
* @return false|string
*/
- function route_to(string $method, ...$params): string
+ function route_to(string $method, ...$params)
{
return Services::routes()->reverseRoute($method, ...$params);
}
@@ -536,7 +538,7 @@
*
* @return string
*/
- function remove_invisible_characters($str, $url_encoded = true)
+ function remove_invisible_characters(string $str, bool $url_encoded = true): string
{
$non_displayables = [];
@@ -573,7 +575,8 @@
* 2. {namespace}/Helpers
* 3. system/Helpers
*
- * @param string|array $filenames
+ * @param string|array $filenames
+ * @throws \CodeIgniter\Files\Exceptions\FileNotFoundException
*/
function helper($filenames)
{
@@ -682,7 +685,7 @@
*
* @return string
*/
- function app_timezone()
+ function app_timezone(): string
{
$config = config(\Config\App::class);
@@ -701,7 +704,7 @@
*
* @return string
*/
- function csrf_token()
+ function csrf_token(): string
{
$config = config(\Config\App::class);
@@ -720,7 +723,7 @@
*
* @return string
*/
- function csrf_hash()
+ function csrf_hash(): string
{
$security = Services::security(null, true);
@@ -735,9 +738,11 @@
/**
* Generates a hidden input field for use within manually generated forms.
*
+ * @param string|null $id
+ *
* @return string
*/
- function csrf_field(string $id = null)
+ function csrf_field(string $id = null): string
{
return '';
}
@@ -820,6 +825,12 @@
*/
function old(string $key, $default = null, $escape = 'html')
{
+ // Ensure the session is loaded
+ if (session_status() === PHP_SESSION_NONE && ENVIRONMENT !== 'testing')
+ {
+ session();
+ }
+
$request = Services::request();
$value = $request->getOldInput($key);
@@ -861,7 +872,7 @@
*
* @return \CodeIgniter\HTTP\RedirectResponse
*/
- function redirect(string $uri = null)
+ function redirect(string $uri = null): RedirectResponse
{
$response = Services::redirectResponse(null, true);
@@ -889,7 +900,7 @@
*
* @return string
*/
- function stringify_attributes($attributes, $js = false): string
+ function stringify_attributes($attributes, bool $js = false): string
{
$atts = '';
@@ -933,7 +944,7 @@
*
* @codeCoverageIgnore Not practical to test, as travis runs on linux
*/
- function is_really_writable($file)
+ function is_really_writable(string $file): bool
{
// If we're on a Unix server with safe_mode off we call is_writable
if (DIRECTORY_SEPARATOR === '/' || ! ini_get('safe_mode'))
@@ -983,7 +994,7 @@
* @return string|null The configuration item or NULL if
* the item doesn't exist
*/
- function slash_item($item)
+ function slash_item(string $item): ?string
{
$config = config(\Config\App::class);
$configItem = $config->{$item};
@@ -1014,7 +1025,7 @@
* terminate script execution if a disabled function is executed.
*
* The above described behavior turned out to be a bug in Suhosin,
- * but even though a fix was commited for 0.9.34 on 2012-02-12,
+ * but even though a fix was committed for 0.9.34 on 2012-02-12,
* that version is yet to be released. This function will therefore
* be just temporary, but would probably be kept for a few years.
*
@@ -1025,7 +1036,7 @@
*
* @codeCoverageIgnore This is too exotic
*/
- function function_usable($function_name)
+ function function_usable(string $function_name): bool
{
static $_suhosin_func_blacklist;
diff --git a/system/ComposerScripts.php b/system/ComposerScripts.php
index fb86d20..d7ebade 100644
--- a/system/ComposerScripts.php
+++ b/system/ComposerScripts.php
@@ -1,4 +1,4 @@
-search('Config/Registrar.php');
+ $locator = \Config\Services::locator();
+ static::$registrars = $locator->search('Config/Registrar.php');
+ static::$didDiscovery = true;
}
$shortName = (new \ReflectionClass($this))->getShortName();
diff --git a/system/Config/BaseService.php b/system/Config/BaseService.php
index 62929ce..aadf04d 100644
--- a/system/Config/BaseService.php
+++ b/system/Config/BaseService.php
@@ -1,5 +1,4 @@
-add('basecontroller(:any)', function()
+{
+ throw \CodeIgniter\Exceptions\PageNotFoundException::forPageNotFound();
+});
+
// Migrations
$routes->cli('migrations/(:segment)/(:segment)', '\CodeIgniter\Commands\MigrationsCommand::$1/$2');
$routes->cli('migrations/(:segment)', '\CodeIgniter\Commands\MigrationsCommand::$1');
$routes->cli('migrations', '\CodeIgniter\Commands\MigrationsCommand::index');
-// CLI Catchall - uses a _remap to
+// CLI Catchall - uses a _remap to call Commands
$routes->cli('ci(:any)', '\CodeIgniter\CLI\CommandRunner::index/$1');
+
+// Prevent access to initController method
+$routes->add('(:any)/initController', function()
+{
+ throw \CodeIgniter\Exceptions\PageNotFoundException::forPageNotFound();
+});
diff --git a/system/Config/Services.php b/system/Config/Services.php
index f22d946..9cba4cb 100644
--- a/system/Config/Services.php
+++ b/system/Config/Services.php
@@ -1,4 +1,4 @@
-request, $this->response);
}
@@ -150,7 +153,7 @@
*
* @param integer $time
*/
- public function cachePage(int $time)
+ protected function cachePage(int $time)
{
CodeIgniter::cache($time);
}
@@ -179,12 +182,12 @@
* A shortcut to performing validation on input data. If validation
* is not successful, a $errors property will be set on this class.
*
- * @param array $rules
- * @param array $messages An array of custom error messages
+ * @param array|string $rules
+ * @param array $messages An array of custom error messages
*
* @return boolean
*/
- public function validate($rules, array $messages = []): bool
+ protected function validate($rules, array $messages = []): bool
{
$this->validator = Services::validation();
diff --git a/system/Database/BaseBuilder.php b/system/Database/BaseBuilder.php
index be8269c..ff67d1f 100644
--- a/system/Database/BaseBuilder.php
+++ b/system/Database/BaseBuilder.php
@@ -1,4 +1,4 @@
-maxMinAvgSum($select, $alias, 'MAX');
}
@@ -332,7 +342,7 @@
*
* @return BaseBuilder
*/
- public function selectMin($select = '', $alias = '')
+ public function selectMin(string $select = '', string $alias = '')
{
return $this->maxMinAvgSum($select, $alias, 'MIN');
}
@@ -349,7 +359,7 @@
*
* @return BaseBuilder
*/
- public function selectAvg($select = '', $alias = '')
+ public function selectAvg(string $select = '', string $alias = '')
{
return $this->maxMinAvgSum($select, $alias, 'AVG');
}
@@ -366,7 +376,7 @@
*
* @return BaseBuilder
*/
- public function selectSum($select = '', $alias = '')
+ public function selectSum(string $select = '', string $alias = '')
{
return $this->maxMinAvgSum($select, $alias, 'SUM');
}
@@ -386,13 +396,19 @@
* @param string $type
*
* @return BaseBuilder
+ * @throws \CodeIgniter\Database\Exceptions\DataException
* @throws \CodeIgniter\Database\Exceptions\DatabaseException
*/
- protected function maxMinAvgSum($select = '', $alias = '', $type = 'MAX')
+ protected function maxMinAvgSum(string $select = '', string $alias = '', string $type = 'MAX')
{
- if (! is_string($select) || $select === '')
+ if ($select === '')
{
- throw new DatabaseException('The query you submitted is not valid.');
+ throw DataException::forEmptyInputGiven('Select');
+ }
+
+ if (strpos($select, ',') !== false)
+ {
+ throw DataException::forInvalidArgument('column name not separated by comma');
}
$type = strtoupper($type);
@@ -424,7 +440,7 @@
*
* @return string
*/
- protected function createAliasFromTable($item)
+ protected function createAliasFromTable(string $item): string
{
if (strpos($item, '.') !== false)
{
@@ -447,9 +463,9 @@
*
* @return BaseBuilder
*/
- public function distinct($val = true)
+ public function distinct(bool $val = true)
{
- $this->QBDistinct = is_bool($val) ? $val : true;
+ $this->QBDistinct = $val;
return $this;
}
@@ -466,7 +482,7 @@
*
* @return BaseBuilder
*/
- public function from($from, $overwrite = false)
+ public function from($from, bool $overwrite = false)
{
if ($overwrite === true)
{
@@ -508,14 +524,14 @@
*
* Generates the JOIN portion of the query
*
- * @param string $table
- * @param string $cond The join condition
- * @param string $type The type of join
- * @param string $escape Whether not to try to escape identifiers
+ * @param string $table
+ * @param string $cond The join condition
+ * @param string $type The type of join
+ * @param boolean $escape Whether not to try to escape identifiers
*
* @return BaseBuilder
*/
- public function join($table, $cond, $type = '', $escape = null)
+ public function join(string $table, string $cond, string $type = '', bool $escape = null)
{
if ($type !== '')
{
@@ -603,7 +619,7 @@
*
* @return BaseBuilder
*/
- public function where($key, $value = null, $escape = null)
+ public function where($key, $value = null, bool $escape = null)
{
return $this->whereHaving('QBWhere', $key, $value, 'AND ', $escape);
}
@@ -622,7 +638,7 @@
*
* @return BaseBuilder
*/
- public function orWhere($key, $value = null, $escape = null)
+ public function orWhere($key, $value = null, bool $escape = null)
{
return $this->whereHaving('QBWhere', $key, $value, 'OR ', $escape);
}
@@ -645,7 +661,7 @@
*
* @return BaseBuilder
*/
- protected function whereHaving($qb_key, $key, $value = null, $type = 'AND ', $escape = null)
+ protected function whereHaving(string $qb_key, $key, $value = null, string $type = 'AND ', bool $escape = null)
{
if (! is_array($key))
{
@@ -661,8 +677,21 @@
if ($v !== null)
{
- $op = $this->getOperator($k);
- $k = trim(str_replace($op, '', $k));
+ $op = $this->getOperator($k, true);
+
+ if (! empty($op))
+ {
+ $k = trim($k);
+
+ end($op);
+
+ $op = trim(current($op));
+
+ if (substr($k, -1 * strlen($op)) === $op)
+ {
+ $k = rtrim(strrev(preg_replace(strrev('/' . $op . '/'), strrev(''), strrev($k), 1)));
+ }
+ }
$bind = $this->setBind($k, $v, $escape);
@@ -674,6 +703,8 @@
{
$k .= $op;
}
+
+ $v = " :$bind:";
}
elseif (! $this->hasOperator($k))
{
@@ -685,8 +716,6 @@
$k = substr($k, 0, $match[0][1]) . ($match[1][0] === '=' ? ' IS NULL' : ' IS NOT NULL');
}
- $v = ! is_null($v) ? " :$bind:" : $v;
-
$this->{$qb_key}[] = [
'condition' => $prefix . $k . $v,
'escape' => $escape,
@@ -710,7 +739,7 @@
*
* @return BaseBuilder
*/
- public function whereIn($key = null, $values = null, $escape = null)
+ public function whereIn(string $key = null, array $values = null, bool $escape = null)
{
return $this->_whereIn($key, $values, false, 'AND ', $escape);
}
@@ -729,7 +758,7 @@
*
* @return BaseBuilder
*/
- public function orWhereIn($key = null, $values = null, $escape = null)
+ public function orWhereIn(string $key = null, array $values = null, bool $escape = null)
{
return $this->_whereIn($key, $values, false, 'OR ', $escape);
}
@@ -748,7 +777,7 @@
*
* @return BaseBuilder
*/
- public function whereNotIn($key = null, $values = null, $escape = null)
+ public function whereNotIn(string $key = null, array $values = null, bool $escape = null)
{
return $this->_whereIn($key, $values, true, 'AND ', $escape);
}
@@ -767,7 +796,7 @@
*
* @return BaseBuilder
*/
- public function orWhereNotIn($key = null, $values = null, $escape = null)
+ public function orWhereNotIn(string $key = null, array $values = null, bool $escape = null)
{
return $this->_whereIn($key, $values, true, 'OR ', $escape);
}
@@ -790,18 +819,13 @@
*
* @return BaseBuilder
*/
- protected function _whereIn($key = null, $values = null, $not = false, $type = 'AND ', $escape = null)
+ protected function _whereIn(string $key = null, array $values = null, bool $not = false, string $type = 'AND ', bool $escape = null)
{
if ($key === null || $values === null)
{
return $this;
}
- if (! is_array($values))
- {
- $values = [$values];
- }
-
is_bool($escape) || $escape = $this->db->protectIdentifiers;
$ok = $key;
@@ -844,7 +868,7 @@
*
* @return BaseBuilder
*/
- public function like($field, $match = '', $side = 'both', $escape = null, $insensitiveSearch = false)
+ public function like($field, string $match = '', string $side = 'both', bool $escape = null, bool $insensitiveSearch = false)
{
return $this->_like($field, $match, 'AND ', $side, '', $escape, $insensitiveSearch);
}
@@ -865,7 +889,7 @@
*
* @return BaseBuilder
*/
- public function notLike($field, $match = '', $side = 'both', $escape = null, $insensitiveSearch = false)
+ public function notLike($field, string $match = '', string $side = 'both', bool $escape = null, bool $insensitiveSearch = false)
{
return $this->_like($field, $match, 'AND ', $side, 'NOT', $escape, $insensitiveSearch);
}
@@ -886,7 +910,7 @@
*
* @return BaseBuilder
*/
- public function orLike($field, $match = '', $side = 'both', $escape = null, $insensitiveSearch = false)
+ public function orLike($field, string $match = '', string $side = 'both', bool $escape = null, bool $insensitiveSearch = false)
{
return $this->_like($field, $match, 'OR ', $side, '', $escape, $insensitiveSearch);
}
@@ -907,7 +931,7 @@
*
* @return BaseBuilder
*/
- public function orNotLike($field, $match = '', $side = 'both', $escape = null, $insensitiveSearch = false)
+ public function orNotLike($field, string $match = '', string $side = 'both', bool $escape = null, bool $insensitiveSearch = false)
{
return $this->_like($field, $match, 'OR ', $side, 'NOT', $escape, $insensitiveSearch);
}
@@ -932,7 +956,7 @@
*
* @return BaseBuilder
*/
- protected function _like($field, $match = '', $type = 'AND ', $side = 'both', $not = '', $escape = null, $insensitiveSearch = false)
+ protected function _like($field, string $match = '', string $type = 'AND ', string $side = 'both', string $not = '', bool $escape = null, bool $insensitiveSearch = false)
{
if (! is_array($field))
{
@@ -992,17 +1016,16 @@
/**
* Platform independent LIKE statement builder.
*
- * @param string|null $prefix
- * @param string $column
- * @param string|null $not
- * @param string $bind
- * @param boolean $insensitiveSearch
+ * @param string $prefix
+ * @param string $column
+ * @param string $not
+ * @param string $bind
+ * @param boolean $insensitiveSearch
*
* @return string $like_statement
*/
public function _like_statement(string $prefix = null, string $column, string $not = null, string $bind, bool $insensitiveSearch = false): string
{
- // TODO fmertins: $column param seems to require a default value? Because $prefix has...
$like_statement = "{$prefix} {$column} {$not} LIKE :{$bind}:";
if ($insensitiveSearch === true)
@@ -1023,7 +1046,7 @@
*
* @return BaseBuilder
*/
- public function groupStart($not = '', $type = 'AND ')
+ public function groupStart(string $not = '', string $type = 'AND ')
{
$type = $this->groupGetType($type);
@@ -1109,11 +1132,11 @@
*
* @return string
*/
- protected function groupGetType($type)
+ protected function groupGetType(string $type): string
{
if ($this->QBWhereGroupStarted)
{
- $type = '';
+ $type = '';
$this->QBWhereGroupStarted = false;
}
@@ -1125,12 +1148,12 @@
/**
* GROUP BY
*
- * @param string $by
- * @param boolean $escape
+ * @param string|array $by
+ * @param boolean $escape
*
* @return BaseBuilder
*/
- public function groupBy($by, $escape = null)
+ public function groupBy($by, bool $escape = null)
{
is_bool($escape) || $escape = $this->db->protectIdentifiers;
@@ -1164,13 +1187,13 @@
*
* Separates multiple calls with 'AND'.
*
- * @param string $key
- * @param string $value
- * @param boolean $escape
+ * @param string|array $key
+ * @param mixed $value
+ * @param boolean $escape
*
* @return BaseBuilder
*/
- public function having($key, $value = null, $escape = null)
+ public function having($key, $value = null, bool $escape = null)
{
return $this->whereHaving('QBHaving', $key, $value, 'AND ', $escape);
}
@@ -1182,13 +1205,13 @@
*
* Separates multiple calls with 'OR'.
*
- * @param string $key
- * @param string $value
- * @param boolean $escape
+ * @param string|array $key
+ * @param mixed $value
+ * @param boolean $escape
*
* @return BaseBuilder
*/
- public function orHaving($key, $value = null, $escape = null)
+ public function orHaving($key, $value = null, bool $escape = null)
{
return $this->whereHaving('QBHaving', $key, $value, 'OR ', $escape);
}
@@ -1198,13 +1221,13 @@
/**
* ORDER BY
*
- * @param string $orderby
+ * @param string $orderBy
* @param string $direction ASC, DESC or RANDOM
* @param boolean $escape
*
* @return BaseBuilder
*/
- public function orderBy($orderby, $direction = '', $escape = null)
+ public function orderBy(string $orderBy, string $direction = '', bool $escape = null)
{
$direction = strtoupper(trim($direction));
@@ -1213,9 +1236,9 @@
$direction = '';
// Do we have a seed value?
- $orderby = ctype_digit((string) $orderby) ? sprintf($this->randomKeyword[1], $orderby) : $this->randomKeyword[0];
+ $orderBy = ctype_digit((string) $orderBy) ? sprintf($this->randomKeyword[1], $orderBy) : $this->randomKeyword[0];
}
- elseif (empty($orderby))
+ elseif (empty($orderBy))
{
return $this;
}
@@ -1229,7 +1252,7 @@
if ($escape === false)
{
$qb_orderby[] = [
- 'field' => $orderby,
+ 'field' => $orderBy,
'direction' => $direction,
'escape' => false,
];
@@ -1237,18 +1260,21 @@
else
{
$qb_orderby = [];
- foreach (explode(',', $orderby) as $field)
+ foreach (explode(',', $orderBy) as $field)
{
- $qb_orderby[] = ($direction === '' &&
- preg_match('/\s+(ASC|DESC)$/i', rtrim($field), $match, PREG_OFFSET_CAPTURE)) ? [
- 'field' => ltrim(substr($field, 0, $match[0][1])),
- 'direction' => ' ' . $match[1][0],
- 'escape' => true,
- ] : [
- 'field' => trim($field),
- 'direction' => $direction,
- 'escape' => true,
- ];
+ $qb_orderby[] = ($direction === '' && preg_match('/\s+(ASC|DESC)$/i', rtrim($field), $match, PREG_OFFSET_CAPTURE))
+ ?
+ [
+ 'field' => ltrim(substr($field, 0, $match[0][1])),
+ 'direction' => ' ' . $match[1][0],
+ 'escape' => true,
+ ]
+ :
+ [
+ 'field' => trim($field),
+ 'direction' => $direction,
+ 'escape' => true,
+ ];
}
}
@@ -1291,7 +1317,7 @@
*
* @return BaseBuilder
*/
- public function offset($offset)
+ public function offset(int $offset)
{
if (! empty($offset))
{
@@ -1312,7 +1338,7 @@
*
* @return string
*/
- protected function _limit($sql)
+ protected function _limit(string $sql): string
{
return $sql . ' LIMIT ' . ($this->QBOffset ? $this->QBOffset . ', ' : '') . $this->QBLimit;
}
@@ -1330,7 +1356,7 @@
*
* @return BaseBuilder
*/
- public function set($key, $value = '', $escape = null)
+ public function set($key, string $value = '', bool $escape = null)
{
$key = $this->objectToArray($key);
@@ -1345,7 +1371,7 @@
{
if ($escape)
{
- $bind = $this->setBind($k, $v, $escape);
+ $bind = $this->setBind($k, $v, $escape);
$this->QBSet[$this->db->protectIdentifiers($k, false, $escape)] = ":$bind:";
}
else
@@ -1367,7 +1393,7 @@
*
* @return array
*/
- public function getSetData(bool $clean = false)
+ public function getSetData(bool $clean = false): array
{
$data = $this->QBSet;
@@ -1390,7 +1416,7 @@
*
* @return string
*/
- public function getCompiledSelect($reset = true)
+ public function getCompiledSelect(bool $reset = true): string
{
$select = $this->compileSelect();
@@ -1410,7 +1436,7 @@
*
* @param string $sql
*
- * @return mixed|string
+ * @return string
*/
protected function compileFinalQuery(string $sql): string
{
@@ -1438,7 +1464,7 @@
*
* @return ResultInterface
*/
- public function get(int $limit = null, int $offset = 0, $returnSQL = false, $reset = true)
+ public function get(int $limit = null, int $offset = 0, bool $returnSQL = false, bool $reset = true)
{
if (! is_null($limit))
{
@@ -1471,9 +1497,9 @@
* @param boolean $reset Are we want to clear query builder values?
* @param boolean $test Are we running automated tests?
*
- * @return integer
+ * @return integer|string when $test = true
*/
- public function countAll($reset = true, $test = false)
+ public function countAll(bool $reset = true, bool $test = false)
{
$table = $this->QBFrom[0];
@@ -1512,22 +1538,25 @@
* @param boolean $reset
* @param boolean $test The reset clause
*
- * @return integer
+ * @return integer|string when $test = true
*/
- public function countAllResults($reset = true, $test = false)
+ public function countAllResults(bool $reset = true, bool $test = false)
{
// ORDER BY usage is often problematic here (most notably
// on Microsoft SQL Server) and ultimately unnecessary
// for selecting COUNT(*) ...
- $orderby = [];
+ $orderBy = [];
if (! empty($this->QBOrderBy))
{
- $orderby = $this->QBOrderBy;
+ $orderBy = $this->QBOrderBy;
$this->QBOrderBy = null;
}
- $sql = ($this->QBDistinct === true) ? $this->countString . $this->db->protectIdentifiers('numrows') . "\nFROM (\n" .
- $this->compileSelect() . "\n) CI_count_all_results" : $this->compileSelect($this->countString . $this->db->protectIdentifiers('numrows'));
+ $sql = ($this->QBDistinct === true)
+ ?
+ $this->countString . $this->db->protectIdentifiers('numrows') . "\nFROM (\n" . $this->compileSelect() . "\n) CI_count_all_results"
+ :
+ $this->compileSelect($this->countString . $this->db->protectIdentifiers('numrows'));
if ($test)
{
@@ -1543,7 +1572,7 @@
// If we've previously reset the QBOrderBy values, get them back
elseif (! isset($this->QBOrderBy))
{
- $this->QBOrderBy = $orderby ?? [];
+ $this->QBOrderBy = $orderBy ?? [];
}
$row = (! $result instanceof ResultInterface)
@@ -1565,13 +1594,13 @@
*
* Allows the where clause, limit and offset to be added directly
*
- * @param string $where
- * @param integer $limit
- * @param integer $offset
+ * @param string|array $where
+ * @param integer $limit
+ * @param integer $offset
*
* @return ResultInterface
*/
- public function getWhere($where = null, $limit = null, $offset = null)
+ public function getWhere($where = null, int $limit = null, int $offset = null)
{
if ($where !== null)
{
@@ -1605,7 +1634,7 @@
* @return integer Number of rows inserted or FALSE on failure
* @throws DatabaseException
*/
- public function insertBatch($set = null, $escape = null, $batchSize = 100, $testing = false)
+ public function insertBatch(array $set = null, bool $escape = null, int $batchSize = 100, bool $testing = false)
{
if ($set === null)
{
@@ -1674,7 +1703,7 @@
*
* @return string
*/
- protected function _insertBatch($table, $keys, $values)
+ protected function _insertBatch(string $table, array $keys, array $values): string
{
return 'INSERT INTO ' . $table . ' (' . implode(', ', $keys) . ') VALUES ' . implode(', ', $values);
}
@@ -1688,9 +1717,9 @@
* @param string $value
* @param boolean $escape
*
- * @return BaseBuilder
+ * @return BaseBuilder|null
*/
- public function setInsertBatch($key, $value = '', $escape = null)
+ public function setInsertBatch($key, string $value = '', bool $escape = null)
{
$key = $this->batchObjectToArray($key);
@@ -1712,7 +1741,7 @@
// batch function above returns an error on an empty array
$this->QBSet[] = [];
- return;
+ return null;
}
ksort($row); // puts $row in the same order as our keys
@@ -1747,7 +1776,7 @@
*
* @return string
*/
- public function getCompiledInsert($reset = true)
+ public function getCompiledInsert(bool $reset = true): string
{
if ($this->validateInsert() === false)
{
@@ -1781,7 +1810,7 @@
*
* @return BaseResult|Query|false
*/
- public function insert($set = null, $escape = null, $test = false)
+ public function insert(array $set = null, bool $escape = null, bool $test = false)
{
if ($set !== null)
{
@@ -1810,6 +1839,8 @@
return $result;
}
+
+ return false;
}
//--------------------------------------------------------------------
@@ -1821,10 +1852,10 @@
* validate that the there data is actually being set and that table
* has been chosen to be inserted into.
*
- * @return string
+ * @return bool
* @throws DatabaseException
*/
- protected function validateInsert()
+ protected function validateInsert(): bool
{
if (empty($this->QBSet))
{
@@ -1852,7 +1883,7 @@
*
* @return string
*/
- protected function _insert($table, array $keys, array $unescapedKeys)
+ protected function _insert(string $table, array $keys, array $unescapedKeys): string
{
return 'INSERT INTO ' . $table . ' (' . implode(', ', $keys) . ') VALUES (' . implode(', ', $unescapedKeys) . ')';
}
@@ -1870,7 +1901,7 @@
* @return BaseResult|Query|string|false
* @throws DatabaseException
*/
- public function replace($set = null, $returnSQL = false)
+ public function replace(array $set = null, bool $returnSQL = false)
{
if ($set !== null)
{
@@ -1908,7 +1939,7 @@
*
* @return string
*/
- protected function _replace($table, $keys, $values)
+ protected function _replace(string $table, array $keys, array $values): string
{
return 'REPLACE INTO ' . $table . ' (' . implode(', ', $keys) . ') VALUES (' . implode(', ', $values) . ')';
}
@@ -1925,7 +1956,7 @@
*
* @return string
*/
- protected function _fromTables()
+ protected function _fromTables(): string
{
return implode(', ', $this->QBFrom);
}
@@ -1941,7 +1972,7 @@
*
* @return string
*/
- public function getCompiledUpdate($reset = true)
+ public function getCompiledUpdate(bool $reset = true): string
{
if ($this->validateUpdate() === false)
{
@@ -1972,7 +2003,7 @@
*
* @return boolean TRUE on success, FALSE on failure
*/
- public function update($set = null, $where = null, int $limit = null, $test = false)
+ public function update(array $set = null, $where = null, int $limit = null, bool $test = false): bool
{
if ($set !== null)
{
@@ -2031,8 +2062,10 @@
*
* @return string
*/
- protected function _update($table, $values)
+ protected function _update(string $table, array $values): string
{
+ $valstr = [];
+
foreach ($values as $key => $val)
{
$valstr[] = $key . ' = ' . $val;
@@ -2056,7 +2089,7 @@
* @return boolean
* @throws \CodeIgniter\Database\Exceptions\DatabaseException
*/
- protected function validateUpdate()
+ protected function validateUpdate(): bool
{
if (empty($this->QBSet))
{
@@ -2086,7 +2119,7 @@
* @return mixed Number of rows affected, SQL string, or FALSE on failure
* @throws \CodeIgniter\Database\Exceptions\DatabaseException
*/
- public function updateBatch($set = null, $index = null, $batchSize = 100, $returnSQL = false)
+ public function updateBatch(array $set = null, string $index = null, int $batchSize = 100, bool $returnSQL = false)
{
if ($index === null)
{
@@ -2127,7 +2160,7 @@
// Batch this baby
$affected_rows = 0;
- $savedSQL = [];
+ $savedSQL = [];
for ($i = 0, $total = count($this->QBSet); $i < $total; $i += $batchSize)
{
$sql = $this->_updateBatch($table, array_slice($this->QBSet, $i, $batchSize), $this->db->protectIdentifiers($index)
@@ -2164,9 +2197,10 @@
*
* @return string
*/
- protected function _updateBatch($table, $values, $index)
+ protected function _updateBatch(string $table, array $values, string $index): string
{
$ids = [];
+ $final = [];
foreach ($values as $key => $val)
{
$ids[] = $val[$index];
@@ -2198,20 +2232,20 @@
/**
* The "setUpdateBatch" function. Allows key/value pairs to be set for batch updating
*
- * @param array $key
- * @param string $index
- * @param boolean $escape
+ * @param array|object $key
+ * @param string $index
+ * @param boolean $escape
*
- * @return BaseBuilder
+ * @return BaseBuilder|null
* @throws \CodeIgniter\Database\Exceptions\DatabaseException
*/
- public function setUpdateBatch($key, $index = '', $escape = null)
+ public function setUpdateBatch($key, string $index = '', bool $escape = null)
{
$key = $this->batchObjectToArray($key);
if (! is_array($key))
{
- return;
+ return null;
}
is_bool($escape) || $escape = $this->db->protectIdentifiers;
@@ -2253,7 +2287,7 @@
* @param boolean $test
* @return boolean TRUE on success, FALSE on failure
*/
- public function emptyTable($test = false)
+ public function emptyTable(bool $test = false)
{
$table = $this->QBFrom[0];
@@ -2282,7 +2316,7 @@
*
* @return boolean TRUE on success, FALSE on failure
*/
- public function truncate($test = false)
+ public function truncate(bool $test = false)
{
$table = $this->QBFrom[0];
@@ -2312,7 +2346,7 @@
*
* @return string
*/
- protected function _truncate($table)
+ protected function _truncate(string $table): string
{
return 'TRUNCATE ' . $table;
}
@@ -2328,13 +2362,11 @@
*
* @return string
*/
- public function getCompiledDelete($reset = true)
+ public function getCompiledDelete(bool $reset = true): string
{
$table = $this->QBFrom[0];
- $this->returnDeleteSQL = true;
- $sql = $this->delete($table, '', null, $reset);
- $this->returnDeleteSQL = false;
+ $sql = $this->delete($table, '', $reset, true);
return $this->compileFinalQuery($sql);
}
@@ -2347,14 +2379,14 @@
* Compiles a delete string and runs the query
*
* @param mixed $where The where clause
- * @param mixed $limit The limit clause
+ * @param integer $limit The limit clause
* @param boolean $reset_data
* @param boolean $returnSQL
*
* @return mixed
* @throws \CodeIgniter\Database\Exceptions\DatabaseException
*/
- public function delete($where = '', $limit = null, $reset_data = true, $returnSQL = false)
+ public function delete($where = '', int $limit = null, bool $reset_data = true, bool $returnSQL = false)
{
$table = $this->db->protectIdentifiers($this->QBFrom[0], true, null, false);
@@ -2447,7 +2479,7 @@
*
* @return string
*/
- protected function _delete($table)
+ protected function _delete(string $table): string
{
return 'DELETE FROM ' . $table . $this->compileWhereHaving('QBWhere')
. ($this->QBLimit ? ' LIMIT ' . $this->QBLimit : '');
@@ -2460,9 +2492,9 @@
*
* Used to track SQL statements written with aliased tables.
*
- * @param string $table The table to inspect
+ * @param string|array $table The table to inspect
*
- * @return string
+ * @return string|void
*/
protected function trackAliases($table)
{
@@ -2472,8 +2504,6 @@
{
$this->trackAliases($t);
}
-
- return;
}
// Does the string contain a comma? If so, we need to separate
@@ -2505,11 +2535,11 @@
* Generates a query string based on which functions were used.
* Should not be called directly.
*
- * @param boolean $select_override
+ * @param mixed $select_override
*
* @return string
*/
- protected function compileSelect($select_override = false)
+ protected function compileSelect($select_override = false): string
{
// Write the "select" portion of the query
if ($select_override !== false)
@@ -2579,7 +2609,7 @@
*
* @return string SQL statement
*/
- protected function compileWhereHaving($qb_key)
+ protected function compileWhereHaving(string $qb_key): string
{
if (! empty($this->$qb_key))
{
@@ -2621,7 +2651,6 @@
if (! empty($matches[4]))
{
- // $this->isLiteral($matches[4]) OR $matches[4] = $this->db->protectIdentifiers(trim($matches[4]));
$matches[4] = ' ' . $matches[4];
}
@@ -2646,13 +2675,13 @@
*
* Escapes identifiers in GROUP BY statements at execution time.
*
- * Required so that aliases are tracked properly, regardless of wether
+ * Required so that aliases are tracked properly, regardless of whether
* groupBy() is called prior to from(), join() and prefixTable is added
* only if needed.
*
* @return string SQL statement
*/
- protected function compileGroupBy()
+ protected function compileGroupBy(): string
{
if (! empty($this->QBGroupBy))
{
@@ -2681,13 +2710,13 @@
*
* Escapes identifiers in ORDER BY statements at execution time.
*
- * Required so that aliases are tracked properly, regardless of wether
+ * Required so that aliases are tracked properly, regardless of whether
* orderBy() is called prior to from(), join() and prefixTable is added
* only if needed.
*
* @return string SQL statement
*/
- protected function compileOrderBy()
+ protected function compileOrderBy(): string
{
if (is_array($this->QBOrderBy) && ! empty($this->QBOrderBy))
{
@@ -2718,9 +2747,9 @@
*
* Takes an object as input and converts the class variables to array key/vals
*
- * @param object $object
+ * @param mixed $object
*
- * @return array
+ * @return mixed
*/
protected function objectToArray($object)
{
@@ -2749,9 +2778,9 @@
*
* Takes an object as input and converts the class variables to array key/vals
*
- * @param object $object
+ * @param mixed $object
*
- * @return array
+ * @return mixed
*/
protected function batchObjectToArray($object)
{
@@ -2791,7 +2820,7 @@
*
* @return boolean
*/
- protected function isLiteral($str)
+ protected function isLiteral(string $str): bool
{
$str = trim($str);
@@ -2835,8 +2864,10 @@
* Resets the query builder values. Called by the get() function
*
* @param array $qb_reset_items An array of fields to reset
+ *
+ * @return void
*/
- protected function resetRun($qb_reset_items)
+ protected function resetRun(array $qb_reset_items)
{
foreach ($qb_reset_items as $item => $default_value)
{
@@ -2898,7 +2929,7 @@
*
* @return boolean
*/
- protected function hasOperator($str)
+ protected function hasOperator(string $str): bool
{
return (bool) preg_match('/(<|>|!|=|\sIS NULL|\sIS NOT NULL|\sEXISTS|\sBETWEEN|\sLIKE|\sIN\s*\(|\s)/i', trim($str));
}
@@ -2908,11 +2939,12 @@
/**
* Returns the SQL string operator
*
- * @param string $str
+ * @param string $str
+ * @param boolean $list
*
- * @return string
+ * @return mixed
*/
- protected function getOperator($str)
+ protected function getOperator(string $str, bool $list = false)
{
static $_operators;
@@ -2935,7 +2967,7 @@
];
}
- return preg_match('/' . implode('|', $_operators) . '/i', $str, $match) ? $match[0] : false;
+ return preg_match_all('/' . implode('|', $_operators) . '/i', $str, $match) ? ($list ? $match[0] : $match[0][count($match[0]) - 1]) : false;
}
// --------------------------------------------------------------------
@@ -2947,12 +2979,12 @@
* arrays instead, so lets take advantage of that here.
*
* @param string $key
- * @param null $value
+ * @param mixed $value
* @param boolean $escape
*
* @return string
*/
- protected function setBind(string $key, $value = null, bool $escape = true)
+ protected function setBind(string $key, $value = null, bool $escape = true): string
{
if (! array_key_exists($key, $this->binds))
{
diff --git a/system/Database/BaseConnection.php b/system/Database/BaseConnection.php
index 477574d..7e16330 100644
--- a/system/Database/BaseConnection.php
+++ b/system/Database/BaseConnection.php
@@ -1,4 +1,4 @@
-pretend)
{
- // Let others do somethign with this query
+ // Let others do something with this query
Events::trigger('DBQuery', $query);
}
@@ -1093,10 +1095,10 @@
// This is basically a bug fix for queries that use MAX, MIN, etc.
// If a parenthesis is found we know that we do not need to
// escape the data or add a prefix. There's probably a more graceful
- // way to deal with this, but I'm not thinking of it -- Rick
+ // way to deal with this, but I'm not thinking of it
//
// Added exception for single quotes as well, we don't want to alter
- // literal strings. -- Narf
+ // literal strings.
if (strcspn($item, "()'") !== strlen($item))
{
return $item;
diff --git a/system/Database/BasePreparedQuery.php b/system/Database/BasePreparedQuery.php
index 9c9681f..887f906 100644
--- a/system/Database/BasePreparedQuery.php
+++ b/system/Database/BasePreparedQuery.php
@@ -1,5 +1,4 @@
-createDatabaseStr === false)
{
@@ -242,7 +244,7 @@
* @return boolean
* @throws \CodeIgniter\Database\Exceptions\DatabaseException
*/
- public function dropDatabase($db_name)
+ public function dropDatabase(string $db_name): bool
{
if ($this->dropDatabaseStr === false)
{
@@ -392,7 +394,7 @@
* @return \CodeIgniter\Database\Forge
* @throws \CodeIgniter\Database\Exceptions\DatabaseException
*/
- public function addForeignKey($fieldName = '', $tableName = '', $tableField = '', $onUpdate = false, $onDelete = false)
+ public function addForeignKey(string $fieldName = '', string $tableName = '', string $tableField = '', bool $onUpdate = false, bool $onDelete = false)
{
if (! isset($this->fields[$fieldName]))
{
@@ -420,7 +422,7 @@
* @return boolean|\CodeIgniter\Database\BaseResult|\CodeIgniter\Database\Query|false|mixed
* @throws \CodeIgniter\Database\Exceptions\DatabaseException
*/
- public function dropForeignKey($table, $foreign_name)
+ public function dropForeignKey(string $table, string $foreign_name)
{
$sql = sprintf($this->dropConstraintStr, $this->db->escapeIdentifiers($this->db->DBPrefix . $table),
$this->db->escapeIdentifiers($this->db->DBPrefix . $foreign_name));
@@ -447,10 +449,10 @@
* @param boolean $if_not_exists Whether to add IF NOT EXISTS condition
* @param array $attributes Associative array of table attributes
*
- * @return boolean
+ * @return mixed
* @throws \CodeIgniter\Database\Exceptions\DatabaseException
*/
- public function createTable($table, $if_not_exists = false, array $attributes = [])
+ public function createTable(string $table, bool $if_not_exists = false, array $attributes = [])
{
if ($table === '')
{
@@ -482,7 +484,7 @@
if (($result = $this->db->query($sql)) !== false)
{
- empty($this->db->dataCache['table_names']) || $this->db->dataCache['table_names'][] = $table;
+ empty($this->db->dataCache['table_names']) || ($this->db->dataCache['table_names'][] = $table);
// Most databases don't support creating indexes from within the CREATE TABLE statement
if (! empty($this->keys))
@@ -510,7 +512,7 @@
*
* @return mixed
*/
- protected function _createTable($table, $if_not_exists, $attributes)
+ protected function _createTable(string $table, bool $if_not_exists, array $attributes)
{
// For any platforms that don't support Create If Not Exists...
if ($if_not_exists === true && $this->createTableIfStr === false)
@@ -560,7 +562,7 @@
*
* @return string
*/
- protected function _createTableAttributes($attributes)
+ protected function _createTableAttributes(array $attributes): string
{
$sql = '';
@@ -587,7 +589,7 @@
* @return mixed
* @throws \CodeIgniter\Database\Exceptions\DatabaseException
*/
- public function dropTable($table_name, $if_exists = false, $cascade = false)
+ public function dropTable(string $table_name, bool $if_exists = false, bool $cascade = false)
{
if ($table_name === '')
{
@@ -639,7 +641,7 @@
*
* @return string
*/
- protected function _dropTable($table, $if_exists, $cascade)
+ protected function _dropTable(string $table, bool $if_exists, bool $cascade): string
{
$sql = 'DROP TABLE';
@@ -674,7 +676,7 @@
* @return mixed
* @throws \CodeIgniter\Database\Exceptions\DatabaseException
*/
- public function renameTable($table_name, $new_table_name)
+ public function renameTable(string $table_name, string $new_table_name)
{
if ($table_name === '' || $new_table_name === '')
{
@@ -713,13 +715,13 @@
/**
* Column Add
*
- * @param string $table Table name
- * @param array $field Column definition
+ * @param string $table Table name
+ * @param string|array $field Column definition
*
* @return boolean
* @throws \CodeIgniter\Database\Exceptions\DatabaseException
*/
- public function addColumn($table, $field)
+ public function addColumn(string $table, $field): bool
{
// Work-around for literal column definitions
is_array($field) || $field = [$field];
@@ -760,10 +762,10 @@
* @param string $table Table name
* @param string $column_name Column name
*
- * @return boolean
+ * @return mixed
* @throws \CodeIgniter\Database\Exceptions\DatabaseException
*/
- public function dropColumn($table, $column_name)
+ public function dropColumn(string $table, string $column_name)
{
$sql = $this->_alterTable('DROP', $this->db->DBPrefix . $table, $column_name);
if ($sql === false)
@@ -784,13 +786,13 @@
/**
* Column Modify
*
- * @param string $table Table name
- * @param string $field Column definition
+ * @param string $table Table name
+ * @param string|array $field Column definition
*
* @return boolean
* @throws \CodeIgniter\Database\Exceptions\DatabaseException
*/
- public function modifyColumn($table, $field)
+ public function modifyColumn(string $table, $field): bool
{
// Work-around for literal column definitions
is_array($field) || $field = [$field];
@@ -842,7 +844,7 @@
*
* @return string|string[]
*/
- protected function _alterTable($alter_type, $table, $field)
+ protected function _alterTable(string $alter_type, string $table, $field)
{
$sql = 'ALTER TABLE ' . $this->db->escapeIdentifiers($table) . ' ';
@@ -873,7 +875,7 @@
*
* @return array
*/
- protected function _processFields($create_table = false)
+ protected function _processFields(bool $create_table = false): array
{
$fields = [];
@@ -973,7 +975,7 @@
*
* @return string
*/
- protected function _processColumn($field)
+ protected function _processColumn(array $field): string
{
return $this->db->escapeIdentifiers($field['name'])
. ' ' . $field['type'] . $field['length']
@@ -995,7 +997,7 @@
*
* @return void
*/
- protected function _attributeType(&$attributes)
+ protected function _attributeType(array &$attributes)
{
// Usually overridden by drivers
}
@@ -1017,9 +1019,9 @@
* @param array &$attributes
* @param array &$field
*
- * @return void
+ * @return null|void
*/
- protected function _attributeUnsigned(&$attributes, &$field)
+ protected function _attributeUnsigned(array &$attributes, array &$field)
{
if (empty($attributes['UNSIGNED']) || $attributes['UNSIGNED'] !== true)
{
@@ -1061,9 +1063,9 @@
* @param array &$attributes
* @param array &$field
*
- * @return void
+ * @return null|void
*/
- protected function _attributeDefault(&$attributes, &$field)
+ protected function _attributeDefault(array &$attributes, array &$field)
{
if ($this->default === false)
{
@@ -1097,7 +1099,7 @@
*
* @return void
*/
- protected function _attributeUnique(&$attributes, &$field)
+ protected function _attributeUnique(array &$attributes, array &$field)
{
if (! empty($attributes['UNIQUE']) && $attributes['UNIQUE'] === true)
{
@@ -1115,7 +1117,7 @@
*
* @return void
*/
- protected function _attributeAutoIncrement(&$attributes, &$field)
+ protected function _attributeAutoIncrement(array &$attributes, array &$field)
{
if (! empty($attributes['AUTO_INCREMENT']) && $attributes['AUTO_INCREMENT'] === true
&& stripos($field['type'], 'int') !== false
@@ -1134,7 +1136,7 @@
*
* @return string
*/
- protected function _processPrimaryKeys($table)
+ protected function _processPrimaryKeys(string $table): string
{
$sql = '';
@@ -1164,7 +1166,7 @@
*
* @return array
*/
- protected function _processIndexes($table)
+ protected function _processIndexes(string $table)
{
$sqls = [];
@@ -1209,7 +1211,7 @@
*
* @return string
*/
- protected function _processForeignKeys($table)
+ protected function _processForeignKeys(string $table): string
{
$sql = '';
diff --git a/system/Database/Migration.php b/system/Database/Migration.php
index 3efef03..eb27199 100644
--- a/system/Database/Migration.php
+++ b/system/Database/Migration.php
@@ -1,4 +1,4 @@
-checkMigrations($migrations, $method, $targetVersion);
// loop migration for each namespace (module)
+
+ $migrationStatus = false;
foreach ($migrations as $version => $migration)
{
// Only include migrations within the scoop
- if (($method === 'up' && $version > $currentVersion && $version <= $targetVersion) || ( $method === 'down' && $version <= $currentVersion && $version > $targetVersion)
- )
+ if (($method === 'up' && $version > $currentVersion && $version <= $targetVersion) || ( $method === 'down' && $version <= $currentVersion && $version > $targetVersion))
{
+ $migrationStatus = false;
include_once $migration->path;
// Get namespaced class name
$class = $this->namespace . '\Database\Migrations\Migration_' . ($migration->name);
@@ -288,10 +291,12 @@
{
$this->removeHistory($migration->version);
}
+
+ $migrationStatus = true;
}
}
- return true;
+ return ($migrationStatus) ? $targetVersion : false;
}
//--------------------------------------------------------------------
@@ -347,11 +352,10 @@
$this->setGroup($group);
}
- // Get all namespaces form PSR4 paths.
- $config = config('Autoload');
- $namespaces = $config->psr4;
+ // Get all namespaces from the autoloader
+ $namespaces = Services::autoloader()->getNamespace();
- foreach ($namespaces as $namespace => $path)
+ foreach ($namespaces as $namespace => $paths)
{
$this->setNamespace($namespace);
$migrations = $this->findMigrations();
@@ -401,36 +405,30 @@
//--------------------------------------------------------------------
/**
- * Retrieves list of available migration scripts
+ * Retrieves list of available migration scripts for one namespace
*
* @return array list of migrations as $version for one namespace
*/
public function findMigrations()
{
$migrations = [];
- helper('filesystem');
// If $this->path contains a valid directory use it.
if (! empty($this->path))
{
- $dir = rtrim($this->path, DIRECTORY_SEPARATOR) . '/';
+ helper('filesystem');
+ $dir = rtrim($this->path, DIRECTORY_SEPARATOR) . '/';
+ $files = get_filenames($dir, true);
}
- // Otherwise, get namespace location form PSR4 paths
- // and add Database/Migrations for a standard loation.
+ // Otherwise use FileLocator to search files in the subdirectory of the namespace
else
{
- $config = config('Autoload');
-
- $location = $config->psr4[$this->namespace];
-
- // Setting migration directories.
- $dir = rtrim($location, DIRECTORY_SEPARATOR) . '/Database/Migrations/';
+ $locator = Services::locator(true);
+ $files = $locator->listNamespaceFiles($this->namespace, '/Database/Migrations/');
}
// Load all *_*.php files in the migrations path
// We can't use glob if we want it to be testable....
- $files = get_filenames($dir, true);
-
foreach ($files as $file)
{
if (substr($file, -4) !== '.php')
@@ -695,7 +693,7 @@
/**
* Retrieves current schema version
*
- * @return string Current migration version
+ * @return array Current migration version
*/
public function getCliMessages()
{
diff --git a/system/Database/MySQLi/Builder.php b/system/Database/MySQLi/Builder.php
index 07cd6c4..264171e 100644
--- a/system/Database/MySQLi/Builder.php
+++ b/system/Database/MySQLi/Builder.php
@@ -1,4 +1,4 @@
-mysqli->client_info, '5.6', '>='))
{
- $this->mysqli->options(MYSQLI_CLIENT_SSL_DONT_VERIFY_SERVER_CERT, true);
+ $client_flags += MYSQLI_CLIENT_SSL_DONT_VERIFY_SERVER_CERT;
}
}
- $client_flags |= MYSQLI_CLIENT_SSL;
+ $client_flags += MYSQLI_CLIENT_SSL;
$this->mysqli->ssl_set(
$ssl['key'] ?? null, $ssl['cert'] ?? null, $ssl['ca'] ?? null,
$ssl['capath'] ?? null, $ssl['cipher'] ?? null
diff --git a/system/Database/MySQLi/Forge.php b/system/Database/MySQLi/Forge.php
index bd5be18..188625e 100644
--- a/system/Database/MySQLi/Forge.php
+++ b/system/Database/MySQLi/Forge.php
@@ -1,4 +1,4 @@
-db->escapeIdentifiers($field['after']) : '';
@@ -229,7 +231,7 @@
* @param string $table (ignored)
* @return string
*/
- protected function _processIndexes($table)
+ protected function _processIndexes(string $table): string
{
$sql = '';
@@ -257,7 +259,7 @@
$unique = in_array($i, $this->uniqueKeys) ? 'UNIQUE ' : '';
$sql .= ",\n\t{$unique}KEY " . $this->db->escapeIdentifiers(implode('_', $this->keys[$i]))
- . ' (' . implode(', ', $this->db->escapeIdentifiers($this->keys[$i])) . ')';
+ . ' (' . implode(', ', $this->db->escapeIdentifiers($this->keys[$i])) . ')';
}
$this->keys = [];
diff --git a/system/Database/MySQLi/PreparedQuery.php b/system/Database/MySQLi/PreparedQuery.php
index d17e5b5..668df92 100644
--- a/system/Database/MySQLi/PreparedQuery.php
+++ b/system/Database/MySQLi/PreparedQuery.php
@@ -1,4 +1,4 @@
- 1 ? "0.{$orderby}" : $orderby);
+ $orderBy = (float) ($orderBy > 1 ? "0.{$orderBy}" : $orderBy);
}
- if (is_float($orderby))
+ if (is_float($orderBy))
{
- $this->db->simpleQuery("SET SEED {$orderby}");
+ $this->db->simpleQuery("SET SEED {$orderBy}");
}
- $orderby = $this->randomKeyword[0];
+ $orderBy = $this->randomKeyword[0];
$direction = '';
$escape = false;
}
- return parent::orderBy($orderby, $direction, $escape);
+ return parent::orderBy($orderBy, $direction, $escape);
}
//--------------------------------------------------------------------
@@ -144,7 +145,7 @@
* @throws DatabaseException
* @internal param true $bool returns the generated SQL, false executes the query.
*/
- public function replace($set = null, $returnSQL = false)
+ public function replace(array $set = null, bool $returnSQL = false)
{
if ($set !== null)
{
@@ -199,8 +200,8 @@
*
* Compiles a delete string and runs the query
*
- * @param string $where
- * @param null $limit
+ * @param mixed $where
+ * @param integer $limit
* @param boolean $reset_data
* @param boolean $returnSQL
*
@@ -210,7 +211,7 @@
* @internal param the $mixed limit clause
* @internal param $bool
*/
- public function delete($where = '', $limit = null, $reset_data = true, $returnSQL = false)
+ public function delete($where = '', int $limit = null, bool $reset_data = true, bool $returnSQL = false)
{
if (! empty($limit) || ! empty($this->QBLimit))
{
@@ -231,7 +232,7 @@
*
* @return string
*/
- protected function _limit($sql)
+ protected function _limit(string $sql): string
{
return $sql . ' LIMIT ' . $this->QBLimit . ($this->QBOffset ? " OFFSET {$this->QBOffset}" : '');
}
@@ -251,7 +252,7 @@
* @internal param the $string table name
* @internal param the $array update data
*/
- protected function _update($table, $values)
+ protected function _update(string $table, array $values): string
{
if (! empty($this->QBLimit))
{
@@ -275,7 +276,7 @@
*
* @return string
*/
- protected function _updateBatch($table, $values, $index)
+ protected function _updateBatch(string $table, array $values, string $index): string
{
$ids = [];
foreach ($values as $key => $val)
@@ -315,7 +316,7 @@
*
* @return string
*/
- protected function _delete($table)
+ protected function _delete(string $table): string
{
$this->QBLimit = false;
return parent::_delete($table);
@@ -335,7 +336,7 @@
*
* @return string
*/
- protected function _truncate($table)
+ protected function _truncate(string $table): string
{
return 'TRUNCATE ' . $table . ' RESTART IDENTITY';
}
@@ -350,11 +351,11 @@
*
* @see https://www.postgresql.org/docs/9.2/static/functions-matching.html
*
- * @param string|null $prefix
- * @param string $column
- * @param string|null $not
- * @param string $bind
- * @param boolean $insensitiveSearch
+ * @param string $prefix
+ * @param string $column
+ * @param string $not
+ * @param string $bind
+ * @param boolean $insensitiveSearch
*
* @return string $like_statement
*/
diff --git a/system/Database/Postgre/Connection.php b/system/Database/Postgre/Connection.php
index 1c046e9..56aec4f 100644
--- a/system/Database/Postgre/Connection.php
+++ b/system/Database/Postgre/Connection.php
@@ -1,5 +1,4 @@
-db->escapeIdentifiers($field['name'])
. ' ' . $field['type'] . $field['length']
@@ -177,7 +179,7 @@
*
* @return void
*/
- protected function _attributeType(&$attributes)
+ protected function _attributeType(array &$attributes)
{
// Reset field lengths for data types that don't support it
if (isset($attributes['CONSTRAINT']) && stripos($attributes['TYPE'], 'int') !== false)
@@ -190,15 +192,16 @@
case 'TINYINT':
$attributes['TYPE'] = 'SMALLINT';
$attributes['UNSIGNED'] = false;
- return;
+ break;
case 'MEDIUMINT':
$attributes['TYPE'] = 'INTEGER';
$attributes['UNSIGNED'] = false;
- return;
+ break;
case 'DATETIME':
$attributes['TYPE'] = 'TIMESTAMP';
+ break;
default:
- return;
+ break;
}
}
@@ -212,7 +215,7 @@
*
* @return void
*/
- protected function _attributeAutoIncrement(&$attributes, &$field)
+ protected function _attributeAutoIncrement(array &$attributes, array &$field)
{
if (! empty($attributes['AUTO_INCREMENT']) && $attributes['AUTO_INCREMENT'] === true)
{
@@ -233,7 +236,7 @@
*
* @return string
*/
- protected function _dropTable($table, $if_exists, $cascade)
+ protected function _dropTable(string $table, bool $if_exists, bool $cascade): string
{
$sql = parent::_dropTable($table, $if_exists, $cascade);
diff --git a/system/Database/Postgre/PreparedQuery.php b/system/Database/Postgre/PreparedQuery.php
index 2864985..fdd0aa4 100644
--- a/system/Database/Postgre/PreparedQuery.php
+++ b/system/Database/Postgre/PreparedQuery.php
@@ -1,4 +1,4 @@
-endTime - $this->startTime), $decimals);
}
@@ -265,7 +266,7 @@
* @param integer $code
* @param string $error
*
- * @return Query
+ * @return $this
*/
public function setError(int $code, string $error)
{
@@ -332,7 +333,7 @@
* @param string $orig
* @param string $swap
*
- * @return mixed
+ * @return $this
*/
public function swapPrefix(string $orig, string $swap)
{
@@ -350,7 +351,7 @@
*
* @return string
*/
- public function getOriginalQuery()
+ public function getOriginalQuery(): string
{
return $this->originalQueryString;
}
@@ -359,6 +360,8 @@
/**
* Escapes and inserts any binds into the finalQueryString object.
+ *
+ * @return null|void
*/
protected function compileBinds()
{
@@ -416,7 +419,7 @@
* @param array $binds
* @return string
*/
- protected function matchNamedBinds(string $sql, array $binds)
+ protected function matchNamedBinds(string $sql, array $binds): string
{
$replacers = [];
@@ -452,7 +455,7 @@
* @param integer $ml
* @return string
*/
- protected function matchSimpleBinds(string $sql, array $binds, int $bindCount, int $ml)
+ protected function matchSimpleBinds(string $sql, array $binds, int $bindCount, int $ml): string
{
// Make sure not to replace a chunk inside a string that happens to match the bind marker
if ($c = preg_match_all("/'[^']*'/i", $sql, $matches))
@@ -473,8 +476,8 @@
do
{
- $c --;
- $escapedValue = $binds[$c][1] ? $this->db->escape($binds[$c][0]) : $binds[$c[0]];
+ $c--;
+ $escapedValue = $binds[$c][1] ? $this->db->escape($binds[$c][0]) : $binds[$c][0];
if (is_array($escapedValue))
{
$escapedValue = '(' . implode(',', $escapedValue) . ')';
@@ -491,9 +494,9 @@
/**
* Return text representation of the query
*
- * @return mixed|string
+ * @return string
*/
- public function __toString()
+ public function __toString(): string
{
return $this->getQuery();
}
diff --git a/system/Database/QueryInterface.php b/system/Database/QueryInterface.php
index fe24a8c..7f5cfb1 100644
--- a/system/Database/QueryInterface.php
+++ b/system/Database/QueryInterface.php
@@ -1,4 +1,4 @@
-viewDirectory . '/errors/';
+ $path = $paths->viewDirectory . '/errors/';
}
$path = is_cli()
@@ -298,7 +300,7 @@
*
* @return array
*/
- protected function collectVars(\Throwable $exception, int $statusCode)
+ protected function collectVars(\Throwable $exception, int $statusCode): array
{
return [
'title' => get_class($exception),
@@ -356,7 +358,7 @@
*
* @return string
*/
- public static function cleanPath($file)
+ public static function cleanPath(string $file): string
{
if (strpos($file, APPPATH) === 0)
{
@@ -403,13 +405,13 @@
/**
* Creates a syntax-highlighted version of a PHP file.
*
- * @param $file
- * @param $lineNumber
- * @param integer $lines
+ * @param string $file
+ * @param integer $lineNumber
+ * @param integer $lines
*
* @return boolean|string
*/
- public static function highlightFile($file, $lineNumber, $lines = 15)
+ public static function highlightFile(string $file, int $lineNumber, int $lines = 15)
{
if (empty($file) || ! is_readable($file))
{
diff --git a/system/Debug/Iterator.php b/system/Debug/Iterator.php
index a8c0e33..2a8d332 100644
--- a/system/Debug/Iterator.php
+++ b/system/Debug/Iterator.php
@@ -1,5 +1,4 @@
-results))
{
diff --git a/system/Debug/Timer.php b/system/Debug/Timer.php
index b124a38..11c228c 100644
--- a/system/Debug/Timer.php
+++ b/system/Debug/Timer.php
@@ -1,4 +1,4 @@
-timers;
@@ -172,7 +174,7 @@
*
* @return boolean
*/
- public function has(string $name)
+ public function has(string $name): bool
{
return array_key_exists(strtolower($name), $this->timers);
}
diff --git a/system/Debug/Toolbar.php b/system/Debug/Toolbar.php
index 2cf3e70..f67bffb 100644
--- a/system/Debug/Toolbar.php
+++ b/system/Debug/Toolbar.php
@@ -1,5 +1,4 @@
- $value)
{
+ // Replace the binary data with string to avoid json_encode failure.
+ if (preg_match('~[^\x20-\x7E\t\r\n]~', $value))
+ {
+ $value = 'binary data';
+ }
+
$data['vars']['session'][esc($key)] = is_string($value) ? esc($value) : print_r($value, true);
}
}
@@ -273,7 +280,7 @@
*
* @return array
*/
- protected function collectVarData()// : array
+ protected function collectVarData(): array
{
$data = [];
@@ -300,7 +307,7 @@
*
* @return float
*/
- protected function roundTo($number, $increments = 5)
+ protected function roundTo($number, $increments = 5): float
{
$increments = 1 / $increments;
@@ -440,7 +447,7 @@
*
* @return string
*/
- protected function format(string $data, string $format = 'html')
+ protected function format(string $data, string $format = 'html'): string
{
$data = json_decode($data, true);
diff --git a/system/Debug/Toolbar/Collectors/BaseCollector.php b/system/Debug/Toolbar/Collectors/BaseCollector.php
index dd06de6..0785f13 100644
--- a/system/Debug/Toolbar/Collectors/BaseCollector.php
+++ b/system/Debug/Toolbar/Collectors/BaseCollector.php
@@ -1,5 +1,4 @@
-hasVarData;
}
@@ -249,7 +250,7 @@
*
* @return string
*/
- public function cleanPath($file)
+ public function cleanPath(string $file): string
{
if (strpos($file, APPPATH) === 0)
{
@@ -284,7 +285,7 @@
*
* @return boolean
*/
- public function isEmpty()
+ public function isEmpty(): bool
{
return false;
}
@@ -302,7 +303,7 @@
return '';
}
- public function getAsArray()
+ public function getAsArray(): array
{
return [
'title' => $this->getTitle(),
diff --git a/system/Debug/Toolbar/Collectors/Config.php b/system/Debug/Toolbar/Collectors/Config.php
index cd23cc7..7ab1e3d 100644
--- a/system/Debug/Toolbar/Collectors/Config.php
+++ b/system/Debug/Toolbar/Collectors/Config.php
@@ -1,12 +1,53 @@
- $time,
- 'datetime' => date('Y-m-d H:i:s', $time),
- 'active' => $time === $current,
- 'status' => $contents->vars->response->statusCode,
- 'method' => $contents->method,
- 'url' => $contents->url,
- 'isAJAX' => $contents->isAJAX ? 'Yes' : 'No',
- 'contentType' => $contents->vars->response->contentType,
- ];
+ // Debugbar files shown in History Collector
+ $files[] = [
+ 'time' => $time,
+ 'datetime' => date('Y-m-d H:i:s', $time),
+ 'active' => $time === $current,
+ 'status' => $contents->vars->response->statusCode,
+ 'method' => $contents->method,
+ 'url' => $contents->url,
+ 'isAJAX' => $contents->isAJAX ? 'Yes' : 'No',
+ 'contentType' => $contents->vars->response->contentType,
+ ];
+ }
}
$this->files = $files;
@@ -144,12 +149,12 @@
*
* @return integer
*/
- public function getBadgeValue()
+ public function getBadgeValue(): int
{
return count($this->files);
}
- public function isEmpty()
+ public function isEmpty(): bool
{
return empty($this->files);
}
diff --git a/system/Debug/Toolbar/Collectors/Logs.php b/system/Debug/Toolbar/Collectors/Logs.php
index 5e0c7e9..7077765 100644
--- a/system/Debug/Toolbar/Collectors/Logs.php
+++ b/system/Debug/Toolbar/Collectors/Logs.php
@@ -1,4 +1,4 @@
-collectLogs();
diff --git a/system/Debug/Toolbar/Collectors/Routes.php b/system/Debug/Toolbar/Collectors/Routes.php
index b4176dc..bc9c595 100644
--- a/system/Debug/Toolbar/Collectors/Routes.php
+++ b/system/Debug/Toolbar/Collectors/Routes.php
@@ -1,5 +1,4 @@
- $this->viewer->getData(),
@@ -170,7 +172,7 @@
*
* @return integer
*/
- public function getBadgeValue()
+ public function getBadgeValue(): int
{
return count($this->viewer->getPerformanceData());
}
diff --git a/system/Entity.php b/system/Entity.php
index fa54c2d..bdada1b 100644
--- a/system/Entity.php
+++ b/system/Entity.php
@@ -1,6 +1,4 @@
-_original[$key] === null && $value === null) || $this->_original[$key] === $value);
}
@@ -253,6 +261,7 @@
* @param string $key
*
* @return mixed
+ * @throws \Exception
*/
public function __get(string $key)
{
@@ -373,6 +382,8 @@
* attribute will be reset to that default value.
*
* @param string $key
+ *
+ * @throws \ReflectionException
*/
public function __unset(string $key)
{
@@ -449,6 +460,7 @@
* @param $value
*
* @return \CodeIgniter\I18n\Time
+ * @throws \Exception
*/
protected function mutateDate($value)
{
@@ -479,12 +491,13 @@
/**
* Provides the ability to cast an item as a specific data type.
- * Add ? at the beginning of $type (i.e. ?string) to get NULL instead of castig $value if $value === null
+ * Add ? at the beginning of $type (i.e. ?string) to get NULL instead of casting $value if $value === null
*
* @param $value
* @param string $type
*
* @return mixed
+ * @throws \Exception
*/
protected function castAs($value, string $type)
@@ -554,6 +567,7 @@
* @param boolean $asArray
*
* @return mixed
+ * @throws \CodeIgniter\Exceptions\CastException
*/
private function castAsJson($value, bool $asArray = false)
{
diff --git a/system/Events/Events.php b/system/Events/Events.php
index bde2866..f92f42a 100644
--- a/system/Events/Events.php
+++ b/system/Events/Events.php
@@ -1,7 +1,4 @@
getBaseName();
$destination = $overwrite ? $targetPath . $name : $this->getDestination($targetPath . $name);
- if (! @rename($this->getPath(), $destination))
+ $oldName = empty($this->getRealPath()) ? $this->getPath() : $this->getRealPath();
+
+ if (! @rename($oldName, $destination))
{
$error = error_get_last();
throw FileException::forUnableToMove($this->getBasename(), $targetPath, strip_tags($error['message']));
@@ -172,7 +181,7 @@
@chmod($targetPath, 0777 & ~umask());
- return true;
+ return new File($destination);
}
//--------------------------------------------------------------------
diff --git a/system/Filters/CSRF.php b/system/Filters/CSRF.php
index c9a47d5..1f1c2a1 100644
--- a/system/Filters/CSRF.php
+++ b/system/Filters/CSRF.php
@@ -1,4 +1,4 @@
-initialize(strtolower($uri));
@@ -142,7 +147,7 @@
if ($position === 'before')
{
- $result = $class->before($this->request, $this->arguments[$alias] ?? null);
+ $result = $class->before($this->request);
if ($result instanceof RequestInterface)
{
diff --git a/system/Filters/Honeypot.php b/system/Filters/Honeypot.php
index e0c55f3..e1c84d6 100644
--- a/system/Filters/Honeypot.php
+++ b/system/Filters/Honeypot.php
@@ -1,5 +1,4 @@
-getDownloadFileName();
@@ -377,7 +377,7 @@
$this->setContentTypeByMimeType();
}
- $this->setHeader('Content-Disposition', $this->getContentDisponsition());
+ $this->setHeader('Content-Disposition', $this->getContentDisposition());
$this->setHeader('Expires-Disposition', '0');
$this->setHeader('Content-Transfer-Encoding', 'binary');
$this->setHeader('Content-Length', (string)$this->getContentLength());
diff --git a/system/HTTP/Exceptions/HTTPException.php b/system/HTTP/Exceptions/HTTPException.php
index 0f3b222..49e83f3 100644
--- a/system/HTTP/Exceptions/HTTPException.php
+++ b/system/HTTP/Exceptions/HTTPException.php
@@ -1,9 +1,49 @@
$value)
+ foreach ($iterator as $key => $val)
{
array_splice($stack, $iterator->getDepth() + 1);
$pointer = &$stack[count($stack) - 1];
@@ -251,7 +253,7 @@
$stack[] = &$pointer;
if (! $iterator->hasChildren())
{
- $pointer[$field] = $value;
+ $pointer[$field] = $val;
}
}
}
@@ -270,7 +272,7 @@
*
* @return mixed
*/
- protected function getValueDotNotationSyntax($index, $value)
+ protected function getValueDotNotationSyntax(array $index, array $value)
{
if (is_array($index) && ! empty($index))
{
diff --git a/system/HTTP/Files/UploadedFile.php b/system/HTTP/Files/UploadedFile.php
index 5c61f76..f219d28 100644
--- a/system/HTTP/Files/UploadedFile.php
+++ b/system/HTTP/Files/UploadedFile.php
@@ -1,5 +1,5 @@
lang('HTTP.uploadErrOk'),
@@ -273,7 +275,7 @@
UPLOAD_ERR_NO_FILE => lang('HTTP.uploadErrNoFile'),
UPLOAD_ERR_CANT_WRITE => lang('HTTP.uploadErrCantWrite'),
UPLOAD_ERR_NO_TMP_DIR => lang('HTTP.uploadErrNoTmpDir'),
- UPLOAD_ERR_EXTENSION => lang('HTTP.uploadErrExtension')
+ UPLOAD_ERR_EXTENSION => lang('HTTP.uploadErrExtension'),
];
$error = is_null($this->error) ? UPLOAD_ERR_OK : $this->error;
@@ -393,7 +395,7 @@
* @param string $fileName the name to rename the file to.
* @return string file full path
*/
- public function store($folderName = null, $fileName = null): string
+ public function store(string $folderName = null, string $fileName = null): string
{
$folderName = $folderName ?? date('Ymd');
$fileName = $fileName ?? $this->getRandomName();
diff --git a/system/HTTP/Files/UploadedFileInterface.php b/system/HTTP/Files/UploadedFileInterface.php
index 04bcaad..76c0069 100644
--- a/system/HTTP/Files/UploadedFileInterface.php
+++ b/system/HTTP/Files/UploadedFileInterface.php
@@ -1,4 +1,4 @@
-uri->setPath($this->detectPath($protocol));
@@ -614,7 +613,7 @@
*
* @return string
*/
- public function detectPath($protocol = '')
+ public function detectPath(string $protocol = ''): string
{
if (empty($protocol))
{
@@ -650,7 +649,7 @@
*
* @return string
*/
- public function negotiate(string $type, array $supported, bool $strictMatch = false)
+ public function negotiate(string $type, array $supported, bool $strictMatch = false): string
{
if (is_null($this->negotiator))
{
@@ -775,7 +774,7 @@
*
* @return string
*/
- protected function removeRelativeDirectory($uri)
+ protected function removeRelativeDirectory(string $uri): string
{
$uris = [];
$tok = strtok($uri, '/');
diff --git a/system/HTTP/Message.php b/system/HTTP/Message.php
index f82f375..7114750 100644
--- a/system/HTTP/Message.php
+++ b/system/HTTP/Message.php
@@ -1,7 +1,4 @@
globals[$method][$index] ?? null;
}
diff --git a/system/HTTP/RequestInterface.php b/system/HTTP/RequestInterface.php
index b0b4e2b..bb507ab 100644
--- a/system/HTTP/RequestInterface.php
+++ b/system/HTTP/RequestInterface.php
@@ -1,4 +1,4 @@
-host;
}
@@ -539,15 +544,15 @@
/**
* Builds a representation of the string from the component parts.
*
- * @param $scheme
- * @param $authority
- * @param $path
- * @param $query
- * @param $fragment
+ * @param string $scheme
+ * @param string $authority
+ * @param string $path
+ * @param string $query
+ * @param string $fragment
*
* @return string
*/
- public static function createURIString($scheme = null, $authority = null, $path = null, $query = null, $fragment = null)
+ public static function createURIString(string $scheme = null, string $authority = null, string $path = null, string $query = null, string $fragment = null): string
{
$uri = '';
if (! empty($scheme))
@@ -962,9 +967,9 @@
/**
* Saves our parts from a parse_url call.
*
- * @param $parts
+ * @param array $parts
*/
- protected function applyParts($parts)
+ protected function applyParts(array $parts)
{
if (! empty($parts['host']))
{
@@ -1107,7 +1112,7 @@
*
* @return string
*/
- protected function mergePaths(URI $base, URI $reference)
+ protected function mergePaths(URI $base, URI $reference): string
{
if (! empty($base->getAuthority()) && empty($base->getPath()))
{
diff --git a/system/HTTP/UserAgent.php b/system/HTTP/UserAgent.php
index 1b8ecdb..6bd2309 100644
--- a/system/HTTP/UserAgent.php
+++ b/system/HTTP/UserAgent.php
@@ -1,7 +1,49 @@
-isBrowser)
{
@@ -139,7 +181,7 @@
*
* @return boolean
*/
- public function isRobot($key = null)
+ public function isRobot(string $key = null): bool
{
if (! $this->isRobot)
{
@@ -165,7 +207,7 @@
*
* @return boolean
*/
- public function isMobile($key = null)
+ public function isMobile(string $key = null): bool
{
if (! $this->isMobile)
{
@@ -189,7 +231,7 @@
*
* @return boolean
*/
- public function isReferral()
+ public function isReferral(): bool
{
if (! isset($this->referrer))
{
@@ -216,7 +258,7 @@
*
* @return string
*/
- public function getAgentString()
+ public function getAgentString(): string
{
return $this->agent;
}
@@ -228,7 +270,7 @@
*
* @return string
*/
- public function getPlatform()
+ public function getPlatform(): string
{
return $this->platform;
}
@@ -240,7 +282,7 @@
*
* @return string
*/
- public function getBrowser()
+ public function getBrowser(): string
{
return $this->browser;
}
@@ -252,7 +294,7 @@
*
* @return string
*/
- public function getVersion()
+ public function getVersion(): string
{
return $this->version;
}
@@ -264,7 +306,7 @@
*
* @return string
*/
- public function getRobot()
+ public function getRobot(): string
{
return $this->robot;
}
@@ -275,7 +317,7 @@
*
* @return string
*/
- public function getMobile()
+ public function getMobile(): string
{
return $this->mobile;
}
@@ -285,9 +327,9 @@
/**
* Get the referrer
*
- * @return boolean
+ * @return string
*/
- public function getReferrer()
+ public function getReferrer(): string
{
return empty($_SERVER['HTTP_REFERER']) ? '' : trim($_SERVER['HTTP_REFERER']);
}
@@ -301,7 +343,7 @@
*
* @return void
*/
- public function parse($string)
+ public function parse(string $string)
{
// Reset values
$this->isBrowser = false;
@@ -325,7 +367,7 @@
/**
* Compile the User Agent Data
*
- * @return boolean
+ * @return void
*/
protected function compileData()
{
@@ -347,7 +389,7 @@
*
* @return boolean
*/
- protected function setPlatform()
+ protected function setPlatform(): bool
{
if (is_array($this->config->platforms) && $this->config->platforms)
{
@@ -374,7 +416,7 @@
*
* @return boolean
*/
- protected function setBrowser()
+ protected function setBrowser(): bool
{
if (is_array($this->config->browsers) && $this->config->browsers)
{
@@ -402,7 +444,7 @@
*
* @return boolean
*/
- protected function setRobot()
+ protected function setRobot(): bool
{
if (is_array($this->config->robots) && $this->config->robots)
{
@@ -429,7 +471,7 @@
*
* @return boolean
*/
- protected function setMobile()
+ protected function setMobile(): bool
{
if (is_array($this->config->mobiles) && $this->config->mobiles)
{
@@ -455,7 +497,7 @@
*
* @return string
*/
- public function __toString()
+ public function __toString(): string
{
return $this->getAgentString();
}
diff --git a/system/Helpers/array_helper.php b/system/Helpers/array_helper.php
index ea8bbc7..5215173 100644
--- a/system/Helpers/array_helper.php
+++ b/system/Helpers/array_helper.php
@@ -1,4 +1,49 @@
'text',
@@ -905,12 +915,12 @@
*
* Helper function used by some of the form helpers
*
- * @param array $attributes List of attributes
- * @param array $default Default values
+ * @param string|array $attributes List of attributes
+ * @param array $default Default values
*
* @return string
*/
- function parse_form_attributes($attributes, $default): string
+ function parse_form_attributes($attributes, array $default): string
{
if (is_array($attributes))
{
diff --git a/system/Helpers/html_helper.php b/system/Helpers/html_helper.php
index 8002bc1..a1cc95e 100755
--- a/system/Helpers/html_helper.php
+++ b/system/Helpers/html_helper.php
@@ -38,7 +38,7 @@
// --------------------------------------------------------------------
/**
- * CodeIgniter HTML Helper
+ * CodeIgniter HTML Helpers
*
* @package CodeIgniter
* @subpackage Helpers
@@ -331,7 +331,7 @@
/**
* Video
*
- * Geneartes a video element to embed videos. The video element can
+ * Generates a video element to embed videos. The video element can
* contain one or more video sources
*
* @param mixed $src Either a source string or an array of sources
@@ -461,6 +461,17 @@
if (! function_exists('_media'))
{
+ /**
+ * Generate media based tag
+ *
+ * @param string $name
+ * @param array $types
+ * @param string $unsupportedMessage
+ * @param string $attributes
+ * @param array $tracks
+ *
+ * @return string
+ */
function _media(string $name, array $types = [], string $unsupportedMessage = '', string $attributes = '', array $tracks = []): string
{
$media = '<' . $name;
@@ -687,7 +698,12 @@
if (! function_exists('_has_protocol'))
{
- function _has_protocol($url)
+ /**
+ * @param string $url
+ *
+ * @return false|integer
+ */
+ function _has_protocol(string $url)
{
return preg_match('#^([a-z]+:)?//#i', $url);
}
@@ -697,7 +713,12 @@
if (! function_exists('_space_indent'))
{
- function _space_indent($depth = 2)
+ /**
+ * @param integer $depth
+ *
+ * @return string
+ */
+ function _space_indent($depth = 2): string
{
return str_repeat(' ', $depth);
}
diff --git a/system/Helpers/number_helper.php b/system/Helpers/number_helper.php
index 805f8a9..35126f8 100644
--- a/system/Helpers/number_helper.php
+++ b/system/Helpers/number_helper.php
@@ -27,7 +27,7 @@
* THE SOFTWARE.
*
* @package CodeIgniter
- * @author EllisLab Dev Team
+ * @author CodeIgniter Dev Team
* @copyright 2008-2014 EllisLab, Inc. (https://ellislab.com/)
* @copyright 2014-2019 British Columbia Institute of Technology (https://bcit.ca/)
* @license https://opensource.org/licenses/MIT MIT License
@@ -36,6 +36,16 @@
* @filesource
*/
+/**
+ * CodeIgniter Number Helpers
+ *
+ * @package CodeIgniter
+ * @subpackage Helpers
+ * @category Helpers
+ * @author CodeIgniter Dev Team
+ * @link https://codeigniter.com/user_guide/helpers/cookie_helper.html
+ */
+
if (! function_exists('number_to_size'))
{
/**
@@ -257,11 +267,11 @@
/**
* Convert a number to a roman numeral.
*
- * @param integer $num it will convert to int
+ * @param string $num it will convert to int
*
* @return string|null
*/
- function number_to_roman($num)
+ function number_to_roman(string $num): ?string
{
$num = (int) $num;
if ($num < 1 || $num > 3999)
diff --git a/system/Helpers/security_helper.php b/system/Helpers/security_helper.php
index 7e67cf2..04aa284 100644
--- a/system/Helpers/security_helper.php
+++ b/system/Helpers/security_helper.php
@@ -38,6 +38,16 @@
use Config\Services;
+/**
+ * CodeIgniter Security Helpers
+ *
+ * @package CodeIgniter
+ * @subpackage Helpers
+ * @category Helpers
+ * @author CodeIgniter Dev Team
+ * @link https://codeigniter.com/user_guide/helpers/cookie_helper.html
+ */
+
if (! function_exists('sanitize_filename'))
{
/**
diff --git a/system/Helpers/text_helper.php b/system/Helpers/text_helper.php
index 52f61b2..8a49361 100755
--- a/system/Helpers/text_helper.php
+++ b/system/Helpers/text_helper.php
@@ -28,7 +28,7 @@
* THE SOFTWARE.
*
* @package CodeIgniter
- * @author EllisLab Dev Team
+ * @author CodeIgniter Dev Team
* @copyright 2008-2014 EllisLab, Inc. (https://ellislab.com/)
* @copyright 2014-2019 British Columbia Institute of Technology (https://bcit.ca/)
* @license https://opensource.org/licenses/MIT MIT License
@@ -43,7 +43,7 @@
* @package CodeIgniter
* @subpackage Helpers
* @category Helpers
- * @author EllisLab Dev Team
+ * @author CodeIgniter Dev Team
* @link https://codeigniter.com/user_guide/helpers/text_helper.html
*/
//--------------------------------------------------------------------
@@ -264,14 +264,14 @@
* word you've submitted.
*
* @param string $str the text string
- * @param string $censored the array of censored words
+ * @param array $censored the array of censored words
* @param string $replacement the optional replacement value
*
* @return string
*/
- function word_censor(string $str, $censored, string $replacement = ''): string
+ function word_censor(string $str, array $censored, string $replacement = ''): string
{
- if (! is_array($censored))
+ if (empty($censored))
{
return $str;
}
@@ -460,7 +460,7 @@
* Anything placed between {unwrap}{/unwrap} will not be word wrapped, nor
* will URLs.
*
- * @param string $str the text string
+ * @param string $str the text string
* @param integer $charlim = 76 the number of characters to wrap at
*
* @return string
@@ -604,7 +604,7 @@
*
* Removes slashes contained in a string or in an array
*
- * @param mixed $str string or array
+ * @param mixed $str string or array
*
* @return mixed string or array
*/
diff --git a/system/Helpers/url_helper.php b/system/Helpers/url_helper.php
index 4fbaaae..0184b25 100644
--- a/system/Helpers/url_helper.php
+++ b/system/Helpers/url_helper.php
@@ -35,23 +35,33 @@
* @filesource
*/
+/**
+ * CodeIgniter URL Helpers
+ *
+ * @package CodeIgniter
+ * @subpackage Helpers
+ * @category Helpers
+ * @author CodeIgniter Dev Team
+ * @link https://codeigniter.com/user_guide/helpers/cookie_helper.html
+ */
+
if (! function_exists('site_url'))
{
/**
* Return a site URL to use in views
*
- * @param string|array $path
- * @param string|null $scheme
+ * @param mixed $uri URI string or array of URI segments
+ * @param string|null $protocol
* @param \Config\App|null $altConfig Alternate configuration to use
*
* @return string
*/
- function site_url($path = '', string $scheme = null, \Config\App $altConfig = null): string
+ function site_url($uri = '', string $protocol = null, \Config\App $altConfig = null): string
{
// convert segment array to string
- if (is_array($path))
+ if (is_array($uri))
{
- $path = implode('/', $path);
+ $uri = implode('/', $uri);
}
// use alternate config if provided, else default one
@@ -64,17 +74,17 @@
{
$fullPath .= rtrim($config->indexPage, '/');
}
- if (! empty($path))
+ if (! empty($uri))
{
- $fullPath .= '/' . $path;
+ $fullPath .= '/' . $uri;
}
$url = new \CodeIgniter\HTTP\URI($fullPath);
// allow the scheme to be over-ridden; else, use default
- if (! empty($scheme))
+ if (! empty($protocol))
{
- $url->setScheme($scheme);
+ $url->setScheme($protocol);
}
return (string) $url;
@@ -88,16 +98,16 @@
/**
* Return the base URL to use in views
*
- * @param string|array $path
- * @param string $scheme
+ * @param mixed $uri URI string or array of URI segments
+ * @param string $protocol
* @return string
*/
- function base_url($path = '', string $scheme = null): string
+ function base_url($uri = '', string $protocol = null): string
{
// convert segment array to string
- if (is_array($path))
+ if (is_array($uri))
{
- $path = implode('/', $path);
+ $uri = implode('/', $uri);
}
// We should be using the configured baseURL that the user set;
@@ -108,21 +118,21 @@
unset($config);
// Merge in the path set by the user, if any
- if (! empty($path))
+ if (! empty($uri))
{
- $url = $url->resolveRelativeURI($path);
+ $url = $url->resolveRelativeURI($uri);
}
// If the scheme wasn't provided, check to
// see if it was a secure request
- if (empty($scheme) && \CodeIgniter\Config\Services::request()->isSecure())
+ if (empty($protocol) && \CodeIgniter\Config\Services::request()->isSecure())
{
- $scheme = 'https';
+ $protocol = 'https';
}
- if (! empty($scheme))
+ if (! empty($protocol))
{
- $url->setScheme($scheme);
+ $url->setScheme($protocol);
}
return (string) $url;
@@ -223,7 +233,7 @@
*
* Creates an anchor based on the local URL.
*
- * @param string $uri The URL
+ * @param mixed $uri URI string or array of URI segments
* @param string $title The link title
* @param mixed $attributes Any attributes
* @param \Config\App|null $altConfig Alternate configuration to use
@@ -332,7 +342,7 @@
*
* @return string
*/
- function mailto($email, string $title = '', $attributes = ''): string
+ function mailto(string $email, string $title = '', $attributes = ''): string
{
if (trim($title) === '')
{
@@ -358,7 +368,7 @@
*
* @return string
*/
- function safe_mailto($email, string $title = '', $attributes = ''): string
+ function safe_mailto(string $email, string $title = '', $attributes = ''): string
{
if (trim($title) === '')
{
@@ -470,7 +480,7 @@
*
* @return string
*/
- function auto_link($str, $type = 'both', $popup = false): string
+ function auto_link(string $str, string $type = 'both', bool $popup = false): string
{
// Find and replace any URLs.
if ($type !== 'email' && preg_match_all('#(\w*://|www\.)[^\s()<>;]+\w#i', $str, $matches, PREG_OFFSET_CAPTURE | PREG_SET_ORDER))
@@ -522,7 +532,7 @@
* @param string the URL
* @return string
*/
- function prep_url($str = ''): string
+ function prep_url(string $str = ''): string
{
if ($str === 'http://' || $str === '')
{
@@ -556,7 +566,7 @@
* @param boolean $lowercase Whether to transform the output string to lowercase
* @return string
*/
- function url_title($str, $separator = '-', $lowercase = false): string
+ function url_title(string $str, string $separator = '-', bool $lowercase = false): string
{
$q_separator = preg_quote($separator, '#');
diff --git a/system/Helpers/xml_helper.php b/system/Helpers/xml_helper.php
index 3848ece..e18c579 100644
--- a/system/Helpers/xml_helper.php
+++ b/system/Helpers/xml_helper.php
@@ -35,16 +35,26 @@
* @filesource
*/
+/**
+ * CodeIgniter XML Helpers
+ *
+ * @package CodeIgniter
+ * @subpackage Helpers
+ * @category Helpers
+ * @author CodeIgniter Dev Team
+ * @link https://codeigniter.com/user_guide/helpers/cookie_helper.html
+ */
+
if (! function_exists('xml_convert'))
{
/**
* Convert Reserved XML characters to Entities
*
- * @param string
- * @param boolean
+ * @param string $str
+ * @param boolean $protect_all
* @return string
*/
- function xml_convert(string $str, $protect_all = false): string
+ function xml_convert(string $str, bool $protect_all = false): string
{
$temp = '__TEMP_AMPERSANDS__';
diff --git a/system/Honeypot/Honeypot.php b/system/Honeypot/Honeypot.php
index b2ba4ee..90ef152 100644
--- a/system/Honeypot/Honeypot.php
+++ b/system/Honeypot/Honeypot.php
@@ -1,6 +1,5 @@
config->label, $template);
$template = str_ireplace('{name}', $this->config->name, $template);
diff --git a/system/I18n/Time.php b/system/I18n/Time.php
index 45114b6..f5d03cd 100644
--- a/system/I18n/Time.php
+++ b/system/I18n/Time.php
@@ -1,5 +1,4 @@
toLocalizedString('Y');
}
@@ -406,7 +416,7 @@
*
* @return string
*/
- public function getMonth()
+ public function getMonth(): string
{
return $this->toLocalizedString('M');
}
@@ -418,7 +428,7 @@
*
* @return string
*/
- public function getDay()
+ public function getDay(): string
{
return $this->toLocalizedString('d');
}
@@ -430,7 +440,7 @@
*
* @return string
*/
- public function getHour()
+ public function getHour(): string
{
return $this->toLocalizedString('H');
}
@@ -442,7 +452,7 @@
*
* @return string
*/
- public function getMinute()
+ public function getMinute(): string
{
return $this->toLocalizedString('m');
}
@@ -454,7 +464,7 @@
*
* @return string
*/
- public function getSecond()
+ public function getSecond(): string
{
return $this->toLocalizedString('s');
}
@@ -466,7 +476,7 @@
*
* @return string
*/
- public function getDayOfWeek()
+ public function getDayOfWeek(): string
{
return $this->toLocalizedString('c');
}
@@ -478,7 +488,7 @@
*
* @return string
*/
- public function getDayOfYear()
+ public function getDayOfYear(): string
{
return $this->toLocalizedString('D');
}
@@ -490,7 +500,7 @@
*
* @return string
*/
- public function getWeekOfMonth()
+ public function getWeekOfMonth(): string
{
return $this->toLocalizedString('W');
}
@@ -502,7 +512,7 @@
*
* @return string
*/
- public function getWeekOfYear()
+ public function getWeekOfYear(): string
{
return $this->toLocalizedString('w');
}
@@ -528,7 +538,7 @@
*
* @return string
*/
- public function getQuarter()
+ public function getQuarter(): string
{
return $this->toLocalizedString('Q');
}
@@ -562,7 +572,7 @@
* Returns boolean whether the passed timezone is the same as
* the local timezone.
*/
- public function getLocal()
+ public function getLocal(): bool
{
$local = date_default_timezone_get();
@@ -574,17 +584,17 @@
/**
* Returns boolean whether object is in UTC.
*/
- public function getUtc()
+ public function getUtc(): bool
{
return $this->getOffset() === 0;
}
/**
- * Reeturns the name of the current timezone.
+ * Returns the name of the current timezone.
*
* @return string
*/
- public function getTimezoneName()
+ public function getTimezoneName(): string
{
return $this->timezone->getName();
}
@@ -709,6 +719,7 @@
* @param $value
*
* @return \CodeIgniter\I18n\Time
+ * @throws \Exception
*/
protected function setValue(string $name, $value)
{
@@ -976,6 +987,7 @@
* @param string|null $format
*
* @return string
+ * @throws \Exception
*/
public function toLocalizedString(?string $format = null)
{
@@ -999,6 +1011,7 @@
* @param string|null $timezone
*
* @return boolean
+ * @throws \Exception
*/
public function equals($testTime, string $timezone = null): bool
{
@@ -1124,7 +1137,7 @@
{
$before = $days < 0;
- // Yesterday/Tommorrow special cases
+ // Yesterday/Tomorrow special cases
if (abs($days) === 1)
{
return $before ? lang('Time.yesterday') : lang('Time.tomorrow');
@@ -1240,8 +1253,9 @@
* Outputs a short format version of the datetime.
*
* @return string
+ * @throws \Exception
*/
- public function __toString()
+ public function __toString(): string
{
return IntlDateFormatter::formatObject($this->toDateTime(), $this->toStringFormat, $this->locale);
}
diff --git a/system/I18n/TimeDifference.php b/system/I18n/TimeDifference.php
index 4a4ac3a..b1c19bf 100644
--- a/system/I18n/TimeDifference.php
+++ b/system/I18n/TimeDifference.php
@@ -1,7 +1,48 @@
- '{0} is not a valid Model Event callback.',
- 'invalidArgument' => 'You must provide a valid {0}.',
- 'invalidAllowedFields' => 'Allowed fields must be specified for model: {0}',
- 'emptyDataset' => 'There is no data to {0}.',
- 'failGetFieldData' => 'Failed to get field data from database.',
- 'failGetIndexData' => 'Failed to get index data from database.',
- 'failGetForeignKeyData' => 'Failed to get foreign key data from database.',
- 'parseStringFail' => 'Parsing key string failed.',
- 'featureUnavailable' => 'This feature is not available for the database you are using.',
- 'tableNotFound' => 'Table `{0}` was not found in the current database.',
+ 'invalidEvent' => '{0} is not a valid Model Event callback.',
+ 'invalidArgument' => 'You must provide a valid {0}.',
+ 'invalidAllowedFields' => 'Allowed fields must be specified for model: {0}',
+ 'emptyDataset' => 'There is no data to {0}.',
+ 'failGetFieldData' => 'Failed to get field data from database.',
+ 'failGetIndexData' => 'Failed to get index data from database.',
+ 'failGetForeignKeyData' => 'Failed to get foreign key data from database.',
+ 'parseStringFail' => 'Parsing key string failed.',
+ 'featureUnavailable' => 'This feature is not available for the database you are using.',
+ 'tableNotFound' => 'Table `{0}` was not found in the current database.',
+ 'noPrimaryKey' => '`{0}` model class does not specify a Primary Key.',
+ 'forEmptyInputGiven' => 'Empty statement is given for the field `{0}`',
+ 'forFindColumnHaveMultipleColumns' => 'Only single column allowed in Column name.',
];
diff --git a/system/Language/en/HTTP.php b/system/Language/en/HTTP.php
index eb0b29c..6b423bb 100644
--- a/system/Language/en/HTTP.php
+++ b/system/Language/en/HTTP.php
@@ -64,14 +64,14 @@
'alreadyMoved' => 'The uploaded file has already been moved.',
'invalidFile' => 'The original file is not a valid file.',
'moveFailed' => 'Could not move file {0} to {1} ({2})',
-
- 'uploadErrOk' => 'The file uploaded with success.',
- 'uploadErrIniSize' => 'The file "%s" exceeds your upload_max_filesize ini directive.',
- 'uploadErrFormSize' => 'The file "%s" exceeds the upload limit defined in your form.',
- 'uploadErrPartial' => 'The file "%s" was only partially uploaded.',
- 'uploadErrNoFile' => 'No file was uploaded.',
- 'uploadErrCantWrite' => 'The file "%s" could not be written on disk.',
- 'uploadErrNoTmpDir' => 'File could not be uploaded: missing temporary directory.',
- 'uploadErrExtension' => 'File upload was stopped by a PHP extension.',
- 'uploadErrUnknown' => 'The file "%s" was not uploaded due to an unknown error.'
+
+ 'uploadErrOk' => 'The file uploaded with success.',
+ 'uploadErrIniSize' => 'The file "%s" exceeds your upload_max_filesize ini directive.',
+ 'uploadErrFormSize' => 'The file "%s" exceeds the upload limit defined in your form.',
+ 'uploadErrPartial' => 'The file "%s" was only partially uploaded.',
+ 'uploadErrNoFile' => 'No file was uploaded.',
+ 'uploadErrCantWrite' => 'The file "%s" could not be written on disk.',
+ 'uploadErrNoTmpDir' => 'File could not be uploaded: missing temporary directory.',
+ 'uploadErrExtension' => 'File upload was stopped by a PHP extension.',
+ 'uploadErrUnknown' => 'The file "%s" was not uploaded due to an unknown error.',
];
diff --git a/system/Language/en/Images.php b/system/Language/en/Images.php
index f7ee1ad..6417d53 100644
--- a/system/Language/en/Images.php
+++ b/system/Language/en/Images.php
@@ -21,7 +21,7 @@
'gifNotSupported' => 'GIF images are often not supported due to licensing restrictions. You may have to use JPG or PNG images instead.',
'jpgNotSupported' => 'JPG images are not supported.',
'pngNotSupported' => 'PNG images are not supported.',
- 'unsupportedImagecreate' => 'Your server does not support the GD function required to process this type of image.',
+ 'unsupportedImageCreate' => 'Your server does not support the GD function required to process this type of image.',
'jpgOrPngRequired' => 'The image resize protocol specified in your preferences only works with JPEG or PNG image types.',
'rotateUnsupported' => 'Image rotation does not appear to be supported by your server.',
'libPathInvalid' => 'The path to your image library is not correct. Please set the correct path in your image preferences. {0, string)',
diff --git a/system/Log/Handlers/BaseHandler.php b/system/Log/Handlers/BaseHandler.php
index 7fc66fa..cc55ea6 100644
--- a/system/Log/Handlers/BaseHandler.php
+++ b/system/Log/Handlers/BaseHandler.php
@@ -1,4 +1,4 @@
-tempReturnType = $this->returnType;
$this->tempUseSoftDeletes = $this->useSoftDeletes;
- $this->reset();
-
return $row['data'];
}
//--------------------------------------------------------------------
/**
+ * Fetches the column of database from $this->table
+ *
+ * @param string $column_name Column name
+ *
+ * @return array|null The resulting row of data, or null if no data found.
+ *
+ * @throws \CodeIgniter\Database\Exceptions\DataException
+ */
+ public function findColumn(string $columnName)
+ {
+ if (strpos($columnName, ',') !== false)
+ {
+ throw DataException::forFindColumnHaveMultipleColumns();
+ }
+
+ $resultSet = $this->select($columnName)
+ ->asArray()
+ ->find();
+
+ return (!empty($resultSet)) ? array_column($resultSet, $columnName) : null;
+ }
+
+ //--------------------------------------------------------------------
+
+ /**
* Works with the current Query Builder instance to return
* all results, while optionally limiting them.
*
@@ -385,7 +411,7 @@
/**
* Returns the first row of the result set. Will take any previous
- * Query Builder calls into account when determing the result set.
+ * Query Builder calls into account when determining the result set.
*
* @return array|object|null
*/
@@ -424,13 +450,13 @@
* data here. This allows it to be used with any of the other
* builder methods and still get validated data, like replace.
*
- * @param $key
+ * @param mixed $key
* @param string $value
* @param boolean|null $escape
*
* @return $this
*/
- public function set($key, $value = '', bool $escape = null)
+ public function set($key, string $value = '', bool $escape = null)
{
$data = is_array($key)
? $key
@@ -456,7 +482,7 @@
* @return boolean
* @throws \ReflectionException
*/
- public function save($data)
+ public function save($data): bool
{
// If $data is using a custom class with public or protected
// properties representing the table elements, we need to grab
@@ -481,7 +507,12 @@
}
else
{
- $response = $this->insert($data);
+ $response = $this->insert($data, false);
+ // call insert directly if you want the ID or the record object
+ if ($response !== false)
+ {
+ $response = true;
+ }
}
return $response;
@@ -565,7 +596,7 @@
*
* @return integer
*/
- public function getInsertID()
+ public function getInsertID(): int
{
return $this->insertID;
}
@@ -629,10 +660,16 @@
// strip out created_at values.
$data = $this->doProtectFields($data);
- if ($this->useTimestamps && ! array_key_exists($this->createdField, $data))
+ // Set created_at and updated_at with same time
+ $date = $this->setDate();
+
+ if ($this->useTimestamps && ! empty($this->createdField) && ! array_key_exists($this->createdField, $data))
{
- $date = $this->setDate();
$data[$this->createdField] = $date;
+ }
+
+ if ($this->useTimestamps && ! empty($this->updatedField) && ! array_key_exists($this->updatedField, $data))
+ {
$data[$this->updatedField] = $date;
}
@@ -673,9 +710,9 @@
* @param integer $batchSize
* @param boolean $testing
*
- * @return integer Number of rows inserted or FALSE on failure
+ * @return integer|boolean Number of rows inserted or FALSE on failure
*/
- public function insertBatch($set = null, $escape = null, $batchSize = 100, $testing = false)
+ public function insertBatch(array $set = null, bool $escape = null, int $batchSize = 100, bool $testing = false)
{
if (is_array($set) && $this->skipValidation === false)
{
@@ -703,7 +740,7 @@
* @return boolean
* @throws \ReflectionException
*/
- public function update($id = null, $data = null)
+ public function update($id = null, $data = null): bool
{
$escape = null;
@@ -753,7 +790,7 @@
// strip out updated_at values.
$data = $this->doProtectFields($data);
- if ($this->useTimestamps && ! array_key_exists($this->updatedField, $data))
+ if ($this->useTimestamps && ! empty($this->updatedField) && ! array_key_exists($this->updatedField, $data))
{
$data[$this->updatedField] = $this->setDate();
}
@@ -797,7 +834,7 @@
* @return mixed Number of rows affected or FALSE on failure
* @throws \CodeIgniter\Database\Exceptions\DatabaseException
*/
- public function updateBatch($set = null, $index = null, $batchSize = 100, $returnSQL = false)
+ public function updateBatch(array $set = null, string $index = null, int $batchSize = 100, bool $returnSQL = false)
{
if (is_array($set) && $this->skipValidation === false)
{
@@ -825,7 +862,7 @@
* @return mixed
* @throws \CodeIgniter\Database\Exceptions\DatabaseException
*/
- public function delete($id = null, $purge = false)
+ public function delete($id = null, bool $purge = false)
{
if (! empty($id) && is_numeric($id))
{
@@ -844,7 +881,7 @@
{
$set[$this->deletedField] = 1;
- if ($this->useTimestamps)
+ if ($this->useTimestamps && ! empty($this->updatedField))
{
$set[$this->updatedField] = $this->setDate();
}
@@ -928,7 +965,7 @@
*
* @return boolean TRUE on success, FALSE on failure
*/
- public function replace($data = null, $returnSQL = false)
+ public function replace($data = null, bool $returnSQL = false): bool
{
// Validate data before saving.
if (! empty($data) && $this->skipValidation === false)
@@ -989,7 +1026,7 @@
*
* @throws \CodeIgniter\Database\Exceptions\DataException
*/
- public function chunk($size = 100, \Closure $userFunc)
+ public function chunk(int $size, \Closure $userFunc)
{
$total = $this->builder()
->countAllResults(false);
@@ -1007,7 +1044,7 @@
throw DataException::forEmptyDataset('chunk');
}
- $rows = $rows->getResult();
+ $rows = $rows->getResult($this->tempReturnType);
$offset += $size;
@@ -1090,6 +1127,14 @@
return $this->builder;
}
+ // We're going to force a primary key to exist
+ // so we don't have overly convoluted code,
+ // and future features are likely to require them.
+ if (empty($this->primaryKey))
+ {
+ throw ModelException::forNoPrimaryKey(get_class($this));
+ }
+
$table = empty($table) ? $this->table : $table;
// Ensure we have a good db connection
@@ -1117,7 +1162,7 @@
* @return array
* @throws \CodeIgniter\Database\Exceptions\DataException
*/
- protected function doProtectFields($data)
+ protected function doProtectFields(array $data): array
{
if ($this->protectFields === false)
{
@@ -1160,7 +1205,7 @@
*
* @return mixed
*/
- protected function setDate($userData = null)
+ protected function setDate(int $userData = null)
{
$currentDate = is_numeric($userData) ? (int) $userData : time();
@@ -1246,6 +1291,36 @@
//--------------------------------------------------------------------
/**
+ * Allows to set validation messages.
+ * It could be used when you have to change default or override current validate messages.
+ *
+ * @param array $validationMessages
+ *
+ * @return void
+ */
+ public function setValidationMessages(array $validationMessages)
+ {
+ $this->validationMessages = $validationMessages;
+ }
+ //--------------------------------------------------------------------
+
+ /**
+ * Allows to set field wise validation message.
+ * It could be used when you have to change default or override current validate messages.
+ *
+ * @param string $field
+ * @param array $fieldMessages
+ *
+ * @return void
+ */
+ public function setValidationMessage(string $field, array $fieldMessages)
+ {
+ $this->validationMessages[$field] = $fieldMessages;
+ }
+
+ //--------------------------------------------------------------------
+
+ /**
* Validate the data against the validation rules (or the validation group)
* specified in the class property, $validationRules.
*
@@ -1302,11 +1377,13 @@
* currently so that rules don't block updating when only updating
* a partial row.
*
- * @param array $rules
+ * @param array $rules
+ *
+ * @param array|null $data
*
* @return array
*/
- protected function cleanValidationRules($rules, array $data = null)
+ protected function cleanValidationRules(array $rules, array $data = null): array
{
if (empty($data))
{
@@ -1344,7 +1421,7 @@
*
* @return array
*/
- protected function fillPlaceholders(array $rules, array $data)
+ protected function fillPlaceholders(array $rules, array $data): array
{
$replacements = [];
@@ -1386,9 +1463,11 @@
* Returns the model's defined validation rules so that they
* can be used elsewhere, if needed.
*
+ * @param array $options
+ *
* @return array
*/
- public function getValidationRules(array $options = [])
+ public function getValidationRules(array $options = []): array
{
$rules = $this->validationRules;
@@ -1412,7 +1491,7 @@
*
* @return array
*/
- public function getValidationMessages()
+ public function getValidationMessages(): array
{
return $this->validationMessages;
}
@@ -1488,7 +1567,7 @@
*
* @param string $name
*
- * @return null
+ * @return mixed
*/
public function __get(string $name)
{
@@ -1519,7 +1598,7 @@
*
* @return Model|null
*/
- public function __call($name, array $params)
+ public function __call(string $name, array $params)
{
$result = null;
diff --git a/system/Pager/Pager.php b/system/Pager/Pager.php
index ee09e31..2af6ac7 100644
--- a/system/Pager/Pager.php
+++ b/system/Pager/Pager.php
@@ -1,4 +1,4 @@
-routesOptions[$from] ?? [] : $this->routesOptions;
}
@@ -887,10 +889,10 @@
* Example:
* $route->match( ['get', 'post'], 'users/(:num)', 'users/$1);
*
- * @param array $verbs
- * @param $from
- * @param $to
- * @param array $options
+ * @param array $verbs
+ * @param string $from
+ * @param string|array $to
+ * @param array $options
*
* @return \CodeIgniter\Router\RouteCollectionInterface
*/
@@ -911,9 +913,9 @@
/**
* Specifies a route that is only available to GET requests.
*
- * @param $from
- * @param $to
- * @param array $options
+ * @param string $from
+ * @param string|array $to
+ * @param array $options
*
* @return \CodeIgniter\Router\RouteCollectionInterface
*/
@@ -929,9 +931,9 @@
/**
* Specifies a route that is only available to POST requests.
*
- * @param $from
- * @param $to
- * @param array $options
+ * @param string $from
+ * @param string|array $to
+ * @param array $options
*
* @return \CodeIgniter\Router\RouteCollectionInterface
*/
@@ -947,9 +949,9 @@
/**
* Specifies a route that is only available to PUT requests.
*
- * @param $from
- * @param $to
- * @param array $options
+ * @param string $from
+ * @param string|array $to
+ * @param array $options
*
* @return \CodeIgniter\Router\RouteCollectionInterface
*/
@@ -965,9 +967,9 @@
/**
* Specifies a route that is only available to DELETE requests.
*
- * @param $from
- * @param $to
- * @param array $options
+ * @param string $from
+ * @param string|array $to
+ * @param array $options
*
* @return \CodeIgniter\Router\RouteCollectionInterface
*/
@@ -983,9 +985,9 @@
/**
* Specifies a route that is only available to HEAD requests.
*
- * @param $from
- * @param $to
- * @param array $options
+ * @param string $from
+ * @param string|array $to
+ * @param array $options
*
* @return \CodeIgniter\Router\RouteCollectionInterface
*/
@@ -1001,9 +1003,9 @@
/**
* Specifies a route that is only available to PATCH requests.
*
- * @param $from
- * @param $to
- * @param array $options
+ * @param string $from
+ * @param string|array $to
+ * @param array $options
*
* @return \CodeIgniter\Router\RouteCollectionInterface
*/
@@ -1019,9 +1021,9 @@
/**
* Specifies a route that is only available to OPTIONS requests.
*
- * @param $from
- * @param $to
- * @param array $options
+ * @param string $from
+ * @param string|array $to
+ * @param array $options
*
* @return \CodeIgniter\Router\RouteCollectionInterface
*/
@@ -1037,9 +1039,9 @@
/**
* Specifies a route that is only available to command-line requests.
*
- * @param $from
- * @param $to
- * @param array $options
+ * @param string $from
+ * @param string|array $to
+ * @param array $options
*
* @return \CodeIgniter\Router\RouteCollectionInterface
*/
@@ -1225,10 +1227,10 @@
* the request method(s) that this route will work for. They can be separated
* by a pipe character "|" if there is more than one.
*
- * @param string $verb
- * @param string $from
- * @param $to
- * @param array|null $options
+ * @param string $verb
+ * @param string $from
+ * @param string|array $to
+ * @param array $options
*/
protected function create(string $verb, string $from, $to, array $options = null)
{
@@ -1238,7 +1240,7 @@
$from = filter_var($prefix . $from, FILTER_SANITIZE_STRING);
// While we want to add a route within a group of '/',
- // it doens't work with matching, so remove them...
+ // it doesn't work with matching, so remove them...
if ($from !== '/')
{
$from = trim($from, '/');
@@ -1341,11 +1343,11 @@
* Compares the subdomain(s) passed in against the current subdomain
* on this page request.
*
- * @param $subdomains
+ * @param mixed $subdomains
*
* @return boolean
*/
- private function checkSubdomains($subdomains)
+ private function checkSubdomains($subdomains): bool
{
// CLI calls can't be on subdomain.
if (! isset($_SERVER['HTTP_HOST']))
diff --git a/system/Router/RouteCollectionInterface.php b/system/Router/RouteCollectionInterface.php
index 2413ccf..b61ffcf 100644
--- a/system/Router/RouteCollectionInterface.php
+++ b/system/Router/RouteCollectionInterface.php
@@ -1,4 +1,4 @@
- $val)
{
+ $key = $key === '/'
+ ? $key
+ : ltrim($key, '/ ');
+
// Are we dealing with a locale?
if (strpos($key, '{locale}') !== false)
{
- $localeSegment = array_search('{locale}', explode('/', $key));
+ $localeSegment = array_search('{locale}', preg_split('/[\/]*((^[a-zA-Z0-9])|\(([^()]*)\))*[\/]+/m', $key));
// Replace it with a regex so it
// will actually match.
@@ -471,7 +477,15 @@
}
elseif (strpos($val, '/') !== false)
{
- $val = str_replace('/', '\\', $val);
+ [
+ $controller,
+ $method,
+ ] = explode( '::', $val );
+
+ // Only replace slashes in the controller, not in the method.
+ $controller = str_replace('/', '\\', $controller);
+
+ $val = $controller . '::' . $method;
}
// Is this route supposed to redirect to another?
diff --git a/system/Router/RouterInterface.php b/system/Router/RouterInterface.php
index 85491b3..67d2827 100644
--- a/system/Router/RouterInterface.php
+++ b/system/Router/RouterInterface.php
@@ -1,4 +1,4 @@
-CSRFHash;
}
@@ -276,7 +278,7 @@
*
* @return string
*/
- public function getCSRFTokenName()
+ public function getCSRFTokenName(): string
{
return $this->CSRFTokenName;
}
@@ -287,8 +289,9 @@
* Sets the CSRF Hash and cookie.
*
* @return string
+ * @throws \Exception
*/
- protected function CSRFSetHash()
+ protected function CSRFSetHash(): string
{
if ($this->CSRFHash === null)
{
diff --git a/system/Session/Handlers/BaseHandler.php b/system/Session/Handlers/BaseHandler.php
index 7605b4f..5f15462 100644
--- a/system/Session/Handlers/BaseHandler.php
+++ b/system/Session/Handlers/BaseHandler.php
@@ -1,4 +1,4 @@
-savePath);
diff --git a/system/Session/Handlers/DatabaseHandler.php b/system/Session/Handlers/DatabaseHandler.php
index 6d04569..2acdb16 100644
--- a/system/Session/Handlers/DatabaseHandler.php
+++ b/system/Session/Handlers/DatabaseHandler.php
@@ -1,4 +1,4 @@
-lockSession($sessionID) === false)
{
diff --git a/system/Session/Handlers/FileHandler.php b/system/Session/Handlers/FileHandler.php
index d14c01d..ac9bd10 100644
--- a/system/Session/Handlers/FileHandler.php
+++ b/system/Session/Handlers/FileHandler.php
@@ -1,4 +1,4 @@
-keyPrefix .= $this->ipAddress . ':';
}
-
- if(!empty($this->keyPrefix))
+
+ if (! empty($this->keyPrefix))
{
ini_set('memcached.sess_prefix', $this->keyPrefix);
}
@@ -115,7 +116,7 @@
*
* @return boolean
*/
- public function open($save_path, $name)
+ public function open($save_path, $name): bool
{
$this->memcached = new \Memcached();
$this->memcached->setOption(\Memcached::OPT_BINARY_PROTOCOL, true); // required for touch() usage
@@ -176,7 +177,7 @@
*
* @return string Serialized session data
*/
- public function read($sessionID)
+ public function read($sessionID): string
{
if (isset($this->memcached) && $this->lockSession($sessionID))
{
@@ -204,7 +205,7 @@
*
* @return boolean
*/
- public function write($sessionID, $sessionData)
+ public function write($sessionID, $sessionData): bool
{
if (! isset($this->memcached))
{
@@ -253,7 +254,7 @@
*
* @return boolean
*/
- public function close()
+ public function close(): bool
{
if (isset($this->memcached))
{
@@ -283,7 +284,7 @@
*
* @return boolean
*/
- public function destroy($session_id)
+ public function destroy($session_id): bool
{
if (isset($this->memcached, $this->lockKey))
{
@@ -306,7 +307,7 @@
*
* @return boolean
*/
- public function gc($maxlifetime)
+ public function gc($maxlifetime): bool
{
// Not necessary, Memcached takes care of that.
return true;
diff --git a/system/Session/Handlers/RedisHandler.php b/system/Session/Handlers/RedisHandler.php
index 5132785..1d50ba8 100644
--- a/system/Session/Handlers/RedisHandler.php
+++ b/system/Session/Handlers/RedisHandler.php
@@ -1,4 +1,4 @@
-sessionExpiration);
}
-
- if(!empty($this->sessionSavePath))
+
+ if (! empty($this->sessionSavePath))
{
ini_set('session.save_path', $this->sessionSavePath);
}
diff --git a/system/Session/SessionInterface.php b/system/Session/SessionInterface.php
index 4e9a47b..498a586 100644
--- a/system/Session/SessionInterface.php
+++ b/system/Session/SessionInterface.php
@@ -1,4 +1,4 @@
-dom, $function))
diff --git a/system/Test/ControllerTester.php b/system/Test/ControllerTester.php
index 0dad1b8..f132973 100644
--- a/system/Test/ControllerTester.php
+++ b/system/Test/ControllerTester.php
@@ -1,4 +1,5 @@
-response = new Response($this->appConfig);
}
- $this->controller = new $name($this->request, $this->response);
+ if (empty($this->logger))
+ {
+ $this->logger = Services::logger();
+ }
+
+ $this->controller = new $name();
+ $this->controller->initController($this->request, $this->response, $this->logger);
return $this;
}
@@ -110,7 +117,7 @@
* @param string $method
* @param array $params
*
- * @return \CodeIgniter\TestControllerResponse
+ * @return \CodeIgniter\Test\ControllerResponse|\InvalidArgumentException
*/
public function execute(string $method, ...$params)
{
@@ -124,9 +131,10 @@
helper('url');
$result = (new ControllerResponse())
- ->setRequest($this->request)
- ->setResponse($this->response);
+ ->setRequest($this->request)
+ ->setResponse($this->response);
+ $response = null;
try
{
ob_start();
@@ -136,21 +144,33 @@
catch (\Throwable $e)
{
$result->response()
- ->setStatusCode($e->getCode());
+ ->setStatusCode($e->getCode());
}
finally
{
$output = ob_get_clean();
- // If the controller returned a redirect response
- // then we need to use that...
+ // If the controller returned a response, use it
if (isset($response) && $response instanceof Response)
{
$result->setResponse($response);
}
- $result->response()->setBody($output);
- $result->setBody($output);
+ // check if controller returned a view rather than echoing it
+ if (is_string($response))
+ {
+ $output = $response;
+ $result->response()->setBody($output);
+ $result->setBody($output);
+ }
+ elseif (! empty($response) && ! empty($response->getBody()))
+ {
+ $result->setBody($response->getBody());
+ }
+ else
+ {
+ $result->setBody('');
+ }
}
// If not response code has been sent, assume a success
@@ -199,6 +219,18 @@
}
/**
+ * @param mixed $logger
+ *
+ * @return mixed
+ */
+ public function withLogger($logger)
+ {
+ $this->logger = $logger;
+
+ return $this;
+ }
+
+ /**
* @param string $uri
*
* @return mixed
diff --git a/system/Test/DOMParser.php b/system/Test/DOMParser.php
index 55bd10e..09befc8 100644
--- a/system/Test/DOMParser.php
+++ b/system/Test/DOMParser.php
@@ -1,4 +1,4 @@
-dom = new \DOMDocument('1.0', 'utf-8');
@@ -80,7 +88,11 @@
if (! $this->dom->loadHTML($content))
{
+ // unclear how we would get here, given that we are trapping libxml errors
+ // @codeCoverageIgnoreStart
+ libxml_clear_errors();
throw new \BadMethodCallException('Invalid HTML');
+ // @codeCoverageIgnoreEnd
}
// ignore the whitespace.
@@ -248,7 +260,7 @@
{
foreach ($selector['attr'] as $key => $value)
{
- $path .= "[{$key}={$value}]";
+ $path .= "[@{$key}=\"{$value}\"]";
}
}
diff --git a/system/Test/FeatureResponse.php b/system/Test/FeatureResponse.php
index 3a60672..2b8b75a 100644
--- a/system/Test/FeatureResponse.php
+++ b/system/Test/FeatureResponse.php
@@ -1,9 +1,49 @@
-tokenTime;
}
@@ -123,7 +125,7 @@
* @return boolean
* @internal param int $maxRequests
*/
- public function check(string $key, int $capacity, int $seconds, int $cost = 1)
+ public function check(string $key, int $capacity, int $seconds, int $cost = 1): bool
{
$tokenName = $this->prefix . $key;
@@ -193,7 +195,7 @@
*
* @return integer
*/
- public function time()
+ public function time(): int
{
return $this->testTime ?? time();
}
diff --git a/system/Throttle/ThrottlerInterface.php b/system/Throttle/ThrottlerInterface.php
index f1dfd0d..6bbbc59 100644
--- a/system/Throttle/ThrottlerInterface.php
+++ b/system/Throttle/ThrottlerInterface.php
@@ -1,5 +1,4 @@
-valid_email(trim($str));
- }
-
foreach (explode(',', $str) as $email)
{
$email = trim($email);
diff --git a/system/Validation/Rules.php b/system/Validation/Rules.php
index 4aa20a3..bc37610 100644
--- a/system/Validation/Rules.php
+++ b/system/Validation/Rules.php
@@ -1,4 +1,4 @@
-= mb_strlen($str));
}
@@ -254,11 +256,6 @@
*/
public function min_length(string $str = null, string $val, array $data): bool
{
- if (! is_numeric($val))
- {
- return false;
- }
-
return ($val <= mb_strlen($str));
}
@@ -284,7 +281,7 @@
//--------------------------------------------------------------------
/**
- * The field is required when any of the other fields are present
+ * The field is required when any of the other required fields are present
* in the data.
*
* Example (field is required when the password field is present):
@@ -336,8 +333,8 @@
//--------------------------------------------------------------------
/**
- * The field is required when all of the other fields are not present
- * in the data.
+ * The field is required when all of the other fields are present
+ * in the data but not required.
*
* Example (field is required when the id or email field is missing):
*
diff --git a/system/Validation/Validation.php b/system/Validation/Validation.php
index 29ca043..3191580 100644
--- a/system/Validation/Validation.php
+++ b/system/Validation/Validation.php
@@ -1,4 +1,4 @@
-rules;
}
@@ -540,13 +545,13 @@
*
* @param string|null $group
*
- * @return array|void
+ * @return array|ValidationException|null
*/
public function loadRuleGroup(string $group = null)
{
if (empty($group))
{
- return;
+ return null;
}
if (! isset($this->config->$group))
@@ -615,7 +620,7 @@
/**
* Returns the array of errors that were encountered during
- * a run() call. The array should be in the followig format:
+ * a run() call. The array should be in the following format:
*
* [
* 'field1' => 'error message',
diff --git a/system/Validation/ValidationInterface.php b/system/Validation/ValidationInterface.php
index d7c1003..9da71b2 100644
--- a/system/Validation/ValidationInterface.php
+++ b/system/Validation/ValidationInterface.php
@@ -1,4 +1,4 @@
- 'error message',
diff --git a/system/Validation/Views/list.php b/system/Validation/Views/list.php
index 50f0571..cc95156 100644
--- a/system/Validation/Views/list.php
+++ b/system/Validation/Views/list.php
@@ -1,5 +1,5 @@
-
+
- = esc($error) ?>
diff --git a/system/View/Cell.php b/system/View/Cell.php
index c1e5108..9ce4907 100644
--- a/system/View/Cell.php
+++ b/system/View/Cell.php
@@ -1,5 +1,4 @@
-data);
try
{
- $result = eval('?>' . $template . '' . $template . 'renderVars['start'] = microtime(true);
@@ -237,7 +239,7 @@
// When using layouts, the data has already been stored
// in $this->sections, and no other valid output
// is allowed in $output so we'll overwrite it.
- if (! is_null($this->layout))
+ if (! is_null($this->layout) && empty($this->currentSection))
{
$layoutView = $this->layout;
$this->layout = null;
@@ -294,7 +296,7 @@
*
* @return string
*/
- public function renderString(string $view, array $options = null, $saveData = null): string
+ public function renderString(string $view, array $options = null, bool $saveData = null): string
{
$start = microtime(true);
if (is_null($saveData))
@@ -388,7 +390,7 @@
*
* @return RendererInterface
*/
- public function resetData()
+ public function resetData(): RendererInterface
{
$this->data = [];
@@ -402,7 +404,7 @@
*
* @return array
*/
- public function getData()
+ public function getData(): array
{
return $this->data;
}
@@ -414,7 +416,7 @@
*
* @param string $layout
*
- * @return $this
+ * @return void
*/
public function extend(string $layout)
{
@@ -486,6 +488,22 @@
//--------------------------------------------------------------------
/**
+ * Used within layout views to include additional views.
+ *
+ * @param string $view
+ * @param array|null $options
+ * @param null $saveData
+ *
+ * @return string
+ */
+ public function include(string $view, array $options = null, $saveData = null): string
+ {
+ return $this->render($view, $options, $saveData);
+ }
+
+ //--------------------------------------------------------------------
+
+ /**
* Returns the performance data that might have been collected
* during the execution. Used primarily in the Debug Toolbar.
*