dev/core#3707 Fix wordpress issue of page not refreshing after import
[civicrm-core.git] / CRM / Core / Error.php
index a131be146a9e909b5974bd01b3e783c8bf7126b7..accc3f0e76e64bd0d2ffe26a2daabd7d454b4e2c 100644 (file)
@@ -204,9 +204,11 @@ class CRM_Core_Error extends PEAR_ErrorStack {
     CRM_Core_Error::debug_var('Fatal Error Details', $error, TRUE, TRUE, '', PEAR_LOG_ERR);
     CRM_Core_Error::backtrace('backTrace', TRUE);
 
+    $exit = TRUE;
     if ($config->initialized) {
       $content = $template->fetch('CRM/common/fatal.tpl');
       echo CRM_Utils_System::theme($content);
+      $exit = CRM_Utils_System::shouldExitAfterFatal();
     }
     else {
       echo "Sorry. A non-recoverable error has occurred. The error trace below might help to resolve the issue<p>";
@@ -217,7 +219,13 @@ class CRM_Core_Error extends PEAR_ErrorStack {
       exit;
     }
     $runOnce = TRUE;
-    self::abend(CRM_Core_Error::FATAL_ERROR);
+
+    if ($exit) {
+      self::abend(CRM_Core_Error::FATAL_ERROR);
+    }
+    else {
+      self::inpageExceptionDisplay(CRM_Core_Error::FATAL_ERROR);
+    }
   }
 
   /**
@@ -242,9 +250,9 @@ class CRM_Core_Error extends PEAR_ErrorStack {
   }
 
   /**
-   * this function is used to return error details
+   * This function is used to return error details
    *
-   * @param $pearError
+   * @param PEAR_Error $pearError
    *
    * @return array $error
    */
@@ -442,9 +450,14 @@ class CRM_Core_Error extends PEAR_ErrorStack {
     }
 
     echo CRM_Utils_System::theme($content);
+    $exit = CRM_Utils_System::shouldExitAfterFatal();
 
-    // fin
-    self::abend(CRM_Core_Error::FATAL_ERROR);
+    if ($exit) {
+      self::abend(CRM_Core_Error::FATAL_ERROR);
+    }
+    else {
+      self::inpageExceptionDisplay(CRM_Core_Error::FATAL_ERROR);
+    }
   }
 
   /**
@@ -452,7 +465,7 @@ class CRM_Core_Error extends PEAR_ErrorStack {
    * so we can interrupt a potential POST/redirect
    *
    * @param string $name name of debug section
-   * @param $variable mixed reference to variables that we need a trace of
+   * @param mixed $variable reference to variables that we need a trace of
    * @param bool $log should we log or return the output
    * @param bool $html whether to generate a HTML-escaped output
    * @param bool $checkPermission should we check permissions before displaying output
@@ -902,9 +915,8 @@ class CRM_Core_Error extends PEAR_ErrorStack {
    *
    * @param string $status
    *   The status message to set.
-   *
-   * @param null $redirect
-   * @param string $title
+   * @param string|null $redirect
+   * @param string|null $title
    */
   public static function statusBounce($status, $redirect = NULL, $title = NULL) {
     $session = CRM_Core_Session::singleton();
@@ -934,7 +946,7 @@ class CRM_Core_Error extends PEAR_ErrorStack {
   /**
    * PEAR error-handler which converts errors to exceptions
    *
-   * @param $pearError
+   * @param PEAR_Error $pearError
    * @throws PEAR_Exception
    */
   public static function exceptionHandler($pearError) {
@@ -999,7 +1011,7 @@ class CRM_Core_Error extends PEAR_ErrorStack {
   /**
    * Terminate execution abnormally.
    *
-   * @param string $code
+   * @param int $code
    */
   protected static function abend($code) {
     // do a hard rollback of any pending transactions
@@ -1008,6 +1020,37 @@ class CRM_Core_Error extends PEAR_ErrorStack {
     CRM_Utils_System::civiExit($code);
   }
 
+  /**
+   * Show in-page exception
+   * For situations where where calling abend will block the ability for a branded error screen
+   *
+   * Although the host page will run past this point, CiviCRM should not,
+   * therefore we trigger the civi.exit events
+   *
+   * @param string $code
+   */
+  protected static function inpageExceptionDisplay($code) {
+    // do a hard rollback of any pending transactions
+    // if we've come here, its because of some unexpected PEAR errors
+    CRM_Core_Transaction::forceRollbackIfEnabled();
+
+    if ($code > 0 && !headers_sent()) {
+      http_response_code(500);
+    }
+
+    // move things to CiviCRM cache as needed
+    CRM_Core_Session::storeSessionObjects();
+
+    if (Civi\Core\Container::isContainerBooted()) {
+      Civi::dispatcher()->dispatch('civi.core.exit');
+    }
+
+    $userSystem = CRM_Core_Config::singleton()->userSystem;
+    if (is_callable([$userSystem, 'onCiviExit'])) {
+      $userSystem->onCiviExit();
+    }
+  }
+
   /**
    * @param array $error
    * @param int $type