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