Aleksander Machniak
2013-03-18 5147eea0a228e6680f0af7b6f9f2f4fe41aa921d
commit | author | age
48e9c1 1 <?php
T 2
3 /**
4  * New Mail Notifier plugin
5  *
6  * Supports three methods of notification:
7  * 1. Basic - focus browser window and change favicon
8  * 2. Sound - play wav file
9  * 3. Desktop - display desktop notification (using webkitNotifications feature,
10  *              supported by Chrome and Firefox with 'HTML5 Notifications' plugin)
11  *
12  * @version @package_version@
13  * @author Aleksander Machniak <alec@alec.pl>
14  *
15  *
16  * Copyright (C) 2011, Kolab Systems AG
17  *
18  * This program is free software; you can redistribute it and/or modify
19  * it under the terms of the GNU General Public License version 2
20  * as published by the Free Software Foundation.
21  *
22  * This program is distributed in the hope that it will be useful,
23  * but WITHOUT ANY WARRANTY; without even the implied warranty of
24  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
25  * GNU General Public License for more details.
26  *
27  * You should have received a copy of the GNU General Public License along
28  * with this program; if not, write to the Free Software Foundation, Inc.,
29  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
30  */
31
32 class newmail_notifier extends rcube_plugin
33 {
34     public $task = 'mail|settings';
35
36     private $rc;
37     private $notified;
6e8f2a 38     private $opt = array();
AM 39     private $exceptions = array();
40
48e9c1 41
T 42     /**
43      * Plugin initialization
44      */
45     function init()
46     {
47         $this->rc = rcmail::get_instance();
48
49         // Preferences hooks
50         if ($this->rc->task == 'settings') {
51             $this->add_hook('preferences_list', array($this, 'prefs_list'));
52             $this->add_hook('preferences_save', array($this, 'prefs_save'));
53         }
54         else { // if ($this->rc->task == 'mail') {
55             // add script when not in ajax and not in frame
a7e8eb 56             if ($this->rc->output->type == 'html' && empty($_REQUEST['_framed'])) {
48e9c1 57                 $this->add_texts('localization/');
T 58                 $this->rc->output->add_label('newmail_notifier.title', 'newmail_notifier.body');
59                 $this->include_script('newmail_notifier.js');
60             }
6e8f2a 61
AM 62             if ($this->rc->action == 'refresh') {
63                 // Load configuration
64                 $this->load_config();
65
66                 $this->opt['basic']   = $this->rc->config->get('newmail_notifier_basic');
67                 $this->opt['sound']   = $this->rc->config->get('newmail_notifier_sound');
68                 $this->opt['desktop'] = $this->rc->config->get('newmail_notifier_desktop');
69
70                 if (!empty($this->opt)) {
71                     // Get folders to skip checking for
72                     $exceptions = array('drafts_mbox', 'sent_mbox', 'trash_mbox');
73                     foreach ($exceptions as $folder) {
74                         $folder = $this->rc->config->get($folder);
75                         if (strlen($folder) && $folder != 'INBOX') {
76                             $this->exceptions[] = $folder;
77                         }
78                     }
79
80                     $this->add_hook('new_messages', array($this, 'notify'));
81                 }
82              }
48e9c1 83         }
T 84     }
85
86     /**
87      * Handler for user preferences form (preferences_list hook)
88      */
89     function prefs_list($args)
90     {
91         if ($args['section'] != 'mailbox') {
92             return $args;
93         }
94
95         // Load configuration
96         $this->load_config();
97
98         // Load localization and configuration
99         $this->add_texts('localization/');
100
101         if (!empty($_REQUEST['_framed'])) {
102             $this->rc->output->add_label('newmail_notifier.title', 'newmail_notifier.testbody',
103                 'newmail_notifier.desktopunsupported', 'newmail_notifier.desktopenabled', 'newmail_notifier.desktopdisabled');
104             $this->include_script('newmail_notifier.js');
105         }
106
107         // Check that configuration is not disabled
108         $dont_override = (array) $this->rc->config->get('dont_override', array());
109
110         foreach (array('basic', 'desktop', 'sound') as $type) {
111             $key = 'newmail_notifier_' . $type;
112             if (!in_array($key, $dont_override)) {
113                 $field_id = '_' . $key;
114                 $input    = new html_checkbox(array('name' => $field_id, 'id' => $field_id, 'value' => 1));
115                 $content  = $input->show($this->rc->config->get($key))
116                     . ' ' . html::a(array('href' => '#', 'onclick' => 'newmail_notifier_test_'.$type.'()'),
117                         $this->gettext('test'));
118
119                 $args['blocks']['new_message']['options'][$key] = array(
61be82 120                     'title' => html::label($field_id, rcube::Q($this->gettext($type))),
48e9c1 121                     'content' => $content
T 122                 );
123             }
124         }
125
126         return $args;
127     }
128
129     /**
130      * Handler for user preferences save (preferences_save hook)
131      */
132     function prefs_save($args)
133     {
134         if ($args['section'] != 'mailbox') {
135             return $args;
136         }
137
138         // Load configuration
139         $this->load_config();
140
141         // Check that configuration is not disabled
142         $dont_override = (array) $this->rc->config->get('dont_override', array());
143
144         foreach (array('basic', 'desktop', 'sound') as $type) {
145             $key = 'newmail_notifier_' . $type;
146             if (!in_array($key, $dont_override)) {
61be82 147                 $args['prefs'][$key] = rcube_utils::get_input_value('_'.$key, rcube_utils::INPUT_POST) ? true : false;
48e9c1 148             }
T 149         }
150
151         return $args;
152     }
153
154     /**
155      * Handler for new message action (new_messages hook)
156      */
157     function notify($args)
158     {
6e8f2a 159         // Already notified or unexpected input
AM 160         if ($this->notified || empty($args['diff']['new'])) {
48e9c1 161             return $args;
T 162         }
163
6e8f2a 164         $mbox      = $args['mailbox'];
AM 165         $storage   = $this->rc->get_storage();
166         $delimiter = $storage->get_hierarchy_delimiter();
48e9c1 167
T 168         // Skip exception (sent/drafts) folders (and their subfolders)
169         foreach ($this->exceptions as $folder) {
6e8f2a 170             if (strpos($mbox.$delimiter, $folder.$delimiter) === 0) {
48e9c1 171                 return $args;
T 172             }
173         }
174
6e8f2a 175         // Check if any of new messages is UNSEEN
AM 176         $deleted = $this->rc->config->get('skip_deleted') ? 'UNDELETED ' : '';
177         $search  = $deleted . 'UNSEEN UID ' . $args['diff']['new'];
178         $unseen  = $storage->search_once($mbox, $search);
48e9c1 179
6e8f2a 180         if ($unseen->count()) {
AM 181             $this->notified = true;
48e9c1 182
T 183             $this->rc->output->command('plugin.newmail_notifier',
5147ee 184                 array(
AM 185                     'basic'   => $this->opt['basic'],
186                     'sound'   => $this->opt['sound'],
187                     'desktop' => $this->opt['desktop'],
188                 ));
48e9c1 189         }
T 190
191         return $args;
192     }
193 }