1
<?php
2
/**
3
 * Copyright (c) 2012-2013, Laurent Laville <pear@laurent-laville.org>
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 <pear@laurent-laville.org>
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 <pear@laurent-laville.org>
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 2
    public function __construct(Net_Growl $growl = null)
75
    {
76 2
        parent::__construct();
77 2
        $this->growl = $growl;
78
    }
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 2
    public function init()
88
    {
89 2
        $autoloader = 'Net/Growl/Autoload.php';
90

91 2
        if (!$handle = @fopen($autoloader, 'r', true)) {
92 0
            throw new BuildException(
93 0
                'The Growl Notify task requires the pear/net_growl package.'
94
            );
95
        }
96

97 2
        fclose($handle);
98 2
        include_once $autoloader;
99

100 2
        $this->setTaskName('GrowlNotify');
101 2
        $this->setName();
102 2
        $this->setSticky(false);
103 2
        $this->setMessage();
104 2
        $this->setTitle();
105 2
        $this->setNotification();
106 2
        $this->setAppicon();
107 2
        $this->setHost();
108 2
        $this->setPassword();
109 2
        $this->setPriority();
110 2
        $this->setProtocol();
111 2
        $this->setIcon();
112
    }
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 2
    public function setName($name = '')
125
    {
126 2
        if ('' == $name) {
127 2
            $name = 'Growl for Phing';
128
        }
129

130 2
        if (!is_string($name)) {
131 0
            throw new BuildException(
132
                '"name" attribute is invalid.' .
133 0
                ' Expect to be a string, actual is ' . gettype($name)
134
            );
135
        }
136

137 2
        $this->name = $name;
138
    }
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 2
    public function setSticky(bool $sticky = true)
148
    {
149 2
        $this->sticky = $sticky;
150
    }
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 2
    public function setMessage($message = '')
162
    {
163 2
        if (!is_string($message)) {
164 0
            throw new BuildException(
165
                '"message" attribute is invalid.' .
166 0
                ' Expect to be a string, actual is ' . gettype($message)
167
            );
168
        }
169

170 2
        $this->message = $message;
171
    }
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 2
    public function setTitle($title = '')
184
    {
185 2
        if ('' == $title) {
186 2
            $title = 'GrowlNotify';
187
        }
188

189 2
        if (!is_string($title)) {
190 0
            throw new BuildException(
191
                '"title" attribute is invalid.' .
192 0
                ' Expect to be a string, actual is ' . gettype($title)
193
            );
194
        }
195

196 2
        $this->title = $title;
197
    }
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 2
    public function setNotification($notification = '')
209
    {
210 2
        if ('' == $notification) {
211 2
            $notification = 'General Notification';
212
        }
213

214 2
        if (!is_string($notification)) {
215 0
            throw new BuildException(
216
                '"notification" attribute is invalid.' .
217 0
                ' Expect to be a string, actual is ' . gettype($notification)
218
            );
219
        }
220

221 2
        $this->notification = $notification;
222
    }
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 2
    public function setAppicon($icon = '')
240
    {
241 2
        if (!is_string($icon)) {
242 0
            throw new BuildException(
243
                '"appicon" attribute is invalid.' .
244 0
                ' Expect to be a string, actual is ' . gettype($icon)
245
            );
246
        }
247

248
        // relative location
249 2
        if (strpos($icon, '..') === 0) {
250 2
            $icon = realpath(__DIR__ . DIRECTORY_SEPARATOR . $icon);
251 2
        } elseif (strpos($icon, '.') === 0) {
252 0
            $icon = __DIR__ . substr($icon, 1);
253
        }
254

255 2
        $this->appicon = $icon;
256
    }
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 2
    public function setHost($host = '127.0.0.1')
272
    {
273 2
        if (!is_string($host)) {
274 0
            throw new BuildException(
275
                '"host" attribute is invalid.' .
276 0
                ' Expect to be a string, actual is ' . gettype($host)
277
            );
278
        }
279

280 2
        $this->host = $host;
281
    }
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 2
    public function setPassword($password = '')
297
    {
298 2
        if (!is_string($password)) {
299 0
            throw new BuildException(
300
                '"password" attribute is invalid.' .
301 0
                ' Expect to be a string, actual is ' . gettype($password)
302
            );
303
        }
304

305 2
        $this->password = $password;
306
    }
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 2
    public function setPriority($priority = '')
321
    {
322 2
        if ('' == $priority) {
323 2
            $priority = 'normal';
324
        }
325

326 2
        switch ($priority) {
327 2
            case 'low':
328 0
                $priority = Net_Growl::PRIORITY_LOW;
329 0
                break;
330 2
            case 'moderate':
331 0
                $priority = Net_Growl::PRIORITY_MODERATE;
332 0
                break;
333 2
            case 'normal':
334 2
                $priority = Net_Growl::PRIORITY_NORMAL;
335 2
                break;
336 2
            case 'high':
337 2
                $priority = Net_Growl::PRIORITY_HIGH;
338 2
                break;
339 0
            case 'emergency':
340 0
                $priority = Net_Growl::PRIORITY_EMERGENCY;
341 0
                break;
342
            default:
343 0
                throw new BuildException(
344 0
                    '"priority" attribute is invalid.'
345
                );
346
        }
347

348 2
        $this->priority = $priority;
349
    }
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 2
    public function setProtocol($protocol = '')
365
    {
366 2
        if ('' == $protocol) {
367 2
            $protocol = 'gntp';
368
        }
369

370 2
        switch ($protocol) {
371 2
            case 'udp':
372 2
            case 'gntp':
373 2
                break;
374
            default:
375 0
                throw new BuildException(
376
                    '"protocol" attribute is invalid.' .
377 0
                    ' Expect to be either udp or gntp.'
378
                );
379
        }
380

381 2
        $this->protocol = $protocol;
382
    }
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 2
    public function setIcon($icon = '')
400
    {
401 2
        if (!is_string($icon)) {
402 0
            throw new BuildException(
403
                '"icon" attribute is invalid.' .
404 0
                ' Expect to be a string, actual is ' . gettype($icon)
405
            );
406
        }
407

408
        // relative location
409 2
        if (strpos($icon, '..') === 0) {
410 2
            $icon = realpath(__DIR__ . DIRECTORY_SEPARATOR . $icon);
411 2
        } elseif (strpos($icon, '.') === 0) {
412 0
            $icon = __DIR__ . substr($icon, 1);
413
        }
414

415 2
        $this->icon = $icon;
416
    }
417

418
    /**
419
     * The main entry point method
420
     *
421
     * @return void
422
     * @throws BuildException
423
     */
