Overview

Packages

  • awl
    • caldav-client-v2
    • RRule
  • davical
    • authentication
      • drivers
    • caldav
    • DAViCalSession
    • DAVTicket
    • external-bind
    • feed
    • HTTPAuthSession
    • iSchedule
    • iSchedule-POST
    • logging
    • metrics
    • Principal
    • propfind
    • PublicSession
    • Request
    • Resource
    • tzservice
  • None
  • PHP

Functions

  • create_external
  • Overview
  • Package
  • Function
  • Tree
  • Deprecated
  • Todo
  1: <?php
  2: /**
  3: * Functions for managing external BIND resources
  4: *
  5: *
  6: * @package   davical
  7: * @subpackage   external-bind
  8: * @author    Rob Ostensen <rob@boxacle.net>
  9: * @copyright Rob Ostensen
 10: * @license   http://gnu.org/copyleft/gpl.html GNU GPL v3 or later
 11: */
 12: 
 13: function create_external ( $path,$is_calendar,$is_addressbook )
 14: {
 15:   global $request;
 16:   if ( ! function_exists ( "curl_init" ) ) {
 17:     dbg_error_log("external", "external resource cannot be fetched without curl, please install curl");
 18:     $request->DoResponse( 503, translate('PHP5 curl support is required for external binds') );
 19:     return ;
 20:   }
 21:   $resourcetypes = '<DAV::collection/>';
 22:   if ($is_calendar) $resourcetypes .= '<urn:ietf:params:xml:ns:caldav:calendar/>';
 23:   $qry = new AwlQuery();
 24:   if ( ! $qry->QDo( 'INSERT INTO collection ( user_no, parent_container, dav_name, dav_etag, dav_displayname,
 25:                                  is_calendar, is_addressbook, resourcetypes, created )
 26:               VALUES( :user_no, :parent_container, :dav_name, :dav_etag, :dav_displayname,
 27:                       :is_calendar, :is_addressbook, :resourcetypes, current_timestamp )',
 28:            array(
 29:               ':user_no'          => $request->user_no,
 30:               ':parent_container' => '/.external/',
 31:               ':dav_name'         => $path,
 32:               ':dav_etag'         => md5($request->user_no. $path),
 33:               ':dav_displayname'  => $path,
 34:               ':is_calendar'      => ($is_calendar ? 't' : 'f'),
 35:               ':is_addressbook'   => ($is_addressbook ? 't' : 'f'),
 36:               ':resourcetypes'    => $resourcetypes
 37:             ) ) ) {
 38:     $request->DoResponse( 500, translate('Error writing calendar details to database.') );
 39:   }
 40: }
 41: 
 42: function fetch_external ( $bind_id, $min_age = '1 hour' )
 43: {
 44:   if ( ! function_exists ( "curl_init" ) ) {
 45:     dbg_error_log("external", "external resource cannot be fetched without curl, please install curl");
 46:     $request->DoResponse( 503, translate('PHP5 curl support is required for external binds') );
 47:     return ;
 48:   }
 49:   $sql = 'SELECT collection.*, collection.dav_name AS path, dav_binding.external_url AS external_url FROM dav_binding LEFT JOIN collection ON (collection.collection_id=bound_source_id) WHERE bind_id = :bind_id';
 50:   $params = array( ':bind_id' => $bind_id );
 51:   if ( strlen ( $min_age ) > 2 ) {
 52:     $sql .= ' AND collection.modified + interval :interval < NOW()';
 53:     $params[':interval'] = $min_age;
 54:   }
 55:   $sql .= ' ORDER BY modified DESC LIMIT 1';
 56:   $qry = new AwlQuery( $sql, $params );
 57:   if ( $qry->Exec('DAVResource') && $qry->rows() > 0 && $row = $qry->Fetch() ) {
 58:     $curl = curl_init ( $row->external_url );
 59:     curl_setopt ( $curl, CURLOPT_RETURNTRANSFER, true );
 60:     if ( $row->modified ) {
 61:       $local_ts = new DateTime($row->modified);
 62:       curl_setopt ( $curl, CURLOPT_HEADER, true );
 63:       curl_setopt ( $curl, CURLOPT_FILETIME, true );
 64:       curl_setopt ( $curl, CURLOPT_NOBODY, true );
 65:       curl_setopt ( $curl, CURLOPT_TIMEVALUE, $local_ts->format("U") );
 66:       curl_setopt ( $curl, CURLOPT_TIMECONDITION, CURL_TIMECOND_IFMODSINCE );
 67:       dbg_error_log("external", "checking external resource for remote changes " . $row->external_url );
 68:       $ics = curl_exec ( $curl );
 69:       $info = curl_getinfo ( $curl );
 70:       if ( $info['http_code'] === 304 || (isset($info['filetime']) && $info['filetime'] != -1 && new DateTime("@" . $info['filetime']) <=  $local_ts )) {
 71:         dbg_error_log("external", "external resource unchanged " . $info['filetime'] . '  < ' . $local_ts->getTimestamp() . ' (' . $info['http_code'] . ')');
 72:         curl_close ( $curl );
 73:         // BUGlet: should track server-time instead of local-time
 74:         $qry = new AwlQuery( 'UPDATE collection SET modified=NOW() WHERE collection_id = :cid', array ( ':cid' => $row->collection_id ) );
 75:         $qry->Exec('DAVResource');
 76:         return true;
 77:       }
 78:       dbg_error_log("external", "external resource changed, re importing" . $info['filetime'] );
 79:     }
 80:     else {
 81:       dbg_error_log("external", "fetching external resource for the first time " . $row->external_url );
 82:     }
 83:     curl_setopt ( $curl, CURLOPT_NOBODY, false );
 84:     curl_setopt ( $curl, CURLOPT_HEADER, false );
 85:     $ics = curl_exec ( $curl );
 86:     curl_close ( $curl );
 87:     if ( is_string ( $ics ) && strlen ( $ics ) > 20 ) {
 88:       // BUGlet: should track server-time instead of local-time
 89:       $qry = new AwlQuery( 'UPDATE collection SET modified=NOW(), dav_etag=:etag WHERE collection_id = :cid',
 90:         array ( ':cid' => $row->collection_id, ':etag' => md5($ics) ) );
 91:       $qry->Exec('DAVResource');
 92:       require_once ( 'caldav-PUT-functions.php');
 93:       import_collection ( $ics , $row->user_no, $row->path, 'External Fetch' , false ) ;
 94:       return true;
 95:     }
 96:   }
 97:   else {
 98:     dbg_error_log("external", "external resource up to date or not found id(%s)", $bind_id );
 99:   }
100:   return false;
101: }
102: 
103: function update_external ( $request )
104: {
105:   global $c;
106:   if ( $c->external_refresh < 1 )
107:     return ;
108:   if ( ! function_exists ( "curl_init" ) ) {
109:     dbg_error_log("external", "external resource cannot be fetched without curl, please install curl");
110:     return ;
111:   }
112:   $sql = 'SELECT bind_id, external_url as url from dav_binding LEFT JOIN collection ON (collection.collection_id=bound_source_id) WHERE dav_binding.dav_name = :dav_name AND collection.modified + interval :interval < NOW()';
113:   $qry = new AwlQuery( $sql, array ( ':dav_name' => $request->dav_name(), ':interval' => $c->external_refresh . ' minutes' ) );
114:   dbg_error_log("external", "checking if external resource needs update");
115:   if ( $qry->Exec('DAVResource') && $qry->rows() > 0 && $row = $qry->Fetch() ) {
116:     if ( $row->bind_id != 0 ) {
117:       dbg_error_log("external", "external resource needs updating, this might take a minute : %s", $row->url );
118:       fetch_external ( $row->bind_id, $c->external_refresh . ' minutes' );
119:     }
120:   }
121: }
122: 
DAViCal API documentation generated by ApiGen 2.8.0