diff --git a/administrator/includes/framework.php b/administrator/includes/framework.php index de67ad3e970b2..10cf9710afc52 100644 --- a/administrator/includes/framework.php +++ b/administrator/includes/framework.php @@ -77,6 +77,18 @@ define('JDEBUG', $config->debug); +// Check deprecation logging +if (empty($config->log_deprecated)) +{ + // Reset handler for E_USER_DEPRECATED + set_error_handler(null, E_USER_DEPRECATED); +} +else +{ + // Make sure handler for E_USER_DEPRECATED is registered + set_error_handler(['Joomla\CMS\Exception\ExceptionHandler', 'handleUserDeprecatedErrors'], E_USER_DEPRECATED); +} + if (JDEBUG || $config->error_reporting === 'maximum') { // Set new Exception handler with debug enabled diff --git a/api/includes/framework.php b/api/includes/framework.php index 1dc4bc9a8de2c..2d60aadb9a4f7 100644 --- a/api/includes/framework.php +++ b/api/includes/framework.php @@ -82,6 +82,18 @@ define('JDEBUG', $config->debug); +// Check deprecation logging +if (empty($config->log_deprecated)) +{ + // Reset handler for E_USER_DEPRECATED + set_error_handler(null, E_USER_DEPRECATED); +} +else +{ + // Make sure handler for E_USER_DEPRECATED is registered + set_error_handler(['Joomla\CMS\Exception\ExceptionHandler', 'handleUserDeprecatedErrors'], E_USER_DEPRECATED); +} + if (JDEBUG || $config->error_reporting === 'maximum') { // Set new Exception handler with debug enabled diff --git a/includes/framework.php b/includes/framework.php index e3a61e797791a..94d5e7ff2a4bf 100644 --- a/includes/framework.php +++ b/includes/framework.php @@ -80,6 +80,18 @@ define('JDEBUG', $config->debug); } +// Check deprecation logging +if (empty($config->log_deprecated)) +{ + // Reset handler for E_USER_DEPRECATED + set_error_handler(null, E_USER_DEPRECATED); +} +else +{ + // Make sure handler for E_USER_DEPRECATED is registered + set_error_handler(['Joomla\CMS\Exception\ExceptionHandler', 'handleUserDeprecatedErrors'], E_USER_DEPRECATED); +} + if (JDEBUG || $config->error_reporting === 'maximum') { // Set new Exception handler with debug enabled diff --git a/libraries/bootstrap.php b/libraries/bootstrap.php index 83ff97a887595..b18714035fd89 100644 --- a/libraries/bootstrap.php +++ b/libraries/bootstrap.php @@ -57,7 +57,10 @@ class_exists('\\Joomla\\CMS\\Autoload\\ClassLoader'); \Symfony\Component\ErrorHandler\ErrorRenderer\HtmlErrorRenderer::setTemplate(__DIR__ . '/../templates/system/fatal.php'); // Register the error handler which processes E_USER_DEPRECATED errors -set_error_handler(['Joomla\CMS\Exception\ExceptionHandler', 'handleUserDeprecatedErrors'], E_USER_DEPRECATED); +if (error_reporting() & E_USER_DEPRECATED) +{ + set_error_handler(['Joomla\CMS\Exception\ExceptionHandler', 'handleUserDeprecatedErrors'], E_USER_DEPRECATED); +} // Suppress phar stream wrapper for non .phar files $behavior = new \TYPO3\PharStreamWrapper\Behavior; diff --git a/libraries/src/Document/Renderer/Html/MessageRenderer.php b/libraries/src/Document/Renderer/Html/MessageRenderer.php index 28c3b94661e58..e31e92f1ffe6b 100644 --- a/libraries/src/Document/Renderer/Html/MessageRenderer.php +++ b/libraries/src/Document/Renderer/Html/MessageRenderer.php @@ -53,7 +53,10 @@ public function render($name, $params = array(), $content = null) if (\function_exists('renderMessage')) { - Log::add('renderMessage() is deprecated. Override system message rendering with layouts instead.', Log::WARNING, 'deprecated'); + @trigger_error( + 'renderMessage() is deprecated. Override system message rendering with layouts instead.', + E_USER_DEPRECATED + ); return renderMessage($msgList); } diff --git a/libraries/src/Exception/ExceptionHandler.php b/libraries/src/Exception/ExceptionHandler.php index 3046d69164ad2..561adfe8e3f43 100644 --- a/libraries/src/Exception/ExceptionHandler.php +++ b/libraries/src/Exception/ExceptionHandler.php @@ -39,11 +39,14 @@ public static function handleUserDeprecatedErrors(int $errorNumber, string $erro // We only want to handle user deprecation messages, these will be triggered in code if ($errorNumber === E_USER_DEPRECATED) { - Log::add( - $errorMessage, - Log::WARNING, - 'deprecated' - ); + try + { + Log::add($errorMessage, Log::WARNING, 'deprecated'); + } + catch (\Exception $e) + { + // Silence + } // If debug mode is enabled, we want to let PHP continue to handle the error; otherwise, we can bail early if (\defined('JDEBUG') && JDEBUG) diff --git a/libraries/src/HTML/HTMLHelper.php b/libraries/src/HTML/HTMLHelper.php index c37f5a47d5e10..0a2d333de36d4 100644 --- a/libraries/src/HTML/HTMLHelper.php +++ b/libraries/src/HTML/HTMLHelper.php @@ -86,18 +86,10 @@ protected static function extract($key) if (\count($parts) === 3) { - try - { - Log::add( - 'Support for a three segment service key is deprecated and will be removed in Joomla 5.0, use the service registry instead', - Log::WARNING, - 'deprecated' - ); - } - catch (\RuntimeException $exception) - { - // Informational message only, continue on - } + @trigger_error( + 'Support for a three segment service key is deprecated and will be removed in Joomla 5.0, use the service registry instead', + E_USER_DEPRECATED + ); } $prefix = \count($parts) === 3 ? array_shift($parts) : 'JHtml'; @@ -207,18 +199,10 @@ final public static function _(string $key, ...$methodArgs) */ public static function register($key, callable $function) { - try - { - Log::add( - 'Support for registering functions is deprecated and will be removed in Joomla 5.0, use the service registry instead', - Log::WARNING, - 'deprecated' - ); - } - catch (\RuntimeException $exception) - { - // Informational message only, continue on - } + @trigger_error( + 'Support for registering functions is deprecated and will be removed in Joomla 5.0, use the service registry instead', + E_USER_DEPRECATED + ); list($key) = static::extract($key); @@ -239,18 +223,10 @@ public static function register($key, callable $function) */ public static function unregister($key) { - try - { - Log::add( - 'Support for registering functions is deprecated and will be removed in Joomla 5.0, use the service registry instead', - Log::WARNING, - 'deprecated' - ); - } - catch (\RuntimeException $exception) - { - // Informational message only, continue on - } + @trigger_error( + 'Support for registering functions is deprecated and will be removed in Joomla 5.0, use the service registry instead', + E_USER_DEPRECATED + ); list($key) = static::extract($key); @@ -1220,18 +1196,10 @@ public static function calendar($value, $name, $id, $format = '%Y-%m-%d', $attri */ public static function addIncludePath($path = '') { - try - { - Log::add( - 'Support for registering lookup paths is deprecated and will be removed in Joomla 5.0, use the service registry instead', - Log::WARNING, - 'deprecated' - ); - } - catch (\RuntimeException $exception) - { - // Informational message only, continue on - } + @trigger_error( + 'Support for registering lookup paths is deprecated and will be removed in Joomla 5.0, use the service registry instead', + E_USER_DEPRECATED + ); // Loop through the path directories foreach ((array) $path as $dir) diff --git a/libraries/src/Language/Text.php b/libraries/src/Language/Text.php index 95d43a8df7069..d700ec7d0f4c5 100644 --- a/libraries/src/Language/Text.php +++ b/libraries/src/Language/Text.php @@ -350,15 +350,14 @@ public static function script($string = null, $jsSafe = false, $interpretBackSla { if ($string === null) { - Log::add( + @trigger_error( sprintf( 'As of 3.7.0, passing a null value for the first argument of %1$s() is deprecated and will not be supported in 4.0.' . ' Use the %2$s::getScriptStrings() method to get the strings from the JavaScript language store instead.', __METHOD__, __CLASS__ ), - Log::WARNING, - 'deprecated' + E_USER_DEPRECATED ); } diff --git a/libraries/src/Log/Log.php b/libraries/src/Log/Log.php index b8027d0904f32..fe89c267073a2 100644 --- a/libraries/src/Log/Log.php +++ b/libraries/src/Log/Log.php @@ -10,6 +10,8 @@ \defined('JPATH_PLATFORM') or die; +use Joomla\CMS\Factory; + /** * Joomla! Log Class * diff --git a/libraries/src/MVC/View/HtmlView.php b/libraries/src/MVC/View/HtmlView.php index dd08f608196cf..02db2a99f669d 100644 --- a/libraries/src/MVC/View/HtmlView.php +++ b/libraries/src/MVC/View/HtmlView.php @@ -112,7 +112,10 @@ public function __construct($config = array()) // Set the charset (used by the variable escaping functions) if (\array_key_exists('charset', $config)) { - Log::add('Setting a custom charset for escaping is deprecated. Override \JViewLegacy::escape() instead.', Log::WARNING, 'deprecated'); + @trigger_error( + 'Setting a custom charset for escaping is deprecated. Override \JViewLegacy::escape() instead.', + E_USER_DEPRECATED + ); $this->_charset = $config['charset']; } diff --git a/libraries/src/MVC/View/JsonView.php b/libraries/src/MVC/View/JsonView.php index 3308de1ec0426..d01f2d2b8960a 100644 --- a/libraries/src/MVC/View/JsonView.php +++ b/libraries/src/MVC/View/JsonView.php @@ -66,7 +66,10 @@ public function __construct($config = array()) // Set the charset (used by the variable escaping functions) if (\array_key_exists('charset', $config)) { - Log::add('Setting a custom charset for escaping is deprecated. Override \JViewLegacy::escape() instead.', Log::WARNING, 'deprecated'); + @trigger_error( + 'Setting a custom charset for escaping is deprecated. Override \JViewLegacy::escape() instead.', + E_USER_DEPRECATED + ); $this->_charset = $config['charset']; } diff --git a/libraries/src/Pagination/Pagination.php b/libraries/src/Pagination/Pagination.php index f3a6bf1cd3961..408d75cb09a24 100644 --- a/libraries/src/Pagination/Pagination.php +++ b/libraries/src/Pagination/Pagination.php @@ -518,7 +518,10 @@ public function getListFooter() if (\function_exists('pagination_list_footer')) { - Log::add('pagination_list_footer is deprecated. Use the layout joomla.pagination.links instead.', Log::WARNING, 'deprecated'); + @trigger_error( + 'pagination_list_footer is deprecated. Use the layout joomla.pagination.links instead.', + E_USER_DEPRECATED + ); $list = array( 'prefix' => $this->prefix, diff --git a/libraries/src/Router/Route.php b/libraries/src/Router/Route.php index f51e75f641c20..3512d034e2a4f 100644 --- a/libraries/src/Router/Route.php +++ b/libraries/src/Router/Route.php @@ -73,10 +73,9 @@ public static function _($url, $xhtml = true, $tls = self::TLS_IGNORE, $absolute // @deprecated 4.0 Before 3.9.7 this method silently converted $tls to integer if (!is_int($tls)) { - Log::add( + @trigger_error( __METHOD__ . '() called with incompatible variable type on parameter $tls.', - Log::WARNING, - 'deprecated' + E_USER_DEPRECATED ); $tls = (int) $tls; diff --git a/libraries/src/Session/Session.php b/libraries/src/Session/Session.php index 88f28c8a6384c..d96e9c01e30e8 100644 --- a/libraries/src/Session/Session.php +++ b/libraries/src/Session/Session.php @@ -159,10 +159,9 @@ public static function getHandlers(): array */ public static function getInstance() { - Log::add( + @trigger_error( __METHOD__ . '() is deprecated. Load the session from the dependency injection container or via Factory::getApplication()->getSession().', - Log::WARNING, - 'deprecated' + E_USER_DEPRECATED ); return Factory::getApplication()->getSession(); @@ -187,11 +186,10 @@ public function get($name, $default = null) if (!empty($args[2])) { - Log::add( + @trigger_error( 'Passing a namespace as a parameter to ' . __METHOD__ . '() is deprecated. ' . 'The namespace should be prepended to the name instead.', - Log::WARNING, - 'deprecated' + E_USER_DEPRECATED ); $name = $args[2] . '.' . $name; @@ -244,11 +242,10 @@ public function set($name, $value = null) if (!empty($args[2])) { - Log::add( + @trigger_error( 'Passing a namespace as a parameter to ' . __METHOD__ . '() is deprecated. ' . 'The namespace should be prepended to the name instead.', - Log::WARNING, - 'deprecated' + E_USER_DEPRECATED ); $name = $args[2] . '.' . $name; @@ -276,11 +273,10 @@ public function has($name) if (!empty($args[1])) { - Log::add( + @trigger_error( 'Passing a namespace as a parameter to ' . __METHOD__ . '() is deprecated. ' . 'The namespace should be prepended to the name instead.', - Log::WARNING, - 'deprecated' + E_USER_DEPRECATED ); $name = $args[1] . '.' . $name; @@ -324,10 +320,9 @@ public function clear() if (!empty($args[0])) { - Log::add( + @trigger_error( 'Using ' . __METHOD__ . '() to remove a single element from the session is deprecated. Use ' . __CLASS__ . '::remove() instead.', - Log::WARNING, - 'deprecated' + E_USER_DEPRECATED ); $name = $args[0]; @@ -335,11 +330,10 @@ public function clear() // Also check for a namespace if (\func_num_args() > 1 && !empty($args[1])) { - Log::add( + @trigger_error( 'Passing a namespace as a parameter to ' . __METHOD__ . '() is deprecated. ' . 'The namespace should be prepended to the name instead.', - Log::WARNING, - 'deprecated' + E_USER_DEPRECATED ); $name = $args[1] . '.' . $name; diff --git a/libraries/src/Toolbar/Toolbar.php b/libraries/src/Toolbar/Toolbar.php index 53eeba7c2c8a9..048a64ecc9815 100644 --- a/libraries/src/Toolbar/Toolbar.php +++ b/libraries/src/Toolbar/Toolbar.php @@ -98,14 +98,13 @@ public function __construct($name = 'toolbar', ToolbarFactoryInterface $factory // At 5.0, require the factory to be injected if (!$factory) { - Log::add( + @trigger_error( sprintf( 'As of Joomla! 5.0, a %1$s must be provided to a %2$s object when creating it.', ToolbarFactoryInterface::class, \get_class($this) ), - Log::WARNING, - 'deprecated' + E_USER_DEPRECATED ); $factory = new ContainerAwareToolbarFactory; @@ -182,14 +181,13 @@ public function appendButton($button, ...$args) array_unshift($args, $button); $this->_bar[] = $args; - Log::add( + @trigger_error( sprintf( '%s::appendButton() should only accept %s instance in Joomla 5.0.', static::class, ToolbarButton::class ), - Log::WARNING, - 'deprecated' + E_USER_DEPRECATED ); return true; @@ -261,14 +259,13 @@ public function prependButton($button, ...$args) array_unshift($args, $button); array_unshift($this->_bar, $args); - Log::add( + @trigger_error( sprintf( '%s::prependButton() should only accept %s instance in Joomla 5.0.', static::class, ToolbarButton::class ), - Log::WARNING, - 'deprecated' + E_USER_DEPRECATED ); return true; @@ -400,15 +397,14 @@ public function loadButtonType($type, $new = false) */ public function addButtonPath($path) { - Log::add( + @trigger_error( sprintf( 'Registering lookup paths for toolbar buttons is deprecated and will be removed in Joomla 5.0.' . ' %1$s objects should be autoloaded or a custom %2$s implementation supporting path lookups provided.', ToolbarButton::class, ToolbarFactoryInterface::class ), - Log::WARNING, - 'deprecated' + E_USER_DEPRECATED ); // Loop through the path directories. @@ -439,13 +435,12 @@ public function addButtonPath($path) */ public function getButtonPath(): array { - Log::add( + @trigger_error( sprintf( 'Lookup paths for %s objects is deprecated and will be removed in Joomla 5.0.', ToolbarButton::class ), - Log::WARNING, - 'deprecated' + E_USER_DEPRECATED ); return $this->_buttonPath; diff --git a/plugins/system/debug/debug.php b/plugins/system/debug/debug.php index c2d6cb0639806..aa01cacb4b4f1 100644 --- a/plugins/system/debug/debug.php +++ b/plugins/system/debug/debug.php @@ -589,20 +589,34 @@ private function collectLogs(): self break; } - $file = $entry->callStack[2]['file'] ?? ''; - $line = $entry->callStack[2]['line'] ?? ''; + $file = ''; + $line = ''; - if (!$file) + // Find the caller, skip Log methods and trigger_error function + foreach ($entry->callStack as $stackEntry) { - // In case trigger_error is used - $file = $entry->callStack[4]['file'] ?? ''; - $line = $entry->callStack[4]['line'] ?? ''; + if (!empty($stackEntry['class']) + && ($stackEntry['class'] === 'Joomla\CMS\Log\LogEntry' || $stackEntry['class'] === 'Joomla\CMS\Log\Log')) + { + continue; + } + + if (empty($stackEntry['class']) && !empty($stackEntry['function']) + && $stackEntry['function'] === 'trigger_error') + { + continue; + } + + $file = $stackEntry['file'] ?? ''; + $line = $stackEntry['line'] ?? ''; + + break; } $category = $entry->category; - $relative = str_replace(JPATH_ROOT, '', $file); + $relative = $file ? str_replace(JPATH_ROOT, '', $file) : ''; - if (0 === strpos($relative, '/libraries/src')) + if ($relative && 0 === strpos($relative, '/libraries/src')) { if (!$logDeprecatedCore) {