Completed
Pull Request — master (#12)
by Tyler
03:55
created

Notifier   A

Complexity

Total Complexity 18

Size/Duplication

Total Lines 139
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 4

Test Coverage

Coverage 98.11%

Importance

Changes 6
Bugs 0 Features 4
Metric Value
wmc 18
c 6
b 0
f 4
lcom 1
cbo 4
dl 0
loc 139
ccs 52
cts 53
cp 0.9811
rs 10

9 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 0 9 2
A wrapValueInClosure() 0 7 2
A setMessage() 0 5 1
A getMessage() 0 11 3
A setSubject() 0 5 1
A getSubject() 0 7 2
A pushHandler() 0 4 1
B send() 0 26 4
A buildContext() 0 6 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 42
    public function __construct(Logger $log = null) {
23 42
        if ($log === null) {
24 42
            $log = new Logger(config('lern.notify.channel'));
25 42
        }
26
27 42
        $this->log = $log;
28 42
        $this->config = config('lern.notify');
29 42
        $this->drivers = $this->config['drivers'];
30 42
    }
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);
1 ignored issue
show
Bug introduced by
The method __invoke cannot be called on $this->messageCb (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...
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);
1 ignored issue
show
Bug introduced by
The method __invoke cannot be called on $this->subjectCb (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...
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 6
    public function send(Exception $e, array $context = []) {
1 ignored issue
show
Unused Code introduced by
The parameter $e is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
112
        try{
113 6
            if($this->shouldntHandle($e)){
114
                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 6
            foreach ($drivers as $driver) {
124 6
                $handler = $factory->create($driver, $subject);
125 6
                $this->log->pushHandler($handler);
126 6
            }
127
128 6
            $context = $this->buildContext($context);
129
130 6
            $this->log->addCritical($message, $context);
131
132 3
            return true;
133 3
        } catch (Exception $e) {
134 3
            throw new NotifierFailedException($e->getMessage(), $e->getCode(), $e);
135
        }
136
    }
137
138
    /**
139
     * Builds a context array to pass to Monolog
140
     * @param  array  $context Additional information that you would like to pass to Monolog
141
     * @return array           The modified context array
142
     */
143 6
    protected function buildContext(array $context = []){
144 6
        if(in_array('pushover', $this->drivers)){
145 6
            $context['sound'] = $this->config['pushover']['sound'];
146 6
        }
147 6
        return $context;
148
    }
149
}