Completed
Pull Request — master (#48)
by Markus
03:54 queued 02:21
created

ExceptionStrategy::detach()   A

Complexity

Conditions 3
Paths 3

Size

Total Lines 8
Code Lines 4

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
c 1
b 0
f 0
dl 0
loc 8
rs 9.4285
cc 3
eloc 4
nc 3
nop 1
1
<?php
2
3
/**
4
 * cloud solutions ZendSentry
5
 *
6
 * This source file is part of the cloud solutions ZendSentry package
7
 *
8
 * @package    ZendSentry\Mvc\View\Http\ExceptionStrategy
9
 * @license    New BSD License {@link /docs/LICENSE}
10
 * @copyright  Copyright (c) 2011, cloud solutions OÜ
11
 */
12
13
namespace ZendSentry\Mvc\View\Http;
14
15
use Zend\EventManager\EventManagerInterface;
16
use Zend\EventManager\ListenerAggregateInterface;
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 implements ListenerAggregateInterface
30
{
31
    /**
32
     * Display exceptions?
33
     * @var bool
34
     */
35
    protected $displayExceptions = false;
36
    
37
    /**
38
     * Default Exception Message
39
     * @var string
40
     */
41
    protected $defaultExceptionMessage = 'Oh no. Something went wrong, but we have been notified. If you are testing, tell us your eventID: %s';
42
43
    /**
44
     * Name of exception template
45
     * @var string
46
     */
47
    protected $exceptionTemplate = 'error/index';
48
49
    /**
50
     * @var \Zend\Stdlib\CallbackHandler[]
51
     */
52
    protected $listeners = array();
53
54
    /**
55
     * Attach the aggregate to the specified event manager
56
     *
57
     * @param  EventManagerInterface $events
58
     * @return void
59
     */
60
    public function attach(EventManagerInterface $events)
61
    {
62
        $this->listeners[] = $events->attach(MvcEvent::EVENT_DISPATCH_ERROR, array($this, 'prepareExceptionViewModel'));
63
        $this->listeners[] = $events->attach(MvcEvent::EVENT_RENDER_ERROR, array($this, 'prepareExceptionViewModel'));
64
    }
65
66
    /**
67
     * Detach aggregate listeners from the specified event manager
68
     *
69
     * @param  EventManagerInterface $events
70
     * @return void
71
     */
72
    public function detach(EventManagerInterface $events)
73
    {
74
        foreach ($this->listeners as $index => $listener) {
75
            if ($events->detach($listener)) {
76
                unset($this->listeners[$index]);
77
            }
78
        }
79
    }
80
81
    /**
82
     * Flag: display exceptions in error pages?
83
     *
84
     * @param  bool $displayExceptions
85
     * @return ExceptionStrategy
86
     */
87
    public function setDisplayExceptions($displayExceptions)
88
    {
89
        $this->displayExceptions = (bool) $displayExceptions;
90
        return $this;
91
    }
92
93
    /**
94
     * Should we display exceptions in error pages?
95
     *
96
     * @return bool
97
     */
98
    public function displayExceptions()
99
    {
100
        return $this->displayExceptions;
101
    }
102
    
103
    /**
104
     * Set the default exception message
105
     * @param string $defaultExceptionMessage
106
     */
107
    public function setDefaultExceptionMessage($defaultExceptionMessage)
108
    {
109
        $this->defaultExceptionMessage = $defaultExceptionMessage;
110
        return $this;
111
    }
112
113
    /**
114
     * Set the exception template
115
     *
116
     * @param  string $exceptionTemplate
117
     * @return ExceptionStrategy
118
     */
119
    public function setExceptionTemplate($exceptionTemplate)
120
    {
121
        $this->exceptionTemplate = (string) $exceptionTemplate;
122
        return $this;
123
    }
124
125
    /**
126
     * Retrieve the exception template
127
     *
128
     * @return string
129
     */
130
    public function getExceptionTemplate()
131
    {
132
        return $this->exceptionTemplate;
133
    }
134
135
    /**
136
     * Create an exception view model, and set the HTTP status code
137
     *
138
     * @param  MvcEvent $e
139
     * @return void
140
     */
141
    public function prepareExceptionViewModel(MvcEvent $e)
142
    {
143
        // Do nothing if no error in the event
144
        $error = $e->getError();
145
        if (empty($error)) {
146
            return;
147
        }
148
149
        // Do nothing if the result is a response object
150
        $result = $e->getResult();
151
        if ($result instanceof Response) {
1 ignored issue
show
Bug introduced by
The class Zend\Stdlib\ResponseInterface does not exist. Did you forget a USE statement, or did you not list all dependencies?

This error could be the result of:

1. Missing dependencies

PHP Analyzer uses your composer.json file (if available) to determine the dependencies of your project and to determine all the available classes and functions. It expects the composer.json to be in the root folder of your repository.

Are you sure this class is defined by one of your dependencies, or did you maybe not list a dependency in either the require or require-dev section?

2. Missing use statement

PHP does not complain about undefined classes in ìnstanceof checks. For example, the following PHP code will work perfectly fine:

if ($x instanceof DoesNotExist) {
    // Do something.
}

If you have not tested against this specific condition, such errors might go unnoticed.

Loading history...
152
            return;
153
        }
154
155
        // Proceed to showing an error page with or without exception
156
        switch ($error) {
157
            case Application::ERROR_CONTROLLER_NOT_FOUND:
158
            case Application::ERROR_CONTROLLER_INVALID:
159
            case Application::ERROR_ROUTER_NO_MATCH:
160
                // Specifically not handling these
161
                return;
162
163
            case Application::ERROR_EXCEPTION:
164
            default:
165
                // check if there really is an exception
166
                // zf2 also throw normal errors, for example: error-route-unauthorized
167
                // if there is no exception we have nothing to log
168
                if ($e->getParam('exception') == null) {
169
                    return;
170
                }
171
172
                // Log exception to sentry by triggering an exception event
173
                $eventID = $e->getApplication()->getEventManager()->trigger('logException', $this, array('exception' => $e->getParam('exception')));
174
175
                $model = new ViewModel(array(
176
                    'message'            => sprintf($this->defaultExceptionMessage, $eventID->last()),
177
                    'exception'          => $e->getParam('exception'),
178
                    'display_exceptions' => $this->displayExceptions(),
179
                ));
180
                $model->setTemplate($this->getExceptionTemplate());
181
                $e->setResult($model);
182
183
                $response = $e->getResponse();
184
                if (!$response) {
185
                    $response = new HttpResponse();
186
                    $response->setStatusCode(500);
187
                    $e->setResponse($response);
188
                } else {
189
                    $statusCode = $response->getStatusCode();
190
                    if ($statusCode === 200) {
191
                        $response->setStatusCode(500);
192
                    }
193
                }
194
195
                break;
196
        }
197
    }
198
}
1 ignored issue
show
Coding Style introduced by
As per coding style, files should not end with a newline character.

This check marks files that end in a newline character, i.e. an empy line.

Loading history...
199