source: contrib/davical/htdocs/always.php @ 3733

Revision 3733, 22.9 KB checked in by gabriel.malheiros, 13 years ago (diff)

Ticket #1541 - <Davical customizado para o Expresso.Utiliza Caldav e CardDav?>

Line 
1<?php
2/**
3* @package davical
4* @author Andrew McMillan <andrew@mcmillan.net.nz>
5* @copyright Catalyst .Net Ltd, Morphoss Ltd <http://www.morphoss.com/>
6* @license   http://gnu.org/copyleft/gpl.html GNU GPL v2 or later
7*/
8
9if ( preg_match('{/always.php$}', $_SERVER['SCRIPT_NAME'] ) ) header('Location: index.php');
10
11// Ensure the configuration starts out as an empty object.
12$c = (object) array();
13$c->script_start_time = microtime(true);
14
15// Ditto for a few other global things
16unset($session); unset($request); unset($dbconn); unset($_awl_dbconn); unset($include_properties);
17
18// An ultra-simple exception handler to catch errors that occur
19// before we get a more functional exception handler in place...
20function early_exception_handler($e) {
21  echo "Uncaught early exception: ", $e->getMessage(), "\nAt line ", $e->getLine(), " of ", $e->getFile(), "\n";
22
23  $trace = array_reverse($e->getTrace());
24  foreach( $trace AS $k => $v ) {
25    printf( "=====================================================\n%s[%d] %s%s%s()\n", $v['file'], $v['line'], (isset($v['class'])?$v['class']:''), (isset($v['type'])?$v['type']:''), (isset($v['function'])?$v['function']:'') );
26  }
27}
28set_exception_handler('early_exception_handler');
29
30// Default some of the configurable values
31$c->sysabbr     = 'davical';
32$c->admin_email = 'admin@davical.example.com';
33$c->system_name = 'DAViCal CalDAV Server';
34$c->domain_name = (isset($_SERVER['SERVER_NAME'])?$_SERVER['SERVER_NAME']:$_SERVER['SERVER_ADDR']);
35$c->save_time_zone_defs = true;
36$c->collections_always_exist = false;
37$c->allow_get_email_visibility = false;
38$c->permission_scan_depth = 2;
39$c->expand_pdo_parameters = true;
40$c->home_calendar_name = 'home';
41$c->enable_row_linking = true;
42$c->enable_scheduling = false;
43$c->http_auth_mode = 'Basic';
44// $c->default_locale = array('es_MX', 'es_AR', 'es', 'pt');  // An array of locales to try, or just a single locale
45// $c->local_tzid = 'Pacific/Auckland';  // Perhaps we should read from /etc/timezone - I wonder how standard that is?
46$c->default_locale = 'en';
47$c->locale_path = '../locale';
48$c->base_url = preg_replace('#/[^/]+\.php.*$#', '', $_SERVER['SCRIPT_NAME']);
49$c->base_directory = preg_replace('#/[^/]*$#', '', $_SERVER['DOCUMENT_ROOT']);
50$c->default_privileges = array('read-free-busy', 'schedule-deliver');
51
52$c->stylesheets = array( $c->base_url.'/davical.css' );
53$c->images      = $c->base_url . '/images';
54
55// Add a default for newly created users
56$c->template_usr = array( 'active' => true,
57                          'locale' => 'en_GB',
58                          'date_format_type' => 'E',
59                          'email_ok' => date('Y-m-d')
60                        );
61
62$c->hide_TODO = true;                      // VTODO only visible to collection owner
63$c->readonly_webdav_collections = true;    // WebDAV access is readonly
64
65// Kind of private configuration values
66$c->total_query_time = 0;
67
68$c->dbg = array();
69
70
71// Utilities
72if ( ! @include_once('AWLUtilities.php') ) {
73  $try_paths = array(
74        '../../awl/inc'
75      , '/usr/share/awl/inc'
76      , '/usr/local/share/awl/inc'
77  );
78  foreach( $try_paths AS $awl_include_path ) {
79    if ( @file_exists($awl_include_path.'/AWLUtilities.php') ) {
80      set_include_path( $awl_include_path. PATH_SEPARATOR. get_include_path());
81      break;
82    }
83  }
84  if ( ! @include_once('AWLUtilities.php') ) {
85    echo "Could not find the AWL libraries. Are they installed? Check your include_path in php.ini!\n";
86    exit;
87  }
88}
89
90// Ensure that ../inc is in our included paths as early as possible
91set_include_path( '../inc'. PATH_SEPARATOR. get_include_path());
92
93
94/** We actually discovered this and worked around it earlier, but we can't log it until the utilties are loaded */
95if ( !isset($_SERVER['SERVER_NAME']) ) {
96  @dbg_error_log( 'WARN', "Your webserver is not setting the SERVER_NAME parameter. You may need to set \$c->domain_name in your configuration.  Using IP address meanhwhile..." );
97}
98
99/**
100* Calculate the simplest form of reference to this page, excluding the PATH_INFO following the script name.
101*/
102$c->protocol_server_port = sprintf( '%s://%s%s',
103                 (isset($_SERVER['HTTPS']) && $_SERVER['HTTPS'] == 'on'? 'https' : 'http'),
104                 $_SERVER['SERVER_NAME'],
105                 (
106                   ( (!isset($_SERVER['HTTPS']) || $_SERVER['HTTPS'] != 'on') && $_SERVER['SERVER_PORT'] == 80 )
107                           || (isset($_SERVER['HTTPS']) && $_SERVER['HTTPS'] == 'on' && $_SERVER['SERVER_PORT'] == 443 )
108                   ? ''
109                   : ':'.$_SERVER['SERVER_PORT']
110                 ) );
111$c->protocol_server_port_script = $c->protocol_server_port . ($_SERVER['SCRIPT_NAME'] == '/index.php' ? '' : $_SERVER['SCRIPT_NAME']);
112
113
114/**
115* We use @file_exists because things like open_basedir might noisily deny
116* access which could break DAViCal completely by causing output to start
117* too early.
118*/
119ob_start( );
120if ( @file_exists('/etc/davical/'.$_SERVER['SERVER_NAME'].'-conf.php') ) {
121  include('/etc/davical/'.$_SERVER['SERVER_NAME'].'-conf.php');
122}
123else if ( @file_exists('/etc/davical/config.php') ) {
124  include('/etc/davical/config.php');
125}
126else if ( @file_exists('/usr/local/etc/davical/'.$_SERVER['SERVER_NAME'].'-conf.php') ) {
127  include('/usr/local/etc/davical/'.$_SERVER['SERVER_NAME'].'-conf.php');
128}
129else if ( @file_exists('/usr/local/etc/davical/config.php') ) {
130  include('/usr/local/etc/davical/config.php');
131}
132else if ( @file_exists('../config/config.php') ) {
133  include('../config/config.php');
134}
135else if ( @file_exists('config/config.php') ) {
136  include('config/config.php');
137}
138else {
139  include('davical_configuration_missing.php');
140  exit;
141}
142$config_warnings = trim(ob_get_contents());
143ob_end_clean();
144
145if ( !isset($c->page_title) ) $c->page_title = $c->system_name;
146
147if ( isset($_SERVER['HTTP_X_DAVICAL_TESTCASE']) ) {
148  @dbg_error_log( 'LOG', '==========> Test case =%s=', $_SERVER['HTTP_X_DAVICAL_TESTCASE'] );
149}
150else if ( isset($c->dbg['script_start']) && $c->dbg['script_start'] ) {
151  // Only log this if more than a little debugging of some sort is turned on, somewhere
152  @dbg_error_log( 'LOG', '==========> method =%s= =%s= =%s= =%s= =%s=',
153         $_SERVER['REQUEST_METHOD'], $c->protocol_server_port_script, $_SERVER['PATH_INFO'], $c->base_url, $c->base_directory );
154}
155
156/**
157* Now that we have loaded the configuration file we can switch to a
158* default site locale.  This may be overridden by each user.
159*/
160putenv("LANG=". $c->default_locale);
161awl_set_locale($c->default_locale);
162init_gettext( 'davical', $c->locale_path );
163
164/**
165* Work out our version
166*
167*/
168$c->code_version = 0;
169$c->version_string = '0.9.9.2'; // The actual version # is replaced into that during the build /release process
170if ( isset($c->version_string) && preg_match( '/(\d+)\.(\d+)\.(\d+)(.*)/', $c->version_string, $matches) ) {
171  $c->code_major = $matches[1];
172  $c->code_minor = $matches[2];
173  $c->code_patch = $matches[3];
174  $c->code_version = (($c->code_major * 1000) + $c->code_minor).'.'.$c->code_patch;
175  dbg_error_log('caldav', 'Version (%d.%d.%d) == %s', $c->code_major, $c->code_minor, $c->code_patch, $c->code_version);
176  header( sprintf('Server: %d.%d', $c->code_major, $c->code_minor) );
177}
178
179/**
180* Force the domain name to what was in the configuration file
181*/
182$_SERVER['SERVER_NAME'] = $c->domain_name;
183
184require_once('AwlQuery.php');
185
186$c->want_dbversion = array(1,2,9);
187$c->schema_version = 0;
188$qry = new AwlQuery( 'SELECT schema_major, schema_minor, schema_patch FROM awl_db_revision ORDER BY schema_id DESC LIMIT 1;' );
189if ( $qry->Exec('always',__LINE__,__FILE__) && $row = $qry->Fetch() ) {
190  $c->schema_version = doubleval( sprintf( '%d%03d.%03d', $row->schema_major, $row->schema_minor, $row->schema_patch) );
191  $c->wanted_version = doubleval( sprintf( '%d%03d.%03d', $c->want_dbversion[0], $c->want_dbversion[1], $c->want_dbversion[2]) );
192  $c->schema_major = $row->schema_major;
193  $c->schema_minor = $row->schema_minor;
194  $c->schema_patch = $row->schema_patch;
195  if ( $c->schema_version < $c->wanted_version ) {
196    $c->messages[] = sprintf( 'Database schema needs upgrading. Current: %d.%d.%d, Desired: %d.%d.%d',
197             $row->schema_major, $row->schema_minor, $row->schema_patch, $c->want_dbversion[0], $c->want_dbversion[1], $c->want_dbversion[2]);
198  }
199  if ( isset($_SERVER['HTTP_X_DAVICAL_TESTCASE']) ) $qry->QDo('SET TIMEZONE TO \'Pacific/Auckland\'');
200}
201
202
203$_known_users_name = array();
204$_known_users_id   = array();
205$_known_users_pid  = array();
206
207function _davical_get_principal_query_cached( $where, $parameter ) {
208  global $c, $session, $_known_users_name, $_known_users_id, $_known_users_pid;
209
210  $sql = 'SELECT *, to_char(updated at time zone \'GMT\',\'Dy, DD Mon IYYY HH24:MI:SS "GMT"\') AS modified, principal.*, ';
211  if ( isset($session->principal_id) ) {
212    $sql .= 'pprivs(:session_principal::int8,principal.principal_id,:scan_depth::int) AS privileges ';
213    $params = array( ':session_principal' => $session->principal_id, ':scan_depth' => $c->permission_scan_depth );
214  }
215  else {
216    $sql .= '0::BIT(24) AS privileges ';
217    $params = array( );
218  }
219  $sql .= 'FROM usr LEFT JOIN principal USING(user_no) WHERE '. $where;
220  $params[':param'] = $parameter;
221
222  $qry = new AwlQuery( $sql, $params );
223  if ( $qry->Exec('always',__LINE__,__FILE__) && $qry->rows() == 1 && $row = $qry->Fetch() ) {
224    if ( isset($session->principal_id) ) {
225      $_known_users_name[$row->username]      = $row;
226      $_known_users_id[$row->user_no]         = $row;
227      $_known_users_pid[$row->principal_id]   = $row;
228    }
229    return $row;
230  }
231
232  return false;
233}
234
235/**
236* Return a user record identified by a username, caching it for any subsequent lookup
237* @param string $username The username of the record to retrieve
238* @param boolean $use_cache Whether or not to use the cache (default: yes)
239*/
240function getUserByName( $username, $use_cache = true ) {
241  global $_known_users_name;
242  settype($username,"string");                           
243  if ( $use_cache && isset( $_known_users_name[$username] ) ) return $_known_users_name[$username];
244     
245  if (is_numeric($username))
246       return _davical_get_principal_query_cached( 'username = :param', $username );
247  else
248       return _davical_get_principal_query_cached( 'lower(username) = lower(:param)', $username );
249}
250
251
252/**
253* Return a user record identified by e-mail address, caching it for any subsequent lookup
254* @param string $email The email address of the user record to retrieve
255* @param boolean $use_cache Whether or not to use the cache (default: yes)
256*/
257function getUserByEMail( $email, $use_cache = true ) {
258  global $_known_users_name;
259
260  if ( $use_cache ) {
261    /** We don't actually maintain a cache-access by e-mail, since it's rare */
262    foreach( $_known_users_name AS $k => $v ) {
263      if ( strtolower($email) == strtolower($v->email) ) return $v;
264    }
265  }
266  return _davical_get_principal_query_cached( 'email = :param', $email );
267}
268
269
270/**
271* Return a user record identified by a user_no, caching it for any subsequent lookup
272* @param int $user_no The ID of the record to retrieve
273* @param boolean $use_cache Whether or not to use the cache (default: yes)
274*/
275function getUserByID( $user_no, $use_cache = true ) {
276  global $c, $session, $_known_users_id;
277
278  if ( $use_cache && isset( $_known_users_id[$user_no] ) ) return $_known_users_id[$user_no];
279  return _davical_get_principal_query_cached( 'user_no = :param', $user_no );
280}
281
282
283/**
284* Return a user record identified by a user_no, caching it for any subsequent lookup
285* @param int $user_no The ID of the record to retrieve
286* @param boolean $use_cache Whether or not to use the cache (default: yes)
287*/
288function getPrincipalByID( $principal_id, $use_cache = true ) {
289  global $c, $session, $_known_users_pid;
290
291  if ( $use_cache && isset( $_known_users_pid[$principal_id] ) ) return $_known_users_pid[$principal_id];
292  return _davical_get_principal_query_cached( 'principal_id = :param', $principal_id );
293}
294
295
296/**
297 * Return the HTTP status code description for a given code. Hopefully
298 * this is an efficient way to code this.
299 * @return string The text for a give HTTP status code, in english
300 */
301function getStatusMessage($status) {
302  switch( $status ) {
303    case 100:  $ans = 'Continue';                             break;
304    case 101:  $ans = 'Switching Protocols';                  break;
305    case 200:  $ans = 'OK';                                   break;
306    case 201:  $ans = 'Created';                              break;
307    case 202:  $ans = 'Accepted';                             break;
308    case 203:  $ans = 'Non-Authoritative Information';        break;
309    case 204:  $ans = 'No Content';                           break;
310    case 205:  $ans = 'Reset Content';                        break;
311    case 206:  $ans = 'Partial Content';                      break;
312    case 207:  $ans = 'Multi-Status';                         break;
313    case 300:  $ans = 'Multiple Choices';                     break;
314    case 301:  $ans = 'Moved Permanently';                    break;
315    case 302:  $ans = 'Found';                                break;
316    case 303:  $ans = 'See Other';                            break;
317    case 304:  $ans = 'Not Modified';                         break;
318    case 305:  $ans = 'Use Proxy';                            break;
319    case 307:  $ans = 'Temporary Redirect';                   break;
320    case 400:  $ans = 'Bad Request';                          break;
321    case 401:  $ans = 'Unauthorized';                         break;
322    case 402:  $ans = 'Payment Required';                     break;
323    case 403:  $ans = 'Forbidden';                            break;
324    case 404:  $ans = 'Not Found';                            break;
325    case 405:  $ans = 'Method Not Allowed';                   break;
326    case 406:  $ans = 'Not Acceptable';                       break;
327    case 407:  $ans = 'Proxy Authentication Required';        break;
328    case 408:  $ans = 'Request Timeout';                      break;
329    case 409:  $ans = 'Conflict';                             break;
330    case 410:  $ans = 'Gone';                                 break;
331    case 411:  $ans = 'Length Required';                      break;
332    case 412:  $ans = 'Precondition Failed';                  break;
333    case 413:  $ans = 'Request Entity Too Large';             break;
334    case 414:  $ans = 'Request-URI Too Long';                 break;
335    case 415:  $ans = 'Unsupported Media Type';               break;
336    case 416:  $ans = 'Requested Range Not Satisfiable';      break;
337    case 417:  $ans = 'Expectation Failed';                   break;
338    case 422:  $ans = 'Unprocessable Entity';                 break;
339    case 423:  $ans = 'Locked';                               break;
340    case 424:  $ans = 'Failed Dependency';                    break;
341    case 500:  $ans = 'Internal Server Error';                break;
342    case 501:  $ans = 'Not Implemented';                      break;
343    case 502:  $ans = 'Bad Gateway';                          break;
344    case 503:  $ans = 'Service Unavailable';                  break;
345    case 504:  $ans = 'Gateway Timeout';                      break;
346    case 505:  $ans = 'HTTP Version Not Supported';           break;
347    default:   $ans = 'Unknown HTTP Status Code '.$status;
348  }
349  return $ans;
350}
351
352
353/**
354* Construct a URL from the supplied dav_name.  The URL will be urlencoded,
355* except for any '/' characters in it.
356* @param string $partial_path  The part of the path after the script name
357*/
358function ConstructURL( $partial_path, $force_script = false ) {
359  global $c;
360
361  $partial_path = rawurlencode($partial_path);
362  $partial_path = str_replace( '%2F', '/', $partial_path);
363
364  if ( ! isset($c->_url_script_path) ) {
365    $c->_url_script_path = (preg_match('#/$#', $c->protocol_server_port_script) ? 'caldav.php' : '');
366    $c->_url_script_path = $c->protocol_server_port_script . $c->_url_script_path;
367  }
368
369  $url = $c->_url_script_path;
370  if ( $force_script ) {
371    if ( ! preg_match( '#/caldav\.php$#', $url ) ) $url .= '/caldav.php';
372  }
373  $url .= $partial_path;
374  $url = preg_replace( '#^(https?://.+)//#', '$1/', $url );  // Ensure we don't double any '/'
375  $url = preg_replace('#^https?://[^/]+#', '', $url );       // Remove any protocol + hostname portion
376
377  return $url;
378}
379
380
381/**
382* Deconstruct a dav_name from the supplied URL.  The dav_name will be urldecoded.
383*
384* @param string $partial_path  The part of the path after the script name
385*/
386function DeconstructURL( $url, $force_script = false ) {
387  global $c;
388
389  $dav_name = rawurldecode($url);
390
391  /** Allow a path like .../username/calendar.ics to translate into the calendar URL */
392  if ( preg_match( '#^(/[^/]+/[^/]+).ics$#', $dav_name, $matches ) ) {
393    $dav_name = $matches[1]. '/';
394  }
395
396  /** remove any leading protocol/server/port/prefix... */
397  if ( !isset($c->deconstruction_base_path) ) $c->deconstruction_base_path = ConstructURL('/');
398  if ( preg_match( '%^(.*?)'.str_replace('%', '\\%',$c->deconstruction_base_path).'(.*)$%', $dav_name, $matches ) ) {
399    if ( $matches[1] == '' || $matches[1] == $c->protocol_server_port ) {
400      $dav_name = $matches[2];
401    }
402  }
403
404  /** strip doubled slashes */
405  if ( strstr($dav_name,'//') ) $dav_name = preg_replace( '#//+#', '/', $dav_name);
406
407  if ( substr($dav_name,0,1) != '/' ) $dav_name = '/'.$dav_name;
408
409  return $dav_name;
410}
411
412
413/**
414* Convert a date from ISO format into the sad old HTTP format.
415* @param string $isodate The date to convert
416*/
417function ISODateToHTTPDate( $isodate ) {
418  // Use strtotime since strptime is not available on Windows platform.
419  return( gmstrftime('%a, %d %b %Y %T GMT', strtotime($isodate)) );
420}
421
422/**
423* Convert a date into ISO format into the sparkly new ISO format.
424* @param string $indate The date to convert
425*/
426function DateToISODate( $indate ) {
427  // Use strtotime since strptime is not available on Windows platform.
428  return( date('c', strtotime($indate)) );
429}
430
431/**
432* Given a privilege string, or an array of privilege strings, return a bit mask
433* of the privileges.
434* @param mixed $raw_privs The string (or array of strings) of privilege names
435* @return integer A bit mask of the privileges.
436*/
437define("DAVICAL_MAXPRIV", "65535");
438define("DAVICAL_ADDRESSBOOK_MAXPRIV", "1023");
439function privilege_to_bits( $raw_privs ) {
440  $out_priv = 0;
441
442  if ( gettype($raw_privs) == 'string' ) $raw_privs = array( $raw_privs );
443
444  if ( ! is_array($raw_privs) ) $raw_privs = array($raw_privs);
445
446  foreach( $raw_privs AS $priv ) {
447    $trim_priv = trim(strtolower(preg_replace( '/^.*:/', '', $priv)));
448    switch( $trim_priv ) {
449      case 'read'                            : $out_priv |=     1;  break;
450      case 'write-properties'                : $out_priv |=     2;  break;
451      case 'write-content'                   : $out_priv |=     4;  break;
452      case 'unlock'                          : $out_priv |=     8;  break;
453      case 'read-acl'                        : $out_priv |=    16;  break;
454      case 'read-current-user-privilege-set' : $out_priv |=    32;  break;
455      case 'bind'                            : $out_priv |=    64;  break;
456      case 'unbind'                          : $out_priv |=   128;  break;
457      case 'write-acl'                       : $out_priv |=   256;  break;
458      case 'read-free-busy'                  : $out_priv |=   512;  break;
459      case 'schedule-deliver-invite'         : $out_priv |=  1024;  break;
460      case 'schedule-deliver-reply'          : $out_priv |=  2048;  break;
461      case 'schedule-query-freebusy'         : $out_priv |=  4096;  break;
462      case 'schedule-send-invite'            : $out_priv |=  8192;  break;
463      case 'schedule-send-reply'             : $out_priv |= 16384;  break;
464      case 'schedule-send-freebusy'          : $out_priv |= 32768;  break;
465
466      /** Aggregates of Privileges */
467      case 'write'                           : $out_priv |=   198;  break; // 2 + 4 + 64 + 128
468      case 'schedule-deliver'                : $out_priv |=  7168;  break; // 1024 + 2048 + 4096
469      case 'schedule-send'                   : $out_priv |= 57344;  break; // 8192 + 16384 + 32768
470      case 'all'                             : $out_priv  = DAVICAL_MAXPRIV;  break;
471      default:
472        dbg_error_log( 'ERROR', 'Cannot convert privilege of "%s" into bits.', $priv );
473
474    }
475  }
476
477  // 'all' will include future privileges
478  if ( ($out_priv & DAVICAL_MAXPRIV) >= DAVICAL_MAXPRIV ) $out_priv = pow(2,24) - 1;
479  return $out_priv;
480}
481
482
483/**
484* Given a bit mask of the privileges, will return an array of the
485* text values of privileges.
486* @param integer $raw_bits A bit mask of the privileges.
487* @return mixed The string (or array of strings) of privilege names
488*/
489function bits_to_privilege( $raw_bits, $resourcetype = 'resource' ) {
490  $out_priv = array();
491
492  if ( is_string($raw_bits) ) {
493    $raw_bits = bindec($raw_bits);
494  }
495
496  if ( ($raw_bits & DAVICAL_MAXPRIV) == DAVICAL_MAXPRIV ) $out_priv[] = 'all';
497
498  if ( ($raw_bits &   1) != 0 ) $out_priv[] = 'DAV::read';
499  if ( ($raw_bits &   8) != 0 ) $out_priv[] = 'DAV::unlock';
500  if ( ($raw_bits &  16) != 0 ) $out_priv[] = 'DAV::read-acl';
501  if ( ($raw_bits &  32) != 0 ) $out_priv[] = 'DAV::read-current-user-privilege-set';
502  if ( ($raw_bits & 256) != 0 ) $out_priv[] = 'DAV::write-acl';
503  if ( ($resourcetype == 'calendar' || $resourcetype == 'proxy') && ($raw_bits & 512) != 0 ) $out_priv[] = 'urn:ietf:params:xml:ns:caldav:read-free-busy';
504
505  if ( ($raw_bits & 198) != 0 ) {
506    if ( ($raw_bits & 198) == 198 ) $out_priv[] = 'DAV::write';
507    if ( ($raw_bits &   2) != 0 ) $out_priv[] = 'DAV::write-properties';
508    if ( ($raw_bits &   4) != 0 ) $out_priv[] = 'DAV::write-content';
509    if ( ($raw_bits &  64) != 0 ) $out_priv[] = 'DAV::bind';
510    if ( ($raw_bits & 128) != 0 ) $out_priv[] = 'DAV::unbind';
511  }
512
513  if ( $resourcetype == 'schedule-inbox' && ($raw_bits & 7168) != 0 ) {
514    if ( ($raw_bits & 7168) == 7168 ) $out_priv[] = 'urn:ietf:params:xml:ns:caldav:schedule-deliver';
515    if ( ($raw_bits & 1024) != 0 ) $out_priv[] = 'urn:ietf:params:xml:ns:caldav:schedule-deliver-invite';
516    if ( ($raw_bits & 2048) != 0 ) $out_priv[] = 'urn:ietf:params:xml:ns:caldav:schedule-deliver-reply';
517    if ( ($raw_bits & 4096) != 0 ) $out_priv[] = 'urn:ietf:params:xml:ns:caldav:schedule-query-freebusy';
518  }
519
520  if ( $resourcetype == 'schedule-outbox' && ($raw_bits & 57344) != 0 ) {
521    if ( ($raw_bits & 57344) == 57344 ) $out_priv[] = 'urn:ietf:params:xml:ns:caldav:schedule-send';
522    if ( ($raw_bits &  8192) != 0 ) $out_priv[] = 'urn:ietf:params:xml:ns:caldav:schedule-send-invite';
523    if ( ($raw_bits & 16384) != 0 ) $out_priv[] = 'urn:ietf:params:xml:ns:caldav:schedule-send-reply';
524    if ( ($raw_bits & 32768) != 0 ) $out_priv[] = 'urn:ietf:params:xml:ns:caldav:schedule-send-freebusy';
525  }
526
527//  dbg_error_log( 'DAVResource', ' Privilege bit "%s" is "%s".', $raw_bits, implode(', ', $out_priv) );
528
529  return $out_priv;
530}
531
532
533/**
534* Returns the array of privilege names converted into XMLElements
535*/
536function privileges_to_XML( $privilege_names, &$xmldoc=null ) {
537  if ( !isset($xmldoc) && isset($GLOBALS['reply']) ) $xmldoc = $GLOBALS['reply'];
538  $privileges = array();
539  foreach( $privilege_names AS $k ) {
540    $privilege = new XMLElement('privilege');
541    if ( isset($xmldoc) )
542      $xmldoc->NSElement($privilege,$k);
543    else
544      $privilege->NewElement($k);
545    $privileges[] = $privilege;
546  }
547  return $privileges;
548}
549
Note: See TracBrowser for help on using the repository browser.