/[drupal]/contributions/modules/xmpp/xmpp.module
ViewVC logotype

Diff of /contributions/modules/xmpp/xmpp.module

Parent Directory Parent Directory | Revision Log Revision Log | View Revision Graph Revision Graph | View Patch Patch

revision 1.1 by mkhitrov, Sun Jul 15 14:54:29 2007 UTC revision 1.2 by mkhitrov, Sun Jul 15 15:09:55 2007 UTC
# Line 5  Line 5 
5   * @file   * @file
6   * Extensible Messaging and Presence Protocol API.   * Extensible Messaging and Presence Protocol API.
7   *   *
8   * When enabled, allows Drupal components to send messages to users via the   * Allows Drupal components to send instant messages to users via the extensible
9   * extensible messaging and presence protocol.   * messaging and presence protocol.
10   */   */
11    
12  /**  /**
  * Server types.  
  */  
 define('XMPP_SERVER_TCP',      0);  
 define('XMPP_SERVER_BOSH',     1);  
 define('XMPP_SERVER_INTERNAL', 2);  
   
 /**  
  * TCP encryption methods.  
  */  
 define('XMPP_CRYPTO_TLS', 0);  
 define('XMPP_CRYPTO_SSL', 1);  
   
 /**  
13   * Implementation of hook_help().   * Implementation of hook_help().
14   */   */
15  function xmpp_help($section) {  function xmpp_help($section) {
16          switch ($section) {    switch ($section) {
17                  case 'admin/help#xmpp':      case 'admin/help#xmpp':
18                          return t('        return '<p>'. t('
19                                  <p>The XMPP module provides Drupal components with a way to communicate          The XMPP module provides other Drupal components with a way to
20                                  over the extensible messaging and presence protocol (aka Jabber). Once          communicate over the extensible messaging and presence protocol (aka
21                                  enabled, other modules will be able to send instant messages to site          Jabber). Once enabled and configured, other modules will be able to send
22                                  users.</p>          instant messages to site users.
23                          ');        ') .'</p>';
24    
25                  case 'admin/settings/xmpp/client':      case 'admin/settings/xmpp/server':
26                          return t('        return '<p>'. t('
27                                  <p>Configure the XMPP client to act on your site\'s behalf.</p>          The built-in server is not currently implemented.
28                          ');        ') .'</p>';
29      }
                 case 'admin/settings/xmpp/server':  
                         return t('  
                                 <p>The built-in server is not currently implemented.</p>  
                         ');  
         }  
30  }  }
31    
32  /**  /**
33   * Implementation of hook_perm().   * Implementation of hook_perm().
34   */   */
35  function xmpp_perm() {  function xmpp_perm() {
36          return array(    return array(
37                  'administer xmpp'      'administer xmpp'
38          );    );
39  }  }
40    
41  /**  /**
42   * Implementation of hook_menu().   * Implementation of hook_menu().
43   */   */
44  function xmpp_menu($may_cache) {  function xmpp_menu($may_cache) {
45          $items = array();    $items = array();
46    
47          if ($may_cache) {    if ($may_cache) {
48    
49                  $items[] = array(      $items[] = array(
50                          'path'               => 'admin/settings/xmpp',        'path'               => 'admin/settings/xmpp',
51                          'title'              => t('XMPP Settings'),        'title'              => t('XMPP Settings'),
52                          'description'        => t('Configure XMPP API.'),        'description'        => t('Configure XMPP API.'),
53                          'callback'           => 'drupal_get_form',        'callback'           => 'drupal_get_form',
54                          'callback arguments' => array('xmpp_client_settings'),        'callback arguments' => array('xmpp_client_settings'),
55                          'access'             => user_access('administer xmpp'),        'access'             => user_access('administer xmpp'),
56                  );      );
57    
58                  $items[] = array(      $items[] = array(
59                          'path'  => 'admin/settings/xmpp/client',        'path'   => 'admin/settings/xmpp/client',
60                          'title' => t('Client'),        'title'  => t('Client'),
61                          'type'  => MENU_DEFAULT_LOCAL_TASK,        'type'   => MENU_DEFAULT_LOCAL_TASK,
62                  );        'access' => user_access('administer xmpp'),
63        );
64                  $items[] = array(  
65                          'path'               => 'admin/settings/xmpp/server',      $items[] = array(
66                          'title'              => t('Server'),        'path'               => 'admin/settings/xmpp/server',
67                          'callback'           => 'drupal_get_form',        'title'              => t('Server'),
68                          'callback arguments' => array('xmpp_server_settings'),        'callback'           => 'drupal_get_form',
69                          'type'               => MENU_LOCAL_TASK        'callback arguments' => array('xmpp_server_settings'),
70                  );        'type'               => MENU_LOCAL_TASK,
71          }        'access'             => user_access('administer xmpp')
72        );
73      }
74    
75          return $items;    return $items;
76  }  }
77    
78  /**  /**
79   * XMPP client settings page.   * Client settings page.
80   */   */
81  function xmpp_client_settings() {  function xmpp_client_settings() {
         $form = array();  
82    
83          $fields_sql = 'SELECT fid, title FROM {profile_fields}'.    $form   = array();
84                                                                  ' WHERE type = \'textfield\'';    $fields = array();
85      $query  = db_query(
86        'SELECT fid, title FROM {profile_fields}'.
87        ' WHERE type = \'textfield\''
88      );
89    
90      while ($record = db_fetch_array($query))
91        $fields[$record['fid']] = $record['title'];
92    
93      $transport_methods = array(
94        'tcp' => t('External (TCP/IP)')
95      );
96    
97      $crypto_methods = array(
98        'tls_opt' => t('TLS (Optional)'),
99        'tls'     => t('TLS (Required)'),
100        'ssl'     => t('SSL'),
101      );
102    
103      $crypto_disabled = !extension_loaded('openssl');
104      $crypto_text     = $crypto_disabled ? ' (Requires OpenSSL extension)' : '';
105      $jid_format      = htmlspecialchars('<user>@<domain>[/<resource>]');
106    
107      //
108      // Basic settings
109      //
110    
111      $form['auth'] = array(
112        '#type'        => 'fieldset',
113        '#title'       => t('Basic settings')
114      );
115    
116      $form['auth']['xmpp_jid'] = array(
117        '#type'          => 'textfield',
118        '#title'         => t('Username'),
119        '#description'   => t('JID to use for authentication ('.$jid_format.').'),
120        '#default_value' => variable_get('xmpp_jid', '')
121      );
122    
123      $form['auth']['xmpp_passwd'] = array(
124        '#type'          => 'password',
125        '#title'         => t('Password'),
126        '#description'   => t('Password to use for authentication.'),
127        '#default_value' => variable_get('xmpp_passwd', '')
128      );
129    
130      $form['auth']['xmpp_jid_field'] = array(
131        '#type'          => 'select',
132        '#title'         => t('User JID Field'),
133        '#description'   => t('Profile field which is used to store user JIDs.'),
134        '#options'       => $fields,
135        '#default_value' => variable_get('xmpp_jid_field', '')
136      );
137    
138      //
139      // Server type
140      //
141    
142      $form['server_type'] = array(
143        '#type'  => 'fieldset',
144        '#title' => t('Server type'),
145      );
146    
147      $form['server_type']['xmpp_transport_method'] = array(
148        '#type'          => 'radios',
149        '#title'         => t('Transport method'),
150        '#description'   => t('Server type and transport method to be used.'),
151        '#options'       => $transport_methods,
152        '#default_value' => variable_get('xmpp_transport_method', 'tcp')
153      );
154    
155      //
156      // External (TCP/IP)
157      //
158    
159      $form['external_tcp'] = array(
160        '#type'        => 'fieldset',
161        '#title'       => t('External (TCP/IP)'),
162        '#collapsible' => true,
163        '#collapsed'   => true,
164      );
165    
166      $form['external_tcp']['xmpp_transport_tcp_host'] = array(
167        '#type'          => 'textfield',
168        '#title'         => t('Host'),
169        '#description'   => t('Hostname or IP of the external server.'),
170        '#default_value' => variable_get('xmpp_transport_tcp_host', ''),
171        '#maxlength'     => 255,
172      );
173    
174      $form['external_tcp']['xmpp_transport_tcp_port'] = array(
175        '#type'          => 'textfield',
176        '#title'         => t('Port'),
177        '#description'   => t('Port on which to establish the connection.'),
178        '#default_value' => variable_get('xmpp_transport_tcp_port', '5222'),
179        '#maxlength'     => 5,
180      );
181    
182      $form['external_tcp']['xmpp_transport_tcp_use_dns'] = array(
183        '#type'          => 'checkbox',
184        '#title'         => t('Use DNS'),
185        '#default_value' => variable_get('xmpp_transport_tcp_use_dns', true),
186        '#description'   => t('Enable DNS SRV look-ups.'),
187      );
188    
189      $form['external_tcp']['xmpp_transport_tcp_crypto'] = array(
190        '#type'          => 'radios',
191        '#title'         => t('Encryption mechanism'. $crypto_text),
192        '#description'   => t('Type of encryption to use (if available).'),
193        '#default_value' => variable_get('xmpp_transport_tcp_crypto', 'tls_opt'),
194        '#options'       => $crypto_methods,
195        '#disabled'      => $crypto_disabled
196      );
197    
198      //
199      // Test configuration
200      //
201    
202      $form['test'] = array(
203        '#type'        => 'fieldset',
204        '#title'       => t('Test configuration'),
205        '#collapsible' => true,
206        '#collapsed'   => true,
207      );
208    
209      $form['test']['xmpp_test_jid'] = array(
210        '#type'          => 'textfield',
211        '#title'         => t('Recipient'),
212        '#description'   => t('Send a test IM to the specified JID.'),
213        '#default_value' => '',
214      );
215    
216      return system_settings_form($form);
217    }
218    
219          $jid_format  = '&lt;user&gt;@&lt;domain&gt;[/&lt;resource&gt;]';  /**
220          $server_type = variable_get('xmpp_server_type', XMPP_SERVER_TCP);   * Server settings page.
221          $query       = db_query($fields_sql);   */
222          $fields      = array();  function xmpp_server_settings() {
223      $form = array();
224          while ($record = db_fetch_array($query))    return system_settings_form($form);
225                  $fields[$record['fid']] = $record['title'];  }
   
         $server_types = array(  
                 XMPP_SERVER_TCP => t('External (TCP/IP)')  
         );  
   
         $crypto_methods = array(  
                 XMPP_CRYPTO_TLS => t('TLS'),  
                 XMPP_CRYPTO_SSL => t('SSL'),  
         );  
   
         $crypto_disabled = !extension_loaded('openssl');  
         $crypto_text     = $crypto_disabled ? ' (Requires OpenSSL extension)' : '';  
   
   
   
         $form['auth'] = array(  
                 '#type'        => 'fieldset',  
                 '#title'       => t('User info'),  
         );  
   
         $form['auth']['xmpp_client_jid'] = array(  
                 '#type'          => 'textfield',  
                 '#title'         => t('Username'),  
                 '#description'   => t('JID to use for authentication ('.$jid_format.').'),  
                 '#default_value' => variable_get('xmpp_client_jid', ''),  
         );  
   
         $form['auth']['xmpp_client_password'] = array(  
                 '#type'          => 'password',  
                 '#title'         => t('Password'),  
                 '#description'   => t('Password to use for authentication'),  
                 '#default_value' => variable_get('xmpp_client_password', ''),  
         );  
   
         $form['auth']['xmpp_client_jid_field'] = array(  
                 '#type'          => 'select',  
                 '#title'         => t('User JID Field'),  
                 '#description'   => t('Profile field which is used to store JIDs.'),  
                 '#options'       => $fields,  
                 '#default_value' => variable_get('xmpp_client_jid_field', null)  
         );  
   
   
   
         $form['server_type'] = array(  
                 '#type'  => 'fieldset',  
                 '#title' => t('Server type'),  
         );  
   
         $form['server_type']['xmpp_server_type'] = array(  
                 '#type'          => 'radios',  
                 '#title'         => t('Server type'),  
                 '#default_value' => $server_type,  
                 '#options'       => $server_types,  
                 '#description'   => t('Server type and connection method to be used.'),  
         );  
   
   
   
         $form['external_tcp'] = array(  
                 '#type'        => 'fieldset',  
                 '#title'       => t('External server (TCP/IP)'),  
                 '#collapsible' => true,  
                 '#collapsed'   => true,  
         );  
   
         $form['external_tcp']['xmpp_client_tcp_hostname'] = array(  
                 '#type'          => 'textfield',  
                 '#title'         => t('Hostname (optional)'),  
                 '#description'   => t('Hostname or IP of the external server.'),  
                 '#default_value' => variable_get('xmpp_client_tcp_hostname', ''),  
                 '#maxlength'     => 255,  
         );  
   
         $form['external_tcp']['xmpp_client_tcp_port'] = array(  
                 '#type'          => 'textfield',  
                 '#title'         => t('Port (optional)'),  
                 '#description'   => t('Port on which to establish the connection.'),  
                 '#default_value' => variable_get('xmpp_client_tcp_port', ''),  
                 '#maxlength'     => 5,  
         );  
   
         $form['external_tcp']['xmpp_client_tcp_use_dns'] = array(  
                 '#type'          => 'checkbox',  
                 '#title'         => t('Use DNS'),  
                 '#default_value' => variable_get('xmpp_client_tcp_use_dns', true),  
                 '#description'   => t('Enable DNS SRV look-ups.'),  
         );  
   
         $form['external_tcp']['xmpp_client_tcp_crypto'] = array(  
                 '#type'          => 'radios',  
                 '#title'         => t('Encryption mechanism'.$crypto_text),  
                 '#default_value' => variable_get('xmpp_client_tcp_crypto', XMPP_CRYPTO_TLS),  
                 '#options'       => $crypto_methods,  
                 '#description'   => t('Type of encryption to use (if available).'),  
                 '#disabled'      => $crypto_disabled  
         );  
   
         $form['external_tcp']['xmpp_client_tcp_require_crypto'] = array(  
                 '#type'          => 'checkbox',  
                 '#title'         => t('Require encryption'.$crypto_text),  
                 '#default_value' => variable_get('xmpp_client_tcp_require_crypto', false),  
                 '#description'   => t('Require the use of encryption.'),  
                 '#disabled'      => $crypto_disabled  
         );  
   
   
   
         $form['test'] = array(  
                 '#type'        => 'fieldset',  
                 '#title'       => t('Test settings'),  
                 '#collapsible' => true,  
                 '#collapsed'   => true,  
         );  
   
         $form['test']['xmpp_client_test_jid'] = array(  
                 '#type'          => 'textfield',  
                 '#title'         => t('Recipient'),  
                 '#description'   => t('Send a test IM to the specified JID.'),  
                 '#default_value' => '',  
         );  
   
   
   
         return system_settings_form($form);  
 }  
   
 /**  
  * We can't execute any 'Update options' if no comments were selected.  
  */  
 //function xmpp_client_settings_validate($form_id, $form_values) {  
         //form_set_error('', t('Please select one or more comments to perform the update on.'));  
         //drupal_goto('admin/settings/xmpp');`  
 //}  
226    
227  /**  /**
228   * Execute the chosen 'Update option' on the selected comments, such as   * Validate client settings form.
229   * publishing, unpublishing or deleting.   */
230    function xmpp_client_settings_validate($form_id, $form_values, $form) {
231    
232      variable_set('xmpp_client_configured', false);
233    
234      if (empty($form_values['xmpp_passwd'])) {
235        $passwd = variable_get('xmpp_passwd', '');
236    
237        if (empty($passwd)) {
238          form_set_error('', t('Please enter the login password'));
239          return;
240        }
241    
242        form_set_value($form['auth']['xmpp_passwd'], $passwd);
243        $form_values['xmpp_passwd'] = $passwd;
244      }
245    
246      if (!xmpp_client_settings_check($form_values, $error)) {
247        form_set_error('', t($error));
248        return;
249      }
250    
251      variable_set('xmpp_client_configured', true);
252    }
253    
254    /**
255     * Submit client settings form.
256   */   */
257  function xmpp_client_settings_submit($form_id, $form_values) {  function xmpp_client_settings_submit($form_id, $form_values) {
         if (!empty($form_values['xmpp_client_test_jid']))  
         {  
         }  
258    
259          drupal_set_message(print_r($_SESSION, true));    $fields = array(
260          drupal_goto('admin/settings/xmpp');      'xmpp_jid',
261        'xmpp_passwd',
262        'xmpp_jid_field',
263        'xmpp_transport_method',
264        'xmpp_transport_tcp_host',
265        'xmpp_transport_tcp_port',
266        'xmpp_transport_tcp_use_dns',
267        'xmpp_transport_tcp_crypto'
268      );
269    
270      foreach ($fields as $field)
271        variable_set($field, $form_values[$field]);
272    
273      $crypto = $form_values['xmpp_transport_tcp_crypto'];
274      variable_set('xmpp_transport_tcp_scheme', ($crypto == 'ssl' ? 'ssl' : 'tcp'));
275    
276      preg_match('/@([^\/]+)/', $form_values['xmpp_jid'], $matches);
277      variable_set('xmpp_stream_send_to', $matches[1]);
278    
279      $test_jid = $form_values['xmpp_test_jid'];
280      if (!empty($test_jid)) {
281    
282        if (!xmpp_message($test_jid, 'Hello, this is a test IM from Drupal :)')) {
283          drupal_set_message('Error sending message: '. xmpp_last_error(), 'error');
284          return;
285        }
286    
287        drupal_set_message('Test message sent.');
288      }
289    
290      drupal_set_message('The configuration options have been saved.');
291  }  }
292    
293    // -----------------------------------------------------------------------------
294    // XMPP API
295    // -----------------------------------------------------------------------------
296    
297  /**  /**
298   * Send a simple message to   * Get a connected XMPP_Session object.
299   */   */
300  function xmpp_message($uid, $message)  function xmpp_get_session() {
301  {    static $sess = null;
302    
303      if (is_null($sess)) {
304    
305        if (!xmpp_ready())
306          return null;
307    
308        try {
309          $sess   = @XMPP_Client::connect(xmpp_client_config());
310          $crypto = variable_get('xmpp_transport_tcp_crypto', 'tls_opt');
311          $user   = variable_get('xmpp_jid', '');
312          $passwd = variable_get('xmpp_passwd', '');
313    
314          if ($crypto != 'tls_opt' && !$sess['transport.encrypted'])
315            throw new Exception('Unable to use encryption');
316    
317          if (!@$sess->Core->login($user, $passwd))
318            throw new Exception('Unable to bind to resource');
319        }
320        catch (Exception $e) {
321          $sess = null;
322          xmpp_last_error($e->getMessage());
323        }
324      }
325    
326      return $sess;
327  }  }
328    
329  /**  /**
330   * Map user id to their jabber id.   * Map user id to their jabber id.
331   */   */
332  function xmpp_uid_to_jid($uid = null)  function xmpp_get_jid($uid = null) {
333  {  
334          $fid = variable_get('xmpp_client_jid_field', null);    $fid = variable_get('xmpp_jid_field', null);
335    
336          if (is_null($fid))    if (is_null($fid))
337                  return null;      return '';
338    
339          if (is_null($uid)) {    if (is_null($uid)) {
340                  global $user;      global $user;
341                  $uid = $user->uid;      $uid = $user->uid;
342          }    }
343    
344      $query  = "SELECT value FROM {profile_values} WHERE uid=$uid AND fid=$fid";
345      $result = db_result(db_query($query));
346    
347      return ($result ? $result : '');
348    }
349    
350    /**
351     * Send a simple message to the specified jid.
352     */
353    function xmpp_message($jid, $message) {
354    
355          $query = 'SELECT value FROM {profile_values} WHERE uid='.$uid.' AND'.    if (is_null($sess = xmpp_get_session()))
356                                           ' fid='.$fid;      return false;
357    
358          return db_result(db_query($fields_sql));    try {
359        @$sess->Core->sendMessage($jid, $message);
360      }
361      catch (Exception $e) {
362        xmpp_last_error($e->getMessage());
363        return false;
364      }
365    
366      return true;
367    }
368    
369    /**
370     * Get the last XMPP error message.
371     */
372    function xmpp_last_error($set = null) {
373      static $error = '';
374    
375      if (!is_null($set))
376        $error = t($set);
377    
378      return $error;
379    }
380    
381    // -----------------------------------------------------------------------------
382    // Private functions
383    // -----------------------------------------------------------------------------
384    
385    /**
386     * Check submitted client settings.
387     */
388    function xmpp_client_settings_check($form, &$error) {
389    
390      $jid_regex = '/^[^@]+@[^\/]+(?:\/.+)?$/';
391    
392      if (empty($form['xmpp_jid']) || empty($form['xmpp_passwd'])) {
393        $error = 'Please enter the login username and password';
394        return false;
395      }
396    
397      if (!preg_match($jid_regex, $form['xmpp_jid'])) {
398        $error = 'Please enter a valid login username';
399        return false;
400      }
401    
402      if (empty($form['xmpp_jid_field'])) {
403        $error = 'Please select a valid JID profile field';
404        return false;
405      }
406    
407      if ($form['xmpp_transport_method'] == 'tcp') {
408        if (empty($form['xmpp_transport_tcp_host'])) {
409          $error = 'Please enter the tcp host';
410          return false;
411        }
412    
413        if (intval($form['xmpp_transport_tcp_port']) == 0) {
414          $error = 'Please enter a valid tcp port';
415          return false;
416        }
417      }
418    
419      if (!empty($form['xmpp_test_jid'])) {
420        if (!preg_match($jid_regex, $form['xmpp_test_jid'])) {
421          $error = 'Please enter a valid test JID';
422          return false;
423        }
424      }
425    
426      return true;
427    }
428    
429    /**
430     * Check if the client is configured and ready to be used.
431     */
432    function xmpp_ready() {
433    
434      if (!variable_get('xmpp_client_configured', false)) {
435        xmpp_last_error('Client is not configured');
436        return false;
437      }
438    
439      require_once dirname(__FILE__).'/lib/client.inc';
440    
441      try {
442        @XMPP_Client::init(false, variable_get('xmpp_lib_path', null));
443      }
444      catch (Exception $e) {
445        xmpp_last_error($e->getMessage());
446        return false;
447      }
448    
449      return true;
450    }
451    
452    /**
453     * Get current client configuration.
454     */
455    function xmpp_client_config() {
456      static $conf = null;
457    
458      if (!xmpp_ready())
459        return null;
460    
461      if (is_null($conf)) {
462        $conf = array();
463    
464        xmpp_set_conf($conf, 'stream.send.to');
465        xmpp_set_conf($conf, 'transport.method');
466    
467        if ($conf['transport.method'] == 'tcp') {
468          xmpp_set_conf($conf, 'transport.tcp.scheme');
469          xmpp_set_conf($conf, 'transport.tcp.host');
470          xmpp_set_conf($conf, 'transport.tcp.port');
471          xmpp_set_conf($conf, 'transport.tcp.use_dns');
472        }
473    
474        $conf = array_diff_assoc($conf, XMPP_Client::getDefaults());
475      }
476    
477      return $conf;
478    }
479    
480    /**
481     * Set client configuration key.
482     */
483    function xmpp_set_conf(&$conf, $key) {
484      $var        = 'xmpp_'.str_replace('.', '_', $key);
485      $conf[$key] = variable_get($var, $conf[$key]);
486  }  }

Legend:
Removed from v.1.1  
changed lines
  Added in v.1.2

  ViewVC Help
Powered by ViewVC 1.1.3