Completed
Push — master ( 681b8e...92c3fc )
by Tyler
8s
created

Notifier::__construct()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 9
Code Lines 6

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 8
CRAP Score 2

Importance

Changes 2
Bugs 0 Features 1
Metric Value
c 2
b 0
f 1
dl 0
loc 9
ccs 8
cts 8
cp 1
rs 9.6666
cc 2
eloc 6
nc 2
nop 1
crap 2
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\Factories\MonologHandlerFactory;
9
use Tylercd100\LERN\Exceptions\NotifierFailedException;
10
11
class Notifier extends Component {
12
    protected $config;
13
    protected $log;
14
    protected $messageCb;
15
    protected $subjectCb;
16
    protected $drivers;
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 48
    public function __construct(Logger $log = null) {
23 48
        if ($log === null) {
24 48
            $log = new Logger(config('lern.notify.channel'));
25 48
        }
26
27 48
        $this->log = $log;
28 48
        $this->config = config('lern.notify');
29 48
        $this->drivers = $this->config['drivers'];
30 48
    }
31
32
    /**
33
     * Transforms a value into a closure that returns itself when called
34
     * @param  callable|string $cb The value that you want to wrap in a closure
35
     * @return callable
36
     */
37 12
    private function wrapValueInClosure($cb) {
38 12
        if (is_callable($cb)) {
39 6
            return $cb;
40
        } else {
41
            return function() use ($cb) { return $cb; };
42
        }
43
    }
44
45
    /**
46
     * Set a string or a closure to be called that will generate the message body for the notification
47
     * @param callable|string $cb A closure or string that will be set for the message
48
     */
49 6
    public function setMessage($cb)
50
    {
51 6
        $this->messageCb = $this->wrapValueInClosure($cb);
52 6
        return $this;
53
    }
54
55
    /**
56
     * Returns the result of the message closure
57
     * @param  Exception $e The Exception instance that you want to build the message around
58
     * @return string       The message string
59
     */
60 12
    public function getMessage(Exception $e) {
61 12
        if (is_callable($this->messageCb)) {
62 6
            return $this->messageCb->__invoke($e);
63
        } else {
64 6
            $msg = get_class($e) . " was thrown! \n" . $e->getMessage();
65 6
            if ($this->config['includeExceptionStackTrace'] === true) {
66 6
                $msg .= "\n\n" . $e->getTraceAsString();
67 6
            }
68 6
            return $msg;
69
        }
70
    }
71
72
    /**
73
     * Set a string or a closure to be called that will generate the subject line for the notification
74
     * @param callable|string $cb A closure or string that will be set for the subject line
75
     */
76 6
    public function setSubject($cb)
77
    {
78 6
        $this->subjectCb = $this->wrapValueInClosure($cb);
79 6
        return $this;
80
    }
81
82
    /**
83
     * Returns the result of the subject closure
84
     * @param  Exception $e The Exception instance that you want to build the subject around
85
     * @return string       The subject string
86
     */
87 12
    public function getSubject(Exception $e) {
88 12
        if (is_callable($this->subjectCb)) {
89 6
            return $this->subjectCb->__invoke($e);
90
        } else {
91 6
            return get_class($e);
92
        }
93
    }
94
95
    /**
96
     * Pushes on another Monolog Handler
97
     * @param  HandlerInterface $handler The handler instance to add on
98
     * @return Notifier                  Returns this
99
     */
100 6
    public function pushHandler(HandlerInterface $handler) {
101 6
        $this->log->pushHandler($handler);
102 6
        return $this;
103
    }
104
105
    /**
106
     * Triggers the Monolog Logger instance to log an error to all handlers
107
     * @param  Exception $e The exception to use
108
     * @param  array $context Additional information that you would like to pass to Monolog
109
     * @return bool
110
     */
111 9
    public function send(Exception $e, array $context = []) {
112
        
113 9
        if($this->shouldntHandle($e)){
114 3
            return false;
115
        }
116
117 6
        $factory = new MonologHandlerFactory();
118 6
        $drivers = $this->drivers;
119
120 6
        $message = $this->getMessage($e);
121 6
        $subject = $this->getSubject($e);
122
        
123
        try{
124 6
            foreach ($drivers as $driver) {
125 6
                $handler = $factory->create($driver, $subject);
126 6
                $this->log->pushHandler($handler);
127 6
            }
128
129 6
            $context = $this->buildContext($context);
130
131 6
            $this->log->addCritical($message, $context);
132
133 3
            return true;
134 3
        } catch (Exception $e) {
135 3
            throw new NotifierFailedException($e->getMessage(), $e->getCode(), $e);
136
        }
137
    }
138
139
    /**
140
     * Builds a context array to pass to Monolog
141
     * @param  array  $context Additional information that you would like to pass to Monolog
142
     * @return array           The modified context array
143
     */
144 6
    protected function buildContext(array $context = []){
145 6
        if(in_array('pushover', $this->drivers)){
146 6
            $context['sound'] = $this->config['pushover']['sound'];
147 6
        }
148 6
        return $context;
149
    }
150
}