File indexing completed on 2024-12-22 05:33:40

0001 <?php
0002 
0003 /**
0004  *  ocs-webserver
0005  *
0006  *  Copyright 2016 by pling GmbH.
0007  *
0008  *    This file is part of ocs-webserver.
0009  *
0010  *    This program is free software: you can redistribute it and/or modify
0011  *    it under the terms of the GNU Affero General Public License as
0012  *    published by the Free Software Foundation, either version 3 of the
0013  *    License, or (at your option) any later version.
0014  *
0015  *    This program is distributed in the hope that it will be useful,
0016  *    but WITHOUT ANY WARRANTY; without even the implied warranty of
0017  *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
0018  *    GNU Affero General Public License for more details.
0019  *
0020  *    You should have received a copy of the GNU Affero General Public License
0021  *    along with this program.  If not, see <http://www.gnu.org/licenses/>.
0022  **/
0023 class Default_Plugin_ErrorHandler extends Zend_Controller_Plugin_ErrorHandler
0024 {
0025 
0026     const EXCEPTION_NO_ACL_RULE = 'EXCEPTION_NO_ACL_RULE';
0027 
0028     /**
0029      * Called before Zend_Controller_Front begins evaluating the
0030      * request against its routes.
0031      *
0032      * @todo Remove when ZF addeds an ability to set a custom errorHandler
0033      *
0034      * @param Zend_Controller_Request_Abstract $request
0035      *
0036      * @return void
0037      */
0038     public function routeStartup(Zend_Controller_Request_Abstract $request)
0039     {
0040         $frontController = Zend_Controller_Front::getInstance();
0041 
0042         // Ensure this plugin is the only one (hackish, because FC does not allow custom ER setting)
0043         // We want to ensure compatibility with the 'noErrorHandler' param
0044         if ($frontController->hasPlugin('Zend_Controller_Plugin_ErrorHandler')) {
0045             $frontController->unregisterPlugin('Zend_Controller_Plugin_ErrorHandler');
0046         }
0047     }
0048 
0049     /**
0050      * @param Zend_Controller_Request_Abstract $request
0051      *
0052      * @throws mixed
0053      */
0054     protected function _handleError(Zend_Controller_Request_Abstract $request)
0055     {
0056         $frontController = Zend_Controller_Front::getInstance();
0057         if ($frontController->getParam('noErrorHandler')) {
0058             return;
0059         }
0060 
0061         $response = $this->getResponse();
0062 
0063         if ($this->_isInsideErrorHandlerLoop) {
0064             $exceptions = $response->getException();
0065             if (count($exceptions) > $this->_exceptionCountAtFirstEncounter) {
0066                 // Exception thrown by error handler; tell the front controller to throw it
0067                 $frontController->throwExceptions(true);
0068                 throw array_pop($exceptions);
0069             }
0070         }
0071 
0072         // check for an exception AND allow the error handler controller the option to forward
0073         if (($response->isException()) && (!$this->_isInsideErrorHandlerLoop)) {
0074             $this->_isInsideErrorHandlerLoop = true;
0075 
0076             // Get exception information
0077             $error = new ArrayObject(array(), ArrayObject::ARRAY_AS_PROPS);
0078             $exceptions = $response->getException();
0079             $exception = $exceptions[0];
0080             $exceptionType = get_class($exception);
0081             $error->exception = $exception;
0082             switch ($exceptionType) {
0083                 case 'Zend_Controller_Router_Exception':
0084                     if (404 == $exception->getCode()) {
0085                         $error->type = self::EXCEPTION_NO_ROUTE;
0086                     } else {
0087                         $error->type = self::EXCEPTION_OTHER;
0088                     }
0089                     break;
0090                 case 'Zend_Controller_Dispatcher_Exception':
0091                     $error->type = self::EXCEPTION_NO_CONTROLLER;
0092                     break;
0093                 case 'Zend_Controller_Action_Exception':
0094                     if (404 == $exception->getCode()) {
0095                         $error->type = self::EXCEPTION_NO_ACTION;
0096                     } else {
0097                         $error->type = self::EXCEPTION_OTHER;
0098                     }
0099                     break;
0100                 case 'Zend_Acl_Exception':
0101                     $error->type = self::EXCEPTION_NO_ACL_RULE;
0102                     break;
0103                 default:
0104                     $error->type = self::EXCEPTION_OTHER;
0105                     break;
0106             }
0107 
0108             // Keep a copy of the original request
0109             $error->request = clone $request;
0110 
0111             // get a count of the number of exceptions encountered
0112             $this->_exceptionCountAtFirstEncounter = count($exceptions);
0113 
0114             // Forward to the error handler
0115             $request->setParam('error_handler', $error)
0116                     ->setModuleName($this->getErrorHandlerModule())
0117                     ->setControllerName($this->getErrorHandlerController())
0118                     ->setActionName($this->getErrorHandlerAction())
0119                     ->setDispatched(false)
0120             ;
0121         }
0122     }
0123 
0124 }