merging develop

This commit is contained in:
Lonnie Ezell 2018-04-22 23:42:00 -05:00
commit 8dde051d81
No known key found for this signature in database
GPG Key ID: 8EB408F8D82F5002
58 changed files with 1047 additions and 486 deletions

View File

@ -270,6 +270,9 @@ class App extends BaseConfig
| and state of your application during that page display. By default it will
| NOT be displayed under production environments, and will only display if
| CI_DEBUG is true, since if it's not, there's not much to display anyway.
|
| toolbarMaxHistory = Number of history files, 0 for none or -1 for unlimited
|
*/
public $toolbarCollectors = [
'CodeIgniter\Debug\Toolbar\Collectors\Timers',
@ -281,6 +284,7 @@ class App extends BaseConfig
'CodeIgniter\Debug\Toolbar\Collectors\Routes',
'CodeIgniter\Debug\Toolbar\Collectors\Events',
];
public $toolbarMaxHistory = 20;
/*
|--------------------------------------------------------------------------

View File

@ -36,7 +36,7 @@ class Cache extends BaseConfig
| system.
|
*/
public $path = WRITEPATH.'cache/';
public $storePath = WRITEPATH.'cache/';
/*
|--------------------------------------------------------------------------

View File

@ -33,15 +33,13 @@ class DebugToolbar implements FilterInterface
*/
public function after(RequestInterface $request, ResponseInterface $response)
{
$format = $response->getHeaderLine('content-type');
if ( ! is_cli() && CI_DEBUG && strpos($format, 'html') !== false)
if ( ! is_cli() && CI_DEBUG)
{
global $app;
$toolbar = Services::toolbar(new App());
$stats = $app->getPerformanceStats();
$output = $toolbar->run(
$data = $toolbar->run(
$stats['startTime'],
$stats['totalTime'],
$stats['startMemory'],
@ -49,7 +47,7 @@ class DebugToolbar implements FilterInterface
$response
);
helper(['filesystem', 'url']);
helper('filesystem');
// Updated to time() so we can get history
$time = time();
@ -59,7 +57,19 @@ class DebugToolbar implements FilterInterface
mkdir(WRITEPATH.'debugbar', 0777);
}
write_file(WRITEPATH .'debugbar/'.'debugbar_' . $time, $output, 'w+');
write_file(WRITEPATH .'debugbar/'.'debugbar_' . $time, $data, 'w+');
$format = $response->getHeaderLine('content-type');
// Non-HTML formats should not include the debugbar
// then we send headers saying where to find the debug data
// for this response
if ($request->isAJAX() || strpos($format, 'html') === false)
{
return $response->setHeader('Debugbar-Time', (string)$time)
->setHeader('Debugbar-Link', site_url("?debugbar_time={$time}"))
->getBody();
}
$script = PHP_EOL
. '<script type="text/javascript" id="debugbar_loader" '

View File

@ -1,15 +1,102 @@
<!DOCTYPE html>
<html>
<head>
<title>CodeIgniter 4 ... almost!</title>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
</head>
<body>
<p>If you see this message, you have not configured your web server properly.</p>
<p>You need to set your "document root" to the <code>public</code> folder
inside your project. This could be your default setting, or that of
a virtual host, depending on how you set up your local development
environment.</p>
</body>
<head>
<title>CodeIgniter 4 ... almost!</title>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<style>
div.logo {
height: 200px;
width: 155px;
display: inline-block;
opacity: 0.08;
position: absolute;
top: 2rem;
left: 50%;
margin-left: -73px;
}
body {
height: 100%;
background: #fafafa;
font-family: "Helvetica Neue", Helvetica, Arial, sans-serif;
color: #777;
font-weight: 300;
}
h1 {
font-weight: lighter;
letter-spacing: 0.8;
font-size: 3rem;
margin-top: 145px;
margin-bottom: 0;
color: #222;
}
.wrap {
max-width: 1024px;
margin: 5rem auto;
padding: 2rem;
background: #fff;
text-align: center;
border: 1px solid #efefef;
border-radius: 0.5rem;
position: relative;
}
.guide {
margin-top: 3rem;
text-align: left;
}
p {
margin-top: 1.5rem;
}
a:active,
a:link,
a:visited {
color: #dd4814;
}
</style>
</head>
<body>
<div class="wrap">
<h1>CodeIgniter 4 ... Almost!!!</h1>
<div class="logo">
<svg version="1.0" xmlns="http://www.w3.org/2000/svg"
width="155.000000px" height="200.000000px" viewBox="0 0 155.000000 200.000000"
preserveAspectRatio="xMidYMid meet">
<g transform="translate(0.000000,200.000000) scale(0.100000,-0.100000)" fill="#000000" stroke="none">
<path d="M737 1963 c22 -79 -7 -185 -78 -290 -18 -26 -107 -122 -197 -213
-239 -240 -336 -371 -403 -544 -79 -206 -78 -408 5 -582 64 -134 212 -264 361
-314 l60 -20 -30 22 c-210 152 -229 387 -48 588 25 27 48 50 51 50 4 0 7 -27
7 -61 0 -57 2 -62 37 -95 30 -27 46 -34 78 -34 56 0 99 24 116 65 29 69 16
120 -50 205 -105 134 -117 233 -43 347 l31 48 7 -47 c13 -82 58 -129 250 -258
209 -141 306 -261 328 -405 11 -72 -1 -161 -31 -218 -27 -53 -112 -143 -165
-174 -24 -14 -43 -26 -43 -28 0 -2 24 4 53 14 241 83 427 271 482 486 19 76
19 202 -1 285 -35 152 -146 305 -299 412 l-70 49 -6 -33 c-8 -48 -26 -76 -59
-93 -45 -23 -103 -19 -138 10 -67 57 -78 146 -37 305 30 116 32 206 5 291 -27
89 -104 206 -162 247 -17 13 -18 12 -11 -15z"/>
</g>
</svg>
</div>
<div class="guide">
<p>If you see this message, you have not configured your web server properly.</p>
<p>You need to set your "document root" to the <code>public</code> folder
inside your project. This could be your default setting, or that of
a virtual host, depending on how you set up your local development
environment.</p>
<p>If you are exploring CodeIgniter for the very first time, you
should start by reading the (in progress)
<a href="https://bcit-ci.github.io/CodeIgniter4">User Guide</a>.</p>
</div>
</div>
</body>
</html>

51
php_errors.log Normal file
View File

@ -0,0 +1,51 @@
[22-Feb-2018 03:32:25 UTC] PHP Warning: PHP Startup: Unable to load dynamic library '/usr/local/opt/php70-intl/intl.so' - dlopen(/usr/local/opt/php70-intl/intl.so, 9): Library not loaded: /usr/local/opt/icu4c/lib/libicui18n.59.dylib
Referenced from: /usr/local/opt/php70-intl/intl.so
Reason: image not found in Unknown on line 0
[22-Feb-2018 04:35:39 UTC] PHP Warning: PHP Startup: Unable to load dynamic library '/usr/local/opt/php70-intl/intl.so' - dlopen(/usr/local/opt/php70-intl/intl.so, 9): Library not loaded: /usr/local/opt/icu4c/lib/libicui18n.59.dylib
Referenced from: /usr/local/opt/php70-intl/intl.so
Reason: image not found in Unknown on line 0
[22-Feb-2018 04:35:43 UTC] PHP Warning: PHP Startup: Unable to load dynamic library '/usr/local/opt/php70-intl/intl.so' - dlopen(/usr/local/opt/php70-intl/intl.so, 9): Library not loaded: /usr/local/opt/icu4c/lib/libicui18n.59.dylib
Referenced from: /usr/local/opt/php70-intl/intl.so
Reason: image not found in Unknown on line 0
[23-Feb-2018 05:01:52 UTC] PHP Warning: PHP Startup: Unable to load dynamic library '/usr/local/opt/php70-intl/intl.so' - dlopen(/usr/local/opt/php70-intl/intl.so, 9): Library not loaded: /usr/local/opt/icu4c/lib/libicui18n.59.dylib
Referenced from: /usr/local/opt/php70-intl/intl.so
Reason: image not found in Unknown on line 0
[23-Feb-2018 05:01:54 UTC] PHP Warning: PHP Startup: Unable to load dynamic library '/usr/local/opt/php70-intl/intl.so' - dlopen(/usr/local/opt/php70-intl/intl.so, 9): Library not loaded: /usr/local/opt/icu4c/lib/libicui18n.59.dylib
Referenced from: /usr/local/opt/php70-intl/intl.so
Reason: image not found in Unknown on line 0
[23-Feb-2018 05:02:01 UTC] PHP Warning: PHP Startup: Unable to load dynamic library '/usr/local/opt/php70-intl/intl.so' - dlopen(/usr/local/opt/php70-intl/intl.so, 9): Library not loaded: /usr/local/opt/icu4c/lib/libicui18n.59.dylib
Referenced from: /usr/local/opt/php70-intl/intl.so
Reason: image not found in Unknown on line 0
[23-Feb-2018 05:02:09 UTC] PHP Warning: PHP Startup: Unable to load dynamic library '/usr/local/opt/php70-intl/intl.so' - dlopen(/usr/local/opt/php70-intl/intl.so, 9): Library not loaded: /usr/local/opt/icu4c/lib/libicui18n.59.dylib
Referenced from: /usr/local/opt/php70-intl/intl.so
Reason: image not found in Unknown on line 0
[23-Feb-2018 05:02:12 UTC] PHP Warning: PHP Startup: Unable to load dynamic library '/usr/local/opt/php70-intl/intl.so' - dlopen(/usr/local/opt/php70-intl/intl.so, 9): Library not loaded: /usr/local/opt/icu4c/lib/libicui18n.59.dylib
Referenced from: /usr/local/opt/php70-intl/intl.so
Reason: image not found in Unknown on line 0
[23-Feb-2018 05:04:00 UTC] PHP Warning: PHP Startup: Unable to load dynamic library '/usr/local/opt/php70-intl/intl.so' - dlopen(/usr/local/opt/php70-intl/intl.so, 9): Library not loaded: /usr/local/opt/icu4c/lib/libicui18n.59.dylib
Referenced from: /usr/local/opt/php70-intl/intl.so
Reason: image not found in Unknown on line 0
[23-Feb-2018 05:04:09 UTC] PHP Warning: PHP Startup: Unable to load dynamic library '/usr/local/opt/php70-intl/intl.so' - dlopen(/usr/local/opt/php70-intl/intl.so, 9): Library not loaded: /usr/local/opt/icu4c/lib/libicui18n.59.dylib
Referenced from: /usr/local/opt/php70-intl/intl.so
Reason: image not found in Unknown on line 0
[23-Feb-2018 05:07:05 UTC] PHP Warning: PHP Startup: Unable to load dynamic library '/usr/local/opt/php70-intl/intl.so' - dlopen(/usr/local/opt/php70-intl/intl.so, 9): Library not loaded: /usr/local/opt/icu4c/lib/libicui18n.59.dylib
Referenced from: /usr/local/opt/php70-intl/intl.so
Reason: image not found in Unknown on line 0
[23-Feb-2018 05:24:37 UTC] PHP Warning: PHP Startup: Unable to load dynamic library '/usr/local/opt/php70-intl/intl.so' - dlopen(/usr/local/opt/php70-intl/intl.so, 9): Library not loaded: /usr/local/opt/icu4c/lib/libicui18n.59.dylib
Referenced from: /usr/local/opt/php70-intl/intl.so
Reason: image not found in Unknown on line 0
[23-Feb-2018 05:24:39 UTC] PHP Warning: PHP Startup: Unable to load dynamic library '/usr/local/opt/php70-intl/intl.so' - dlopen(/usr/local/opt/php70-intl/intl.so, 9): Library not loaded: /usr/local/opt/icu4c/lib/libicui18n.59.dylib
Referenced from: /usr/local/opt/php70-intl/intl.so
Reason: image not found in Unknown on line 0
[23-Feb-2018 05:24:46 UTC] PHP Warning: PHP Startup: Unable to load dynamic library '/usr/local/opt/php70-intl/intl.so' - dlopen(/usr/local/opt/php70-intl/intl.so, 9): Library not loaded: /usr/local/opt/icu4c/lib/libicui18n.59.dylib
Referenced from: /usr/local/opt/php70-intl/intl.so
Reason: image not found in Unknown on line 0
[23-Feb-2018 05:24:50 UTC] PHP Warning: PHP Startup: Unable to load dynamic library '/usr/local/opt/php70-intl/intl.so' - dlopen(/usr/local/opt/php70-intl/intl.so, 9): Library not loaded: /usr/local/opt/icu4c/lib/libicui18n.59.dylib
Referenced from: /usr/local/opt/php70-intl/intl.so
Reason: image not found in Unknown on line 0
[23-Feb-2018 05:25:00 UTC] PHP Warning: PHP Startup: Unable to load dynamic library '/usr/local/opt/php70-intl/intl.so' - dlopen(/usr/local/opt/php70-intl/intl.so, 9): Library not loaded: /usr/local/opt/icu4c/lib/libicui18n.59.dylib
Referenced from: /usr/local/opt/php70-intl/intl.so
Reason: image not found in Unknown on line 0
[23-Feb-2018 05:25:10 UTC] PHP Warning: PHP Startup: Unable to load dynamic library '/usr/local/opt/php70-intl/intl.so' - dlopen(/usr/local/opt/php70-intl/intl.so, 9): Library not loaded: /usr/local/opt/icu4c/lib/libicui18n.59.dylib
Referenced from: /usr/local/opt/php70-intl/intl.so
Reason: image not found in Unknown on line 0

View File

@ -33,6 +33,6 @@
</filter>
<logging>
<log type="coverage-clover" target="build/logs/clover.xml"/>
<!--<log type="coverage-clover" target="build/logs/clover.xml"/>-->
</logging>
</phpunit>

View File

@ -35,8 +35,8 @@
* @since Version 3.0.0
* @filesource
*/
use CodeIgniter\Cache\CacheInterface;
use CodeIgniter\CriticalError;
use CodeIgniter\Cache\CacheInterface;
class RedisHandler implements CacheInterface
{
@ -70,8 +70,9 @@ class RedisHandler implements CacheInterface
//--------------------------------------------------------------------
public function __construct(array $config)
public function __construct($config)
{
$config = (array)$config;
$this->prefix = $config['prefix'] ?? '';
if ( ! empty($config))

View File

@ -109,7 +109,7 @@ class CreateMigration extends BaseCommand
'matchIP' => $config->sessionMatchIP ?? false,
];
$template = view('\CodeIgniter\Commands\Sessions\Views\migration.tpl', $data);
$template = view('\CodeIgniter\Commands\Sessions\Views\migration.tpl', $data, ['debug' => false]);
$template = str_replace('@php', '<?php', $template);
// Write the file out.

View File

@ -1,41 +1,5 @@
@php namespace <?= $namespace ?>\Database\Migrations;
/**
* CodeIgniter
*
* An open source application development framework for PHP
*
* This content is released under the MIT License (MIT)
*
* Copyright (c) 2014-2018 British Columbia Institute of Technology
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*
* @package CodeIgniter
* @author CodeIgniter Dev Team
* @copyright 2014-2018 British Columbia Institute of Technology (https://bcit.ca/)
* @license https://opensource.org/licenses/MIT MIT License
* @link https://codeigniter.com
* @since Version 3.0.0
* @filesource
*/
use CodeIgniter\Database\Migration;
class Migration_create_<?= $tableName ?>_table extends Migration

View File

@ -282,14 +282,15 @@ if ( ! function_exists('session'))
*/
function session($val = null)
{
$session = \Config\Services::session();
// Returning a single item?
if (is_string($val))
{
helper('array');
return dot_array_search($val, $_SESSION);
return $session->get($val);
}
return \Config\Services::session();
return $session;
}
}

View File

@ -101,7 +101,7 @@ class BaseConfig
elseif ($value === 'true')
$value = true;
$this->$property = $value;
$this->$property = trim($value, '\'"');
}
}
}

