Completed
Push — master ( e0784c...952513 )
by Tyler
04:36 queued 02:46
created

Notifier::getLogLevel()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 4
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 2
CRAP Score 1

Importance

Changes 0
Metric Value
c 0
b 0
f 0
dl 0
loc 4
ccs 2
cts 2
cp 1
rs 10
cc 1
eloc 2
nc 1
nop 0
crap 1
1
<?php
2
3
namespace Tylercd100\LERN\Components;
4
5
use Auth;
6
use Exception;
7
use Illuminate\Support\Facades\Input;
8
use Monolog\Handler\HandlerInterface;
9
use Monolog\Logger;
10
use Request;
11
use Tylercd100\LERN\Exceptions\NotifierFailedException;
12
use Tylercd100\Notify\Drivers\FromConfig as Notify;
13
use View;
14
15
class Notifier extends Component
16
{
17
    protected $config;
18
    protected $log;
19
    protected $messageCb;
20
    protected $subjectCb;
21
    protected $contextCb;
22
23
    /**
24
     * You can provide a Monolog Logger instance to use in the constructor
25
     * @param Logger|null $log Logger instance to use
26
     */
27 75
    public function __construct(Logger $log = null)
28
    {
29 75
        if ($log === null) {
30 75
            $log = new Logger(config('lern.notify.channel'));
31
        }
32
33 75
        $this->config = config('lern.notify');
34 75
        $this->log = $log;
35 75
    }
36
37
    /**
38
     * Transforms a value into a closure that returns itself when called
39
     * @param  callable|string $cb The value that you want to wrap in a closure
40
     * @return callable
41
     */
42 15
    private function wrapValueInClosure($cb)
43
    {
44 15
        if (is_callable($cb)) {
45 9
            return $cb;
46
        } else {
47
            return function () use ($cb) { return $cb; };
48
        }
49
    }
50
51
    /**
52
     * Set a string or a closure to be called that will generate the message body for the notification
53
     * @param callable|string $cb A closure or string that will be set for the message
54
     * @return $this
55
     */
56 6
    public function setMessage($cb)
57
    {
58 6
        $this->messageCb = $this->wrapValueInClosure($cb);
59 6
        return $this;
60
    }
61
62
    /**
63
     * Returns the result of the message closure
64
     * @param  Exception $e The Exception instance that you want to build the message around
65
     * @return string       The message string
66
     */
67 27
    public function getMessage(Exception $e)
68
    {
69 27
        $msg = $this->getMessageViaView($e);
70
71 27
        if ($msg === false) {
72 9
            $msg = $this->getMessageViaCallback($e);
73
        }
74
75 27
        if ($msg === false) {
76 3
            $msg = $this->getMessageViaDefault($e);
77
        }
78
        
79 27
        return $msg;
80
    }
81
82
    /**
83
     * Gets a basic Exception message
84
     * @param  Exception $e The Exception instance that you want to build the message around
85
     * @return String       Returns the message string
86
     */
87 3
    public function getMessageViaDefault(Exception $e)
88
    {
89 3
        $msg = get_class($e)." was thrown! \n".$e->getMessage();
90 3
        if ($this->config['includeExceptionStackTrace'] === true) {
91 3
            $msg .= "\n\n".$e->getTraceAsString();
92
        }
93 3
        return $msg;
94
    }
95
96
    /**
97
     * Gets the Exception message using a callback if it is set
98
     * @param  Exception    $e The Exception instance that you want to build the message around
99
     * @return String|false    Returns the message string or false
100
     */
101 9
    public function getMessageViaCallback(Exception $e)
102
    {
103 9
        if (is_callable($this->messageCb)) {
104 6
            return $this->messageCb->__invoke($e);
105
        }
106 3
        return false;
107
    }
108
109
    /**
110
     * Gets the Exception message using a Laravel view file
111
     * @param  Exception    $e The Exception instance that you want to build the message around
112
     * @return String|false    Returns the message string or false
113
     */
114 27
    public function getMessageViaView(Exception $e)
115
    {
116 27
        $path = @$this->config["view"];
117 27
        if (!empty($path) && View::exists($path)) {
118 18
            return View::make($path, [
119 18
                "exception" => $e,
120 18
                "url" => Request::url(),
121 18
                "method" => Request::method(),
122 18
                "input" => Input::all(),
123 18
                "user" => Auth::user(),
124 18
            ])->render();
125
        }
126 9
        return false;
127
    }
128
129
    /**
130
     * Set a string or a closure to be called that will generate the subject line for the notification
131
     * @param callable|string $cb A closure or string that will be set for the subject line
132
     * @return $this
133
     */
134 6
    public function setSubject($cb)
135
    {
136 6
        $this->subjectCb = $this->wrapValueInClosure($cb);
137 6
        return $this;
138
    }
139
140
    /**
141
     * Returns the result of the subject closure
142
     * @param  Exception $e The Exception instance that you want to build the subject around
143
     * @return string       The subject string
144
     */
145 18
    public function getSubject(Exception $e)
146
    {
147 18
        if (is_callable($this->subjectCb)) {
148 6
            return $this->subjectCb->__invoke($e);
149
        } else {
150 12
            return get_class($e);
151
        }
152
    }
153
154
    /**
155
     * Set an array or a closure to be called that will generate the context array for the notification
156
     * @param callable|array $cb A closure or array that will be set for the context
157
     * @return $this
158
     */
159 3
    public function setContext($cb)
160
    {
161 3
        $this->contextCb = $this->wrapValueInClosure($cb);
162 3
        return $this;
163
    }
164
165
    /**
166
     * Returns the result of the context closure
167
     * @param  Exception $e The Exception instance that you want to build the context around
168
     * @return array        The context array
169
     */
170 15
    public function getContext(Exception $e, $context = [])
171
    {
172
        //This needs a better solution. How do I set specific context needs for different drivers?
173 15
        if (in_array('pushover', $this->config['drivers'])) {
174 12
            $context['sound'] = $this->config['pushover']['sound'];
175
        }
176
177
        // Call the callback or return the default
178 15
        if (is_callable($this->contextCb)) {
179 3
            return $this->contextCb->__invoke($e, $context);
180
        } else {
181 12
            return $context;
182
        }
183
    }
184
185
    /**
186
     * Get the log level
187
     * @return string 
188
     */
189 3
    public function getLogLevel()
190
    {
191 3
        return $this->config['log_level'];
192
    }
193
194
    /**
195
     * Set the log level
196
     * @param string $level The log level
197
     * @return \Tylercd100\LERN\LERN
198
     */
199 3
    public function setLogLevel($level)
200
    {
201 3
        $this->config['log_level'] = $level;
202 3
        return $this;
203
    }
204
205
    /**
206
     * Pushes on another Monolog Handler
207
     * @param  HandlerInterface $handler The handler instance to add on
208
     * @return Notifier                  Returns this
209
     */
210 6
    public function pushHandler(HandlerInterface $handler)
211
    {
212 6
        $this->log->pushHandler($handler);
213 6
        return $this;
214
    }
215
216
    /**
217
     * Triggers the Monolog Logger instance to log an error to all handlers
218
     * @param  Exception $e The exception to use
219
     * @param  array $context Additional information that you would like to pass to Monolog
220
     * @return bool
221
     * @throws NotifierFailedException
222
     */
223 15
    public function send(Exception $e, array $context = [])
224
    {
225 15
        if ($this->shouldntHandle($e)) {
226 3
            return false;
227
        }
228
229 12
        $message = $this->getMessage($e);
230 12
        $subject = $this->getSubject($e);
231 12
        $context = $this->getContext($e, $context);
232
233
        try {
234 12
            $notify = new Notify($this->config, $this->log, $subject);
235
236 12
            $level = (array_key_exists('log_level', $this->config) && !empty($this->config['log_level']))
237 12
                ? $this->config['log_level']
238 12
                : 'critical';
239
240 12
            $notify->{$level}($message, $context);
241
242 9
            return true;
243 3
        } catch (Exception $e) {
244 3
            $code = (is_int($e->getCode()) ? $e->getCode() : 0);
245 3
            throw new NotifierFailedException($e->getMessage(), $code, $e);
246
        }
247
    }
248
}
249