Completed
Push — version-4 ( b70e7e...6ad551 )
by Tyler
04:14
created

Notifier::pushHandler()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 4
Code Lines 3

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 3
CRAP Score 1

Importance

Changes 1
Bugs 0 Features 0
Metric Value
c 1
b 0
f 0
dl 0
loc 4
rs 10
ccs 3
cts 3
cp 1
cc 1
eloc 3
nc 1
nop 1
crap 1
1
<?php
2
3
namespace Tylercd100\LERN\Components;
4
5
use Exception;
6
use Monolog\Handler\HandlerInterface;
7
use Monolog\Logger;
8
use Tylercd100\LERN\Exceptions\NotifierFailedException;
9
use Tylercd100\Notify\Drivers\FromConfig as Notify;
10
use View;
11
12
class Notifier extends Component
13
{
14
    protected $config;
15
    protected $log;
16
    protected $messageCb;
17
    protected $subjectCb;
18
    protected $contextCb;
19
20
    /**
21
     * You can provide a Monolog Logger instance to use in the constructor
22
     * @param Logger|null $log Logger instance to use
23
     */
24 63
    public function __construct(Logger $log = null)
25
    {
26 63
        if ($log === null) {
27 63
            $log = new Logger(config('lern.notify.channel'));
28 63
        }
29
30 63
        $this->config = config('lern.notify');
31 63
        $this->log = $log;
32 63
    }
33
34
    /**
35
     * Transforms a value into a closure that returns itself when called
36
     * @param  callable|string $cb The value that you want to wrap in a closure
37
     * @return callable
38
     */
39 15
    private function wrapValueInClosure($cb)
40
    {
41 15
        if (is_callable($cb)) {
42 9
            return $cb;
43
        } else {
44
            return function () use ($cb) { return $cb; };
45
        }
46
    }
47
48
    /**
49
     * Set a string or a closure to be called that will generate the message body for the notification
50
     * @param callable|string $cb A closure or string that will be set for the message
51
     * @return $this
52
     */
53 6
    public function setMessage($cb)
54
    {
55 6
        $this->messageCb = $this->wrapValueInClosure($cb);
56 6
        return $this;
57
    }
58
59
    /**
60
     * Returns the result of the message closure
61
     * @param  Exception $e The Exception instance that you want to build the message around
62
     * @return string       The message string
63
     */
64 21
    public function getMessage(Exception $e)
65
    {
66 21
        $view = $this->config["view"];
67 21
        if (!empty($view) && View::exists($view)) {
68 15
            return View::make($this->config["view"], ["exception" => $e])->render();
69 6
        } elseif (is_callable($this->messageCb)) {
70 6
            return $this->messageCb->__invoke($e);
71
        } else {
72
            $msg = get_class($e)." was thrown! \n".$e->getMessage();
73
            if ($this->config['includeExceptionStackTrace'] === true) {
74
                $msg .= "\n\n".$e->getTraceAsString();
75
            }
76
            return $msg;
77
        }
78
    }
79
80
    /**
81
     * Set a string or a closure to be called that will generate the subject line for the notification
82
     * @param callable|string $cb A closure or string that will be set for the subject line
83
     * @return $this
84
     */
85 6
    public function setSubject($cb)
86
    {
87 6
        $this->subjectCb = $this->wrapValueInClosure($cb);
88 6
        return $this;
89
    }
90
91
    /**
92
     * Returns the result of the subject closure
93
     * @param  Exception $e The Exception instance that you want to build the subject around
94
     * @return string       The subject string
95
     */
96 18
    public function getSubject(Exception $e)
97
    {
98 18
        if (is_callable($this->subjectCb)) {
99 6
            return $this->subjectCb->__invoke($e);
100
        } else {
101 12
            return get_class($e);
102
        }
103
    }
104
105
    /**
106
     * Set an array or a closure to be called that will generate the context array for the notification
107
     * @param callable|array $cb A closure or array that will be set for the context
108
     * @return $this
109
     */
110 3
    public function setContext($cb)
111
    {
112 3
        $this->contextCb = $this->wrapValueInClosure($cb);
113 3
        return $this;
114
    }
115
116
    /**
117
     * Returns the result of the context closure
118
     * @param  Exception $e The Exception instance that you want to build the context around
119
     * @return array        The context array
120
     */
121 15
    public function getContext(Exception $e, $context = [])
122
    {
123
        //This needs a better solution. How do I set specific context needs for different drivers?
124 15
        if (in_array('pushover', $this->config['drivers'])) {
125 12
            $context['sound'] = $this->config['pushover']['sound'];
126 12
        }
127
128
        // Call the callback or return the default
129 15
        if (is_callable($this->contextCb)) {
130 3
            return $this->contextCb->__invoke($e, $context);
131
        } else {
132 12
            return $context;
133
        }
134
    }
135
136
    /**
137
     * Pushes on another Monolog Handler
138
     * @param  HandlerInterface $handler The handler instance to add on
139
     * @return Notifier                  Returns this
140
     */
141 6
    public function pushHandler(HandlerInterface $handler) {
142 6
        $this->log->pushHandler($handler);
143 6
        return $this;
144
    }
145
146
    /**
147
     * Triggers the Monolog Logger instance to log an error to all handlers
148
     * @param  Exception $e The exception to use
149
     * @param  array $context Additional information that you would like to pass to Monolog
150
     * @return bool
151
     * @throws NotifierFailedException
152
     */
153 15
    public function send(Exception $e, array $context = [])
154
    {
155 15
        if ($this->shouldntHandle($e)) {
156 3
            return false;
157
        }
158
159 12
        $message = $this->getMessage($e);
160 12
        $subject = $this->getSubject($e);
161 12
        $context = $this->getContext($e, $context);
162
163
        try {
164 12
            $notify = new Notify($this->config, $this->log, $subject);
165
166 12
            $level = (array_key_exists('log_level', $this->config) && !empty($this->config['log_level']))
167 12
                ? $this->config['log_level']
168 12
                : 'critical';
169
170 12
            $notify->{$level}($message, $context);
171
172 9
            return true;
173 3
        } catch (Exception $e) {
174 3
            $code = (is_int($e->getCode()) ? $e->getCode() : 0);
175 3
            throw new NotifierFailedException($e->getMessage(), $code, $e);
176
        }
177
    }
178
}
179