View File

@ -220,16 +220,18 @@ class Services
* - set_error_handler
* - register_shutdown_function
*
* @param \Config\Exceptions $config
* @param bool $getShared
* @param \Config\Exceptions $config
* @param \CodeIgniter\HTTP\IncomingRequest $request
* @param \CodeIgniter\HTTP\Response $response
* @param bool $getShared
*
* @return \CodeIgniter\Debug\Exceptions
*/
public static function exceptions(\Config\Exceptions $config = null, $getShared = true)
public static function exceptions(\Config\Exceptions $config = null, \CodeIgniter\HTTP\IncomingRequest $request = null, \CodeIgniter\HTTP\Response $response = null, $getShared = true)
{
if ($getShared)
{
return self::getSharedInstance('exceptions', $config);
return self::getSharedInstance('exceptions', $config, $request, $response);
}
if (empty($config))
@ -237,7 +239,17 @@ class Services
$config = new \Config\Exceptions();
}
return (new \CodeIgniter\Debug\Exceptions($config));
if (empty($request))
{
$request = static::request();
}
if (empty($response))
{
$response = static::response();
}
return (new \CodeIgniter\Debug\Exceptions($config, $request, $response));
}
//--------------------------------------------------------------------

View File

@ -170,11 +170,11 @@ class Controller
//--------------------------------------------------------------------
/**
* A shortcut to performing validation on $_POST input. If validation
* A shortcut to performing validation on input data. If validation
* is not successful, a $errors property will be set on this class.
*
* @param $rules
* @param array|null $messages
* @param array $rules
* @param array $messages An array of custom error messages
*
* @return bool
*/

View File

@ -389,7 +389,7 @@ class MigrationRunner
$location = $config->psr4[$this->namespace];
// Setting migration directories.
$dir = rtrim($location, '/') . '/Database/Migrations/';
$dir = rtrim($location, DIRECTORY_SEPARATOR) . '/Database/Migrations/';
// Load all *_*.php files in the migrations path
foreach (glob($dir . '*_*.php') as $file)

View File

