[ Index ]
 

Code source de eGroupWare 1.2.106-2

Accédez au Source d'autres logiciels libresSoutenez Angelica Josefina !

title

Body

[fermer]

/phpgwapi/inc/ -> class.http_dav_client.inc.php (source)

   1  <?php
   2    /**************************************************************************\
   3    * eGroupWare API - WebDAV                                                  *
   4    * This file written by Jonathon Sim (for Zeald Ltd) <jsim@free.net.nz>     *
   5    * Provides methods for manipulating an RFC 2518 DAV repository             *
   6    * Copyright (C) 2002 Zeald Ltd                                             *
   7    * -------------------------------------------------------------------------*
   8    * This library is part of the eGroupWare API                               *
   9    * http://www.egroupware.org/api                                            *
  10    * ------------------------------------------------------------------------ *
  11    * This library is free software; you can redistribute it and/or modify it  *
  12    * under the terms of the GNU Lesser General Public License as published by *
  13    * the Free Software Foundation; either version 2.1 of the License,         *
  14    * or any later version.                                                    *
  15    * This library is distributed in the hope that it will be useful, but      *
  16    * WITHOUT ANY WARRANTY; without even the implied warranty of               *
  17    * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.                     *
  18    * See the GNU Lesser General Public License for more details.              *
  19    * You should have received a copy of the GNU Lesser General Public License *
  20    * along with this library; if not, write to the Free Software Foundation,  *
  21    * Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA            *
  22    \**************************************************************************/
  23  
  24    /* $Id: class.http_dav_client.inc.php 16311 2004-08-09 13:46:03Z reinerj $ */
  25  
  26    /*At the moment much of this is simply a wrapper around the NET_HTTP_Client class,
  27    with some other methods for parsing the returned XML etc
  28    Ideally this will eventually use groupware's inbuilt HTTP class
  29    */
  30  
  31    define ('DEBUG_DAV_CLIENT', 0);
  32    define ('DEBUG_DAV_XML', 0);
  33    define ('DEBUG_CACHE', 0);
  34  
  35  
  36  ##############################################################
  37  # 'Private' classes - these are only used internally and should
  38  # not be used by external code
  39  ##############################################################
  40  
  41      /*
  42      PHP STILL doesnt have any sort of stable DOM parser.  So lets make our
  43      own XML parser, that parses XML into a tree of arrays (I know, it could do
  44      something resembling DOM, but it doesnt!)
  45      */
  46      class xml_tree_parser
  47      {
  48          var $namespaces;
  49          var $current_element;
  50          var $num = 1;
  51          var $tree = NULL;
  52  
  53          /*
  54          This is the only end-user function in the class.  Call parse with an XML string, and
  55          you will get back the tree of 'element' arrays
  56          */
  57  		function parse($xml_string)
  58          {
  59              $this->xml_parser = xml_parser_create();
  60              xml_set_element_handler($this->xml_parser,array(&$this,"start_element"),array(&$this,"end_element"));
  61              xml_set_character_data_handler($this->xml_parser,array(&$this,"parse_data"));
  62  
  63              $this->parser_result=array();
  64              $this->xml = $xml_string;
  65              xml_parse($this->xml_parser,$xml_string);
  66              xml_parser_free($this->xml_parser);
  67              if (DEBUG_DAV_XML) 
  68              {
  69                  echo '<pre>'.htmlentities($xml_string).'</pre>';
  70                  echo 'parsed to:' ; $this->print_tree();
  71              }
  72              return $this->tree;
  73          }
  74          
  75          //a useful function for debug output - will print the tree after parsing
  76  		function print_tree($element=NULL, $prefix='|', $processed=array()) 
  77          {    
  78          
  79              if ($processed[$element['id']])
  80              {
  81                  echo '<b>***RECURSION!!***</b></br>';    
  82                  die();
  83              }
  84              else
  85              {
  86                  $processed[$element['id']] = true;
  87              }
  88              
  89              if ($element == NULL)
  90              {
  91                  $element = $this->tree;
  92              }
  93              echo $prefix.$element['namespace'].':'.$element['name'].' '.$element['start'].'->'.$element['end'].'<br>';
  94              $prefix .= '-->';
  95              if ($element['data'])
  96              {
  97                  echo $prefix.$element['data'].'<br>';
  98              }
  99  
 100              foreach ($element['children'] as $id=>$child)
 101              {
 102                  $this->print_tree($child, $prefix, &$processed);
 103              }
 104              
 105          }
 106          
 107          //called by the xml parser at the start of an element, it creates that elements node in the tree
 108  		function start_element($parser,$name,$attr)
 109          {
 110              
 111              if (preg_match('/(.*):(.*)/', $name, $matches))
 112              {
 113                  $ns = $this->namespaces[$matches[1]];
 114                  $element = $matches[2];
 115              }
 116              else
 117              {
 118                  $element = $name;
 119              }
 120              
 121              if ($this->tree == NULL) 
 122              {
 123                  $this->tree = array(
 124                      'namespace'=>$ns,
 125                      'name' => $element,
 126                      'attributes' => $attr,
 127                      'data' => '',
 128                      'children' => array(),
 129                      'parent' => NULL,
 130                      'type' => 'xml_element',
 131                      'id' => $this->num
 132                      );
 133                  $this->current_element = &$this->tree;
 134              }
 135              else
 136              {    
 137                  $parent = &$this->current_element;    
 138                  $parent['children'][$this->num]=array(
 139                      'namespace'=>$ns,
 140                      'name' => $element,
 141                      'attributes' => $attr,
 142                      'data' => '',
 143                      'children' => array(),
 144                      'parent' => &$parent,
 145                      'type' => 'xml_element',
 146                      'id' => $this->num
 147                      );
 148                  $this->current_element = &$parent['children'][$this->num];                
 149              }
 150              $this->num++;
 151              $this->current_element['start'] = xml_get_current_byte_index($parser);
 152              foreach ($attr as $name => $value)
 153              {
 154                  if (ereg('^XMLNS:(.*)', $name, $matches) )
 155                  {
 156                      $this->namespaces[$matches[1]] = $value;
 157                  }
 158              }
 159          }
 160  
 161          //at the end of an element, stores the start and end positions in the xml stream, and moves up the tree
 162  		function end_element($parser,$name)
 163          {
 164              $curr = xml_get_current_byte_index($parser);
 165              $this->current_element['end'] =strpos($this->xml, '>', $curr);
 166              $this->current_element = &$this->current_element['parent'];        
 167              
 168          }
 169  
 170          //if there is a CDATA element, puts it into the parent elements node
 171  		function parse_data($parser,$data)
 172          {
 173              $this->current_element['data']=$data;
 174          }
 175          
 176      }
 177      
 178      /*This class uses a bunch of recursive functions to process the DAV XML tree
 179      digging out the relevent information and putting it into an array
 180      */
 181      class dav_processor
 182      {
 183  		function dav_processor($xml_string)
 184          {
 185              $this->xml = $xml_string;
 186              $this->dav_parser = new xml_tree_parser();
 187              $this->tree = $this->dav_parser->parse($xml_string);
 188              
 189          }
 190          
 191  		function process_tree(&$element, &$result_array)
 192          {
 193      
 194              //This lets us mark a node as 'done' and provides protection against infinite loops
 195              if ($this->processed[$element['id']])
 196              {
 197                  return $result_array;    
 198              }
 199              else
 200              {
 201                  $this->processed[$element['id']] = true;
 202              }
 203              
 204              if ( $element['namespace'] == 'DAV:')
 205              {
 206                  if ($element['name'] == 'RESPONSE')
 207                  {
 208                          $result = array(         
 209                              'size' => 0,
 210                              'getcontenttype' => 'application/octet-stream',
 211                              'is_dir' => 0
 212                      );
 213                      foreach ($element['children'] as $id=>$child)
 214                      {
 215                          $this->process_properties($child, $result);
 216                      }
 217                      $result_array[$result['full_name']] = $result;
 218                      
 219                  }
 220              }
 221              // ->recursion
 222              foreach ($element['children'] as $id=>$child)
 223              {
 224                  $this->process_tree($child, $result_array);
 225              }
 226              return $result_array;
 227          }
 228          
 229  		function process_properties($element, &$result_array)
 230          {    
 231              if ($this->processed[$element['id']])
 232              {
 233                  return $result_array;    
 234              }
 235              else
 236              {
 237                  $this->processed[$element['id']] = true;
 238              }
 239  
 240              if ( $element['namespace'] == 'DAV:')
 241              {
 242                  switch ($element['name'])
 243                  {
 244                      case 'HREF':
 245                          $string = $element['data'];
 246                          $idx=strrpos($string,SEP);
 247                          if($idx && $idx==strlen($string)-1)
 248                          {
 249                              $this->current_ref=substr($string,0,$idx);
 250                          }
 251                          else
 252                          {
 253                              $this->current_ref=$string;
 254                          }
 255                          $result_array['name']=basename($string);
 256                          $result_array['directory']=dirname($string);
 257                          $result_array['full_name'] = $this->current_ref;
 258                      break;
 259                      case 'SUPPORTEDLOCK':
 260                          if (count($element['children'])) //There are active locks
 261                          {
 262                              $result_array['supported_locks'] = array();
 263                              foreach ($element['children'] as $id=>$child)
 264                              {
 265                                  $this->process_properties($child, $result_array['supported_locks']);
 266                              }
 267                          }    
 268                      break;
 269                      case 'LOCKDISCOVERY':
 270                          if (count($element['children'])) //There are active locks
 271                          {
 272                              $result_array['locks'] = array();
 273                              foreach ($element['children'] as $id=>$child)
 274                              {
 275                                  $this->process_properties($child, $result_array['locks']);
 276                              }
 277                      }    
 278                      break;
 279                      case 'LOCKENTRY':
 280                          if (count($element['children'])) 
 281                          {
 282                              $result_array[$element['id']] = array();
 283                              foreach ($element['children'] as $id=>$child)
 284                              {
 285                                  $this->process_properties($child, $result_array[$element['id']] );
 286                              }
 287                      }    
 288                      break;
 289                      case 'ACTIVELOCK':
 290                          if (count($element['children'])) 
 291                          {
 292                              $result_array[$element['id']] = array();
 293                              foreach ($element['children'] as $id=>$child)
 294                              {
 295                                  $this->process_properties($child, $result_array[$element['id']] );
 296                              }
 297                      }    
 298                      break;
 299                      case 'OWNER':
 300                          $result_array['owner'] = array();
 301  
 302                          foreach ($element['children'] as $child) 
 303                          {
 304                              $this->process_verbatim($child, &$result_array['owner'][]);                            
 305                          }
 306                          
 307                          //print_r($element);die();
 308                          //die();
 309                          $result_array['owner_xml'] = substr($this->xml, $element['start'], $element['end']-$element['start']+1);
 310                          return $result_array; //No need to process this branch further
 311                      break;    
 312                      case 'LOCKTOKEN':
 313                          if (count($element['children'])) 
 314                          {
 315                              
 316                              foreach ($element['children'] as $id=>$child)
 317                              {
 318                                  $this->process_properties($child, $tmp_result , $processed);
 319                                  $result_array['lock_tokens'][$tmp_result['full_name']] = $tmp_result;
 320                              }
 321                      }    
 322                      break;
 323                      case 'LOCKTYPE':
 324                          $child = end($element['children']);
 325                          if ($child) 
 326                          {
 327                              $this->processed[$child['id']] = true;
 328                              $result_array['locktype'] = $child['name'];
 329                          }
 330                      break;
 331                      case 'LOCKSCOPE':
 332                          $child = end($element['children']);
 333                          if ($child) 
 334                          {
 335                              $this->processed[$child['id']] = true;
 336                              $result_array['lockscope'] = $child['name'];
 337                          }
 338                      break;
 339                      default:
 340                          if (trim($element['data']))
 341                          {
 342                              $result_array[strtolower($element['name'])] = $element['data'];
 343                          }
 344                  }
 345              }
 346              else
 347              {
 348                  if (trim($element['data']))
 349                  {
 350                      $result_array[strtolower($element['name'])] = $element['data'];
 351                  }
 352              }
 353  
 354              foreach ($element['children'] as $id=>$child)
 355              {
 356                  $this->process_properties($child, $result_array);
 357              }
 358              
 359              return $result_array;
 360          }    
 361          
 362  		function process_verbatim($element, &$result_array)
 363          {    
 364              if ($this->processed[$element['id']])
 365              {
 366                  return $result_array;    
 367              }
 368              else
 369              {
 370                  $this->processed[$element['id']] = true;
 371              }
 372              
 373              foreach ( $element as $key => $value)
 374              {
 375                  //The parent link is death to naive programmers (eg me) :)
 376                  if (!( $key == 'children' || $key == 'parent') )
 377                  {
 378                      $result_array[$key] = $value;
 379                  }
 380              }
 381              $result_array['children'] = array();        
 382              foreach ($element['children'] as $id=>$child)
 383              {
 384                  echo 'processing child:';
 385                  $this->process_verbatim($child, $result_array['children']);
 386              }
 387              return $result_array;
 388          }
 389      }
 390      
 391  #####################################################
 392  #This is the actual public interface of this class
 393  #####################################################
 394      class http_dav_client 
 395      {
 396          var $attributes=array();
 397          var $vfs_property_map = array();
 398          var $cached_props =  array();
 399  		function http_dav_client()
 400          {
 401              $this->http_client = CreateObject('phpgwapi.net_http_client');
 402              $this->set_debug(0);
 403          }
 404          
 405          //TODO:  Get rid of this
 406          //A quick, temporary debug output function
 407  		function debug($info) {
 408  
 409              if (DEBUG_DAV_CLIENT)
 410              {
 411                  echo '<b> http_dav_client debug:<em> ';
 412                  if (is_array($info))
 413                  {
 414                      print_r($info);
 415                  }
 416                  else
 417                  {
 418                      echo $info;
 419                  }
 420                  echo '</em></b><br>';
 421              }
 422          }
 423          /*!
 424          @function glue_url
 425          @abstract glues a parsed url (ie parsed using PHP's parse_url) back
 426              together
 427          @param $url    The parsed url (its an array)
 428          */
 429          
 430  		function glue_url ($url){
 431              if (!is_array($url))
 432              {
 433                  return false;
 434              }
 435              // scheme
 436              $uri = (!empty($url['scheme'])) ? $url['scheme'].'://' : '';
 437              // user & pass
 438              if (!empty($url['user']))
 439              {
 440                  $uri .= $url['user'];
 441                  if (!empty($url['pass']))
 442                  {
 443                      $uri .=':'.$url['pass'];
 444                  }
 445                  $uri .='@'; 
 446              }
 447              // host 
 448              $uri .= $url['host'];
 449              // port 
 450              $port = (!empty($url['port'])) ? ':'.$url['port'] : '';
 451              $uri .= $port; 
 452              // path 
 453              $uri .= $url['path'];
 454              // fragment or query
 455              if (isset($url['fragment']))
 456              {
 457                  $uri .= '#'.$url['fragment'];
 458              } elseif (isset($url['query']))
 459              {
 460                  $uri .= '?'.$url['query'];
 461              }
 462              return $uri;
 463          }    
 464          
 465          /*!
 466          @function encodeurl
 467          @abstract encodes a url from its "display name" to something the dav server will accept
 468          @param uri The unencoded uri
 469          @discussion
 470              Deals with "url"s which may contain spaces and other unsavoury characters,
 471              by using appropriate %20s
 472          */            
 473  		function encodeurl($uri)
 474          {
 475              $parsed_uri =  parse_url($uri);
 476              if (empty($parsed_uri['scheme']))
 477              {
 478                  $path = $uri;
 479              }
 480              else
 481              {
 482                  $path = $parsed_uri['path'];
 483              }
 484              $fixed_array = array();
 485              foreach (explode('/', $path) as $name)
 486              {
 487                  $fixed_array[] = rawurlencode($name);
 488              }
 489              $fixed_path = implode('/', $fixed_array);
 490              if (!empty($parsed_uri['scheme']))
 491              {
 492                  $parsed_uri['path'] = $fixed_path;
 493                  $newuri = $this->glue_url($parsed_uri);
 494              }
 495              else
 496              {
 497                  $newuri = $fixed_path;
 498              }            
 499              return $newuri;
 500              
 501          }
 502          /*!
 503          @function decodeurl
 504          @abstract decodes a url to its "display name"
 505          @param uri The encoded uri
 506          @discussion
 507              Deals with "url"s which may contain spaces and other unsavoury characters,
 508              by using appropriate %20s
 509          */        
 510  		function decodeurl($uri)
 511          {
 512              $parsed_uri =  parse_url($uri);
 513              if (empty($parsed_uri['scheme']))
 514              {
 515                  $path = $uri;
 516              }
 517              else
 518              {
 519                  $path = $parsed_uri['path'];
 520              }
 521              $fixed_array = array();
 522              foreach (explode('/', $path) as $name)
 523              {
 524                  $fixed_array[]  = rawurldecode($name);
 525              }
 526              $fixed_path = implode('/', $fixed_array);
 527              if (!empty($parsed_uri['scheme']))
 528              {
 529                  $parsed_uri['path'] = $fixed_path;
 530                  $newuri = $this->glue_url($parsed_uri);
 531              }
 532              else
 533              {
 534                  $newuri = $fixed_path;
 535              }            
 536              return $newuri;
 537              
 538          }
 539          /*!
 540          @function set_attributes
 541          @abstract Sets the "attribute map"
 542          @param attributes Attributes to extract "as-is" from the DAV properties
 543          @param dav_map A mapping of dav_property_name => attribute_name for attributes 
 544              with different names in DAV and the desired name space.
 545          @discussion
 546              This is mainly for use by VFS, where the VFS attributes (eg size) differ
 547              from the corresponding DAV ones ("getcontentlength")
 548          */
 549  		function set_attributes($attributes, $dav_map)
 550          {
 551              $this->vfs_property_map = $dav_map;
 552              $this->attributes = $attributes;
 553          }
 554          
 555          /*!
 556          @function set_credentials
 557          @abstract Sets authentication credentials for HTTP AUTH
 558          @param username The username to connect with
 559          @param password The password to connect with
 560          @discussion
 561              The only supported authentication type is "basic"
 562          */
 563  		function set_credentials( $username, $password )
 564          {
 565              $this->http_client->setCredentials($username, $password );
 566          }
 567  
 568          /*!
 569          @function connect
 570          @abstract connects to the server
 571          @param dav_host The host to connect to
 572          @param dav_port The port to connect to
 573          @discussion
 574              If the server requires authentication you will need to set credentials
 575              with set_credentials first
 576          */
 577  
 578  		function connect($dav_host,$dav_port)
 579          {
 580              $this->dav_host = $dav_host;
 581              $this->dav_port = $dav_port;
 582              $this->http_client->addHeader('Host',$this->dav_host);
 583              $this->http_client->addHeader('Connection','close');
 584              //$this->http_client->addHeader('transfer-encoding','identity');
 585      //        $this->http_client->addHeader('Connection','keep-alive');
 586      //        $this->http_client->addHeader('Keep-Alive','timeout=20, state="Accept,Accept-Language"');
 587              $this->http_client->addHeader('Accept-Encoding','chunked');
 588              $this->http_client->setProtocolVersion( '1.1' );
 589              $this->http_client->addHeader( 'user-agent', 'Mozilla/5.0 (compatible; eGroupWare dav_client/1; Linux)');
 590              return $this->http_client->Connect($dav_host,$dav_port);
 591          }
 592  		function set_debug($debug)
 593          {
 594              $this->http_client->setDebug($debug);
 595          }
 596  
 597          /*!
 598          @function disconnect
 599          @abstract disconnect from the server
 600          @discussion
 601              When doing HTTP 1.1 we frequently close/reopen the connection
 602              anyway, so this function needs to be called after any other DAV calls
 603              (since if they find the connection closed, they just reopen it)
 604          */
 605  
 606  		function disconnect()
 607          {
 608              $this->http_client->Disconnect();
 609          }
 610          
 611          /*!
 612          @function get_properties
 613          @abstract a high-level method of getting DAV properties
 614          @param url The URL to get properties for
 615          @param scope the 'depth' to recuse subdirectories (default 1)
 616          @param sorted whether we should sort the rsulting array (default True)
 617          @result array of file->property arra
 618          @discussion
 619              This function performs all the necessary XML parsing etc to convert DAV properties (ie XML nodes)
 620              into associative arrays of properties - including doing mappings
 621              from DAV property names to any desired property name format (eg the VFS one)
 622              This is controlled by the attribute arrays set in the set_attributes function.
 623          */
 624  		function get_properties($url,$scope=1){
 625              $request_id = $url.'//'.$scope.'//'.$sorted; //A unique id for this request (for caching)
 626              if ($this->cached_props[$request_id])
 627              {
 628  if (DEBUG_CACHE) echo'Cache hit : cache id:'.$request_id;
 629                  return $this->cached_props[$request_id];
 630              }
 631              else if (! $sorted && $this->cached_props[$url.'//'.$scope.'//1'])
 632              {
 633  if (DEBUG_CACHE) echo ' Cache hit : cache id: '.$request_id;
 634                  return $this->cached_props[$url.'//'.$scope.'//1'];
 635              }
 636  if (DEBUG_CACHE) 
 637  {
 638      echo ' <b>Cache miss </b>: cache id: '.$request_id;
 639  /*    echo " cache:<pre>";
 640      print_r($this->cached_props);
 641      echo '</pre>';*/
 642  }
 643      
 644  
 645              if($this->propfind($url,$scope) != 207)
 646              {
 647                  if($this->propfind($url.'/',$scope) != 207)
 648                  {
 649                      return array();
 650                  }
 651              }
 652              $xml_result=$this->http_client->getBody();
 653              $result_array = array();
 654              $dav_processor = new dav_processor($xml_result);
 655              $tmp_list = $dav_processor->process_tree($dav_processor->tree, $result_array);
 656  
 657              foreach($tmp_list as $name=>$item) {
 658                  $fixed_name = $this->decodeurl($name);
 659                  $newitem = $item;
 660                  $newitem['is_dir']= ($item['getcontenttype'] =='httpd/unix-directory' ? 1 : 0);
 661                  $item['directory'] = $this->decodeurl($item['directory']);
 662                  //Since above we sawed off the protocol and host portions of the url, lets readd them.
 663                  if (strlen($item['directory'])) {
 664                      $path = $item['directory'];
 665                      $host = $this->dav_host;
 666                      $newitem['directory'] = $host.$path;
 667                  }
 668  
 669                  //Get any extra properties that may share the vfs name
 670                  foreach ($this->attributes as $num=>$vfs_name)
 671                  {
 672                      if ($item[$vfs_name])
 673                      {
 674                          $newitem[$vfs_name] = $item[$vfs_name];
 675                      }
 676                  }
 677  
 678                  //Map some DAV properties onto VFS ones.
 679                  foreach ($this->vfs_property_map as $dav_name=>$vfs_name)
 680                  {
 681                      if ($item[$dav_name])
 682                      {
 683                          $newitem[$vfs_name] = $item[$dav_name];
 684                      }
 685                  }
 686                  
 687                  if ($newitem['is_dir'] == 1)
 688                  {
 689                      $newitem['mime_type']='Directory';
 690                  }
 691                  
 692                  $this->debug('<br><br>properties:<br>');
 693                  $this->debug($newitem);
 694                  $newitem['name'] = $this->decodeurl($newitem['name']);
 695                  $result[$fixed_name]=$newitem;
 696                  if ($newitem['is_dir']==1)
 697                  {
 698                      $this->cached_props[$name.'//0//1'] = array($fixed_name=>$newitem);
 699                  }
 700                  else
 701                  {
 702                      $this->cached_props[$name.'//1//1'] = array($fixed_name=>$newitem);
 703                  }
 704              }
 705              if ($sorted)
 706              {
 707                  ksort($result);
 708              }
 709              $this->cached_props[$request_id] = $result;
 710              return $result;
 711          }
 712          
 713  		function get($uri)
 714          {
 715              $uri = $this->encodeurl($uri);
 716              return $this->http_client->Get($uri);
 717          }
 718  
 719          /*!
 720          @function get_body
 721          @abstract return the response body
 722          @result string body content
 723          @discussion
 724              invoke it after a Get() call for instance, to retrieve the response
 725          */
 726  		function get_body()
 727          {
 728              return $this->http_client->getBody();
 729          }
 730  
 731          /*!
 732          @function get_headers
 733          @abstract return the response headers
 734          @result array headers received from server in the form headername => value
 735          @discussion
 736              to be called after a Get() or Head() call
 737          */
 738  		function get_headers()
 739          {
 740              return $this->http_client->getHeaders();
 741          }
 742  
 743          /*!
 744          @function copy
 745          @abstract PUT is the method to sending a file on the server.
 746          @param uri the location of the file on the server. dont forget the heading "/"
 747          @param data the content of the file. binary content accepted
 748          @result string response status code 201 (Created) if ok
 749          */
 750  		function put($uri, $data, $token='')
 751          {
 752          $uri = $this->encodeurl($uri);
 753  if (DEBUG_CACHE) echo '<b>cache cleared</b>';
 754          if (strlen($token)) 
 755          {
 756              $this->http_client->addHeader('If', '<'.$uri.'>'.' (<'.$token.'>)');
 757          }
 758  
 759          $this->cached_props = array();
 760          $result = $this->http_client->Put($uri, $data);
 761          $this->http_client->removeHeader('If');
 762          return $result;
 763          }
 764          
 765          /*!
 766          @function copy
 767          @abstract Copy a file -allready on the server- into a new location
 768          @param srcUri the current file location on the server. dont forget the heading "/"
 769          @param destUri the destination location on the server. this is *not* a full URL
 770          @param overwrite boolean - true to overwrite an existing destination - overwrite by default
 771          @result Returns the HTTP status code
 772          @discussion
 773              returns response status code 204 (Unchanged) if ok
 774          */
 775  		function copy( $srcUri, $destUri, $overwrite=true, $scope=0, $token='')
 776          {
 777              $srcUri = $this->encodeurl($srcUri);
 778              $destUri = $this->encodeurl($destUri);
 779  if (DEBUG_CACHE) echo '<b>cache cleared</b>';
 780              if (strlen($token)) 
 781              {
 782                  $this->http_client->addHeader('If', '<'.$uri.'>'.' (<'.$token.'>)');
 783              }
 784              $this->cached_props = array();
 785              $result = $this->http_client->Copy( $srcUri, $destUri, $overwrite, $scope);
 786              $this->http_client->removeHeader('If');
 787              return $result;
 788          }
 789  
 790          /*!
 791          @function move
 792          @abstract Moves a WEBDAV resource on the server
 793          @param srcUri the current file location on the server. dont forget the heading "/"
 794          @param destUri the destination location on the server. this is *not* a full URL
 795          @param overwrite boolean - true to overwrite an existing destination (default is yes)
 796          @result Returns the HTTP status code
 797          @discussion
 798              returns response status code 204 (Unchanged) if ok
 799          */
 800  		function move( $srcUri, $destUri, $overwrite=true, $scope=0, $token='' )
 801          {
 802              $srcUri = $this->encodeurl($srcUri);
 803              $destUri = $this->encodeurl($destUri);
 804  if (DEBUG_CACHE) echo '<b>cache cleared</b>';
 805              if (strlen($token)) 
 806              {
 807                  $this->http_client->addHeader('If', '<'.$uri.'>'.' (<'.$token.'>)');
 808              }
 809              $this->cached_props = array();
 810              $result = $this->http_client->Move( $srcUri, $destUri, $overwrite, $scope);
 811              $this->http_client->removeHeader('If');
 812              return $result;
 813          }
 814  
 815          /*!
 816          @function delete
 817          @abstract Deletes a WEBDAV resource
 818          @param uri The URI we are deleting
 819          @result Returns the HTTP status code
 820          @discussion
 821              returns response status code 204 (Unchanged) if ok
 822          */
 823  		function delete( $uri, $scope=0, $token='')
 824          {
 825              $uri = $this->encodeurl($uri);
 826  if (DEBUG_CACHE) echo '<b>cache cleared</b>';
 827              if (strlen($token)) 
 828              {
 829                  $this->http_client->addHeader('If', '<'.$uri.'>'.' (<'.$token.'>)');
 830              }
 831              
 832              $this->cached_props = array();
 833              $result = $this->http_client->Delete( $uri, $scope);
 834              $this->http_client->removeHeader('If');
 835              return $result;
 836          }
 837          
 838          /*!
 839          @function mkcol
 840          @abstract Creates a WEBDAV collection (AKA a directory)
 841          @param uri The URI to create
 842          @result Returns the HTTP status code
 843          */
 844  		function mkcol( $uri, $token='' )
 845          {
 846              $uri = $this->encodeurl($uri);
 847  if (DEBUG_CACHE) echo '<b>cache cleared</b>';
 848              if (strlen($token)) 
 849              {
 850                  $this->http_client->addHeader('If', '<'.$uri.'>'.' (<'.$token.'>)');
 851              }
 852              $this->cached_props = array();
 853              return $this->http_client->MkCol( $uri );
 854              $this->http_client->removeHeader('If');
 855          }
 856  
 857          /*!
 858          @function propfind
 859          @abstract Queries WEBDAV properties
 860          @param uri uri of resource whose properties we are changing
 861          @param scope Specifies how "deep" to search (0=just this file/dir 1=subfiles/dirs etc)
 862          @result Returns the HTTP status code
 863          @discussion
 864              to get the result XML call get_body()
 865          */
 866  		function propfind( $uri, $scope=0 )
 867          {
 868              $uri = $this->encodeurl($uri);
 869              return $this->http_client->PropFind( $uri, $scope);
 870          }
 871          /*!
 872          @function proppatch
 873          @abstract Sets DAV properties
 874          @param uri uri of resource whose properties we are changing
 875          @param attributes An array of attributes and values.
 876          @param namespaces Extra namespace definitions that apply to the properties
 877          @result Returns the HTTP status code
 878          @discussion
 879              To make DAV properties useful it helps to use a well established XML dialect
 880              such as the "Dublin Core"
 881  
 882          */
 883  		function proppatch($uri, $attributes,  $namespaces='', $token='')
 884          {
 885              $uri = $this->encodeurl($uri);
 886  if (DEBUG_CACHE) echo '<b>cache cleared</b>';
 887              if (strlen($token)) 
 888              {
 889                  $this->http_client->addHeader('If', '<'.$uri.'>'.' (<'.$token.'>)');
 890              }
 891              $this->cached_props = array();
 892              //Begin evil nastiness
 893              $davxml = '<?xml version="1.0" encoding="utf-8" ?>
 894  <D:propertyupdate xmlns:D="DAV:"';
 895  
 896              if ($namespaces)
 897              {
 898                  $davxml .= ' ' . $namespaces;
 899              }
 900              $davxml .= ' >';
 901              foreach ($attributes as $name => $value)
 902              {
 903                  $davxml .= '
 904    <D:set>
 905      <D:prop>
 906         <'.$name.'>'.utf8_encode(htmlspecialchars($value)).'</'.$name.'>
 907      </D:prop>
 908    </D:set>
 909  ';
 910              }
 911              $davxml .= '
 912  </D:propertyupdate>';
 913  
 914              if (DEBUG_DAV_XML) {
 915                  echo '<b>send</b><pre>'.htmlentities($davxml).'</pre>';
 916              }
 917              $this->http_client->requestBody = $davxml;
 918              if( $this->http_client->sendCommand( 'PROPPATCH '.$uri.' HTTP/1.1' ) )
 919              {
 920                  $this->http_client->processReply();
 921              }
 922  
 923              if (DEBUG_DAV_XML) {
 924                  echo '<b>Recieve</b><pre>'.htmlentities($this->http_client->getBody()).'</pre>';
 925              }
 926              $this->http_client->removeHeader('If');
 927              return $this->http_client->reply;
 928          }
 929          
 930          /*!
 931          @function unlock
 932          @abstract unlocks a locked resource on the DAV server
 933          @param uri uri of the resource we are unlocking
 934          @param a 'token' for the lock (to get the token, do a propfind)
 935          @result true if successfull
 936          @discussion
 937              Not all DAV servers support locking (its in the RFC, but many common
 938              DAV servers only implement "DAV class 1" (no locking)
 939          */    
 940                  
 941  		function unlock($uri, $token)
 942          {
 943              $uri = $this->encodeurl($uri);
 944  if (DEBUG_CACHE) echo '<b>cache cleared</b>';
 945              $this->cached_props = array();
 946              $this->http_client->addHeader('Lock-Token', '<'.$token.'>');
 947              $this->http_client->sendCommand( 'UNLOCK '.$uri.' HTTP/1.1');
 948              $this->http_client->removeHeader('Lock-Token');
 949              $this->http_client->processReply();
 950              if ( $this->http_client->reply  == '204')
 951              {
 952                  return true;
 953              }
 954              else
 955              {
 956                  $headers = $this->http_client->getHeaders();
 957                  echo $this->http_client->getBody();
 958                  if ($headers['Content-Type'] == 'text/html')
 959                  {
 960                      echo $this->http_client->getBody();
 961                      die();
 962                  }
 963                  else
 964                  {
 965                      return false;
 966                  }
 967              }
 968          }
 969          
 970          /*!
 971          @function lock
 972          @abstract locks a resource on the DAV server
 973          @param uri uri of the resource we are locking
 974          @param owner the 'owner' information for the lock (purely informative)
 975          @param depth the depth to which we lock collections
 976          @result true if successfull
 977          @discussion
 978              Not all DAV servers support locking (its in the RFC, but many common
 979              DAV servers only implement "DAV class 1" (no locking)
 980          */    
 981  		function lock($uri, $owner, $depth=0, $timeout='infinity')
 982          {
 983              $uri = $this->encodeurl($uri);
 984  if (DEBUG_CACHE) echo '<b>cache cleared</b>';
 985              $this->cached_props = array();
 986              $body = "<?xml version=\"1.0\" encoding=\"utf-8\" ?>
 987  <D:lockinfo xmlns:D='DAV:'>
 988  <D:lockscope><D:exclusive/></D:lockscope>\n<D:locktype><D:write/></D:locktype>
 989      <D:owner><D:href>$owner</D:href></D:owner>
 990  </D:lockinfo>\n";
 991          
 992          $this->http_client->requestBody = utf8_encode( $body );
 993          $this->http_client->addHeader('Depth', $depth);
 994          if (! (strtolower(trim($timeout)) == 'infinite'))
 995          {
 996              $timeout = 'Second-'.$timeout;
 997          }
 998          $this->http_client->addHeader('Timeout', $timeout);
 999          
1000          if( $this->http_client->sendCommand( "LOCK $uri HTTP/1.1" ) )
1001              $this->http_client->processReply();
1002              $this->http_client->removeHeader('timeout');
1003              if ( $this->http_client->reply  == '200')
1004              {
1005                  return true;
1006              }
1007              else
1008              {
1009                  $headers = $this->http_client->getHeaders();
1010                  echo $this->http_client->getBody();
1011                  return false;
1012  
1013              }
1014  
1015          }
1016          /*!
1017          @function options
1018          @abstract determines the optional HTTP features supported by a server
1019          @param uri uri of the resource we are seeking options for (or * for the whole server)
1020          @result Returns an array of option values
1021          @discussion
1022              Interesting options include "ACCESS" (whether you can read a file) and
1023              DAV (DAV features)
1024  
1025          */
1026  		function options($uri)
1027          {
1028              $uri = $this->encodeurl($uri);
1029              if( $this->http_client->sendCommand( 'OPTIONS '.$uri.' HTTP/1.1' ) == '200' )
1030              {
1031                  $this->http_client->processReply();
1032                  $headers = $this->http_client->getHeaders();
1033                  return $headers;
1034              }
1035              else
1036              {
1037                  return False;
1038              }
1039          }
1040          /*!
1041          @function dav_features
1042          @abstract determines the features of a DAV server
1043          @param uri uri of resource whose properties we are changing
1044          @result Returns an array of option values
1045          @discussion
1046              Likely return codes include NULL (this isnt a dav server!), 1 
1047              (This is a dav server, supporting all standard DAV features except locking)
1048              2, (additionally supports locking (should also return 1)) and 
1049              'version-control' (this server supports versioning extensions for this resource)
1050          */        
1051  		function dav_features($uri)
1052          {
1053              $uri = $this->encodeurl($uri);
1054              $options = $this->options($uri);
1055              $dav_options = $options['DAV'];
1056              if ($dav_options)
1057              {
1058                  $features=explode(',', $dav_options);
1059              }
1060              else
1061              {
1062                  $features = NULL;
1063              }
1064              return $features;
1065          }
1066  /**************************************************************
1067   RFC 3253 DeltaV versioning extensions 
1068   **************************************************************
1069   These are 100% untested, and almost certainly dont work yet...
1070   eventually they will be made to work with subversion...
1071   */
1072      
1073          /*!
1074          @function report
1075          @abstract Report is a kind of extended PROPFIND - it queries properties accros versions etc
1076          @param uri uri of resource whose properties we are changing
1077          @param report the type of report desired eg DAV:version-tree, DAV:expand-property etc (see http://greenbytes.de/tech/webdav/rfc3253.html#METHOD_REPORT)
1078          @param namespace any extra XML namespaces needed for the specified properties
1079          @result Returns an array of option values
1080          @discussion
1081              From the relevent RFC:
1082              "A REPORT request is an extensible mechanism for obtaining information about
1083              a resource. Unlike a resource property, which has a single value, the value 
1084              of a report can depend on additional information specified in the REPORT 
1085              request body and in the REPORT request headers."
1086          */        
1087  		function report($uri, $report, $properties,  $namespaces='')
1088          {
1089              $uri = $this->encodeurl($uri);
1090              $davxml = '<?xml version="1.0" encoding="utf-8" ?>
1091  <D:'.$report . 'xmlns:D="DAV:"';
1092              if ($namespaces)
1093              {
1094                  $davxml .= ' ' . $namespaces;
1095              }
1096              $davxml .= ' >
1097      <D:prop>';
1098              foreach($properties as $property) 
1099              {
1100                  $davxml .= '<'.$property.'/>\n';
1101              }
1102              $davxml .= '\t<D:/prop>\n<D:/'.$report.'>';        
1103              if (DEBUG_DAV_XML) {
1104                  echo '<b>send</b><pre>'.htmlentities($davxml).'</pre>';
1105              }
1106              $this->http_client->requestBody = $davxml;
1107              if( $this->http_client->sendCommand( 'REPORT '.$uri.' HTTP/1.1' ) )
1108              {
1109                  $this->http_client->processReply();
1110              }
1111  
1112              if (DEBUG_DAV_XML) {
1113                  echo '<b>Recieve</b><pre>'.htmlentities($this->http_client->getBody()).'</pre>';
1114              }
1115              return $this->http_client->reply;        
1116          }
1117      
1118      }
1119  


Généré le : Sun Feb 25 17:20:01 2007 par Balluche grâce à PHPXref 0.7