Passed
Push — master ( 30bcbc...eba4fe )
by Siad
06:53
created

GrowlNotifyTask::setProtocol()   A

Complexity

Conditions 4
Paths 6

Size

Total Lines 18
Code Lines 11

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 8
CRAP Score 4.128

Importance

Changes 0
Metric Value
cc 4
eloc 11
nc 6
nop 1
dl 0
loc 18
ccs 8
cts 10
cp 0.8
crap 4.128
rs 9.9
c 0
b 0
f 0
1
<?php
2
/**
3
 * Copyright (c) 2012-2013, Laurent Laville <[email protected]>
4
 *
5
 * All rights reserved.
6
 *
7
 * Redistribution and use in source and binary forms, with or without
8
 * modification, are permitted provided that the following conditions
9
 * are met:
10
 *
11
 *     * Redistributions of source code must retain the above copyright
12
 *       notice, this list of conditions and the following disclaimer.
13
 *     * Redistributions in binary form must reproduce the above copyright
14
 *       notice, this list of conditions and the following disclaimer in the
15
 *       documentation and/or other materials provided with the distribution.
16
 *     * Neither the name of the authors nor the names of its contributors
17
 *       may be used to endorse or promote products derived from this software
18
 *       without specific prior written permission.
19
 *
20
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
21
 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
22
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
23
 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
24
 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
25
 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
26
 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
27
 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
28
 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
29
 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
30
 * POSSIBILITY OF SUCH DAMAGE.
31
 *
32
 * PHP version 5
33
 *
34
 * @category Tasks
35
 * @package  phing.tasks.ext
36
 * @author   Laurent Laville <[email protected]>
37
 * @license  http://www.opensource.org/licenses/bsd-license.php  BSD License
38
 * @link     https://github.com/llaville/phing-GrowlNotifyTask
39
 */
40
41
42
/**
43
 * Growl notification task for Phing, the PHP build tool.
44
 *
45
 * PHP version 5
46
 *
47
 * @category Tasks
48
 * @package  phing.tasks.ext
49
 * @author   Laurent Laville <[email protected]>
50
 * @license  http://www.opensource.org/licenses/bsd-license.php  BSD License
51
 * @link     https://github.com/llaville/phing-GrowlNotifyTask
52
 */