@ -35,7 +35,6 @@
* @since Version 3.0.0
* @filesource
*/
use Config\Services;
require __DIR__.'/CustomExceptions.php';
@ -44,6 +43,8 @@ require __DIR__.'/CustomExceptions.php';
*/
class Exceptions
{
use \CodeIgniter\API\ResponseTrait;
/**
* Nesting level of the output buffering mechanism
*
@ -64,20 +65,35 @@ class Exceptions
*/
protected $config;
/**
* @var \CodeIgniter\HTTP\IncomingRequest
*/
protected $request;
/**
* @var \CodeIgniter\HTTP\Response
*/
protected $response;
//--------------------------------------------------------------------
/**
* Constructor.
*
* @param \Config\Exceptions $config
* @param \Config\Exceptions $config
* @param \CodeIgniter\HTTP\IncomingRequest $request
* @param \CodeIgniter\HTTP\Response $response
*/
public function __construct(\Config\Exceptions $config)
public function __construct(\Config\Exceptions $config, \CodeIgniter\HTTP\IncomingRequest $request, \CodeIgniter\HTTP\Response $response)
{
$this->ob_level = ob_get_level();
$this->viewPath = rtrim($config->errorViewPath, '/ ') . '/';
$this->config = $config;
$this->request = $request;
$this->response = $response;
}
//--------------------------------------------------------------------
@ -124,9 +140,16 @@ class Exceptions
if (! is_cli())
{
$response = Services::response()->setStatusCode($statusCode);
$header = "HTTP/1.1 {$response->getStatusCode()} {$response->getReason()}";
$this->response->setStatusCode($statusCode);
$header = "HTTP/{$this->request->getProtocolVersion()} {$this->response->getStatusCode()} {$this->response->getReason()}";
header($header, true, $statusCode);
if (strpos($this->request->getHeaderLine('accept'), 'text/html') === false)
{
$this->respond(ENVIRONMENT === 'development' ? $this->collectVars($exception, $statusCode) : '', $statusCode)->send();
exit($exitCode);
}
}
$this->render($exception, $statusCode);
@ -271,13 +294,13 @@ class Exceptions
protected function collectVars(\Throwable $exception, int $statusCode)
{
return [
'type' => get_class($exception),
'code' => $statusCode,
'title' => get_class($exception),
'type' => get_class($exception),
'code' => $statusCode,
'message' => $exception->getMessage() ?? '(null)',
'file' => $exception->getFile(),
'line' => $exception->getLine(),
'trace' => $exception->getTrace(),
'title' => get_class($exception)
'file' => $exception->getFile(),
'line' => $exception->getLine(),
'trace' => $exception->getTrace(),
];
}

View File

@ -37,6 +37,7 @@
*/
use CodeIgniter\Config\BaseConfig;
use Config\Services;
use CodeIgniter\Format\XMLFormatter;
/**
* Debug Toolbar
@ -58,9 +59,11 @@ class Toolbar
protected $collectors = [];
/**
* @var float App start time
* Incoming Request
*
* @var \CodeIgniter\HTTP\IncomingRequest
*/
protected $startTime;
protected static $request;
//--------------------------------------------------------------------
@ -86,33 +89,207 @@ class Toolbar
//--------------------------------------------------------------------
/**
* Run
* Returns all the data required by Debug Bar
*
* @param float $startTime
* @param float $startTime App start time
* @param float $totalTime
* @param float $startMemory
* @param \CodeIgniter\HTTP\RequestInterface $request
* @param \CodeIgniter\HTTP\ResponseInterface $response
*
* @return string
* @return string JSON encoded data
*/
public function run($startTime, $totalTime, $startMemory, $request, $response): string
{
$this->startTime = $startTime;
// Data items used within the view.
$collectors = $this->collectors;
$data['url'] = current_url();
$data['method'] = $request->getMethod(true);
$data['isAJAX'] = $request->isAJAX();
$data['startTime'] = $startTime;
$data['totalTime'] = $totalTime*1000;
$data['totalMemory'] = number_format((memory_get_peak_usage()-$startMemory)/1048576, 3);
$data['segmentDuration'] = $this->roundTo($data['totalTime']/7, 5);
$data['segmentCount'] = (int)ceil($data['totalTime']/$data['segmentDuration']);
$data['CI_VERSION'] = \CodeIgniter\CodeIgniter::CI_VERSION;
$data['collectors'] = [];
$totalTime = $totalTime*1000;
$totalMemory = number_format((memory_get_peak_usage()-$startMemory)/1048576, 3);
$segmentDuration = $this->roundTo($totalTime/7, 5);
$segmentCount = (int)ceil($totalTime/$segmentDuration);
$varData = $this->collectVarData();
foreach($this->collectors as $collector)
{
$data['collectors'][] = [
'title' => $collector->getTitle(),
'titleSafe' => $collector->getTitle(true),
'titleDetails' => $collector->getTitleDetails(),
'display' => $collector->display(),
'badgeValue' => $collector->getBadgeValue(),
'isEmpty' => $collector->isEmpty(),
'hasTabContent' => $collector->hasTabContent(),
'hasLabel' => $collector->hasLabel(),
'icon' => $collector->icon(),
'hasTimelineData' => $collector->hasTimelineData(),
'timelineData' => $collector->timelineData(),
];
}
ob_start();
include(__DIR__.'/Toolbar/Views/toolbar.tpl.php');
$output = ob_get_contents();
ob_end_clean();
foreach ($this->collectVarData() as $heading => $items)
{
$vardata = [];
if (is_array($items))
{
foreach ($items as $key => $value)
{
$vardata[esc($key)] = is_string($value) ? esc($value) : print_r($value, true);
}
}
$data['vars']['varData'][esc($heading)] = $vardata;
}
if (isset($_SESSION) && ! empty($_SESSION))
{
foreach ($_SESSION as $key => $value)
{
$data['vars']['session'][esc($key)] = is_string($value) ? esc($value) : print_r($value, true);
}
}
foreach ($request->getGet() as $name => $value)
{
$data['vars']['get'][esc($name)] = esc($value);
}
foreach ($request->getPost() as $name => $value)
{
$data['vars']['post'][esc($name)] = is_array($value) ? esc(print_r($value, true)) : esc($value);
}
foreach ($request->getHeaders() as $header => $value)
{
if (empty($value))
{
continue;
}
if (! is_array($value))
{
$value = [$value];
}
foreach ($value as $h)
{
$data['vars']['headers'][esc($h->getName())] = esc($h->getValueLine());
}
}
foreach ($request->getCookie() as $name => $value)
{
$data['vars']['cookies'][esc($name)] = esc($value);
}
$data['vars']['request'] = ($request->isSecure() ? 'HTTPS' : 'HTTP').'/'.$request->getProtocolVersion();
$data['vars']['response'] = [
'statusCode' => $response->getStatusCode(),
'reason' => esc($response->getReason()),
'contentType' => esc($response->getHeaderLine('content-type')),
];
$data['config'] = \CodeIgniter\Debug\Toolbar\Collectors\Config::display();
return json_encode($data);
}
//--------------------------------------------------------------------
/**
* Format output
*
* @param string $data JSON encoded Toolbar data
* @param string $format html, json, xml
*
* @return string
*/
protected static function format(string $data, string $format = 'html')
{
$data = json_decode($data, true);
// History must be loaded on the fly
$filenames = glob(WRITEPATH.'debugbar/debugbar_*');
$total = count($filenames);
rsort($filenames);
$files = [];
$current = self::$request->getGet('debugbar_time');
$app = new \Config\App;
for ($i = 0; $i < $total; $i++)
{
// Get the contents of this specific history request
ob_start();
include($filenames[$i]);
$contents = ob_get_contents();
ob_end_clean();
$file = json_decode($contents, true);
// Debugbar files shown in History Collector
$files[$i] = [
'time' => (int)$time = substr($filenames[$i], -10),
'datetime' => date('Y-m-d H:i:s', $time),
'active' => (int)($time == $current),
'status' => $file['vars']['response']['statusCode'],
'method' => $file['method'],
'url' => $file['url'],
'isAJAX' => $file['isAJAX'] ? 'Yes' : 'No',
'contentType' => $file['vars']['response']['contentType'],
];
// Oldest files will be deleted
if ($app->toolbarMaxHistory >= 0 && $i >= $app->toolbarMaxHistory)
{
unlink($filenames[$i]);
continue;
}
}
// Set the History here. Class is not necessary
$data['collectors'][] = [
'title' => 'History',
'titleSafe' => 'history',
'titleDetails' => '',
'display' => ['files' => $files],
'badgeValue' => $count = count($files),
'isEmpty' => ! (bool)$count,
'hasTabContent' => true,
'hasLabel' => true,
'icon' => 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABgAAAAYCAYAAADgdz34AAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAJySURBVEhL3ZU7aJNhGIVTpV6i4qCIgkIHxcXLErS4FBwUFNwiCKGhuTYJGaIgnRoo4qRu6iCiiIuIXXTTIkIpuqoFwaGgonUQlC5KafU5ycmNP0lTdPLA4fu+8573/a4/f6hXpFKpwUwmc9fDfweKbk+n07fgEv33TLSbtt/hvwNFT1PsG/zdTE0Gp+GFfD6/2fbVIxqNrqPIRbjg4t/hY8aztcngfDabHXbKyiiXy2vcrcPH8oDCry2FKDrA+Ar6L01E/ypyXzXaARjDGGcoeNxSDZXE0dHRA5VRE5LJ5CFy5jzJuOX2wHRHRnjbklZ6isQ3tIctBaAd4vlK3jLtkOVWqABBXd47jGHLmjTmSScttQV5J+SjfcUweFQEbsjAas5aqoCLXutJl7vtQsAzpRowYqkBinyCC8Vicb2lOih8zoldd0F8RD7qTFiqAnGrAy8stUAvi/hbqDM+YzkAFrLPdR5ZqoLXsd+Bh5YCIH7JniVdquUWxOPxDfboHhrI5XJ7HHhiqQXox+APe/Qk64+gGYVCYZs8cMpSFQj9JOoFzVqqo7k4HIvFYpscCoAjOmLffUsNUGRaQUwDlmofUa34ecsdgXdcXo4wbakBgiUFafXJV8A4DJ/2UrxUKm3E95H8RbjLcgOJRGILhnmCP+FBy5XvwN2uIPcy1AJvWgqC4xm2aU4Xb3lF4I+Tpyf8hRe5w3J7YLymSeA8Z3nSclv4WLRyFdfOjzrUFX0klJUEtZtntCNc+F69cz/FiDzEPtjzmcUMOr83kDQEX6pAJxJfpL3OX22n01YN7SZCoQnaSdoZ+Jz+PZihH3wt/xlCoT9M6nEtmRSPCQAAAABJRU5ErkJggg==',
'hasTimelineData' => false,
'timelineData' => [],
];
$output = '';
switch ($format)
{
case 'html':
extract($data);
$parser = Services::parser(BASEPATH . 'Debug/Toolbar/Views/', null,false);
ob_start();
include(__DIR__.'/Toolbar/Views/toolbar.tpl.php');
$output = ob_get_contents();
ob_end_clean();
break;
case 'json':
$output = json_encode($data);
break;
case 'json':
$output = json_encode($data);
case 'xml':
$formatter = new XMLFormatter;
$output = $formatter->format($data);
break;
}
return $output;
}
@ -122,18 +299,18 @@ class Toolbar
/**
* Called within the view to display the timeline itself.
*
* @param int $segmentCount
* @param int $segmentDuration
* @param array $collectors
* @param float $startTime
* @param int $segmentCount
* @param int $segmentDuration
*
* @return string
*/
protected function renderTimeline(int $segmentCount, int $segmentDuration): string
protected static function renderTimeline(array $collectors, $startTime, int $segmentCount, int $segmentDuration): string
{
$displayTime = $segmentCount*$segmentDuration;
$rows = $this->collectTimelineData();
$output = '';
$rows = self::collectTimelineData($collectors);
$output = '';
foreach ($rows as $row)
{
@ -143,15 +320,12 @@ class Toolbar
$output .= "<td style='text-align: right'>".number_format($row['duration']*1000, 2)." ms</td>";
$output .= "<td colspan='{$segmentCount}' style='overflow: hidden'>";
$offset = ((($row['start']-$this->startTime)*1000)/
$displayTime)*100;
$offset = ((($row['start']-$startTime)*1000)/$displayTime)*100;
$length = (($row['duration']*1000)/$displayTime)*100;
$output .= "<span class='timer' style='left: {$offset}%; width: {$length}%;' title='".number_format($length,
2)."%'></span>";
$output .= "</td>";
$output .= "</tr>";
}
@ -165,24 +339,23 @@ class Toolbar
*
* @return array
*/
protected function collectTimelineData(): array
protected static function collectTimelineData($collectors): array
{
$data = [];
// Collect it
foreach ($this->collectors as $collector)
foreach ($collectors as $collector)
{
if (! $collector->hasTimelineData())
if (! $collector['hasTimelineData'])
{
continue;
}
$data = array_merge($data, $collector->timelineData());
$data = array_merge($data, $collector['timelineData']);
}
// Sort it
return $data;
}
@ -235,11 +408,11 @@ class Toolbar
*/
public static function eventHandler()
{
$request = Services::request();
self::$request = Services::request();
// If the request contains '?debugbar then we're
// simply returning the loading script
if ($request->getGet('debugbar') !== null)
if (self::$request->getGet('debugbar') !== null)
{
// Let the browser know that we are sending javascript
header('Content-Type: application/javascript');
@ -254,23 +427,31 @@ class Toolbar
// Otherwise, if it includes ?debugbar_time, then
// we should return the entire debugbar.
if ($request->getGet('debugbar_time'))
if (self::$request->getGet('debugbar_time'))
{
helper('security');
$file = sanitize_filename('debugbar_'.$request->getGet('debugbar_time'));
// Negotiate the content-type to format the output
$format = self::$request->negotiate('media', [
'text/html',
'application/json',
'application/xml'
]);
$format = explode('/', $format)[1];
$file = sanitize_filename('debugbar_'.self::$request->getGet('debugbar_time'));
$filename = WRITEPATH.'debugbar/'.$file;
// Show the toolbar
if (file_exists($filename))
{
$contents = file_get_contents($filename);
unlink($filename);
$contents = self::format(file_get_contents($filename), $format);
exit($contents);
}
// File was not written or do not exists
exit('<script id="toolbar_js">console.log(\'CI DebugBar: File "WRITEPATH/'.$file.'" not found.\')</script>');
http_response_code(404);
exit(); // Exit here is needed to avoid load the index page
}
}
}

View File

@ -229,14 +229,13 @@ class BaseCollector
//--------------------------------------------------------------------
/**
* Builds and returns the HTML needed to fill a tab to display
* within the Debug Bar
* Returns the data of this collector to be formatted in the toolbar
*
* @return string
* @return array
*/
public function display(): string
public function display(): array
{
return '';
return [];
}
//--------------------------------------------------------------------

View File

@ -9,24 +9,17 @@ class Config
public static function display()
{
$config = new App();
$parser = \Config\Services::parser(BASEPATH . 'Debug/Toolbar/Views/', null,false);
$data = [
'ciVersion' => CodeIgniter::CI_VERSION,
'phpVersion' => phpversion(),
'phpSAPI' => php_sapi_name(),
return [
'ciVersion' => CodeIgniter::CI_VERSION,
'phpVersion' => phpversion(),
'phpSAPI' => php_sapi_name(),
'environment' => ENVIRONMENT,
'baseURL' => $config->baseURL,
'timezone' => app_timezone(),
'locale' => Services::request()->getLocale(),
'cspEnabled' => $config->CSPEnabled,
'salt' => $config->salt,
'baseURL' => $config->baseURL,
'timezone' => app_timezone(),
'locale' => Services::request()->getLocale(),
'cspEnabled' => $config->CSPEnabled,
'salt' => $config->salt,
];
$output = $parser->setData($data)
->render('_config.tpl');
return $output;
}
}

View File

@ -149,11 +149,11 @@ class Database extends BaseCollector
//--------------------------------------------------------------------
/**
* Returns the HTML to fill the Database tab in the toolbar.
* Returns the data of this collector to be formatted in the toolbar
*
* @return string The data formatted for the toolbar.
* @return array
*/
public function display(): string
public function display(): array
{
// Key words we want bolded
$highlight = ['SELECT', 'DISTINCT', 'FROM', 'WHERE', 'AND', 'LEFT&nbsp;JOIN', 'ORDER&nbsp;BY', 'GROUP&nbsp;BY',
@ -161,8 +161,6 @@ class Database extends BaseCollector
'IN', 'LIKE', 'NOT&nbsp;LIKE', 'COUNT', 'MAX', 'MIN', 'ON', 'AS', 'AVG', 'SUM', '(', ')'
];
$parser = \Config\Services::parser(BASEPATH . 'Debug/Toolbar/Views/', null,false);
$data = [
'queries' => []
];
@ -182,10 +180,7 @@ class Database extends BaseCollector
];
}
$output = $parser->setData($data)
->render('_database.tpl');
return $output;
return $data;
}
//--------------------------------------------------------------------
@ -236,9 +231,7 @@ class Database extends BaseCollector
*/
public function icon(): string
{
return <<<EOD
<img src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABgAAAAYCAYAAADgdz34AAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAADMSURBVEhLY6A3YExLSwsA4nIycQDIDIhRWEBqamo/UNF/SjDQjF6ocZgAKPkRiFeEhoYyQ4WIBiA9QAuWAPEHqBAmgLqgHcolGQD1V4DMgHIxwbCxYD+QBqcKINseKo6eWrBioPrtQBq/BcgY5ht0cUIYbBg2AJKkRxCNWkDQgtFUNJwtABr+F6igE8olGQD114HMgHIxAVDyAhA/AlpSA8RYUwoeXAPVex5qHCbIyMgwBCkAuQJIY00huDBUz/mUlBQDqHGjgBjAwAAACexpph6oHSQAAAAASUVORK5CYII=">
EOD;
return 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABgAAAAYCAYAAADgdz34AAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAADMSURBVEhLY6A3YExLSwsA4nIycQDIDIhRWEBqamo/UNF/SjDQjF6ocZgAKPkRiFeEhoYyQ4WIBiA9QAuWAPEHqBAmgLqgHcolGQD1V4DMgHIxwbCxYD+QBqcKINseKo6eWrBioPrtQBq/BcgY5ht0cUIYbBg2AJKkRxCNWkDQgtFUNJwtABr+F6igE8olGQD114HMgHIxAVDyAhA/AlpSA8RYUwoeXAPVex5qHCbIyMgwBCkAuQJIY00huDBUz/mUlBQDqHGjgBjAwAAACexpph6oHSQAAAAASUVORK5CYII=';
}

View File

