diff --git a/libraries/src/Application/ApiApplication.php b/libraries/src/Application/ApiApplication.php index 6b8f338b8d1fc..382c32a510377 100644 --- a/libraries/src/Application/ApiApplication.php +++ b/libraries/src/Application/ApiApplication.php @@ -146,8 +146,32 @@ public function addFormatMap($contentHeader, $format) */ protected function render() { + // Trigger the onBeforeRender event. + PluginHelper::importPlugin('system'); + $this->triggerEvent('onBeforeRender'); + + /** + * Check we aren't in offline mode. In which case for users who can't access the site the API is disabled + * and we won't show anything! + */ + if ($this->get('offline') && !$this->getIdentity()->authorise('core.login.offline')) { + $offlineMessage = ''; + + if ($this->get('display_offline_message', true) == true) { + $offlineMessage = $this->get('offline_message'); + } + + throw new Exception\OfflineWebsiteException($offlineMessage); + } + // Render the document $this->setBody($this->document->render($this->allowCache())); + + // Trigger the onAfterRender event. + $this->triggerEvent('onAfterRender'); + + // Mark afterRender in the profiler. + JDEBUG ? $this->profiler->mark('afterRender') : null; } /** diff --git a/libraries/src/Application/Exception/OfflineWebsiteException.php b/libraries/src/Application/Exception/OfflineWebsiteException.php new file mode 100644 index 0000000000000..c9727a2c5b0a1 --- /dev/null +++ b/libraries/src/Application/Exception/OfflineWebsiteException.php @@ -0,0 +1,19 @@ + + * @license GNU General Public License version 2 or later; see LICENSE.txt + */ + +namespace Joomla\CMS\Application\Exception; + +/** + * Exception class for a website that is in offline mode! + * + * @since __DEPLOY_VERSION__ + */ +class OfflineWebsiteException extends \RuntimeException +{ +} diff --git a/libraries/src/Error/JsonApi/OfflineWebsiteExceptionHandler.php b/libraries/src/Error/JsonApi/OfflineWebsiteExceptionHandler.php new file mode 100644 index 0000000000000..76d0afdaecf89 --- /dev/null +++ b/libraries/src/Error/JsonApi/OfflineWebsiteExceptionHandler.php @@ -0,0 +1,61 @@ + + * @license GNU General Public License version 2 or later; see LICENSE.txt + */ + +namespace Joomla\CMS\Error\JsonApi; + +use Exception; +use Joomla\CMS\Application\Exception\OfflineWebsiteException; +use Tobscure\JsonApi\Exception\Handler\ExceptionHandlerInterface; +use Tobscure\JsonApi\Exception\Handler\ResponseBag; + +/** + * Handler for the site being in offline mode + * + * @since __DEPLOY_VERSION__ + */ +class OfflineWebsiteExceptionHandler implements ExceptionHandlerInterface +{ + /** + * If the exception handler is able to format a response for the provided exception, + * then the implementation should return true. + * + * @param \Exception $e The exception to be handled + * + * @return boolean + * + * @since __DEPLOY_VERSION__ + */ + public function manages(Exception $e) + { + return $e instanceof OfflineWebsiteException; + } + + /** + * Handle the provided exception. + * + * @param Exception $e The exception being handled + * + * @return \Tobscure\JsonApi\Exception\Handler\ResponseBag + * + * @since __DEPLOY_VERSION__ + */ + public function handle(Exception $e) + { + $status = 503; + $error = ['title' => $e->getMessage()]; + + $code = $e->getCode(); + + if ($code) { + $error['code'] = $code; + } + + return new ResponseBag($status, [$error]); + } +} diff --git a/libraries/src/Error/Renderer/JsonapiRenderer.php b/libraries/src/Error/Renderer/JsonapiRenderer.php index 1b377da1432ed..afb29c950cf79 100644 --- a/libraries/src/Error/Renderer/JsonapiRenderer.php +++ b/libraries/src/Error/Renderer/JsonapiRenderer.php @@ -16,6 +16,7 @@ use Joomla\CMS\Error\JsonApi\InvalidRouteExceptionHandler; use Joomla\CMS\Error\JsonApi\NotAcceptableExceptionHandler; use Joomla\CMS\Error\JsonApi\NotAllowedExceptionHandler; +use Joomla\CMS\Error\JsonApi\OfflineWebsiteExceptionHandler; use Joomla\CMS\Error\JsonApi\ResourceNotFoundExceptionHandler; use Joomla\CMS\Error\JsonApi\SaveExceptionHandler; use Joomla\CMS\Error\JsonApi\SendEmailExceptionHandler; @@ -57,6 +58,7 @@ public function render(\Throwable $error): string if ($error instanceof \Exception) { $errors = new ErrorHandler(); + $errors->registerHandler(new OfflineWebsiteExceptionHandler()); $errors->registerHandler(new InvalidRouteExceptionHandler()); $errors->registerHandler(new AuthenticationFailedExceptionHandler()); $errors->registerHandler(new NotAcceptableExceptionHandler());