Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
205 changes: 93 additions & 112 deletions system/core/Exceptions.php
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
<?php

/**
* CodeIgniter
*
Expand Down Expand Up @@ -26,65 +27,70 @@
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*
* @package CodeIgniter
* @author EllisLab Dev Team
* @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (https://ellislab.com/)
* @copyright Copyright (c) 2014 - 2019, British Columbia Institute of Technology (https://bcit.ca/)
* @copyright Copyright (c) 2019 - 2022, CodeIgniter Foundation (https://codeigniter.com/)
* @license https://opensource.org/licenses/MIT MIT License
* @link https://codeigniter.com
* @since Version 1.0.0
* @package CodeIgniter
* @author EllisLab Dev Team
* @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (https://ellislab.com/)
* @copyright Copyright (c) 2014 - 2019, British Columbia Institute of Technology (https://bcit.ca/)
* @copyright Copyright (c) 2019 - 2022, CodeIgniter Foundation (https://codeigniter.com/)
* @license https://opensource.org/licenses/MIT MIT License
* @link https://codeigniter.com
* @since Version 1.0.0
* @filesource
*/
defined('BASEPATH') OR exit('No direct script access allowed');
defined('BASEPATH') or exit('No direct script access allowed');

/**
* Exceptions Class
*
* @package CodeIgniter
* @subpackage Libraries
* @category Exceptions
* @author EllisLab Dev Team
* @link https://codeigniter.com/userguide3/libraries/exceptions.html
* @package CodeIgniter
* @subpackage Libraries
* @category Exceptions
* @author EllisLab Dev Team
* @link https://codeigniter.com/userguide3/libraries/exceptions.html
*/
class CI_Exceptions {
class CI_Exceptions
{

/**
* Nesting level of the output buffering mechanism
*
* @var int
* @var int
*/
public $ob_level;

/**
* List of available error levels
*
* @var array
* @var array
*/
public $levels = array(
E_ERROR => 'Error',
E_WARNING => 'Warning',
E_PARSE => 'Parsing Error',
E_NOTICE => 'Notice',
E_CORE_ERROR => 'Core Error',
E_CORE_WARNING => 'Core Warning',
E_COMPILE_ERROR => 'Compile Error',
E_COMPILE_WARNING => 'Compile Warning',
E_USER_ERROR => 'User Error',
E_USER_WARNING => 'User Warning',
E_USER_NOTICE => 'User Notice',
E_STRICT => 'Runtime Notice'
E_ERROR => 'Error',
E_WARNING => 'Warning',
E_PARSE => 'Parsing Error',
E_NOTICE => 'Notice',
E_CORE_ERROR => 'Core Error',
E_CORE_WARNING => 'Core Warning',
E_COMPILE_ERROR => 'Compile Error',
E_COMPILE_WARNING => 'Compile Warning',
E_USER_ERROR => 'User Error',
E_USER_WARNING => 'User Warning',
E_USER_NOTICE => 'User Notice'
);

/**
* Class constructor
*
* @return void
* @return void
*/
public function __construct()
{
$this->ob_level = ob_get_level();
// Note: Do not log messages from this constructor.

// Check if PHP version is less than 8.4.0 and E_STRICT is defined
if (version_compare(PHP_VERSION, '8.4.0', '<') && defined('E_STRICT')) {
$this->levels[E_STRICT] = 'Runtime Notice';
}
}

// --------------------------------------------------------------------
Expand All @@ -94,47 +100,43 @@ public function __construct()
*
* Logs PHP generated error messages
*
* @param int $severity Log level
* @param string $message Error message
* @param string $filepath File path
* @param int $line Line number
* @return void
* @param int $severity Log level
* @param string $message Error message
* @param string $filepath File path
* @param int $line Line number
* @return void
*/
#[\ReturnTypeWillChange]
public function log_exception($severity, $message, $filepath, $line)
{
$severity = isset($this->levels[$severity]) ? $this->levels[$severity] : $severity;
log_message('error', 'Severity: '.$severity.' --> '.$message.' '.$filepath.' '.$line);
log_message('error', 'Severity: ' . $severity . ' --> ' . $message . ' ' . $filepath . ' ' . $line);
}

// --------------------------------------------------------------------

/**
* 404 Error Handler
*
* @uses CI_Exceptions::show_error()
* @param string $page Page URI
* @param bool $log_error Whether to log the error
* @return void
* @uses CI_Exceptions::show_error()
*
* @param string $page Page URI
* @param bool $log_error Whether to log the error
* @return void
*/
public function show_404($page = '', $log_error = TRUE)
public function show_404($page = '', $log_error = true)
{
if (is_cli())
{
if (is_cli()) {
$heading = 'Not Found';
$message = 'The controller/method pair you requested was not found.';
}
else
{
} else {
$heading = '404 Page Not Found';
$message = 'The page you requested was not found.';
}

// By default we log this, but allow a dev to skip it
if ($log_error)
{
log_message('error', $heading.': '.$page);
if ($log_error) {
log_message('error', $heading . ': ' . $page);
}

echo $this->show_error($heading, $message, 'error_404', 404);
Expand All @@ -149,50 +151,41 @@ public function show_404($page = '', $log_error = TRUE)
* Takes an error message as input (either as a string or an array)
* and displays it using the specified template.
*
* @param string $heading Page heading
* @param string|string[] $message Error message
* @param string $template Template name
* @param int $status_code (default: 500)
* @param string $heading Page heading
* @param string|string[] $message Error message
* @param string $template Template name
* @param int $status_code (default: 500)
*
* @return string Error page output
* @return string Error page output
*/
public function show_error($heading, $message, $template = 'error_general', $status_code = 500)
{
$templates_path = config_item('error_views_path');
if (empty($templates_path))
{
$templates_path = VIEWPATH.'errors'.DIRECTORY_SEPARATOR;
if (empty($templates_path)) {
$templates_path = VIEWPATH . 'errors' . DIRECTORY_SEPARATOR;
}

if (is_cli())
{
$message = "\t".(is_array($message) ? implode("\n\t", $message) : $message);
$template = 'cli'.DIRECTORY_SEPARATOR.$template;
}
else
{
if (is_cli()) {
$message = "\t" . (is_array($message) ? implode("\n\t", $message) : $message);
$template = 'cli' . DIRECTORY_SEPARATOR . $template;
} else {
set_status_header($status_code);
if (is_array($message))
{
foreach ($message as &$value)
{
if (is_array($message)) {
foreach ($message as &$value) {
$value = htmlspecialchars($value);
}
}
else
{
} else {
$message = htmlspecialchars($message);
}
$message = '<p>'.(is_array($message) ? implode('</p><p>', $message) : $message).'</p>';
$template = 'html'.DIRECTORY_SEPARATOR.$template;
$message = '<p>' . (is_array($message) ? implode('</p><p>', $message) : $message) . '</p>';
$template = 'html' . DIRECTORY_SEPARATOR . $template;
}

if (ob_get_level() > $this->ob_level + 1)
{
if (ob_get_level() > $this->ob_level + 1) {
ob_end_flush();
}
ob_start();
include($templates_path.$template.'.php');
include($templates_path . $template . '.php');
$buffer = ob_get_contents();
ob_end_clean();
return $buffer;
Expand All @@ -203,33 +196,27 @@ public function show_error($heading, $message, $template = 'error_general', $sta
public function show_exception($exception)
{
$templates_path = config_item('error_views_path');
if (empty($templates_path))
{
$templates_path = VIEWPATH.'errors'.DIRECTORY_SEPARATOR;
if (empty($templates_path)) {
$templates_path = VIEWPATH . 'errors' . DIRECTORY_SEPARATOR;
}

$message = $exception->getMessage();
if (empty($message))
{
if (empty($message)) {
$message = '(null)';
}

if (is_cli())
{
$templates_path .= 'cli'.DIRECTORY_SEPARATOR;
}
else
{
$templates_path .= 'html'.DIRECTORY_SEPARATOR;
if (is_cli()) {
$templates_path .= 'cli' . DIRECTORY_SEPARATOR;
} else {
$templates_path .= 'html' . DIRECTORY_SEPARATOR;
}

if (ob_get_level() > $this->ob_level + 1)
{
if (ob_get_level() > $this->ob_level + 1) {
ob_end_flush();
}

ob_start();
include($templates_path.'error_exception.php');
include($templates_path . 'error_exception.php');
$buffer = ob_get_contents();
ob_end_clean();
echo $buffer;
Expand All @@ -240,45 +227,39 @@ public function show_exception($exception)
/**
* Native PHP error handler
*
* @param int $severity Error level
* @param string $message Error message
* @param string $filepath File path
* @param int $line Line number
* @return void
* @param int $severity Error level
* @param string $message Error message
* @param string $filepath File path
* @param int $line Line number
* @return void
*/
public function show_php_error($severity, $message, $filepath, $line)
{
$templates_path = config_item('error_views_path');
if (empty($templates_path))
{
$templates_path = VIEWPATH.'errors'.DIRECTORY_SEPARATOR;
if (empty($templates_path)) {
$templates_path = VIEWPATH . 'errors' . DIRECTORY_SEPARATOR;
}

$severity = isset($this->levels[$severity]) ? $this->levels[$severity] : $severity;

// For safety reasons we don't show the full file path in non-CLI requests
if ( ! is_cli())
{
if (!is_cli()) {
$filepath = str_replace('\\', '/', $filepath);
if (FALSE !== strpos($filepath, '/'))
{
if (false !== strpos($filepath, '/')) {
$x = explode('/', $filepath);
$filepath = $x[count($x)-2].'/'.end($x);
$filepath = $x[count($x) - 2] . '/' . end($x);
}

$template = 'html'.DIRECTORY_SEPARATOR.'error_php';
}
else
{
$template = 'cli'.DIRECTORY_SEPARATOR.'error_php';
$template = 'html' . DIRECTORY_SEPARATOR . 'error_php';
} else {
$template = 'cli' . DIRECTORY_SEPARATOR . 'error_php';
}

if (ob_get_level() > $this->ob_level + 1)
{
if (ob_get_level() > $this->ob_level + 1) {
ob_end_flush();
}
ob_start();
include($templates_path.$template.'.php');
include($templates_path . $template . '.php');
$buffer = ob_get_contents();
ob_end_clean();
echo $buffer;
Expand Down