@ -122,14 +122,12 @@ class Events extends BaseCollector
//--------------------------------------------------------------------
/**
* Returns the HTML to fill the Events tab in the toolbar.
* Returns the data of this collector to be formatted in the toolbar
*
* @return string The data formatted for the toolbar.
* @return array
*/
public function display(): string
public function display(): array
{
$parser = \Config\Services::parser(BASEPATH . 'Debug/Toolbar/Views/', null,false);
$data = [
'events' => []
];
@ -153,10 +151,7 @@ class Events extends BaseCollector
$data['events'][$key]['count']++;
}
$output = $parser->setData($data)
->render('_events.tpl');
return $output;
return $data;
}
//--------------------------------------------------------------------
@ -180,9 +175,7 @@ class Events extends BaseCollector
*/
public function icon(): string
{
return <<<EOD
<img src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABgAAAAYCAYAAADgdz34AAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAEASURBVEhL7ZXNDcIwDIVTsRBH1uDQDdquUA6IM1xgCA6MwJUN2hk6AQzAz0vl0ETUxC5VT3zSU5w81/mRMGZysixbFEVR0jSKNt8geQU9aRpFmp/keX6AbjZ5oB74vsaN5lSzA4tLSjpBFxsjeSuRy4d2mDdQTWU7YLbXTNN05mKyovj5KL6B7q3hoy3KwdZxBlT+Ipz+jPHrBqOIynZgcZonoukb/0ckiTHqNvDXtXEAaygRbaB9FvUTjRUHsIYS0QaSp+Dw6wT4hiTmYHOcYZsdLQ2CbXa4ftuuYR4x9vYZgdb4vsFYUdmABMYeukK9/SUme3KMFQ77+Yfzh8eYF8+orDuDWU5LAAAAAElFTkSuQmCC">
EOD;
return 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABgAAAAYCAYAAADgdz34AAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAEASURBVEhL7ZXNDcIwDIVTsRBH1uDQDdquUA6IM1xgCA6MwJUN2hk6AQzAz0vl0ETUxC5VT3zSU5w81/mRMGZysixbFEVR0jSKNt8geQU9aRpFmp/keX6AbjZ5oB74vsaN5lSzA4tLSjpBFxsjeSuRy4d2mDdQTWU7YLbXTNN05mKyovj5KL6B7q3hoy3KwdZxBlT+Ipz+jPHrBqOIynZgcZonoukb/0ckiTHqNvDXtXEAaygRbaB9FvUTjRUHsIYS0QaSp+Dw6wT4hiTmYHOcYZsdLQ2CbXa4ftuuYR4x9vYZgdb4vsFYUdmABMYeukK9/SUme3KMFQ77+Yfzh8eYF8+orDuDWU5LAAAAAElFTkSuQmCC';
}
}

View File

@ -81,15 +81,12 @@ class Files extends BaseCollector
//--------------------------------------------------------------------
/**
* Builds and returns the HTML needed to fill a tab to display
* within the Debug Bar
* Returns the data of this collector to be formatted in the toolbar
*
* @return string
* @return array
*/
public function display(): string
public function display(): array
{
$parser = \Config\Services::parser(BASEPATH . 'Debug/Toolbar/Views/', null, false);
$rawFiles = get_included_files();
$coreFiles = [];
$userFiles = [];
@ -117,11 +114,10 @@ class Files extends BaseCollector
sort($userFiles);
sort($coreFiles);
return $parser->setData([
'coreFiles' => $coreFiles,
'userFiles' => $userFiles,
])
->render('_files.tpl');
return [
'coreFiles' => $coreFiles,
'userFiles' => $userFiles,
];
}
//--------------------------------------------------------------------
@ -147,9 +143,7 @@ class Files extends BaseCollector
*/
public function icon(): string
{
return <<<EOD
<img src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABgAAAAYCAYAAADgdz34AAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAGBSURBVEhL7ZQ9S8NQGIVTBQUncfMfCO4uLgoKbuKQOWg+OkXERRE1IAXrIHbVDrqIDuLiJgj+gro7S3dnpfq88b1FMTE3VZx64HBzzvvZWxKnj15QCcPwCD5HUfSWR+JtzgmtsUcQBEva5IIm9SwSu+95CAWbUuy67qBa32ByZEDpIaZYZSZMjjQuPcQUq8yEyYEb8FSerYeQVGbAFzJkX1PyQWLhgCz0BxTCekC1Wp0hsa6yokzhed4oje6Iz6rlJEkyIKfUEFtITVtQdAibn5rMyaYsMS+a5wTv8qeXMhcU16QZbKgl3hbs+L4/pnpdc87MElZgq10p5DxGdq8I7xrvUWUKvG3NbSK7ubngYzdJwSsF7TiOh9VOgfcEz1UayNe3JUPM1RWC5GXYgTfc75B4NBmXJnAtTfpABX0iPvEd9ezALwkplCFXcr9styiNOKc1RRZpaPM9tcqBwlWzGY1qPL9wjqRBgF5BH6j8HWh2S7MHlX8PrmbK+k/8PzjOOzx1D3i1pKTTAAAAAElFTkSuQmCC">
EOD;
return 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABgAAAAYCAYAAADgdz34AAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAGBSURBVEhL7ZQ9S8NQGIVTBQUncfMfCO4uLgoKbuKQOWg+OkXERRE1IAXrIHbVDrqIDuLiJgj+gro7S3dnpfq88b1FMTE3VZx64HBzzvvZWxKnj15QCcPwCD5HUfSWR+JtzgmtsUcQBEva5IIm9SwSu+95CAWbUuy67qBa32ByZEDpIaZYZSZMjjQuPcQUq8yEyYEb8FSerYeQVGbAFzJkX1PyQWLhgCz0BxTCekC1Wp0hsa6yokzhed4oje6Iz6rlJEkyIKfUEFtITVtQdAibn5rMyaYsMS+a5wTv8qeXMhcU16QZbKgl3hbs+L4/pnpdc87MElZgq10p5DxGdq8I7xrvUWUKvG3NbSK7ubngYzdJwSsF7TiOh9VOgfcEz1UayNe3JUPM1RWC5GXYgTfc75B4NBmXJnAtTfpABX0iPvEd9ezALwkplCFXcr9styiNOKc1RRZpaPM9tcqBwlWzGY1qPL9wjqRBgF5BH6j8HWh2S7MHlX8PrmbK+k/8PzjOOzx1D3i1pKTTAAAAAElFTkSuQmCC';
}
}

View File

@ -77,26 +77,22 @@ class Logs extends BaseCollector
//--------------------------------------------------------------------
/**
* Builds and returns the HTML needed to fill a tab to display
* within the Debug Bar
* Returns the data of this collector to be formatted in the toolbar
*
* @return string
* @return array
*/
public function display(): string
public function display(): array
{
$this->collectLogs();
$parser = \Config\Services::parser(BASEPATH . 'Debug/Toolbar/Views/', null, false);
$logs = $this->collectLogs();
if (empty($logs) || ! is_array($logs))
{
return '<p>Nothing was logged. If you were expecting logged items, ensure that LoggerConfig file has the correct threshold set.</p>';
$logs = [];
}
return $parser->setData([
'logs' => $logs
])
->render('_logs.tpl');
return [
'logs' => $logs
];
}
//--------------------------------------------------------------------
@ -122,9 +118,7 @@ class Logs extends BaseCollector
*/
public function icon(): string
{
return <<<EOD
<img src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABgAAAAYCAYAAADgdz34AAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAACYSURBVEhLYxgFJIHU1FSjtLS0i0D8AYj7gEKMEBkqAaAFF4D4ERCvAFrwH4gDoFIMKSkpFkB+OTEYqgUTACXfA/GqjIwMQyD9H2hRHlQKJFcBEiMGQ7VgAqCBvUgK32dmZspCpagGGNPT0/1BLqeF4bQHQJePpiIwhmrBBEADR1MRfgB0+WgqAmOoFkwANHA0FY0CUgEDAwCQ0PUpNB3kqwAAAABJRU5ErkJggg==">
EOD;
return 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABgAAAAYCAYAAADgdz34AAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAACYSURBVEhLYxgFJIHU1FSjtLS0i0D8AYj7gEKMEBkqAaAFF4D4ERCvAFrwH4gDoFIMKSkpFkB+OTEYqgUTACXfA/GqjIwMQyD9H2hRHlQKJFcBEiMGQ7VgAqCBvUgK32dmZspCpagGGNPT0/1BLqeF4bQHQJePpiIwhmrBBEADR1MRfgB0+WgqAmOoFkwANHA0FY0CUgEDAwCQ0PUpNB3kqwAAAABJRU5ErkJggg==';
}

View File

@ -70,15 +70,12 @@ class Routes extends BaseCollector
//--------------------------------------------------------------------
/**
* Builds and returns the HTML needed to fill a tab to display
* within the Debug Bar
* Returns the data of this collector to be formatted in the toolbar
*
* @return string
* @return array
*/
public function display(): string
public function display(): array
{
$parser = \Config\Services::parser();
$rawRoutes = Services::routes(true);
$router = Services::router(null, true);
@ -126,11 +123,10 @@ class Routes extends BaseCollector
];
}
return $parser->setData([
'matchedRoute' => $matchedRoute,
'routes' => $routes
])
->render('CodeIgniter\Debug\Toolbar\Views\_routes.tpl');
return [
'matchedRoute' => $matchedRoute,
'routes' => $routes
];
}
//--------------------------------------------------------------------
@ -158,9 +154,7 @@ class Routes extends BaseCollector
*/
public function icon(): string
{
return <<<EOD
<img src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABgAAAAYCAYAAADgdz34AAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAFDSURBVEhL7ZRNSsNQFIUjVXSiOFEcuQIHDpzpxC0IGYeE/BEInbWlCHEDLsSiuANdhKDjgm6ggtSJ+l25ldrmmTwIgtgDh/t37r1J+16cX0dRFMtpmu5pWAkrvYjjOB7AETzStBFW+inxu3KUJMmhludQpoflS1zXban4LYqiO224h6VLTHr8Z+z8EpIHFF9gG78nDVmW7UgTHKjsCyY98QP+pcq+g8Ku2s8G8X3f3/I8b038WZTp+bO38zxfFd+I6YY6sNUvFlSDk9CRhiAI1jX1I9Cfw7GG1UB8LAuwbU0ZwQnbRDeEN5qqBxZMLtE1ti9LtbREnMIuOXnyIf5rGIb7Wq8HmlZgwYBH7ORTcKH5E4mpjeGt9fBZcHE2GCQ3Vt7oTNPNg+FXLHnSsHkw/FR+Gg2bB8Ptzrst/v6C/wrH+QB+duli6MYJdQAAAABJRU5ErkJggg==">
EOD;
return 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABgAAAAYCAYAAADgdz34AAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAFDSURBVEhL7ZRNSsNQFIUjVXSiOFEcuQIHDpzpxC0IGYeE/BEInbWlCHEDLsSiuANdhKDjgm6ggtSJ+l25ldrmmTwIgtgDh/t37r1J+16cX0dRFMtpmu5pWAkrvYjjOB7AETzStBFW+inxu3KUJMmhludQpoflS1zXban4LYqiO224h6VLTHr8Z+z8EpIHFF9gG78nDVmW7UgTHKjsCyY98QP+pcq+g8Ku2s8G8X3f3/I8b038WZTp+bO38zxfFd+I6YY6sNUvFlSDk9CRhiAI1jX1I9Cfw7GG1UB8LAuwbU0ZwQnbRDeEN5qqBxZMLtE1ti9LtbREnMIuOXnyIf5rGIb7Wq8HmlZgwYBH7ORTcKH5E4mpjeGt9fBZcHE2GCQ3Vt7oTNPNg+FXLHnSsHkw/FR+Gg2bB8Ptzrst/v6C/wrH+QB+duli6MYJdQAAAABJRU5ErkJggg==';
}
}

View File

@ -98,5 +98,4 @@ class Timers extends BaseCollector
return $data;
}
//--------------------------------------------------------------------
}

View File

@ -182,9 +182,7 @@ class Views extends BaseCollector
*/
public function icon(): string
{
return <<<EOD
<img src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABgAAAAYCAYAAADgdz34AAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAADeSURBVEhL7ZSxDcIwEEWNYA0YgGmgyAaJLTcUaaBzQQEVjMEabBQxAdw53zTHiThEovGTfnE/9rsoRUxhKLOmaa6Uh7X2+UvguLCzVxN1XW9x4EYHzik033Hp3X0LO+DaQG8MDQcuq6qao4qkHuMgQggLvkPLjqh00ZgFDBacMJYFkuwFlH1mshdkZ5JPJERA9JpI6xNCBESvibQ+IURA9JpI6xNCBESvibQ+IURA9DTsuHTOrVFFxixgB/eUFlU8uKJ0eDBFOu/9EvoeKnlJS2/08Tc8NOwQ8sIfMeYFjqKDjdU2sp4AAAAASUVORK5CYII=">
EOD;
return 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABgAAAAYCAYAAADgdz34AAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAADeSURBVEhL7ZSxDcIwEEWNYA0YgGmgyAaJLTcUaaBzQQEVjMEabBQxAdw53zTHiThEovGTfnE/9rsoRUxhKLOmaa6Uh7X2+UvguLCzVxN1XW9x4EYHzik033Hp3X0LO+DaQG8MDQcuq6qao4qkHuMgQggLvkPLjqh00ZgFDBacMJYFkuwFlH1mshdkZ5JPJERA9JpI6xNCBESvibQ+IURA9JpI6xNCBESvibQ+IURA9DTsuHTOrVFFxixgB/eUFlU8uKJ0eDBFOu/9EvoeKnlJS2/08Tc8NOwQ8sIfMeYFjqKDjdU2sp4AAAAASUVORK5CYII=';
}
}

View File