424 2
    public function main()
425
    {
426 2
        if (empty($this->message)) {
427 2
            throw new BuildException(
428 2
                '"message" attribute cannot be empty'
429
            );
430
        }
431

432
        $notifications = [
433 2
            $this->notification
434
        ];
435
        $options = [
436 2
            'host' => $this->host,
437 2
            'protocol' => $this->protocol,
438
        ];
439 2
        if (!empty($this->appicon)) {
440 0
            $options['AppIcon'] = $this->appicon;
441
        }
442

443
        try {
444 2
            if ($this->growl instanceof Net_Growl) {
445 2
                $growl = $this->growl;
446
            } else {
447 2
                $growl = Net_Growl::singleton(
448 2
                    $this->name,
449
                    $notifications,
450 2
                    $this->password,
451
                    $options
452
                );
453
            }
454 2
            $response = $growl->register();
455

456 2
            if ($this->protocol == 'gntp') {
457 2
                if ($response->getStatus() != 'OK') {
458 0
                    throw new BuildException(
459 0
                        'Growl Error ' . $response->getErrorCode() .
460 0
                        ' - ' . $response->getErrorDescription()
461
                    );
462
                }
463
            }
464 2
            $this->log(
465 2
                'Application ' . $this->name . ' registered',
466 2
                Project::MSG_VERBOSE
467
            );
468

469
            $logRequest = [
470 2
                'Application-Name' => $this->name,
471 2
                'Application-Icon' => $this->appicon,
472 2
                'Notification-Name' => $this->notification,
473 2
                'Notification-Title' => $this->title,
474 2
                'Notification-Text' => $this->message,
475 2
                'Notification-Priority' => $this->priority,
476 2
                'Notification-Icon' => $this->icon,
477 2
                'Notification-Sticky' => $this->sticky,
478
            ];
479 2
            foreach ($logRequest as $key => $value) {
480 2
                $this->log($key . ': ' . $value, Project::MSG_DEBUG);
481
            }
482

483
            $options = [
484 2
                'sticky' => $this->sticky,
485 2
                'priority' => $this->priority,
486 2
                'icon' => $this->icon,
487
            ];
488 2
            $response = $growl->publish(
489 2
                $this->notification,
490 2
                $this->title,
491 2
                $this->message,
492
                $options
493
            );
494

495 2
            if ($this->protocol == 'gntp') {
496 2
                if ($response->getStatus() != 'OK') {
497 0
                    throw new BuildException(
498 0
                        'Growl Error ' . $response->getErrorCode() .
499 0
                        ' - ' . $response->getErrorDescription()
500
                    );
501
                }
502
            }
503 2
            $this->log('Notification was sent to remote host ' . $this->host);
504 0
        } catch (Net_Growl_Exception $e) {
505 0
            throw new BuildException(
506 0
                'Growl Exception : ' . $e->getMessage()
507
            );
508
        }
509
    }
510
}

Read our documentation on viewing source code .

Loading