diff --git a/libraries/src/MVC/Controller/AdminController.php b/libraries/src/MVC/Controller/AdminController.php index 81ba17e880128..20d2dbc3d9b5b 100644 --- a/libraries/src/MVC/Controller/AdminController.php +++ b/libraries/src/MVC/Controller/AdminController.php @@ -14,6 +14,7 @@ use Joomla\CMS\Language\Text; use Joomla\CMS\MVC\Factory\MVCFactoryInterface; use Joomla\CMS\MVC\Model\BaseDatabaseModel; +use Joomla\CMS\MVC\Model\Exception\ModelExceptionInterface; use Joomla\CMS\MVC\Model\WorkflowModelInterface; use Joomla\CMS\Router\Route; use Joomla\Input\Input; @@ -140,10 +141,14 @@ public function delete() $model = $this->getModel(); // Remove the items. - if ($model->delete($cid)) { - $this->setMessage(Text::plural($this->text_prefix . '_N_ITEMS_DELETED', \count($cid))); - } else { - $this->setMessage($model->getError(), 'error'); + try { + if ($model->delete($cid)) { + $this->setMessage(Text::plural($this->text_prefix . '_N_ITEMS_DELETED', \count($cid))); + } else { + $this->setMessage($model->getError(), 'error'); + } + } catch (ModelExceptionInterface $e) { + $this->setMessage($e->getMessage()); } // Invoke the postDelete method to allow for the child class to access the model. diff --git a/libraries/src/MVC/Model/BaseModel.php b/libraries/src/MVC/Model/BaseModel.php index 0e3b60943c045..01779970bc9ad 100644 --- a/libraries/src/MVC/Model/BaseModel.php +++ b/libraries/src/MVC/Model/BaseModel.php @@ -11,7 +11,7 @@ use Joomla\CMS\Filesystem\Path; use Joomla\CMS\Language\Text; -use Joomla\CMS\Object\CMSObject; +use Joomla\CMS\Object\LegacyErrorHandlingTrait; // phpcs:disable PSR1.Files.SideEffects \defined('JPATH_PLATFORM') or die; @@ -22,10 +22,11 @@ * * @since 4.0.0 */ -abstract class BaseModel extends CMSObject implements ModelInterface, StatefulModelInterface +abstract class BaseModel implements ModelInterface, StatefulModelInterface { use StateBehaviorTrait; use LegacyModelLoaderTrait; + use LegacyErrorHandlingTrait; /** * The model (base) name diff --git a/libraries/src/MVC/Model/Exception/ModelExceptionInterface.php b/libraries/src/MVC/Model/Exception/ModelExceptionInterface.php new file mode 100644 index 0000000000000..7848c5cd2dbc5 --- /dev/null +++ b/libraries/src/MVC/Model/Exception/ModelExceptionInterface.php @@ -0,0 +1,23 @@ + + * @license GNU General Public License version 2 or later; see LICENSE.txt + */ + +namespace Joomla\CMS\MVC\Model\Exception; + +// phpcs:disable PSR1.Files.SideEffects +\defined('JPATH_PLATFORM') or die; +// phpcs:enable PSR1.Files.SideEffects + +/** + * Interface that all exceptions stemming from the model should implement for processing by the controller + * + * @since __DEPLOY_VERSION__ + */ +interface ModelExceptionInterface extends \Throwable +{ +} diff --git a/libraries/src/Object/CMSObject.php b/libraries/src/Object/CMSObject.php index 89b3bf7b44ec5..d58f712303308 100644 --- a/libraries/src/Object/CMSObject.php +++ b/libraries/src/Object/CMSObject.php @@ -24,14 +24,7 @@ */ class CMSObject { - /** - * An array of error messages or Exception objects. - * - * @var array - * @since 1.7.0 - * @deprecated 3.1.4 JError has been deprecated - */ - protected $_errors = array(); + use LegacyErrorHandlingTrait; /** * Class constructor, overridden in descendant classes. @@ -125,51 +118,6 @@ public function getProperties($public = true) return $vars; } - /** - * Get the most recent error message. - * - * @param integer $i Option error index. - * @param boolean $toString Indicates if Exception objects should return their error message. - * - * @return string Error message - * - * @since 1.7.0 - * @deprecated 3.1.4 JError has been deprecated - */ - public function getError($i = null, $toString = true) - { - // Find the error - if ($i === null) { - // Default, return the last message - $error = end($this->_errors); - } elseif (!\array_key_exists($i, $this->_errors)) { - // If $i has been specified but does not exist, return false - return false; - } else { - $error = $this->_errors[$i]; - } - - // Check if only the string is requested - if ($error instanceof \Exception && $toString) { - return $error->getMessage(); - } - - return $error; - } - - /** - * Return all errors, if any. - * - * @return array Array of error messages. - * - * @since 1.7.0 - * @deprecated 3.1.4 JError has been deprecated - */ - public function getErrors() - { - return $this->_errors; - } - /** * Modifies a property of the object, creating it if it does not already exist. * @@ -212,19 +160,4 @@ public function setProperties($properties) return false; } - - /** - * Add an error message. - * - * @param string $error Error message. - * - * @return void - * - * @since 1.7.0 - * @deprecated 3.1.4 JError has been deprecated - */ - public function setError($error) - { - $this->_errors[] = $error; - } } diff --git a/libraries/src/Object/LegacyErrorHandlingTrait.php b/libraries/src/Object/LegacyErrorHandlingTrait.php new file mode 100644 index 0000000000000..bad7eb7ec5a85 --- /dev/null +++ b/libraries/src/Object/LegacyErrorHandlingTrait.php @@ -0,0 +1,96 @@ + + * @license GNU General Public License version 2 or later; see LICENSE + */ + +namespace Joomla\CMS\Object; + +// phpcs:disable PSR1.Files.SideEffects +\defined('JPATH_PLATFORM') or die; +// phpcs:enable PSR1.Files.SideEffects + +/** + * Trait which contains the legacy methods that formerly were inherited from \Joomla\CMS\Object\CMSObject to set and + * get errors in a class. Strategically deprecated in favour of exceptions which implement the interface + * \Joomla\CMS\MVC\Model\Exception\ModelExceptionInterface + * + * @since __DEPLOY_VERSION__ + * @deprecated 6.0 Will be removed in favour of throwing exceptions + */ +trait LegacyErrorHandlingTrait +{ + /** + * An array of error messages or Exception objects. + * + * @var array + * @since 1.7.0 + * @deprecated 3.1.4 JError has been deprecated + */ + // phpcs:disable PSR2.Classes.PropertyDeclaration + protected $_errors = array(); + // phpcs:enable PSR2.Classes.PropertyDeclaration + + /** + * Get the most recent error message. + * + * @param integer $i Option error index. + * @param boolean $toString Indicates if Exception objects should return their error message. + * + * @return string Error message + * + * @since 1.7.0 + * @deprecated 3.1.4 JError has been deprecated + */ + public function getError($i = null, $toString = true) + { + // Find the error + if ($i === null) { + // Default, return the last message + $error = end($this->_errors); + } elseif (!\array_key_exists($i, $this->_errors)) { + // If $i has been specified but does not exist, return false + return false; + } else { + $error = $this->_errors[$i]; + } + + // Check if only the string is requested + if ($error instanceof \Exception && $toString) { + return $error->getMessage(); + } + + return $error; + } + + /** + * Return all errors, if any. + * + * @return array Array of error messages. + * + * @since 1.7.0 + * @deprecated 3.1.4 JError has been deprecated + */ + public function getErrors() + { + return $this->_errors; + } + + /** + * Add an error message. + * + * @param string $error Error message. + * + * @return void + * + * @since 1.7.0 + * @deprecated 3.1.4 JError has been deprecated + */ + public function setError($error) + { + $this->_errors[] = $error; + } +}