@ -0,0 +1,28 @@
<table>
<thead>
<tr>
<th>Action</th>
<th>Datetime</th>
<th>Status</th>
<th>Method</th>
<th>URL</th>
<th>Content-Type</th>
<th>Is AJAX?</th>
</tr>
</thead>
<tbody>
{files}
<tr data-active="{active}">
<td style="width: 70px">
<button class="ci-history-load" data-time="{time}">Load</button>
</td>
<td style="width: 140px">{datetime}</td>
<td>{status}</td>
<td>{method}</td>
<td>{url}</td>
<td>{contentType}</td>
<td>{isAJAX}</td>
</tr>
{/files}
</tbody>
</table>

View File

@ -1,3 +1,6 @@
{ if logs == [] }
<p>Nothing was logged. If you were expecting logged items, ensure that LoggerConfig file has the correct threshold set.</p>
{ else }
<table>
<thead>
<tr>
@ -14,3 +17,4 @@
{/logs}
</tbody>
</table>
{ endif }

View File

@ -163,6 +163,38 @@
margin-left: 0.5em;
}
#debug-bar span.ci-label .badge.active {
background-color: red;
}
#debug-bar button {
border: 1px solid #ddd;
background-color: #fff;
cursor: pointer;
border-radius: 4px;
color: #333;
}
#debug-bar button:hover {
background-color: #eaeaea;
}
#debug-bar tr[data-active="1"] {
background-color: #dff0d8;
}
#debug-bar tr[data-active="1"]:hover {
background-color: #a7d499;
}
#debug-bar tr.current {
background-color: #FDC894;
}
#debug-bar tr.current:hover {
background-color: #DD4814;
}
#debug-bar table strong {
font-weight: 500;
color: rgba(0, 0, 0, 0.3);

View File

