ExceptionStrategy::prepareExceptionViewModel()   B
last analyzed

Complexity

Conditions 10
Paths 13

Size

Total Lines 60

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 60
rs 7.006
c 0
b 0
f 0
cc 10
nc 13
nop 1

How to fix   Long Method    Complexity   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

1
<?php
2
3
/**
4
 * Bright Answer ZendSentry
5
 *
6
 * This source file is part of the Bright Answer ZendSentry package
7
 *
8
 * @package    ZendSentry\Mvc\View\Http\ExceptionStrategy
9
 * @license    MIT License {@link /docs/LICENSE}
10
 * @copyright  Copyright (c) 2016, Bright Answer OÜ
11
 */
12
13
namespace ZendSentry\Mvc\View\Http;
14
15
use Zend\EventManager\AbstractListenerAggregate;
16
use Zend\EventManager\EventManagerInterface;
17
use Zend\Http\Response as HttpResponse;
18
use Zend\Mvc\Application;
19
use Zend\Mvc\MvcEvent;
20
use Zend\Stdlib\ResponseInterface as Response;
21
use Zend\View\Model\ViewModel;
22
23
/**
24
 * For the moment, this is just an augmented copy of the default ZF ExceptionStrategy
25
 * This is on purpose despite the duplication of code until the module stabilizes and it's clear what need exactly
26
 *
27
 * @package    ZendSentry\Mvc\View\Http\ExceptionStrategy
28
 */
29
class ExceptionStrategy extends AbstractListenerAggregate
30
{
31
    /**
32
     * Display exceptions?
33
     *
34
     * @var bool
35
     */
36
    protected $displayExceptions = false;
37
38
    /**
39
     * Default Exception Message
40
     *
41
     * @var string
42
     */
43
    protected $defaultExceptionMessage = 'Oh no. Something went wrong, but we have been notified. If you are testing, tell us your eventID: %s';
44
45
    /**
46
     * Name of exception template
47
     *
48
     * @var string
49
     */
50
    protected $exceptionTemplate = 'error';
51
52
    /**
53
     * {@inheritDoc}
54
     */
55
    public function attach(EventManagerInterface $events, $priority = 1)
56
    {
57
        $this->listeners[] = $events->attach(MvcEvent::EVENT_DISPATCH_ERROR, [$this, 'prepareExceptionViewModel']);
58
        $this->listeners[] = $events->attach(MvcEvent::EVENT_RENDER_ERROR, [$this, 'prepareExceptionViewModel']);
59
    }
60
61
    /**
62
     * Flag: display exceptions in error pages?
63
     *
64
     * @param  bool $displayExceptions
65
     *
66
     * @return ExceptionStrategy
67
     */
68
    public function setDisplayExceptions($displayExceptions): ExceptionStrategy
69
    {
70
        $this->displayExceptions = (bool)$displayExceptions;
71
        return $this;
72
    }
73
74
    /**
75
     * Set the default exception message
76
     *
77
     * @param string $defaultExceptionMessage
78
     *
79
     * @return self
80
     */
81
    public function setDefaultExceptionMessage($defaultExceptionMessage): self
82
    {
83
        $this->defaultExceptionMessage = $defaultExceptionMessage;
84
        return $this;
85
    }
86
87
    /**
88
     * Create an exception view model, and set the HTTP status code
89
     *
90
     * @param  MvcEvent $e
91
     *
92
     * @return void
93
     */
94
    public function prepareExceptionViewModel(MvcEvent $e)
95
    {
96
        // Do nothing if no error in the event
97
        $error = $e->getError();
98
        if (empty($error)) {
99
            return;
100
        }
101
102
        // Do nothing if the result is a response object
103
        $result = $e->getResult();
104
        if ($result instanceof Response) {
105
            return;
106
        }
107
108
        // Proceed to showing an error page with or without exception
109
        switch ($error) {
110
            case Application::ERROR_CONTROLLER_NOT_FOUND:
111
            case Application::ERROR_CONTROLLER_INVALID:
112
            case Application::ERROR_ROUTER_NO_MATCH:
113
                // Specifically not handling these
114
                return;
115
116
            case Application::ERROR_EXCEPTION:
117
            default:
118
                // check if there really is an exception
119
                // ZF also throws normal errors, for example: error-route-unauthorized
120
                // if there is no exception we have nothing to log
121
                if ($e->getParam('exception') == null) {
122
                    return;
123
                }
124
125
                // Log exception to sentry by triggering an exception event
126
                $eventID = $e->getApplication()->getEventManager()->trigger('logException', $this, ['exception' => $e->getParam('exception')]);
127
128
                $model = new ViewModel(
129
                    [
130
                        'message'            => sprintf($this->defaultExceptionMessage, $eventID->last()),
131
                        'exception'          => $e->getParam('exception'),
132
                        'display_exceptions' => $this->displayExceptions(),
133
                    ]
134
                );
135
                $model->setTemplate($this->getExceptionTemplate());
136
                $e->setResult($model);
137
138
                /** @var HttpResponse $response */
139
                $response = $e->getResponse();
140
                if (!$response) {
141
                    $response = new HttpResponse();
142
                    $response->setStatusCode(500);
143
                    $e->setResponse($response);
144
                } else {
145
                    $statusCode = $response->getStatusCode();
146
                    if ($statusCode === 200) {
147
                        $response->setStatusCode(500);
148
                    }
149
                }
150
151
                break;
152
        }
153
    }
154
155
    /**
156
     * Should we display exceptions in error pages?
157
     *
158
     * @return bool
159
     */
160
    public function displayExceptions(): bool
161
    {
162
        return $this->displayExceptions;
163
    }
164
165
    /**
166
     * Retrieve the exception template
167
     *
168
     * @return string
169
     */
170
    public function getExceptionTemplate(): string
171
    {
172
        return $this->exceptionTemplate;
173
    }
174
175
    /**
176
     * Set the exception template
177
     *
178
     * @param  string $exceptionTemplate
179
     *
180
     * @return ExceptionStrategy
181
     */
182
    public function setExceptionTemplate($exceptionTemplate): ExceptionStrategy
183
    {
184
        $this->exceptionTemplate = (string)$exceptionTemplate;
185
        return $this;
186
    }
187
}