53
class GrowlNotifyTask extends Task
54
{
55
    protected $growl;
56
57
    protected $name;
58
    protected $sticky;
59
    protected $message;
60
    protected $title;
61
    protected $notification;
62
    protected $appicon;
63
    protected $host;
64
    protected $password;
65
    protected $priority;
66
    protected $protocol;
67
    protected $icon;
68
69
    /**
70
     * Initializes task with default options
71
     *
72
     * @param Net_Growl $growl (optional) mock instance
73
     */
74 14
    public function __construct(Net_Growl $growl = null)
75
    {
76 14
        parent::__construct();
77 14
        $this->growl = $growl;
78 14
    }
79
80
    /**
81
     * The init method check if Net_Growl is available
82
     * (exists and can be loaded)
83
     *
84
     * @return void
85
     * @throws BuildException
86
     */
87 6
    public function init()
88
    {
89 6
        $autoloader = 'Net/Growl/Autoload.php';
90
91 6
        if (!$handle = @fopen($autoloader, 'r', true)) {
92
            throw new BuildException(
93
                'The Growl Notify task requires the Net_Growl PEAR package.'
94
            );
95
        }
96
97 6
        fclose($handle);
98 6
        include_once $autoloader;
99
100 6
        $this->setTaskName('GrowlNotify');
101 6
        $this->setName();
102 6
        $this->setSticky(false);
103 6
        $this->setMessage();
104 6
        $this->setTitle();
105 6
        $this->setNotification();
106 6
        $this->setAppicon();
107 6
        $this->setHost();
108 6
        $this->setPassword();
109 6
        $this->setPriority();
110 6
        $this->setProtocol();
111 6
        $this->setIcon();
112 6
    }
113
114
    /**
115
     * Defines the name of the application sending the notification
116
     *
117
     * @param string $name (optional) Name of the application
118
     *                     that appears in your Growl preferences
119
     *                     Default: "Growl for Phing"
120
     *
121
     * @return void
122
     * @throws BuildException
123
     */
124 6
    public function setName($name = '')
125
    {
126 6
        if ('' == $name) {
127 6
            $name = 'Growl for Phing';
128
        }
129
130 6
        if (!is_string($name)) {
0 ignored issues
show
introduced by
The condition is_string($name) is always true.
Loading history...
131
            throw new BuildException(
132
                '"name" attribute is invalid.' .
133
                ' Expect to be a string, actual is ' . gettype($name)
134
            );
135
        }
136
137 6
        $this->name = $name;
138 6
    }
139
140
    /**
141
     * Indicates if the notification should be sticky
142
     *
143
     * @param bool $sticky (optional) Notification should be sticky
144
     *
145
     * @return void
146
     */
147 7
    public function setSticky(bool $sticky = true)
148
    {
149 7
        $this->sticky = $sticky;
150 7
    }
151
152
    /**
153
     * The notification's text is required.
154
     * Use \n to specify a line break.
155
     *
156
     * @param string $message Notification's text
157
     *
158
     * @return void
159
     * @throws BuildException
160
     */
161 14
    public function setMessage($message = '')
162
    {
163 14
        if (!is_string($message)) {
0 ignored issues
show
introduced by
The condition is_string($message) is always true.
Loading history...
164
            throw new BuildException(
165
                '"message" attribute is invalid.' .
166
                ' Expect to be a string, actual is ' . gettype($message)
167
            );
168
        }
169
170 14
        $this->message = $message;
171 14
    }
172
173
    /**
174
     * The notification's title.
175
     * Use \n to specify a line break.
176
     *
177
     * @param string $title (optional) Notification's title
178
     *                      Default: GrowlNotify
179
     *
180
     * @return void
181
     * @throws BuildException
182
     */
183 7
    public function setTitle($title = '')
184
    {
185 7
        if ('' == $title) {
186 6
            $title = 'GrowlNotify';
187
        }
188
189 7
        if (!is_string($title)) {
0 ignored issues
show
introduced by
The condition is_string($title) is always true.
Loading history...
190
            throw new BuildException(
191
                '"title" attribute is invalid.' .
192
                ' Expect to be a string, actual is ' . gettype($title)
193
            );
194
        }
195
196 7
        $this->title = $title;
197 7
    }
198
199
    /**
200
     * The notification name/type
201
     *
202
     * @param string $notification Name/type
203
     *                             Default: "General Notification"
204
     *
205
     * @return void
206
     * @throws BuildException
207
     */
208 7
    public function setNotification($notification = '')
209
    {
210 7
        if ('' == $notification) {
211 6
            $notification = 'General Notification';
212
        }
213
214 7
        if (!is_string($notification)) {
0 ignored issues
show
introduced by
The condition is_string($notification) is always true.
Loading history...
215
            throw new BuildException(
216
                '"notification" attribute is invalid.' .
217
                ' Expect to be a string, actual is ' . gettype($notification)
218
            );
219
        }
220
221 7
        $this->notification = $notification;
222 7
    }
223
224
    /**
225
     * The icon of the application being registered.
226
     *
227
     * Must be a valid file type (png, jpg, gif, ico).
228
     * Can be any of the following:
229
     *  - absolute url (http://domain/image.png)
230
     *  - absolute file path (c:\temp\image.png)
231
     *  - relative file path (.\folder\image.png) (relative file paths must start
232
     *    with a dot and are relative to GrowlNotify's phing task location
233
     *
234
     * @param string $icon Icon of the application
235
     *
236
     * @return void
237
     * @throws BuildException
238
     */
239 8
    public function setAppicon($icon = '')
240
    {
241 8
        if (!is_string($icon)) {
0 ignored issues
show
introduced by
The condition is_string($icon) is always true.
Loading history...
242
            throw new BuildException(
243
                '"appicon" attribute is invalid.' .
244
                ' Expect to be a string, actual is ' . gettype($icon)
245
            );
246
        }
247
248
        // relative location
249 8
        if (strpos($icon, '..') === 0) {
250 2
            $icon = realpath(__DIR__ . DIRECTORY_SEPARATOR . $icon);
251 6
        } elseif (strpos($icon, '.') === 0) {
252
            $icon = __DIR__ . substr($icon, 1);
253
        }
254
255 8
        $this->appicon = $icon;
256 8
    }
257
258
    /**
259
     * The host address to send the notification to.
260
     *
261
     * If any value other than 'localhost' or '127.0.0.1' is provided, the host
262
     * is considered a remote host and the "pass" attribute must also be provided.
263
     * Default: 127.0.0.1
264
     *
265
     * @param string $host Remote host name/ip
266
     *                     Default: 127.0.0.1
267
     *
268
     * @return void
269
     * @throws BuildException
270
     */
271 7
    public function setHost($host = '127.0.0.1')
272
    {
273 7
        if (!is_string($host)) {
0 ignored issues
show
introduced by
The condition is_string($host) is always true.
Loading history...
274
            throw new BuildException(
275
                '"host" attribute is invalid.' .
276
                ' Expect to be a string, actual is ' . gettype($host)
277
            );
278
        }
279
280 7
        $this->host = $host;
281 7
    }
282
283
    /**
284
     * The password required to send notifications.
285
     *
286
     * A password is required to send a request to a remote host. If host attribute
287
     * is specified and is any value other than 'localhost' or '127.0.0.1',
288
     * then "pass" attribute is also required.
289
     * Default: no password
290
     *
291
     * @param string $password Password to send request to a remote host
292
     *
293
     * @return void
294
     * @throws BuildException
295
     */
296 6
    public function setPassword($password = '')
297
    {
298 6
        if (!is_string($password)) {
0 ignored issues
show
introduced by
The condition is_string($password) is always true.
Loading history...
299
            throw new BuildException(
300
                '"password" attribute is invalid.' .
301
                ' Expect to be a string, actual is ' . gettype($password)
302
            );
303
        }
304
305 6
        $this->password = $password;
306 6
    }
307
308
    /**
309
     * The notification priority.
310
     *
311
     * Valid values are : low, moderate, normal, high, emergency
312
     * Default: normal
313
     *
314
     * @param string $priority Notification priority
315
     *                         Default: normal
316
     *
317
     * @return void
318
     * @throws BuildException
319
     */
320 7
    public function setPriority($priority = '')
321
    {
322 7
        if ('' == $priority) {
323 6
            $priority = 'normal';
324
        }
325
326 7
        switch ($priority) {
327 7
            case 'low':
328
                $priority = Net_Growl::PRIORITY_LOW;
329
                break;
330 7
            case 'moderate':
331
                $priority = Net_Growl::PRIORITY_MODERATE;
332
                break;
333 7
            case 'normal':
334 6
                $priority = Net_Growl::PRIORITY_NORMAL;
335 6
                break;
336 1
            case 'high':
337 1
                $priority = Net_Growl::PRIORITY_HIGH;
338 1
                break;
339
            case 'emergency':
340
                $priority = Net_Growl::PRIORITY_EMERGENCY;
341
                break;
342
            default:
343
                throw new BuildException(
344
                    '"priority" attribute is invalid.'
345
                );
346
        }
347
348 7
        $this->priority = $priority;
349 7
    }
350
351
    /**
352
     * The protocol (and port) to send the notification to.
353
     *
354
     * With TCP (GNTP) protocol, port is always 23053
355
     * With UDP protocol, port is always 9887
356
     * Default: 23053
357
     *
358
     * @param string $protocol Protocol to use to send request to remote host
359
     *                         Default: gntp
360
     *
361
     * @return void
362
     * @throws BuildException
363
     */
364 6
    public function setProtocol($protocol = '')
365
    {
366 6
        if ('' == $protocol) {
367 6
            $protocol = 'gntp';
368
        }
369
370 6
        switch ($protocol) {
371 6
            case 'udp':
372 6
            case 'gntp':
373 6
                break;
374
            default:
375
                throw new BuildException(
376
                    '"protocol" attribute is invalid.' .
377
                    ' Expect to be either udp or gntp.'
378
                );
379
        }
380
381 6
        $this->protocol = $protocol;
382 6
    }
383
384
    /**
385
     * The icon to show for the notification.
386
     *
387
     * Must be a valid file type (png, jpg, gif, ico).
388
     * Can be any of the following:
389
     *  - absolute url (http://domain/image.png)
390
     *  - absolute file path (c:\temp\image.png)
391
     *  - relative file path (.\folder\image.png) (relative file paths must start
392
     *    with a dot and are relative to GrowlNotify's phing task location
393
     *
394
     * @param string $icon Icon of the message
395
     *
396
     * @return void
397
     * @throws BuildException
398
     */
399 7
    public function setIcon($icon = '')
400
    {
401 7
        if (!is_string($icon)) {
0 ignored issues
show
introduced by
The condition is_string($icon) is always true.
Loading history...
402
            throw new BuildException(
403
                '"icon" attribute is invalid.' .
404
                ' Expect to be a string, actual is ' . gettype($icon)
405
            );
406
        }
407
408
        // relative location
409 7
        if (strpos($icon, '..') === 0) {
410 1
            $icon = realpath(__DIR__ . DIRECTORY_SEPARATOR . $icon);
411 6
        } elseif (strpos($icon, '.') === 0) {
412
            $icon = __DIR__ . substr($icon, 1);
413
        }
414
415 7
        $this->icon = $icon;
416 7
    }
417
418
    /**
419
     * The main entry point method
420
     *
421
     * @return void
422
     * @throws BuildException
423
     */
424 14
    public function main()
425
    {
426 14
        if (empty($this->message)) {
427 1
            throw new BuildException(
428 1
                '"message" attribute cannot be empty'
429
            );
430
        }
431
432
        $notifications = [
433 13
            $this->notification
434
        ];
435
        $options = [
436 13
            'host' => $this->host,
437 13
            'protocol' => $this->protocol,
438
        ];
439 13
        if (!empty($this->appicon)) {
440
            $options['AppIcon'] = $this->appicon;
441
        }
442
443
        try {
444 13
            if ($this->growl instanceof Net_Growl) {
445 8
                $growl = $this->growl;
446
            } else {
447 5
                $growl = Net_Growl::singleton(
448 5
                    $this->name,
449 5
                    $notifications,
450 5
                    $this->password,
451 5
                    $options
452
                );
453
            }
454 13
            $response = $growl->register();
455
456 13
            if ($this->protocol == 'gntp') {
457 5
                if ($response->getStatus() != 'OK') {
458
                    throw new BuildException(
459
                        'Growl Error ' . $response->getErrorCode() .
460
                        ' - ' . $response->getErrorDescription()
461
                    );
462
                }
463
            }
464 13
            $this->log(
465 13
                'Application ' . $this->name . ' registered',
466 13
                Project::MSG_VERBOSE
467
            );
468
469
            $logRequest = [
470 13
                'Application-Name' => $this->name,
471 13
                'Application-Icon' => $this->appicon,
472 13
                'Notification-Name' => $this->notification,
473 13
                'Notification-Title' => $this->title,
474 13
                'Notification-Text' => $this->message,
475 13
                'Notification-Priority' => $this->priority,
476 13
                'Notification-Icon' => $this->icon,
477 13
                'Notification-Sticky' => $this->sticky,
478
            ];
479 13
            foreach ($logRequest as $key => $value) {
480 13
                $this->log($key . ': ' . $value, Project::MSG_DEBUG);
481
            }
482
483
            $options = [
484 13
                'sticky' => $this->sticky,
485 13
                'priority' => $this->priority,
486 13
                'icon' => $this->icon,
487
            ];
488 13
            $response = $growl->publish(
489 13
                $this->notification,
490 13
                $this->title,
491 13
                $this->message,
492 13
                $options
0 ignored issues
show
Bug introduced by
$options of type array is incompatible with the type string expected by parameter $options of Net_Growl::publish(). ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

492
                /** @scrutinizer ignore-type */ $options
Loading history...
493
            );
494
495 13
            if ($this->protocol == 'gntp') {
496 5
                if ($response->getStatus() != 'OK') {
497
                    throw new BuildException(
498
                        'Growl Error ' . $response->getErrorCode() .
499
                        ' - ' . $response->getErrorDescription()
500
                    );
501
                }
502
            }
503 13
            $this->log('Notification was sent to remote host ' . $this->host);
504
        } catch (Net_Growl_Exception $e) {
505
            throw new BuildException(
506
                'Growl Exception : ' . $e->getMessage()
507
            );
508
        }
509 13
    }
510
}
511