@ -17,11 +17,36 @@ var ciDebugBar = {
ciDebugBar.createListeners();
ciDebugBar.setToolbarState();
ciDebugBar.setToolbarPosition();
ciDebugBar.toogleViewsHints();
document.getElementById('debug-bar-link').addEventListener('click', ciDebugBar.toggleToolbar, true);
document.getElementById('debug-icon-link').addEventListener('click', ciDebugBar.toggleToolbar, true);
ciDebugBar.toggleViewsHints();
document.getElementById('debug-bar-link').addEventListener('click', ciDebugBar.toggleToolbar, true);
document.getElementById('debug-icon-link').addEventListener('click', ciDebugBar.toggleToolbar, true);
// Allows to highlight the row of the current history request
var btn = document.querySelector('button[data-time="'+localStorage.getItem('debugbar-time')+'"]');
ciDebugBar.addClass(btn.parentNode.parentNode, 'current');
historyLoad = document.getElementsByClassName('ci-history-load');
for (var i = 0; i < historyLoad.length; i++)
{
historyLoad[i].addEventListener('click', function() {
loadDoc(this.getAttribute('data-time'));
}, true);
}
// Display the active Tab on page load
var tab = ciDebugBar.readCookie('debug-bar-tab');
if (document.getElementById(tab)) {
var el = document.getElementById(tab);
el.style.display = 'block';
ciDebugBar.addClass(el, 'active');
tab = document.querySelector('[data-tab='+tab+']');
if (tab) {
ciDebugBar.addClass(tab.parentNode, 'active');
}
}
},
//--------------------------------------------------------------------
@ -48,6 +73,9 @@ var ciDebugBar = {
return;
}
// Remove debug-bar-tab cookie
ciDebugBar.createCookie('debug-bar-tab', '', -1);
// Check our current state.
var state = tab.style.display;
@ -72,6 +100,8 @@ var ciDebugBar = {
{
tab.style.display = 'block';
ciDebugBar.addClass(this.parentNode, 'active');
// Create debug-bar-tab cookie to persistent state
ciDebugBar.createCookie('debug-bar-tab', this.getAttribute('data-tab'), 365);
}
},
@ -156,8 +186,16 @@ var ciDebugBar = {
//--------------------------------------------------------------------
toogleViewsHints: function()
toggleViewsHints: function()
{
// Avoid toggle hints on history requests that are not the initial
if (localStorage.getItem('debugbar-time') != localStorage.getItem('debugbar-time-new'))
{
var a = document.querySelector('a[data-tab="ci-views"]');
a.href = '#';
return;
}
var nodeList = []; // [ Element, NewElement( 1 )/OldElement( 0 ) ]
var sortedComments = [];
var comments = [];
@ -399,15 +437,7 @@ var ciDebugBar = {
return;
}
btn = btn.parentNode;
// Determine Hints state on page load
if (ciDebugBar.readCookie('debug-view'))
{
showHints();
}
btn.onclick = function() {
btn.parentNode.onclick = function() {
if (ciDebugBar.readCookie('debug-view'))
{
hideHints();
@ -417,6 +447,12 @@ var ciDebugBar = {
showHints();
}
};
// Determine Hints state on page load
if (ciDebugBar.readCookie('debug-view'))
{
showHints();
}
},
//--------------------------------------------------------------------

View File

@ -6,86 +6,86 @@
<?= file_get_contents(__DIR__.'/toolbar.js') ?>
</script>
<div id="debug-icon" style="display:none">
<a id="debug-icon-link" href="javascript:void(0)">
<svg version="1.0" xmlns="http://www.w3.org/2000/svg"
width="155.000000px" height="200.000000px" viewBox="0 0 155.000000 200.000000"
preserveAspectRatio="xMidYMid meet">
<g transform="translate(0.000000,200.000000) scale(0.100000,-0.100000)" fill="#dd4814" stroke="none">
<path d="M737 1963 c22 -79 -7 -185 -78 -290 -18 -26 -107 -122 -197 -213
-239 -240 -336 -371 -403 -544 -79 -206 -78 -408 5 -582 64 -134 212 -264 361
-314 l60 -20 -30 22 c-210 152 -229 387 -48 588 25 27 48 50 51 50 4 0 7 -27
7 -61 0 -57 2 -62 37 -95 30 -27 46 -34 78 -34 56 0 99 24 116 65 29 69 16
120 -50 205 -105 134 -117 233 -43 347 l31 48 7 -47 c13 -82 58 -129 250 -258
209 -141 306 -261 328 -405 11 -72 -1 -161 -31 -218 -27 -53 -112 -143 -165
-174 -24 -14 -43 -26 -43 -28 0 -2 24 4 53 14 241 83 427 271 482 486 19 76
19 202 -1 285 -35 152 -146 305 -299 412 l-70 49 -6 -33 c-8 -48 -26 -76 -59
-93 -45 -23 -103 -19 -138 10 -67 57 -78 146 -37 305 30 116 32 206 5 291 -27
89 -104 206 -162 247 -17 13 -18 12 -11 -15z"/>
</g>
</svg>
</a>
<a id="debug-icon-link" href="javascript:void(0)">
<svg version="1.0" xmlns="http://www.w3.org/2000/svg"
width="155.000000px" height="200.000000px" viewBox="0 0 155.000000 200.000000"
preserveAspectRatio="xMidYMid meet">
<g transform="translate(0.000000,200.000000) scale(0.100000,-0.100000)" fill="#dd4814" stroke="none">
<path d="M737 1963 c22 -79 -7 -185 -78 -290 -18 -26 -107 -122 -197 -213
-239 -240 -336 -371 -403 -544 -79 -206 -78 -408 5 -582 64 -134 212 -264 361
-314 l60 -20 -30 22 c-210 152 -229 387 -48 588 25 27 48 50 51 50 4 0 7 -27
7 -61 0 -57 2 -62 37 -95 30 -27 46 -34 78 -34 56 0 99 24 116 65 29 69 16
120 -50 205 -105 134 -117 233 -43 347 l31 48 7 -47 c13 -82 58 -129 250 -258
209 -141 306 -261 328 -405 11 -72 -1 -161 -31 -218 -27 -53 -112 -143 -165
-174 -24 -14 -43 -26 -43 -28 0 -2 24 4 53 14 241 83 427 271 482 486 19 76
19 202 -1 285 -35 152 -146 305 -299 412 l-70 49 -6 -33 c-8 -48 -26 -76 -59
-93 -45 -23 -103 -19 -138 10 -67 57 -78 146 -37 305 30 116 32 206 5 291 -27
89 -104 206 -162 247 -17 13 -18 12 -11 -15z"/>
</g>
</svg>
</a>
</div>
<div id="debug-bar">
<div class="toolbar">
<span id="toolbar-position"><a href="javascript: void(0)">&#8597;</a></span>
<span id="toolbar-position"><a href="javascript: void(0)">&#8597;</a></span>
<span class="ci-label">
<a href="javascript: void(0)" data-tab="ci-timeline">
<img src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABgAAAAYCAYAAADgdz34AAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAD7SURBVEhLY6ArSEtLK09NTbWHcvGC9PR0BaDaQiAdUl9fzwQVxg+AFvwHamqHcnGCpKQkeaDa9yD1UD09UCn8AKaBWJySkmIApFehi0ONwwRQBceBLurAh4FqFoHUAtkrgPgREN+ByYEw1DhMANVEMIhAYQ5U1wtU/wmILwLZRlAp/IBYC8gGw88CaFj3A/FnIL4ETDXGUCnyANSC/UC6HIpnQMXAqQXIvo0khxNDjcMEQEmU9AzDuNI7Lgw1DhOAJIEuhQcRKMcC+e+QNHdDpcgD6BaAANSSQqBcENFlDi6AzQKqgkFlwWhxjVI8o2OgmkFaXI8CTMDAAAAxd1O4FzLMaAAAAABJRU5ErkJggg==">
<span class="hide-sm"><?= $totalTime ?> ms &nbsp; <?= $totalMemory ?> MB</span>
</a>
</span>
<?php foreach ($this->collectors as $c) : ?>
<?php if (! $c->isEmpty()) : ?>
<?php if ($c->hasTabContent() || $c->hasLabel()) : ?>
<span class="ci-label">
<a href="javascript: void(0)" data-tab="ci-<?= esc($c->getTitle(true)) ?>" >
<?= $c->icon() ?>
<span class="hide-sm">
<?= esc($c->getTitle()) ?>
<?php if (! is_null($c->getBadgeValue())) : ?>
<span class="badge"><?= $c->getBadgeValue() ?></span>
<?php endif ?>
</span>
</a>
</span>
<?php endif ?>
<?php endif ?>
<?php endforeach; ?>
<a href="javascript: void(0)" data-tab="ci-timeline">
<img src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABgAAAAYCAYAAADgdz34AAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAD7SURBVEhLY6ArSEtLK09NTbWHcvGC9PR0BaDaQiAdUl9fzwQVxg+AFvwHamqHcnGCpKQkeaDa9yD1UD09UCn8AKaBWJySkmIApFehi0ONwwRQBceBLurAh4FqFoHUAtkrgPgREN+ByYEw1DhMANVEMIhAYQ5U1wtU/wmILwLZRlAp/IBYC8gGw88CaFj3A/FnIL4ETDXGUCnyANSC/UC6HIpnQMXAqQXIvo0khxNDjcMEQEmU9AzDuNI7Lgw1DhOAJIEuhQcRKMcC+e+QNHdDpcgD6BaAANSSQqBcENFlDi6AzQKqgkFlwWhxjVI8o2OgmkFaXI8CTMDAAAAxd1O4FzLMaAAAAABJRU5ErkJggg==">
<span class="hide-sm"><?= $totalTime ?> ms &nbsp; <?= $totalMemory ?> MB</span>
</a>
</span>
<?php foreach ($collectors as $c) : ?>
<?php if (! $c['isEmpty'] && ($c['hasTabContent'] || $c['hasLabel'])) : ?>
<span class="ci-label">
<a href="javascript: void(0)" data-tab="ci-<?= $c['titleSafe'] ?>" >
<img src="<?= $c['icon'] ?>">
<span class="hide-sm">
<?= $c['title'] ?>
<?php if (! is_null($c['badgeValue'])) : ?>
<span class="badge"><?= $c['badgeValue'] ?></span>
<?php endif ?>
</span>
</a>
</span>
<?php endif ?>
<?php endforeach ?>
<span class="ci-label">
<a href="javascript: void(0)" data-tab="ci-vars">
<img src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABgAAAAYCAYAAADgdz34AAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAACLSURBVEhLYxgFJIHU1NSraWlp/6H4T0pKSjRUijoAyXAwBlrYDpViAFpmARQrJwZDtWACoCROC4D8CnR5XBiqBRMADfyNprgRKkUdAApzoCUdUNwE5MtApYYIALp6NBWBMVQLJgAaOJqK8AOgq+mSio6DggjEBtLUT0UwQ5HZIADkj6aiUTAggIEBANAEDa/lkCRlAAAAAElFTkSuQmCC">
<span class="hide-sm">Vars</span>
</a>
</span>
<a href="javascript: void(0)" data-tab="ci-vars">
<img src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABgAAAAYCAYAAADgdz34AAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAACLSURBVEhLYxgFJIHU1NSraWlp/6H4T0pKSjRUijoAyXAwBlrYDpViAFpmARQrJwZDtWACoCROC4D8CnR5XBiqBRMADfyNprgRKkUdAApzoCUdUNwE5MtApYYIALp6NBWBMVQLJgAaOJqK8AOgq+mSio6DggjEBtLUT0UwQ5HZIADkj6aiUTAggIEBANAEDa/lkCRlAAAAAElFTkSuQmCC">
<span class="hide-sm">Vars</span>
</a>
</span>
<h1>
<span class="ci-label">
<a href="javascript: void(0)" data-tab="ci-config" >
<svg version="1.0" xmlns="http://www.w3.org/2000/svg"
width="18.60px" height="24.0px" viewBox="0 0 18.60 28.000000"
preserveAspectRatio="xMidYMid meet">
<g transform="translate(0.000000,28.000000) scale(0.010000,-0.010000)" fill="#dd4814" stroke="none">
<path d="M737 1963 c22 -79 -7 -185 -78 -290 -18 -26 -107 -122 -197 -213
-239 -240 -336 -371 -403 -544 -79 -206 -78 -408 5 -582 64 -134 212 -264 361
-314 l60 -20 -30 22 c-210 152 -229 387 -48 588 25 27 48 50 51 50 4 0 7 -27
7 -61 0 -57 2 -62 37 -95 30 -27 46 -34 78 -34 56 0 99 24 116 65 29 69 16
120 -50 205 -105 134 -117 233 -43 347 l31 48 7 -47 c13 -82 58 -129 250 -258
209 -141 306 -261 328 -405 11 -72 -1 -161 -31 -218 -27 -53 -112 -143 -165
-174 -24 -14 -43 -26 -43 -28 0 -2 24 4 53 14 241 83 427 271 482 486 19 76
19 202 -1 285 -35 152 -146 305 -299 412 l-70 49 -6 -33 c-8 -48 -26 -76 -59
-93 -45 -23 -103 -19 -138 10 -67 57 -78 146 -37 305 30 116 32 206 5 291 -27
89 -104 206 -162 247 -17 13 -18 12 -11 -15z"/>
</g>
</svg>
<?= \CodeIgniter\CodeIgniter::CI_VERSION ?>
</a>
</span>
</h1>
<h1>
<span class="ci-label">
<a href="javascript: void(0)" data-tab="ci-config" >
<svg version="1.0" xmlns="http://www.w3.org/2000/svg"
width="18.60px" height="24.0px" viewBox="0 0 18.60 28.000000"
preserveAspectRatio="xMidYMid meet">
<g transform="translate(0.000000,28.000000) scale(0.010000,-0.010000)" fill="#dd4814" stroke="none">
<path d="M737 1963 c22 -79 -7 -185 -78 -290 -18 -26 -107 -122 -197 -213
-239 -240 -336 -371 -403 -544 -79 -206 -78 -408 5 -582 64 -134 212 -264 361
-314 l60 -20 -30 22 c-210 152 -229 387 -48 588 25 27 48 50 51 50 4 0 7 -27
7 -61 0 -57 2 -62 37 -95 30 -27 46 -34 78 -34 56 0 99 24 116 65 29 69 16
120 -50 205 -105 134 -117 233 -43 347 l31 48 7 -47 c13 -82 58 -129 250 -258
209 -141 306 -261 328 -405 11 -72 -1 -161 -31 -218 -27 -53 -112 -143 -165
-174 -24 -14 -43 -26 -43 -28 0 -2 24 4 53 14 241 83 427 271 482 486 19 76
19 202 -1 285 -35 152 -146 305 -299 412 l-70 49 -6 -33 c-8 -48 -26 -76 -59
-93 -45 -23 -103 -19 -138 10 -67 57 -78 146 -37 305 30 116 32 206 5 291 -27
89 -104 206 -162 247 -17 13 -18 12 -11 -15z"/>
</g>
</svg>
<?= $CI_VERSION ?>
</a>
</span>
</h1>
<!-- Open/Close Toggle -->
<a id="debug-bar-link" href="javascript:void(0)">
<img src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABgAAAAYCAYAAADgdz34AAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAEPSURBVEhL7ZVLDoJAEEThRuoGDwSEG+jCuFU34s3AK3APP1VDDSGMqI1xx0s6M/2rnlHEaMZElmWrPM+vsDvsYbQ7+us0TReSC2EBrEHxCevRYuppYLXkQpC8sVCuGfTvqSE3hFdFwUGuGfRvqSE35NUAfKZrbQNQm2jrMA+gOK+M+FmhDsRL5voHMA8gFGecq0JOXLWlQg7E7AMIxZnjOiZOEJ82gFCcedUE4gS56QP8yf8ywItz7e+RituKlkkDBoIOH4Nd4HZD4NsGYJ/Abn1xEVOcuZ8f0zc/tHiYmzTAwscBvDIK/veyQ9K/rnewjdF26q0kF1IUxZIFPAVW98x/a+qp8L2M/+HMhETRE6S8TxpZ7KGXAAAAAElFTkSuQmCC">
</a>
<!-- Open/Close Toggle -->
<a id="debug-bar-link" href="javascript:void(0)" title="Open/Close">
<img src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABgAAAAYCAYAAADgdz34AAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAEPSURBVEhL7ZVLDoJAEEThRuoGDwSEG+jCuFU34s3AK3APP1VDDSGMqI1xx0s6M/2rnlHEaMZElmWrPM+vsDvsYbQ7+us0TReSC2EBrEHxCevRYuppYLXkQpC8sVCuGfTvqSE3hFdFwUGuGfRvqSE35NUAfKZrbQNQm2jrMA+gOK+M+FmhDsRL5voHMA8gFGecq0JOXLWlQg7E7AMIxZnjOiZOEJ82gFCcedUE4gS56QP8yf8ywItz7e+RituKlkkDBoIOH4Nd4HZD4NsGYJ/Abn1xEVOcuZ8f0zc/tHiYmzTAwscBvDIK/veyQ9K/rnewjdF26q0kF1IUxZIFPAVW98x/a+qp8L2M/+HMhETRE6S8TxpZ7KGXAAAAAElFTkSuQmCC">
</a>
</div>
<!-- Timeline -->
@ -96,107 +96,87 @@
<th style="width: 30%">NAME</th>
<th style="width: 10%">COMPONENT</th>
<th style="width: 10%;">DURATION</th>
<?php for ($i=0; $i < $segmentCount; $i++) : ?>
<?php for ($i = 0; $i < $segmentCount; $i++) : ?>
<th><?= $i * $segmentDuration ?> ms</th>
<?php endfor; ?>
<?php endfor ?>
</tr>
</thead>
<tbody>
<?= $this->renderTimeline($segmentCount, $segmentDuration, $totalTime) ?>
<?= self::renderTimeline($collectors, $startTime, $segmentCount, $segmentDuration) ?>
</tbody>
</table>
</div>
<!-- Collector-provided Tabs -->
<?php foreach ($this->collectors as $c) : ?>
<?php if (! $c->isEmpty()) : ?>
<?php if ($c->hasTabContent()) : ?>
<div id="ci-<?= esc($c->getTitle(true)) ?>" class="tab">
<h2><?= esc($c->getTitle()) ?> <span><?= esc($c->getTitleDetails()) ?></span></h2>
<?php foreach ($collectors as $c) : ?>
<?php if (! $c['isEmpty']) : ?>
<?php if ($c['hasTabContent']) : ?>
<div id="ci-<?= $c['titleSafe'] ?>" class="tab">
<h2><?= $c['title'] ?> <span><?= $c['titleDetails'] ?></span></h2>
<?= $c->display() ?>
</div>
<?php endif ?>
<?php endif ?>
<?= $parser->setData($c['display'])->render("_{$c['titleSafe']}.tpl") ?>
</div>
<?php endif ?>
<?php endif ?>
<?php endforeach ?>
<!-- In & Out -->
<div id="ci-vars" class="tab">
<!-- VarData from Collectors -->
<?php foreach ($varData as $heading => $items) : ?>
<?php if(isset($vars['varData'])) : ?>
<?php foreach ($vars['varData'] as $heading => $items) : ?>
<a href="javascript:void(0)" onclick="ciDebugBar.toggleDataTable('<?= strtolower(str_replace(' ', '-', $heading)) ?>'); return false;">
<h2><?= esc($heading) ?></h2>
</a>
<a href="javascript:void(0)" onclick="ciDebugBar.toggleDataTable('<?= strtolower(str_replace(' ', '-', $heading)) ?>'); return false;">
<h2><?= $heading ?></h2>
</a>
<?php if (is_array($items)) : ?>
<?php if (is_array($items)) : ?>
<table id="<?= strtolower(str_replace(' ', '-', $heading.'_table')) ?>">
<tbody>
<?php foreach ($items as $key => $value) : ?>
<tr>
<td><?= esc($key) ?></td>
<td>
<?php
if (is_string($value))
{
echo esc($value);
}
else
{
echo print_r($value, true);
}
?>
</td>
</tr>
<?php endforeach; ?>
</tbody>
</table>
<table id="<?= strtolower(str_replace(' ', '-', $heading.'_table')) ?>">
<tbody>
<?php foreach ($items as $key => $value) : ?>
<tr>
<td><?= $key ?></td>
<td><?= $value ?></td>
</tr>
<?php endforeach ?>
</tbody>
</table>
<?php else: ?>
<p class="muted">No data to display.</p>
<?php endif; ?>
<?php endforeach; ?>
<?php else: ?>
<p class="muted">No data to display.</p>
<?php endif ?>
<?php endforeach ?>
<?php endif ?>
<!-- Session -->
<a href="javascript:void(0)" onclick="ciDebugBar.toggleDataTable('session'); return false;">
<h2>Session User Data</h2>
</a>
<?php if (isset($_SESSION)) : ?>
<?php if (! empty($_SESSION)) : ?>
<?php if (isset($vars['session'])) : ?>
<?php if (! empty($vars['session'])) : ?>
<table id="session_table">
<tbody>
<?php foreach ($_SESSION as $key => $value) : ?>
<?php foreach ($vars['session'] as $key => $value) : ?>
<tr>
<td><?= esc($key) ?></td>
<td>
<?php
if (is_string($value))
{
echo esc($value);
}
else
{
echo print_r($value, true);
}
?>
</td>
<td><?= $key ?></td>
<td><?= $value ?></td>
</tr>
<?php endforeach; ?>
<?php endforeach ?>
</tbody>
</table>
<?php else : ?>
<p class="muted">No data to display.</p>
<?php endif; ?>
<?php endif ?>
<?php else : ?>
<p class="muted">Session doesn't seem to be active.</p>
<?php endif; ?>
<?php endif ?>
<h2>Request <span>( <?= ($request->isSecure() ? 'HTTPS' : 'HTTP').'/'.$request->getProtocolVersion() ?> )</span></h2>
<h2>Request <span>( <?= $vars['request'] ?> )</span></h2>
<?php if ($get = $request->getGet()) : ?>
<?php if (isset($vars['get']) && $get = $vars['get']) : ?>
<a href="javascript:void(0)" onclick="ciDebugBar.toggleDataTable('get'); return false;">
<h3>$_GET</h3>
</a>
@ -205,15 +185,15 @@
<tbody>
<?php foreach ($get as $name => $value) : ?>
<tr>
<td><?= esc($name) ?></td>
<td><?= esc($value) ?></td>
<td><?= $name ?></td>
<td><?= $value ?></td>
</tr>
<?php endforeach; ?>
<?php endforeach ?>
</tbody>
</table>
<?php endif ?>
<?php if ($post = $request->getPost()) : ?>
<?php if (isset($vars['post']) && $post = $vars['post']) : ?>
<a href="javascript:void(0)" onclick="ciDebugBar.toggleDataTable('post'); return false;">
<h3>$_POST</h3>
</a>
@ -222,56 +202,51 @@
<tbody>
<?php foreach ($post as $name => $value) : ?>
<tr>
<td><?= esc($name) ?></td>
<td><?= is_array($value) ? esc(print_r($value, true)) : esc($value) ?></td>
<td><?= $name ?></td>
<td><?= $value ?></td>
</tr>
<?php endforeach; ?>
<?php endforeach ?>
</tbody>
</table>
<?php endif ?>
<?php if ($headers = $request->getHeaders()) : ?>
<?php if (isset($vars['headers']) && $headers = $vars['headers']) : ?>
<a href="javascript:void(0)" onclick="ciDebugBar.toggleDataTable('request_headers'); return false;">
<h3>Headers</h3>
</a>
<table id="request_headers_table">
<tbody>
<?php foreach ($headers as $header => $value) : ?>
<?php if (empty($value)) continue; ?>
<?php if (! is_array($value)) { $value = [$value]; } ?>
<?php foreach ($value as $h) : ?>
<tr>
<td><?= esc($h->getName()) ?></td>
<td><?= esc($h->getValueLine()) ?></td>
<td><?= $header ?></td>
<td><?= $value ?></td>
</tr>
<?php endforeach; ?>
<?php endforeach; ?>
<?php endforeach ?>
</tbody>
</table>
<?php endif ?>
<?php if ($get = $request->getCookie()) : ?>
<?php if (isset($vars['cookies']) && $cookies = $vars['cookies']) : ?>
<a href="javascript:void(0)" onclick="ciDebugBar.toggleDataTable('cookie'); return false;">
<h3>Cookies</h3>
</a>
<table id="cookie_table">
<tbody>
<?php foreach ($get as $name => $value) : ?>
<?php foreach ($cookies as $name => $value) : ?>
<tr>
<td><?= esc($name) ?></td>
<td><?= esc($value) ?></td>
<td><?= $name ?></td>
<td><?= $value ?></td>
</tr>
<?php endforeach; ?>
<?php endforeach ?>
</tbody>
</table>
<?php endif ?>
<h2>Response <span>( <?= $response->getStatusCode().' - '. esc($response->getReason()) ?> )</span></h2>
<h2>Response <span>( <?= $vars['response']['statusCode'].' - '. $vars['response']['reason'] ?> )</span></h2>
<?php if ($headers = $response->getHeaders()) : ?>
<?php if (isset($vars['headers']) && $headers = $vars['headers']) : ?>
<a href="javascript:void(0)" onclick="ciDebugBar.toggleDataTable('response_headers'); return false;">
<h3>Headers</h3>
</a>
@ -280,18 +255,20 @@
<tbody>
<?php foreach ($headers as $header => $value) : ?>
<tr>
<td><?= esc($header) ?></td>
<td><?= esc($response->getHeaderLine($header)) ?></td>
<td><?= $header ?></td>
<td><?= $value ?></td>
</tr>
<?php endforeach; ?>
<?php endforeach ?>
</tbody>
</table>
<?php endif; ?>
<?php endif ?>
</div>
<!-- Config Values -->
<div id="ci-config" class="tab">
<h2>System Configuration</h2>
<!-- Config Values -->
<div id="ci-config" class="tab">
<h2>System Configuration</h2>
<?= \CodeIgniter\Debug\Toolbar\Collectors\Config::display() ?>
</div>
<?= $parser->setData($config)->render('_config.tpl') ?>
</div>
</div>

View File

@ -1,24 +1,58 @@
document.addEventListener('DOMContentLoaded', loadDoc, false);
document.addEventListener('DOMContentLoaded', loadDoc, false );
function loadDoc(time) {
if (isNaN(time)) {
time = document.getElementById("debugbar_loader").getAttribute("data-time");
localStorage.setItem('debugbar-time', time);
}
function loadDoc() {
var time = document.getElementById("debugbar_loader").getAttribute("data-time");
var url = "<?php echo rtrim(site_url(), '/') ?>";
localStorage.setItem('debugbar-time-new', time);
var xhttp = new XMLHttpRequest();
xhttp.onreadystatechange = function () {
if (this.readyState == 4 && this.status == 200) {
var toolbar = document.createElement( 'div' );
toolbar.setAttribute( 'id', 'toolbarContainer' );
toolbar.innerHTML = this.responseText;
document.body.appendChild( toolbar );
eval(document.getElementById("toolbar_js").innerHTML);
if (typeof ciDebugBar === 'object') {
ciDebugBar.init();
}
}
};
var url = "<?= rtrim(site_url(), '/') ?>";
xhttp.open("GET", url + "?debugbar_time=" + time, true);
xhttp.send();
var xhttp = new XMLHttpRequest();
xhttp.onreadystatechange = function() {
if (this.readyState === 4 && this.status === 200) {
var toolbar = document.getElementById("toolbarContainer");
if (!toolbar) {
toolbar = document.createElement('div');
toolbar.setAttribute('id', 'toolbarContainer');
toolbar.innerHTML = this.responseText;
document.body.appendChild(toolbar);
} else {
toolbar.innerHTML = this.responseText;
}
eval(document.getElementById("toolbar_js").innerHTML);
if (typeof ciDebugBar === 'object') {
ciDebugBar.init();
}
} else if (this.readyState === 4 && this.status === 404) {
console.log('CodeIgniter DebugBar: File "WRITEPATH/debugbar/debugbar_' + time + '" not found.');
}
};
xhttp.open("GET", url + "?debugbar_time=" + time, true);
xhttp.send();
}
// Track all AJAX requests
var oldXHR = window.XMLHttpRequest;
function newXHR() {
var realXHR = new oldXHR();
realXHR.addEventListener("readystatechange", function() {
// Only success responses and URLs that do not contains "debugbar_time" are tracked
if (realXHR.readyState === 4 && realXHR.status.toString()[0] === '2' && realXHR.responseURL.indexOf('debugbar_time') === -1) {
var debugbarTime = realXHR.getResponseHeader('Debugbar-Time');
if (debugbarTime) {
var h2 = document.querySelector('#ci-history > h2');
h2.innerHTML = 'History <small>You have new debug data.</small> <button onclick="loadDoc(' + debugbarTime + ')">Update</button>';
var badge = document.querySelector('a[data-tab="ci-history"] > span > .badge');
badge.className += ' active';
}
}
}, false);
return realXHR;
}
window.XMLHttpRequest = newXHR;

View File

@ -79,7 +79,7 @@ class FileCollection
*
* @param string $name
*
* @return null
* @return UploadedFile|null
*/
public function getFile(string $name)
{

24
system/HTTP/IncomingRequest.php Normal file → Executable file
View File

@ -466,7 +466,7 @@ class IncomingRequest extends Request
/**
* Attempts to get old Input data that has been flashed to the session
* with redirect_with_input(). It first checks for the data in the old
* POST data, then the old GET data.
* POST data, then the old GET data and finally check for dot arrays
*
* @param string $key
*
@ -490,6 +490,28 @@ class IncomingRequest extends Request
{
return $_SESSION['_ci_old_input']['get'][$key];
}
helper('array');
// Check for an array value in POST.
if (isset($_SESSION['_ci_old_input']['post']))
{
$value = dot_array_search($key, $_SESSION['_ci_old_input']['post']);
if ( ! is_null($value))
{
return $value;
}
}
// Check for an array value in GET.
if (isset($_SESSION['_ci_old_input']['get']))
{
$value = dot_array_search($key, $_SESSION['_ci_old_input']['get']);
if ( ! is_null($value))
{
return $value;
}
}
}
/**

View File

@ -72,6 +72,13 @@ class Pager implements PagerInterface
*/
protected $view;
/**
* List of only permitted queries
*
* @var array
*/
protected $only = [];
//--------------------------------------------------------------------
public function __construct($config, RendererInterface $view)
@ -295,11 +302,11 @@ class Pager implements PagerInterface
/**
* Returns the URI for a specific page for the specified group.
*
* @param int $page
* @param string $group
* @param bool $returnObject
* @param int|null $page
* @param string $group
* @param bool $returnObject
*
* @return string
* @return string|\CodeIgniter\HTTP\URI
*/
public function getPageURI(int $page = null, string $group = 'default', $returnObject = false)
{
@ -307,7 +314,18 @@ class Pager implements PagerInterface
$uri = $this->groups[$group]['uri'];
$uri->addQuery('page', $page);
if ($this->only)
{
$query = array_intersect_key($_GET, array_flip($this->only));
$query['page'] = $page;
$uri->setQueryArray($query);
}
else
{
$uri->addQuery('page', $page);
}
return $returnObject === true ? $uri : (string) $uri;
}
@ -419,6 +437,22 @@ class Pager implements PagerInterface
//--------------------------------------------------------------------
/**
* Sets only allowed queries on pagination links.
*
* @param array $queries
*
* @return Pager
*/
public function only(array $queries):Pager
{
$this->only = $queries;
return $this;
}
//--------------------------------------------------------------------
/**
* Ensures that an array exists for the group specified.
*

View File

@ -215,7 +215,7 @@ class PagerRenderer
'active' => ($i == $this->current)
];
}
dd($links);
return $links;
}

View File

@ -1129,9 +1129,11 @@ class RouteCollection implements RouteCollectionInterface
{
// Ensure that the param we're inserting matches
// the expected param type.
$pos = strpos($from, $pattern);
if (preg_match("|{$pattern}|", $params[$index]))
{
$from = str_replace($pattern, $params[$index], $from);
$from = substr_replace($from, $params[$index], $pos, strlen($pattern));
}
else
{

View File

@ -35,9 +35,9 @@
* @since Version 3.0.0
* @filesource
*/
use Config\Database;
use CodeIgniter\Config\BaseConfig;
use CodeIgniter\Database\BaseConnection;
use Config\Database;
/**
* Session handler using current Database for storage
@ -169,7 +169,9 @@ class DatabaseHandler extends BaseHandler implements \SessionHandlerInterface
$builder = $builder->where('ip_address', $_SERVER['REMOTE_ADDR']);
}
if ($result = $builder->get()->getRow() === null)
$result = $builder->get()->getRow();
if ($result === null)
{
// PHP7 will reuse the same SessionHandler object after
// ID regeneration, so we need to explicitly set this to

View File

@ -166,6 +166,8 @@ class Session implements SessionInterface
$this->cookieDomain = $config->cookieDomain;
$this->cookiePath = $config->cookiePath;
$this->cookieSecure = $config->cookieSecure;
helper('array');
}
//--------------------------------------------------------------------
@ -233,6 +235,8 @@ class Session implements SessionInterface
$this->initVars();
$this->logger->info("Session: Class initialized using '" . $this->sessionDriverName . "' driver.");
return $this;
}
//--------------------------------------------------------------------
@ -461,9 +465,9 @@ class Session implements SessionInterface
*/
public function get(string $key = null)
{
if (isset($key))
if ($value = dot_array_search($key, $_SESSION))
{
return $_SESSION[$key] ?? null;
return $value;
}
elseif (empty($_SESSION))
{

View File

@ -284,8 +284,8 @@ class Validation implements ValidationInterface
//--------------------------------------------------------------------
/**
* Takes a Request object and grabs the data to use from its
* POST array values.
* Takes a Request object and grabs the input data to use from its
* array values.
*
* @param \CodeIgniter\HTTP\RequestInterface|\CodeIgniter\HTTP\IncomingRequest $request
*
@ -293,7 +293,14 @@ class Validation implements ValidationInterface
*/
public function withRequest(RequestInterface $request): ValidationInterface
{
$this->data = $request->getPost() ?? [];
if (in_array($request->getMethod(), ['put', 'patch', 'delete']))
{
$this->data = $request->getRawInput();
}
else
{
$this->data = $request->getVar() ?? [];
}
return $this;
}
@ -675,7 +682,7 @@ class Validation implements ValidationInterface
}
$message = str_replace('{field}', $label ?? $field, $message);
$message = str_replace('{param}', $param, $message);
$message = str_replace('{param}', $this->rules[$param]['label'] ?? $param, $message);
return $message;
}

View File

@ -68,8 +68,8 @@ interface ValidationInterface
//--------------------------------------------------------------------
/**
* Takes a Request object and grabs the data to use from its
* POST array values.
* Takes a Request object and grabs the input data to use from its
* array values.
*
* @param \CodeIgniter\HTTP\RequestInterface $request
*

View File

@ -209,7 +209,7 @@ class View implements RendererInterface
$this->logPerformance($this->renderVars['start'], microtime(true), $this->renderVars['view']);
if (CI_DEBUG)
if (CI_DEBUG && (! isset($options['debug']) || $options['debug'] === true))
{
$after = (new \Config\Filters())->globals['after'];
if (in_array('toolbar', $after) || array_key_exists('toolbar', $after))

View File

@ -11,8 +11,8 @@ class CacheFactoryTest extends \CIUnitTestCase
$this->cacheFactory = new CacheFactory();
//Initialize path
$this->config = new \Config\Cache();
$this->config->path .= self::$directory;
$this->config = new \Config\Cache();
$this->config->storePath .= self::$directory;
}
public function tearDown()
@ -83,7 +83,7 @@ class CacheFactoryTest extends \CIUnitTestCase
$this->assertInstanceOf(\CodeIgniter\Cache\Handlers\DummyHandler::class, $this->cacheFactory->getHandler($this->config));
//Initialize path
$this->config = new \Config\Cache();
$this->config->path .= self::$directory;
$this->config = new \Config\Cache();
$this->config->storePath .= self::$directory;
}
}

View File

@ -24,10 +24,10 @@ class FileHandlerTest extends \CIUnitTestCase
public function setUp()
{
//Initialize path
$this->config = new \Config\Cache();
$this->config->path .= self::$directory;
if (!is_dir($this->config->path)) {
mkdir($this->config->path, 0777, true);
$this->config = new \Config\Cache();
$this->config->storePath .= self::$directory;
if (!is_dir($this->config->storePath)) {
mkdir($this->config->storePath, 0777, true);
}
$this->fileHandler = new FileHandler($this->config);
@ -58,8 +58,8 @@ class FileHandlerTest extends \CIUnitTestCase
public function testSetDefaultPath()
{
//Initialize path
$config = new \Config\Cache();
$config->path = null;
$config = new \Config\Cache();
$config->storePath = null;
$this->fileHandler = new FileHandler($config);
$this->fileHandler->initialize();
@ -198,15 +198,15 @@ final class BaseTestFileHandler extends FileHandler
public function __construct()
{
$this->config = new \Config\Cache();
$this->config->path .= self::$directory;
$this->config = new \Config\Cache();
$this->config->storePath .= self::$directory;
parent::__construct($this->config);
}
public function getFileInfoTest()
{
return $this->getFileInfo($this->config->path, [
return $this->getFileInfo($this->config->storePath, [
'name',
'server_path',
'size',

View File

@ -28,13 +28,13 @@ class ServicesTest extends \CIUnitTestCase
public function testNewExceptions()
{
$actual = Services::exceptions(new Exceptions());
$actual = Services::exceptions(new Exceptions(), Services::request(), Services::response());
$this->assertInstanceOf(\CodeIgniter\Debug\Exceptions::class, $actual);
}
public function testNewExceptionsWithNullConfig()
{
$actual = Services::exceptions(null, false);
$actual = Services::exceptions(null, null, null, false);
$this->assertInstanceOf(\CodeIgniter\Debug\Exceptions::class, $actual);
}

View File

@ -1,8 +1,5 @@
<?php namespace CodeIgniter\Database\Live;
use CodeIgniter\Database\Config;
class AliasTest extends \CIDatabaseTestCase
{
protected $refresh = true;

View File

@ -4,7 +4,7 @@ class ExceptionsTest extends \CIUnitTestCase
{
public function testNew()
{
$actual = new Exceptions(new \Config\Exceptions());
$actual = new Exceptions(new \Config\Exceptions(), \Config\Services::request(), \Config\Services::response());
$this->assertInstanceOf(Exceptions::class, $actual);
}
}

View File

@ -208,14 +208,15 @@ class LoggerTest extends \CIUnitTestCase
$_ENV['foo'] = 'bar';
// For whatever reason, this will often be the class/function instead of file and line.
$expected = 'DEBUG - '.date('Y-m-d').' --> Test message CodeIgniter\Log\LoggerTest testLogInterpolatesFileAndLine';
// Other times it actually returns the line number, so don't look for either
$expected = 'DEBUG - '.date('Y-m-d').' --> Test message CodeIgniter\Log\LoggerTest';
$logger->log('debug', 'Test message {file} {line}');
$logs = TestHandler::getLogs();
$this->assertCount(1, $logs);
$this->assertEquals($expected, $logs[0]);
$this->assertTrue(strpos($logs[0], $expected) === 0);
}
//--------------------------------------------------------------------

View File

@ -268,7 +268,7 @@ class PagerTest extends \CIUnitTestCase
$this->assertEquals((string)$expected, $this->pager->getNextPageURI('foo'));
}
//--------------------------------------------------------------------
public function testGetPreviousURIWithQueryStringUsesCurrentURI()
@ -286,4 +286,35 @@ class PagerTest extends \CIUnitTestCase
}
//--------------------------------------------------------------------
public function testGetOnlyQueries()
{
$_GET = [
'page' => 2,
'search' => 'foo',
'order' => 'asc',
'hello' => 'xxx',
'category' => 'baz',
];
$onlyQueries = ['search', 'order'];
$this->pager->store('default', $_GET['page'], 10, 100);
$uri = current_url(true);
$this->assertEquals(
$this->pager->only($onlyQueries)->getPreviousPageURI(),
(string)$uri->setQuery('search=foo&order=asc&page=1')
);
$this->assertEquals(
$this->pager->only($onlyQueries)->getNextPageURI(),
(string)$uri->setQuery('search=foo&order=asc&page=3')
);
$this->assertEquals(
$this->pager->only($onlyQueries)->getPageURI(4),
(string)$uri->setQuery('search=foo&order=asc&page=4')
);
}
//--------------------------------------------------------------------
}

View File

@ -707,6 +707,18 @@ class RouteCollectionTest extends \CIUnitTestCase
//--------------------------------------------------------------------
public function testReverseRouteMatching()
{
$routes = $this->getCollector();
$routes->get('test/(:segment)/(:segment)', 'TestController::test/$1/$2', ['as' => 'testRouter']);
$match = $routes->reverseRoute('testRouter', 1, 2);
$this->assertEquals('/test/1/2', $match);
}
public function testAddRedirect()
{
$routes = $this->getCollector();

View File

@ -11,6 +11,27 @@ class ThrottleTest extends \CIUnitTestCase
$this->cache = new MockHandler();
}
public function testTokenTime()
{
$throttler = new Throttler($this->cache);
// token time should be zero to start
$this->assertEquals(0,$throttler->getTokenTime());
// as soon as we try a rate check, token time affected
$rate = 1; // allow 1 per minute
$cost = 1;
// after using one slot, still good
$throttler->check('127.0.0.1', $rate, MINUTE, $cost);
$this->assertEquals(0,$throttler->getTokenTime());
// after consuming a second, we have to wait
$throttler->check('127.0.0.1', $rate, MINUTE, $cost);
$this->assertEquals(1,$throttler->getTokenTime());
}
public function testIPSavesBucket()
{

View File

@ -6,7 +6,7 @@ class ViewTest extends \CIUnitTestCase
{
protected $loader;
protected $viewsDir;
protected $config;
protected $config;
//--------------------------------------------------------------------
@ -14,14 +14,14 @@ class ViewTest extends \CIUnitTestCase
{
$this->loader = new \CodeIgniter\Autoloader\FileLocator(new \Config\Autoload());
$this->viewsDir = __DIR__.'/Views';
$this->config = new Config\View();
$this->config = new Config\View();
}
//--------------------------------------------------------------------
public function testSetVarStoresData()
{
$view = new View($this->config, $this->viewsDir, $this->loader);
$view = new View($this->config, $this->viewsDir, $this->loader);
$view->setVar('foo', 'bar');
@ -48,7 +48,7 @@ class ViewTest extends \CIUnitTestCase
$expected = [
'foo' => 'bar',
'bar' => 'baz'
'bar' => 'baz'
];
$view->setData($expected);
@ -191,21 +191,21 @@ class ViewTest extends \CIUnitTestCase
//--------------------------------------------------------------------
public function testRenderCanSaveDataThroughConfigSetting()
{
$this->config->saveData = true;
public function testRenderCanSaveDataThroughConfigSetting()
{
$this->config->saveData = true;
$view = new View($this->config, $this->viewsDir, $this->loader);
$view = new View($this->config, $this->viewsDir, $this->loader);
$view->setVar('testString', 'Hello World');
$view->render('simple');
$view->setVar('testString', 'Hello World');
$view->render('simple');
$expected = ['testString' => 'Hello World'];
$expected = ['testString' => 'Hello World'];
$this->assertEquals($expected, $view->getData());
}
$this->assertEquals($expected, $view->getData());
}
//--------------------------------------------------------------------
//--------------------------------------------------------------------
public function testCanDeleteData()
{

View File

@ -219,8 +219,8 @@ Logical Operators
higher precedence::
$result = true && false; // $result is false, expected
$result = true OR false; // $result is true, evaluated as "($result = true) OR false"
$result = (true OR false); // $result is false
$result = true AND false; // $result is true, evaluated as "($result = true) AND false"
$result = (true AND false); // $result is false
- The logical negation operator MUST be separated from its argument by a
single space, as in **! $result** instead of **!$result**

4
user_guide_src/source/database/entities.rst Normal file → Executable file
View File

@ -50,7 +50,7 @@ Entity itself at **application/Entities/User.php**.
protected $email;
protected $password;
protected $created_at;
protected $updated_on;
protected $updated_at;
}
At its simplest, this is all you need to do, though we'll make it more useful in a minute. Note that all of the
@ -76,7 +76,7 @@ Create the model first at **application/Models/UserModel.php** so that we can in
}
The model uses the ``users`` table in the database for all of its activities. We've set the ``$allowedFields`` property
to include all of the fields that we want outside classes to change. The ``id``, ``created_at``, and ``updated_on`` fields
to include all of the fields that we want outside classes to change. The ``id``, ``created_at``, and ``updated_at`` fields
are handled automatically by the class or the database, so we don't want to change those. Finally, we've set our Entity
class as the ``$returnType``. This ensures that all methods on the model that return rows from the database will return
instances of our User Entity class instead of an object or array like normal.

4
user_guide_src/source/database/query_builder.rst Normal file → Executable file
View File

@ -543,7 +543,7 @@ Query grouping allows you to create groups of WHERE clauses by enclosing them in
you to create queries with complex WHERE clauses. Nested groups are supported. Example::
$builder->select('*')->from('my_table')
->group_start()
->groupStart()
->where('a', 'a')
->orGroupStart()
->where('b', 'b')
@ -556,7 +556,7 @@ you to create queries with complex WHERE clauses. Nested groups are supported. E
// Generates:
// SELECT * FROM (`my_table`) WHERE ( `a` = 'a' OR ( `b` = 'b' AND `c` = 'c' ) ) AND `d` = 'd'
.. note:: groups need to be balanced, make sure every group_start() is matched by a group_end().
.. note:: groups need to be balanced, make sure every groupStart() is matched by a groupEnd().
**$builder->groupStart()**

4
user_guide_src/source/general/common_functions.rst Normal file → Executable file
View File

@ -63,7 +63,7 @@ Service Accessors
.. php:function:: helper( $filename )
:param string $filename: The name of the helper file to load.
:param string|array $filename: The name of the helper file to load, or an array of names.
Loads a helper file.
@ -100,6 +100,8 @@ Service Accessors
// In the view
<input type="email" name="email" value="<?= old('email') ?>">
// Or with arrays
<input type="email" name="user[email]" value="<?= old('user.email') ?>">
.. note:: If you are using the :doc:`form helper </helpers/form_helper>`, this feature is built-in. You only
need to use this function when not using the form helper.

View File

@ -35,10 +35,15 @@ Loading a helper file is quite simple using the following method::
Where **name** is the file name of the helper, without the .php file
extension or the "helper" part.
For example, to load the **URL Helper** file, which is named
**url_helper.php**, you would do this::
For example, to load the **Cookie Helper** file, which is named
**cookie_helper.php**, you would do this::
helper('url');
helper('cookie');
If you need to load more than one helper at a time, you can pass
an array of file names in and all of them will be loaded::
helper(['cookie', 'date']);
A helper can be loaded anywhere within your controller methods (or
even within your View files, although that's not a good practice), as
@ -50,6 +55,8 @@ it.
.. note:: The Helper loading method above does not return a value, so
don't try to assign it to a variable. Just use it as shown.
.. note:: The URL helper is always loaded so you do not need to load it yourself.
Loading from Non-standard Locations
-----------------------------------
@ -136,4 +143,4 @@ Now What?
=========
In the Table of Contents you'll find a list of all the available Helper
Files. Browse each one to see what they do.
Files. Browse each one to see what they do.

View File

@ -103,6 +103,23 @@ sections.
<?= $pager->makeLinks($page, $perPage, $total, 'template_name') ?>
Paginating with Only Expected Queries
=====================================
By default all GET queries are shown in the pagination links.
For example, when accessing the URL *http://domain.tld?search=foo&order=asc&hello=i+am+here&page=2*, the page 3 link can be generated, along with the other links, as follows::
echo $pager->links();
// Page 3 link: http://domain.tld?search=foo&order=asc&hello=i+am+here&page=3
The ``only()`` method allows you to limit this just to queries already expected::
echo $pager->only(['search', 'order'])->links();
// Page 3 link: http://domain.tld?search=foo&order=asc&page=3
The *page* query is enabled by default. And ``only()`` acts in all pagination links.
*********************
Customizing the Links
*********************

View File

@ -238,8 +238,8 @@ withRequest()
-------------
One of the most common times you will use the validation library is when validating
data that was input from an HTML form. If desired, you can pass an instance of the
current Request object and it will take all of the $_POST data and set it as the
data that was input from an HTTP Request. If desired, you can pass an instance of the
current Request object and it will take all of the input data and set it as the
data to be validated::
$validation->withRequest($this->request)