Completed
Push — master ( dc6cb9...681b8e )
by Tyler
06:24
created

MonologHandlerFactory::checkSubject()   A

Complexity

Conditions 3
Paths 3

Size

Total Lines 9
Code Lines 5

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 6
CRAP Score 3

Importance

Changes 1
Bugs 0 Features 0
Metric Value
c 1
b 0
f 0
dl 0
loc 9
rs 9.6666
ccs 6
cts 6
cp 1
cc 3
eloc 5
nc 3
nop 1
crap 3
1
<?php
2
3
namespace Tylercd100\LERN\Factories;
4
5
use Exception;
6
use Monolog\Logger;
7
use Mail;
8
use Swift_Message;
9
10
class MonologHandlerFactory {
11
12
    protected $config;
13
14
    /**
15
     * Creates a handler for a specified driver
16
     * @param  string $driver                    Lowercase driver string that is also in the config/lern.php file
17
     * @param  string $subject                   Title or Subject line for the notification
18
     * @return \Monolog\Handler\HandlerInterface A handler to use with a Monolog\Logger instance
19
     */
20 30
    public function create($driver, $subject = null)
21
    {
22 30
        $this->config = config('lern.notify.' . $driver);
23 30
        if (is_array($this->config)) {
24 27
            return $this->{$driver}($subject);
25
        } else {
26 3
            throw new Exception("config must be an array! You may have chosen an unsupported monolog handler.");
27
        }
28
    }
29
30
    /**
31
     * Creates FleepHook Monolog Handler
32
     * @return \Monolog\Handler\FleepHookHandler A handler to use with a Monolog\Logger instance
33
     */
34 6
    protected function fleephook() {
35 6
        return new \Monolog\Handler\FleepHookHandler(
36 6
            $this->config['token']
37 6
        );
38
    }
39
40
    /**
41
     * Creates HipChat Monolog Handler
42
     * @return \Monolog\Handler\HipChatHandler A handler to use with a Monolog\Logger instance
43
     */
44 6
    protected function hipchat() {
45 6
        return new \Monolog\Handler\HipChatHandler(
46 6
            $this->config['token'],
47 6
            $this->config['room'],
48 6
            $this->config['name'],
49 6
            $this->config['notify'],
50 6
            Logger::CRITICAL,
51 6
            true, 
52 6
            true, 
53 6
            'text', 
54 6
            'api.hipchat.com', 
55
            'v2'
56 6
        );
57
    }
58
59
    /**
60
     * Creates Flowdock Monolog Handler
61
     * @return \Monolog\Handler\FlowdockHandler A handler to use with a Monolog\Logger instance
62
     */
63 6
    protected function flowdock() {
64 6
        return new \Monolog\Handler\FlowdockHandler(
65 6
            $this->config['token']
66 6
        );
67
    }
68
69
    /**
70
     * Creates Pushover Monolog Handler
71
     * @param  string $subject  Title or Subject line for the notification
72
     * @return \Monolog\Handler\PushoverHandler A handler to use with a Monolog\Logger instance
73
     */
74 9
    protected function pushover($subject)
75
    {
76 9
        $this->checkSubject($subject);
77 9
        return new \Monolog\Handler\PushoverHandler(
78 9
            $this->config['token'],
79 9
            $this->config['user'],
80
            $subject
81 9
        );
82
    }
83
84
    /**
85
     * Creates Mail Monolog Handler
86
     * @param  string $subject Title or Subject line for the notification
87
     * @return \Monolog\Handler\NativeMailerHandler A handler to use with a Monolog\Logger instance
88
     */
89 21
    protected function mail($subject)
90
    {
91 21
        $this->checkSubject($subject);
92 15
        if ($this->config['smtp']) {
93 12
            return new \Monolog\Handler\SwiftMailerHandler(
0 ignored issues
show
Bug Best Practice introduced by
The return type of return new \Monolog\Hand...($this->config['to'])); (Monolog\Handler\SwiftMailerHandler) is incompatible with the return type documented by Tylercd100\LERN\Factorie...logHandlerFactory::mail of type Monolog\Handler\NativeMailerHandler.

If you return a value from a function or method, it should be a sub-type of the type that is given by the parent type f.e. an interface, or abstract method. This is more formally defined by the Lizkov substitution principle, and guarantees that classes that depend on the parent type can use any instance of a child type interchangably. This principle also belongs to the SOLID principles for object oriented design.

Let’s take a look at an example:

class Author {
    private $name;

    public function __construct($name) {
        $this->name = $name;
    }

    public function getName() {
        return $this->name;
    }
}

abstract class Post {
    public function getAuthor() {
        return 'Johannes';
    }
}

class BlogPost extends Post {
    public function getAuthor() {
        return new Author('Johannes');
    }
}

class ForumPost extends Post { /* ... */ }

function my_function(Post $post) {
    echo strtoupper($post->getAuthor());
}

Our function my_function expects a Post object, and outputs the author of the post. The base class Post returns a simple string and outputting a simple string will work just fine. However, the child class BlogPost which is a sub-type of Post instead decided to return an object, and is therefore violating the SOLID principles. If a BlogPost were passed to my_function, PHP would not complain, but ultimately fail when executing the strtoupper call in its body.

Loading history...
94 12
                Mail::getSwiftMailer(),
95 12
                Swift_Message::newInstance($subject)->setFrom($this->config['from'])->setTo($this->config['to'])
96 12
            );
97
        } else {
98 3
            return new \Monolog\Handler\NativeMailerHandler(
99 3
                $this->config['to'],
100 3
                $subject,
101 3
                $this->config['from']
102 3
            );
103
        }
104
    }
105
106
    /**
107
     * Creates Slack Monolog Handler
108
     * @return \Monolog\Handler\SlackHandler A handler to use with a Monolog\Logger instance
109
     */
110 12
    protected function slack()
111
    {
112 12
        return new \Monolog\Handler\SlackHandler(
113 12
            $this->config['token'], 
114 12
            $this->config['channel'], 
115 12
            $this->config['username']
116 12
        );
117
    }
118
119
    /**
120
     * Creates Plivo Monolog Handler
121
     * @return \Tylercd100\Monolog\Handler\PlivoHandler A handler to use with a Monolog\Logger instance
122
     */
123 6
    protected function plivo()
124
    {
125 6
        return new \Tylercd100\Monolog\Handler\PlivoHandler(
126 6
            $this->config['token'], 
127 6
            $this->config['auth_id'], 
128 6
            $this->config['from'],
129 6
            $this->config['to']
130 6
        );
131
    }
132
133
    /**
134
     * Creates Twilio Monolog Handler
135
     * @return \Tylercd100\Monolog\Handler\TwilioHandler A handler to use with a Monolog\Logger instance
136
     */
137 6
    protected function twilio()
138
    {
139 6
        return new \Tylercd100\Monolog\Handler\TwilioHandler(
140 6
            $this->config['secret'], 
141 6
            $this->config['sid'], 
142 6
            $this->config['from'],
143 6
            $this->config['to']
144 6
        );
145
    }
146
    /**
147
     * Validates that the subject is an unempty string
148
     * @param  mixed $subject The value to check
149
     * @return void
150
     */
151 24
    private function checkSubject($subject) {
152 24
        if (empty($subject)) {
153 3
            throw new Exception('$subject must not be empty!');
154
        }
155
156 21
        if (!is_string($subject)) {
157 3
            throw new Exception('$subject must be a string!');
158
        }
159
    }
160
}