Infrastructure/Utilities/ErrorHandler.php
private function handleError(string $messageBody, int $errno, bool $die = false)
    {
        // happens when an expression is prefixed with @ (meaning: ignore errors).
        if (error_reporting() == 0) {
            return;
        }

        $errorMessage = $this->generateMessage($messageBody);

        // log to file. suppress errors to prevent infinite loop.
        @error_log($errorMessage, 3, $this->logPath);

        // echo
        if ($this->echoErrors) {
            echo (Functions::isRunningFromCommandLine()) ? $errorMessage : nl2br($errorMessage, false);
        }

        // log to database
        if (isset($this->eventsTableMapper)) {
            /** determine event type */
            switch ($this->getErrorType($errno)) {
                case 'Core Error':
                case 'Parse Error':
                case 'Fatal Error':
                    $eventType = 'critical';
                    break;
                case 'Core Warning':
                case 'Warning':
                    $eventType = 'warning';
                    break;
                case 'Deprecated':
                case 'Notice':
                    $eventType = 'notice';
                    break;
                default:
                    $eventType = 'error';
            }

            $databaseErrorMessage = explode('Stack Trace:', $errorMessage)[0].'...See PHP error log for further details.';

            /** set events administrator id if logged in */
            if ((isset($_SESSION[SlimPostgres::SESSION_KEY_ADMINISTRATOR_ID]))) {
                $this->eventsTableMapper->setAdministratorId((int) $_SESSION[SlimPostgres::SESSION_KEY_ADMINISTRATOR_ID]);
            }

            // suppress errors to prevent infinite loop.
            @$this->eventsTableMapper->insertEvent('PHP Error', $eventType, ['error' => $databaseErrorMessage]);
        }

        // email
        if ($this->emailErrors) {
            @$this->mailer->send($_SERVER['SERVER_NAME'] . " Error", "Check log file for details.", $this->emailTo);
        }

        if ($die) {
            if ($this->redirectPage != null) {
                if (!is_null($this->fatalMessage)) {
                    $_SESSION[SlimPostgres::SESSION_KEY_NOTICE] = [$this->fatalMessage, 'error'];
                }
                header("Location: $this->redirectPage");
            }
            exit();
        }
    }
private function handleError(string $messageBody, int $errno, bool $die = false)
    {
        // happens when an expression is prefixed with @ (meaning: ignore errors).
        if (error_reporting() == 0) {
            return;
        }

        $errorMessage = $this->generateMessage($messageBody);

        // log to file. suppress errors to prevent infinite loop.
        @error_log($errorMessage, 3, $this->logPath);

        // echo
        if ($this->echoErrors) {
            echo (Functions::isRunningFromCommandLine()) ? $errorMessage : nl2br($errorMessage, false);
        }

        // log to database
        if (isset($this->eventsTableMapper)) {
            /** determine event type */
            switch ($this->getErrorType($errno)) {
                case 'Core Error':
                case 'Parse Error':
                case 'Fatal Error':
                    $eventType = 'critical';
                    break;
                case 'Core Warning':
                case 'Warning':
                    $eventType = 'warning';
                    break;
                case 'Deprecated':
                case 'Notice':
                    $eventType = 'notice';
                    break;
                default:
                    $eventType = 'error';
            }

            $databaseErrorMessage = explode('Stack Trace:', $errorMessage)[0].'...See PHP error log for further details.';

            /** set events administrator id if logged in */
            if ((isset($_SESSION[SlimPostgres::SESSION_KEY_ADMINISTRATOR_ID]))) {
                $this->eventsTableMapper->setAdministratorId((int) $_SESSION[SlimPostgres::SESSION_KEY_ADMINISTRATOR_ID]);
            }

            // suppress errors to prevent infinite loop.
            @$this->eventsTableMapper->insertEvent('PHP Error', $eventType, ['error' => $databaseErrorMessage]);
        }

        // email
        if ($this->emailErrors) {
            @$this->mailer->send($_SERVER['SERVER_NAME'] . " Error", "Check log file for details.", $this->emailTo);
        }

        if ($die) {
            if ($this->redirectPage != null) {
                if (!is_null($this->fatalMessage)) {
                    $_SESSION[SlimPostgres::SESSION_KEY_NOTICE] = [$this->fatalMessage, 'error'];
                }
                header("Location: $this->redirectPage");
            }
            exit();
        }
    }
/*
4 ways to handle:
-database - always (as long as database and eventsTableMapper properties have been set)
-log - always
-echo - depends on property
-email - depends on property. never email error deets.
use @ when calling fns from here to avoid infinite loop
die if necessary