Completed
Push — master ( 698f1b...eb1c6a )
by Tyler
04:20
created

Notifier::setContext()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 5
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 5
ccs 3
cts 3
cp 1
rs 9.4285
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
11
class Notifier extends Component {
12
    protected $config;
13
    protected $log;
14
    protected $messageCb;
15
    protected $subjectCb;
16
    protected $contextCb;
17
18
    /**
19
     * You can provide a Monolog Logger instance to use in the constructor 
20
     * @param Logger|null $log Logger instance to use
21
     */
22 57
    public function __construct(Logger $log = null) {
23 57
        if ($log === null) {
24 57
            $log = new Logger(config('lern.notify.channel'));
25 57
        }
26
27 57
        $this->config = config('lern.notify');
28 57
        $this->log = $log;
29 57
    }
30
31
    /**
32
     * Transforms a value into a closure that returns itself when called
33
     * @param  callable|string $cb The value that you want to wrap in a closure
34
     * @return callable
35
     */
36 15
    private function wrapValueInClosure($cb) {
37 15
        if (is_callable($cb)) {
38 9
            return $cb;
39
        } else {
40
            return function() use ($cb) { return $cb; };
41
        }
42
    }
43
44
    /**
45
     * Set a string or a closure to be called that will generate the message body for the notification
46
     * @param callable|string $cb A closure or string that will be set for the message
47
     */
48 6
    public function setMessage($cb)
49
    {
50 6
        $this->messageCb = $this->wrapValueInClosure($cb);
51 6
        return $this;
52
    }
53
54
    /**
55
     * Returns the result of the message closure
56
     * @param  Exception $e The Exception instance that you want to build the message around
57
     * @return string       The message string
58
     */
59 15
    public function getMessage(Exception $e) {
60 15
        if (is_callable($this->messageCb)) {
61 6
            return $this->messageCb->__invoke($e);
62
        } else {
63 9
            $msg = get_class($e) . " was thrown! \n" . $e->getMessage();
64 9
            if ($this->config['includeExceptionStackTrace'] === true) {
65 9
                $msg .= "\n\n" . $e->getTraceAsString();
66 9
            }
67 9
            return $msg;
68
        }
69
    }
70
71
    /**
72
     * Set a string or a closure to be called that will generate the subject line for the notification
73
     * @param callable|string $cb A closure or string that will be set for the subject line
74
     */
75 6
    public function setSubject($cb)
76
    {
77 6
        $this->subjectCb = $this->wrapValueInClosure($cb);
78 6
        return $this;
79
    }
80
81
    /**
82
     * Returns the result of the subject closure
83
     * @param  Exception $e The Exception instance that you want to build the subject around
84
     * @return string       The subject string
85
     */
86 15
    public function getSubject(Exception $e) {
87 15
        if (is_callable($this->subjectCb)) {
88 6
            return $this->subjectCb->__invoke($e);
89
        } else {
90 9
            return get_class($e);
91
        }
92
    }
93
94
    /**
95
     * Set an array or a closure to be called that will generate the context array for the notification
96
     * @param callable|array $cb A closure or array that will be set for the context
97
     */
98 3
    public function setContext($cb)
99
    {
100 3
        $this->contextCb = $this->wrapValueInClosure($cb);
101 3
        return $this;
102
    }
103
104
    /**
105
     * Returns the result of the context closure
106
     * @param  Exception $e The Exception instance that you want to build the context around
107
     * @return array        The context array
108
     */
109 12
    public function getContext(Exception $e, $context = []) {
110
111
        //This needs a better solution. How do I specific context needs for different drivers?
112 12
        if (in_array('pushover', $this->config['drivers'])) {
113 12
            $context['sound'] = $this->config['pushover']['sound'];
114 12
        }
115
116
        // Call the callback or return the default
117 12
        if (is_callable($this->contextCb)) {
118 3
            return $this->contextCb->__invoke($e, $context);
1 ignored issue
show
Bug introduced by
The method __invoke cannot be called on $this->contextCb (of type callable).

Methods can only be called on objects. This check looks for methods being called on variables that have been inferred to never be objects.

Loading history...
119
        } else {
120 9
            return $context;
121
        }
122
    }
123
124
    /**
125
     * Pushes on another Monolog Handler
126
     * @param  HandlerInterface $handler The handler instance to add on
127
     * @return Notifier                  Returns this
128
     */
129 6
    public function pushHandler(HandlerInterface $handler) {
130 6
        $this->log->pushHandler($handler);
131 6
        return $this;
132
    }
133
134
    /**
135
     * Triggers the Monolog Logger instance to log an error to all handlers
136
     * @param  Exception $e The exception to use
137
     * @param  array $context Additional information that you would like to pass to Monolog
138
     * @return bool
139
     */
140 12
    public function send(Exception $e, array $context = []) {
141
        
142 12
        if ($this->shouldntHandle($e)) {
143 3
            return false;
144
        }
145
146 9
        $message = $this->getMessage($e);
147 9
        $subject = $this->getSubject($e);
148 9
        $context = $this->getContext($e, $context);
149
        
150
        try {
151 9
            $notify = new Notify($this->config, $this->log, $subject);
152
153 9
            $notify->critical($message, $context);
154
155 6
            return true;
156 3
        } catch (Exception $e) {
157 3
            $code = (is_int($e->getCode()) ? $e->getCode() : 0);
158 3
            throw new NotifierFailedException($e->getMessage(), $code, $e);
159
        }
160
    }
161
}