mirror of
https://github.com/codeigniter4/CodeIgniter4.git
synced 2025-02-20 11:44:28 +08:00
Merging latest develop
This commit is contained in:
commit
96bf16595b
5
.gitignore
vendored
5
.gitignore
vendored
@ -63,6 +63,10 @@ writable/uploads/*
|
||||
|
||||
writable/debugbar/*
|
||||
|
||||
application/Database/Migrations/2*
|
||||
|
||||
php_errors.log
|
||||
|
||||
#-------------------------
|
||||
# User Guide Temp Files
|
||||
#-------------------------
|
||||
@ -122,3 +126,4 @@ nb-configuration.xml
|
||||
.vscode/
|
||||
|
||||
/results/
|
||||
/phpunit*.xml
|
||||
|
@ -8,7 +8,6 @@ php:
|
||||
matrix:
|
||||
fast_finish: true
|
||||
allow_failures:
|
||||
- php: 7.2
|
||||
- php: nightly
|
||||
|
||||
global:
|
||||
@ -44,4 +43,4 @@ before_script:
|
||||
- composer install --prefer-source
|
||||
|
||||
after_success:
|
||||
- travis_retry php tests/bin/coveralls.phar
|
||||
- travis_retry php tests/bin/php-coveralls.phar -v
|
||||
|
@ -215,7 +215,7 @@ class App extends BaseConfig
|
||||
| Reverse Proxy IPs
|
||||
|--------------------------------------------------------------------------
|
||||
|
|
||||
| If your getServer is behind a reverse proxy, you must whitelist the proxy
|
||||
| If your server is behind a reverse proxy, you must whitelist the proxy
|
||||
| IP addresses from which CodeIgniter should trust headers such as
|
||||
| HTTP_X_FORWARDED_FOR and HTTP_CLIENT_IP in order to properly identify
|
||||
| the visitor's IP address.
|
||||
@ -240,11 +240,13 @@ class App extends BaseConfig
|
||||
| CSRFCookieName = The cookie name
|
||||
| CSRFExpire = The number in seconds the token should expire.
|
||||
| CSRFRegenerate = Regenerate token on every submission
|
||||
| CSRFRedirect = Redirect to previous page with error on failure
|
||||
*/
|
||||
public $CSRFTokenName = 'csrf_test_name';
|
||||
public $CSRFCookieName = 'csrf_cookie_name';
|
||||
public $CSRFExpire = 7200;
|
||||
public $CSRFRegenerate = true;
|
||||
public $CSRFRedirect = true;
|
||||
|
||||
/*
|
||||
|--------------------------------------------------------------------------
|
||||
@ -270,6 +272,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 +286,7 @@ class App extends BaseConfig
|
||||
'CodeIgniter\Debug\Toolbar\Collectors\Routes',
|
||||
'CodeIgniter\Debug\Toolbar\Collectors\Events',
|
||||
];
|
||||
public $toolbarMaxHistory = 20;
|
||||
|
||||
/*
|
||||
|--------------------------------------------------------------------------
|
||||
|
@ -1,6 +1,6 @@
|
||||
<?php namespace Config;
|
||||
|
||||
require BASEPATH.'Config/AutoloadConfig.php';
|
||||
require_once BASEPATH.'Config/AutoloadConfig.php';
|
||||
|
||||
/**
|
||||
* -------------------------------------------------------------------
|
||||
|
@ -36,7 +36,7 @@ class Cache extends BaseConfig
|
||||
| system.
|
||||
|
|
||||
*/
|
||||
public $path = WRITEPATH.'cache/';
|
||||
public $storePath = WRITEPATH.'cache/';
|
||||
|
||||
/*
|
||||
|--------------------------------------------------------------------------
|
||||
|
@ -23,7 +23,7 @@ class ContentSecurityPolicy extends BaseConfig
|
||||
|
||||
public $imageSrc = 'self';
|
||||
|
||||
public $base_uri = null;
|
||||
public $baseURI = 'none';
|
||||
|
||||
public $childSrc = null;
|
||||
|
||||
@ -38,6 +38,8 @@ class ContentSecurityPolicy extends BaseConfig
|
||||
public $mediaSrc = null;
|
||||
|
||||
public $objectSrc = null;
|
||||
|
||||
public $manifestSrc = null;
|
||||
|
||||
public $pluginTypes = null;
|
||||
|
||||
|
@ -8,7 +8,7 @@
|
||||
|
||||
class DocTypes
|
||||
{
|
||||
static $list =
|
||||
public $list =
|
||||
[
|
||||
'xhtml11' => '<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">',
|
||||
'xhtml1-strict' => '<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">',
|
||||
|
@ -2,6 +2,16 @@
|
||||
|
||||
class Email
|
||||
{
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
public $fromEmail;
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
public $fromName;
|
||||
|
||||
/**
|
||||
* The "user agent"
|
||||
* @var string
|
||||
|
@ -9,15 +9,18 @@ class Filters extends BaseConfig
|
||||
public $aliases = [
|
||||
'csrf' => \App\Filters\CSRF::class,
|
||||
'toolbar' => \App\Filters\DebugToolbar::class,
|
||||
'honeypot' => \App\Filters\Honeypot::class
|
||||
];
|
||||
|
||||
// Always applied before every request
|
||||
public $globals = [
|
||||
'before' => [
|
||||
// 'csrf'
|
||||
//'honeypot'
|
||||
// 'csrf',
|
||||
],
|
||||
'after' => [
|
||||
'toolbar'
|
||||
'toolbar',
|
||||
//'honeypot'
|
||||
]
|
||||
];
|
||||
|
||||
|
31
application/Config/Honeypot.php
Normal file
31
application/Config/Honeypot.php
Normal file
@ -0,0 +1,31 @@
|
||||
<?php namespace Config;
|
||||
|
||||
use CodeIgniter\Config\BaseConfig;
|
||||
|
||||
class Honeypot extends BaseConfig
|
||||
{
|
||||
|
||||
/**
|
||||
* Makes Honeypot visible or not to human
|
||||
*
|
||||
* @var boolean
|
||||
*/
|
||||
public $hidden = true;
|
||||
/**
|
||||
* Honeypot Label Content
|
||||
* @var String
|
||||
*/
|
||||
public $label = 'Fill This Field';
|
||||
|
||||
/**
|
||||
* Honeypot Field Name
|
||||
* @var String
|
||||
*/
|
||||
public $name = 'honeypot';
|
||||
|
||||
/**
|
||||
* Honeypot HTML Template
|
||||
* @var String
|
||||
*/
|
||||
public $template = '<label>{label}</label><input type="text" name="{name}" value=""/>';
|
||||
}
|
@ -6,7 +6,7 @@
|
||||
* Modifying these allows you to re-structure your application,
|
||||
* share a system folder between multiple applications, and more.
|
||||
*
|
||||
* All paths are relative to the application's front controller, index.php
|
||||
* All paths are relative to the project's root folder.
|
||||
*/
|
||||
class Paths
|
||||
{
|
||||
@ -19,7 +19,7 @@ class Paths
|
||||
* Include the path if the folder is not in the same directory
|
||||
* as this file.
|
||||
*/
|
||||
public $systemDirectory = '../system';
|
||||
public $systemDirectory = 'system';
|
||||
|
||||
/*
|
||||
*---------------------------------------------------------------
|
||||
@ -34,7 +34,7 @@ class Paths
|
||||
*
|
||||
* NO TRAILING SLASH!
|
||||
*/
|
||||
public $applicationDirectory = '../application';
|
||||
public $applicationDirectory = 'application';
|
||||
|
||||
/*
|
||||
* ---------------------------------------------------------------
|
||||
@ -47,7 +47,7 @@ class Paths
|
||||
* for maximum security, keeping it out of the application and/or
|
||||
* system directories.
|
||||
*/
|
||||
public $writableDirectory = '../writable';
|
||||
public $writableDirectory = 'writable';
|
||||
|
||||
/*
|
||||
* ---------------------------------------------------------------
|
||||
@ -60,7 +60,7 @@ class Paths
|
||||
* for maximum security, keeping it out of the application and/or
|
||||
* system directories.
|
||||
*/
|
||||
public $testsDirectory = '../tests';
|
||||
public $testsDirectory = 'tests';
|
||||
|
||||
/*
|
||||
* ---------------------------------------------------------------
|
||||
|
@ -1,6 +1,7 @@
|
||||
<?php namespace Config;
|
||||
|
||||
use CodeIgniter\Config\Services as CoreServices;
|
||||
use CodeIgniter\Config\BaseConfig;
|
||||
|
||||
require_once BASEPATH.'Config/Services.php';
|
||||
|
||||
@ -30,5 +31,20 @@ class Services extends CoreServices
|
||||
// return new \CodeIgniter\Example();
|
||||
// }
|
||||
|
||||
public static function honeypot(BaseConfig $config = null, $getShared = true)
|
||||
{
|
||||
if ($getShared)
|
||||
{
|
||||
return self::getSharedInstance('honeypot', $config);
|
||||
}
|
||||
|
||||
if (is_null($config))
|
||||
{
|
||||
$config = new \Config\Honeypot();
|
||||
}
|
||||
|
||||
return new \CodeIgniter\Honeypot\Honeypot($config);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
219
application/Config/UserAgents.php
Normal file
219
application/Config/UserAgents.php
Normal file
@ -0,0 +1,219 @@
|
||||
<?php namespace Config;
|
||||
|
||||
use CodeIgniter\Config\BaseConfig;
|
||||
|
||||
class UserAgents extends BaseConfig
|
||||
{
|
||||
/*
|
||||
| -------------------------------------------------------------------
|
||||
| USER AGENT TYPES
|
||||
| -------------------------------------------------------------------
|
||||
| This file contains four arrays of user agent data. It is used by the
|
||||
| User Agent Class to help identify browser, platform, robot, and
|
||||
| mobile device data. The array keys are used to identify the device
|
||||
| and the array values are used to set the actual name of the item.
|
||||
*/
|
||||
public $platforms = [
|
||||
'windows nt 10.0' => 'Windows 10',
|
||||
'windows nt 6.3' => 'Windows 8.1',
|
||||
'windows nt 6.2' => 'Windows 8',
|
||||
'windows nt 6.1' => 'Windows 7',
|
||||
'windows nt 6.0' => 'Windows Vista',
|
||||
'windows nt 5.2' => 'Windows 2003',
|
||||
'windows nt 5.1' => 'Windows XP',
|
||||
'windows nt 5.0' => 'Windows 2000',
|
||||
'windows nt 4.0' => 'Windows NT 4.0',
|
||||
'winnt4.0' => 'Windows NT 4.0',
|
||||
'winnt 4.0' => 'Windows NT',
|
||||
'winnt' => 'Windows NT',
|
||||
'windows 98' => 'Windows 98',
|
||||
'win98' => 'Windows 98',
|
||||
'windows 95' => 'Windows 95',
|
||||
'win95' => 'Windows 95',
|
||||
'windows phone' => 'Windows Phone',
|
||||
'windows' => 'Unknown Windows OS',
|
||||
'android' => 'Android',
|
||||
'blackberry' => 'BlackBerry',
|
||||
'iphone' => 'iOS',
|
||||
'ipad' => 'iOS',
|
||||
'ipod' => 'iOS',
|
||||
'os x' => 'Mac OS X',
|
||||
'ppc mac' => 'Power PC Mac',
|
||||
'freebsd' => 'FreeBSD',
|
||||
'ppc' => 'Macintosh',
|
||||
'linux' => 'Linux',
|
||||
'debian' => 'Debian',
|
||||
'sunos' => 'Sun Solaris',
|
||||
'beos' => 'BeOS',
|
||||
'apachebench' => 'ApacheBench',
|
||||
'aix' => 'AIX',
|
||||
'irix' => 'Irix',
|
||||
'osf' => 'DEC OSF',
|
||||
'hp-ux' => 'HP-UX',
|
||||
'netbsd' => 'NetBSD',
|
||||
'bsdi' => 'BSDi',
|
||||
'openbsd' => 'OpenBSD',
|
||||
'gnu' => 'GNU/Linux',
|
||||
'unix' => 'Unknown Unix OS',
|
||||
'symbian' => 'Symbian OS',
|
||||
];
|
||||
|
||||
|
||||
// The order of this array should NOT be changed. Many browsers return
|
||||
// multiple browser types so we want to identify the sub-type first.
|
||||
public $browsers = [
|
||||
'OPR' => 'Opera',
|
||||
'Flock' => 'Flock',
|
||||
'Edge' => 'Spartan',
|
||||
'Chrome' => 'Chrome',
|
||||
// Opera 10+ always reports Opera/9.80 and appends Version/<real version> to the user agent string
|
||||
'Opera.*?Version' => 'Opera',
|
||||
'Opera' => 'Opera',
|
||||
'MSIE' => 'Internet Explorer',
|
||||
'Internet Explorer' => 'Internet Explorer',
|
||||
'Trident.* rv' => 'Internet Explorer',
|
||||
'Shiira' => 'Shiira',
|
||||
'Firefox' => 'Firefox',
|
||||
'Chimera' => 'Chimera',
|
||||
'Phoenix' => 'Phoenix',
|
||||
'Firebird' => 'Firebird',
|
||||
'Camino' => 'Camino',
|
||||
'Netscape' => 'Netscape',
|
||||
'OmniWeb' => 'OmniWeb',
|
||||
'Safari' => 'Safari',
|
||||
'Mozilla' => 'Mozilla',
|
||||
'Konqueror' => 'Konqueror',
|
||||
'icab' => 'iCab',
|
||||
'Lynx' => 'Lynx',
|
||||
'Links' => 'Links',
|
||||
'hotjava' => 'HotJava',
|
||||
'amaya' => 'Amaya',
|
||||
'IBrowse' => 'IBrowse',
|
||||
'Maxthon' => 'Maxthon',
|
||||
'Ubuntu' => 'Ubuntu Web Browser',
|
||||
'Vivaldi' => 'Vivaldi',
|
||||
];
|
||||
|
||||
public $mobiles = [
|
||||
// legacy array, old values commented out
|
||||
'mobileexplorer' => 'Mobile Explorer',
|
||||
// 'openwave' => 'Open Wave',
|
||||
// 'opera mini' => 'Opera Mini',
|
||||
// 'operamini' => 'Opera Mini',
|
||||
// 'elaine' => 'Palm',
|
||||
'palmsource' => 'Palm',
|
||||
// 'digital paths' => 'Palm',
|
||||
// 'avantgo' => 'Avantgo',
|
||||
// 'xiino' => 'Xiino',
|
||||
'palmscape' => 'Palmscape',
|
||||
// 'nokia' => 'Nokia',
|
||||
// 'ericsson' => 'Ericsson',
|
||||
// 'blackberry' => 'BlackBerry',
|
||||
// 'motorola' => 'Motorola'
|
||||
|
||||
// Phones and Manufacturers
|
||||
'motorola' => 'Motorola',
|
||||
'nokia' => 'Nokia',
|
||||
'palm' => 'Palm',
|
||||
'iphone' => 'Apple iPhone',
|
||||
'ipad' => 'iPad',
|
||||
'ipod' => 'Apple iPod Touch',
|
||||
'sony' => 'Sony Ericsson',
|
||||
'ericsson' => 'Sony Ericsson',
|
||||
'blackberry' => 'BlackBerry',
|
||||
'cocoon' => 'O2 Cocoon',
|
||||
'blazer' => 'Treo',
|
||||
'lg' => 'LG',
|
||||
'amoi' => 'Amoi',
|
||||
'xda' => 'XDA',
|
||||
'mda' => 'MDA',
|
||||
'vario' => 'Vario',
|
||||
'htc' => 'HTC',
|
||||
'samsung' => 'Samsung',
|
||||
'sharp' => 'Sharp',
|
||||
'sie-' => 'Siemens',
|
||||
'alcatel' => 'Alcatel',
|
||||
'benq' => 'BenQ',
|
||||
'ipaq' => 'HP iPaq',
|
||||
'mot-' => 'Motorola',
|
||||
'playstation portable' => 'PlayStation Portable',
|
||||
'playstation 3' => 'PlayStation 3',
|
||||
'playstation vita' => 'PlayStation Vita',
|
||||
'hiptop' => 'Danger Hiptop',
|
||||
'nec-' => 'NEC',
|
||||
'panasonic' => 'Panasonic',
|
||||
'philips' => 'Philips',
|
||||
'sagem' => 'Sagem',
|
||||
'sanyo' => 'Sanyo',
|
||||
'spv' => 'SPV',
|
||||
'zte' => 'ZTE',
|
||||
'sendo' => 'Sendo',
|
||||
'nintendo dsi' => 'Nintendo DSi',
|
||||
'nintendo ds' => 'Nintendo DS',
|
||||
'nintendo 3ds' => 'Nintendo 3DS',
|
||||
'wii' => 'Nintendo Wii',
|
||||
'open web' => 'Open Web',
|
||||
'openweb' => 'OpenWeb',
|
||||
|
||||
// Operating Systems
|
||||
'android' => 'Android',
|
||||
'symbian' => 'Symbian',
|
||||
'SymbianOS' => 'SymbianOS',
|
||||
'elaine' => 'Palm',
|
||||
'series60' => 'Symbian S60',
|
||||
'windows ce' => 'Windows CE',
|
||||
|
||||
// Browsers
|
||||
'obigo' => 'Obigo',
|
||||
'netfront' => 'Netfront Browser',
|
||||
'openwave' => 'Openwave Browser',
|
||||
'mobilexplorer' => 'Mobile Explorer',
|
||||
'operamini' => 'Opera Mini',
|
||||
'opera mini' => 'Opera Mini',
|
||||
'opera mobi' => 'Opera Mobile',
|
||||
'fennec' => 'Firefox Mobile',
|
||||
|
||||
// Other
|
||||
'digital paths' => 'Digital Paths',
|
||||
'avantgo' => 'AvantGo',
|
||||
'xiino' => 'Xiino',
|
||||
'novarra' => 'Novarra Transcoder',
|
||||
'vodafone' => 'Vodafone',
|
||||
'docomo' => 'NTT DoCoMo',
|
||||
'o2' => 'O2',
|
||||
|
||||
// Fallback
|
||||
'mobile' => 'Generic Mobile',
|
||||
'wireless' => 'Generic Mobile',
|
||||
'j2me' => 'Generic Mobile',
|
||||
'midp' => 'Generic Mobile',
|
||||
'cldc' => 'Generic Mobile',
|
||||
'up.link' => 'Generic Mobile',
|
||||
'up.browser' => 'Generic Mobile',
|
||||
'smartphone' => 'Generic Mobile',
|
||||
'cellphone' => 'Generic Mobile',
|
||||
];
|
||||
|
||||
// There are hundreds of bots but these are the most common.
|
||||
public $robots = [
|
||||
'googlebot' => 'Googlebot',
|
||||
'msnbot' => 'MSNBot',
|
||||
'baiduspider' => 'Baiduspider',
|
||||
'bingbot' => 'Bing',
|
||||
'slurp' => 'Inktomi Slurp',
|
||||
'yahoo' => 'Yahoo',
|
||||
'ask jeeves' => 'Ask Jeeves',
|
||||
'fastcrawler' => 'FastCrawler',
|
||||
'infoseek' => 'InfoSeek Robot 1.0',
|
||||
'lycos' => 'Lycos',
|
||||
'yandex' => 'YandexBot',
|
||||
'mediapartners-google' => 'MediaPartners Google',
|
||||
'CRAZYWEBCRAWLER' => 'Crazy Webcrawler',
|
||||
'adsbot-google' => 'AdsBot Google',
|
||||
'feedfetcher-google' => 'Feedfetcher Google',
|
||||
'curious george' => 'Curious George',
|
||||
'ia_archiver' => 'Alexa Crawler',
|
||||
'MJ12bot' => 'Majestic-12',
|
||||
'Uptimebot' => 'Uptimebot',
|
||||
];
|
||||
}
|
@ -1,516 +0,0 @@
|
||||
<?php namespace App\Controllers;
|
||||
|
||||
use CodeIgniter\API\ResponseTrait;
|
||||
use CodeIgniter\Config\Services;
|
||||
use CodeIgniter\Controller;
|
||||
use CodeIgniter\I18n\Time;
|
||||
use CodeIgniter\Model;
|
||||
use Config\Database;
|
||||
|
||||
/**
|
||||
* NOTE: This is not a valid file for actual tests.
|
||||
* This file came about as a small testbed I was using that
|
||||
* accidentally got committed. It will be removed prior to release
|
||||
* If you commit any changes to this file, it should be accompanied
|
||||
* by actual tests also.
|
||||
*
|
||||
* @package App\Controllers
|
||||
*/
|
||||
class Checks extends Controller
|
||||
{
|
||||
use ResponseTrait;
|
||||
|
||||
public function index()
|
||||
{
|
||||
session()->start();
|
||||
}
|
||||
|
||||
public function forge()
|
||||
{
|
||||
echo '<h1>MySQL</h1>';
|
||||
|
||||
log_message('debug', 'MYSQL TEST');
|
||||
|
||||
$forge_mysql = \Config\Database::forge();
|
||||
|
||||
$forge_mysql->getConnection()->query('SET @OLD_FOREIGN_KEY_CHECKS=@@FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=0;');
|
||||
|
||||
$forge_mysql->dropTable('users', true);
|
||||
|
||||
$forge_mysql->getConnection()->query('SET FOREIGN_KEY_CHECKS=@OLD_FOREIGN_KEY_CHECKS;');
|
||||
|
||||
$forge_mysql->addField([
|
||||
'id' => [
|
||||
'type' => 'INTEGER',
|
||||
'constraint' => 11
|
||||
],
|
||||
'name' => [
|
||||
'type' => 'VARCHAR',
|
||||
'constraint' => 50,
|
||||
]
|
||||
]);
|
||||
$forge_mysql->addKey('id', true);
|
||||
$attributes = array('ENGINE' => 'InnoDB');
|
||||
$forge_mysql->createTable('users', true, $attributes);
|
||||
|
||||
$data_insert = array(
|
||||
'id' => 1,
|
||||
'name' => 'User 1',
|
||||
);
|
||||
$forge_mysql->getConnection()->table('users')->insert($data_insert);
|
||||
|
||||
$drop = $forge_mysql->dropTable('invoices', true);
|
||||
|
||||
$forge_mysql->addField([
|
||||
'id' => [
|
||||
'type' => 'INTEGER',
|
||||
'constraint' => 11,
|
||||
],
|
||||
'users_id' => [
|
||||
'type' => 'INTEGER',
|
||||
'constraint' => 11
|
||||
],
|
||||
'other_id' => [
|
||||
'type' => 'INTEGER',
|
||||
'constraint' => 11
|
||||
]
|
||||
]);
|
||||
$forge_mysql->addKey('id', true);
|
||||
|
||||
$forge_mysql->addForeignKey('users_id','users','id','CASCADE','CASCADE');
|
||||
$forge_mysql->addForeignKey('other_id','users','id','CASCADE','CASCADE');
|
||||
|
||||
$attributes = array('ENGINE' => 'InnoDB');
|
||||
$res = $forge_mysql->createTable('invoices', true,$attributes);
|
||||
|
||||
if(!$res){
|
||||
var_dump($forge_mysql->getConnection()->mysqli);
|
||||
}else{
|
||||
echo '<br><br>OK';
|
||||
|
||||
var_dump($forge_mysql->getConnection()->getForeignKeyData('invoices'));
|
||||
}
|
||||
|
||||
$res = $forge_mysql->dropForeignKey('invoices','invoices_other_id_foreign');
|
||||
|
||||
|
||||
echo '<h1>PostgreSQL</h1>';
|
||||
|
||||
$forge_pgsql = \Config\Database::forge('pgsql');
|
||||
|
||||
$forge_pgsql->dropTable('users',true, true);
|
||||
|
||||
$forge_pgsql->addField([
|
||||
'id' => [
|
||||
'type' => 'INTEGER',
|
||||
'constraint' => 11,
|
||||
'auto_increment' => true,
|
||||
],
|
||||
'name' => [
|
||||
'type' => 'VARCHAR',
|
||||
'constraint' => 50,
|
||||
]
|
||||
]);
|
||||
$forge_pgsql->addKey('id', true);
|
||||
$forge_pgsql->createTable('users', true);
|
||||
|
||||
|
||||
$data_insert = array(
|
||||
'id' => 1,
|
||||
'name' => 'User 1',
|
||||
);
|
||||
$forge_pgsql->getConnection()->table('users')->insert($data_insert);
|
||||
|
||||
$forge_pgsql->dropTable('invoices',true);
|
||||
$forge_pgsql->addField([
|
||||
'id' => [
|
||||
'type' => 'INTEGER',
|
||||
'constraint' => 11,
|
||||
'auto_increment' => true,
|
||||
],
|
||||
'users_id' => [
|
||||
'type' => 'INTEGER',
|
||||
'constraint' => 11
|
||||
],
|
||||
'other_id' => [
|
||||
'type' => 'INTEGER',
|
||||
'constraint' => 11
|
||||
],
|
||||
'another_id' => [
|
||||
'type' => 'INTEGER',
|
||||
'constraint' => 11
|
||||
]
|
||||
]);
|
||||
$forge_pgsql->addKey('id', true);
|
||||
|
||||
$forge_pgsql->addForeignKey('users_id','users','id','CASCADE','CASCADE');
|
||||
$forge_pgsql->addForeignKey('other_id','users','id');
|
||||
|
||||
$res = $forge_pgsql->createTable('invoices', true);
|
||||
|
||||
if(!$res){
|
||||
var_dump($forge_pgsql->getConnection()->mysqli);
|
||||
}else{
|
||||
echo '<br><br>OK';
|
||||
var_dump($forge_pgsql->getConnection()->getForeignKeyData('invoices'));
|
||||
}
|
||||
|
||||
//$res = $forge_pgsql->dropForeignKey('invoices','invoices_other_id_foreign');
|
||||
|
||||
}
|
||||
|
||||
public function sqlite()
|
||||
{
|
||||
$forge = \Config\Database::forge();
|
||||
$forge->dropTable('users', true);
|
||||
$forge->dropTable('invoices', true);
|
||||
|
||||
// Ensure Foreign Keys are on
|
||||
$forge->getConnection()->simpleQuery("PRAGMA foreign_keys=1");
|
||||
|
||||
// Create a table
|
||||
$forge->addField([
|
||||
'id' => [
|
||||
'type' => 'INTEGER',
|
||||
'constraint' => 11,
|
||||
'auto_increment' => true,
|
||||
],
|
||||
'name' => [
|
||||
'type' => 'VARCHAR',
|
||||
'constraint' => 50,
|
||||
]
|
||||
]);
|
||||
$forge->addKey('id', true);
|
||||
$forge->createTable('users', true);
|
||||
|
||||
$data_insert = array(
|
||||
'id' => 1,
|
||||
'name' => 'User 1',
|
||||
);
|
||||
|
||||
$forge->getConnection()->table('users')->insert($data_insert);
|
||||
$forge->addField([
|
||||
'id' => [
|
||||
'type' => 'INTEGER',
|
||||
'constraint' => 11,
|
||||
'auto_increment' => true,
|
||||
],
|
||||
'users_id' => [
|
||||
'type' => 'INTEGER',
|
||||
'constraint' => 11
|
||||
],
|
||||
'other_id' => [
|
||||
'type' => 'INTEGER',
|
||||
'constraint' => 11
|
||||
],
|
||||
'another_id' => [
|
||||
'type' => 'INTEGER',
|
||||
'constraint' => 11
|
||||
]
|
||||
]);
|
||||
$forge->addKey('id', true);
|
||||
|
||||
$forge->addForeignKey('users_id','users','id','CASCADE','CASCADE');
|
||||
$forge->addForeignKey('other_id','users','id');
|
||||
|
||||
$res = $forge->createTable('invoices', true);
|
||||
|
||||
dd($forge->getConnection()->getForeignKeyData('invoices'));
|
||||
}
|
||||
|
||||
|
||||
public function escape()
|
||||
{
|
||||
$db = Database::connect();
|
||||
$db->initialize();
|
||||
|
||||
$jobs = $db->table('job')
|
||||
->whereNotIn('name', ['Politician', 'Accountant'])
|
||||
->get()
|
||||
->getResult();
|
||||
|
||||
die(var_dump($jobs));
|
||||
}
|
||||
|
||||
public function password()
|
||||
{
|
||||
$db = Database::connect();
|
||||
$db->initialize();
|
||||
|
||||
$result = $db->table('misc')
|
||||
->insert([
|
||||
'key' => 'password',
|
||||
'value' => '$2y$10$ErQlCj/Mo10il.FthAm0WOjYdf3chZEGPFqaPzjqOX2aj2uYf5Ihq'
|
||||
]);
|
||||
|
||||
die(var_dump($result));
|
||||
}
|
||||
|
||||
|
||||
public function forms()
|
||||
{
|
||||
helper('form');
|
||||
|
||||
var_dump(form_open());
|
||||
}
|
||||
|
||||
public function api()
|
||||
{
|
||||
$data = [
|
||||
"total_users" => 3,
|
||||
"users" => [
|
||||
[
|
||||
"id" => 1,
|
||||
"name" => "Nitya",
|
||||
"address" => [
|
||||
"country" => "India",
|
||||
"city" => "Kolkata",
|
||||
"zip" => 700102,
|
||||
]
|
||||
],
|
||||
[
|
||||
"id" => 2,
|
||||
"name" => "John",
|
||||
"address" => [
|
||||
"country" => "USA",
|
||||
"city" => "Newyork",
|
||||
"zip" => "NY1234",
|
||||
]
|
||||
],
|
||||
[
|
||||
"id" => 3,
|
||||
"name" => "Viktor",
|
||||
"address" => [
|
||||
"country" => "Australia",
|
||||
"city" => "Sydney",
|
||||
"zip" => 123456,
|
||||
]
|
||||
],
|
||||
]
|
||||
];
|
||||
|
||||
return $this->respond($data);
|
||||
}
|
||||
|
||||
public function db()
|
||||
{
|
||||
$db = Database::connect();
|
||||
$db->initialize();
|
||||
|
||||
$query = $db->prepare(function($db){
|
||||
return $db->table('user')->insert([
|
||||
'name' => 'a',
|
||||
'email' => 'b@example.com',
|
||||
'country' => 'x'
|
||||
]);
|
||||
});
|
||||
|
||||
$query->execute('foo', 'foo@example.com', 'US');
|
||||
}
|
||||
|
||||
public function db2()
|
||||
{
|
||||
$db = Database::connect();
|
||||
$db->initialize();
|
||||
|
||||
$db->table('user')->insert([
|
||||
'name' => 'a',
|
||||
'email' => 'b@example.com',
|
||||
'country' => 'x'
|
||||
]);
|
||||
}
|
||||
|
||||
public function format()
|
||||
{
|
||||
echo '<pre>';
|
||||
var_dump($this->response->getHeaderLine('content-type'));
|
||||
}
|
||||
|
||||
public function model()
|
||||
{
|
||||
$model = new class() extends Model {
|
||||
protected $table = 'job';
|
||||
};
|
||||
|
||||
$results = $model->findAll();
|
||||
|
||||
$developer = $model->findWhere('name', 'Developer');
|
||||
|
||||
$politician = $model->find(3);
|
||||
|
||||
dd($politician);
|
||||
|
||||
}
|
||||
|
||||
public function curl()
|
||||
{
|
||||
$client = Services::curlrequest([
|
||||
'debug' => true,
|
||||
'follow_redirects' => true,
|
||||
'json' => ['foo' => 'bar']
|
||||
]);
|
||||
|
||||
echo '<pre>';
|
||||
$response = $client->request('PUT', 'http://ci4.dev/checks/catch');
|
||||
echo $response->getBody();
|
||||
}
|
||||
|
||||
// Simply echos back what's given in the body.
|
||||
public function catch()
|
||||
{
|
||||
$body = print_r($this->request->getRawInput(), true);
|
||||
echo $body;
|
||||
}
|
||||
|
||||
public function redirect()
|
||||
{
|
||||
return redirect('/checks/model');
|
||||
}
|
||||
|
||||
public function image()
|
||||
{
|
||||
$info = Services::image('imagick')
|
||||
->withFile("/Users/kilishan/Documents/BobHeader.jpg")
|
||||
->getFile()
|
||||
->getProperties(true);
|
||||
|
||||
dd(ENVIRONMENT);
|
||||
|
||||
$images = Services::image('imagick')
|
||||
->getVersion();
|
||||
// ->withFile("/Users/kilishan/Documents/BobHeader.jpg")
|
||||
// ->resize(500, 100, true)
|
||||
// ->crop(200, 75, 20, 0, false)
|
||||
// ->rotate(90)
|
||||
// ->save('/Users/kilishan/temp.jpg');
|
||||
|
||||
// $images = Services::image('imagick')
|
||||
// ->withFile("/Users/kilishan/Documents/BobHeader.jpg")
|
||||
// ->fit(500, 100, 'bottom-left')
|
||||
// ->text('Bob is Back!', [
|
||||
// 'fontPath' => '/Users/kilishan/Downloads/Calibri.ttf',
|
||||
// 'fontSize' => 40,
|
||||
// 'padding' => 0,
|
||||
// 'opacity' => 0.5,
|
||||
// 'vAlign' => 'top',
|
||||
// 'hAlign' => 'right',
|
||||
// 'withShadow' => true,
|
||||
// ])
|
||||
// ->save('/Users/kilishan/temp.jpg', 100);
|
||||
|
||||
|
||||
ddd($images);
|
||||
}
|
||||
|
||||
public function time()
|
||||
{
|
||||
$time = new Time();
|
||||
|
||||
echo($time);
|
||||
echo '<br/>';
|
||||
echo Time::now();
|
||||
echo '<br/>';
|
||||
echo Time::parse('First Monday of December');
|
||||
echo '<br/>';
|
||||
|
||||
$time = new Time('Next Monday');
|
||||
die($time);
|
||||
}
|
||||
|
||||
public function csp()
|
||||
{
|
||||
// $this->response->CSP->reportOnly(true);
|
||||
$this->response->CSP->setDefaultSrc(base_url());
|
||||
$this->response->CSP->addStyleSrc('unsafe-inline');
|
||||
$this->response->CSP->addStyleSrc('https://maxcdn.bootstrapcdn.com');
|
||||
|
||||
echo <<<EOF
|
||||
<!doctype html>
|
||||
<html>
|
||||
<head>
|
||||
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" integrity="sha384-BVYiiSIFeK1dGmJRAkycuHAHRg32OmUcww7on3RYdg4Va+PmSTsz/K68vbdEjh4u" crossorigin="anonymous">
|
||||
</head>
|
||||
<body>
|
||||
<style {csp-style-nonce}>
|
||||
body { background: #efefef; }
|
||||
</style>
|
||||
|
||||
</body>
|
||||
</html>
|
||||
EOF;
|
||||
|
||||
}
|
||||
|
||||
public function upload()
|
||||
{
|
||||
if ($this->request->getMethod() == 'post')
|
||||
{
|
||||
$this->validate([
|
||||
'avatar' => 'uploaded[avatar]|ext_in[avatar,png,jpg,jpeg,gif]'
|
||||
]);
|
||||
|
||||
/**
|
||||
* @var \CodeIgniter\HTTP\Files\UploadedFile
|
||||
*/
|
||||
$file = $this->request->getFile('avatar');
|
||||
|
||||
echo "Name: {$file->getName()}<br/>";
|
||||
echo "Temp Name: {$file->getTempName()}<br/>";
|
||||
echo "Original Name: {$file->getClientName()}<br/>";
|
||||
echo "Random Name: {$file->getRandomName()}<br/>";
|
||||
echo "Extension: {$file->getExtension()}<br/>";
|
||||
echo "Client Extension: {$file->getClientExtension()}<br/>";
|
||||
echo "Guessed Extension: {$file->guessExtension()}<br/>";
|
||||
echo "MimeType: {$file->getMimeType()}<br/>";
|
||||
echo "IsValid: {$file->isValid()}<br/>";
|
||||
echo "Size (b): {$file->getSize()}<br/>";
|
||||
echo "Size (kb): {$file->getSize('kb')}<br/>";
|
||||
echo "Size (mb): {$file->getSize('mb')}<br/>";
|
||||
echo "Size (mb): {$file->getSize('mb')}<br/>";
|
||||
echo "Path: {$file->getPath()}<br/>";
|
||||
echo "RealPath: {$file->getRealPath()}<br/>";
|
||||
echo "Filename: {$file->getFilename()}<br/>";
|
||||
echo "Basename: {$file->getBasename()}<br/>";
|
||||
echo "Pathname: {$file->getPathname()}<br/>";
|
||||
echo "Permissions: {$file->getPerms()}<br/>";
|
||||
echo "Inode: {$file->getInode()}<br/>";
|
||||
echo "Owner: {$file->getOwner()}<br/>";
|
||||
echo "Group: {$file->getGroup()}<br/>";
|
||||
echo "ATime: {$file->getATime()}<br/>";
|
||||
echo "MTime: {$file->getMTime()}<br/>";
|
||||
echo "CTime: {$file->getCTime()}<br/>";
|
||||
|
||||
dd($file);
|
||||
}
|
||||
|
||||
echo <<<EOF
|
||||
<!doctype html>
|
||||
<html>
|
||||
<body>
|
||||
|
||||
<form action="" method="post" enctype="multipart/form-data">
|
||||
|
||||
<input type="file" name="avatar">
|
||||
|
||||
<input type="submit" value="Upload">
|
||||
|
||||
</form>
|
||||
|
||||
</body>
|
||||
</html>
|
||||
|
||||
EOF;
|
||||
;
|
||||
}
|
||||
|
||||
public function parser()
|
||||
{
|
||||
$this->parser = Services::parser();
|
||||
}
|
||||
|
||||
public function error()
|
||||
{
|
||||
throw new \RuntimeException('Oops!', 403);
|
||||
}
|
||||
|
||||
}
|
@ -3,6 +3,7 @@
|
||||
use CodeIgniter\Filters\FilterInterface;
|
||||
use CodeIgniter\HTTP\RequestInterface;
|
||||
use CodeIgniter\HTTP\ResponseInterface;
|
||||
use CodeIgniter\Security\Exceptions\SecurityException;
|
||||
use Config\Services;
|
||||
|
||||
class CSRF implements FilterInterface
|
||||
@ -30,7 +31,19 @@ class CSRF implements FilterInterface
|
||||
|
||||
$security = Services::security();
|
||||
|
||||
$security->CSRFVerify($request);
|
||||
try
|
||||
{
|
||||
$security->CSRFVerify($request);
|
||||
}
|
||||
catch (SecurityException $e)
|
||||
{
|
||||
if (config('App')->CSRFRedirect && ! $request->isAJAX())
|
||||
{
|
||||
return redirect()->back()->with('error', $e->getMessage());
|
||||
}
|
||||
|
||||
throw $e;
|
||||
}
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
|
@ -33,23 +33,20 @@ 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());
|
||||
$toolbar = Services::toolbar(config(App::class));
|
||||
$stats = $app->getPerformanceStats();
|
||||
$output = $toolbar->run(
|
||||
$data = $toolbar->run(
|
||||
$stats['startTime'],
|
||||
$stats['totalTime'],
|
||||
$stats['startMemory'],
|
||||
$request,
|
||||
$response
|
||||
);
|
||||
|
||||
helper(['filesystem', 'url']);
|
||||
helper('filesystem');
|
||||
|
||||
// Updated to time() so we can get history
|
||||
$time = time();
|
||||
@ -59,12 +56,26 @@ 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" '
|
||||
. '<script type="text/javascript" {csp-script-nonce} id="debugbar_loader" '
|
||||
. 'data-time="' . $time . '" '
|
||||
. 'src="' . rtrim(site_url(), '/') . '?debugbar"></script>'
|
||||
. '<script type="text/javascript" {csp-script-nonce} id="debugbar_dynamic_script"></script>'
|
||||
. '<style type="text/css" {csp-style-nonce} id="debugbar_dynamic_style"></style>'
|
||||
. PHP_EOL;
|
||||
|
||||
if (strpos($response->getBody(), '</body>') !== false)
|
||||
|
51
application/Filters/Honeypot.php
Normal file
51
application/Filters/Honeypot.php
Normal file
@ -0,0 +1,51 @@
|
||||
<?php namespace App\Filters;
|
||||
|
||||
use CodeIgniter\Filters\FilterInterface;
|
||||
use CodeIgniter\HTTP\RequestInterface;
|
||||
use CodeIgniter\HTTP\ResponseInterface;
|
||||
use Config\Services;
|
||||
use CodeIgniter\Honeypot\Exceptions\HoneypotException;
|
||||
|
||||
class Honeypot implements FilterInterface
|
||||
{
|
||||
|
||||
/**
|
||||
* Checks if Honeypot field is empty, if so
|
||||
* then the requester is a bot,show a blank
|
||||
* page
|
||||
*
|
||||
* @param RequestInterface|\CodeIgniter\HTTP\IncomingRequest $request
|
||||
*
|
||||
* @return mixed
|
||||
*/
|
||||
|
||||
public function before (RequestInterface $request)
|
||||
{
|
||||
|
||||
// Checks honeypot field if value was entered then show blank if so.
|
||||
|
||||
$honeypot = Services::honeypot(new \Config\Honeypot());
|
||||
if($honeypot->hasContent($request))
|
||||
{
|
||||
throw HoneypotException::isBot();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if Honeypot field is empty, if so
|
||||
* then the requester is a bot,show a blank
|
||||
* page
|
||||
*
|
||||
* @param RequestInterface|\CodeIgniter\HTTP\IncomingRequest $request
|
||||
* @param ResponseInterface|\CodeIgniter\HTTP\Response $response
|
||||
* @return mixed
|
||||
*/
|
||||
|
||||
public function after (RequestInterface $request, ResponseInterface $response)
|
||||
{
|
||||
|
||||
$honeypot = Services::honeypot(new \Config\Honeypot());
|
||||
$honeypot->attachHoneypot($response);
|
||||
}
|
||||
}
|
@ -190,7 +190,7 @@
|
||||
|
||||
<!-- Request -->
|
||||
<div class="content" id="request">
|
||||
<?php $request = \CodeIgniter\Config\Services::request(null, true); ?>
|
||||
<?php $request = \Config\Services::request(); ?>
|
||||
|
||||
<table>
|
||||
<tbody>
|
||||
@ -220,7 +220,7 @@
|
||||
</tr>
|
||||
<tr>
|
||||
<td>User Agent</td>
|
||||
<td><?= $request->getUserAgent() ?></td>
|
||||
<td><?= $request->getUserAgent()->getAgentString() ?></td>
|
||||
</tr>
|
||||
|
||||
</tbody>
|
||||
@ -299,7 +299,7 @@
|
||||
|
||||
<!-- Response -->
|
||||
<?php
|
||||
$response = \CodeIgniter\Config\Services::response(null, true);
|
||||
$response = \Config\Services::response();
|
||||
$response->setStatusCode(http_response_code());
|
||||
?>
|
||||
<div class="content" id="response">
|
||||
|
@ -12,17 +12,19 @@
|
||||
},
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
"CodeIgniter\\": "system/"
|
||||
"CodeIgniter\\": "system/",
|
||||
"Psr\\Log\\": "system/ThirdParty/PSR/Log/"
|
||||
}
|
||||
},
|
||||
"require": {
|
||||
"php": ">=7.1",
|
||||
"zendframework/zend-escaper": "^2.5",
|
||||
"paragonie/sodium_compat": "^1.1",
|
||||
"kint-php/kint": "^2.1"
|
||||
"kint-php/kint": "^2.1",
|
||||
"ext-intl": "*"
|
||||
},
|
||||
"require-dev": {
|
||||
"phpunit/phpunit": "^6.0",
|
||||
"phpunit/phpunit": "^7.0",
|
||||
"mikey179/vfsStream": "1.6.*",
|
||||
"codeigniter4/codeigniter4-standard": "^1.0"
|
||||
},
|
||||
|
11
env
11
env
@ -20,7 +20,7 @@
|
||||
# app.sessionDriver = 'CodeIgniter\Session\Handlers\FileHandler'
|
||||
# app.sessionCookieName = 'ci_session'
|
||||
# app.sessionSavePath = NULL
|
||||
# app.sessionMachIP = false
|
||||
# app.sessionMatchIP = false
|
||||
# app.sessionTimeToUpdate = 300
|
||||
# app.sessionRegenerateDestroy = false
|
||||
|
||||
@ -76,3 +76,12 @@
|
||||
# contentsecuritypolicy.reportURI = null
|
||||
# contentsecuritypolicy.sandbox = false
|
||||
# contentsecuritypolicy.upgradeInsecureRequests = false
|
||||
|
||||
#--------------------------------------------------------------------
|
||||
# HONEYPOT
|
||||
#--------------------------------------------------------------------
|
||||
|
||||
# honeypot.hidden = 'true'
|
||||
# honeypot.label = 'Fill This Field'
|
||||
# honeypot.name = 'honeypot'
|
||||
# honeypot.template = '<label>{label}</label><input type="text" name="{name}" value=""/>'
|
||||
|
111
index.html
111
index.html
@ -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>
|
||||
|
@ -10,6 +10,10 @@
|
||||
stopOnIncomplete="false"
|
||||
stopOnSkipped="false">
|
||||
<testsuites>
|
||||
<testsuite name="app">
|
||||
<directory>./tests</directory>
|
||||
<exclude>./tests/system</exclude>
|
||||
</testsuite>
|
||||
<testsuite name="system">
|
||||
<directory>./tests/system</directory>
|
||||
<exclude>./tests/system/Database</exclude>
|
||||
@ -23,14 +27,14 @@
|
||||
<whitelist processUncoveredFilesFromWhitelist="true">
|
||||
<directory suffix=".php">./system</directory>
|
||||
<exclude>
|
||||
<file>./system/bootstrap.php</file>
|
||||
<file>./system/Commands/Sessions/Views/migration.tpl.php</file>
|
||||
<file>./system/ComposerScripts.php</file>
|
||||
<file>./system/Config/Routes.php</file>
|
||||
<directory>./system/Debug/Toolbar/Views</directory>
|
||||
<directory>./system/Pager/Views</directory>
|
||||
<directory>./system/ThirdParty</directory>
|
||||
<directory>./system/Validation/Views</directory>
|
||||
<file>./system/bootstrap.php</file>
|
||||
<file>./system/Commands/Sessions/Views/migration.tpl.php</file>
|
||||
<file>./system/ComposerScripts.php</file>
|
||||
<file>./system/Config/Routes.php</file>
|
||||
</exclude>
|
||||
</whitelist>
|
||||
</filter>
|
||||
|
@ -1,13 +1,12 @@
|
||||
<?php
|
||||
|
||||
// Location to the Paths config file.
|
||||
// This should be the only line you need to
|
||||
// edit in this file.
|
||||
$pathsPath = '../application/Config/Paths.php';
|
||||
|
||||
// Path to the front controller (this file)
|
||||
define('FCPATH', __DIR__.DIRECTORY_SEPARATOR);
|
||||
|
||||
// Location of the Paths config file.
|
||||
// This is the first of two lines that might need to be changed, depending on your folder structure.
|
||||
$pathsPath = FCPATH . '../application/Config/Paths.php';
|
||||
|
||||
/*
|
||||
*---------------------------------------------------------------
|
||||
* BOOTSTRAP THE APPLICATION
|
||||
@ -24,7 +23,9 @@ chdir(__DIR__);
|
||||
require $pathsPath;
|
||||
$paths = new Config\Paths();
|
||||
|
||||
$app = require rtrim($paths->systemDirectory,'/ ').'/bootstrap.php';
|
||||
// Location of the framework bootstrap file.
|
||||
// This is the second of two lines that might need to be changed, depending on your folder structure.
|
||||
$app = require FCPATH . '../system/bootstrap.php';
|
||||
|
||||
/*
|
||||
*---------------------------------------------------------------
|
||||
|
36
serve
36
serve
@ -1,36 +0,0 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* CodeIgniter PHP-Development Server Launcher
|
||||
*
|
||||
* This script launches the built-in PHP development server
|
||||
* making sure that it knows the webroot is in the public folder,
|
||||
* and using the rewrite.php file to mimic mod_rewrite functionality.
|
||||
*
|
||||
* The script is automatically set to the development environment
|
||||
* within the rewrite.php file.
|
||||
*/
|
||||
|
||||
$php = PHP_BINARY; // command to call PHP
|
||||
|
||||
/*
|
||||
* Collect any user-supplied options and apply them
|
||||
*/
|
||||
$options = getopt(null, ['host:', 'port:']);
|
||||
|
||||
$host = $options['host'] ?? 'localhost';
|
||||
$port = $options['port'] ?? '8080';
|
||||
|
||||
/*
|
||||
* Get the party started
|
||||
*/
|
||||
require_once __DIR__.'/system/CLI/CLI.php';
|
||||
\CodeIgniter\CLI\CLI::write("CodeIgniter development server started on http://{$host}:{$port}", 'green');
|
||||
\CodeIgniter\CLI\CLI::write("Press Control-C to stop.");
|
||||
|
||||
/*
|
||||
* 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 public/ rewrite.php");
|
@ -344,16 +344,15 @@ trait ResponseTrait
|
||||
return $data;
|
||||
}
|
||||
|
||||
// Determine correct response type through content negotiation
|
||||
$config = new Format();
|
||||
$format = $this->request->negotiate('media', $config->supportedResponseFormats, true);
|
||||
|
||||
$this->response->setContentType($format);
|
||||
|
||||
// if we don't have a formatter, make one
|
||||
if ( ! isset($this->formatter))
|
||||
{
|
||||
$config = new Format();
|
||||
|
||||
// Determine correct response type through content negotiation
|
||||
$format = $this->request->negotiate('media', $config->supportedResponseFormats, true);
|
||||
|
||||
$this->response->setContentType($format);
|
||||
|
||||
// if no formatter, use the default
|
||||
$this->formatter = $config->getFormatter($format);
|
||||
}
|
||||
|
@ -165,7 +165,7 @@ class Autoloader
|
||||
*
|
||||
* @return Autoloader
|
||||
*/
|
||||
public function addNamespace($namespace, $path)
|
||||
public function addNamespace(string $namespace, string $path)
|
||||
{
|
||||
if (isset($this->prefixes[$namespace]))
|
||||
{
|
||||
@ -194,7 +194,7 @@ class Autoloader
|
||||
*
|
||||
* @return Autoloader
|
||||
*/
|
||||
public function removeNamespace($namespace)
|
||||
public function removeNamespace(string $namespace)
|
||||
{
|
||||
unset($this->prefixes[$namespace]);
|
||||
|
||||
@ -211,7 +211,7 @@ class Autoloader
|
||||
* @return mixed The mapped file on success, or boolean false
|
||||
* on failure.
|
||||
*/
|
||||
public function loadClass($class)
|
||||
public function loadClass(string $class)
|
||||
{
|
||||
$class = trim($class, '\\');
|
||||
$class = str_ireplace('.php', '', $class);
|
||||
@ -237,7 +237,7 @@ class Autoloader
|
||||
*
|
||||
* @return mixed The mapped file name on success, or boolean false on fail
|
||||
*/
|
||||
protected function loadInNamespace($class)
|
||||
protected function loadInNamespace(string $class)
|
||||
{
|
||||
if (strpos($class, '\\') === false)
|
||||
{
|
||||
@ -283,7 +283,7 @@ class Autoloader
|
||||
*
|
||||
* @return mixed The mapped file name on success, or boolean false on failure
|
||||
*/
|
||||
protected function loadLegacy($class)
|
||||
protected function loadLegacy(string $class)
|
||||
{
|
||||
// If there is a namespace on this class, then
|
||||
// we cannot load it from traditional locations.
|
||||
@ -323,7 +323,7 @@ class Autoloader
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
protected function requireFile($file)
|
||||
protected function requireFile(string $file)
|
||||
{
|
||||
$file = $this->sanitizeFilename($file);
|
||||
|
||||
|
@ -151,6 +151,56 @@ class FileLocator
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* Examines a file and returns the fully qualified domain name.
|
||||
*
|
||||
* @param string $file
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getClassname(string $file) : string
|
||||
{
|
||||
$php = file_get_contents($file);
|
||||
$tokens = token_get_all($php);
|
||||
$count = count($tokens);
|
||||
$dlm = false;
|
||||
$namespace = '';
|
||||
$class_name = '';
|
||||
|
||||
for ($i = 2; $i < $count; $i++)
|
||||
{
|
||||
if ((isset($tokens[$i-2][1]) && ($tokens[$i-2][1] == "phpnamespace" || $tokens[$i-2][1] == "namespace")) || ($dlm && $tokens[$i-1][0] == T_NS_SEPARATOR && $tokens[$i][0] == T_STRING))
|
||||
{
|
||||
if (! $dlm)
|
||||
{
|
||||
$namespace = 0;
|
||||
}
|
||||
if (isset($tokens[$i][1]))
|
||||
{
|
||||
$namespace = $namespace ? $namespace."\\".$tokens[$i][1] : $tokens[$i][1];
|
||||
$dlm = true;
|
||||
}
|
||||
}
|
||||
elseif ($dlm && ($tokens[$i][0] != T_NS_SEPARATOR) && ($tokens[$i][0] != T_STRING))
|
||||
{
|
||||
$dlm = false;
|
||||
}
|
||||
if (($tokens[$i-2][0] == T_CLASS || (isset($tokens[$i-2][1]) && $tokens[$i-2][1] == "phpclass"))
|
||||
&& $tokens[$i-1][0] == T_WHITESPACE
|
||||
&& $tokens[$i][0] == T_STRING)
|
||||
{
|
||||
$class_name = $tokens[$i][1];
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if( empty( $class_name ) ) return "";
|
||||
|
||||
return $namespace .'\\'. $class_name;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* Searches through all of the defined namespaces looking for a file.
|
||||
* Returns an array of all found locations for the defined file.
|
||||
|
@ -35,6 +35,7 @@
|
||||
* @since Version 3.0.0
|
||||
* @filesource
|
||||
*/
|
||||
use CodeIgniter\CLI\Exceptions\CLIException;
|
||||
|
||||
/**
|
||||
* Class CLI
|
||||
@ -44,9 +45,18 @@
|
||||
*
|
||||
* Portions of this code were initially from the FuelPHP Framework,
|
||||
* version 1.7.x, and used here under the MIT license they were
|
||||
* originally made available under.
|
||||
* originally made available under. Reference: http://fuelphp.com
|
||||
*
|
||||
* http://fuelphp.com
|
||||
* Some of the code in this class is Windows-specific, and not
|
||||
* possible to test using travis-ci. It has been phpunit-annotated
|
||||
* to prevent messing up code coverage.
|
||||
*
|
||||
* Some of the methods require keyboard input, and are not unit-testable
|
||||
* as a result: input() and prompt().
|
||||
* validate() is internal, and not testable if prompt() isn't.
|
||||
* The wait() method is mostly testable, as long as you don't give it
|
||||
* an argument of "0".
|
||||
* These have been flagged to ignore for code coverage purposes.
|
||||
*
|
||||
* @package CodeIgniter\HTTP
|
||||
*/
|
||||
@ -118,6 +128,7 @@ class CLI
|
||||
* @var array
|
||||
*/
|
||||
protected static $segments = [];
|
||||
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
@ -135,6 +146,10 @@ class CLI
|
||||
// http://www.php.net/manual/en/readline.installation.php
|
||||
static::$readline_support = extension_loaded('readline');
|
||||
|
||||
// clear segments & options to keep testing clean
|
||||
static::$segments = [];
|
||||
static::$options = [];
|
||||
|
||||
static::parseCommandLine();
|
||||
|
||||
static::$initialized = true;
|
||||
@ -149,8 +164,9 @@ class CLI
|
||||
* php index.php user -v --v -name=John --name=John
|
||||
*
|
||||
* @param string $prefix
|
||||
*
|
||||
* @return string
|
||||
*
|
||||
* @codeCoverageIgnore
|
||||
*/
|
||||
public static function input(string $prefix = null): string
|
||||
{
|
||||
@ -188,6 +204,7 @@ class CLI
|
||||
* @param string $validation Validation rules
|
||||
*
|
||||
* @return string The user input
|
||||
* @codeCoverageIgnore
|
||||
*/
|
||||
public static function prompt($field, $options = null, $validation = null): string
|
||||
{
|
||||
@ -196,11 +213,11 @@ class CLI
|
||||
|
||||
if (is_string($options))
|
||||
{
|
||||
$extra_output = ' [' . static::color($options, 'white') .']';
|
||||
$extra_output = ' [' . static::color($options, 'white') . ']';
|
||||
$default = $options;
|
||||
}
|
||||
|
||||
if (is_array($options) && count($options))
|
||||
if (is_array($options) && $options)
|
||||
{
|
||||
$opts = $options;
|
||||
$extra_output_default = static::color($opts[0], 'white');
|
||||
@ -213,8 +230,8 @@ class CLI
|
||||
}
|
||||
else
|
||||
{
|
||||
$extra_output = ' [' .$extra_output_default.', '. implode(', ', $opts) . ']';
|
||||
$validation .= '|in_list['. implode(',', $options) .']';
|
||||
$extra_output = ' [' . $extra_output_default . ', ' . implode(', ', $opts) . ']';
|
||||
$validation .= '|in_list[' . implode(',', $options) . ']';
|
||||
$validation = trim($validation, '|');
|
||||
}
|
||||
|
||||
@ -224,11 +241,11 @@ class CLI
|
||||
fwrite(STDOUT, $field . $extra_output . ': ');
|
||||
|
||||
// Read the input from keyboard.
|
||||
$input = trim(static::input()) ? : $default;
|
||||
$input = trim(static::input()) ?: $default;
|
||||
|
||||
if (isset($validation))
|
||||
{
|
||||
while (! static::validate($field, $input, $validation))
|
||||
while ( ! static::validate($field, $input, $validation))
|
||||
{
|
||||
$input = static::prompt($field, $options, $validation);
|
||||
}
|
||||
@ -247,11 +264,12 @@ class CLI
|
||||
* @param string $rules Validation rules
|
||||
*
|
||||
* @return boolean
|
||||
* @codeCoverageIgnore
|
||||
*/
|
||||
protected static function validate($field, $value, $rules)
|
||||
{
|
||||
$validation = \Config\Services::validation(null, false);
|
||||
$validation->setRule($field, $rules);
|
||||
$validation->setRule($field, null, $rules);
|
||||
$validation->run([$field => $value]);
|
||||
|
||||
if ($validation->hasError($field))
|
||||
@ -345,8 +363,11 @@ class CLI
|
||||
}
|
||||
else
|
||||
{
|
||||
// this chunk cannot be tested because of keyboard input
|
||||
// @codeCoverageIgnoreStart
|
||||
static::write(static::$wait_msg);
|
||||
static::input();
|
||||
// @codeCoverageIgnoreEnd
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -358,7 +379,7 @@ class CLI
|
||||
*/
|
||||
public static function isWindows()
|
||||
{
|
||||
return 'win' === strtolower(substr(php_uname("s"), 0, 3));
|
||||
return stripos(PHP_OS, 'WIN') === 0;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
@ -373,7 +394,7 @@ class CLI
|
||||
public static function newLine(int $num = 1)
|
||||
{
|
||||
// Do it once or more, write with empty string gives us a new line
|
||||
for ($i = 0; $i < $num; $i ++ )
|
||||
for ($i = 0; $i < $num; $i ++)
|
||||
{
|
||||
static::write('');
|
||||
}
|
||||
@ -385,6 +406,7 @@ class CLI
|
||||
* Clears the screen of output
|
||||
*
|
||||
* @return void
|
||||
* @codeCoverageIgnore
|
||||
*/
|
||||
public static function clearScreen()
|
||||
{
|
||||
@ -414,17 +436,19 @@ class CLI
|
||||
{
|
||||
if (static::isWindows() && ! isset($_SERVER['ANSICON']))
|
||||
{
|
||||
// @codeCoverageIgnoreStart
|
||||
return $text;
|
||||
// @codeCoverageIgnoreEnd
|
||||
}
|
||||
|
||||
if ( ! array_key_exists($foreground, static::$foreground_colors))
|
||||
{
|
||||
throw new \RuntimeException('Invalid CLI foreground color: ' . $foreground);
|
||||
throw CLIException::forInvalidColor('foreground', $foreground);
|
||||
}
|
||||
|
||||
if ($background !== null && ! array_key_exists($background, static::$background_colors))
|
||||
{
|
||||
throw new \RuntimeException('Invalid CLI background color: ' . $background);
|
||||
throw CLIException::forInvalidColor('background', $background);
|
||||
}
|
||||
|
||||
$string = "\033[" . static::$foreground_colors[$foreground] . "m";
|
||||
@ -459,7 +483,9 @@ class CLI
|
||||
{
|
||||
if (static::isWindows() || (int) shell_exec('tput cols') == 0)
|
||||
{
|
||||
// @codeCoverageIgnoreStart
|
||||
return $default;
|
||||
// @codeCoverageIgnoreEnd
|
||||
}
|
||||
|
||||
return (int) shell_exec('tput cols');
|
||||
@ -480,7 +506,9 @@ class CLI
|
||||
{
|
||||
if (static::isWindows())
|
||||
{
|
||||
// @codeCoverageIgnoreStart
|
||||
return $default;
|
||||
// @codeCoverageIgnoreEnd
|
||||
}
|
||||
|
||||
return (int) shell_exec('tput lines');
|
||||
@ -604,7 +632,8 @@ class CLI
|
||||
{
|
||||
$optionsFound = false;
|
||||
|
||||
for ($i = 1; $i < $_SERVER['argc']; $i ++ )
|
||||
// start picking segments off from #1, ignoring the invoking program
|
||||
for ($i = 1; $i < $_SERVER['argc']; $i ++)
|
||||
{
|
||||
// If there's no '-' at the beginning of the argument
|
||||
// then add it to our segments.
|
||||
@ -619,16 +648,11 @@ class CLI
|
||||
// value belonging to this option.
|
||||
$optionsFound = true;
|
||||
|
||||
if (mb_substr($_SERVER['argv'][$i], 0, 1) != '-')
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
$arg = str_replace('-', '', $_SERVER['argv'][$i]);
|
||||
$value = null;
|
||||
|
||||
// if the next item doesn't have a dash it's a value.
|
||||
if (isset($_SERVER['argv'][$i + 1]) && mb_substr($_SERVER['argv'][$i + 1], 0, 1) != '-')
|
||||
// if there is a following segment, and it doesn't start with a dash, it's a value.
|
||||
if (isset($_SERVER['argv'][$i + 1]) && mb_strpos($_SERVER['argv'][$i + 1], '-') !== 0)
|
||||
{
|
||||
$value = $_SERVER['argv'][$i + 1];
|
||||
$i ++;
|
||||
@ -683,6 +707,18 @@ class CLI
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* Returns the raw array of segments found.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public static function getSegments()
|
||||
{
|
||||
return static::$segments;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* Gets a single command-line option. Returns TRUE if the option
|
||||
* exists, but doesn't have a value, and is simply acting as a flag.
|
||||
@ -720,7 +756,7 @@ class CLI
|
||||
//--------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* Returns the options a string, suitable for passing along on
|
||||
* Returns the options as a string, suitable for passing along on
|
||||
* the CLI to other commands.
|
||||
*
|
||||
* @return string
|
||||
@ -765,7 +801,7 @@ class CLI
|
||||
$table_rows = [];
|
||||
|
||||
// We need only indexes and not keys
|
||||
if (! empty($thead))
|
||||
if ( ! empty($thead))
|
||||
{
|
||||
$table_rows[] = array_values($thead);
|
||||
}
|
||||
@ -787,7 +823,7 @@ class CLI
|
||||
$max_cols_lengths = [];
|
||||
|
||||
// Read row by row and define the longest columns
|
||||
for ($row = 0; $row < $total_rows; $row++)
|
||||
for ($row = 0; $row < $total_rows; $row ++ )
|
||||
{
|
||||
$column = 0; // Current column index
|
||||
foreach ($table_rows[$row] as $col)
|
||||
@ -798,19 +834,19 @@ class CLI
|
||||
// If the current column does not have a value among the larger ones
|
||||
// or the value of this is greater than the existing one
|
||||
// then, now, this assumes the maximum length
|
||||
if (! isset($max_cols_lengths[$column]) || $all_cols_lengths[$row][$column] > $max_cols_lengths[$column])
|
||||
if ( ! isset($max_cols_lengths[$column]) || $all_cols_lengths[$row][$column] > $max_cols_lengths[$column])
|
||||
{
|
||||
$max_cols_lengths[$column] = $all_cols_lengths[$row][$column];
|
||||
}
|
||||
|
||||
// We can go check the size of the next column...
|
||||
$column++;
|
||||
$column ++;
|
||||
}
|
||||
}
|
||||
|
||||
// Read row by row and add spaces at the end of the columns
|
||||
// to match the exact column length
|
||||
for ($row = 0; $row < $total_rows; $row++)
|
||||
for ($row = 0; $row < $total_rows; $row ++ )
|
||||
{
|
||||
$column = 0;
|
||||
foreach ($table_rows[$row] as $col)
|
||||
@ -820,14 +856,14 @@ class CLI
|
||||
{
|
||||
$table_rows[$row][$column] = $table_rows[$row][$column] . str_repeat(' ', $diff);
|
||||
}
|
||||
$column++;
|
||||
$column ++;
|
||||
}
|
||||
}
|
||||
|
||||
$table = '';
|
||||
|
||||
// Joins columns and append the well formatted rows to the table
|
||||
for ($row = 0; $row < $total_rows; $row++)
|
||||
for ($row = 0; $row < $total_rows; $row ++ )
|
||||
{
|
||||
// Set the table border-top
|
||||
if ($row === 0)
|
||||
@ -856,5 +892,7 @@ class CLI
|
||||
//--------------------------------------------------------------------
|
||||
}
|
||||
|
||||
// Ensure the class is initialized.
|
||||
// Ensure the class is initialized. Done outside of code coverage
|
||||
// @codeCoverageIgnoreStart
|
||||
CLI::init();
|
||||
// @codeCoverageIgnoreEnd
|
||||
|
@ -39,7 +39,6 @@ use CodeIgniter\Controller;
|
||||
|
||||
class CommandRunner extends Controller
|
||||
{
|
||||
|
||||
/**
|
||||
* Stores the info about found Commands.
|
||||
*
|
||||
@ -47,6 +46,11 @@ class CommandRunner extends Controller
|
||||
*/
|
||||
protected $commands = [];
|
||||
|
||||
/**
|
||||
* @var \CodeIgniter\Log\Logger
|
||||
*/
|
||||
protected $logger;
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
|
@ -63,15 +63,20 @@ class Console
|
||||
|
||||
/**
|
||||
* Runs the current command discovered on the CLI.
|
||||
*
|
||||
* @param bool $useSafeOutput
|
||||
*
|
||||
* @return \CodeIgniter\HTTP\RequestInterface|\CodeIgniter\HTTP\Response|\CodeIgniter\HTTP\ResponseInterface|mixed
|
||||
* @throws \CodeIgniter\HTTP\RedirectException
|
||||
*/
|
||||
public function run()
|
||||
public function run(bool $useSafeOutput = false)
|
||||
{
|
||||
$path = CLI::getURI() ?: 'list';
|
||||
|
||||
// Set the path for the application to route to.
|
||||
$this->app->setPath("ci{$path}");
|
||||
|
||||
return $this->app->run();
|
||||
return $this->app->useSafeOutput($useSafeOutput)->run();
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
|
15
system/CLI/Exceptions/CLIException.php
Normal file
15
system/CLI/Exceptions/CLIException.php
Normal file
@ -0,0 +1,15 @@
|
||||
<?php namespace CodeIgniter\CLI\Exceptions;
|
||||
|
||||
class CLIException extends \RuntimeException
|
||||
{
|
||||
/**
|
||||
* @param string $type
|
||||
* @param string $color
|
||||
*
|
||||
* @return \CodeIgniter\CLI\Exceptions\CLIException
|
||||
*/
|
||||
public static function forInvalidColor(string $type, string $color)
|
||||
{
|
||||
return new static(lang('CLI.invalidColor', [$type, $color]));
|
||||
}
|
||||
}
|
@ -36,6 +36,8 @@
|
||||
* @filesource
|
||||
*/
|
||||
|
||||
use CodeIgniter\Cache\Exceptions\CacheException;
|
||||
|
||||
/**
|
||||
* Class Cache
|
||||
*
|
||||
@ -45,7 +47,6 @@
|
||||
*/
|
||||
class CacheFactory
|
||||
{
|
||||
|
||||
/**
|
||||
* Attempts to create the desired cache handler, based upon the
|
||||
*
|
||||
@ -59,12 +60,12 @@ class CacheFactory
|
||||
{
|
||||
if ( ! isset($config->validHandlers) || ! is_array($config->validHandlers))
|
||||
{
|
||||
throw new \InvalidArgumentException(lang('Cache.cacheInvalidHandlers'));
|
||||
throw CacheException::forInvalidHandlers();
|
||||
}
|
||||
|
||||
if ( ! isset($config->handler) || ! isset($config->backupHandler))
|
||||
{
|
||||
throw new \InvalidArgumentException(lang('Cache.cacheNoBackup'));
|
||||
throw CacheException::forNoBackup();
|
||||
}
|
||||
|
||||
$handler = ! empty($handler) ? $handler : $config->handler;
|
||||
@ -72,7 +73,7 @@ class CacheFactory
|
||||
|
||||
if ( ! array_key_exists($handler, $config->validHandlers) || ! array_key_exists($backup, $config->validHandlers))
|
||||
{
|
||||
throw new \InvalidArgumentException(lang('Cache.cacheHandlerNotFound'));
|
||||
throw CacheException::forHandlerNotFound();
|
||||
}
|
||||
|
||||
// Get an instance of our handler.
|
||||
|
28
system/Cache/Exceptions/CacheException.php
Normal file
28
system/Cache/Exceptions/CacheException.php
Normal file
@ -0,0 +1,28 @@
|
||||
<?php namespace CodeIgniter\Cache\Exceptions;
|
||||
|
||||
class CacheException extends \RuntimeException implements ExceptionInterface
|
||||
{
|
||||
/**
|
||||
* @return \CodeIgniter\Cache\Exceptions\CacheException
|
||||
*/
|
||||
public static function forInvalidHandlers()
|
||||
{
|
||||
return new static(lang('Cache.invalidHandlers'));
|
||||
}
|
||||
|
||||
/**
|
||||
* @return \CodeIgniter\Cache\Exceptions\CacheException
|
||||
*/
|
||||
public static function forNoBackup()
|
||||
{
|
||||
return new static(lang('Cache.noBackup'));
|
||||
}
|
||||
|
||||
/**
|
||||
* @return \CodeIgniter\Cache\Exceptions\CacheException
|
||||
*/
|
||||
public static function forHandlerNotFound()
|
||||
{
|
||||
return new static(lang('Cache.handlerNotFound'));
|
||||
}
|
||||
}
|
11
system/Cache/Exceptions/ExceptionInterface.php
Normal file
11
system/Cache/Exceptions/ExceptionInterface.php
Normal file
@ -0,0 +1,11 @@
|
||||
<?php namespace CodeIgniter\Cache\Exceptions;
|
||||
|
||||
/**
|
||||
* Provides a domain-level interface for broad capture
|
||||
* of all framework-related exceptions.
|
||||
*
|
||||
* catch (\CodeIgniter\Cache\Exceptions\ExceptionInterface) { ... }
|
||||
*/
|
||||
interface ExceptionInterface
|
||||
{
|
||||
}
|
@ -59,7 +59,7 @@ class FileHandler implements CacheInterface
|
||||
public function __construct($config)
|
||||
{
|
||||
$this->prefix = $config->prefix ?: '';
|
||||
$this->path = ! empty($config->path) ? $config->path : WRITEPATH . 'cache';
|
||||
$this->path = ! empty($config->storePath) ? $config->storePath : WRITEPATH . 'cache';
|
||||
|
||||
$this->path = rtrim($this->path, '/') . '/';
|
||||
}
|
||||
@ -322,7 +322,14 @@ class FileHandler implements CacheInterface
|
||||
*/
|
||||
protected function writeFile($path, $data, $mode = 'wb')
|
||||
{
|
||||
if (($fp = @fopen($path, $mode)) === false)
|
||||
try
|
||||
{
|
||||
if (($fp = @fopen($path, $mode)) === false)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
catch (\ErrorException $e)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
@ -287,7 +287,8 @@ class MemcachedHandler implements CacheInterface
|
||||
|
||||
$stored = $this->memcached->get($key);
|
||||
|
||||
if (count($stored) !== 3)
|
||||
// if not an array, don't try to count for PHP7.2
|
||||
if (! is_array($stored) || count($stored) !== 3)
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
@ -310,7 +311,7 @@ class MemcachedHandler implements CacheInterface
|
||||
*/
|
||||
public function isSupported(): bool
|
||||
{
|
||||
return (extension_loaded('memcached') OR extension_loaded('memcache'));
|
||||
return (extension_loaded('memcached') || extension_loaded('memcache'));
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -95,7 +95,7 @@ class PredisHandler implements CacheInterface
|
||||
|
||||
// Check if the connection is valid by trying to get the time.
|
||||
$this->redis->time();
|
||||
} catch (Exception $e)
|
||||
} catch (\Exception $e)
|
||||
{
|
||||
// thrown if can't connect to redis server.
|
||||
throw new CriticalError('Cache: Predis connection refused (' . $e->getMessage() . ')');
|
||||
@ -117,7 +117,7 @@ class PredisHandler implements CacheInterface
|
||||
['__ci_type', '__ci_value'], $this->redis->hmget($key, ['__ci_type', '__ci_value'])
|
||||
);
|
||||
|
||||
if ( ! isset($data['__ci_type'], $data['__ci_value']) OR $data['__ci_value'] === false)
|
||||
if ( ! isset($data['__ci_type'], $data['__ci_value']) || $data['__ci_value'] === false)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
@ -263,7 +263,7 @@ class PredisHandler implements CacheInterface
|
||||
{
|
||||
$data = array_combine(['__ci_value'], $this->redis->hmget($key, ['__ci_value']));
|
||||
|
||||
if (isset($data['__ci_value']) AND $data['__ci_value'] !== false)
|
||||
if (isset($data['__ci_value']) && $data['__ci_value'] !== false)
|
||||
{
|
||||
return [
|
||||
'expire' => time() + $this->redis->ttl($key),
|
||||
|
@ -35,8 +35,8 @@
|
||||
* @since Version 3.0.0
|
||||
* @filesource
|
||||
*/
|
||||
use CodeIgniter\Exceptions\CriticalError;
|
||||
use CodeIgniter\Cache\CacheInterface;
|
||||
use CodeIgniter\CriticalError;
|
||||
|
||||
class RedisHandler implements CacheInterface
|
||||
{
|
||||
@ -70,13 +70,14 @@ class RedisHandler implements CacheInterface
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
|
||||
public function __construct(array $config)
|
||||
public function __construct($config)
|
||||
{
|
||||
$config = (array)$config;
|
||||
$this->prefix = $config['prefix'] ?? '';
|
||||
|
||||
if ( ! empty($config))
|
||||
{
|
||||
$this->config = array_merge($this->config, $config);
|
||||
$this->config = array_merge($this->config, $config['redis']);
|
||||
}
|
||||
}
|
||||
|
||||
@ -116,7 +117,7 @@ class RedisHandler implements CacheInterface
|
||||
{
|
||||
// log_message('error', 'Cache: Redis authentication failed.');
|
||||
}
|
||||
} catch (RedisException $e)
|
||||
} catch (\RedisException $e)
|
||||
{
|
||||
throw new CriticalError('Cache: Redis connection refused (' . $e->getMessage() . ')');
|
||||
}
|
||||
@ -137,7 +138,7 @@ class RedisHandler implements CacheInterface
|
||||
|
||||
$data = $this->redis->hMGet($key, ['__ci_type', '__ci_value']);
|
||||
|
||||
if ( ! isset($data['__ci_type'], $data['__ci_value']) OR $data['__ci_value'] === false)
|
||||
if ( ! isset($data['__ci_type'], $data['__ci_value']) || $data['__ci_value'] === false)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
@ -36,6 +36,8 @@
|
||||
* @filesource
|
||||
*/
|
||||
use CodeIgniter\HTTP\RedirectResponse;
|
||||
use CodeIgniter\HTTP\Request;
|
||||
use CodeIgniter\HTTP\ResponseInterface;
|
||||
use Config\Services;
|
||||
use Config\Cache;
|
||||
use CodeIgniter\HTTP\URI;
|
||||
@ -44,6 +46,7 @@ use CodeIgniter\Events\Events;
|
||||
use CodeIgniter\HTTP\Response;
|
||||
use CodeIgniter\HTTP\CLIRequest;
|
||||
use CodeIgniter\Router\RouteCollectionInterface;
|
||||
use CodeIgniter\Exceptions\PageNotFoundException;
|
||||
|
||||
/**
|
||||
* This class is the core of the framework, and will analyse the
|
||||
@ -64,12 +67,6 @@ class CodeIgniter
|
||||
*/
|
||||
protected $startTime;
|
||||
|
||||
/**
|
||||
* Amount of memory at app start.
|
||||
* @var int
|
||||
*/
|
||||
protected $startMemory;
|
||||
|
||||
/**
|
||||
* Total app execution time
|
||||
* @var float
|
||||
@ -136,12 +133,18 @@ class CodeIgniter
|
||||
*/
|
||||
protected $path;
|
||||
|
||||
/**
|
||||
* Should the Response instance "pretend"
|
||||
* to keep from setting headers/cookies/etc
|
||||
* @var bool
|
||||
*/
|
||||
protected $useSafeOutput = false;
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
|
||||
public function __construct($config)
|
||||
{
|
||||
$this->startTime = microtime(true);
|
||||
$this->startMemory = memory_get_usage(true);
|
||||
$this->config = $config;
|
||||
}
|
||||
|
||||
@ -179,8 +182,12 @@ class CodeIgniter
|
||||
* makes all of the pieces work together.
|
||||
*
|
||||
* @param \CodeIgniter\Router\RouteCollectionInterface $routes
|
||||
* @param bool $returnResponse
|
||||
*
|
||||
* @throws \CodeIgniter\HTTP\RedirectException
|
||||
* @throws \Exception
|
||||
*/
|
||||
public function run(RouteCollectionInterface $routes = null)
|
||||
public function run(RouteCollectionInterface $routes = null, bool $returnResponse = false)
|
||||
{
|
||||
$this->startBenchmark();
|
||||
|
||||
@ -196,12 +203,23 @@ class CodeIgniter
|
||||
// Check for a cached page. Execution will stop
|
||||
// if the page has been cached.
|
||||
$cacheConfig = new Cache();
|
||||
$this->displayCache($cacheConfig);
|
||||
$response = $this->displayCache($cacheConfig);
|
||||
if ($response instanceof ResponseInterface)
|
||||
{
|
||||
if ($returnResponse)
|
||||
{
|
||||
return $response;
|
||||
}
|
||||
|
||||
$this->response->pretend($this->useSafeOutput)->send();
|
||||
$this->callExit(EXIT_SUCCESS);
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
$this->handleRequest($routes, $cacheConfig);
|
||||
} catch (Router\RedirectException $e)
|
||||
return $this->handleRequest($routes, $cacheConfig, $returnResponse);
|
||||
}
|
||||
catch (Router\RedirectException $e)
|
||||
{
|
||||
$logger = Services::logger();
|
||||
$logger->info('REDIRECTED ROUTE at ' . $e->getMessage());
|
||||
@ -219,13 +237,35 @@ class CodeIgniter
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* Set our Response instance to "pretend" mode so that things like
|
||||
* cookies and headers are not actually sent, allowing PHP 7.2+ to
|
||||
* not complain when ini_set() function is used.
|
||||
*
|
||||
* @param bool $safe
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function useSafeOutput(bool $safe = true)
|
||||
{
|
||||
$this->useSafeOutput = $safe;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* Handles the main request logic and fires the controller.
|
||||
*
|
||||
* @param \CodeIgniter\Router\RouteCollectionInterface $routes
|
||||
* @param $cacheConfig
|
||||
* @param bool $returnResponse
|
||||
*
|
||||
* @return \CodeIgniter\HTTP\RequestInterface|\CodeIgniter\HTTP\Response|\CodeIgniter\HTTP\ResponseInterface|mixed
|
||||
* @throws \CodeIgniter\Filters\Exceptions\FilterException
|
||||
*/
|
||||
protected function handleRequest(RouteCollectionInterface $routes = null, $cacheConfig)
|
||||
protected function handleRequest(RouteCollectionInterface $routes = null, $cacheConfig, bool $returnResponse = false)
|
||||
{
|
||||
$this->tryToRouteIt($routes);
|
||||
|
||||
@ -233,7 +273,16 @@ class CodeIgniter
|
||||
$filters = Services::filters();
|
||||
$uri = $this->request instanceof CLIRequest ? $this->request->getPath() : $this->request->uri->getPath();
|
||||
|
||||
$filters->run($uri, 'before');
|
||||
$possibleRedirect = $filters->run($uri, 'before');
|
||||
if($possibleRedirect instanceof RedirectResponse)
|
||||
{
|
||||
return $possibleRedirect;
|
||||
}
|
||||
// If a Response instance is returned, the Response will be sent back to the client and script execution will stop
|
||||
if($possibleRedirect instanceof ResponseInterface)
|
||||
{
|
||||
return $possibleRedirect->send();
|
||||
}
|
||||
|
||||
$returned = $this->startController();
|
||||
|
||||
@ -256,6 +305,11 @@ class CodeIgniter
|
||||
// Handle any redirects
|
||||
if ($returned instanceof RedirectResponse)
|
||||
{
|
||||
if ($returnResponse)
|
||||
{
|
||||
return $returned;
|
||||
}
|
||||
|
||||
$this->callExit(EXIT_SUCCESS);
|
||||
}
|
||||
|
||||
@ -278,12 +332,17 @@ class CodeIgniter
|
||||
|
||||
unset($uri);
|
||||
|
||||
$this->sendResponse();
|
||||
if (! $returnResponse)
|
||||
{
|
||||
$this->sendResponse();
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
// Is there a post-system event?
|
||||
//--------------------------------------------------------------------
|
||||
Events::trigger('post_system');
|
||||
|
||||
return $this->response;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
@ -357,6 +416,23 @@ class CodeIgniter
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* Sets a Request object to be used for this request.
|
||||
* Used when running certain tests.
|
||||
*
|
||||
* @param \CodeIgniter\HTTP\Request $request
|
||||
*
|
||||
* @return \CodeIgniter\CodeIgniter
|
||||
*/
|
||||
public function setRequest(Request $request)
|
||||
{
|
||||
$this->request = $request;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* Get our Request object, (either IncomingRequest or CLIRequest)
|
||||
* and set the server protocol based on the information provided
|
||||
@ -364,14 +440,20 @@ class CodeIgniter
|
||||
*/
|
||||
protected function getRequestObject()
|
||||
{
|
||||
if (is_cli())
|
||||
if ($this->request instanceof Request)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (is_cli() && ! (ENVIRONMENT == 'testing'))
|
||||
{
|
||||
$this->request = Services::clirequest($this->config);
|
||||
}
|
||||
else
|
||||
{
|
||||
$this->request = Services::request($this->config);
|
||||
$this->request->setProtocolVersion($_SERVER['SERVER_PROTOCOL']);
|
||||
// guess at protocol if needed
|
||||
$this->request->setProtocolVersion($_SERVER['SERVER_PROTOCOL'] ?? 'HTTP/1.1');
|
||||
}
|
||||
}
|
||||
|
||||
@ -385,7 +467,7 @@ class CodeIgniter
|
||||
{
|
||||
$this->response = Services::response($this->config);
|
||||
|
||||
if ( ! is_cli())
|
||||
if ( ! is_cli() || ENVIRONMENT == 'testing')
|
||||
{
|
||||
$this->response->setProtocolVersion($this->request->getProtocolVersion());
|
||||
}
|
||||
@ -453,8 +535,9 @@ class CodeIgniter
|
||||
}
|
||||
|
||||
$output = $this->displayPerformanceMetrics($output);
|
||||
$this->response->setBody($output)->send();
|
||||
$this->callExit(EXIT_SUCCESS);
|
||||
$this->response->setBody($output);
|
||||
|
||||
return $this->response;
|
||||
};
|
||||
}
|
||||
|
||||
@ -469,7 +552,7 @@ class CodeIgniter
|
||||
*/
|
||||
public static function cache(int $time)
|
||||
{
|
||||
self::$cacheTTL = (int) $time;
|
||||
self::$cacheTTL = $time;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
@ -507,7 +590,6 @@ class CodeIgniter
|
||||
return [
|
||||
'startTime' => $this->startTime,
|
||||
'totalTime' => $this->totalTime,
|
||||
'startMemory' => $this->startMemory
|
||||
];
|
||||
}
|
||||
|
||||
@ -522,7 +604,7 @@ class CodeIgniter
|
||||
*/
|
||||
protected function generateCacheName($config): string
|
||||
{
|
||||
if (is_cli())
|
||||
if (is_cli() && ! (ENVIRONMENT == 'testing'))
|
||||
{
|
||||
return md5($this->request->getPath());
|
||||
}
|
||||
@ -616,7 +698,7 @@ class CodeIgniter
|
||||
return $this->path;
|
||||
}
|
||||
|
||||
return is_cli() ? $this->request->getPath() : $this->request->uri->getPath();
|
||||
return (is_cli() && ! (ENVIRONMENT == 'testing')) ? $this->request->getPath() : $this->request->uri->getPath();
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
@ -660,19 +742,19 @@ class CodeIgniter
|
||||
// No controller specified - we don't know what to do now.
|
||||
if (empty($this->controller))
|
||||
{
|
||||
throw new PageNotFoundException('Controller is empty.');
|
||||
throw PageNotFoundException::forEmptyController();
|
||||
}
|
||||
|
||||
// Try to autoload the class
|
||||
if ( ! class_exists($this->controller, true) || $this->method[0] === '_')
|
||||
{
|
||||
throw new PageNotFoundException('Controller or its method is not found.');
|
||||
throw PageNotFoundException::forControllerNotFound($this->controller, $this->method);
|
||||
}
|
||||
else if ( ! method_exists($this->controller, '_remap') &&
|
||||
! is_callable([$this->controller, $this->method], false)
|
||||
)
|
||||
{
|
||||
throw new PageNotFoundException('Controller method is not found.');
|
||||
throw PageNotFoundException::forMethodNotFound($this->method);
|
||||
}
|
||||
}
|
||||
|
||||
@ -685,7 +767,8 @@ class CodeIgniter
|
||||
*/
|
||||
protected function createController()
|
||||
{
|
||||
$class = new $this->controller($this->request, $this->response);
|
||||
$class = new $this->controller();
|
||||
$class->initController($this->request, $this->response, Services::logger());
|
||||
|
||||
$this->benchmark->stop('controller_constructor');
|
||||
|
||||
@ -755,7 +838,7 @@ class CodeIgniter
|
||||
}
|
||||
|
||||
// Display 404 Errors
|
||||
$this->response->setStatusCode(404);
|
||||
$this->response->setStatusCode($e->getCode());
|
||||
|
||||
if (ENVIRONMENT !== 'testing')
|
||||
{
|
||||
@ -773,7 +856,7 @@ class CodeIgniter
|
||||
}
|
||||
}
|
||||
|
||||
throw new PageNotFoundException(lang('HTTP.pageNotFound'));
|
||||
throw PageNotFoundException::forPageNotFound($e->getMessage());
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
@ -875,7 +958,7 @@ class CodeIgniter
|
||||
*/
|
||||
protected function sendResponse()
|
||||
{
|
||||
$this->response->send();
|
||||
$this->response->pretend($this->useSafeOutput)->send();
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
|
@ -108,15 +108,15 @@ class CreateMigration extends BaseCommand
|
||||
|
||||
if (empty($name))
|
||||
{
|
||||
$name = CLI::prompt(lang('Migrations.migNameMigration'));
|
||||
$name = CLI::prompt(lang('Migrations.nameMigration'));
|
||||
}
|
||||
|
||||
if (empty($name))
|
||||
{
|
||||
CLI::error(lang('Migrations.migBadCreateName'));
|
||||
CLI::error(lang('Migrations.badCreateName'));
|
||||
return;
|
||||
}
|
||||
$namespace = CLI::getOption('n');
|
||||
$ns = CLI::getOption('n');
|
||||
$homepath = APPPATH;
|
||||
|
||||
if ( ! empty($ns))
|
||||
@ -168,7 +168,7 @@ EOD;
|
||||
helper('filesystem');
|
||||
if ( ! write_file($path, $template))
|
||||
{
|
||||
CLI::error(lang('Migrations.migWriteError'));
|
||||
CLI::error(lang('Migrations.writeError'));
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -102,7 +102,7 @@ class MigrateCurrent extends BaseCommand
|
||||
{
|
||||
$runner = Services::migrations();
|
||||
|
||||
CLI::write(lang('Migrations.migToVersion'), 'yellow');
|
||||
CLI::write(lang('Migrations.toVersion'), 'yellow');
|
||||
|
||||
$group = CLI::getOption('g');
|
||||
try
|
||||
@ -115,13 +115,13 @@ class MigrateCurrent extends BaseCommand
|
||||
}
|
||||
|
||||
CLI::write('Done');
|
||||
|
||||
|
||||
} catch (\Exception $e)
|
||||
{
|
||||
$this->showError($e);
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -102,7 +102,7 @@ class MigrateLatest extends BaseCommand
|
||||
{
|
||||
$runner = Services::migrations();
|
||||
|
||||
CLI::write(lang('Migrations.migToLatest'), 'yellow');
|
||||
CLI::write(lang('Migrations.toLatest'), 'yellow');
|
||||
|
||||
$namespace = CLI::getOption('n');
|
||||
$group = CLI::getOption('g');
|
||||
@ -124,13 +124,13 @@ class MigrateLatest extends BaseCommand
|
||||
}
|
||||
|
||||
CLI::write('Done');
|
||||
|
||||
|
||||
} catch (\Exception $e)
|
||||
{
|
||||
$this->showError($e);
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -106,7 +106,7 @@ class MigrateRollback extends BaseCommand
|
||||
{
|
||||
$runner = Services::migrations();
|
||||
|
||||
CLI::write(lang('Migrations.migRollingBack'), 'yellow');
|
||||
CLI::write(lang('Migrations.rollingBack'), 'yellow');
|
||||
$group = CLI::getOption('g');
|
||||
if ( ! is_null($group))
|
||||
{
|
||||
@ -148,7 +148,7 @@ class MigrateRollback extends BaseCommand
|
||||
$this->showError($e);
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -93,6 +93,12 @@ class MigrateStatus extends BaseCommand
|
||||
'-g' => 'Set database group',
|
||||
];
|
||||
|
||||
protected $ignoredNamespaces = [
|
||||
'CodeIgniter',
|
||||
'Config',
|
||||
'Tests\Support'
|
||||
];
|
||||
|
||||
/**
|
||||
* Displays a list of all migrations and whether they've been run or not.
|
||||
*
|
||||
@ -114,25 +120,25 @@ class MigrateStatus extends BaseCommand
|
||||
// Loop for all $namespaces
|
||||
foreach ($namespaces as $namespace => $path)
|
||||
{
|
||||
if (in_array($namespace, $this->ignoredNamespaces))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
$runner->setNamespace($namespace);
|
||||
$migrations = $runner->findMigrations();
|
||||
$history = $runner->getHistory();
|
||||
|
||||
CLI::write($namespace);
|
||||
|
||||
if (empty($migrations))
|
||||
{
|
||||
CLI::error("$namespace: " . lang('Migrations.migNoneFound'));
|
||||
CLI::error(lang('Migrations.noneFound'));
|
||||
continue;
|
||||
}
|
||||
|
||||
ksort($migrations);
|
||||
|
||||
CLI::newLine(1);
|
||||
|
||||
CLI::write(lang('Migrations.migHistoryFor') . "$namespace: ", 'green');
|
||||
|
||||
CLI::newLine(1);
|
||||
|
||||
$max = 0;
|
||||
foreach ($migrations as $version => $migration)
|
||||
{
|
||||
@ -142,7 +148,7 @@ class MigrateStatus extends BaseCommand
|
||||
$max = max($max, strlen($file));
|
||||
}
|
||||
|
||||
CLI::write(str_pad(lang('Migrations.filename'), $max + 6) . lang('Migrations.migOn'), 'yellow');
|
||||
CLI::write(' '. str_pad(lang('Migrations.filename'), $max + 4) . lang('Migrations.on'), 'yellow');
|
||||
|
||||
|
||||
foreach ($migrations as $version => $migration)
|
||||
@ -157,7 +163,7 @@ class MigrateStatus extends BaseCommand
|
||||
|
||||
$date = date("Y-m-d H:i:s", $row['time']);
|
||||
}
|
||||
CLI::write(str_pad($migration->name, $max + 6) . ($date ? $date : '---'));
|
||||
CLI::write(str_pad(' '.$migration->name, $max + 6) . ($date ? $date : '---'));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -118,7 +118,7 @@ class MigrateVersion extends BaseCommand
|
||||
exit();
|
||||
}
|
||||
|
||||
CLI::write(sprintf(lang('Migrations.migToVersionPH'), $version), 'yellow');
|
||||
CLI::write(sprintf(lang('Migrations.toVersionPH'), $version), 'yellow');
|
||||
|
||||
$namespace = CLI::getOption('n');
|
||||
$group = CLI::getOption('g');
|
||||
@ -131,7 +131,7 @@ class MigrateVersion extends BaseCommand
|
||||
$this->showError($e);
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -125,77 +125,68 @@ class ListCommands extends BaseCommand
|
||||
*/
|
||||
protected function describeCommands(array $commands = [])
|
||||
{
|
||||
arsort($commands);
|
||||
ksort($commands);
|
||||
|
||||
$names = array_keys($commands);
|
||||
$descs = array_column($commands, 'description');
|
||||
$groups = array_column($commands, 'group');
|
||||
$lastGroup = '';
|
||||
// Sort into buckets by group
|
||||
$sorted = [];
|
||||
$maxTitleLength = 0;
|
||||
|
||||
// Pad each item to the same length
|
||||
$names = $this->padArray($names, 2, 2);
|
||||
$countNames = count($names);
|
||||
for ($i = 0; $i < $countNames; $i ++ )
|
||||
foreach ($commands as $title => $command)
|
||||
{
|
||||
$lastGroup = $this->describeGroup($groups[$i], $lastGroup);
|
||||
|
||||
$out = CLI::color($names[$i], 'yellow');
|
||||
|
||||
if (isset($descs[$i]))
|
||||
if (! isset($sorted[$command['group']]))
|
||||
{
|
||||
$out .= CLI::wrap($descs[$i], 125, strlen($names[$i]));
|
||||
$sorted[$command['group']] = [];
|
||||
}
|
||||
|
||||
CLI::write($out);
|
||||
$sorted[$command['group']][$title] = $command;
|
||||
|
||||
$maxTitleLength = max($maxTitleLength, strlen($title));
|
||||
}
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
ksort($sorted);
|
||||
|
||||
/**
|
||||
* Outputs the description, if necessary.
|
||||
*
|
||||
* @param string $new
|
||||
* @param string $old
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
protected function describeGroup(string $new, string $old)
|
||||
{
|
||||
if ($new == $old)
|
||||
// Display it all...
|
||||
foreach ($sorted as $group => $items)
|
||||
{
|
||||
return $old;
|
||||
CLI::newLine();
|
||||
CLI::write($group);
|
||||
|
||||
foreach ($items as $title => $item)
|
||||
{
|
||||
$title = $this->padTitle($title, $maxTitleLength, 2, 2);
|
||||
|
||||
$out = CLI::color($title, 'yellow');
|
||||
|
||||
if (isset($item['description']))
|
||||
{
|
||||
$out .= CLI::wrap($item['description'], 125, strlen($title));
|
||||
}
|
||||
|
||||
CLI::write($out);
|
||||
}
|
||||
}
|
||||
|
||||
CLI::newLine();
|
||||
CLI::write($new);
|
||||
|
||||
return $new;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* Returns a new array where all of the string elements have
|
||||
* been padding with trailing spaces to be the same length.
|
||||
* Pads our string out so that all titles are the same length to nicely line up descriptions.
|
||||
*
|
||||
* @param array $array
|
||||
* @param int $extra // How many extra spaces to add at the end
|
||||
* @param int $indent
|
||||
* @param string $item
|
||||
* @param $max
|
||||
* @param int $extra // How many extra spaces to add at the end
|
||||
* @param int $indent
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
protected function padArray($array, $extra = 2, $indent = 0)
|
||||
protected function padTitle(string $item, $max, $extra = 2, $indent = 0)
|
||||
{
|
||||
$max = max(array_map('strlen', $array)) + $extra + $indent;
|
||||
$max += $extra + $indent;
|
||||
|
||||
foreach ($array as &$item)
|
||||
{
|
||||
$item = str_repeat(' ', $indent) . $item;
|
||||
$item = str_pad($item, $max);
|
||||
}
|
||||
$item = str_repeat(' ', $indent) . $item;
|
||||
$item = str_pad($item, $max);
|
||||
|
||||
return $array;
|
||||
return $item;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
|
85
system/Commands/Server/Serve.php
Normal file
85
system/Commands/Server/Serve.php
Normal file
@ -0,0 +1,85 @@
|
||||
<?php namespace CodeIgniter\Commands\Server;
|
||||
|
||||
/**
|
||||
* 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\CLI\BaseCommand;
|
||||
use CodeIgniter\CLI\CLI;
|
||||
|
||||
/**
|
||||
* Launch the PHP development server
|
||||
*
|
||||
* Not testable, as it throws phpunit for a loop :-/
|
||||
* @codeCoverageIgnore
|
||||
*/
|
||||
class Serve extends BaseCommand
|
||||
{
|
||||
|
||||
protected $group = 'CodeIgniter';
|
||||
protected $name = 'serve';
|
||||
protected $description = 'Launchs the CodeIgniter PHP-Development Server.';
|
||||
protected $usage = 'serve';
|
||||
protected $arguments = [];
|
||||
protected $options = [
|
||||
'-php' => 'The PHP Binary [default: "PHP_BINARY"]',
|
||||
'-host' => 'The HTTP Host [default: "localhost"]',
|
||||
'-port' => 'The HTTP Host Port [default: "8080"]',
|
||||
];
|
||||
|
||||
public function run(array $params)
|
||||
{
|
||||
// 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');
|
||||
CLI::write('Press Control-C to stop.');
|
||||
|
||||
// Set the Front Controller path as Document Root
|
||||
$docroot = FCPATH;
|
||||
|
||||
// Mimic Apache's mod_rewrite functionality with user settings
|
||||
$rewrite = __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}");
|
||||
}
|
||||
|
||||
}
|
@ -2,11 +2,18 @@
|
||||
/**
|
||||
* CodeIgniter PHP-Development Server Rewrite Rules
|
||||
*
|
||||
* This script works with serve.php to help run a seamless
|
||||
* This script works with the CLI serve command to help run a seamless
|
||||
* development server based around PHP's built-in development
|
||||
* server. This file simply tries to mimic Apache's mod_rewrite
|
||||
* functionality so the site will operate as normal.
|
||||
*
|
||||
*/
|
||||
// @codeCoverageIgnoreStart
|
||||
// Avoid this file run when listing commands
|
||||
if (php_sapi_name() === 'cli')
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
// If we're serving the site locally, then we need
|
||||
// to let the application know that we're in development mode
|
||||
@ -14,15 +21,20 @@ $_SERVER['CI_ENVIRONMENT'] = 'development';
|
||||
|
||||
$uri = urldecode(parse_url($_SERVER['REQUEST_URI'], PHP_URL_PATH));
|
||||
|
||||
$path = __DIR__.'/public/'.ltrim($uri,'/');
|
||||
// Front Controller path - expected to be in the default folder
|
||||
$fcpath = $_SERVER['DOCUMENT_ROOT'] . DIRECTORY_SEPARATOR;
|
||||
|
||||
// Full path
|
||||
$path = $fcpath . ltrim($uri, '/');
|
||||
|
||||
// If $path is an existing file or folder within the public folder
|
||||
// then let the request handle it like normal.
|
||||
if ($uri !== '/' && (is_file($path) || is_dir($path)))
|
||||
{
|
||||
return false;
|
||||
return false;
|
||||
}
|
||||
|
||||
// Otherwise, we'll load the index file and let
|
||||
// the framework handle the request from here.
|
||||
require_once __DIR__.'/public/index.php';
|
||||
require_once $fcpath . 'index.php';
|
||||
// @codeCoverageIgnoreEnd
|
@ -39,6 +39,12 @@ use CodeIgniter\CLI\BaseCommand;
|
||||
use CodeIgniter\CLI\CLI;
|
||||
use Config\App;
|
||||
|
||||
/**
|
||||
* Creates a migration file for database sessions.
|
||||
*
|
||||
* @package CodeIgniter\Commands
|
||||
*/
|
||||
|
||||
class CreateMigration extends BaseCommand
|
||||
{
|
||||
|
||||
@ -98,7 +104,7 @@ class CreateMigration extends BaseCommand
|
||||
{
|
||||
$config = new App();
|
||||
|
||||
$tableName = CLI::getOption('t') ?? $config->sessionSavePath ?? 'ci_sessions';
|
||||
$tableName = CLI::getOption('t') ?? 'ci_sessions';
|
||||
|
||||
$path = APPPATH . 'Database/Migrations/' . date('YmdHis_') . 'create_' . $tableName . '_table' . '.php';
|
||||
|
||||
@ -109,7 +115,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.
|
||||
|
@ -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
|
||||
|
123
system/Commands/Utilities/Namespaces.php
Normal file
123
system/Commands/Utilities/Namespaces.php
Normal file
@ -0,0 +1,123 @@
|
||||
<?php namespace CodeIgniter\Commands\Utilities;
|
||||
|
||||
/**
|
||||
* 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\CLI\BaseCommand;
|
||||
use CodeIgniter\CLI\CLI;
|
||||
use Config\Autoload;
|
||||
|
||||
/**
|
||||
* Lists namespaces set in Config\Autoload with their
|
||||
* full server path. Helps you to verify that you have
|
||||
* the namespaces setup correctly.
|
||||
*
|
||||
* @package CodeIgniter\Commands
|
||||
*/
|
||||
class Namespaces extends BaseCommand
|
||||
{
|
||||
|
||||
/**
|
||||
* The group the command is lumped under
|
||||
* when listing commands.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $group = 'CodeIgniter';
|
||||
|
||||
/**
|
||||
* The Command's name
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $name = 'namespaces';
|
||||
|
||||
/**
|
||||
* the Command's short description
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $description = 'Verifies your namespaces are setup correctly.';
|
||||
|
||||
/**
|
||||
* the Command's usage
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $usage = 'namespaces';
|
||||
|
||||
/**
|
||||
* the Command's Arguments
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $arguments = [];
|
||||
|
||||
/**
|
||||
* the Command's Options
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $options = [];
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* Displays the help for the spark cli script itself.
|
||||
*
|
||||
* @param array $params
|
||||
*/
|
||||
public function run(array $params)
|
||||
{
|
||||
$config = new Autoload();
|
||||
|
||||
$tbody = [];
|
||||
foreach ($config->psr4 as $ns => $path)
|
||||
{
|
||||
$path = realpath($path) ?? $path;
|
||||
|
||||
$tbody[] = [
|
||||
$ns,
|
||||
realpath($path) ?? $path,
|
||||
is_dir($path) ? "Yes" : "MISSING"
|
||||
];
|
||||
}
|
||||
|
||||
$thead = ['Namespace', 'Path', 'Found?'];
|
||||
|
||||
CLI::table($tbody, $thead);
|
||||
}
|
||||
|
||||
}
|
125
system/Commands/Utilities/Routes.php
Normal file
125
system/Commands/Utilities/Routes.php
Normal file
@ -0,0 +1,125 @@
|
||||
<?php namespace CodeIgniter\Commands\Utilities;
|
||||
|
||||
/**
|
||||
* 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:
|
||||
*RouRouddfdf
|
||||
* 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\CLI\BaseCommand;
|
||||
use CodeIgniter\CLI\CLI;
|
||||
use Config\Services;
|
||||
|
||||
/**
|
||||
* Lists all of the user-defined routes. This will include any Routes files
|
||||
* that can be discovered, but will NOT include any routes that are not defined
|
||||
* in a routes file, but are instead discovered through auto-routing.
|
||||
*
|
||||
* @package CodeIgniter\Commands
|
||||
*/
|
||||
class Routes extends BaseCommand
|
||||
{
|
||||
|
||||
/**
|
||||
* The group the command is lumped under
|
||||
* when listing commands.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $group = 'CodeIgniter';
|
||||
|
||||
/**
|
||||
* The Command's name
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $name = 'routes';
|
||||
|
||||
/**
|
||||
* the Command's short description
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $description = 'Displays all of user-defined routes. Does NOT display auto-detected routes.';
|
||||
|
||||
/**
|
||||
* the Command's usage
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $usage = 'routes';
|
||||
|
||||
/**
|
||||
* the Command's Arguments
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $arguments = [];
|
||||
|
||||
/**
|
||||
* the Command's Options
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $options = [];
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* Displays the help for the spark cli script itself.
|
||||
*
|
||||
* @param array $params
|
||||
*/
|
||||
public function run(array $params)
|
||||
{
|
||||
$collection = Services::routes(true);
|
||||
$methods = ['get', 'head', 'post', 'put', 'delete', 'options', 'trace', 'connect', 'cli'];
|
||||
|
||||
$tbody = [];
|
||||
foreach ($methods as $method)
|
||||
{
|
||||
$routes = $collection->getRoutes($method);
|
||||
|
||||
foreach ($routes as $from => $to)
|
||||
$tbody[] = [
|
||||
$from,
|
||||
$method,
|
||||
$to
|
||||
];
|
||||
}
|
||||
|
||||
$thead = ['Route', 'Method', 'Command'];
|
||||
|
||||
CLI::table($tbody, $thead);
|
||||
}
|
||||
|
||||
}
|
@ -85,6 +85,24 @@ if ( ! function_exists('cache'))
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
|
||||
if ( ! function_exists('config'))
|
||||
{
|
||||
/**
|
||||
* More simple way of getting config instances
|
||||
*
|
||||
* @param string $name
|
||||
* @param bool $getShared
|
||||
*
|
||||
* @return mixed
|
||||
*/
|
||||
function config(string $name, bool $getShared = true)
|
||||
{
|
||||
return \CodeIgniter\Config\Config::get($name, $getShared);
|
||||
}
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
|
||||
if ( ! function_exists('view'))
|
||||
{
|
||||
|
||||
@ -252,8 +270,16 @@ if ( ! function_exists('esc'))
|
||||
$method = 'escape' . ucfirst($context);
|
||||
}
|
||||
|
||||
// @todo Optimize this to only load a single instance during page request.
|
||||
$escaper = new \Zend\Escaper\Escaper($encoding);
|
||||
static $escaper;
|
||||
if (! $escaper)
|
||||
{
|
||||
$escaper = new \Zend\Escaper\Escaper($encoding);
|
||||
}
|
||||
|
||||
if ($encoding && $escaper->getEncoding() !== $encoding)
|
||||
{
|
||||
$escaper = new \Zend\Escaper\Escaper($encoding);
|
||||
}
|
||||
|
||||
$data = $escaper->$method($data);
|
||||
}
|
||||
@ -282,14 +308,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;
|
||||
}
|
||||
|
||||
}
|
||||
@ -434,13 +461,15 @@ if ( ! function_exists('log_message'))
|
||||
// for asserting that logs were called in the test code.
|
||||
if (ENVIRONMENT == 'testing')
|
||||
{
|
||||
$logger = new \CodeIgniter\Log\TestLogger(new \Config\Logger());
|
||||
$logger = new \Tests\Support\Log\TestLogger(new \Config\Logger());
|
||||
|
||||
return $logger->log($level, $message, $context);
|
||||
}
|
||||
|
||||
// @codeCoverageIgnoreStart
|
||||
return Services::logger(true)
|
||||
->log($level, $message, $context);
|
||||
// @codeCoverageIgnoreEnd
|
||||
}
|
||||
|
||||
}
|
||||
@ -584,7 +613,7 @@ if ( ! function_exists('app_timezone'))
|
||||
*/
|
||||
function app_timezone()
|
||||
{
|
||||
$config = new \Config\App();
|
||||
$config = config(\Config\App::class);
|
||||
|
||||
return $config->appTimezone;
|
||||
}
|
||||
@ -605,7 +634,7 @@ if ( ! function_exists('csrf_token'))
|
||||
*/
|
||||
function csrf_token()
|
||||
{
|
||||
$config = new \Config\App();
|
||||
$config = config(\Config\App::class);
|
||||
|
||||
return $config->CSRFTokenName;
|
||||
}
|
||||
@ -667,6 +696,11 @@ if ( ! function_exists('force_https'))
|
||||
* Defaults to 1 year.
|
||||
* @param RequestInterface $request
|
||||
* @param ResponseInterface $response
|
||||
*
|
||||
* Not testable, as it will exit!
|
||||
*
|
||||
* @throws \CodeIgniter\HTTP\RedirectException
|
||||
* @codeCoverageIgnore
|
||||
*/
|
||||
function force_https(int $duration = 31536000, RequestInterface $request = null, ResponseInterface $response = null)
|
||||
{
|
||||
@ -679,7 +713,7 @@ if ( ! function_exists('force_https'))
|
||||
$response = Services::response(null, true);
|
||||
}
|
||||
|
||||
if ($request->isSecure())
|
||||
if (is_cli() || $request->isSecure())
|
||||
{
|
||||
return;
|
||||
}
|
||||
@ -716,12 +750,13 @@ if (! function_exists('old'))
|
||||
* Provides access to "old input" that was set in the session
|
||||
* during a redirect()->withInput().
|
||||
*
|
||||
* @param string $key
|
||||
* @param null $default
|
||||
* @param string $key
|
||||
* @param null $default
|
||||
* @param string|bool $escape
|
||||
*
|
||||
* @return mixed|null
|
||||
*/
|
||||
function old(string $key, $default=null)
|
||||
function old(string $key, $default = null, $escape = 'html')
|
||||
{
|
||||
$request = Services::request();
|
||||
|
||||
@ -735,12 +770,12 @@ if (! function_exists('old'))
|
||||
}
|
||||
|
||||
// If the result was serialized array or string, then unserialize it for use...
|
||||
if (substr($value, 0, 2) == 'a:' || substr($value, 0, 2) == 's:')
|
||||
if (strpos($value, 'a:') === 0 || strpos($value, 's:') === 0)
|
||||
{
|
||||
$value = unserialize($value);
|
||||
}
|
||||
|
||||
return $value;
|
||||
return $escape === false ? $value : esc($value, $escape);
|
||||
}
|
||||
}
|
||||
|
||||
@ -835,6 +870,8 @@ if ( ! function_exists('is_really_writable'))
|
||||
* @param string $file
|
||||
*
|
||||
* @return bool
|
||||
*
|
||||
* @codeCoverageIgnore Not practical to test, as travis runs on linux
|
||||
*/
|
||||
function is_really_writable($file)
|
||||
{
|
||||
@ -861,7 +898,7 @@ if ( ! function_exists('is_really_writable'))
|
||||
|
||||
return true;
|
||||
}
|
||||
elseif ( ! is_file($file) OR ( $fp = @fopen($file, 'ab')) === false)
|
||||
elseif ( ! is_file($file) || ( $fp = @fopen($file, 'ab')) === false)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
@ -890,7 +927,7 @@ if ( ! function_exists('slash_item'))
|
||||
*/
|
||||
function slash_item($item)
|
||||
{
|
||||
$config = new \Config\App();
|
||||
$config = config(\Config\App::class);
|
||||
$configItem = $config->{$item};
|
||||
|
||||
if ( ! isset($configItem) || empty(trim($configItem)))
|
||||
@ -929,6 +966,8 @@ if ( ! function_exists('function_usable'))
|
||||
* @param string $function_name Function to check for
|
||||
* @return bool TRUE if the function exists and is safe to call,
|
||||
* FALSE otherwise.
|
||||
*
|
||||
* @codeCoverageIgnore This is too exotic
|
||||
*/
|
||||
function function_usable($function_name)
|
||||
{
|
||||
@ -957,6 +996,8 @@ if (! function_exists('dd'))
|
||||
* Prints a Kint debug report and exits.
|
||||
*
|
||||
* @param array ...$vars
|
||||
*
|
||||
* @codeCoverageIgnore Can't be tested ... exits
|
||||
*/
|
||||
function dd(...$vars)
|
||||
{
|
||||
|
@ -91,7 +91,7 @@ class AutoloadConfig
|
||||
|
||||
if (isset($_SERVER['CI_ENVIRONMENT']) && $_SERVER['CI_ENVIRONMENT'] === 'testing')
|
||||
{
|
||||
$this->psr4['Tests\Support'] = BASEPATH . '../tests/_support/';
|
||||
$this->psr4['Tests\Support'] = BASEPATH . '../tests/_support';
|
||||
}
|
||||
|
||||
/**
|
||||
@ -143,10 +143,6 @@ class AutoloadConfig
|
||||
'CodeIgniter\Debug\Exceptions' => BASEPATH . 'Debug/Exceptions.php',
|
||||
'CodeIgniter\Debug\Timer' => BASEPATH . 'Debug/Timer.php',
|
||||
'CodeIgniter\Debug\Iterator' => BASEPATH . 'Debug/Iterator.php',
|
||||
'CodeIgniter\Encryption\Encryption' => BASEPATH . 'Encryption/Encryption.php',
|
||||
'CodeIgniter\Encryption\EncrypterInterface' => BASEPATH . 'Encryption/EncrypterInterface.php',
|
||||
'CodeIgniter\Encryption\Handlers\BaseHandler' => BASEPATH . 'Encryption/Handlers/BaseHandler.php',
|
||||
'CodeIgniter\Encryption\Handlers\OpenSSLHandler' => BASEPATH . 'Encryption/Handlers/OpenSSLHandler.php',
|
||||
'CodeIgniter\Events\Events' => BASEPATH . 'Events/Events.php',
|
||||
'CodeIgniter\HTTP\CLIRequest' => BASEPATH . 'HTTP/CLIRequest.php',
|
||||
'CodeIgniter\HTTP\ContentSecurityPolicy' => BASEPATH . 'HTTP/ContentSecurityPolicy.php',
|
||||
|
@ -59,7 +59,7 @@ class BaseConfig
|
||||
/**
|
||||
* Will attempt to get environment variables with names
|
||||
* that match the properties of the child class.
|
||||
*
|
||||
*
|
||||
* The "shortPrefix" is the lowercase-only config class name.
|
||||
*/
|
||||
public function __construct()
|
||||
@ -78,12 +78,18 @@ class BaseConfig
|
||||
if ($value = $this->getEnvValue("{$property}.{$key}", $prefix, $shortPrefix))
|
||||
{
|
||||
if (is_null($value))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
if ($value === 'false')
|
||||
{
|
||||
$value = false;
|
||||
}
|
||||
elseif ($value === 'true')
|
||||
{
|
||||
$value = true;
|
||||
}
|
||||
|
||||
$this->$property[$key] = $value;
|
||||
}
|
||||
@ -94,14 +100,22 @@ class BaseConfig
|
||||
if (($value = $this->getEnvValue($property, $prefix, $shortPrefix)) !== false)
|
||||
{
|
||||
if (is_null($value))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
if ($value === 'false')
|
||||
{
|
||||
$value = false;
|
||||
}
|
||||
elseif ($value === 'true')
|
||||
{
|
||||
$value = true;
|
||||
}
|
||||
|
||||
$this->$property = $value;
|
||||
$this->$property = is_bool($value)
|
||||
? $value
|
||||
: trim($value, '\'"');
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -123,7 +137,8 @@ class BaseConfig
|
||||
protected function getEnvValue(string $property, string $prefix, string $shortPrefix)
|
||||
{
|
||||
$shortPrefix = ltrim( $shortPrefix, '\\' );
|
||||
switch (true) {
|
||||
switch (true)
|
||||
{
|
||||
case array_key_exists( "{$shortPrefix}.{$property}", $_ENV ):
|
||||
return $_ENV["{$shortPrefix}.{$property}"];
|
||||
break;
|
||||
@ -160,7 +175,9 @@ class BaseConfig
|
||||
{
|
||||
// ignore non-applicable registrars
|
||||
if ( ! method_exists($callable, $shortName))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
$properties = $callable::$shortName();
|
||||
|
||||
|
241
system/Config/BaseService.php
Normal file
241
system/Config/BaseService.php
Normal file
@ -0,0 +1,241 @@
|
||||
<?php namespace CodeIgniter\Config;
|
||||
|
||||
/**
|
||||
* 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
|
||||
*/
|
||||
|
||||
|
||||
/**
|
||||
* Services Configuration file.
|
||||
*
|
||||
* Services are simply other classes/libraries that the system uses
|
||||
* to do its job. This is used by CodeIgniter to allow the core of the
|
||||
* framework to be swapped out easily without affecting the usage within
|
||||
* the rest of your application.
|
||||
*
|
||||
* This is used in place of a Dependency Injection container primarily
|
||||
* due to its simplicity, which allows a better long-term maintenance
|
||||
* of the applications built on top of CodeIgniter. A bonus side-effect
|
||||
* is that IDEs are able to determine what class you are calling
|
||||
* whereas with DI Containers there usually isn't a way for them to do this.
|
||||
*
|
||||
* @see http://blog.ircmaxell.com/2015/11/simple-easy-risk-and-change.html
|
||||
* @see http://www.infoq.com/presentations/Simple-Made-Easy
|
||||
*/
|
||||
class BaseService
|
||||
{
|
||||
|
||||
/**
|
||||
* Cache for instance of any services that
|
||||
* have been requested as a "shared" instance.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
static protected $instances = [];
|
||||
|
||||
/**
|
||||
* Mock objects for testing which are returned if exist.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
static protected $mocks = [];
|
||||
|
||||
/**
|
||||
* Have we already discovered other Services?
|
||||
*
|
||||
* @var bool
|
||||
*/
|
||||
static protected $discovered = false;
|
||||
|
||||
/**
|
||||
* A cache of other service classes we've found.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
static protected $services = [];
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* Returns a shared instance of any of the class' services.
|
||||
*
|
||||
* $key must be a name matching a service.
|
||||
*
|
||||
* @param string $key
|
||||
* @param array ...$params
|
||||
*
|
||||
* @return mixed
|
||||
*/
|
||||
protected static function getSharedInstance(string $key, ...$params)
|
||||
{
|
||||
// Returns mock if exists
|
||||
if (isset(static::$mocks[$key]))
|
||||
{
|
||||
return static::$mocks[$key];
|
||||
}
|
||||
|
||||
if (! isset(static::$instances[$key]))
|
||||
{
|
||||
// Make sure $getShared is false
|
||||
array_push($params, false);
|
||||
|
||||
static::$instances[$key] = static::$key(...$params);
|
||||
}
|
||||
|
||||
return static::$instances[$key];
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* The file locator provides utility methods for looking for non-classes
|
||||
* within namespaced folders, as well as convenience methods for
|
||||
* loading 'helpers', and 'libraries'.
|
||||
*
|
||||
* @param bool $getShared
|
||||
*
|
||||
* @return \CodeIgniter\Autoloader\FileLocator
|
||||
*/
|
||||
public static function locator($getShared = true)
|
||||
{
|
||||
if ($getShared)
|
||||
{
|
||||
return self::getSharedInstance('locator');
|
||||
}
|
||||
|
||||
return new \CodeIgniter\Autoloader\FileLocator(new \Config\Autoload());
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* Provides the ability to perform case-insensitive calling of service
|
||||
* names.
|
||||
*
|
||||
* @param string $name
|
||||
* @param array $arguments
|
||||
*
|
||||
* @return mixed
|
||||
*/
|
||||
public static function __callStatic(string $name, array $arguments)
|
||||
{
|
||||
$name = strtolower($name);
|
||||
|
||||
if (method_exists(__CLASS__, $name))
|
||||
{
|
||||
return Services::$name(...$arguments);
|
||||
}
|
||||
|
||||
return static::discoverServices($name, $arguments);
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* Reset shared instances and mocks for testing.
|
||||
*/
|
||||
public static function reset()
|
||||
{
|
||||
static::$mocks = [];
|
||||
|
||||
static::$instances = [];
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* Inject mock object for testing.
|
||||
*
|
||||
* @param string $name
|
||||
* @param $mock
|
||||
*/
|
||||
public static function injectMock(string $name, $mock)
|
||||
{
|
||||
$name = strtolower($name);
|
||||
static::$mocks[$name] = $mock;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* Will scan all psr4 namespaces registered with system to look
|
||||
* for new Config\Services files. Caches a copy of each one, then
|
||||
* looks for the service method in each, returning an instance of
|
||||
* the service, if available.
|
||||
*
|
||||
* @param string $name
|
||||
* @param array $arguments
|
||||
*/
|
||||
protected static function discoverServices(string $name, array $arguments)
|
||||
{
|
||||
if (! static::$discovered)
|
||||
{
|
||||
$locator = static::locator();
|
||||
$files = $locator->search('Config/Services');
|
||||
|
||||
if (empty($files))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
// Get instances of all service classes and cache them locally.
|
||||
foreach ($files as $file)
|
||||
{
|
||||
$classname = $locator->getClassname($file);
|
||||
|
||||
if (! in_array($classname, ['CodeIgniter\\Config\\Services']))
|
||||
{
|
||||
static::$services[] = new $classname();
|
||||
}
|
||||
}
|
||||
|
||||
static::$discovered = true;
|
||||
}
|
||||
|
||||
if (! static::$services)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
// Try to find the desired service method
|
||||
foreach (static::$services as $class)
|
||||
{
|
||||
if (method_exists(get_class($class), $name))
|
||||
{
|
||||
return $class::$name(...$arguments);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
120
system/Config/Config.php
Normal file
120
system/Config/Config.php
Normal file
@ -0,0 +1,120 @@
|
||||
<?php namespace CodeIgniter\Config;
|
||||
|
||||
/**
|
||||
* 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
|
||||
*/
|
||||
|
||||
/**
|
||||
* Class Config
|
||||
*
|
||||
* @package CodeIgniter\Config
|
||||
*/
|
||||
class Config
|
||||
{
|
||||
/**
|
||||
* Cache for instance of any configurations that
|
||||
* have been requested as "shared" instance.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
static private $instances = [];
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* Create new configuration instances or return
|
||||
* a shared instance
|
||||
*
|
||||
* @param string $name Configuration name
|
||||
* @param boolean $getShared Use shared instance
|
||||
*
|
||||
* @return mixed|null
|
||||
*/
|
||||
public static function get(string $name, bool $getShared = true)
|
||||
{
|
||||
$class = $name;
|
||||
if (($pos = strrpos($name, '\\')) !== false)
|
||||
{
|
||||
$class = substr($name, $pos + 1);
|
||||
}
|
||||
|
||||
if (! $getShared)
|
||||
{
|
||||
return self::createClass($name);
|
||||
}
|
||||
|
||||
if (! isset( self::$instances[$class] ))
|
||||
{
|
||||
self::$instances[$class] = self::createClass($name);
|
||||
}
|
||||
return self::$instances[$class];
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* Find configuration class and create instance
|
||||
*
|
||||
* @param string $name Classname
|
||||
*
|
||||
* @return mixed|null
|
||||
*/
|
||||
private static function createClass(string $name)
|
||||
{
|
||||
if (class_exists($name))
|
||||
{
|
||||
return new $name();
|
||||
}
|
||||
|
||||
$locator = Services::locator();
|
||||
$file = $locator->locateFile($name, 'Config');
|
||||
|
||||
if (empty($file))
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
$name = $locator->getClassname($file);
|
||||
|
||||
if (empty($name))
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
return new $name();
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
}
|
@ -109,6 +109,7 @@ class DotEnv
|
||||
}
|
||||
}
|
||||
|
||||
return true; // for success
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
@ -126,11 +127,17 @@ class DotEnv
|
||||
list($name, $value) = $this->normaliseVariable($name, $value);
|
||||
|
||||
if ( ! getenv($name, true))
|
||||
{
|
||||
putenv("$name=$value");
|
||||
}
|
||||
if (empty($_ENV[$name]))
|
||||
{
|
||||
$_ENV[$name] = $value;
|
||||
}
|
||||
if (empty($_SERVER[$name]))
|
||||
{
|
||||
$_SERVER[$name] = $value;
|
||||
}
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
|
@ -27,14 +27,15 @@
|
||||
* 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
|
||||
* @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 Config\App;
|
||||
use CodeIgniter\Database\ConnectionInterface;
|
||||
use CodeIgniter\Database\MigrationRunner;
|
||||
use CodeIgniter\View\RendererInterface;
|
||||
@ -56,26 +57,8 @@ use CodeIgniter\View\RendererInterface;
|
||||
* @see http://blog.ircmaxell.com/2015/11/simple-easy-risk-and-change.html
|
||||
* @see http://www.infoq.com/presentations/Simple-Made-Easy
|
||||
*/
|
||||
class Services
|
||||
class Services extends BaseService
|
||||
{
|
||||
|
||||
/**
|
||||
* Cache for instance of any services that
|
||||
* have been requested as a "shared" instance.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
static protected $instances = [];
|
||||
|
||||
/**
|
||||
* Mock objects for testing which are returned if exist.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
static protected $mocks = [];
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* The Autoloader class is the central class that handles our
|
||||
* spl_autoload_register method, and helper methods.
|
||||
@ -112,7 +95,7 @@ class Services
|
||||
return self::getSharedInstance('cache', $config);
|
||||
}
|
||||
|
||||
if ( ! is_object($config))
|
||||
if (! is_object($config))
|
||||
{
|
||||
$config = new \Config\Cache();
|
||||
}
|
||||
@ -138,14 +121,12 @@ class Services
|
||||
return self::getSharedInstance('clirequest', $config);
|
||||
}
|
||||
|
||||
if ( ! is_object($config))
|
||||
if (! is_object($config))
|
||||
{
|
||||
$config = new \Config\App();
|
||||
$config = config(App::class);
|
||||
}
|
||||
|
||||
return new \CodeIgniter\HTTP\CLIRequest(
|
||||
$config, new \CodeIgniter\HTTP\URI()
|
||||
);
|
||||
return new \CodeIgniter\HTTP\CLIRequest($config);
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
@ -161,28 +142,27 @@ class Services
|
||||
*
|
||||
* @return \CodeIgniter\HTTP\CURLRequest
|
||||
*/
|
||||
public static function curlrequest(array $options = [], $response = null, \Config\App $config = null, $getShared = true)
|
||||
{
|
||||
public static function curlrequest(array $options = [], $response = null, \Config\App $config = null, $getShared = true) {
|
||||
if ($getShared === true)
|
||||
{
|
||||
return self::getSharedInstance('curlrequest', $options, $response, $config);
|
||||
}
|
||||
|
||||
if ( ! is_object($config))
|
||||
if (! is_object($config))
|
||||
{
|
||||
$config = new \Config\App();
|
||||
$config = config(App::class);
|
||||
}
|
||||
|
||||
if ( ! is_object($response))
|
||||
if (! is_object($response))
|
||||
{
|
||||
$response = new \CodeIgniter\HTTP\Response($config);
|
||||
}
|
||||
|
||||
return new \CodeIgniter\HTTP\CURLRequest(
|
||||
$config,
|
||||
new \CodeIgniter\HTTP\URI(isset($options['base_uri']) ? : null),
|
||||
$response,
|
||||
$options
|
||||
$config,
|
||||
new \CodeIgniter\HTTP\URI($options['base_uri'] ?? null),
|
||||
$response,
|
||||
$options
|
||||
);
|
||||
}
|
||||
|
||||
@ -220,16 +200,22 @@ 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 +223,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));
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
@ -249,7 +245,7 @@ class Services
|
||||
* act on or modify the response itself before it is sent to the client.
|
||||
*
|
||||
* @param mixed $config
|
||||
* @param bool $getShared
|
||||
* @param bool $getShared
|
||||
*
|
||||
* @return \CodeIgniter\Filters\Filters
|
||||
*/
|
||||
@ -334,37 +330,20 @@ class Services
|
||||
{
|
||||
if ($getShared)
|
||||
{
|
||||
return self::getSharedInstance('language', $locale);
|
||||
return self::getSharedInstance('language', $locale)
|
||||
->setLocale($locale);
|
||||
}
|
||||
|
||||
$locale = ! empty($locale) ? $locale : self::request()->getLocale();
|
||||
$locale = ! empty($locale)
|
||||
? $locale
|
||||
: self::request()
|
||||
->getLocale();
|
||||
|
||||
return new \CodeIgniter\Language\Language($locale);
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* The file locator provides utility methods for looking for non-classes
|
||||
* within namespaced folders, as well as convenience methods for
|
||||
* loading 'helpers', and 'libraries'.
|
||||
*
|
||||
* @param bool $getShared
|
||||
*
|
||||
* @return \CodeIgniter\Autoloader\FileLocator
|
||||
*/
|
||||
public static function locator($getShared = true)
|
||||
{
|
||||
if ($getShared)
|
||||
{
|
||||
return self::getSharedInstance('locator');
|
||||
}
|
||||
|
||||
return new \CodeIgniter\Autoloader\FileLocator(new \Config\Autoload());
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* The Logger class is a PSR-3 compatible Logging class that supports
|
||||
* multiple handlers that process the actual logging.
|
||||
@ -453,7 +432,7 @@ class Services
|
||||
$config = new \Config\Pager();
|
||||
}
|
||||
|
||||
if ( ! $view instanceof RendererInterface)
|
||||
if (! $view instanceof RendererInterface)
|
||||
{
|
||||
$view = self::renderer();
|
||||
}
|
||||
@ -467,12 +446,12 @@ class Services
|
||||
* The Parser is a simple template parser.
|
||||
*
|
||||
* @param string $viewPath
|
||||
* @param mixed $config
|
||||
* @param mixed $config
|
||||
* @param bool $getShared
|
||||
*
|
||||
* @return \CodeIgniter\View\Parser
|
||||
*/
|
||||
public static function parser($viewPath = APPPATH . 'Views/', $config = null, $getShared = true)
|
||||
public static function parser($viewPath = APPPATH.'Views/', $config = null, $getShared = true)
|
||||
{
|
||||
if ($getShared)
|
||||
{
|
||||
@ -500,7 +479,7 @@ class Services
|
||||
*
|
||||
* @return \CodeIgniter\View\View
|
||||
*/
|
||||
public static function renderer($viewPath = APPPATH . 'Views/', $config = null, $getShared = true)
|
||||
public static function renderer($viewPath = APPPATH.'Views/', $config = null, $getShared = true)
|
||||
{
|
||||
if ($getShared)
|
||||
{
|
||||
@ -532,13 +511,16 @@ class Services
|
||||
return self::getSharedInstance('request', $config);
|
||||
}
|
||||
|
||||
if ( ! is_object($config))
|
||||
if (! is_object($config))
|
||||
{
|
||||
$config = new \Config\App();
|
||||
$config = config(App::class);
|
||||
}
|
||||
|
||||
return new \CodeIgniter\HTTP\IncomingRequest(
|
||||
$config, new \CodeIgniter\HTTP\URI()
|
||||
$config,
|
||||
new \CodeIgniter\HTTP\URI(),
|
||||
'php://input',
|
||||
new \CodeIgniter\HTTP\UserAgent()
|
||||
);
|
||||
}
|
||||
|
||||
@ -559,9 +541,9 @@ class Services
|
||||
return self::getSharedInstance('response', $config);
|
||||
}
|
||||
|
||||
if ( ! is_object($config))
|
||||
if (! is_object($config))
|
||||
{
|
||||
$config = new \Config\App();
|
||||
$config = config(App::class);
|
||||
}
|
||||
|
||||
return new \CodeIgniter\HTTP\Response($config);
|
||||
@ -584,12 +566,16 @@ class Services
|
||||
return self::getSharedInstance('redirectResponse', $config);
|
||||
}
|
||||
|
||||
if ( ! is_object($config))
|
||||
if (! is_object($config))
|
||||
{
|
||||
$config = new \Config\App();
|
||||
$config = config(App::class);
|
||||
}
|
||||
|
||||
return new \CodeIgniter\HTTP\RedirectResponse($config);
|
||||
$response = new \CodeIgniter\HTTP\RedirectResponse($config);
|
||||
$response->setProtocolVersion(self::request()
|
||||
->getProtocolVersion());
|
||||
|
||||
return $response;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
@ -656,9 +642,9 @@ class Services
|
||||
return self::getSharedInstance('security', $config);
|
||||
}
|
||||
|
||||
if ( ! is_object($config))
|
||||
if (! is_object($config))
|
||||
{
|
||||
$config = new \Config\App();
|
||||
$config = config(App::class);
|
||||
}
|
||||
|
||||
return new \CodeIgniter\Security\Security($config);
|
||||
@ -679,20 +665,25 @@ class Services
|
||||
return self::getSharedInstance('session', $config);
|
||||
}
|
||||
|
||||
if ( ! is_object($config))
|
||||
if (! is_object($config))
|
||||
{
|
||||
$config = new \Config\App();
|
||||
$config = config(App::class);
|
||||
}
|
||||
|
||||
$logger = self::logger(true);
|
||||
|
||||
$driverName = $config->sessionDriver;
|
||||
$driver = new $driverName($config);
|
||||
$driver = new $driverName($config);
|
||||
$driver->setLogger($logger);
|
||||
|
||||
$session = new \CodeIgniter\Session\Session($driver, $config);
|
||||
$session->setLogger($logger);
|
||||
|
||||
if (session_status() == PHP_SESSION_NONE)
|
||||
{
|
||||
$session->start();
|
||||
}
|
||||
|
||||
return $session;
|
||||
}
|
||||
|
||||
@ -751,9 +742,9 @@ class Services
|
||||
return self::getSharedInstance('toolbar', $config);
|
||||
}
|
||||
|
||||
if ( ! is_object($config))
|
||||
if (! is_object($config))
|
||||
{
|
||||
$config = new \Config\App();
|
||||
$config = config(App::class);
|
||||
}
|
||||
|
||||
return new \CodeIgniter\Debug\Toolbar($config);
|
||||
@ -843,86 +834,6 @@ class Services
|
||||
return new \CodeIgniter\Typography\Typography();
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
//--------------------------------------------------------------------
|
||||
// Utility Methods - DO NOT EDIT
|
||||
//--------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* Returns a shared instance of any of the class' services.
|
||||
*
|
||||
* $key must be a name matching a service.
|
||||
*
|
||||
* @param string $key
|
||||
* @param array ...$params
|
||||
*
|
||||
* @return mixed
|
||||
*/
|
||||
protected static function getSharedInstance(string $key, ...$params)
|
||||
{
|
||||
// Returns mock if exists
|
||||
if (isset(static::$mocks[$key]))
|
||||
{
|
||||
return static::$mocks[$key];
|
||||
}
|
||||
|
||||
if ( ! isset(static::$instances[$key]))
|
||||
{
|
||||
// Make sure $getShared is false
|
||||
array_push($params, false);
|
||||
|
||||
static::$instances[$key] = static::$key(...$params);
|
||||
}
|
||||
|
||||
return static::$instances[$key];
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* Provides the ability to perform case-insensitive calling of service
|
||||
* names.
|
||||
*
|
||||
* @param string $name
|
||||
* @param array $arguments
|
||||
*
|
||||
* @return mixed
|
||||
*/
|
||||
public static function __callStatic(string $name, array $arguments)
|
||||
{
|
||||
$name = strtolower($name);
|
||||
|
||||
if (method_exists(__CLASS__, $name))
|
||||
{
|
||||
return Services::$name(...$arguments);
|
||||
}
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* Reset shared instances and mocks for testing.
|
||||
*/
|
||||
public static function reset()
|
||||
{
|
||||
static::$mocks = [];
|
||||
|
||||
static::$instances = [];
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* Inject mock object for testing.
|
||||
*
|
||||
* @param string $name
|
||||
* @param $mock
|
||||
*/
|
||||
public static function injectMock(string $name, $mock)
|
||||
{
|
||||
$name = strtolower($name);
|
||||
static::$mocks[$name] = $mock;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
}
|
||||
|
@ -27,45 +27,49 @@
|
||||
* 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
|
||||
* @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 4.0.0
|
||||
* @filesource
|
||||
*/
|
||||
class View extends BaseConfig
|
||||
{
|
||||
|
||||
protected $coreFilters = [
|
||||
'abs' => '\abs',
|
||||
'capitalize' => '\CodeIgniter\View\Filters::capitalize',
|
||||
'date' => '\CodeIgniter\View\Filters::date',
|
||||
'date_modify' => '\CodeIgniter\View\Filters::date_modify',
|
||||
'default' => '\CodeIgniter\View\Filters::default',
|
||||
'esc' => '\CodeIgniter\View\Filters::esc',
|
||||
'excerpt' => '\CodeIgniter\View\Filters::excerpt',
|
||||
'highlight' => '\CodeIgniter\View\Filters::highlight',
|
||||
'abs' => '\abs',
|
||||
'capitalize' => '\CodeIgniter\View\Filters::capitalize',
|
||||
'date' => '\CodeIgniter\View\Filters::date',
|
||||
'date_modify' => '\CodeIgniter\View\Filters::date_modify',
|
||||
'default' => '\CodeIgniter\View\Filters::default',
|
||||
'esc' => '\CodeIgniter\View\Filters::esc',
|
||||
'excerpt' => '\CodeIgniter\View\Filters::excerpt',
|
||||
'highlight' => '\CodeIgniter\View\Filters::highlight',
|
||||
'highlight_code' => '\CodeIgniter\View\Filters::highlight_code',
|
||||
'limit_words' => '\CodeIgniter\View\Filters::limit_words',
|
||||
'limit_chars' => '\CodeIgniter\View\Filters::limit_chars',
|
||||
'lower' => '\strtolower',
|
||||
'nl2br' => '\CodeIgniter\View\Filters::nl2br',
|
||||
'number_format' => '\number_format',
|
||||
'prose' => '\CodeIgniter\View\Filters::prose',
|
||||
'round' => '\CodeIgniter\View\Filters::round',
|
||||
'strip_tags' => '\strip_tags',
|
||||
'title' => '\CodeIgniter\View\Filters::title',
|
||||
'upper' => '\strtoupper',
|
||||
'limit_words' => '\CodeIgniter\View\Filters::limit_words',
|
||||
'limit_chars' => '\CodeIgniter\View\Filters::limit_chars',
|
||||
'local_currency' => '\CodeIgniter\View\Filters::local_currency',
|
||||
'local_number' => '\CodeIgniter\View\Filters::local_number',
|
||||
'lower' => '\strtolower',
|
||||
'nl2br' => '\CodeIgniter\View\Filters::nl2br',
|
||||
'number_format' => '\number_format',
|
||||
'prose' => '\CodeIgniter\View\Filters::prose',
|
||||
'round' => '\CodeIgniter\View\Filters::round',
|
||||
'strip_tags' => '\strip_tags',
|
||||
'title' => '\CodeIgniter\View\Filters::title',
|
||||
'upper' => '\strtoupper',
|
||||
];
|
||||
protected $corePlugins = [
|
||||
'current_url' => '\CodeIgniter\View\Plugins::currentURL',
|
||||
'previous_url' => '\CodeIgniter\View\Plugins::previousURL',
|
||||
'mailto' => '\CodeIgniter\View\Plugins::mailto',
|
||||
'safe_mailto' => '\CodeIgniter\View\Plugins::safeMailto',
|
||||
'lang' => '\CodeIgniter\View\Plugins::lang',
|
||||
'validation_errors' => '\CodeIgniter\View\Plugins::validationErrors',
|
||||
'current_url' => '\CodeIgniter\View\Plugins::currentURL',
|
||||
'previous_url' => '\CodeIgniter\View\Plugins::previousURL',
|
||||
'mailto' => '\CodeIgniter\View\Plugins::mailto',
|
||||
'safe_mailto' => '\CodeIgniter\View\Plugins::safeMailto',
|
||||
'lang' => '\CodeIgniter\View\Plugins::lang',
|
||||
'validation_errors' => '\CodeIgniter\View\Plugins::validationErrors',
|
||||
'route' => '\CodeIgniter\View\Plugins::route',
|
||||
'siteURL' => '\CodeIgniter\View\Plugins::siteURL',
|
||||
];
|
||||
|
||||
public function __construct()
|
||||
|
@ -39,6 +39,7 @@ use CodeIgniter\HTTP\RequestInterface;
|
||||
use CodeIgniter\HTTP\ResponseInterface;
|
||||
use CodeIgniter\Log\Logger;
|
||||
use CodeIgniter\Validation\Validation;
|
||||
use Psr\Log\LoggerInterface;
|
||||
|
||||
/**
|
||||
* Class Controller
|
||||
@ -99,18 +100,17 @@ class Controller
|
||||
/**
|
||||
* Constructor.
|
||||
*
|
||||
* @param RequestInterface $request
|
||||
* @param ResponseInterface $response
|
||||
* @param Logger $logger
|
||||
* @param RequestInterface $request
|
||||
* @param ResponseInterface $response
|
||||
* @param \Psr\Log\LoggerInterface $logger
|
||||
*
|
||||
* @throws \CodeIgniter\HTTP\RedirectException
|
||||
*/
|
||||
public function __construct(RequestInterface $request, ResponseInterface $response, Logger $logger = null)
|
||||
public function initController(RequestInterface $request, ResponseInterface $response, LoggerInterface $logger)
|
||||
{
|
||||
$this->request = $request;
|
||||
|
||||
$this->response = $response;
|
||||
|
||||
$this->logger = is_null($logger) ? Services::logger(true) : $logger;
|
||||
|
||||
$this->logger = $logger;
|
||||
$this->logger->info('Controller "' . get_class($this) . '" loaded.');
|
||||
|
||||
if ($this->forceHTTPS > 0)
|
||||
@ -132,6 +132,8 @@ class Controller
|
||||
* @param int $duration The number of seconds this link should be
|
||||
* considered secure for. Only with HSTS header.
|
||||
* Default value is 1 year.
|
||||
*
|
||||
* @throws \CodeIgniter\HTTP\RedirectException
|
||||
*/
|
||||
public function forceHTTPS(int $duration = 31536000)
|
||||
{
|
||||
@ -170,11 +172,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
|
||||
*/
|
||||
@ -182,9 +184,10 @@ class Controller
|
||||
{
|
||||
$this->validator = Services::validation();
|
||||
|
||||
$success = $this->validator->withRequest($this->request)
|
||||
->setRules($rules, $messages)
|
||||
->run();
|
||||
$success = $this->validator
|
||||
->withRequest($this->request)
|
||||
->setRules($rules, $messages)
|
||||
->run();
|
||||
|
||||
return $success;
|
||||
}
|
||||
|
@ -275,6 +275,19 @@ class BaseBuilder
|
||||
if ($val !== '')
|
||||
{
|
||||
$this->QBSelect[] = $val;
|
||||
|
||||
/*
|
||||
* When doing 'SELECT NULL as field_alias FROM table'
|
||||
* null gets taken as a field, and therefore escaped
|
||||
* with backticks.
|
||||
* This prevents NULL being escaped
|
||||
* @see https://github.com/bcit-ci/CodeIgniter4/issues/1169
|
||||
*/
|
||||
if ( strtoupper(mb_substr(trim($val), 0, 4)) == 'NULL')
|
||||
{
|
||||
$escape = false;
|
||||
}
|
||||
|
||||
$this->QBNoEscape[] = $escape;
|
||||
}
|
||||
}
|
||||
@ -768,7 +781,7 @@ class BaseBuilder
|
||||
*/
|
||||
protected function _whereIn($key = null, $values = null, $not = false, $type = 'AND ', $escape = null)
|
||||
{
|
||||
if ($key === null OR $values === null)
|
||||
if ($key === null || $values === null)
|
||||
{
|
||||
return $this;
|
||||
}
|
||||
@ -1320,6 +1333,28 @@ class BaseBuilder
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* Returns the previously set() data, alternatively resetting it
|
||||
* if needed.
|
||||
*
|
||||
* @param bool $clean
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function getSetData(bool $clean = false)
|
||||
{
|
||||
$data = $this->QBSet;
|
||||
|
||||
if ($clean)
|
||||
{
|
||||
$this->QBSet = [];
|
||||
}
|
||||
|
||||
return $data;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* Get SELECT query string
|
||||
*
|
||||
@ -1501,13 +1536,13 @@ class BaseBuilder
|
||||
* @param array $set An associative array of insert values
|
||||
* @param bool $escape Whether to escape values and identifiers
|
||||
*
|
||||
* @param int $batch_size
|
||||
* @param int $batchSize
|
||||
* @param bool $testing
|
||||
*
|
||||
* @return int Number of rows inserted or FALSE on failure
|
||||
* @throws DatabaseException
|
||||
*/
|
||||
public function insertBatch($set = null, $escape = null, $batch_size = 100, $testing = false)
|
||||
public function insertBatch($set = null, $escape = null, $batchSize = 100, $testing = false)
|
||||
{
|
||||
if ($set === null)
|
||||
{
|
||||
@ -1540,9 +1575,9 @@ class BaseBuilder
|
||||
|
||||
// Batch this baby
|
||||
$affected_rows = 0;
|
||||
for ($i = 0, $total = count($this->QBSet); $i < $total; $i += $batch_size)
|
||||
for ($i = 0, $total = count($this->QBSet); $i < $total; $i += $batchSize)
|
||||
{
|
||||
$sql = $this->_insertBatch($this->db->protectIdentifiers($table, true, $escape, false), $this->QBKeys, array_slice($this->QBSet, $i, $batch_size));
|
||||
$sql = $this->_insertBatch($this->db->protectIdentifiers($table, true, $escape, false), $this->QBKeys, array_slice($this->QBSet, $i, $batchSize));
|
||||
|
||||
if ($testing)
|
||||
{
|
||||
@ -1973,15 +2008,15 @@ class BaseBuilder
|
||||
*
|
||||
* Compiles an update string and runs the query
|
||||
*
|
||||
* @param array $set An associative array of update values
|
||||
* @param string $index The where key
|
||||
* @param int $batch_size The size of the batch to run
|
||||
* @param bool $returnSQL True means SQL is returned, false will execute the query
|
||||
* @param array $set An associative array of update values
|
||||
* @param string $index The where key
|
||||
* @param int $batchSize The size of the batch to run
|
||||
* @param bool $returnSQL True means SQL is returned, false will execute the query
|
||||
*
|
||||
* @return mixed Number of rows affected or FALSE on failure
|
||||
* @throws \CodeIgniter\Database\Exceptions\DatabaseException
|
||||
*/
|
||||
public function updateBatch($set = null, $index = null, $batch_size = 100, $returnSQL = false)
|
||||
public function updateBatch($set = null, $index = null, $batchSize = 100, $returnSQL = false)
|
||||
{
|
||||
if ($index === null)
|
||||
{
|
||||
@ -2023,9 +2058,9 @@ class BaseBuilder
|
||||
// Batch this baby
|
||||
$affected_rows = 0;
|
||||
$savedSQL = [];
|
||||
for ($i = 0, $total = count($this->QBSet); $i < $total; $i += $batch_size)
|
||||
for ($i = 0, $total = count($this->QBSet); $i < $total; $i += $batchSize)
|
||||
{
|
||||
$sql = $this->_updateBatch($table, array_slice($this->QBSet, $i, $batch_size), $this->db->protectIdentifiers($index)
|
||||
$sql = $this->_updateBatch($table, array_slice($this->QBSet, $i, $batchSize), $this->db->protectIdentifiers($index)
|
||||
);
|
||||
|
||||
if ($returnSQL)
|
||||
@ -2499,7 +2534,7 @@ class BaseBuilder
|
||||
for ($ci = 0, $cc = count($conditions); $ci < $cc; $ci ++ )
|
||||
{
|
||||
if (($op = $this->getOperator($conditions[$ci])) === false
|
||||
OR ! preg_match('/^(\(?)(.*)(' . preg_quote($op, '/') . ')\s*(.*(?<!\)))?(\)?)$/i', $conditions[$ci], $matches)
|
||||
|| ! preg_match('/^(\(?)(.*)(' . preg_quote($op, '/') . ')\s*(.*(?<!\)))?(\)?)$/i', $conditions[$ci], $matches)
|
||||
)
|
||||
{
|
||||
continue;
|
||||
|
@ -49,49 +49,49 @@ abstract class BaseConnection implements ConnectionInterface
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
public $DSN;
|
||||
protected $DSN;
|
||||
|
||||
/**
|
||||
* Database port
|
||||
*
|
||||
* @var int
|
||||
*/
|
||||
public $port = '';
|
||||
protected $port = '';
|
||||
|
||||
/**
|
||||
* Hostname
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
public $hostname;
|
||||
protected $hostname;
|
||||
|
||||
/**
|
||||
* Username
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
public $username;
|
||||
protected $username;
|
||||
|
||||
/**
|
||||
* Password
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
public $password;
|
||||
protected $password;
|
||||
|
||||
/**
|
||||
* Database name
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
public $database;
|
||||
protected $database;
|
||||
|
||||
/**
|
||||
* Database driver
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
public $DBDriver = 'MySQLi';
|
||||
protected $DBDriver = 'MySQLi';
|
||||
|
||||
/**
|
||||
* Sub-driver
|
||||
@ -99,21 +99,21 @@ abstract class BaseConnection implements ConnectionInterface
|
||||
* @used-by CI_DB_pdo_driver
|
||||
* @var string
|
||||
*/
|
||||
public $subdriver;
|
||||
protected $subdriver;
|
||||
|
||||
/**
|
||||
* Table prefix
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
public $DBPrefix = '';
|
||||
protected $DBPrefix = '';
|
||||
|
||||
/**
|
||||
* Persistent connection flag
|
||||
*
|
||||
* @var bool
|
||||
*/
|
||||
public $pConnect = false;
|
||||
protected $pConnect = false;
|
||||
|
||||
/**
|
||||
* Debug flag
|
||||
@ -122,56 +122,56 @@ abstract class BaseConnection implements ConnectionInterface
|
||||
*
|
||||
* @var bool
|
||||
*/
|
||||
public $DBDebug = false;
|
||||
protected $DBDebug = false;
|
||||
|
||||
/**
|
||||
* Should we cache results?
|
||||
*
|
||||
* @var bool
|
||||
*/
|
||||
public $cacheOn = false;
|
||||
protected $cacheOn = false;
|
||||
|
||||
/**
|
||||
* Path to store cache files.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
public $cacheDir;
|
||||
protected $cacheDir;
|
||||
|
||||
/**
|
||||
* Character set
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
public $charset = 'utf8';
|
||||
protected $charset = 'utf8';
|
||||
|
||||
/**
|
||||
* Collation
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
public $DBCollat = 'utf8_general_ci';
|
||||
protected $DBCollat = 'utf8_general_ci';
|
||||
|
||||
/**
|
||||
* Swap Prefix
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
public $swapPre = '';
|
||||
protected $swapPre = '';
|
||||
|
||||
/**
|
||||
* Encryption flag/data
|
||||
*
|
||||
* @var mixed
|
||||
*/
|
||||
public $encrypt = false;
|
||||
protected $encrypt = false;
|
||||
|
||||
/**
|
||||
* Compression flag
|
||||
*
|
||||
* @var bool
|
||||
*/
|
||||
public $compress = false;
|
||||
protected $compress = false;
|
||||
|
||||
/**
|
||||
* Strict ON flag
|
||||
@ -180,14 +180,14 @@ abstract class BaseConnection implements ConnectionInterface
|
||||
*
|
||||
* @var bool
|
||||
*/
|
||||
public $strictOn;
|
||||
protected $strictOn;
|
||||
|
||||
/**
|
||||
* Settings for a failover connection.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
public $failover = [];
|
||||
protected $failover = [];
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
|
||||
@ -772,7 +772,7 @@ abstract class BaseConnection implements ConnectionInterface
|
||||
}
|
||||
|
||||
// The query() function will set this flag to FALSE in the event that a query failed
|
||||
if ($this->transStatus === false OR $this->transFailure === true)
|
||||
if ($this->transStatus === false || $this->transFailure === true)
|
||||
{
|
||||
$this->transRollback();
|
||||
|
||||
@ -875,12 +875,12 @@ abstract class BaseConnection implements ConnectionInterface
|
||||
*/
|
||||
public function transRollback(): bool
|
||||
{
|
||||
if (! $this->transEnabled OR $this->transDepth === 0)
|
||||
if (! $this->transEnabled || $this->transDepth === 0)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
// When transactions are nested we only begin/commit/rollback the outermost ones
|
||||
elseif ($this->transDepth > 1 OR $this->_transRollback())
|
||||
elseif ($this->transDepth > 1 || $this->_transRollback())
|
||||
{
|
||||
$this->transDepth --;
|
||||
return true;
|
||||
@ -1241,7 +1241,7 @@ abstract class BaseConnection implements ConnectionInterface
|
||||
*/
|
||||
public function escapeIdentifiers($item)
|
||||
{
|
||||
if ($this->escapeChar === '' OR empty($item) OR in_array($item, $this->reservedIdentifiers))
|
||||
if ($this->escapeChar === '' || empty($item) || in_array($item, $this->reservedIdentifiers))
|
||||
{
|
||||
return $item;
|
||||
}
|
||||
@ -1255,7 +1255,7 @@ abstract class BaseConnection implements ConnectionInterface
|
||||
return $item;
|
||||
}
|
||||
// Avoid breaking functions and literal values inside queries
|
||||
elseif (ctype_digit($item) OR $item[0] === "'" OR ( $this->escapeChar !== '"' && $item[0] === '"') OR
|
||||
elseif (ctype_digit($item) || $item[0] === "'" OR ( $this->escapeChar !== '"' && $item[0] === '"') OR
|
||||
strpos($item, '(') !== false
|
||||
)
|
||||
{
|
||||
@ -1360,7 +1360,7 @@ abstract class BaseConnection implements ConnectionInterface
|
||||
|
||||
return $str;
|
||||
}
|
||||
else if (is_string($str) OR ( is_object($str) && method_exists($str, '__toString')))
|
||||
else if (is_string($str) || ( is_object($str) && method_exists($str, '__toString')))
|
||||
{
|
||||
return "'" . $this->escapeString($str) . "'";
|
||||
}
|
||||
@ -1495,7 +1495,7 @@ abstract class BaseConnection implements ConnectionInterface
|
||||
public function listTables($constrain_by_prefix = FALSE)
|
||||
{
|
||||
// Is there a cached result?
|
||||
if (isset($this->dataCache['table_names']) && count($this->dataCache['table_names']))
|
||||
if (isset($this->dataCache['table_names']) && $this->dataCache['table_names'])
|
||||
{
|
||||
return $this->dataCache['table_names'];
|
||||
}
|
||||
@ -1662,7 +1662,7 @@ abstract class BaseConnection implements ConnectionInterface
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
|
||||
|
||||
/**
|
||||
* Returns an object with foreign key data
|
||||
*
|
||||
@ -1740,4 +1740,15 @@ abstract class BaseConnection implements ConnectionInterface
|
||||
abstract protected function _listColumns(string $table = ''): string;
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
|
||||
public function __get($key)
|
||||
{
|
||||
if (property_exists($this, $key))
|
||||
{
|
||||
return $this->$key;
|
||||
}
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
|
||||
}
|
||||
|
@ -152,7 +152,7 @@ abstract class BaseResult implements ResultInterface
|
||||
{
|
||||
return $this->customResultObject[$className];
|
||||
}
|
||||
elseif ( ! $this->resultID OR $this->numRows === 0)
|
||||
elseif ( ! $this->resultID || $this->numRows === 0)
|
||||
{
|
||||
return [];
|
||||
}
|
||||
@ -183,7 +183,7 @@ abstract class BaseResult implements ResultInterface
|
||||
return $this->customResultObject[$className];
|
||||
}
|
||||
|
||||
is_null($this->rowData) OR $this->dataSeek(0);
|
||||
is_null($this->rowData) || $this->dataSeek(0);
|
||||
$this->customResultObject[$className] = [];
|
||||
|
||||
while ($row = $this->fetchObject($className))
|
||||
@ -213,7 +213,7 @@ abstract class BaseResult implements ResultInterface
|
||||
// In the event that query caching is on, the result_id variable
|
||||
// will not be a valid resource so we'll simply return an empty
|
||||
// array.
|
||||
if ( ! $this->resultID OR $this->numRows === 0)
|
||||
if ( ! $this->resultID || $this->numRows === 0)
|
||||
{
|
||||
return [];
|
||||
}
|
||||
@ -228,7 +228,7 @@ abstract class BaseResult implements ResultInterface
|
||||
return $this->resultArray;
|
||||
}
|
||||
|
||||
is_null($this->rowData) OR $this->dataSeek(0);
|
||||
is_null($this->rowData) || $this->dataSeek(0);
|
||||
while ($row = $this->fetchAssoc())
|
||||
{
|
||||
$this->resultArray[] = $row;
|
||||
@ -256,7 +256,7 @@ abstract class BaseResult implements ResultInterface
|
||||
// In the event that query caching is on, the result_id variable
|
||||
// will not be a valid resource so we'll simply return an empty
|
||||
// array.
|
||||
if ( ! $this->resultID OR $this->numRows === 0)
|
||||
if ( ! $this->resultID || $this->numRows === 0)
|
||||
{
|
||||
return [];
|
||||
}
|
||||
@ -271,7 +271,7 @@ abstract class BaseResult implements ResultInterface
|
||||
return $this->resultObject;
|
||||
}
|
||||
|
||||
is_null($this->rowData) OR $this->dataSeek(0);
|
||||
is_null($this->rowData) || $this->dataSeek(0);
|
||||
while ($row = $this->fetchObject())
|
||||
{
|
||||
$this->resultObject[] = $row;
|
||||
@ -298,10 +298,10 @@ abstract class BaseResult implements ResultInterface
|
||||
if ( ! is_numeric($n))
|
||||
{
|
||||
// We cache the row data for subsequent uses
|
||||
is_array($this->rowData) OR $this->row_data = $this->getRowArray(0);
|
||||
is_array($this->rowData) || $this->row_data = $this->getRowArray(0);
|
||||
|
||||
// array_key_exists() instead of isset() to allow for NULL values
|
||||
if (empty($this->rowData) OR ! array_key_exists($n, $this->rowData))
|
||||
if (empty($this->rowData) || ! array_key_exists($n, $this->rowData))
|
||||
{
|
||||
return null;
|
||||
}
|
||||
@ -335,7 +335,7 @@ abstract class BaseResult implements ResultInterface
|
||||
*/
|
||||
public function getCustomRowObject($n, string $className)
|
||||
{
|
||||
isset($this->customResultObject[$className]) OR $this->customResultObject($className);
|
||||
isset($this->customResultObject[$className]) || $this->getCustomResultObject($className);
|
||||
|
||||
if (empty($this->customResultObject[$className]))
|
||||
{
|
||||
|
@ -76,7 +76,9 @@ class Database
|
||||
throw new \InvalidArgumentException('You have not selected a database type to connect to.');
|
||||
}
|
||||
|
||||
$className = strpos($params['DBDriver'], '\\') === false ? '\CodeIgniter\Database\\' . $params['DBDriver'] . '\\Connection' : $params['DBDriver'] . '\\Connection';
|
||||
$className = strpos($params['DBDriver'], '\\') === false
|
||||
? '\CodeIgniter\Database\\' . $params['DBDriver'] . '\\Connection'
|
||||
: $params['DBDriver'] . '\\Connection';
|
||||
|
||||
$class = new $className($params);
|
||||
|
||||
|
48
system/Database/Exceptions/DataException.php
Normal file
48
system/Database/Exceptions/DataException.php
Normal file
@ -0,0 +1,48 @@
|
||||
<?php namespace CodeIgniter\Database\Exceptions;
|
||||
|
||||
class DataException extends \RuntimeException implements ExceptionInterface
|
||||
{
|
||||
/**
|
||||
* Used by the Model's trigger() method when the callback cannot be found.
|
||||
*
|
||||
* @param string $method
|
||||
*
|
||||
* @return \CodeIgniter\Database\Exceptions\DataException
|
||||
*/
|
||||
public static function forInvalidMethodTriggered(string $method)
|
||||
{
|
||||
return new static(lang('Database.invalidEvent', [$method]));
|
||||
}
|
||||
|
||||
/**
|
||||
* Used by Model's insert/update methods when there isn't
|
||||
* any data to actually work with.
|
||||
*
|
||||
* @param string $mode
|
||||
*
|
||||
* @return \CodeIgniter\Database\Exceptions\DataException
|
||||
*/
|
||||
public static function forEmptyDataset(string $mode)
|
||||
{
|
||||
return new static(lang('Database.emptyDataset', [$mode]));
|
||||
}
|
||||
|
||||
/**
|
||||
* Thrown when an argument for one of the Model's methods
|
||||
* were empty or otherwise invalid, and they could not be
|
||||
* to work correctly for that method.
|
||||
*
|
||||
* @param string $argument
|
||||
*
|
||||
* @return \CodeIgniter\Database\Exceptions\DataException
|
||||
*/
|
||||
public static function forInvalidArgument(string $argument)
|
||||
{
|
||||
return new static(lang('Database.invalidArgument', [$argument]));
|
||||
}
|
||||
|
||||
public static function forInvalidAllowedFields(string $model)
|
||||
{
|
||||
return new static(lang('Database.invalidAllowedFields', [$model]));
|
||||
}
|
||||
}
|
@ -1,5 +1,7 @@
|
||||
<?php namespace CodeIgniter\Database\Exceptions;
|
||||
|
||||
use CodeIgniter\Exceptions\ExceptionInterface;
|
||||
|
||||
/**
|
||||
* CodeIgniter
|
||||
*
|
||||
@ -36,13 +38,11 @@
|
||||
* @filesource
|
||||
*/
|
||||
|
||||
class DatabaseException extends \Error
|
||||
class DatabaseException extends \Error implements ExceptionInterface
|
||||
{
|
||||
|
||||
/**
|
||||
* Exit status code
|
||||
* @var int
|
||||
*/
|
||||
protected $code = 8;
|
||||
|
||||
}
|
||||
|
12
system/Database/Exceptions/ExceptionInterface.php
Normal file
12
system/Database/Exceptions/ExceptionInterface.php
Normal file
@ -0,0 +1,12 @@
|
||||
<?php namespace CodeIgniter\Database\Exceptions;
|
||||
|
||||
/**
|
||||
* Provides a domain-level interface for broad capture
|
||||
* of all database-related exceptions.
|
||||
*
|
||||
* catch (\CodeIgniter\Database\Exceptions\ExceptionInterface) { ... }
|
||||
*/
|
||||
interface ExceptionInterface extends \CodeIgniter\Exceptions\ExceptionInterface
|
||||
{
|
||||
|
||||
}
|
@ -482,7 +482,7 @@ class Forge
|
||||
|
||||
if (($result = $this->db->query($sql)) !== false)
|
||||
{
|
||||
empty($this->db->dataCache['table_names']) OR $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))
|
||||
@ -568,7 +568,7 @@ class Forge
|
||||
{
|
||||
if (is_string($key))
|
||||
{
|
||||
$sql .= ' '.strtoupper($key).' '.$attributes[$key];
|
||||
$sql .= ' ' . strtoupper($key) . ' ' . $this->db->escape($attributes[$key]);
|
||||
}
|
||||
}
|
||||
|
||||
@ -677,7 +677,7 @@ class Forge
|
||||
*/
|
||||
public function renameTable($table_name, $new_table_name)
|
||||
{
|
||||
if ($table_name === '' OR $new_table_name === '')
|
||||
if ($table_name === '' || $new_table_name === '')
|
||||
{
|
||||
throw new \InvalidArgumentException('A table name is required for that operation.');
|
||||
}
|
||||
@ -723,7 +723,7 @@ class Forge
|
||||
public function addColumn($table, $field)
|
||||
{
|
||||
// Work-around for literal column definitions
|
||||
is_array($field) OR $field = [$field];
|
||||
is_array($field) || $field = [$field];
|
||||
|
||||
foreach (array_keys($field) as $k)
|
||||
{
|
||||
@ -794,7 +794,7 @@ class Forge
|
||||
public function modifyColumn($table, $field)
|
||||
{
|
||||
// Work-around for literal column definitions
|
||||
is_array($field) OR $field = [$field];
|
||||
is_array($field) || $field = [$field];
|
||||
|
||||
foreach (array_keys($field) as $k)
|
||||
{
|
||||
@ -1025,7 +1025,7 @@ class Forge
|
||||
*/
|
||||
protected function _attributeUnsigned(&$attributes, &$field)
|
||||
{
|
||||
if (empty($attributes['UNSIGNED']) OR $attributes['UNSIGNED'] !== true)
|
||||
if (empty($attributes['UNSIGNED']) || $attributes['UNSIGNED'] !== true)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
@ -35,10 +35,10 @@
|
||||
* @since Version 3.0.0
|
||||
* @filesource
|
||||
*/
|
||||
use CodeIgniter\Config\BaseConfig;
|
||||
use CodeIgniter\ConfigException;
|
||||
use Config\Autoload;
|
||||
use CodeIgniter\CLI\CLI;
|
||||
use CodeIgniter\Config\BaseConfig;
|
||||
use CodeIgniter\Exceptions\ConfigException;
|
||||
|
||||
/**
|
||||
* Class MigrationRunner
|
||||
@ -152,12 +152,12 @@ class MigrationRunner
|
||||
|
||||
if (empty($this->table))
|
||||
{
|
||||
throw new ConfigException(lang('Migrations.migMissingTable'));
|
||||
throw ConfigException::forMissingMigrationsTable();
|
||||
}
|
||||
|
||||
if ( ! in_array($this->type, ['sequential', 'timestamp']))
|
||||
{
|
||||
throw new ConfigException(lang('Migrations.migInvalidType') . $this->type);
|
||||
throw ConfigException::forInvalidMigrationType($this->type);
|
||||
}
|
||||
|
||||
// Migration basename regex
|
||||
@ -189,7 +189,7 @@ class MigrationRunner
|
||||
{
|
||||
if ( ! $this->enabled)
|
||||
{
|
||||
throw new ConfigException(lang('Migrations.migDisabled'));
|
||||
throw ConfigException::forDisabledMigrations();
|
||||
}
|
||||
// Set Namespace if not null
|
||||
if ( ! is_null($namespace))
|
||||
@ -234,7 +234,7 @@ class MigrationRunner
|
||||
{
|
||||
|
||||
// Only include migrations within the scoop
|
||||
if (($method === 'up' && $version > $currentVersion && $version <= $targetVersion) OR ( $method === 'down' && $version <= $currentVersion && $version > $targetVersion)
|
||||
if (($method === 'up' && $version > $currentVersion && $version <= $targetVersion) || ( $method === 'down' && $version <= $currentVersion && $version > $targetVersion)
|
||||
)
|
||||
{
|
||||
|
||||
@ -247,7 +247,7 @@ class MigrationRunner
|
||||
// Validate the migration file structure
|
||||
if ( ! class_exists($class, false))
|
||||
{
|
||||
throw new \RuntimeException(sprintf(lang('Migrations.migClassNotFound'), $class));
|
||||
throw new \RuntimeException(sprintf(lang('Migrations.classNotFound'), $class));
|
||||
}
|
||||
|
||||
// Forcing migration to selected database group
|
||||
@ -255,7 +255,7 @@ class MigrationRunner
|
||||
|
||||
if ( ! is_callable([$instance, $method]))
|
||||
{
|
||||
throw new \RuntimeException(sprintf(lang('Migrations.migMissingMethod'), $method));
|
||||
throw new \RuntimeException(sprintf(lang('Migrations.missingMethod'), $method));
|
||||
}
|
||||
|
||||
$instance->{$method}();
|
||||
@ -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)
|
||||
@ -435,7 +435,7 @@ class MigrationRunner
|
||||
{
|
||||
return false;
|
||||
}
|
||||
throw new \RuntimeException(lang('Migrations.migEmpty'));
|
||||
throw new \RuntimeException(lang('Migrations.empty'));
|
||||
}
|
||||
|
||||
// Check if $targetversion file is found
|
||||
@ -445,7 +445,7 @@ class MigrationRunner
|
||||
{
|
||||
return false;
|
||||
}
|
||||
throw new \RuntimeException(lang('Migrations.migNotFound') . $targetversion);
|
||||
throw new \RuntimeException(lang('Migrations.notFound') . $targetversion);
|
||||
}
|
||||
|
||||
ksort($migrations);
|
||||
@ -461,14 +461,14 @@ class MigrationRunner
|
||||
{
|
||||
if ($this->type === 'sequential' && abs($migration->version - $loop) > 1)
|
||||
{
|
||||
throw new \RuntimeException(lang('Migration.migGap') . " " . $migration->version);
|
||||
throw new \RuntimeException(lang('Migration.gap') . " " . $migration->version);
|
||||
}
|
||||
// Check if all old migration files are all available to do downgrading
|
||||
if ($method === 'down')
|
||||
{
|
||||
if ($loop <= $history_size && $history_migrations[$loop]['version'] != $migration->version)
|
||||
{
|
||||
throw new \RuntimeException(lang('Migration.migGap') . " " . $migration->version);
|
||||
throw new \RuntimeException(lang('Migration.gap') . " " . $migration->version);
|
||||
}
|
||||
}
|
||||
$loop ++;
|
||||
@ -650,7 +650,7 @@ class MigrationRunner
|
||||
]);
|
||||
if (is_cli())
|
||||
{
|
||||
$this->cliMessages[] = "\t" . CLI::color(lang('Migrations.migAdded'), 'yellow') . "($this->namespace) " . $version . '_' . $this->name;
|
||||
$this->cliMessages[] = "\t" . CLI::color(lang('Migrations.added'), 'yellow') . "($this->namespace) " . $version . '_' . $this->name;
|
||||
}
|
||||
}
|
||||
|
||||
@ -670,7 +670,7 @@ class MigrationRunner
|
||||
->delete();
|
||||
if (is_cli())
|
||||
{
|
||||
$this->cliMessages[] = "\t" . CLI::color(lang('Migrations.migRemoved'), 'yellow') . "($this->namespace) " . $version . '_' . $this->name;
|
||||
$this->cliMessages[] = "\t" . CLI::color(lang('Migrations.removed'), 'yellow') . "($this->namespace) " . $version . '_' . $this->name;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -140,11 +140,11 @@ class Connection extends BaseConnection implements ConnectionInterface
|
||||
if (is_array($this->encrypt))
|
||||
{
|
||||
$ssl = [];
|
||||
empty($this->encrypt['ssl_key']) OR $ssl['key'] = $this->encrypt['ssl_key'];
|
||||
empty($this->encrypt['ssl_cert']) OR $ssl['cert'] = $this->encrypt['ssl_cert'];
|
||||
empty($this->encrypt['ssl_ca']) OR $ssl['ca'] = $this->encrypt['ssl_ca'];
|
||||
empty($this->encrypt['ssl_capath']) OR $ssl['capath'] = $this->encrypt['ssl_capath'];
|
||||
empty($this->encrypt['ssl_cipher']) OR $ssl['cipher'] = $this->encrypt['ssl_cipher'];
|
||||
empty($this->encrypt['ssl_key']) || $ssl['key'] = $this->encrypt['ssl_key'];
|
||||
empty($this->encrypt['ssl_cert']) || $ssl['cert'] = $this->encrypt['ssl_cert'];
|
||||
empty($this->encrypt['ssl_ca']) || $ssl['ca'] = $this->encrypt['ssl_ca'];
|
||||
empty($this->encrypt['ssl_capath']) || $ssl['capath'] = $this->encrypt['ssl_capath'];
|
||||
empty($this->encrypt['ssl_cipher']) || $ssl['cipher'] = $this->encrypt['ssl_cipher'];
|
||||
|
||||
if ( ! empty($ssl))
|
||||
{
|
||||
@ -305,7 +305,7 @@ class Connection extends BaseConnection implements ConnectionInterface
|
||||
$this->connID->next_result();
|
||||
if($res = $this->connID->store_result())
|
||||
{
|
||||
$res->free();
|
||||
$res->free();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -109,18 +109,18 @@ class Forge extends \CodeIgniter\Database\Forge
|
||||
{
|
||||
if (is_string($key))
|
||||
{
|
||||
$sql .= ' ' . strtoupper($key) . ' = ' . $attributes[$key];
|
||||
$sql .= ' ' . strtoupper($key) . ' = ' . $this->db->escape($attributes[$key]);
|
||||
}
|
||||
}
|
||||
|
||||
if ( ! empty($this->db->charset) && ! strpos($sql, 'CHARACTER SET') && ! strpos($sql, 'CHARSET'))
|
||||
{
|
||||
$sql .= ' DEFAULT CHARACTER SET = ' . $this->db->charset;
|
||||
$sql .= ' DEFAULT CHARACTER SET = ' . $this->db->escape($this->db->charset);
|
||||
}
|
||||
|
||||
if ( ! empty($this->db->DBCollat) && ! strpos($sql, 'COLLATE'))
|
||||
{
|
||||
$sql .= ' COLLATE = ' . $this->db->DBCollat;
|
||||
$sql .= ' COLLATE = ' . $this->db->escape($this->db->DBCollat);
|
||||
}
|
||||
|
||||
return $sql;
|
||||
@ -228,7 +228,7 @@ class Forge extends \CodeIgniter\Database\Forge
|
||||
continue;
|
||||
}
|
||||
|
||||
is_array($this->keys[$i]) OR $this->keys[$i] = [$this->keys[$i]];
|
||||
is_array($this->keys[$i]) || $this->keys[$i] = [$this->keys[$i]];
|
||||
|
||||
$unique = in_array($i, $this->uniqueKeys) ? 'UNIQUE ' : '';
|
||||
|
||||
|
@ -148,7 +148,7 @@ class Builder extends BaseBuilder
|
||||
$this->set($set);
|
||||
}
|
||||
|
||||
if (count($this->QBSet) === 0)
|
||||
if (! $this->QBSet)
|
||||
{
|
||||
if (CI_DEBUG)
|
||||
{
|
||||
|
@ -101,7 +101,7 @@ class Connection extends BaseConnection implements ConnectionInterface
|
||||
return false;
|
||||
}
|
||||
|
||||
empty($this->schema) or $this->simpleQuery("SET search_path TO {$this->schema},public");
|
||||
empty($this->schema) || $this->simpleQuery("SET search_path TO {$this->schema},public");
|
||||
|
||||
if ($this->setClientEncoding($this->charset) === false)
|
||||
{
|
||||
@ -217,7 +217,7 @@ class Connection extends BaseConnection implements ConnectionInterface
|
||||
$this->initialize();
|
||||
}
|
||||
|
||||
if (is_string($str) OR ( is_object($str) && method_exists($str, '__toString')))
|
||||
if (is_string($str) || ( is_object($str) && method_exists($str, '__toString')))
|
||||
{
|
||||
return pg_escape_literal($this->connID, $str);
|
||||
}
|
||||
@ -483,7 +483,7 @@ class Connection extends BaseConnection implements ConnectionInterface
|
||||
*/
|
||||
protected function buildDSN()
|
||||
{
|
||||
$this->DSN === '' or $this->DSN = '';
|
||||
$this->DSN === '' || $this->DSN = '';
|
||||
|
||||
// If UNIX sockets are used, we shouldn't set a port
|
||||
if (strpos($this->hostname, '/') !== false)
|
||||
@ -491,7 +491,7 @@ class Connection extends BaseConnection implements ConnectionInterface
|
||||
$this->port = '';
|
||||
}
|
||||
|
||||
$this->hostname === '' or $this->DSN = "host={$this->hostname} ";
|
||||
$this->hostname === '' || $this->DSN = "host={$this->hostname} ";
|
||||
|
||||
if ( ! empty($this->port) && ctype_digit($this->port))
|
||||
{
|
||||
@ -505,10 +505,10 @@ class Connection extends BaseConnection implements ConnectionInterface
|
||||
// An empty password is valid!
|
||||
// password must be set to null to ignore it.
|
||||
|
||||
$this->password === null or $this->DSN .= "password='{$this->password}' ";
|
||||
$this->password === null || $this->DSN .= "password='{$this->password}' ";
|
||||
}
|
||||
|
||||
$this->database === '' or $this->DSN .= "dbname={$this->database} ";
|
||||
$this->database === '' || $this->DSN .= "dbname={$this->database} ";
|
||||
|
||||
// We don't have these options as elements in our standard configuration
|
||||
// array, but they might be set by parse_url() if the configuration was
|
||||
|
@ -76,6 +76,19 @@ class Forge extends \CodeIgniter\Database\Forge
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* CREATE TABLE attributes
|
||||
*
|
||||
* @param array $attributes Associative array of table attributes
|
||||
* @return string
|
||||
*/
|
||||
protected function _createTableAttributes($attributes)
|
||||
{
|
||||
return '';
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* ALTER TABLE
|
||||
*
|
||||
|
@ -149,7 +149,7 @@ class Seeder
|
||||
|
||||
if ( ! class_exists($class, false))
|
||||
{
|
||||
require $path;
|
||||
require_once $path;
|
||||
}
|
||||
|
||||
$seeder = new $class($this->config);
|
||||
|
@ -1,165 +0,0 @@
|
||||
<?php namespace CodeIgniter;
|
||||
|
||||
/**
|
||||
* 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
|
||||
*/
|
||||
/**
|
||||
* Custom Exceptions
|
||||
*
|
||||
* These exceptions are provided for your use, and work to provide a consistent
|
||||
* experience across the application. The default error codes are already set,
|
||||
* and will be used to provide both HTTP status codes and CLI exit codes.
|
||||
*
|
||||
* The Error Exceptions below are primarily to provide a way to have
|
||||
* information logged automatically by the application's log system.
|
||||
*
|
||||
* @package CodeIgniter
|
||||
*/
|
||||
|
||||
/**
|
||||
* Error: system is unusable
|
||||
*/
|
||||
class EmergencyError extends \Error
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Error: Action must be taken immediately (system/db down, etc)
|
||||
*/
|
||||
class AlertError extends \Error
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Error: Critical conditions, like component unavailble, etc.
|
||||
*/
|
||||
class CriticalError extends \Error
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Error: Runtime errors that do not require immediate action
|
||||
*/
|
||||
class Error extends \Error
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Exception for automatic logging.
|
||||
*/
|
||||
class PageNotFoundException extends \OutOfBoundsException
|
||||
{
|
||||
|
||||
/**
|
||||
* Error code
|
||||
* @var int
|
||||
*/
|
||||
protected $code = 404;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Exception for automatic logging.
|
||||
*/
|
||||
class ConfigException extends CriticalError
|
||||
{
|
||||
|
||||
/**
|
||||
* Error code
|
||||
* @var int
|
||||
*/
|
||||
protected $code = 3;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Exception for automatic logging.
|
||||
*/
|
||||
class UnknownFileException extends CriticalError
|
||||
{
|
||||
|
||||
/**
|
||||
* Error code
|
||||
* @var int
|
||||
*/
|
||||
protected $code = 4;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Exception for automatic logging.
|
||||
*/
|
||||
class UnknownClassException extends CriticalError
|
||||
{
|
||||
|
||||
/**
|
||||
* Error code
|
||||
* @var int
|
||||
*/
|
||||
protected $code = 5;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Exception for automatic logging.
|
||||
*/
|
||||
class UnknownMethodException extends CriticalError
|
||||
{
|
||||
|
||||
/**
|
||||
* Error code
|
||||
* @var int
|
||||
*/
|
||||
protected $code = 6;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Exception for automatic logging.
|
||||
*/
|
||||
class UserInputException extends \OutOfBoundsException
|
||||
{
|
||||
|
||||
/**
|
||||
* Error code
|
||||
* @var int
|
||||
*/
|
||||
protected $code = 7;
|
||||
|
||||
}
|
@ -35,15 +35,14 @@
|
||||
* @since Version 3.0.0
|
||||
* @filesource
|
||||
*/
|
||||
use Config\Services;
|
||||
|
||||
require __DIR__.'/CustomExceptions.php';
|
||||
|
||||
/**
|
||||
* Exceptions manager
|
||||
*/
|
||||
class Exceptions
|
||||
{
|
||||
use \CodeIgniter\API\ResponseTrait;
|
||||
|
||||
/**
|
||||
* Nesting level of the output buffering mechanism
|
||||
*
|
||||
@ -64,20 +63,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 +138,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);
|
||||
@ -203,7 +224,7 @@ class Exceptions
|
||||
}
|
||||
|
||||
// 404 Errors
|
||||
if ($exception instanceof \CodeIgniter\PageNotFoundException)
|
||||
if ($exception instanceof \CodeIgniter\Exceptions\PageNotFoundException)
|
||||
{
|
||||
return 'error_404.php';
|
||||
}
|
||||
@ -271,13 +292,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(),
|
||||
];
|
||||
}
|
||||
|
||||
|
@ -35,8 +35,10 @@
|
||||
* @since Version 3.0.0
|
||||
* @filesource
|
||||
*/
|
||||
use CodeIgniter\Config\BaseConfig;
|
||||
use Config\App;
|
||||
use Config\Services;
|
||||
use CodeIgniter\Config\BaseConfig;
|
||||
use CodeIgniter\Format\XMLFormatter;
|
||||
|
||||
/**
|
||||
* Debug Toolbar
|
||||
@ -58,9 +60,11 @@ class Toolbar
|
||||
protected $collectors = [];
|
||||
|
||||
/**
|
||||
* @var float App start time
|
||||
* Incoming Request
|
||||
*
|
||||
* @var \CodeIgniter\HTTP\IncomingRequest
|
||||
*/
|
||||
protected $startTime;
|
||||
protected static $request;
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
|
||||
@ -86,33 +90,210 @@ 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 JSON encoded data
|
||||
*/
|
||||
public function run($startTime, $totalTime, $request, $response): string
|
||||
{
|
||||
// Data items used within the view.
|
||||
$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())/1024/1024, 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'] = [];
|
||||
|
||||
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(),
|
||||
];
|
||||
}
|
||||
|
||||
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 (! 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)] = is_array($value) ? esc(print_r($value, true)) : 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();
|
||||
|
||||
if( $response->CSP !== null )
|
||||
{
|
||||
$response->CSP->addImageSrc( 'data:' );
|
||||
}
|
||||
|
||||
return json_encode($data);
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* Format output
|
||||
*
|
||||
* @param string $data JSON encoded Toolbar data
|
||||
* @param string $format html, json, xml
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function run($startTime, $totalTime, $startMemory, $request, $response): string
|
||||
protected static function format(string $data, string $format = 'html')
|
||||
{
|
||||
$this->startTime = $startTime;
|
||||
$data = json_decode($data, true);
|
||||
|
||||
// Data items used within the view.
|
||||
$collectors = $this->collectors;
|
||||
// History must be loaded on the fly
|
||||
$filenames = glob(WRITEPATH.'debugbar/debugbar_*');
|
||||
$total = count($filenames);
|
||||
rsort($filenames);
|
||||
|
||||
$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();
|
||||
$files = [];
|
||||
|
||||
ob_start();
|
||||
include(__DIR__.'/Toolbar/Views/toolbar.tpl.php');
|
||||
$output = ob_get_contents();
|
||||
ob_end_clean();
|
||||
$current = self::$request->getGet('debugbar_time');
|
||||
$app = config(App::class);
|
||||
|
||||
for ($i = 0; $i < $total; $i++)
|
||||
{
|
||||
// Oldest files will be deleted
|
||||
if ($app->toolbarMaxHistory >= 0 && $i+1 > $app->toolbarMaxHistory)
|
||||
{
|
||||
unlink($filenames[$i]);
|
||||
continue;
|
||||
}
|
||||
|
||||
// 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[] = [
|
||||
'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'],
|
||||
];
|
||||
}
|
||||
|
||||
// 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':
|
||||
$data['styles'] = [];
|
||||
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 'xml':
|
||||
$formatter = new XMLFormatter;
|
||||
$output = $formatter->format($data);
|
||||
break;
|
||||
}
|
||||
|
||||
return $output;
|
||||
}
|
||||
@ -122,37 +303,38 @@ 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, array& $styles ): string
|
||||
{
|
||||
$displayTime = $segmentCount*$segmentDuration;
|
||||
|
||||
$rows = $this->collectTimelineData();
|
||||
|
||||
$output = '';
|
||||
$rows = self::collectTimelineData($collectors);
|
||||
$output = '';
|
||||
$styleCount = 0;
|
||||
|
||||
foreach ($rows as $row)
|
||||
{
|
||||
$output .= "<tr>";
|
||||
$output .= "<td>{$row['name']}</td>";
|
||||
$output .= "<td>{$row['component']}</td>";
|
||||
$output .= "<td style='text-align: right'>".number_format($row['duration']*1000, 2)." ms</td>";
|
||||
$output .= "<td colspan='{$segmentCount}' style='overflow: hidden'>";
|
||||
$output .= "<td class='debug-bar-alignRight'>".number_format($row['duration']*1000, 2)." ms</td>";
|
||||
$output .= "<td class='debug-bar-noverflow' colspan='{$segmentCount}'>";
|
||||
|
||||
$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,
|
||||
$styles['debug-bar-timeline-'.$styleCount] = "left: {$offset}%; width: {$length}%;";
|
||||
$output .= "<span class='timer debug-bar-timeline-{$styleCount}' title='".number_format($length,
|
||||
2)."%'></span>";
|
||||
|
||||
$output .= "</td>";
|
||||
|
||||
$output .= "</tr>";
|
||||
|
||||
$styleCount++;
|
||||
}
|
||||
|
||||
return $output;
|
||||
@ -165,24 +347,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 +416,16 @@ class Toolbar
|
||||
*/
|
||||
public static function eventHandler()
|
||||
{
|
||||
$request = Services::request();
|
||||
self::$request = Services::request();
|
||||
|
||||
if(ENVIRONMENT == 'testing')
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
// 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 +440,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
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -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 [];
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
|
@ -1,32 +1,25 @@
|
||||
<?php namespace CodeIgniter\Debug\Toolbar\Collectors;
|
||||
|
||||
use CodeIgniter\CodeIgniter;
|
||||
use Config\App;
|
||||
use Config\Services;
|
||||
use CodeIgniter\CodeIgniter;
|
||||
|
||||
class Config
|
||||
{
|
||||
public static function display()
|
||||
{
|
||||
$config = new App();
|
||||
$parser = \Config\Services::parser(BASEPATH . 'Debug/Toolbar/Views/', null,false);
|
||||
$config = config(App::class);
|
||||
|
||||
$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;
|
||||
}
|
||||
}
|
||||
|
@ -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 JOIN', 'ORDER BY', 'GROUP BY',
|
||||
@ -161,8 +161,6 @@ class Database extends BaseCollector
|
||||
'IN', 'LIKE', 'NOT 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;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
@ -209,8 +204,8 @@ class Database extends BaseCollector
|
||||
*/
|
||||
public function getTitleDetails(): string
|
||||
{
|
||||
return '(' . count(static::$queries) . ' Queries across ' . count($this->connections) . ' Connection' .
|
||||
(count($this->connections) > 1 ? 's' : '') . ')';
|
||||
return '(' . count(static::$queries) . ' Queries across ' . ($countConnection = count($this->connections)) . ' Connection' .
|
||||
($countConnection > 1 ? 's' : '') . ')';
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
@ -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=';
|
||||
|
||||
}
|
||||
|
||||
|
@ -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';
|
||||
|
||||
}
|
||||
}
|
||||
|
@ -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';
|
||||
|
||||
}
|
||||
}
|
||||
|
@ -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==';
|
||||
|
||||
}
|
||||
|
||||
|
@ -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==';
|
||||
|
||||
}
|
||||
}
|
||||
|
@ -98,5 +98,4 @@ class Timers extends BaseCollector
|
||||
return $data;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
}
|
||||
|
@ -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=';
|
||||
|
||||
}
|
||||
}
|
||||
|
@ -1,4 +1,4 @@
|
||||
<p style="text-align: right">
|
||||
<p class="debug-bar-alignRight">
|
||||
<a href="https://bcit-ci.github.io/CodeIgniter4/index.html" target="_blank" >Read the CodeIgniter docs...</a>
|
||||
</p>
|
||||
|
||||
@ -23,7 +23,7 @@
|
||||
<tr>
|
||||
<td>Base URL:</td>
|
||||
<td>
|
||||
{ if baseURL == '' }
|
||||
{ if $baseURL == '' }
|
||||
<div class="warning">
|
||||
The $baseURL should always be set manually to prevent possible URL personification from external parties.
|
||||
</div>
|
||||
@ -42,12 +42,12 @@
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Content Security Policy Enabled:</td>
|
||||
<td>{ if cspEnabled } Yes { else } No { endif }</td>
|
||||
<td>{ if $cspEnabled } Yes { else } No { endif }</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Salt Set?:</td>
|
||||
<td>
|
||||
{ if salt == '' }
|
||||
{ if $salt == '' }
|
||||
<div class="warning">
|
||||
You have not defined an application-wide $salt. This could lead to a less secure site.
|
||||
</div>
|
||||
|
@ -1,7 +1,7 @@
|
||||
<table>
|
||||
<thead>
|
||||
<tr>
|
||||
<th style="width: 6rem;">Time</th>
|
||||
<th class="debug-bar-width6r">Time</th>
|
||||
<th>Query String</th>
|
||||
</tr>
|
||||
</thead>
|
||||
|
@ -1,7 +1,7 @@
|
||||
<table>
|
||||
<thead>
|
||||
<tr>
|
||||
<th style="width: 6rem;">Time</th>
|
||||
<th class="debug-bar-width6r">Time</th>
|
||||
<th>Event Name</th>
|
||||
<th>Times Called</th>
|
||||
</tr>
|
||||
|
@ -8,7 +8,7 @@
|
||||
{/userFiles}
|
||||
{coreFiles}
|
||||
<tr class="muted">
|
||||
<td style="width: 20em;">{name}</td>
|
||||
<td class="debug-bar-width20e">{name}</td>
|
||||
<td>{path}</td>
|
||||
</tr>
|
||||
{/coreFiles}
|
||||
|
28
system/Debug/Toolbar/Views/_history.tpl.php
Normal file
28
system/Debug/Toolbar/Views/_history.tpl.php
Normal 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 class="debug-bar-width70p">
|
||||
<button class="ci-history-load" data-time="{time}">Load</button>
|
||||
</td>
|
||||
<td class="debug-bar-width140p">{datetime}</td>
|
||||
<td>{status}</td>
|
||||
<td>{method}</td>
|
||||
<td>{url}</td>
|
||||
<td>{contentType}</td>
|
||||
<td>{isAJAX}</td>
|
||||
</tr>
|
||||
{/files}
|
||||
</tbody>
|
||||
</table>
|
@ -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 }
|
||||
|
@ -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);
|
||||
@ -324,3 +356,46 @@
|
||||
display: none !important;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
simple styles to replace inline styles
|
||||
*/
|
||||
.debug-bar-width30 {
|
||||
width: 30%;
|
||||
}
|
||||
|
||||
.debug-bar-width10 {
|
||||
width: 10%;
|
||||
}
|
||||
|
||||
.debug-bar-width70p {
|
||||
width: 70px;
|
||||
}
|
||||
|
||||
.debug-bar-width140p {
|
||||
width: 140px;
|
||||
}
|
||||
|
||||
.debug-bar-width20e {
|
||||
width: 20em;
|
||||
}
|
||||
|
||||
.debug-bar-width6r {
|
||||
width: 6rem;
|
||||
}
|
||||
|
||||
.debug-bar-ndisplay {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.debug-bar-alignRight {
|
||||
text-align: right;
|
||||
}
|
||||
|
||||
.debug-bar-alignLeft {
|
||||
text-align: left;
|
||||
}
|
||||
|
||||
.debug-bar-noverflow {
|
||||
overflow: hidden;
|
||||
}
|
||||
|
@ -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();
|
||||
}
|
||||
},
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
|
@ -5,87 +5,87 @@
|
||||
<script id="toolbar_js" type="text/javascript">
|
||||
<?= 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>
|
||||
<div id="debug-icon" class="debug-bar-ndisplay">
|
||||
<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)">↕</a></span>
|
||||
<span id="toolbar-position"><a href="javascript: void(0)">↕</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 <?= $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 <?= $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 -->
|
||||
@ -93,110 +93,90 @@
|
||||
<table class="timeline">
|
||||
<thead>
|
||||
<tr>
|
||||
<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++) : ?>
|
||||
<th class="debug-bar-width30">NAME</th>
|
||||
<th class="debug-bar-width10">COMPONENT</th>
|
||||
<th class="debug-bar-width10">DURATION</th>
|
||||
<?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, $styles) ?>
|
||||
</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><?= is_array($value) ? var_dump($value) : $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,26 @@
|
||||
<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>
|
||||
<style type="text/css">
|
||||
<?php foreach( $styles as $name => $style ) : ?>
|
||||
.<?= $name ?> {
|
||||
<?= $style ?>
|
||||
}
|
||||
<?php endforeach ?>
|
||||
</style>
|
||||
|
@ -1,24 +1,84 @@
|
||||
<?php if (ENVIRONMENT != 'testing') : ?>
|
||||
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');
|
||||
document.body.appendChild(toolbar);
|
||||
}
|
||||
|
||||
// copy for easier manipulation
|
||||
let responseText = this.responseText;
|
||||
|
||||
// get csp blocked parts
|
||||
// the style block is the first and starts at 0
|
||||
{
|
||||
let PosBeg = responseText.indexOf( '>', responseText.indexOf( '<style' ) ) + 1;
|
||||
let PosEnd = responseText.indexOf( '</style>', PosBeg );
|
||||
document.getElementById( 'debugbar_dynamic_style' ).innerHTML = responseText.substr( PosBeg, PosEnd )
|
||||
responseText = responseText.substr( PosEnd + 8 );
|
||||
}
|
||||
// the script block starts right after style blocks ended
|
||||
{
|
||||
let PosBeg = responseText.indexOf( '>', responseText.indexOf( '<script' ) ) + 1;
|
||||
let PosEnd = responseText.indexOf( '</script>' );
|
||||
document.getElementById( 'debugbar_dynamic_script' ).innerHTML = responseText.substr( PosBeg, PosEnd - PosBeg );
|
||||
responseText = responseText.substr( PosEnd + 9 );
|
||||
}
|
||||
// check for last style block
|
||||
{
|
||||
let PosBeg = responseText.indexOf( '>', responseText.lastIndexOf( '<style' ) ) + 1;
|
||||
let PosEnd = responseText.indexOf( '</style>', PosBeg );
|
||||
document.getElementById( 'debugbar_dynamic_style' ).innerHTML += responseText.substr( PosBeg, PosEnd - PosBeg );
|
||||
responseText = responseText.substr( 0, PosBeg );
|
||||
}
|
||||
|
||||
toolbar.innerHTML = responseText;
|
||||
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;
|
||||
<?php endif; ?>
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -103,6 +103,41 @@ class Entity
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* General method that will return all public and protected
|
||||
* values of this entity as an array. All values are accessed
|
||||
* through the __get() magic method so will have any casts, etc
|
||||
* applied to them.
|
||||
*/
|
||||
public function toArray(): array
|
||||
{
|
||||
$return = [];
|
||||
|
||||
// we need to loop over our properties so that we
|
||||
// allow our magic methods a chance to do their thing.
|
||||
$properties = get_object_vars($this);
|
||||
|
||||
foreach ($properties as $key => $value)
|
||||
{
|
||||
if ($key == '_options') continue;
|
||||
|
||||
$return[$key] = $this->__get($key);
|
||||
}
|
||||
|
||||
// Loop over our mapped properties and add them to the list...
|
||||
if (is_array($this->_options['datamap']))
|
||||
{
|
||||
foreach ($this->_options['datamap'] as $from => $to)
|
||||
{
|
||||
$return[$from] = $this->__get($to);
|
||||
}
|
||||
}
|
||||
|
||||
return $return;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* Magic method to allow retrieval of protected and private
|
||||
* class properties either by their name, or through a `getCamelCasedProperty()`
|
||||
@ -144,7 +179,7 @@ class Entity
|
||||
$result = $this->mutateDate($result);
|
||||
}
|
||||
// Or cast it as something?
|
||||
else if (array_key_exists($key, $this->_options['casts']))
|
||||
else if (isset($this->_options['casts'][$key]) && ! empty($this->_options['casts'][$key]))
|
||||
{
|
||||
$result = $this->castAs($result, $this->_options['casts'][$key]);
|
||||
}
|
||||
@ -267,7 +302,12 @@ class Entity
|
||||
*/
|
||||
protected function mapProperty(string $key)
|
||||
{
|
||||
if (array_key_exists($key, $this->_options['datamap']))
|
||||
if (empty($this->_options['datamap']))
|
||||
{
|
||||
return $key;
|
||||
}
|
||||
|
||||
if (isset($this->_options['datamap'][$key]) && ! empty($this->_options['datamap'][$key]))
|
||||
{
|
||||
return $this->_options['datamap'][$key];
|
||||
}
|
||||
@ -343,7 +383,7 @@ class Entity
|
||||
$value = (object)$value;
|
||||
break;
|
||||
case 'array':
|
||||
if (is_string($value) && (substr($value, 0, 2) === 'a:' || substr($value, 0, 2) === 's:'))
|
||||
if (is_string($value) && (strpos($value,'a:') === 0 || strpos($value, 's:') === 0))
|
||||
{
|
||||
$value = unserialize($value);
|
||||
}
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
x
Reference in New Issue
Block a user