Commit 1f2708d5d4e26b5a3a67db55b34deb016ab51b3f

Authored by kevin_fourie
1 parent 611495d8

Merged in from DEV trunk...

WSA-70
"Provide a mechanism to allow for JSON responses from web service requests"
Implemented.

Committed By: Conrad Vermeulen
Reviewed By: Megan Watson

WSA-44
"web service unit tests in php need to be incorporated for search"
Updated. A few tests for search has been incorporated

Committed By: Conrad Vermeulen
Reviewed By: Kevin Fourie

KTS-2721
"Refactor adding a document to use the storage manager"
Fixed. Removed all references to KTFSFileLike. Added a function to the storagemanager for uploading a temp file.

Committed by: Megan Watson
Reviewed by: Conrad Vermeulen

WSA-71
"Add missing fields to folder contents structure in web services"
Fixed.

Committed By: Conrad Vermeulen
Reviewed By: Martin Kirsten

KTS-2723
"The Search Portlet is not displaying in the browse view"
Fixed. Changed implode/explode to serialise/unserialise.

Committed by: Megan Watson
Reviewed by: Conrad Vermeulen

BBS-301
"Novel NetDrive Webdav as 3rd Party Client"
Fixed. Netdrive didn't resolve the relative paths correctly and kept the "/ktwebdav/ktwebdav.php" path as part of the folder / document path.

KTS-2344
"WEBDAV Not working in 3.4.2 (was in 3.4.1-1)"
Fixed.

Committed By: Megan Watson
Reviewed By: Conrad Vermeulen

KTS-2725
"Archived document should not be found using PropFind"
Fixed.

Committed By: Conrad Vermeulen
Reviewed By: Martin Kirsten

git-svn-id: https://kt-dms.svn.sourceforge.net/svnroot/kt-dms/STABLE/trunk@7739 c91229c3-7414-0410-bfa2-8a42b809f60b
config/dmsDefaults.php
@@ -43,6 +43,7 @@ if (defined('DMS_DEFAULTS_INCLUDED')) @@ -43,6 +43,7 @@ if (defined('DMS_DEFAULTS_INCLUDED'))
43 } 43 }
44 44
45 define('DMS_DEFAULTS_INCLUDED',1); 45 define('DMS_DEFAULTS_INCLUDED',1);
  46 +define('LATEST_WEBSERVICE_VERSION',2);
46 47
47 48
48 if (function_exists('apd_set_pprof_trace')) { 49 if (function_exists('apd_set_pprof_trace')) {
ktapi/KTAPIFolder.inc.php
@@ -315,6 +315,9 @@ class KTAPI_Folder extends KTAPI_FolderItem @@ -315,6 +315,9 @@ class KTAPI_Folder extends KTAPI_FolderItem
315 $read_permission = &KTPermission::getByName(KTAPI_PERMISSION_READ); 315 $read_permission = &KTPermission::getByName(KTAPI_PERMISSION_READ);
316 $folder_permission = &KTPermission::getByName(KTAPI_PERMISSION_VIEW_FOLDER); 316 $folder_permission = &KTPermission::getByName(KTAPI_PERMISSION_VIEW_FOLDER);
317 317
  318 + $config = KTConfig::getSingleton();
  319 +
  320 + $wsversion = $config->get('webservice/version', LATEST_WEBSERVICE_VERSION);
318 321
319 $user = $this->ktapi->get_user(); 322 $user = $this->ktapi->get_user();
320 323
@@ -324,13 +327,10 @@ class KTAPI_Folder extends KTAPI_FolderItem @@ -324,13 +327,10 @@ class KTAPI_Folder extends KTAPI_FolderItem
324 { 327 {
325 $folder_children = Folder::getList(array('parent_id = ?', $this->folderid)); 328 $folder_children = Folder::getList(array('parent_id = ?', $this->folderid));
326 329
327 -  
328 foreach ($folder_children as $folder) 330 foreach ($folder_children as $folder)
329 { 331 {
330 if(KTPermissionUtil::userHasPermissionOnItem($user, $folder_permission, $folder)) 332 if(KTPermissionUtil::userHasPermissionOnItem($user, $folder_permission, $folder))
331 { 333 {
332 - $creator=$this->_resolve_user($folder->getCreatorID());  
333 -  
334 if ($depth-1 > 0) 334 if ($depth-1 > 0)
335 { 335 {
336 $sub_folder = &$this->ktapi->get_folder_by_id($folder->getId()); 336 $sub_folder = &$this->ktapi->get_folder_by_id($folder->getId());
@@ -341,6 +341,50 @@ class KTAPI_Folder extends KTAPI_FolderItem @@ -341,6 +341,50 @@ class KTAPI_Folder extends KTAPI_FolderItem
341 $items=array(); 341 $items=array();
342 } 342 }
343 343
  344 + $creator=$this->_resolve_user($folder->getCreatorID());
  345 +
  346 +
  347 + if ($wsversion >= 2)
  348 + {
  349 + $contents[] = array(
  350 + 'id' => (int) $folder->getId(),
  351 + 'item_type' => 'F',
  352 +
  353 + 'title' => $folder->getName(),
  354 + 'filename' => $folder->getName(),
  355 + 'filesize' => 'n/a',
  356 +
  357 + 'created_by' => is_null($creator)?'n/a':$creator->getName(),
  358 + 'created_date' => 'n/a',
  359 +
  360 + 'checked_out_by' => 'n/a',
  361 + 'checked_out_date' => 'n/a',
  362 +
  363 + 'modified_by' => 'n/a',
  364 + 'modified_date' => 'n/a',
  365 +
  366 + 'owned_by' => 'n/a',
  367 +
  368 + 'version' => 'n/a',
  369 +
  370 + 'immutable'=> 'n/a',
  371 + 'permissions' => 'n/a',
  372 +
  373 + 'workflow'=>'n/a',
  374 + 'workflow_state'=>'n/a',
  375 +
  376 + 'mime_type' => 'folder',
  377 + 'mime_icon_path' => 'folder',
  378 + 'mime_display' => 'Folder',
  379 +
  380 + 'storage_path' => 'n/a',
  381 +
  382 + 'items'=>$items,
  383 +
  384 + );
  385 + }
  386 + else
  387 + {
344 388
345 $contents[] = array( 389 $contents[] = array(
346 'id' => (int) $folder->getId(), 390 'id' => (int) $folder->getId(),
@@ -360,8 +404,9 @@ class KTAPI_Folder extends KTAPI_FolderItem @@ -360,8 +404,9 @@ class KTAPI_Folder extends KTAPI_FolderItem
360 'items'=>$items, 404 'items'=>$items,
361 'workflow'=>'n/a', 405 'workflow'=>'n/a',
362 'workflow_state'=>'n/a' 406 'workflow_state'=>'n/a'
363 -  
364 ); 407 );
  408 + }
  409 +
365 } 410 }
366 } 411 }
367 } 412 }
@@ -376,9 +421,19 @@ class KTAPI_Folder extends KTAPI_FolderItem @@ -376,9 +421,19 @@ class KTAPI_Folder extends KTAPI_FolderItem
376 { 421 {
377 if (KTPermissionUtil::userHasPermissionOnItem($user, $read_permission, $document)) 422 if (KTPermissionUtil::userHasPermissionOnItem($user, $read_permission, $document))
378 { 423 {
379 - $creator=$this->_resolve_user($document->getCreatorID());  
380 - $checkedoutby=$this->_resolve_user($document->getCheckedOutUserID());  
381 - $modifiedby=$this->_resolve_user($document->getCreatorID()); 424 + $created_by=$this->_resolve_user($document->getCreatorID());
  425 + $created_date = $document->getCreatedDateTime();
  426 + if (empty($created_date)) $created_date = 'n/a';
  427 +
  428 + $checked_out_by=$this->_resolve_user($document->getCheckedOutUserID());
  429 + $checked_out_date = $document->getCheckedOutDate();
  430 + if (empty($checked_out_date)) $checked_out_date = 'n/a';
  431 +
  432 + $modified_by=$this->_resolve_user($document->getCreatorID());
  433 + $modified_date = $document->getCheckedOutDate();
  434 + if (empty($modified_date)) $modified_date = 'n/a';
  435 +
  436 + $owned_by =$this->_resolve_user($document->getOwnerID());
382 437
383 $mimetypeid=$document->getMimeTypeID(); 438 $mimetypeid=$document->getMimeTypeID();
384 if (!array_key_exists($mimetypeid, $mime_cache)) 439 if (!array_key_exists($mimetypeid, $mime_cache))
@@ -396,37 +451,73 @@ class KTAPI_Folder extends KTAPI_FolderItem @@ -396,37 +451,73 @@ class KTAPI_Folder extends KTAPI_FolderItem
396 } 451 }
397 $mimeinfo=$mime_cache[$mimetypeid]; 452 $mimeinfo=$mime_cache[$mimetypeid];
398 453
399 - $workflow = KTWorkflowUtil::getWorkflowForDocument($document); 454 + $workflow='n/a';
  455 + $state='n/a';
  456 +
  457 + $wf = KTWorkflowUtil::getWorkflowForDocument($document);
400 458
401 - if (!is_null($workflow) && !PEAR::isError($workflow)) 459 + if (!is_null($wf) && !PEAR::isError($wf))
402 { 460 {
403 - $workflow=$workflow->getHumanName(); 461 + $workflow=$wf->getHumanName();
404 462
405 - $state=KTWorkflowUtil::getWorkflowStateForDocument($document);  
406 - if (!is_null($state) && !PEAR::isError($state)) 463 + $ws=KTWorkflowUtil::getWorkflowStateForDocument($document);
  464 + if (!is_null($ws) && !PEAR::isError($ws))
407 { 465 {
408 $state=$state->getHumanName(); 466 $state=$state->getHumanName();
409 } 467 }
410 - else  
411 - {  
412 - $state='n/a';  
413 - }  
414 } 468 }
415 - else 469 +
  470 + if ($wsversion >= 2)
416 { 471 {
417 - $workflow='n/a';  
418 - $state='n/a'; 472 + $contents[] = array(
  473 + 'id' => (int) $document->getId(),
  474 + 'item_type' => 'D',
  475 +
  476 + 'title' => $document->getName(),
  477 + 'filename' => $document->getFileName(),
  478 + 'filesize' => $document->getFileSize(),
  479 +
  480 + 'created_by' => is_null($created_by)?'n/a':$created_by->getName(),
  481 + 'created_date' => $created_date,
  482 +
  483 + 'checked_out_by' => is_null($checked_out_by)?'n/a':$checked_out_by->getName(),
  484 + 'checked_out_date' => $checked_out_date,
  485 +
  486 + 'modified_by' => is_null($modified_by)?'n/a':$modified_by->getName(),
  487 + 'modified_date' => $modified_date,
  488 +
  489 + 'owned_by' => is_null($owned_by)?'n/a':$owned_by->getName(),
  490 +
  491 + 'version' => $document->getMajorVersionNumber() . '.' . $document->getMinorVersionNumber(),
  492 +
  493 + 'immutable'=> $document->getImmutable()?'true':'false',
  494 + 'permissions' => 'n/a',
  495 +
  496 + 'workflow'=> $workflow,
  497 + 'workflow_state'=> $state,
  498 +
  499 + 'mime_type' => $mime_cache[$mimetypeid]['type'],
  500 + 'mime_icon_path' => $mime_cache[$mimetypeid]['icon'],
  501 + 'mime_display' => $mime_cache[$mimetypeid]['display'],
  502 +
  503 + 'storage_path' => $document->getStoragePath(),
  504 +
  505 + 'items'=>array(),
  506 +
  507 + );
419 } 508 }
  509 + else
  510 + {
420 511
421 512
422 $contents[] = array( 513 $contents[] = array(
423 'id' => (int) $document->getId(), 514 'id' => (int) $document->getId(),
424 'item_type'=>'D', 515 'item_type'=>'D',
425 'title'=>$document->getName(), 516 'title'=>$document->getName(),
426 - 'creator'=>is_null($creator)?'n/a':$creator->getName(),  
427 - 'checkedoutby'=>is_null($checkedoutby)?'n/a':$checkedoutby->getName(),  
428 - 'modifiedby'=>is_null($modifiedby)?'n/a':$modifiedby->getName(),  
429 - 'filename'=>$document->getName(), 517 + 'creator'=>is_null($created_by)?'n/a':$created_by->getName(),
  518 + 'checkedoutby'=>is_null($checked_out_by)?'n/a':$checked_out_by->getName(),
  519 + 'modifiedby'=>is_null($modified_by)?'n/a':$modified_by->getName(),
  520 + 'filename'=>$document->getFileName(),
430 'size'=>$document->getFileSize(), 521 'size'=>$document->getFileSize(),
431 'major_version'=>$document->getMajorVersionNumber(), 522 'major_version'=>$document->getMajorVersionNumber(),
432 'minor_version'=>$document->getMinorVersionNumber(), 523 'minor_version'=>$document->getMinorVersionNumber(),
@@ -438,6 +529,8 @@ class KTAPI_Folder extends KTAPI_FolderItem @@ -438,6 +529,8 @@ class KTAPI_Folder extends KTAPI_FolderItem
438 'workflow'=>$workflow, 529 'workflow'=>$workflow,
439 'workflow_state'=>$state 530 'workflow_state'=>$state
440 ); 531 );
  532 +
  533 + }
441 } 534 }
442 } 535 }
443 536
@@ -478,7 +571,8 @@ class KTAPI_Folder extends KTAPI_FolderItem @@ -478,7 +571,8 @@ class KTAPI_Folder extends KTAPI_FolderItem
478 571
479 572
480 $options = array( 573 $options = array(
481 - 'contents' => new KTFSFileLike($tempfilename), 574 + //'contents' => new KTFSFileLike($tempfilename),
  575 + 'temp_file' => $tempfilename,
482 'novalidate' => true, 576 'novalidate' => true,
483 'documenttype' => DocumentType::get($documenttypeid), 577 'documenttype' => DocumentType::get($documenttypeid),
484 'description' => $title, 578 'description' => $title,
ktwebdav/ktwebdav.php
@@ -35,6 +35,12 @@ @@ -35,6 +35,12 @@
35 * Contributor( s): ______________________________________ 35 * Contributor( s): ______________________________________
36 * 36 *
37 */ 37 */
  38 +
  39 + $userAgentValue = $_SERVER['HTTP_USER_AGENT'];
  40 + if (stristr($userAgentValue, "Microsoft Data Access Internet Publishing Provider DAV")) {
  41 + // Fix for Novell Netdrive
  42 + chdir(realpath(dirname(__FILE__)));
  43 + }
38 44
39 $webdav_pear_path = 'thirdparty/pear'; 45 $webdav_pear_path = 'thirdparty/pear';
40 $kt_pear_path = '../thirdparty/pear'; 46 $kt_pear_path = '../thirdparty/pear';
ktwebdav/lib/KTWebDAVServer.inc.php
@@ -40,8 +40,14 @@ require_once 'HTTP/WebDAV/Server.php'; // thirdparty PEAR @@ -40,8 +40,14 @@ require_once 'HTTP/WebDAV/Server.php'; // thirdparty PEAR
40 require_once 'Config.php'; // thirdparty PEAR 40 require_once 'Config.php'; // thirdparty PEAR
41 require_once 'Log.php'; // thirdparty PEAR 41 require_once 'Log.php'; // thirdparty PEAR
42 42
43 -require_once '../config/dmsDefaults.php'; // This is our plug into KT.  
44 - 43 +$userAgentValue = $_SERVER['HTTP_USER_AGENT'];
  44 +if (stristr($userAgentValue, "Microsoft Data Access Internet Publishing Provider DAV")) {
  45 + // Fix for Novell Netdrive
  46 + chdir(realpath(dirname(__FILE__)));
  47 + require_once '../../config/dmsDefaults.php'; // This is our plug into KT.
  48 +}else{
  49 + require_once '../config/dmsDefaults.php'; // This is our plug into KT.
  50 +}
45 51
46 DEFINE('STATUS_WEBDAV', 5); // Status code to handle 0 byte PUT FIXME: Do we still need this! 52 DEFINE('STATUS_WEBDAV', 5); // Status code to handle 0 byte PUT FIXME: Do we still need this!
47 53
@@ -1371,9 +1377,10 @@ class KTWebDAVServer extends HTTP_WebDAV_Server @@ -1371,9 +1377,10 @@ class KTWebDAVServer extends HTTP_WebDAV_Server
1371 ); 1377 );
1372 $this->ktwebdavLog("aFileArray is " . print_r($aFileArray, true), 'info', true); 1378 $this->ktwebdavLog("aFileArray is " . print_r($aFileArray, true), 'info', true);
1373 1379
1374 - include_once(KT_LIB_DIR . '/filelike/fsfilelike.inc.php'); 1380 + //include_once(KT_LIB_DIR . '/filelike/fsfilelike.inc.php');
1375 $aOptions = array( 1381 $aOptions = array(
1376 - 'contents' => new KTFSFileLike($sTempFilename), 1382 + //'contents' => new KTFSFileLike($sTempFilename),
  1383 + 'temp_file' => $sTempFilename,
1377 'metadata' => array(), 1384 'metadata' => array(),
1378 'novalidate' => true, 1385 'novalidate' => true,
1379 ); 1386 );
@@ -1427,9 +1434,10 @@ class KTWebDAVServer extends HTTP_WebDAV_Server @@ -1427,9 +1434,10 @@ class KTWebDAVServer extends HTTP_WebDAV_Server
1427 ); 1434 );
1428 $this->ktwebdavLog("aFileArray is " . print_r($aFileArray, true), 'info', true); 1435 $this->ktwebdavLog("aFileArray is " . print_r($aFileArray, true), 'info', true);
1429 1436
1430 - include_once(KT_LIB_DIR . '/filelike/fsfilelike.inc.php'); 1437 + //include_once(KT_LIB_DIR . '/filelike/fsfilelike.inc.php');
1431 $aOptions = array( 1438 $aOptions = array(
1432 - 'contents' => new KTFSFileLike($sTempFilename), 1439 + //'contents' => new KTFSFileLike($sTempFilename),
  1440 + 'temp_file' => $sTempFilename,
1433 'metadata' => array(), 1441 'metadata' => array(),
1434 'novalidate' => true, 1442 'novalidate' => true,
1435 ); 1443 );
@@ -1769,7 +1777,7 @@ class KTWebDAVServer extends HTTP_WebDAV_Server @@ -1769,7 +1777,7 @@ class KTWebDAVServer extends HTTP_WebDAV_Server
1769 1777
1770 // Fix for Mac Goliath 1778 // Fix for Mac Goliath
1771 // Modified - 25/10/07 - remove ktwebdav from document path 1779 // Modified - 25/10/07 - remove ktwebdav from document path
1772 - if($this->dav_client == 'MG'){ 1780 + if($this->dav_client == 'MG' || $this->dav_client == 'MS'){
1773 $this->ktwebdavLog("Remove ktwebdav from destination path: ".$options['dest'], 'info', true); 1781 $this->ktwebdavLog("Remove ktwebdav from destination path: ".$options['dest'], 'info', true);
1774 if(!(strpos($options['dest'], 'ktwebdav/ktwebdav.php/') === FALSE)){ 1782 if(!(strpos($options['dest'], 'ktwebdav/ktwebdav.php/') === FALSE)){
1775 $options['dest'] = substr($options['dest'], 22); 1783 $options['dest'] = substr($options['dest'], 22);
@@ -1894,6 +1902,7 @@ class KTWebDAVServer extends HTTP_WebDAV_Server @@ -1894,6 +1902,7 @@ class KTWebDAVServer extends HTTP_WebDAV_Server
1894 1902
1895 /* ** Ensure that the destination path exists ** */ 1903 /* ** Ensure that the destination path exists ** */
1896 if ($options['dest'] == '') $options["dest"] = substr($options["dest_url"], strlen($_SERVER["SCRIPT_NAME"])); 1904 if ($options['dest'] == '') $options["dest"] = substr($options["dest_url"], strlen($_SERVER["SCRIPT_NAME"]));
  1905 + $options['dest'] = $this->_slashify($options['dest']);
1897 $this->ktwebdavLog("Entering _MOVEFolder. options are " . print_r($options, true), 'info', true); 1906 $this->ktwebdavLog("Entering _MOVEFolder. options are " . print_r($options, true), 'info', true);
1898 1907
1899 /* ** RFC 2518 Section 8.9.2. A folder move must have a depth of 'infinity'. 1908 /* ** RFC 2518 Section 8.9.2. A folder move must have a depth of 'infinity'.
@@ -1903,9 +1912,9 @@ class KTWebDAVServer extends HTTP_WebDAV_Server @@ -1903,9 +1912,9 @@ class KTWebDAVServer extends HTTP_WebDAV_Server
1903 return "400 Bad request - depth must be 'inifinity'."; 1912 return "400 Bad request - depth must be 'inifinity'.";
1904 } 1913 }
1905 1914
1906 - // Fix for Mac Goliath 1915 + // Fix for Mac Goliath - and for Novell Netdrive
1907 // Modified - 30/10/07 - remove ktwebdav from folder path 1916 // Modified - 30/10/07 - remove ktwebdav from folder path
1908 - if($this->dav_client == 'MG'){ 1917 + if($this->dav_client == 'MG' || $this->dav_client == 'MS'){
1909 $this->ktwebdavLog("Remove ktwebdav from destination path: ".$options['dest'], 'info', true); 1918 $this->ktwebdavLog("Remove ktwebdav from destination path: ".$options['dest'], 'info', true);
1910 if(!(strpos($options['dest'], 'ktwebdav/ktwebdav.php/') === FALSE)){ 1919 if(!(strpos($options['dest'], 'ktwebdav/ktwebdav.php/') === FALSE)){
1911 $options['dest'] = substr($options['dest'], 22); 1920 $options['dest'] = substr($options['dest'], 22);
ktwebservice/json.php 0 โ†’ 100644
  1 +<?php
  2 +
  3 +define('JSON_WEBSERVICE',1);
  4 +require_once('webservice.php');
  5 +
  6 +?>
0 \ No newline at end of file 7 \ No newline at end of file
ktwebservice/nunit/helper.cs
@@ -174,6 +174,7 @@ namespace MonoTests.KnowledgeTree @@ -174,6 +174,7 @@ namespace MonoTests.KnowledgeTree
174 { 174 {
175 public String title; 175 public String title;
176 public String filename; 176 public String filename;
  177 + public String realFilename;
177 public String content; 178 public String content;
178 public int docId; 179 public int docId;
179 public String session; 180 public String session;
@@ -185,7 +186,8 @@ namespace MonoTests.KnowledgeTree @@ -185,7 +186,8 @@ namespace MonoTests.KnowledgeTree
185 public Document(int offset, String session, KnowledgeTreeService kt, bool verbose, bool local) 186 public Document(int offset, String session, KnowledgeTreeService kt, bool verbose, bool local)
186 { 187 {
187 this.title = "kt unit test" + offset; 188 this.title = "kt unit test" + offset;
188 - this.filename = Helper.isUnix()?("/tmp/kt_unit_test" + offset + ".txt"):("c:\\kt_unit_test"+offset+".txt"); 189 + this.realFilename = "kt_unit_test" + offset + ".txt";
  190 + this.filename = (Helper.isUnix()?("/tmp/"):("c:\\")) + this.realFilename;
189 this.content = "hello world!"; 191 this.content = "hello world!";
190 this.docId = 0; 192 this.docId = 0;
191 this.session = session; 193 this.session = session;
ktwebservice/nunit/makefile
1 -RESULTS= authentication.result document_detail.result document_add.result document_checkout.result document_type.result document_links.result document_owner.result document_rename.result document_history.result document_workflow.result document_copy.result folder.result document_metadata.result document_system_metadata.result 1 +RESULTS= authentication.result document_detail.result document_add.result document_checkout.result document_type.result document_links.result document_owner.result document_rename.result document_history.result document_workflow.result document_copy.result folder.result document_metadata.result document_system_metadata.result query.result
2 #document_download.result 2 #document_download.result
3 PROXY=KTproxy.cs 3 PROXY=KTproxy.cs
4 WSDL=ktdms.wsdl 4 WSDL=ktdms.wsdl
ktwebservice/nunit/query.cs
@@ -22,19 +22,38 @@ namespace MonoTests.KnowledgeTree @@ -22,19 +22,38 @@ namespace MonoTests.KnowledgeTree
22 [Test] 22 [Test]
23 public void Query() 23 public void Query()
24 { 24 {
25 - kt_search_response response = this._kt.search(this._session, "Filesize >= \"0\"", ""); 25 + Document doc = new Document(0,this._session, this._kt, false, false);
  26 + doc.createFile(1);
  27 + kt_search_response response = this._kt.search(this._session, "Filesize = \"13\"", "");
26 28
27 Assert.AreEqual(0,response.status_code); 29 Assert.AreEqual(0,response.status_code);
  30 + Assert.AreEqual(doc.content.Length + 1,response.hits[0].filesize);
  31 + Assert.AreEqual(doc.title,response.hits[0].title);
  32 + Assert.AreEqual(doc.realFilename,response.hits[0].filename);
  33 +
  34 + response = this._kt.search(this._session, "DocumentId = \""+ response.hits[0].document_id +"\"", "");
28 35
  36 + Assert.AreEqual(0,response.status_code);
  37 + Assert.AreEqual(doc.content.Length + 1,response.hits[0].filesize);
  38 + Assert.AreEqual(doc.title,response.hits[0].title);
  39 + Assert.AreEqual(doc.realFilename,response.hits[0].filename);
  40 +
  41 + response = this._kt.search(this._session, "Title = \""+ response.hits[0].title +"\"", "");
29 42
30 - if (response.status_code == 0)  
31 - {  
32 -  
33 - for(int i=0;i<response.hits.Length;i++)  
34 - { 43 + Assert.AreEqual(0,response.status_code);
  44 + Assert.AreEqual(doc.content.Length + 1,response.hits[0].filesize);
  45 + Assert.AreEqual(doc.title,response.hits[0].title);
  46 + Assert.AreEqual(doc.realFilename,response.hits[0].filename);
  47 +
  48 +
  49 + response = this._kt.search(this._session, "Filename = \""+ response.hits[0].filename +"\"", "");
35 50
36 - }  
37 - } 51 + Assert.AreEqual(0,response.status_code);
  52 + Assert.AreEqual(doc.content.Length + 1,response.hits[0].filesize);
  53 + Assert.AreEqual(doc.title,response.hits[0].title);
  54 + Assert.AreEqual(doc.realFilename,response.hits[0].filename);
  55 +
  56 + doc.deleteFile();
38 } 57 }
39 } 58 }
40 } 59 }
ktwebservice/webservice.php
@@ -127,7 +127,7 @@ class KTWebService @@ -127,7 +127,7 @@ class KTWebService
127 // Caching was giving some problems, so disable it. 127 // Caching was giving some problems, so disable it.
128 128
129 $config = &KTConfig::getSingleton(); 129 $config = &KTConfig::getSingleton();
130 - $this->version = $config->get('webservice/version', 2); 130 + $this->version = $config->get('webservice/version', LATEST_WEBSERVICE_VERSION);
131 $this->mustDebug = $config->get('webservice/debug', false); 131 $this->mustDebug = $config->get('webservice/debug', false);
132 $this->ktapi = null; 132 $this->ktapi = null;
133 133
@@ -175,6 +175,46 @@ class KTWebService @@ -175,6 +175,46 @@ class KTWebService
175 'items' =>"{urn:$this->namespace}kt_folder_items" 175 'items' =>"{urn:$this->namespace}kt_folder_items"
176 ); 176 );
177 177
  178 + if ($this->version >= 2)
  179 + {
  180 + $this->__typedef["{urn:$this->namespace}kt_folder_item"] =
  181 + array(
  182 + 'id' => 'int',
  183 + 'item_type' => 'string',
  184 +
  185 + 'title' => 'string',
  186 + 'filename' => 'string',
  187 + 'filesize' => 'string',
  188 +
  189 + 'created_by' => 'string',
  190 + 'created_date' => 'string',
  191 +
  192 + 'checked_out_by' => 'string',
  193 + 'checked_out_date' => 'string',
  194 +
  195 + 'modified_by' => 'string',
  196 + 'modified_date' => 'string',
  197 +
  198 + 'owned_by' => 'string',
  199 +
  200 + 'version' => 'string',
  201 +
  202 + 'immutable'=>'boolean',
  203 + 'permissions' => 'string',
  204 +
  205 + 'workflow'=>'string',
  206 + 'workflow_state'=>'string',
  207 +
  208 + 'mime_type' => 'string',
  209 + 'mime_icon_path' => 'string',
  210 + 'mime_display' => 'string',
  211 +
  212 + 'storage_path' => 'string',
  213 +
  214 + 'items' =>"{urn:$this->namespace}kt_folder_items"
  215 + );
  216 + }
  217 +
178 $this->__typedef["{urn:$this->namespace}kt_folder_items"] = 218 $this->__typedef["{urn:$this->namespace}kt_folder_items"] =
179 array( 219 array(
180 array( 220 array(
@@ -230,7 +270,6 @@ class KTWebService @@ -230,7 +270,6 @@ class KTWebService
230 'folder_id' => 'int', 270 'folder_id' => 'int',
231 'workflow' => 'string', 271 'workflow' => 'string',
232 'workflow_state' => 'string', 272 'workflow_state' => 'string',
233 - //'checkout_by' => 'string',  
234 'full_path' => 'string', 273 'full_path' => 'string',
235 'owner'=>'string', 274 'owner'=>'string',
236 'is_immutable'=>'boolean', 275 'is_immutable'=>'boolean',
@@ -3985,6 +4024,109 @@ class KTWebService @@ -3985,6 +4024,109 @@ class KTWebService
3985 return new SOAP_Value('return',"{urn:$this->namespace}kt_search_response", $response); 4024 return new SOAP_Value('return',"{urn:$this->namespace}kt_search_response", $response);
3986 } 4025 }
3987 4026
  4027 +
  4028 + /**
  4029 + * The main json request processing function.
  4030 + *
  4031 + * The method name of the method to be called must be $_POST['_method'].
  4032 + * All parameters may be set in any order, as long as the names correspond with the wdsl names.
  4033 + *
  4034 + */
  4035 + function runJSON()
  4036 + {
  4037 + // Let us check that all the POST variables that are expected are set
  4038 + if ($_SERVER['REQUEST_METHOD'] != 'POST')
  4039 + {
  4040 + print json_encode(array('msg'=>'Post request must be made!'));
  4041 + return;
  4042 + }
  4043 + $method = '';
  4044 + if (array_key_exists('_method',$_POST))
  4045 + {
  4046 + $method=$_POST['_method'];
  4047 + }
  4048 + if ($method == '' || !array_key_exists($method,$this->__dispatch_map))
  4049 + {
  4050 + print json_encode(array('msg'=>'Method must exist!'));
  4051 + return;
  4052 + }
  4053 +
  4054 + // let us check that we have all the variables for the method to be called.
  4055 + $dispatcher = $this->__dispatch_map[$method];
  4056 + $params = array();
  4057 + foreach($dispatcher['in'] as $var=>$type)
  4058 + {
  4059 + $param = array('var'=>$var, 'set'=>0);
  4060 +
  4061 + if (array_key_exists($var, $_POST))
  4062 + {
  4063 + $param['set'] = 1;
  4064 +
  4065 + // if it looks json like we should decode it
  4066 + if (substr($_POST[$var],0,1) == '{' && substr($_POST[$var],-1) == '}')
  4067 + {
  4068 + $original = $_POST[$var];
  4069 + $decoded = json_decode($original);
  4070 +
  4071 + $_POST[$var] = is_null($decoded)?$original:$decoded;
  4072 + unset($original);
  4073 + unset($decoded);
  4074 + }
  4075 + }
  4076 +
  4077 + $params[] = $param;
  4078 + }
  4079 +
  4080 + // prepare the parameters and call the method
  4081 + // by passing references to $POST we hopefully save some memory
  4082 +
  4083 + $paramstr = '';
  4084 + foreach($params as $param)
  4085 + {
  4086 + $var = $param['var'];
  4087 + if ($param['set'] == 0)
  4088 + {
  4089 + print json_encode(array('msg'=>"'$var' is not set!"));
  4090 + return;
  4091 + }
  4092 + if ($paramstr != '') $paramstr .= ',';
  4093 +
  4094 + $paramstr .= "\$_POST['$var']";
  4095 + }
  4096 +
  4097 + $result = eval("return \$this->$method($paramstr);");
  4098 +
  4099 + // return the json encoded result
  4100 + print json_encode(KTWebService::decodeSOAPValue($result));
  4101 + }
  4102 +
  4103 + /**
  4104 + * Returns a decoded soap value structure.
  4105 + *
  4106 + * @param SOAP_Value $value
  4107 + * @return mixed
  4108 + */
  4109 + function decodeSOAPValue($value)
  4110 + {
  4111 + if ($value instanceof SOAP_Value)
  4112 + {
  4113 + $x = new stdClass();
  4114 + $v = & $value->value;
  4115 + $vars = array_keys($v);
  4116 +
  4117 + foreach($vars as $var)
  4118 + {
  4119 + $x->$var = KTWebService::decodeSOAPValue($v[$var]);
  4120 + }
  4121 +
  4122 + return $x;
  4123 + }
  4124 + else
  4125 + {
  4126 + return $value;
  4127 + }
  4128 + }
  4129 +
3988 /** 4130 /**
3989 * This runs the web service 4131 * This runs the web service
3990 * 4132 *
@@ -3993,6 +4135,12 @@ class KTWebService @@ -3993,6 +4135,12 @@ class KTWebService
3993 */ 4135 */
3994 function run() 4136 function run()
3995 { 4137 {
  4138 + if (defined('JSON_WEBSERVICE'))
  4139 + {
  4140 + $this->runJSON();
  4141 + return;
  4142 + }
  4143 +
3996 ob_start(); 4144 ob_start();
3997 $server = new SOAP_Server(); 4145 $server = new SOAP_Server();
3998 4146
lib/documentmanagement/documentutil.inc.php
@@ -234,7 +234,7 @@ class KTDocumentUtil { @@ -234,7 +234,7 @@ class KTDocumentUtil {
234 function &_add($oFolder, $sFilename, $oUser, $aOptions) { 234 function &_add($oFolder, $sFilename, $oUser, $aOptions) {
235 global $default; 235 global $default;
236 236
237 - $oContents = KTUtil::arrayGet($aOptions, 'contents'); 237 + //$oContents = KTUtil::arrayGet($aOptions, 'contents');
238 $aMetadata = KTUtil::arrayGet($aOptions, 'metadata', null, false); 238 $aMetadata = KTUtil::arrayGet($aOptions, 'metadata', null, false);
239 $oDocumentType = KTUtil::arrayGet($aOptions, 'documenttype'); 239 $oDocumentType = KTUtil::arrayGet($aOptions, 'documenttype');
240 $sDescription = KTUtil::arrayGet($aOptions, 'description', $sFilename); 240 $sDescription = KTUtil::arrayGet($aOptions, 'description', $sFilename);
@@ -256,20 +256,20 @@ class KTDocumentUtil { @@ -256,20 +256,20 @@ class KTDocumentUtil {
256 'documenttypeid' => $iDocumentTypeId, 256 'documenttypeid' => $iDocumentTypeId,
257 )); 257 ));
258 258
259 - if (is_null($oContents)) {  
260 - $res = KTDocumentUtil::setIncomplete($oDocument, 'contents');  
261 - if (PEAR::isError($res)) {  
262 - $oDocument->delete();  
263 - return $res;  
264 - }  
265 - } else { 259 +// if (is_null($oContents)) {
  260 +// $res = KTDocumentUtil::setIncomplete($oDocument, 'contents');
  261 +// if (PEAR::isError($res)) {
  262 +// $oDocument->delete();
  263 +// return $res;
  264 +// }
  265 +// } else {
266 // $oUploadChannel->sendMessage(new KTUploadGenericMessage(_kt('Storing contents'))); 266 // $oUploadChannel->sendMessage(new KTUploadGenericMessage(_kt('Storing contents')));
267 - $res = KTDocumentUtil::storeContents($oDocument, $oContents, $aOptions); 267 + $res = KTDocumentUtil::storeContents($oDocument, '', $aOptions);
268 if (PEAR::isError($res)) { 268 if (PEAR::isError($res)) {
269 $oDocument->delete(); 269 $oDocument->delete();
270 return $res; 270 return $res;
271 } 271 }
272 - } 272 +// }
273 273
274 if (is_null($aMetadata)) { 274 if (is_null($aMetadata)) {
275 $res = KTDocumentUtil::setIncomplete($oDocument, 'metadata'); 275 $res = KTDocumentUtil::setIncomplete($oDocument, 'metadata');
@@ -694,7 +694,7 @@ class KTDocumentUtil { @@ -694,7 +694,7 @@ class KTDocumentUtil {
694 /** 694 /**
695 * Stores contents (filelike) from source into the document storage 695 * Stores contents (filelike) from source into the document storage
696 */ 696 */
697 - function storeContents(&$oDocument, $oContents, $aOptions = null) { 697 + function storeContents(&$oDocument, $oContents = null, $aOptions = null) {
698 if (is_null($aOptions)) { 698 if (is_null($aOptions)) {
699 $aOptions = array(); 699 $aOptions = array();
700 } 700 }
@@ -704,17 +704,20 @@ class KTDocumentUtil { @@ -704,17 +704,20 @@ class KTDocumentUtil {
704 $oKTConfig =& KTConfig::getSingleton(); 704 $oKTConfig =& KTConfig::getSingleton();
705 $sBasedir = $oKTConfig->get('urls/tmpDirectory'); 705 $sBasedir = $oKTConfig->get('urls/tmpDirectory');
706 706
707 - $sFilename = tempnam($sBasedir, 'kt_storecontents');  
708 - $oOutputFile = new KTFSFileLike($sFilename);  
709 - $res = KTFileLikeUtil::copy_contents($oContents, $oOutputFile);  
710 - if (($res === false)) {  
711 - return PEAR::raiseError(_kt("Couldn't store contents, and no reason given."));  
712 - } else if (PEAR::isError($res)) {  
713 - return PEAR::raiseError(sprintf(_kt("Couldn't store contents: %s"), $res->getMessage()));  
714 - } 707 + $sFilename = (isset($aOptions['temp_file'])) ? $aOptions['temp_file'] : tempnam($sBasedir, 'kt_storecontents');
  708 +
  709 +// $oOutputFile = new KTFSFileLike($sFilename);
  710 +// $res = KTFileLikeUtil::copy_contents($oContents, $oOutputFile);
  711 +// if (($res === false)) {
  712 +// return PEAR::raiseError(_kt("Couldn't store contents, and no reason given."));
  713 +// } else if (PEAR::isError($res)) {
  714 +// return PEAR::raiseError(sprintf(_kt("Couldn't store contents: %s"), $res->getMessage()));
  715 +// }
  716 +
715 $sType = KTMime::getMimeTypeFromFile($sFilename); 717 $sType = KTMime::getMimeTypeFromFile($sFilename);
716 $iMimeTypeId = KTMime::getMimeTypeID($sType, $oDocument->getFileName()); 718 $iMimeTypeId = KTMime::getMimeTypeID($sType, $oDocument->getFileName());
717 $oDocument->setMimeTypeId($iMimeTypeId); 719 $oDocument->setMimeTypeId($iMimeTypeId);
  720 +
718 $res = $oStorage->upload($oDocument, $sFilename); 721 $res = $oStorage->upload($oDocument, $sFilename);
719 if ($res === false) { 722 if ($res === false) {
720 return PEAR::raiseError(sprintf(_kt("Couldn't store contents: %s"), _kt('No reason given'))); 723 return PEAR::raiseError(sprintf(_kt("Couldn't store contents: %s"), _kt('No reason given')));
@@ -725,7 +728,7 @@ class KTDocumentUtil { @@ -725,7 +728,7 @@ class KTDocumentUtil {
725 KTDocumentUtil::setComplete($oDocument, 'contents'); 728 KTDocumentUtil::setComplete($oDocument, 'contents');
726 729
727 if ($aOptions['cleanup_initial_file']) { 730 if ($aOptions['cleanup_initial_file']) {
728 - @unlink($oContents->sFilename); 731 + @unlink($sFilename);
729 } 732 }
730 733
731 return true; 734 return true;
lib/plugins/plugin.inc.php
@@ -84,9 +84,9 @@ class KTPlugin { @@ -84,9 +84,9 @@ class KTPlugin {
84 84
85 // Register helper in DB 85 // Register helper in DB
86 if(is_array($aLocation)){ 86 if(is_array($aLocation)){
87 - $sLocation = implode('_|', $aLocation); 87 + $aLocation = serialize($aLocation);
88 } 88 }
89 - $params = $sLocation.'|'.$sPortletClassName.'|'.$sPortletNamespace.'|'.$sFilename.'|'.$this->sNamespace; 89 + $params = $aLocation.'|'.$sPortletClassName.'|'.$sPortletNamespace.'|'.$sFilename.'|'.$this->sNamespace;
90 $this->registerPluginHelper($sPortletNamespace, $sPortletClassName, $sFilename, $params, 'general', 'portlet'); 90 $this->registerPluginHelper($sPortletNamespace, $sPortletClassName, $sFilename, $params, 'general', 'portlet');
91 } 91 }
92 92
@@ -288,10 +288,10 @@ class KTPlugin { @@ -288,10 +288,10 @@ class KTPlugin {
288 288
289 // Register helper in DB 289 // Register helper in DB
290 if(is_array($aInitialize)){ 290 if(is_array($aInitialize)){
291 - $sInitialize = implode('_|', $aInitialize); 291 + $aInitialize = serialize($aInitialize);
292 } 292 }
293 293
294 - $params = $sClassName.'|'.$sNamespace.'|'.$sFilename.'|'.$sInitialize; 294 + $params = $sClassName.'|'.$sNamespace.'|'.$sFilename.'|'.$aInitialize;
295 $this->registerPluginHelper($sNamespace, $sClassName, $sFilename, $params, 'general', 'criterion'); 295 $this->registerPluginHelper($sNamespace, $sClassName, $sFilename, $params, 'general', 'criterion');
296 } 296 }
297 297
@@ -404,8 +404,10 @@ class KTPlugin { @@ -404,8 +404,10 @@ class KTPlugin {
404 404
405 switch ($sClassType) { 405 switch ($sClassType) {
406 case 'portlet': 406 case 'portlet':
407 - $aLocation = explode('_|', $aParams[0]);  
408 - $aParams[0] = $aLocation; 407 + $aLocation = unserialize($aParams[0]);
  408 + if($aLocation != false){
  409 + $aParams[0] = $aLocation;
  410 + }
409 $this->_aPortlets[$sName] = $aParams; 411 $this->_aPortlets[$sName] = $aParams;
410 break; 412 break;
411 413
@@ -474,8 +476,10 @@ class KTPlugin { @@ -474,8 +476,10 @@ class KTPlugin {
474 break; 476 break;
475 477
476 case 'criterion': 478 case 'criterion':
477 - $aInit = explode('_|', $aParams[3]);  
478 - $aParams[3] = $aInit; 479 + $aInit = unserialize($aParams[3]);
  480 + if($aInit != false){
  481 + $aParams[3] = $aInit;
  482 + }
479 $this->_aCriteria[$sName] = $aParams; 483 $this->_aCriteria[$sName] = $aParams;
480 break; 484 break;
481 485
lib/plugins/pluginutil.inc.php
@@ -264,8 +264,10 @@ class KTPluginUtil { @@ -264,8 +264,10 @@ class KTPluginUtil {
264 264
265 switch ($sClassType) { 265 switch ($sClassType) {
266 case 'portlet': 266 case 'portlet':
267 - $aLocation = explode('_|', $aParams[0]);  
268 - $aParams[0] = $aLocation; 267 + $aLocation = unserialize($aParams[0]);
  268 + if($aLocation != false){
  269 + $aParams[0] = $aLocation;
  270 + }
269 call_user_func_array(array(&$oPRegistry, 'registerPortlet'), $aParams); 271 call_user_func_array(array(&$oPRegistry, 'registerPortlet'), $aParams);
270 break; 272 break;
271 273
@@ -334,8 +336,10 @@ class KTPluginUtil { @@ -334,8 +336,10 @@ class KTPluginUtil {
334 break; 336 break;
335 337
336 case 'criterion': 338 case 'criterion':
337 - $aInit = explode('_|', $aParams[3]);  
338 - $aParams[3] = $aInit; 339 + $aInit = unserialize($aParams[3]);
  340 + if($aInit != false){
  341 + $aParams[3] = $aInit;
  342 + }
339 call_user_func_array(array(&$oCriteriaRegistry, 'registerCriterion'), $aParams); 343 call_user_func_array(array(&$oCriteriaRegistry, 'registerCriterion'), $aParams);
340 break; 344 break;
341 345
lib/storage/ondiskhashedstoragemanager.inc.php
@@ -8,32 +8,32 @@ @@ -8,32 +8,32 @@
8 * KnowledgeTree Open Source Edition 8 * KnowledgeTree Open Source Edition
9 * Document Management Made Simple 9 * Document Management Made Simple
10 * Copyright (C) 2004 - 2007 The Jam Warehouse Software (Pty) Limited 10 * Copyright (C) 2004 - 2007 The Jam Warehouse Software (Pty) Limited
11 - * 11 + *
12 * This program is free software; you can redistribute it and/or modify it under 12 * This program is free software; you can redistribute it and/or modify it under
13 * the terms of the GNU General Public License version 3 as published by the 13 * the terms of the GNU General Public License version 3 as published by the
14 * Free Software Foundation. 14 * Free Software Foundation.
15 - * 15 + *
16 * This program is distributed in the hope that it will be useful, but WITHOUT 16 * This program is distributed in the hope that it will be useful, but WITHOUT
17 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS 17 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
18 * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more 18 * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
19 * details. 19 * details.
20 - * 20 + *
21 * You should have received a copy of the GNU General Public License 21 * You should have received a copy of the GNU General Public License
22 * along with this program. If not, see <http://www.gnu.org/licenses/>. 22 * along with this program. If not, see <http://www.gnu.org/licenses/>.
23 - * 23 + *
24 * You can contact The Jam Warehouse Software (Pty) Limited, Unit 1, Tramber Place, 24 * You can contact The Jam Warehouse Software (Pty) Limited, Unit 1, Tramber Place,
25 * Blake Street, Observatory, 7925 South Africa. or email info@knowledgetree.com. 25 * Blake Street, Observatory, 7925 South Africa. or email info@knowledgetree.com.
26 - * 26 + *
27 * The interactive user interfaces in modified source and object code versions 27 * The interactive user interfaces in modified source and object code versions
28 * of this program must display Appropriate Legal Notices, as required under 28 * of this program must display Appropriate Legal Notices, as required under
29 * Section 5 of the GNU General Public License version 3. 29 * Section 5 of the GNU General Public License version 3.
30 - * 30 + *
31 * In accordance with Section 7(b) of the GNU General Public License version 3, 31 * In accordance with Section 7(b) of the GNU General Public License version 3,
32 * these Appropriate Legal Notices must retain the display of the "Powered by 32 * these Appropriate Legal Notices must retain the display of the "Powered by
33 - * KnowledgeTree" logo and retain the original copyright notice. If the display of the 33 + * KnowledgeTree" logo and retain the original copyright notice. If the display of the
34 * logo is not reasonably feasible for technical reasons, the Appropriate Legal Notices 34 * logo is not reasonably feasible for technical reasons, the Appropriate Legal Notices
35 - * must display the words "Powered by KnowledgeTree" and retain the original  
36 - * copyright notice. 35 + * must display the words "Powered by KnowledgeTree" and retain the original
  36 + * copyright notice.
37 * Contributor( s): ______________________________________ 37 * Contributor( s): ______________________________________
38 */ 38 */
39 39
@@ -77,6 +77,29 @@ class KTOnDiskHashedStorageManager extends KTStorageManager { @@ -77,6 +77,29 @@ class KTOnDiskHashedStorageManager extends KTStorageManager {
77 } 77 }
78 } 78 }
79 79
  80 + /**
  81 + * Upload a temporary file
  82 + *
  83 + * @param unknown_type $sUploadedFile
  84 + * @param unknown_type $sTmpFilePath
  85 + * @return unknown
  86 + */
  87 + function uploadTmpFile($sUploadedFile, $sTmpFilePath) {
  88 +
  89 + //copy the file accross
  90 + if (OS_WINDOWS) {
  91 + $sTmpFilePath = str_replace('\\','/',$sTmpFilePath);
  92 + }
  93 + if ($this->writeToFile($sUploadedFile, $sTmpFilePath)) {
  94 + if (file_exists($sTmpFilePath)) {
  95 + return true;
  96 + } else {
  97 + return false;
  98 + }
  99 + }
  100 + return false;
  101 + }
  102 +
80 function writeToFile($sTmpFilePath, $sDocumentFileSystemPath) { 103 function writeToFile($sTmpFilePath, $sDocumentFileSystemPath) {
81 // Make it easy to write compressed/encrypted storage 104 // Make it easy to write compressed/encrypted storage
82 105
@@ -318,7 +341,7 @@ class KTOnDiskHashedStorageManager extends KTStorageManager { @@ -318,7 +341,7 @@ class KTOnDiskHashedStorageManager extends KTStorageManager {
318 $sDocumentRoot = $oConfig->get('urls/documentRoot'); 341 $sDocumentRoot = $oConfig->get('urls/documentRoot');
319 $iContentId = $oVersion->getContentVersionId(); 342 $iContentId = $oVersion->getContentVersionId();
320 $oContentVersion = KTDocumentContentVersion::get($iContentId); 343 $oContentVersion = KTDocumentContentVersion::get($iContentId);
321 - 344 +
322 $sPath = $oContentVersion->getStoragePath(); 345 $sPath = $oContentVersion->getStoragePath();
323 $sFullPath = sprintf("%s/%s", $sDocumentRoot, $sPath); 346 $sFullPath = sprintf("%s/%s", $sDocumentRoot, $sPath);
324 if (file_exists($sFullPath)) { 347 if (file_exists($sFullPath)) {
plugins/ktcore/folder/addDocument.php
@@ -5,32 +5,32 @@ @@ -5,32 +5,32 @@
5 * KnowledgeTree Open Source Edition 5 * KnowledgeTree Open Source Edition
6 * Document Management Made Simple 6 * Document Management Made Simple
7 * Copyright (C) 2004 - 2007 The Jam Warehouse Software (Pty) Limited 7 * Copyright (C) 2004 - 2007 The Jam Warehouse Software (Pty) Limited
8 - * 8 + *
9 * This program is free software; you can redistribute it and/or modify it under 9 * This program is free software; you can redistribute it and/or modify it under
10 * the terms of the GNU General Public License version 3 as published by the 10 * the terms of the GNU General Public License version 3 as published by the
11 * Free Software Foundation. 11 * Free Software Foundation.
12 - * 12 + *
13 * This program is distributed in the hope that it will be useful, but WITHOUT 13 * This program is distributed in the hope that it will be useful, but WITHOUT
14 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS 14 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
15 * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more 15 * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
16 * details. 16 * details.
17 - * 17 + *
18 * You should have received a copy of the GNU General Public License 18 * You should have received a copy of the GNU General Public License
19 * along with this program. If not, see <http://www.gnu.org/licenses/>. 19 * along with this program. If not, see <http://www.gnu.org/licenses/>.
20 - * 20 + *
21 * You can contact The Jam Warehouse Software (Pty) Limited, Unit 1, Tramber Place, 21 * You can contact The Jam Warehouse Software (Pty) Limited, Unit 1, Tramber Place,
22 * Blake Street, Observatory, 7925 South Africa. or email info@knowledgetree.com. 22 * Blake Street, Observatory, 7925 South Africa. or email info@knowledgetree.com.
23 - * 23 + *
24 * The interactive user interfaces in modified source and object code versions 24 * The interactive user interfaces in modified source and object code versions
25 * of this program must display Appropriate Legal Notices, as required under 25 * of this program must display Appropriate Legal Notices, as required under
26 * Section 5 of the GNU General Public License version 3. 26 * Section 5 of the GNU General Public License version 3.
27 - * 27 + *
28 * In accordance with Section 7(b) of the GNU General Public License version 3, 28 * In accordance with Section 7(b) of the GNU General Public License version 3,
29 * these Appropriate Legal Notices must retain the display of the "Powered by 29 * these Appropriate Legal Notices must retain the display of the "Powered by
30 - * KnowledgeTree" logo and retain the original copyright notice. If the display of the 30 + * KnowledgeTree" logo and retain the original copyright notice. If the display of the
31 * logo is not reasonably feasible for technical reasons, the Appropriate Legal Notices 31 * logo is not reasonably feasible for technical reasons, the Appropriate Legal Notices
32 - * must display the words "Powered by KnowledgeTree" and retain the original  
33 - * copyright notice. 32 + * must display the words "Powered by KnowledgeTree" and retain the original
  33 + * copyright notice.
34 * Contributor( s): ______________________________________ 34 * Contributor( s): ______________________________________
35 * 35 *
36 */ 36 */
@@ -193,14 +193,20 @@ class KTFolderAddDocumentAction extends KTFolderAction { @@ -193,14 +193,20 @@ class KTFolderAddDocumentAction extends KTFolderAction {
193 $sBasedir = $oKTConfig->get("urls/tmpDirectory"); 193 $sBasedir = $oKTConfig->get("urls/tmpDirectory");
194 194
195 $sFilename = tempnam($sBasedir, 'kt_storecontents'); 195 $sFilename = tempnam($sBasedir, 'kt_storecontents');
196 - $oContents = new KTFSFileLike($data['file']['tmp_name']);  
197 - $oOutputFile = new KTFSFileLike($sFilename);  
198 - $res = KTFileLikeUtil::copy_contents($oContents, $oOutputFile);  
199 - $data['file']['tmp_name'] = $sFilename;  
200 196
201 - if (PEAR::isError($res)) {  
202 - $oForm->handleError(sprintf(_kt("Failed to store file: %s"), $res->getMessage()));  
203 - } 197 + //$oContents = new KTFSFileLike($data['file']['tmp_name']);
  198 + //$oOutputFile = new KTFSFileLike($sFilename);
  199 + //$res = KTFileLikeUtil::copy_contents($oContents, $oOutputFile);
  200 +
  201 + //if (PEAR::isError($res)) {
  202 + // $oForm->handleError(sprintf(_kt("Failed to store file: %s"), $res->getMessage()));
  203 + //}
  204 +
  205 +
  206 + $oStorage =& KTStorageManagerUtil::getSingleton();
  207 + $oStorage->uploadTmpFile($data['file']['tmp_name'], $sFilename);
  208 +
  209 + $data['file']['tmp_name'] = $sFilename;
204 $_SESSION['_add_data'] = array($key => $data); 210 $_SESSION['_add_data'] = array($key => $data);
205 211
206 // if we don't need metadata 212 // if we don't need metadata
@@ -294,7 +300,7 @@ class KTFolderAddDocumentAction extends KTFolderAction { @@ -294,7 +300,7 @@ class KTFolderAddDocumentAction extends KTFolderAction {
294 $oUploadChannel->addObserver($mpo); 300 $oUploadChannel->addObserver($mpo);
295 301
296 require_once(KT_LIB_DIR . '/storage/storagemanager.inc.php'); 302 require_once(KT_LIB_DIR . '/storage/storagemanager.inc.php');
297 - require_once(KT_LIB_DIR . '/filelike/fsfilelike.inc.php'); 303 + //require_once(KT_LIB_DIR . '/filelike/fsfilelike.inc.php');
298 require_once(KT_LIB_DIR . '/documentmanagement/DocumentType.inc'); 304 require_once(KT_LIB_DIR . '/documentmanagement/DocumentType.inc');
299 require_once(KT_LIB_DIR . '/metadata/fieldset.inc.php'); 305 require_once(KT_LIB_DIR . '/metadata/fieldset.inc.php');
300 require_once(KT_LIB_DIR . '/documentmanagement/documentutil.inc.php'); 306 require_once(KT_LIB_DIR . '/documentmanagement/documentutil.inc.php');
@@ -309,7 +315,8 @@ class KTFolderAddDocumentAction extends KTFolderAction { @@ -309,7 +315,8 @@ class KTFolderAddDocumentAction extends KTFolderAction {
309 315
310 $iFolderId = $this->oFolder->getId(); 316 $iFolderId = $this->oFolder->getId();
311 $aOptions = array( 317 $aOptions = array(
312 - 'contents' => new KTFSFileLike($aFile['tmp_name']), 318 + // 'contents' => new KTFSFileLike($aFile['tmp_name']),
  319 + 'temp_file' => $aFile['tmp_name'],
313 'documenttype' => DocumentType::get($extra_d['document_type']), 320 'documenttype' => DocumentType::get($extra_d['document_type']),
314 'metadata' => $MDPack, 321 'metadata' => $MDPack,
315 'description' => $sTitle, 322 'description' => $sTitle,
sql/mysql/upgrade/3.5.2/scheduler_tasks.sql 0 โ†’ 100644
  1 +ALTER TABLE `scheduler_tasks` ADD `status` ENUM( 'enabled', 'disabled', 'system' ) NOT NULL DEFAULT 'disabled';
  2 +
  3 +UPDATE `scheduler_tasks` SET `status` = 'system' WHERE `task` = 'Indexing' OR `task` = 'Index Migration' OR `task` = 'Index Optimisation';
  4 +
  5 +INSERT INTO `scheduler_tasks` VALUES (4,'Periodic Document Expunge','bin/expungeall.php','',0,'weekly','2007-10-01',NULL,0,'disabled');
0 \ No newline at end of file 6 \ No newline at end of file
thirdparty/pear/WebDAV/Client.php deleted
1 -<?php  
2 -/* vim: set expandtab tabstop=4 shiftwidth=4: */  
3 -// +----------------------------------------------------------------------+  
4 -// | PHP version 4 |  
5 -// +----------------------------------------------------------------------+  
6 -// | Copyright (c) 1997-2003 The PHP Group |  
7 -// +----------------------------------------------------------------------+  
8 -// | This source file is subject to version 3.0 of the PHP license, |  
9 -// | that is bundled with this package in the file LICENSE, and is |  
10 -// | available through the world-wide-web at |  
11 -// | http://www.php.net/license/3_0.txt. |  
12 -// | If you did not receive a copy of the PHP license and are unable to |  
13 -// | obtain it through the world-wide-web, please send a note to |  
14 -// | license@php.net so we can mail you a copy immediately. |  
15 -// +----------------------------------------------------------------------+  
16 -// | Author: Alexey Borzov <avb@php.net> |  
17 -// +----------------------------------------------------------------------+  
18 -//  
19 -// $Id: Client.php 6819 2007-06-20 13:09:21Z kevin_fourie $  
20 -  
21 -require_once 'HTTP/Request.php';  
22 -require_once 'HTTP/Client/CookieManager.php';  
23 -  
24 -/**  
25 - * A simple HTTP client class.  
26 - *  
27 - * The class wraps around HTTP_Request providing a higher-level  
28 - * API for performing multiple HTTP requests  
29 - *  
30 - * @package HTTP_Client  
31 - * @author Alexey Borzov <avb@php.net>  
32 - * @version $Revision: 6819 $  
33 - */  
34 -class HTTP_Client  
35 -{  
36 - /**  
37 - * An HTTP_Client_CookieManager instance  
38 - * @var object  
39 - */  
40 - var $_cookieManager;  
41 -  
42 - /**  
43 - * Received HTTP responses  
44 - * @var array  
45 - */  
46 - var $_responses;  
47 -  
48 - /**  
49 - * Default headers to send on every request  
50 - * @var array  
51 - */  
52 - var $_defaultHeaders = array();  
53 -  
54 - /**  
55 - * Default parameters for HTTP_Request's constructor  
56 - * @var array  
57 - */  
58 - var $_defaultRequestParams = array();  
59 -  
60 - /**  
61 - * How many redirects were done  
62 - * @var integer  
63 - */  
64 - var $_redirectCount = 0;  
65 -  
66 - /**  
67 - * Maximum allowed redirects  
68 - * @var integer  
69 - */  
70 - var $_maxRedirects = 5;  
71 -  
72 - /**  
73 - * Listeners attached to the client  
74 - * @var array  
75 - */  
76 - var $_listeners = array();  
77 -  
78 - /**  
79 - * Whether the listener should be propagated to Request objects  
80 - * @var array  
81 - */  
82 - var $_propagate = array();  
83 -  
84 - /**  
85 - * Whether to keep all the responses or just the most recent one  
86 - * @var boolean  
87 - */  
88 - var $_isHistoryEnabled = true;  
89 -  
90 - /**  
91 - * Constructor  
92 - *  
93 - * @access public  
94 - * @param array Parameters to pass to HTTP_Request's constructor  
95 - * @param array Default headers to send on every request  
96 - */  
97 - function HTTP_Client($defaultRequestParams = null, $defaultHeaders = null)  
98 - {  
99 - $this->_cookieManager =& new HTTP_Client_CookieManager();  
100 - if (isset($defaultHeaders)) {  
101 - $this->setDefaultHeader($defaultHeaders);  
102 - }  
103 - if (isset($defaultRequestParams)) {  
104 - $this->setRequestParameter($defaultRequestParams);  
105 - }  
106 - }  
107 -  
108 -  
109 - /**  
110 - * Sets the maximum redirects that will be processed.  
111 - *  
112 - * Setting this to 0 disables redirect processing. If not 0 and the  
113 - * number of redirects in a request is bigger than this number, then an  
114 - * error will be raised.  
115 - *  
116 - * @access public  
117 - * @param int Max number of redirects to process  
118 - */  
119 - function setMaxRedirects($value)  
120 - {  
121 - $this->_maxRedirects = $value;  
122 - }  
123 -  
124 -  
125 - /**  
126 - * Sets whether to keep all the responses or just the most recent one  
127 - *  
128 - * @access public  
129 - * @param bool Whether to enable history  
130 - */  
131 - function enableHistory($enable)  
132 - {  
133 - $this->_isHistoryEnabled = (bool)$enable;  
134 - }  
135 -  
136 - /**  
137 - * Creates a HTTP_Request objects, applying all the necessary defaults  
138 - *  
139 - * @param string URL  
140 - * @param integer Method, constants are defined in HTTP_Request  
141 - * @access private  
142 - * @return object HTTP_Request object with all defaults applied  
143 - */  
144 - function &_createRequest($url, $method = HTTP_REQUEST_METHOD_GET)  
145 - {  
146 - $req =& new HTTP_Request($url, $this->_defaultRequestParams);  
147 - $req->setMethod($method);  
148 - foreach ($this->_defaultHeaders as $name => $value) {  
149 - $req->addHeader($name, $value);  
150 - }  
151 - $this->_cookieManager->passCookies($req);  
152 - foreach ($this->_propagate as $id => $propagate) {  
153 - if ($propagate) {  
154 - $req->attach($this->_listeners[$id]);  
155 - }  
156 - }  
157 - return $req;  
158 - }  
159 -  
160 -  
161 - /**  
162 - * Sends a 'HEAD' HTTP request  
163 - *  
164 - * @param string URL  
165 - * @access public  
166 - * @return integer HTTP response code  
167 - * @throws PEAR_Error  
168 - */  
169 - function head($url)  
170 - {  
171 - $request =& $this->_createRequest($url, HTTP_REQUEST_METHOD_HEAD);  
172 - return $this->_performRequest($request);  
173 - }  
174 -  
175 -  
176 - /**  
177 - * Sends a 'GET' HTTP request  
178 - *  
179 - * @param string URL  
180 - * @param mixed additional data to send  
181 - * @param boolean Whether the data is already urlencoded  
182 - * @access public  
183 - * @return integer HTTP response code  
184 - * @throws PEAR_Error  
185 - */  
186 - function get($url, $data = null, $preEncoded = false)  
187 - {  
188 - $request =& $this->_createRequest($url);  
189 - if (is_array($data)) {  
190 - foreach ($data as $name => $value) {  
191 - $request->addQueryString($name, $value, $preEncoded);  
192 - }  
193 - } elseif (isset($data)) {  
194 - $request->addRawQueryString($data, $preEncoded);  
195 - }  
196 - return $this->_performRequest($request);  
197 - }  
198 -  
199 -  
200 - /**  
201 - * Sends a 'POST' HTTP request  
202 - *  
203 - * @param string URL  
204 - * @param mixed Data to send  
205 - * @param boolean Whether the data is already urlencoded  
206 - * @param array Files to upload. Elements of the array should have the form:  
207 - * array(name, filename(s)[, content type]), see HTTP_Request::addFile()  
208 - * @access public  
209 - * @return integer HTTP response code  
210 - * @throws PEAR_Error  
211 - */  
212 - function post($url, $data, $preEncoded = false, $files = array())  
213 - {  
214 - $request =& $this->_createRequest($url, HTTP_REQUEST_METHOD_POST);  
215 - if (is_array($data)) {  
216 - foreach ($data as $name => $value) {  
217 - $request->addPostData($name, $value, $preEncoded);  
218 - }  
219 - } else {  
220 - $request->addRawPostData($data, $preEncoded);  
221 - }  
222 - foreach ($files as $fileData) {  
223 - $res = call_user_func_array(array(&$request, 'addFile'), $fileData);  
224 - if (PEAR::isError($res)) {  
225 - return $res;  
226 - }  
227 - }  
228 - return $this->_performRequest($request);  
229 - }  
230 -  
231 -  
232 - /**  
233 - * Sets default header(s) for HTTP requests  
234 - *  
235 - * @param mixed header name or array ('header name' => 'header value')  
236 - * @param string header value if $name is not an array  
237 - * @access public  
238 - */  
239 - function setDefaultHeader($name, $value = null)  
240 - {  
241 - if (is_array($name)) {  
242 - $this->_defaultHeaders = array_merge($this->_defaultHeaders, $name);  
243 - } else {  
244 - $this->_defaultHeaders[$name] = $value;  
245 - }  
246 - }  
247 -  
248 -  
249 - /**  
250 - * Sets parameter(s) for HTTP requests  
251 - *  
252 - * @param mixed parameter name or array ('parameter name' => 'parameter value')  
253 - * @param string parameter value if $name is not an array  
254 - * @access public  
255 - */  
256 - function setRequestParameter($name, $value = null)  
257 - {  
258 - if (is_array($name)) {  
259 - $this->_defaultRequestParams = array_merge($this->_defaultRequestParams, $name);  
260 - } else {  
261 - $this->_defaultRequestParams[$name] = $value;  
262 - }  
263 - }  
264 -  
265 -  
266 - /**  
267 - * Performs a request, processes redirects  
268 - *  
269 - * @param object HTTP_Request object  
270 - * @access private  
271 - * @return integer HTTP response code  
272 - * @throws PEAR_Error  
273 - */  
274 - function _performRequest(&$request)  
275 - {  
276 - // If this is not a redirect, notify the listeners of new request  
277 - if (0 == $this->_redirectCount) {  
278 - $this->_notify('request', $request->_url->getUrl());  
279 - }  
280 - if (PEAR::isError($err = $request->sendRequest())) {  
281 - return $err;  
282 - }  
283 - $this->_pushResponse($request);  
284 -  
285 - $code = $request->getResponseCode();  
286 - if ($this->_maxRedirects > 0 && in_array($code, array(300, 301, 302, 303, 307))) {  
287 - if (++$this->_redirectCount > $this->_maxRedirects) {  
288 - return PEAR::raiseError('Too many redirects');  
289 - }  
290 - $location = $request->getResponseHeader('Location');  
291 - if ('' == $location) {  
292 - return PEAR::raiseError("No 'Location' field on redirect");  
293 - }  
294 - $url = $this->_redirectUrl($request->_url, $location);  
295 - // Notify of redirection  
296 - $this->_notify('httpRedirect', $url);  
297 - // we access the private properties directly, as there are no accessors for them  
298 - switch ($request->_method) {  
299 - case HTTP_REQUEST_METHOD_POST:  
300 - if (302 == $code || 303 == $code) {  
301 - return $this->get($url);  
302 - } else {  
303 - $postFiles = array();  
304 - foreach ($request->_postFiles as $name => $data) {  
305 - $postFiles[] = array($name, $data['name'], $data['type']);  
306 - }  
307 - return $this->post($url, $request->_postData, true, $postFiles);  
308 - }  
309 - case HTTP_REQUEST_METHOD_HEAD:  
310 - return (303 == $code? $this->get($url): $this->head($url));  
311 - case HTTP_REQUEST_METHOD_GET:  
312 - default:  
313 - return $this->get($url);  
314 - } // switch  
315 -  
316 - } else {  
317 - $this->_redirectCount = 0;  
318 - if (400 >= $code) {  
319 - $this->_notify('httpSuccess');  
320 - $this->setDefaultHeader('Referer', $request->_url->getUrl());  
321 - // some result processing should go here  
322 - } else {  
323 - $this->_notify('httpError');  
324 - }  
325 - }  
326 - return $code;  
327 - }  
328 -  
329 -  
330 - /**  
331 - * Returns the most recent HTTP response  
332 - *  
333 - * @access public  
334 - * @return array  
335 - */  
336 - function &currentResponse()  
337 - {  
338 - return $this->_responses[count($this->_responses) - 1];  
339 - }  
340 -  
341 -  
342 - /**  
343 - * Saves the server's response to responses list  
344 - *  
345 - * @param object HTTP_Request object, with request already sent  
346 - * @access private  
347 - */  
348 - function _pushResponse(&$request)  
349 - {  
350 - $this->_cookieManager->updateCookies($request);  
351 - $idx = $this->_isHistoryEnabled? count($this->_responses): 0;  
352 - $this->_responses[$idx] = array(  
353 - 'code' => $request->getResponseCode(),  
354 - 'headers' => $request->getResponseHeader(),  
355 - 'body' => $request->getResponseBody()  
356 - );  
357 - }  
358 -  
359 -  
360 - /**  
361 - * Clears object's internal properties  
362 - *  
363 - * @access public  
364 - */  
365 - function reset()  
366 - {  
367 - $this->_cookieManager->reset();  
368 - $this->_responses = array();  
369 - $this->_defaultHeaders = array();  
370 - $this->_defaultRequestParams = array();  
371 - }  
372 -  
373 -  
374 - /**  
375 - * Adds a Listener to the list of listeners that are notified of  
376 - * the object's events  
377 - *  
378 - * @param object HTTP_Request_Listener instance to attach  
379 - * @param boolean Whether the listener should be attached to the  
380 - * created HTTP_Request objects  
381 - * @return boolean whether the listener was successfully attached  
382 - * @access public  
383 - */  
384 - function attach(&$listener, $propagate = false)  
385 - {  
386 - if (!is_a($listener, 'HTTP_Request_Listener')) {  
387 - return false;  
388 - }  
389 - $this->_listeners[$listener->getId()] =& $listener;  
390 - $this->_propagate[$listener->getId()] = $propagate;  
391 - return true;  
392 - }  
393 -  
394 -  
395 - /**  
396 - * Removes a Listener from the list of listeners  
397 - *  
398 - * @param object HTTP_Request_Listener instance to detach  
399 - * @return boolean whether the listener was successfully detached  
400 - * @access public  
401 - */  
402 - function detach(&$listener)  
403 - {  
404 - if (!is_a($listener, 'HTTP_Request_Listener') ||  
405 - !isset($this->_listeners[$listener->getId()])) {  
406 - return false;  
407 - }  
408 - unset($this->_listeners[$listener->getId()], $this->_propagate[$listener->getId()]);  
409 - return true;  
410 - }  
411 -  
412 -  
413 - /**  
414 - * Notifies all registered listeners of an event.  
415 - *  
416 - * Currently available events are:  
417 - * 'request': sent on HTTP request that is not a redirect  
418 - * 'httpSuccess': sent when we receive a successfull 2xx response  
419 - * 'httpRedirect': sent when we receive a redirection response  
420 - * 'httpError': sent on 4xx, 5xx response  
421 - *  
422 - * @param string Event name  
423 - * @param mixed Additional data  
424 - * @access private  
425 - */  
426 - function _notify($event, $data = null)  
427 - {  
428 - foreach (array_keys($this->_listeners) as $id) {  
429 - $this->_listeners[$id]->update($this, $event, $data);  
430 - }  
431 - }  
432 -  
433 -  
434 - /**  
435 - * Calculates the absolute URL of a redirect  
436 - *  
437 - * @param object Net_Url object containing the request URL  
438 - * @param string Value of the 'Location' response header  
439 - * @return string Absolute URL we are being redirected to  
440 - * @access private  
441 - */  
442 - function _redirectUrl($url, $location)  
443 - {  
444 - if (preg_match('!^https?://!i', $location)) {  
445 - return $location;  
446 - } else {  
447 - if ('/' == $location{0}) {  
448 - $url->path = Net_URL::resolvePath($location);  
449 - } elseif('/' == substr($url->path, -1)) {  
450 - $url->path = Net_URL::resolvePath($url->path . $location);  
451 - } else {  
452 - $dirname = (DIRECTORY_SEPARATOR == dirname($url->path)? '/': dirname($url->path));  
453 - $url->path = Net_URL::resolvePath($dirname . '/' . $location);  
454 - }  
455 - $url->querystring = array();  
456 - $url->anchor = '';  
457 - return $url->getUrl();  
458 - }  
459 - }  
460 -}  
461 -?>  
thirdparty/pear/WebDAV/Client/CookieManager.php deleted
1 -<?php  
2 -/* vim: set expandtab tabstop=4 shiftwidth=4: */  
3 -// +----------------------------------------------------------------------+  
4 -// | PHP version 4 |  
5 -// +----------------------------------------------------------------------+  
6 -// | Copyright (c) 1997-2003 The PHP Group |  
7 -// +----------------------------------------------------------------------+  
8 -// | This source file is subject to version 3.0 of the PHP license, |  
9 -// | that is bundled with this package in the file LICENSE, and is |  
10 -// | available through the world-wide-web at |  
11 -// | http://www.php.net/license/3_0.txt. |  
12 -// | If you did not receive a copy of the PHP license and are unable to |  
13 -// | obtain it through the world-wide-web, please send a note to |  
14 -// | license@php.net so we can mail you a copy immediately. |  
15 -// +----------------------------------------------------------------------+  
16 -// | Author: Alexey Borzov <avb@php.net> |  
17 -// +----------------------------------------------------------------------+  
18 -//  
19 -// $Id: CookieManager.php 6819 2007-06-20 13:09:21Z kevin_fourie $  
20 -  
21 -/**  
22 - * This class is used to store cookies and pass them between HTTP requests.  
23 - *  
24 - * @package HTTP_Client  
25 - * @author Alexey Borzov <avb@php.net>  
26 - * @version $Revision: 6819 $  
27 - */  
28 -class HTTP_Client_CookieManager  
29 -{  
30 - /**  
31 - * An array containing cookie values  
32 - * @var array  
33 - */  
34 - var $_cookies = array();  
35 -  
36 -  
37 - /**  
38 - * Constructor  
39 - *  
40 - * @access public  
41 - */  
42 - function HTTP_Client_CookieManager()  
43 - {  
44 - // abstract  
45 - }  
46 -  
47 -  
48 - /**  
49 - * Adds cookies to the request  
50 - *  
51 - * @access public  
52 - * @param object An HTTP_Request object  
53 - */  
54 - function passCookies(&$request)  
55 - {  
56 - if (!empty($this->_cookies)) {  
57 - $url =& $request->_url;  
58 - // We do not check cookie's "expires" field, as we do not store deleted  
59 - // cookies in the array and our client does not work long enough for other  
60 - // cookies to expire. If some kind of persistence is added to this object,  
61 - // then expiration should be checked upon loading and session cookies should  
62 - // be cleared on saving.  
63 - $cookies = array();  
64 - foreach ($this->_cookies as $cookie) {  
65 - if ($this->_domainMatch($url->host, $cookie['domain']) && (0 === strpos($url->path, $cookie['path']))  
66 - && (empty($cookie['secure']) || $url->protocol == 'https')) {  
67 - $cookies[$cookie['name']][strlen($cookie['path'])] = $cookie['value'];  
68 - }  
69 - }  
70 - // cookies with longer paths go first  
71 - foreach ($cookies as $name => $values) {  
72 - krsort($values);  
73 - foreach ($values as $value) {  
74 - $request->addCookie($name, $value);  
75 - }  
76 - }  
77 - }  
78 - return true;  
79 - }  
80 -  
81 -  
82 - /**  
83 - * Explicitly adds cookie to the list  
84 - *  
85 - * @param array An array representing cookie, this function expects all of the array's  
86 - * fields to be set  
87 - * @access public  
88 - */  
89 - function addCookie($cookie)  
90 - {  
91 - $hash = $this->_makeHash($cookie['name'], $cookie['domain'], $cookie['path']);  
92 - $this->_cookies[$hash] = $cookie;  
93 - }  
94 -  
95 -  
96 - /**  
97 - * Updates cookie list from HTTP server response  
98 - *  
99 - * @access public  
100 - * @param object An HTTP_Request object with sendRequest() already done  
101 - */  
102 - function updateCookies(&$request)  
103 - {  
104 - if (false !== ($cookies = $request->getResponseCookies())) {  
105 - $url =& $request->_url;  
106 - foreach ($cookies as $cookie) {  
107 - // use the current domain by default  
108 - if (!isset($cookie['domain'])) {  
109 - $cookie['domain'] = $url->host;  
110 - }  
111 - // use the path to the current page by default  
112 - if (!isset($cookie['path'])) {  
113 - $cookie['path'] = DIRECTORY_SEPARATOR == dirname($url->path)? '/': dirname($url->path);  
114 - }  
115 - // check if the domains match  
116 - if ($this->_domainMatch($url->host, $cookie['domain'])) {  
117 - $hash = $this->_makeHash($cookie['name'], $cookie['domain'], $cookie['path']);  
118 - // if value is empty or the time is in the past the cookie is deleted, else added  
119 - if (strlen($cookie['value'])  
120 - && (!isset($cookie['expires']) || (strtotime($cookie['expires']) > time()))) {  
121 - $this->_cookies[$hash] = $cookie;  
122 - } elseif (isset($this->_cookies[$hash])) {  
123 - unset($this->_cookies[$hash]);  
124 - }  
125 - }  
126 - }  
127 - }  
128 - }  
129 -  
130 -  
131 - /**  
132 - * Generates a key for the $_cookies array.  
133 - *  
134 - * The cookies is uniquely identified by its name, domain and path.  
135 - * Thus we cannot make f.e. an associative array with name as a key, we should  
136 - * generate a key from these 3 values.  
137 - *  
138 - * @access private  
139 - * @param string Cookie name  
140 - * @param string Cookie domain  
141 - * @param string Cookie path  
142 - * @return string a key  
143 - */  
144 - function _makeHash($name, $domain, $path)  
145 - {  
146 - return md5($name . "\r\n" . $domain . "\r\n" . $path);  
147 - }  
148 -  
149 -  
150 - /**  
151 - * Checks whether a cookie domain matches a request host.  
152 - *  
153 - * Cookie domain can begin with a dot, it also must contain at least  
154 - * two dots.  
155 - *  
156 - * @access private  
157 - * @param string request host  
158 - * @param string cookie domain  
159 - * @return bool match success  
160 - */  
161 - function _domainMatch($requestHost, $cookieDomain)  
162 - {  
163 - if ('.' != $cookieDomain{0}) {  
164 - return $requestHost == $cookieDomain;  
165 - } elseif (substr_count($cookieDomain, '.') < 2) {  
166 - return false;  
167 - } else {  
168 - return substr('.'. $requestHost, - strlen($cookieDomain)) == $cookieDomain;  
169 - }  
170 - }  
171 -  
172 -  
173 - /**  
174 - * Clears the $_cookies array  
175 - *  
176 - * @access public  
177 - */  
178 - function reset()  
179 - {  
180 - $this->_cookies = array();  
181 - }  
182 -}  
183 -?>  
thirdparty/pear/WebDAV/Download.php deleted
1 -<?php  
2 -/* vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4: */  
3 -  
4 -/**  
5 - * HTTP::Download  
6 - *  
7 - * PHP versions 4 and 5  
8 - *  
9 - * @category HTTP  
10 - * @package HTTP_Download  
11 - * @author Michael Wallner <mike@php.net>  
12 - * @copyright 2003-2005 Michael Wallner  
13 - * @license BSD, revised  
14 - * @version CVS: $Id: Download.php 6819 2007-06-20 13:09:21Z kevin_fourie $  
15 - * @link http://pear.php.net/package/HTTP_Download  
16 - */  
17 -  
18 -// {{{ includes  
19 -/**  
20 - * Requires PEAR  
21 - */  
22 -require_once 'PEAR.php';  
23 -  
24 -/**  
25 - * Requires HTTP_Header  
26 - */  
27 -require_once 'HTTP/Header.php';  
28 -// }}}  
29 -  
30 -// {{{ constants  
31 -/**#@+ Use with HTTP_Download::setContentDisposition() **/  
32 -/**  
33 - * Send data as attachment  
34 - */  
35 -define('HTTP_DOWNLOAD_ATTACHMENT', 'attachment');  
36 -/**  
37 - * Send data inline  
38 - */  
39 -define('HTTP_DOWNLOAD_INLINE', 'inline');  
40 -/**#@-**/  
41 -  
42 -/**#@+ Use with HTTP_Download::sendArchive() **/  
43 -/**  
44 - * Send as uncompressed tar archive  
45 - */  
46 -define('HTTP_DOWNLOAD_TAR', 'TAR');  
47 -/**  
48 - * Send as gzipped tar archive  
49 - */  
50 -define('HTTP_DOWNLOAD_TGZ', 'TGZ');  
51 -/**  
52 - * Send as bzip2 compressed tar archive  
53 - */  
54 -define('HTTP_DOWNLOAD_BZ2', 'BZ2');  
55 -/**  
56 - * Send as zip archive  
57 - */  
58 -define('HTTP_DOWNLOAD_ZIP', 'ZIP');  
59 -/**#@-**/  
60 -  
61 -/**#@+  
62 - * Error constants  
63 - */  
64 -define('HTTP_DOWNLOAD_E_HEADERS_SENT', -1);  
65 -define('HTTP_DOWNLOAD_E_NO_EXT_ZLIB', -2);  
66 -define('HTTP_DOWNLOAD_E_NO_EXT_MMAGIC', -3);  
67 -define('HTTP_DOWNLOAD_E_INVALID_FILE', -4);  
68 -define('HTTP_DOWNLOAD_E_INVALID_PARAM', -5);  
69 -define('HTTP_DOWNLOAD_E_INVALID_RESOURCE', -6);  
70 -define('HTTP_DOWNLOAD_E_INVALID_REQUEST', -7);  
71 -define('HTTP_DOWNLOAD_E_INVALID_CONTENT_TYPE', -8);  
72 -define('HTTP_DOWNLOAD_E_INVALID_ARCHIVE_TYPE', -9);  
73 -/**#@-**/  
74 -// }}}  
75 -  
76 -/**  
77 - * Send HTTP Downloads/Responses.  
78 - *  
79 - * With this package you can handle (hidden) downloads.  
80 - * It supports partial downloads, resuming and sending  
81 - * raw data ie. from database BLOBs.  
82 - *  
83 - * <i>ATTENTION:</i>  
84 - * You shouldn't use this package together with ob_gzhandler or  
85 - * zlib.output_compression enabled in your php.ini, especially  
86 - * if you want to send already gzipped data!  
87 - *  
88 - * @access public  
89 - * @version $Revision: 6819 $  
90 - */  
91 -class HTTP_Download  
92 -{  
93 - // {{{ protected member variables  
94 - /**  
95 - * Path to file for download  
96 - *  
97 - * @see HTTP_Download::setFile()  
98 - * @access protected  
99 - * @var string  
100 - */  
101 - var $file = '';  
102 -  
103 - /**  
104 - * Data for download  
105 - *  
106 - * @see HTTP_Download::setData()  
107 - * @access protected  
108 - * @var string  
109 - */  
110 - var $data = null;  
111 -  
112 - /**  
113 - * Resource handle for download  
114 - *  
115 - * @see HTTP_Download::setResource()  
116 - * @access protected  
117 - * @var int  
118 - */  
119 - var $handle = null;  
120 -  
121 - /**  
122 - * Whether to gzip the download  
123 - *  
124 - * @access protected  
125 - * @var bool  
126 - */  
127 - var $gzip = false;  
128 -  
129 - /**  
130 - * Whether to allow caching of the download on the clients side  
131 - *  
132 - * @access protected  
133 - * @var bool  
134 - */  
135 - var $cache = true;  
136 -  
137 - /**  
138 - * Size of download  
139 - *  
140 - * @access protected  
141 - * @var int  
142 - */  
143 - var $size = 0;  
144 -  
145 - /**  
146 - * Last modified  
147 - *  
148 - * @access protected  
149 - * @var int  
150 - */  
151 - var $lastModified = 0;  
152 -  
153 - /**  
154 - * HTTP headers  
155 - *  
156 - * @access protected  
157 - * @var array  
158 - */  
159 - var $headers = array(  
160 - 'Content-Type' => 'application/x-octetstream',  
161 - 'Pragma' => 'cache',  
162 - 'Cache-Control' => 'public, must-revalidate, max-age=0',  
163 - 'Accept-Ranges' => 'bytes',  
164 - 'X-Sent-By' => 'PEAR::HTTP::Download'  
165 - );  
166 -  
167 - /**  
168 - * HTTP_Header  
169 - *  
170 - * @access protected  
171 - * @var object  
172 - */  
173 - var $HTTP = null;  
174 -  
175 - /**  
176 - * ETag  
177 - *  
178 - * @access protected  
179 - * @var string  
180 - */  
181 - var $etag = '';  
182 -  
183 - /**  
184 - * Buffer Size  
185 - *  
186 - * @access protected  
187 - * @var int  
188 - */  
189 - var $bufferSize = 2097152;  
190 -  
191 - /**  
192 - * Throttle Delay  
193 - *  
194 - * @access protected  
195 - * @var float  
196 - */  
197 - var $throttleDelay = 0;  
198 -  
199 - /**  
200 - * Sent Bytes  
201 - *  
202 - * @access public  
203 - * @var int  
204 - */  
205 - var $sentBytes = 0;  
206 - // }}}  
207 -  
208 - // {{{ constructor  
209 - /**  
210 - * Constructor  
211 - *  
212 - * Set supplied parameters.  
213 - *  
214 - * @access public  
215 - * @param array $params associative array of parameters  
216 - *  
217 - * <b>one of:</b>  
218 - * o 'file' => path to file for download  
219 - * o 'data' => raw data for download  
220 - * o 'resource' => resource handle for download  
221 - * <br/>  
222 - * <b>and any of:</b>  
223 - * o 'cache' => whether to allow cs caching  
224 - * o 'gzip' => whether to gzip the download  
225 - * o 'lastmodified' => unix timestamp  
226 - * o 'contenttype' => content type of download  
227 - * o 'contentdisposition' => content disposition  
228 - * o 'buffersize' => amount of bytes to buffer  
229 - * o 'throttledelay' => amount of secs to sleep  
230 - * o 'cachecontrol' => cache privacy and validity  
231 - *  
232 - * <br />  
233 - * 'Content-Disposition' is not HTTP compliant, but most browsers  
234 - * follow this header, so it was borrowed from MIME standard.  
235 - *  
236 - * It looks like this: <br />  
237 - * "Content-Disposition: attachment; filename=example.tgz".  
238 - *  
239 - * @see HTTP_Download::setContentDisposition()  
240 - */  
241 - function HTTP_Download($params = array())  
242 - {  
243 - $this->HTTP = &new HTTP_Header;  
244 - $this->setParams($params);  
245 - }  
246 - // }}}  
247 -  
248 - // {{{ public methods  
249 - /**  
250 - * Set parameters  
251 - *  
252 - * Set supplied parameters through its accessor methods.  
253 - *  
254 - * @access public  
255 - * @return mixed Returns true on success or PEAR_Error on failure.  
256 - * @param array $params associative array of parameters  
257 - *  
258 - * @see HTTP_Download::HTTP_Download()  
259 - */  
260 - function setParams($params)  
261 - {  
262 - foreach((array) $params as $param => $value){  
263 - $method = 'set'. $param;  
264 -  
265 - if (!method_exists($this, $method)) {  
266 - return PEAR::raiseError(  
267 - "Method '$method' doesn't exist.",  
268 - HTTP_DOWNLOAD_E_INVALID_PARAM  
269 - );  
270 - }  
271 -  
272 - $e = call_user_func_array(array(&$this, $method), (array) $value);  
273 -  
274 - if (PEAR::isError($e)) {  
275 - return $e;  
276 - }  
277 - }  
278 - return true;  
279 - }  
280 -  
281 - /**  
282 - * Set path to file for download  
283 - *  
284 - * The Last-Modified header will be set to files filemtime(), actually.  
285 - * Returns PEAR_Error (HTTP_DOWNLOAD_E_INVALID_FILE) if file doesn't exist.  
286 - * Sends HTTP 404 status if $send_404 is set to true.  
287 - *  
288 - * @access public  
289 - * @return mixed Returns true on success or PEAR_Error on failure.  
290 - * @param string $file path to file for download  
291 - * @param bool $send_404 whether to send HTTP/404 if  
292 - * the file wasn't found  
293 - */  
294 - function setFile($file, $send_404 = true)  
295 - {  
296 - $file = realpath($file);  
297 - if (!is_file($file)) {  
298 - if ($send_404) {  
299 - $this->HTTP->sendStatusCode(404);  
300 - }  
301 - return PEAR::raiseError(  
302 - "File '$file' not found.",  
303 - HTTP_DOWNLOAD_E_INVALID_FILE  
304 - );  
305 - }  
306 - $this->setLastModified(filemtime($file));  
307 - $this->file = $file;  
308 - $this->size = filesize($file);  
309 - return true;  
310 - }  
311 -  
312 - /**  
313 - * Set data for download  
314 - *  
315 - * Set $data to null if you want to unset this.  
316 - *  
317 - * @access public  
318 - * @return void  
319 - * @param $data raw data to send  
320 - */  
321 - function setData($data = null)  
322 - {  
323 - $this->data = $data;  
324 - $this->size = strlen($data);  
325 - }  
326 -  
327 - /**  
328 - * Set resource for download  
329 - *  
330 - * The resource handle supplied will be closed after sending the download.  
331 - * Returns a PEAR_Error (HTTP_DOWNLOAD_E_INVALID_RESOURCE) if $handle  
332 - * is no valid resource. Set $handle to null if you want to unset this.  
333 - *  
334 - * @access public  
335 - * @return mixed Returns true on success or PEAR_Error on failure.  
336 - * @param int $handle resource handle  
337 - */  
338 - function setResource($handle = null)  
339 - {  
340 - if (!isset($handle)) {  
341 - $this->handle = null;  
342 - $this->size = 0;  
343 - return true;  
344 - }  
345 -  
346 - if (is_resource($handle)) {  
347 - $this->handle = $handle;  
348 - $filestats = fstat($handle);  
349 - $this->size = $filestats['size'];  
350 - return true;  
351 - }  
352 -  
353 - return PEAR::raiseError(  
354 - "Handle '$handle' is no valid resource.",  
355 - HTTP_DOWNLOAD_E_INVALID_RESOURCE  
356 - );  
357 - }  
358 -  
359 - /**  
360 - * Whether to gzip the download  
361 - *  
362 - * Returns a PEAR_Error (HTTP_DOWNLOAD_E_NO_EXT_ZLIB)  
363 - * if ext/zlib is not available/loadable.  
364 - *  
365 - * @access public  
366 - * @return mixed Returns true on success or PEAR_Error on failure.  
367 - * @param bool $gzip whether to gzip the download  
368 - */  
369 - function setGzip($gzip = false)  
370 - {  
371 - if ($gzip && !PEAR::loadExtension('zlib')){  
372 - return PEAR::raiseError(  
373 - 'GZIP compression (ext/zlib) not available.',  
374 - HTTP_DOWNLOAD_E_NO_EXT_ZLIB  
375 - );  
376 - }  
377 - $this->gzip = (bool) $gzip;  
378 - return true;  
379 - }  
380 -  
381 - /**  
382 - * Whether to allow caching  
383 - *  
384 - * If set to true (default) we'll send some headers that are commonly  
385 - * used for caching purposes like ETag, Cache-Control and Last-Modified.  
386 - *  
387 - * If caching is disabled, we'll send the download no matter if it  
388 - * would actually be cached at the client side.  
389 - *  
390 - * @access public  
391 - * @return void  
392 - * @param bool $cache whether to allow caching  
393 - */  
394 - function setCache($cache = true)  
395 - {  
396 - $this->cache = (bool) $cache;  
397 - }  
398 -  
399 - /**  
400 - * Whether to allow proxies to cache  
401 - *  
402 - * If set to 'private' proxies shouldn't cache the response.  
403 - * This setting defaults to 'public' and affects only cached responses.  
404 - *  
405 - * @access public  
406 - * @return bool  
407 - * @param string $cache private or public  
408 - * @param int $maxage maximum age of the client cache entry  
409 - */  
410 - function setCacheControl($cache = 'public', $maxage = 0)  
411 - {  
412 - switch ($cache = strToLower($cache))  
413 - {  
414 - case 'private':  
415 - case 'public':  
416 - $this->headers['Cache-Control'] =  
417 - $cache .', must-revalidate, max-age='. abs($maxage);  
418 - return true;  
419 - break;  
420 - }  
421 - return false;  
422 - }  
423 -  
424 - /**  
425 - * Set ETag  
426 - *  
427 - * Sets a user-defined ETag for cache-validation. The ETag is usually  
428 - * generated by HTTP_Download through its payload information.  
429 - *  
430 - * @access public  
431 - * @return void  
432 - * @param string $etag Entity tag used for strong cache validation.  
433 - */  
434 - function setETag($etag = null)  
435 - {  
436 - $this->etag = (string) $etag;  
437 - }  
438 -  
439 - /**  
440 - * Set Size of Buffer  
441 - *  
442 - * The amount of bytes specified as buffer size is the maximum amount  
443 - * of data read at once from resources or files. The default size is 2M  
444 - * (2097152 bytes). Be aware that if you enable gzip compression and  
445 - * you set a very low buffer size that the actual file size may grow  
446 - * due to added gzip headers for each sent chunk of the specified size.  
447 - *  
448 - * Returns PEAR_Error (HTTP_DOWNLOAD_E_INVALID_PARAM) if $size is not  
449 - * greater than 0 bytes.  
450 - *  
451 - * @access public  
452 - * @return mixed Returns true on success or PEAR_Error on failure.  
453 - * @param int $bytes Amount of bytes to use as buffer.  
454 - */  
455 - function setBufferSize($bytes = 2097152)  
456 - {  
457 - if (0 >= $bytes) {  
458 - return PEAR::raiseError(  
459 - 'Buffer size must be greater than 0 bytes ('. $bytes .' given)',  
460 - HTTP_DOWNLOAD_E_INVALID_PARAM);  
461 - }  
462 - $this->bufferSize = abs($bytes);  
463 - return true;  
464 - }  
465 -  
466 - /**  
467 - * Set Throttle Delay  
468 - *  
469 - * Set the amount of seconds to sleep after each chunck that has been  
470 - * sent. One can implement some sort of throttle through adjusting the  
471 - * buffer size and the throttle delay. With the following settings  
472 - * HTTP_Download will sleep a second after each 25 K of data sent.  
473 - *  
474 - * <code>  
475 - * Array(  
476 - * 'throttledelay' => 1,  
477 - * 'buffersize' => 1024 * 25,  
478 - * )  
479 - * </code>  
480 - *  
481 - * Just be aware that if gzipp'ing is enabled, decreasing the chunk size  
482 - * too much leads to proportionally increased network traffic due to added  
483 - * gzip header and bottom bytes around each chunk.  
484 - *  
485 - * @access public  
486 - * @return void  
487 - * @param float $seconds Amount of seconds to sleep after each  
488 - * chunk that has been sent.  
489 - */  
490 - function setThrottleDelay($seconds = 0)  
491 - {  
492 - $this->throttleDelay = abs($seconds) * 1000;  
493 - }  
494 -  
495 - /**  
496 - * Set "Last-Modified"  
497 - *  
498 - * This is usually determined by filemtime() in HTTP_Download::setFile()  
499 - * If you set raw data for download with HTTP_Download::setData() and you  
500 - * want do send an appropiate "Last-Modified" header, you should call this  
501 - * method.  
502 - *  
503 - * @access public  
504 - * @return void  
505 - * @param int unix timestamp  
506 - */  
507 - function setLastModified($last_modified)  
508 - {  
509 - $this->lastModified = $this->headers['Last-Modified'] = (int) $last_modified;  
510 - }  
511 -  
512 - /**  
513 - * Set Content-Disposition header  
514 - *  
515 - * @see HTTP_Download::HTTP_Download  
516 - *  
517 - * @access public  
518 - * @return void  
519 - * @param string $disposition whether to send the download  
520 - * inline or as attachment  
521 - * @param string $file_name the filename to display in  
522 - * the browser's download window  
523 - *  
524 - * <b>Example:</b>  
525 - * <code>  
526 - * $HTTP_Download->setContentDisposition(  
527 - * HTTP_DOWNLOAD_ATTACHMENT,  
528 - * 'download.tgz'  
529 - * );  
530 - * </code>  
531 - */  
532 - function setContentDisposition( $disposition = HTTP_DOWNLOAD_ATTACHMENT,  
533 - $file_name = null)  
534 - {  
535 - $cd = $disposition;  
536 - if (isset($file_name)) {  
537 - $cd .= '; filename="' . $file_name . '"';  
538 - } elseif ($this->file) {  
539 - $cd .= '; filename="' . basename($this->file) . '"';  
540 - }  
541 - $this->headers['Content-Disposition'] = $cd;  
542 - }  
543 -  
544 - /**  
545 - * Set content type of the download  
546 - *  
547 - * Default content type of the download will be 'application/x-octetstream'.  
548 - * Returns PEAR_Error (HTTP_DOWNLOAD_E_INVALID_CONTENT_TYPE) if  
549 - * $content_type doesn't seem to be valid.  
550 - *  
551 - * @access public  
552 - * @return mixed Returns true on success or PEAR_Error on failure.  
553 - * @param string $content_type content type of file for download  
554 - */  
555 - function setContentType($content_type = 'application/x-octetstream')  
556 - {  
557 - if (!preg_match('/^[a-z]+\w*\/[a-z]+[\w.;= -]*$/', $content_type)) {  
558 - return PEAR::raiseError(  
559 - "Invalid content type '$content_type' supplied.",  
560 - HTTP_DOWNLOAD_E_INVALID_CONTENT_TYPE  
561 - );  
562 - }  
563 - $this->headers['Content-Type'] = $content_type;  
564 - return true;  
565 - }  
566 -  
567 - /**  
568 - * Guess content type of file  
569 - *  
570 - * First we try to use PEAR::MIME_Type, if installed, to detect the content  
571 - * type, else we check if ext/mime_magic is loaded and properly configured.  
572 - *  
573 - * Returns PEAR_Error if:  
574 - * o if PEAR::MIME_Type failed to detect a proper content type  
575 - * (HTTP_DOWNLOAD_E_INVALID_CONTENT_TYPE)  
576 - * o ext/magic.mime is not installed, or not properly configured  
577 - * (HTTP_DOWNLOAD_E_NO_EXT_MMAGIC)  
578 - * o mime_content_type() couldn't guess content type or returned  
579 - * a content type considered to be bogus by setContentType()  
580 - * (HTTP_DOWNLOAD_E_INVALID_CONTENT_TYPE)  
581 - *  
582 - * @access public  
583 - * @return mixed Returns true on success or PEAR_Error on failure.  
584 - */  
585 - function guessContentType()  
586 - {  
587 - if (class_exists('MIME_Type') || @include_once 'MIME/Type.php') {  
588 - if (PEAR::isError($mime_type = MIME_Type::autoDetect($this->file))) {  
589 - return PEAR::raiseError($mime_type->getMessage(),  
590 - HTTP_DOWNLOAD_E_INVALID_CONTENT_TYPE);  
591 - }  
592 - return $this->setContentType($mime_type);  
593 - }  
594 - if (!function_exists('mime_content_type')) {  
595 - return PEAR::raiseError(  
596 - 'This feature requires ext/mime_magic!',  
597 - HTTP_DOWNLOAD_E_NO_EXT_MMAGIC  
598 - );  
599 - }  
600 - if (!is_file(ini_get('mime_magic.magicfile'))) {  
601 - return PEAR::raiseError(  
602 - 'ext/mime_magic is loaded but not properly configured!',  
603 - HTTP_DOWNLOAD_E_NO_EXT_MMAGIC  
604 - );  
605 - }  
606 - if (!$content_type = @mime_content_type($this->file)) {  
607 - return PEAR::raiseError(  
608 - 'Couldn\'t guess content type with mime_content_type().',  
609 - HTTP_DOWNLOAD_E_INVALID_CONTENT_TYPE  
610 - );  
611 - }  
612 - return $this->setContentType($content_type);  
613 - }  
614 -  
615 - /**  
616 - * Send  
617 - *  
618 - * Returns PEAR_Error if:  
619 - * o HTTP headers were already sent (HTTP_DOWNLOAD_E_HEADERS_SENT)  
620 - * o HTTP Range was invalid (HTTP_DOWNLOAD_E_INVALID_REQUEST)  
621 - *  
622 - * @access public  
623 - * @return mixed Returns true on success or PEAR_Error on failure.  
624 - * @param bool $autoSetContentDisposition Whether to set the  
625 - * Content-Disposition header if it isn't already.  
626 - */  
627 - function send($autoSetContentDisposition = true)  
628 - {  
629 - if (headers_sent()) {  
630 - return PEAR::raiseError(  
631 - 'Headers already sent.',  
632 - HTTP_DOWNLOAD_E_HEADERS_SENT  
633 - );  
634 - }  
635 -  
636 - if (!ini_get('safe_mode')) {  
637 - @set_time_limit(0);  
638 - }  
639 -  
640 - if ($autoSetContentDisposition &&  
641 - !isset($this->headers['Content-Disposition'])) {  
642 - $this->setContentDisposition();  
643 - }  
644 -  
645 - if ($this->cache) {  
646 - $this->headers['ETag'] = $this->generateETag();  
647 - if ($this->isCached()) {  
648 - $this->HTTP->sendStatusCode(304);  
649 - $this->sendHeaders();  
650 - return true;  
651 - }  
652 - } else {  
653 - unset($this->headers['Last-Modified']);  
654 - }  
655 -  
656 - while (@ob_end_clean());  
657 -  
658 - if ($this->gzip) {  
659 - @ob_start('ob_gzhandler');  
660 - } else {  
661 - ob_start();  
662 - }  
663 -  
664 - $this->sentBytes = 0;  
665 -  
666 - if ($this->isRangeRequest()) {  
667 - $this->HTTP->sendStatusCode(206);  
668 - $chunks = $this->getChunks();  
669 - } else {  
670 - $this->HTTP->sendStatusCode(200);  
671 - $chunks = array(array(0, $this->size));  
672 - if (!$this->gzip && count(ob_list_handlers()) < 2) {  
673 - $this->headers['Content-Length'] = $this->size;  
674 - }  
675 - }  
676 -  
677 - if (PEAR::isError($e = $this->sendChunks($chunks))) {  
678 - ob_end_clean();  
679 - $this->HTTP->sendStatusCode(416);  
680 - return $e;  
681 - }  
682 -  
683 - ob_end_flush();  
684 - flush();  
685 - return true;  
686 - }  
687 -  
688 - /**  
689 - * Static send  
690 - *  
691 - * @see HTTP_Download::HTTP_Download()  
692 - * @see HTTP_Download::send()  
693 - *  
694 - * @static  
695 - * @access public  
696 - * @return mixed Returns true on success or PEAR_Error on failure.  
697 - * @param array $params associative array of parameters  
698 - * @param bool $guess whether HTTP_Download::guessContentType()  
699 - * should be called  
700 - */  
701 - function staticSend($params, $guess = false)  
702 - {  
703 - $d = &new HTTP_Download();  
704 - $e = $d->setParams($params);  
705 - if (PEAR::isError($e)) {  
706 - return $e;  
707 - }  
708 - if ($guess) {  
709 - $e = $d->guessContentType();  
710 - if (PEAR::isError($e)) {  
711 - return $e;  
712 - }  
713 - }  
714 - return $d->send();  
715 - }  
716 -  
717 - /**  
718 - * Send a bunch of files or directories as an archive  
719 - *  
720 - * Example:  
721 - * <code>  
722 - * require_once 'HTTP/Download.php';  
723 - * HTTP_Download::sendArchive(  
724 - * 'myArchive.tgz',  
725 - * '/var/ftp/pub/mike',  
726 - * HTTP_DOWNLOAD_TGZ,  
727 - * '',  
728 - * '/var/ftp/pub'  
729 - * );  
730 - * </code>  
731 - *  
732 - * @see Archive_Tar::createModify()  
733 - * @deprecated use HTTP_Download_Archive::send()  
734 - * @static  
735 - * @access public  
736 - * @return mixed Returns true on success or PEAR_Error on failure.  
737 - * @param string $name name the sent archive should have  
738 - * @param mixed $files files/directories  
739 - * @param string $type archive type  
740 - * @param string $add_path path that should be prepended to the files  
741 - * @param string $strip_path path that should be stripped from the files  
742 - */  
743 - function sendArchive( $name,  
744 - $files,  
745 - $type = HTTP_DOWNLOAD_TGZ,  
746 - $add_path = '',  
747 - $strip_path = '')  
748 - {  
749 - require_once 'HTTP/Download/Archive.php';  
750 - return HTTP_Download_Archive::send($name, $files, $type,  
751 - $add_path, $strip_path);  
752 - }  
753 - // }}}  
754 -  
755 - // {{{ protected methods  
756 - /**  
757 - * Generate ETag  
758 - *  
759 - * @access protected  
760 - * @return string  
761 - */  
762 - function generateETag()  
763 - {  
764 - if (!$this->etag) {  
765 - if ($this->data) {  
766 - $md5 = md5($this->data);  
767 - } else {  
768 - $fst = is_resource($this->handle) ?  
769 - fstat($this->handle) : stat($this->file);  
770 - $md5 = md5($fst['mtime'] .'='. $fst['ino'] .'='. $fst['size']);  
771 - }  
772 - $this->etag = '"' . $md5 . '-' . crc32($md5) . '"';  
773 - }  
774 - return $this->etag;  
775 - }  
776 -  
777 - /**  
778 - * Send multiple chunks  
779 - *  
780 - * @access protected  
781 - * @return mixed Returns true on success or PEAR_Error on failure.  
782 - * @param array $chunks  
783 - */  
784 - function sendChunks($chunks)  
785 - {  
786 - if (count($chunks) == 1) {  
787 - return $this->sendChunk(array_shift($chunks));  
788 - }  
789 -  
790 - $bound = uniqid('HTTP_DOWNLOAD-', true);  
791 - $cType = $this->headers['Content-Type'];  
792 - $this->headers['Content-Type'] =  
793 - 'multipart/byteranges; boundary=' . $bound;  
794 - $this->sendHeaders();  
795 - foreach ($chunks as $chunk){  
796 - if (PEAR::isError($e = $this->sendChunk($chunk, $cType, $bound))) {  
797 - return $e;  
798 - }  
799 - }  
800 - #echo "\r\n--$bound--\r\n";  
801 - return true;  
802 - }  
803 -  
804 - /**  
805 - * Send chunk of data  
806 - *  
807 - * @access protected  
808 - * @return mixed Returns true on success or PEAR_Error on failure.  
809 - * @param array $chunk start and end offset of the chunk to send  
810 - * @param string $cType actual content type  
811 - * @param string $bound boundary for multipart/byteranges  
812 - */  
813 - function sendChunk($chunk, $cType = null, $bound = null)  
814 - {  
815 - list($offset, $lastbyte) = $chunk;  
816 - $length = ($lastbyte - $offset) + 1;  
817 -  
818 - if ($length < 1) {  
819 - return PEAR::raiseError(  
820 - "Error processing range request: $offset-$lastbyte/$length",  
821 - HTTP_DOWNLOAD_E_INVALID_REQUEST  
822 - );  
823 - }  
824 -  
825 - $range = $offset . '-' . $lastbyte . '/' . $this->size;  
826 -  
827 - if (isset($cType, $bound)) {  
828 - echo "\r\n--$bound\r\n",  
829 - "Content-Type: $cType\r\n",  
830 - "Content-Range: bytes $range\r\n\r\n";  
831 - } else {  
832 - if ($this->isRangeRequest()) {  
833 - $this->headers['Content-Range'] = 'bytes '. $range;  
834 - }  
835 - $this->sendHeaders();  
836 - }  
837 -  
838 - if ($this->data) {  
839 - while (($length -= $this->bufferSize) > 0) {  
840 - $this->flush(substr($this->data, $offset, $this->bufferSize));  
841 - $this->throttleDelay and $this->sleep();  
842 - $offset += $this->bufferSize;  
843 - }  
844 - if ($length) {  
845 - $this->flush(substr($this->data, $offset, $this->bufferSize + $length));  
846 - }  
847 - } else {  
848 - if (!is_resource($this->handle)) {  
849 - $this->handle = fopen($this->file, 'rb');  
850 - }  
851 - fseek($this->handle, $offset);  
852 - while (($length -= $this->bufferSize) > 0) {  
853 - $this->flush(fread($this->handle, $this->bufferSize));  
854 - $this->throttleDelay and $this->sleep();  
855 - }  
856 - if ($length) {  
857 - $this->flush(fread($this->handle, $this->bufferSize + $length));  
858 - }  
859 - }  
860 - return true;  
861 - }  
862 -  
863 - /**  
864 - * Get chunks to send  
865 - *  
866 - * @access protected  
867 - * @return array  
868 - */  
869 - function getChunks()  
870 - {  
871 - $parts = array();  
872 - foreach (explode(',', $this->getRanges()) as $chunk){  
873 - list($o, $e) = explode('-', $chunk);  
874 - if ($e >= $this->size || (empty($e) && $e !== 0 && $e !== '0')) {  
875 - $e = $this->size - 1;  
876 - }  
877 - if (empty($o) && $o !== 0 && $o !== '0') {  
878 - $o = $this->size - $e;  
879 - $e = $this->size - 1;  
880 - }  
881 - $parts[] = array($o, $e);  
882 - }  
883 - return $parts;  
884 - }  
885 -  
886 - /**  
887 - * Check if range is requested  
888 - *  
889 - * @access protected  
890 - * @return bool  
891 - */  
892 - function isRangeRequest()  
893 - {  
894 - if (!isset($_SERVER['HTTP_RANGE'])) {  
895 - return false;  
896 - }  
897 - return $this->isValidRange();  
898 - }  
899 -  
900 - /**  
901 - * Get range request  
902 - *  
903 - * @access protected  
904 - * @return array  
905 - */  
906 - function getRanges()  
907 - {  
908 - return preg_match('/^bytes=((\d*-\d*,? ?)+)$/',  
909 - @$_SERVER['HTTP_RANGE'], $matches) ? $matches[1] : array();  
910 - }  
911 -  
912 - /**  
913 - * Check if entity is cached  
914 - *  
915 - * @access protected  
916 - * @return bool  
917 - */  
918 - function isCached()  
919 - {  
920 - return (  
921 - (isset($_SERVER['HTTP_IF_MODIFIED_SINCE']) &&  
922 - $this->lastModified == strtotime(current($a = explode(  
923 - ';', $_SERVER['HTTP_IF_MODIFIED_SINCE'])))) ||  
924 - (isset($_SERVER['HTTP_IF_NONE_MATCH']) &&  
925 - $this->compareAsterisk('HTTP_IF_NONE_MATCH', $this->etag))  
926 - );  
927 - }  
928 -  
929 - /**  
930 - * Check if entity hasn't changed  
931 - *  
932 - * @access protected  
933 - * @return bool  
934 - */  
935 - function isValidRange()  
936 - {  
937 - if (isset($_SERVER['HTTP_IF_MATCH']) &&  
938 - !$this->compareAsterisk('HTTP_IF_MATCH', $this->etag)) {  
939 - return false;  
940 - }  
941 - if (isset($_SERVER['HTTP_IF_RANGE']) &&  
942 - $_SERVER['HTTP_IF_RANGE'] !== $this->etag &&  
943 - strtotime($_SERVER['HTTP_IF_RANGE']) !== $this->lastModified) {  
944 - return false;  
945 - }  
946 - if (isset($_SERVER['HTTP_IF_UNMODIFIED_SINCE'])) {  
947 - $lm = array_shift(explode(';', $_SERVER['HTTP_IF_UNMODIFIED_SINCE']));  
948 - if (strtotime($lm) !== $this->lastModified) {  
949 - return false;  
950 - }  
951 - }  
952 - if (isset($_SERVER['HTTP_UNLESS_MODIFIED_SINCE'])) {  
953 - $lm = array_shift(explode(';', $_SERVER['HTTP_UNLESS_MODIFIED_SINCE']));  
954 - if (strtotime($lm) !== $this->lastModified) {  
955 - return false;  
956 - }  
957 - }  
958 - return true;  
959 - }  
960 -  
961 - /**  
962 - * Compare against an asterisk or check for equality  
963 - *  
964 - * @access protected  
965 - * @return bool  
966 - * @param string key for the $_SERVER array  
967 - * @param string string to compare  
968 - */  
969 - function compareAsterisk($svar, $compare)  
970 - {  
971 - foreach (array_map('trim', explode(',', $_SERVER[$svar])) as $request) {  
972 - if ($request === '*' || $request === $compare) {  
973 - return true;  
974 - }  
975 - }  
976 - return false;  
977 - }  
978 -  
979 - /**  
980 - * Send HTTP headers  
981 - *  
982 - * @access protected  
983 - * @return void  
984 - */  
985 - function sendHeaders()  
986 - {  
987 - foreach ($this->headers as $header => $value) {  
988 - $this->HTTP->setHeader($header, $value);  
989 - }  
990 - $this->HTTP->sendHeaders();  
991 - /* NSAPI won't output anything if we did this */  
992 - if (strncasecmp(PHP_SAPI, 'nsapi', 5)) {  
993 - ob_flush();  
994 - flush();  
995 - }  
996 - }  
997 -  
998 - /**  
999 - * Flush  
1000 - *  
1001 - * @access protected  
1002 - * @return void  
1003 - * @param string $data  
1004 - */  
1005 - function flush($data = '')  
1006 - {  
1007 - if ($dlen = strlen($data)) {  
1008 - $this->sentBytes += $dlen;  
1009 - echo $data;  
1010 - }  
1011 - ob_flush();  
1012 - flush();  
1013 - }  
1014 -  
1015 - /**  
1016 - * Sleep  
1017 - *  
1018 - * @access protected  
1019 - * @return void  
1020 - */  
1021 - function sleep()  
1022 - {  
1023 - if (OS_WINDOWS) {  
1024 - com_message_pump($this->throttleDelay);  
1025 - } else {  
1026 - usleep($this->throttleDelay * 1000);  
1027 - }  
1028 - }  
1029 - // }}}  
1030 -}  
1031 -?>  
thirdparty/pear/WebDAV/Download/Archive.php deleted
1 -<?php  
2 -/* vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4: */  
3 -  
4 -/**  
5 - * HTTP::Download::Archive  
6 - *  
7 - * PHP versions 4 and 5  
8 - *  
9 - * @category HTTP  
10 - * @package HTTP_Download  
11 - * @author Michael Wallner <mike@php.net>  
12 - * @copyright 2003-2005 Michael Wallner  
13 - * @license BSD, revisewd  
14 - * @version CVS: $Id: Archive.php 6819 2007-06-20 13:09:21Z kevin_fourie $  
15 - * @link http://pear.php.net/package/HTTP_Download  
16 - */  
17 -  
18 -/**  
19 - * Requires HTTP_Download  
20 - */  
21 -require_once 'HTTP/Download.php';  
22 -  
23 -/**  
24 - * Requires System  
25 - */  
26 -require_once 'System.php';  
27 -  
28 -/**  
29 - * HTTP_Download_Archive  
30 - *  
31 - * Helper class for sending Archives.  
32 - *  
33 - * @access public  
34 - * @version $Revision: 6819 $  
35 - */  
36 -class HTTP_Download_Archive  
37 -{  
38 - /**  
39 - * Send a bunch of files or directories as an archive  
40 - *  
41 - * Example:  
42 - * <code>  
43 - * require_once 'HTTP/Download/Archive.php';  
44 - * HTTP_Download_Archive::send(  
45 - * 'myArchive.tgz',  
46 - * '/var/ftp/pub/mike',  
47 - * HTTP_DOWNLOAD_BZ2,  
48 - * '',  
49 - * '/var/ftp/pub'  
50 - * );  
51 - * </code>  
52 - *  
53 - * @see Archive_Tar::createModify()  
54 - * @static  
55 - * @access public  
56 - * @return mixed Returns true on success or PEAR_Error on failure.  
57 - * @param string $name name the sent archive should have  
58 - * @param mixed $files files/directories  
59 - * @param string $type archive type  
60 - * @param string $add_path path that should be prepended to the files  
61 - * @param string $strip_path path that should be stripped from the files  
62 - */  
63 - function send($name, $files, $type = HTTP_DOWNLOAD_TGZ, $add_path = '', $strip_path = '')  
64 - {  
65 - $tmp = System::mktemp();  
66 -  
67 - switch ($type = strToUpper($type))  
68 - {  
69 - case HTTP_DOWNLOAD_TAR:  
70 - include_once 'Archive/Tar.php';  
71 - $arc = &new Archive_Tar($tmp);  
72 - $content_type = 'x-tar';  
73 - break;  
74 -  
75 - case HTTP_DOWNLOAD_TGZ:  
76 - include_once 'Archive/Tar.php';  
77 - $arc = &new Archive_Tar($tmp, 'gz');  
78 - $content_type = 'x-gzip';  
79 - break;  
80 -  
81 - case HTTP_DOWNLOAD_BZ2:  
82 - include_once 'Archive/Tar.php';  
83 - $arc = &new Archive_Tar($tmp, 'bz2');  
84 - $content_type = 'x-bzip2';  
85 - break;  
86 -  
87 - case HTTP_DOWNLOAD_ZIP:  
88 - include_once 'Archive/Zip.php';  
89 - $arc = &new Archive_Zip($tmp);  
90 - $content_type = 'x-zip';  
91 - break;  
92 -  
93 - default:  
94 - return PEAR::raiseError(  
95 - 'Archive type not supported: ' . $type,  
96 - HTTP_DOWNLOAD_E_INVALID_ARCHIVE_TYPE  
97 - );  
98 - }  
99 -  
100 - if ($type == HTTP_DOWNLOAD_ZIP) {  
101 - $options = array( 'add_path' => $add_path,  
102 - 'remove_path' => $strip_path);  
103 - if (!$arc->create($files, $options)) {  
104 - return PEAR::raiseError('Archive creation failed.');  
105 - }  
106 - } else {  
107 - if (!$e = $arc->createModify($files, $add_path, $strip_path)) {  
108 - return PEAR::raiseError('Archive creation failed.');  
109 - }  
110 - if (PEAR::isError($e)) {  
111 - return $e;  
112 - }  
113 - }  
114 - unset($arc);  
115 -  
116 - $dl = &new HTTP_Download(array('file' => $tmp));  
117 - $dl->setContentType('application/' . $content_type);  
118 - $dl->setContentDisposition(HTTP_DOWNLOAD_ATTACHMENT, $name);  
119 - return $dl->send();  
120 - }  
121 -}  
122 -?>  
thirdparty/pear/WebDAV/Download/PgLOB.php deleted
1 -<?php  
2 -/* vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4: */  
3 -  
4 -/**  
5 - * HTTP::Download::PgLOB  
6 - *  
7 - * PHP versions 4 and 5  
8 - *  
9 - * @category HTTP  
10 - * @package HTTP_Download  
11 - * @author Michael Wallner <mike@php.net>  
12 - * @copyright 2003-2005 Michael Wallner  
13 - * @license BSD, revised  
14 - * @version CVS: $Id: PgLOB.php 6819 2007-06-20 13:09:21Z kevin_fourie $  
15 - * @link http://pear.php.net/package/HTTP_Download  
16 - */  
17 -  
18 -$GLOBALS['_HTTP_Download_PgLOB_Connection'] = null;  
19 -stream_register_wrapper('pglob', 'HTTP_Download_PgLOB');  
20 -  
21 -/**  
22 - * PgSQL large object stream interface for HTTP_Download  
23 - *  
24 - * Usage:  
25 - * <code>  
26 - * require_once 'HTTP/Download.php';  
27 - * require_once 'HTTP/Download/PgLOB.php';  
28 - * $db = &DB::connect('pgsql://user:pass@host/db');  
29 - * // or $db = pg_connect(...);  
30 - * $lo = HTTP_Download_PgLOB::open($db, 12345);  
31 - * $dl = &new HTTP_Download;  
32 - * $dl->setResource($lo);  
33 - * $dl->send()  
34 - * </code>  
35 - *  
36 - * @access public  
37 - * @version $Revision: 6819 $  
38 - */  
39 -class HTTP_Download_PgLOB  
40 -{  
41 - /**  
42 - * Set Connection  
43 - *  
44 - * @static  
45 - * @access public  
46 - * @return bool  
47 - * @param mixed $conn  
48 - */  
49 - function setConnection($conn)  
50 - {  
51 - if (is_a($conn, 'DB_Common')) {  
52 - $conn = $conn->dbh;  
53 - } elseif ( is_a($conn, 'MDB_Common') ||  
54 - is_a($conn, 'MDB2_Driver_Common')) {  
55 - $conn = $conn->connection;  
56 - }  
57 - if ($isResource = is_resource($conn)) {  
58 - $GLOBALS['_HTTP_Download_PgLOB_Connection'] = $conn;  
59 - }  
60 - return $isResource;  
61 - }  
62 -  
63 - /**  
64 - * Get Connection  
65 - *  
66 - * @static  
67 - * @access public  
68 - * @return resource  
69 - */  
70 - function getConnection()  
71 - {  
72 - if (is_resource($GLOBALS['_HTTP_Download_PgLOB_Connection'])) {  
73 - return $GLOBALS['_HTTP_Download_PgLOB_Connection'];  
74 - }  
75 - return null;  
76 - }  
77 -  
78 - /**  
79 - * Open  
80 - *  
81 - * @static  
82 - * @access public  
83 - * @return resource  
84 - * @param mixed $conn  
85 - * @param int $loid  
86 - * @param string $mode  
87 - */  
88 - function open($conn, $loid, $mode = 'rb')  
89 - {  
90 - HTTP_Download_PgLOB::setConnection($conn);  
91 - return fopen('pglob:///'. $loid, $mode);  
92 - }  
93 -  
94 - /**#@+  
95 - * Stream Interface Implementation  
96 - * @internal  
97 - */  
98 - var $ID = 0;  
99 - var $size = 0;  
100 - var $conn = null;  
101 - var $handle = null;  
102 -  
103 - function stream_open($path, $mode)  
104 - {  
105 - if (!$this->conn = HTTP_Download_PgLOB::getConnection()) {  
106 - return false;  
107 - }  
108 - if (!preg_match('/(\d+)/', $path, $matches)) {  
109 - return false;  
110 - }  
111 - $this->ID = $matches[1];  
112 -  
113 - if (!pg_query($this->conn, 'BEGIN')) {  
114 - return false;  
115 - }  
116 -  
117 - $this->handle = pg_lo_open($this->conn, $this->ID, $mode);  
118 - if (!is_resource($this->handle)) {  
119 - return false;  
120 - }  
121 -  
122 - // fetch size of lob  
123 - pg_lo_seek($this->handle, 0, PGSQL_SEEK_END);  
124 - $this->size = (int) pg_lo_tell($this->handle);  
125 - pg_lo_seek($this->handle, 0, PGSQL_SEEK_SET);  
126 -  
127 - return true;  
128 - }  
129 -  
130 - function stream_read($length)  
131 - {  
132 - return pg_lo_read($this->handle, $length);  
133 - }  
134 -  
135 - function stream_seek($offset, $whence = SEEK_SET)  
136 - {  
137 - return pg_lo_seek($this->handle, $offset, $whence);  
138 - }  
139 -  
140 - function stream_tell()  
141 - {  
142 - return pg_lo_tell($this->handle);  
143 - }  
144 -  
145 - function stream_eof()  
146 - {  
147 - return pg_lo_tell($this->handle) >= $this->size;  
148 - }  
149 -  
150 - function stream_flush()  
151 - {  
152 - return true;  
153 - }  
154 -  
155 - function stream_stat()  
156 - {  
157 - return array('size' => $this->size, 'ino' => $this->ID);  
158 - }  
159 -  
160 - function stream_write($data)  
161 - {  
162 - return pg_lo_write($this->handle, $data);  
163 - }  
164 -  
165 - function stream_close()  
166 - {  
167 - if (pg_lo_close($this->handle)) {  
168 - return pg_query($this->conn, 'COMMIT');  
169 - } else {  
170 - pg_query($this->conn ,'ROLLBACK');  
171 - return false;  
172 - }  
173 - }  
174 - /**#@-*/  
175 -}  
176 -  
177 -?>  
thirdparty/pear/WebDAV/Header.php deleted
1 -<?php  
2 -/* vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4: */  
3 -  
4 -/**  
5 - * HTTP::Header  
6 - *  
7 - * PHP versions 4 and 5  
8 - *  
9 - * @category HTTP  
10 - * @package HTTP_Header  
11 - * @author Wolfram Kriesing <wk@visionp.de>  
12 - * @author Davey Shafik <davey@php.net>  
13 - * @author Michael Wallner <mike@php.net>  
14 - * @copyright 2003-2005 The Authors  
15 - * @license BSD, revised  
16 - * @version CVS: $Id: Header.php 6819 2007-06-20 13:09:21Z kevin_fourie $  
17 - * @link http://pear.php.net/package/HTTP_Header  
18 - */  
19 -  
20 -/**  
21 - * Requires HTTP  
22 - */  
23 -require_once 'HTTP.php';  
24 -  
25 -/**#@+  
26 - * Information Codes  
27 - */  
28 -define('HTTP_HEADER_STATUS_100', '100 Continue');  
29 -define('HTTP_HEADER_STATUS_101', '101 Switching Protocols');  
30 -define('HTTP_HEADER_STATUS_102', '102 Processing');  
31 -define('HTTP_HEADER_STATUS_INFORMATIONAL',1);  
32 -/**#@-*/  
33 -  
34 -/**#+  
35 - * Success Codes  
36 - */  
37 -define('HTTP_HEADER_STATUS_200', '200 OK');  
38 -define('HTTP_HEADER_STATUS_201', '201 Created');  
39 -define('HTTP_HEADER_STATUS_202', '202 Accepted');  
40 -define('HTTP_HEADER_STATUS_203', '203 Non-Authoritative Information');  
41 -define('HTTP_HEADER_STATUS_204', '204 No Content');  
42 -define('HTTP_HEADER_STATUS_205', '205 Reset Content');  
43 -define('HTTP_HEADER_STATUS_206', '206 Partial Content');  
44 -define('HTTP_HEADER_STATUS_207', '207 Multi-Status');  
45 -define('HTTP_HEADER_STATUS_SUCCESSFUL',2);  
46 -/**#@-*/  
47 -  
48 -/**#@+  
49 - * Redirection Codes  
50 - */  
51 -define('HTTP_HEADER_STATUS_300', '300 Multiple Choices');  
52 -define('HTTP_HEADER_STATUS_301', '301 Moved Permanently');  
53 -define('HTTP_HEADER_STATUS_302', '302 Found');  
54 -define('HTTP_HEADER_STATUS_303', '303 See Other');  
55 -define('HTTP_HEADER_STATUS_304', '304 Not Modified');  
56 -define('HTTP_HEADER_STATUS_305', '305 Use Proxy');  
57 -define('HTTP_HEADER_STATUS_306', '306 (Unused)');  
58 -define('HTTP_HEADER_STATUS_307', '307 Temporary Redirect');  
59 -define('HTTP_HEADER_STATUS_REDIRECT',3);  
60 -/**#@-*/  
61 -  
62 -/**#@+  
63 - * Error Codes  
64 - */  
65 -define('HTTP_HEADER_STATUS_400', '400 Bad Request');  
66 -define('HTTP_HEADER_STATUS_401', '401 Unauthorized');  
67 -define('HTTP_HEADER_STATUS_402', '402 Payment Granted');  
68 -define('HTTP_HEADER_STATUS_403', '403 Forbidden');  
69 -define('HTTP_HEADER_STATUS_404', '404 File Not Found');  
70 -define('HTTP_HEADER_STATUS_405', '405 Method Not Allowed');  
71 -define('HTTP_HEADER_STATUS_406', '406 Not Acceptable');  
72 -define('HTTP_HEADER_STATUS_407', '407 Proxy Authentication Required');  
73 -define('HTTP_HEADER_STATUS_408', '408 Request Time-out');  
74 -define('HTTP_HEADER_STATUS_409', '409 Conflict');  
75 -define('HTTP_HEADER_STATUS_410', '410 Gone');  
76 -define('HTTP_HEADER_STATUS_411', '411 Length Required');  
77 -define('HTTP_HEADER_STATUS_412', '412 Precondition Failed');  
78 -define('HTTP_HEADER_STATUS_413', '413 Request Entity Too Large');  
79 -define('HTTP_HEADER_STATUS_414', '414 Request-URI Too Large');  
80 -define('HTTP_HEADER_STATUS_415', '415 Unsupported Media Type');  
81 -define('HTTP_HEADER_STATUS_416', '416 Requested range not satisfiable');  
82 -define('HTTP_HEADER_STATUS_417', '417 Expectation Failed');  
83 -define('HTTP_HEADER_STATUS_422', '422 Unprocessable Entity');  
84 -define('HTTP_HEADER_STATUS_423', '423 Locked');  
85 -define('HTTP_HEADER_STATUS_424', '424 Failed Dependency');  
86 -define('HTTP_HEADER_STATUS_CLIENT_ERROR',4);  
87 -/**#@-*/  
88 -  
89 -/**#@+  
90 - * Server Errors  
91 - */  
92 -define('HTTP_HEADER_STATUS_500', '500 Internal Server Error');  
93 -define('HTTP_HEADER_STATUS_501', '501 Not Implemented');  
94 -define('HTTP_HEADER_STATUS_502', '502 Bad Gateway');  
95 -define('HTTP_HEADER_STATUS_503', '503 Service Unavailable');  
96 -define('HTTP_HEADER_STATUS_504', '504 Gateway Time-out');  
97 -define('HTTP_HEADER_STATUS_505', '505 HTTP Version not supported');  
98 -define('HTTP_HEADER_STATUS_507', '507 Insufficient Storage');  
99 -define('HTTP_HEADER_STATUS_SERVER_ERROR',5);  
100 -/**#@-*/  
101 -  
102 -/**  
103 - * HTTP_Header  
104 - *  
105 - * @package HTTP_Header  
106 - * @category HTTP  
107 - * @access public  
108 - * @version $Revision: 6819 $  
109 - */  
110 -class HTTP_Header extends HTTP  
111 -{  
112 - /**  
113 - * Default Headers  
114 - *  
115 - * The values that are set as default, are the same as PHP sends by default.  
116 - *  
117 - * @var array  
118 - * @access private  
119 - */  
120 - var $_headers = array(  
121 - 'content-type' => 'text/html',  
122 - 'pragma' => 'no-cache',  
123 - 'cache-control' => 'no-store, no-cache, must-revalidate, post-check=0, pre-check=0'  
124 - );  
125 -  
126 - /**  
127 - * HTTP version  
128 - *  
129 - * @var string  
130 - * @access private  
131 - */  
132 - var $_httpVersion = '1.0';  
133 -  
134 - /**  
135 - * Constructor  
136 - *  
137 - * Sets HTTP version.  
138 - *  
139 - * @access public  
140 - * @return object HTTP_Header  
141 - */  
142 - function HTTP_Header()  
143 - {  
144 - if (isset($_SERVER['SERVER_PROTOCOL'])) {  
145 - $this->setHttpVersion(substr($_SERVER['SERVER_PROTOCOL'], -3));  
146 - }  
147 - }  
148 -  
149 - /**  
150 - * Set HTTP version  
151 - *  
152 - * @access public  
153 - * @return bool Returns true on success or false if version doesn't  
154 - * match 1.0 or 1.1 (note: 1 will result in 1.0)  
155 - * @param mixed $version HTTP version, either 1.0 or 1.1  
156 - */  
157 - function setHttpVersion($version)  
158 - {  
159 - $version = round((float) $version, 1);  
160 - if ($version < 1.0 || $version > 1.1) {  
161 - return false;  
162 - }  
163 - $this->_httpVersion = sprintf('%0.1f', $version);  
164 - return true;  
165 - }  
166 -  
167 - /**  
168 - * Get HTTP version  
169 - *  
170 - * @access public  
171 - * @return string  
172 - */  
173 - function getHttpVersion()  
174 - {  
175 - return $this->_httpVersion;  
176 - }  
177 -  
178 - /**  
179 - * Set Header  
180 - *  
181 - * The default value for the Last-Modified header will be current  
182 - * date and atime if $value is omitted.  
183 - *  
184 - * @access public  
185 - * @return bool Returns true on success or false if $key was empty or  
186 - * $value was not of an scalar type.  
187 - * @param string $key The name of the header.  
188 - * @param string $value The value of the header. (NULL to unset header)  
189 - */  
190 - function setHeader($key, $value = null)  
191 - {  
192 - if (empty($key) || (isset($value) && !is_scalar($value))) {  
193 - return false;  
194 - }  
195 -  
196 - $key = strToLower($key);  
197 - if ($key == 'last-modified') {  
198 - if (!isset($value)) {  
199 - $value = HTTP::Date(time());  
200 - } elseif (is_numeric($value)) {  
201 - $value = HTTP::Date($value);  
202 - }  
203 - }  
204 -  
205 - if (isset($value)) {  
206 - $this->_headers[$key] = $value;  
207 - } else {  
208 - unset($this->_headers[$key]);  
209 - }  
210 -  
211 - return true;  
212 - }  
213 -  
214 - /**  
215 - * Get Header  
216 - *  
217 - * If $key is omitted, all stored headers will be returned.  
218 - *  
219 - * @access public  
220 - * @return mixed Returns string value of the requested header,  
221 - * array values of all headers or false if header $key  
222 - * is not set.  
223 - * @param string $key The name of the header to fetch.  
224 - */  
225 - function getHeader($key = null)  
226 - {  
227 - if (!isset($key)) {  
228 - return $this->_headers;  
229 - }  
230 -  
231 - $key = strToLower($key);  
232 -  
233 - if (!isset($this->_headers[$key])) {  
234 - return false;  
235 - }  
236 -  
237 - return $this->_headers[$key];  
238 - }  
239 -  
240 - /**  
241 - * Send Headers  
242 - *  
243 - * Send out the header that you set via setHeader().  
244 - *  
245 - * @access public  
246 - * @return bool Returns true on success or false if headers are already  
247 - * sent.  
248 - * @param array $keys Headers to (not) send, see $include.  
249 - * @param array $include If true only $keys matching headers will be  
250 - * sent, if false only header not matching $keys will be  
251 - * sent.  
252 - */  
253 - function sendHeaders($keys = array(), $include = true)  
254 - {  
255 - if (headers_sent()) {  
256 - return false;  
257 - }  
258 -  
259 - if (count($keys)) {  
260 - array_change_key_case($keys, CASE_LOWER);  
261 - foreach ($this->_headers as $key => $value) {  
262 - if ($include ? in_array($key, $keys) : !in_array($key, $keys)) {  
263 - header($key .': '. $value);  
264 - }  
265 - }  
266 - } else {  
267 - foreach ($this->_headers as $header => $value) {  
268 - header($header .': '. $value);  
269 - }  
270 - }  
271 - return true;  
272 - }  
273 -  
274 - /**  
275 - * Send Satus Code  
276 - *  
277 - * Send out the given HTTP-Status code. Use this for example when you  
278 - * want to tell the client this page is cached, then you would call  
279 - * sendStatusCode(304).  
280 - *  
281 - * @see HTTP_Header_Cache::exitIfCached()  
282 - *  
283 - * @access public  
284 - * @return bool Returns true on success or false if headers are already  
285 - * sent.  
286 - * @param int $code The status code to send, i.e. 404, 304, 200, etc.  
287 - */  
288 - function sendStatusCode($code)  
289 - {  
290 - if (headers_sent()) {  
291 - return false;  
292 - }  
293 -  
294 - if ($code == (int) $code && defined('HTTP_HEADER_STATUS_'. $code)) {  
295 - $code = constant('HTTP_HEADER_STATUS_'. $code);  
296 - }  
297 -  
298 - if (strncasecmp(PHP_SAPI, 'cgi', 3)) {  
299 - header('HTTP/'. $this->_httpVersion .' '. $code);  
300 - } else {  
301 - header('Status: '. $code);  
302 - }  
303 - return true;  
304 - }  
305 -  
306 - /**  
307 - * Date to Timestamp  
308 - *  
309 - * Converts dates like  
310 - * Mon, 31 Mar 2003 15:26:34 GMT  
311 - * Tue, 15 Nov 1994 12:45:26 GMT  
312 - * into a timestamp, strtotime() didn't do it in older versions.  
313 - *  
314 - * @deprecated Use PHPs strtotime() instead.  
315 - * @access public  
316 - * @return mixed Returns int unix timestamp or false if the date doesn't  
317 - * seem to be a valid GMT date.  
318 - * @param string $date The GMT date.  
319 - */  
320 - function dateToTimestamp($date)  
321 - {  
322 - static $months = array(  
323 - null => 0, 'Jan' => 1, 'Feb' => 2, 'Mar' => 3, 'Apr' => 4,  
324 - 'May' => 5, 'Jun' => 6, 'Jul' => 7, 'Aug' => 8, 'Sep' => 9,  
325 - 'Oct' => 10, 'Nov' => 11, 'Dec' => 12  
326 - );  
327 -  
328 - if (-1 < $timestamp = strToTime($date)) {  
329 - return $timestamp;  
330 - }  
331 -  
332 - if (!preg_match('~[^,]*,\s(\d+)\s(\w+)\s(\d+)\s(\d+):(\d+):(\d+).*~',  
333 - $date, $m)) {  
334 - return false;  
335 - }  
336 -  
337 - // [0] => Mon, 31 Mar 2003 15:42:55 GMT  
338 - // [1] => 31 [2] => Mar [3] => 2003 [4] => 15 [5] => 42 [6] => 55  
339 - return mktime($m[4], $m[5], $m[6], $months[$m[2]], $m[1], $m[3]);  
340 - }  
341 -  
342 - /**  
343 - * Redirect  
344 - *  
345 - * This function redirects the client. This is done by issuing a Location  
346 - * header and exiting. Additionally to HTTP::redirect() you can also add  
347 - * parameters to the url.  
348 - *  
349 - * If you dont need parameters to be added, simply use HTTP::redirect()  
350 - * otherwise use HTTP_Header::redirect().  
351 - *  
352 - * @see HTTP::redirect()  
353 - * @author Wolfram Kriesing <wk@visionp.de>  
354 - * @access public  
355 - * @return void  
356 - * @param string $url The URL to redirect to, if none is given it  
357 - * redirects to the current page.  
358 - * @param array $param Array of query string parameters to add; usually  
359 - * a set of key => value pairs; if an array entry consists  
360 - * only of an value it is used as key and the respective  
361 - * value is fetched from $GLOBALS[$value]  
362 - * @param bool $session Whether the session name/id should be added  
363 - */  
364 - function redirect($url = null, $param = array(), $session = false)  
365 - {  
366 - if (!isset($url)) {  
367 - $url = $_SERVER['PHP_SELF'];  
368 - }  
369 -  
370 - $qs = array();  
371 -  
372 - if ($session) {  
373 - $qs[] = session_name() .'='. session_id();  
374 - }  
375 -  
376 - if (is_array($param) && count($param)) {  
377 - if (count($param)) {  
378 - foreach ($param as $key => $val) {  
379 - if (is_string($key)) {  
380 - $qs[] = urlencode($key) .'='. urlencode($val);  
381 - } else {  
382 - $qs[] = urlencode($val) .'='. urlencode(@$GLOBALS[$val]);  
383 - }  
384 - }  
385 - }  
386 - }  
387 -  
388 - if ($qstr = implode('&', $qs)) {  
389 - $purl = parse_url($url);  
390 - $url .= (isset($purl['query']) ? '&' : '?') . $qstr;  
391 - }  
392 -  
393 - parent::redirect($url);  
394 - }  
395 -  
396 - /**#@+  
397 - * @author Davey Shafik <davey@php.net>  
398 - * @param int $http_code HTTP Code to check  
399 - * @access public  
400 - */  
401 -  
402 - /**  
403 - * Return HTTP Status Code Type  
404 - *  
405 - * @return int|false  
406 - */  
407 - function getStatusType($http_code)  
408 - {  
409 - if(is_int($http_code) && defined('HTTP_HEADER_STATUS_' .$http_code) || defined($http_code)) {  
410 - $type = substr($http_code,0,1);  
411 - switch ($type) {  
412 - case HTTP_HEADER_STATUS_INFORMATIONAL:  
413 - case HTTP_HEADER_STATUS_SUCCESSFUL:  
414 - case HTTP_HEADER_STATUS_REDIRECT:  
415 - case HTTP_HEADER_STATUS_CLIENT_ERROR:  
416 - case HTTP_HEADER_STATUS_SERVER_ERROR:  
417 - return $type;  
418 - break;  
419 - default:  
420 - return false;  
421 - break;  
422 - }  
423 - } else {  
424 - return false;  
425 - }  
426 - }  
427 -  
428 - /**  
429 - * Return Status Code Message  
430 - *  
431 - * @return string|false  
432 - */  
433 - function getStatusText($http_code)  
434 - {  
435 - if ($this->getStatusType($http_code)) {  
436 - if (is_int($http_code) && defined('HTTP_HEADER_STATUS_' .$http_code)) {  
437 - return substr(constant('HTTP_HEADER_STATUS_' .$http_code),4);  
438 - } else {  
439 - return substr($http_code,4);  
440 - }  
441 - } else {  
442 - return false;  
443 - }  
444 - }  
445 -  
446 - /**  
447 - * Checks if HTTP Status code is Information (1xx)  
448 - *  
449 - * @return boolean  
450 - */  
451 - function isInformational($http_code)  
452 - {  
453 - if ($status_type = $this->getStatusType($http_code)) {  
454 - return $status_type{0} == HTTP_HEADER_STATUS_INFORMATIONAL;  
455 - } else {  
456 - return false;  
457 - }  
458 - }  
459 -  
460 - /**  
461 - * Checks if HTTP Status code is Successful (2xx)  
462 - *  
463 - * @return boolean  
464 - */  
465 - function isSuccessful($http_code)  
466 - {  
467 - if ($status_type = $this->getStatusType($http_code)) {  
468 - return $status_type{0} == HTTP_HEADER_STATUS_SUCCESSFUL;  
469 - } else {  
470 - return false;  
471 - }  
472 - }  
473 -  
474 - /**  
475 - * Checks if HTTP Status code is a Redirect (3xx)  
476 - *  
477 - * @return boolean  
478 - */  
479 - function isRedirect($http_code)  
480 - {  
481 - if ($status_type = $this->getStatusType($http_code)) {  
482 - return $status_type{0} == HTTP_HEADER_STATUS_REDIRECT;  
483 - } else {  
484 - return false;  
485 - }  
486 - }  
487 -  
488 - /**  
489 - * Checks if HTTP Status code is a Client Error (4xx)  
490 - *  
491 - * @return boolean  
492 - */  
493 - function isClientError($http_code)  
494 - {  
495 - if ($status_type = $this->getStatusType($http_code)) {  
496 - return $status_type{0} == HTTP_HEADER_STATUS_CLIENT_ERROR;  
497 - } else {  
498 - return false;  
499 - }  
500 - }  
501 -  
502 - /**  
503 - * Checks if HTTP Status code is Server Error (5xx)  
504 - *  
505 - * @return boolean  
506 - */  
507 - function isServerError($http_code)  
508 - {  
509 - if ($status_type = $this->getStatusType($http_code)) {  
510 - return $status_type{0} == HTTP_HEADER_STATUS_SERVER_ERROR;  
511 - } else {  
512 - return false;  
513 - }  
514 - }  
515 -  
516 - /**  
517 - * Checks if HTTP Status code is Server OR Client Error (4xx or 5xx)  
518 - *  
519 - * @return boolean  
520 - */  
521 - function isError($http_code)  
522 - {  
523 - if ($status_type = $this->getStatusType($http_code)) {  
524 - return (($status_type == HTTP_HEADER_STATUS_CLIENT_ERROR) || ($status_type == HTTP_HEADER_STATUS_SERVER_ERROR)) ? true : false;  
525 - } else {  
526 - return false;  
527 - }  
528 - }  
529 - /**#@-*/  
530 -}  
531 -?>  
thirdparty/pear/WebDAV/Header/Cache.php deleted
1 -<?php  
2 -/* vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4: */  
3 -  
4 -/**  
5 - * HTTP::Header::Cache  
6 - *  
7 - * PHP versions 4 and 5  
8 - *  
9 - * @category HTTP  
10 - * @package HTTP_Header  
11 - * @author Wolfram Kriesing <wk@visionp.de>  
12 - * @author Michael Wallner <mike@php.net>  
13 - * @copyright 2003-2005 The Authors  
14 - * @license BSD, revised  
15 - * @version CVS: $Id: Cache.php 6819 2007-06-20 13:09:21Z kevin_fourie $  
16 - * @link http://pear.php.net/package/HTTP_Header  
17 - */  
18 -  
19 -/**  
20 - * Requires HTTP_Header  
21 - */  
22 -require_once 'HTTP/Header.php';  
23 -  
24 -/**  
25 - * HTTP_Header_Cache  
26 - *  
27 - * This package provides methods to easier handle caching of HTTP pages. That  
28 - * means that the pages can be cached at the client (user agent or browser) and  
29 - * your application only needs to send "hey client you already have the pages".  
30 - *  
31 - * Which is done by sending the HTTP-Status "304 Not Modified", so that your  
32 - * application load and the network traffic can be reduced, since you only need  
33 - * to send the complete page once. This is really an advantage e.g. for  
34 - * generated style sheets, or simply pages that do only change rarely.  
35 - *  
36 - * Usage:  
37 - * <code>  
38 - * require_once 'HTTP/Header/Cache.php';  
39 - * $httpCache = new HTTP_Header_Cache(4, 'weeks');  
40 - * $httpCache->sendHeaders();  
41 - * // your code goes here  
42 - * </code>  
43 - *  
44 - * @package HTTP_Header  
45 - * @category HTTP  
46 - * @access public  
47 - * @version $Revision: 6819 $  
48 - */  
49 -class HTTP_Header_Cache extends HTTP_Header  
50 -{  
51 - /**  
52 - * Constructor  
53 - *  
54 - * Set the amount of time to cache.  
55 - *  
56 - * @access public  
57 - * @return object HTTP_Header_Cache  
58 - * @param int $expires  
59 - * @param string $unit  
60 - */  
61 - function HTTP_Header_Cache($expires = 0, $unit = 'seconds')  
62 - {  
63 - parent::HTTP_Header();  
64 - $this->setHeader('Pragma', 'cache');  
65 - $this->setHeader('Last-Modified', $this->getCacheStart());  
66 - $this->setHeader('Cache-Control', 'private, must-revalidate, max-age=0');  
67 -  
68 - if ($expires) {  
69 - if (!$this->isOlderThan($expires, $unit)) {  
70 - $this->exitCached();  
71 - }  
72 - $this->setHeader('Last-Modified', time());  
73 - }  
74 - }  
75 -  
76 - /**  
77 - * Get Cache Start  
78 - *  
79 - * Returns the unix timestamp of the If-Modified-Since HTTP header or the  
80 - * current time if the header was not sent by the client.  
81 - *  
82 - * @access public  
83 - * @return int unix timestamp  
84 - */  
85 - function getCacheStart()  
86 - {  
87 - if (isset($_SERVER['HTTP_IF_MODIFIED_SINCE']) && !$this->isPost()) {  
88 - return strtotime(current($array = explode(';',  
89 - $_SERVER['HTTP_IF_MODIFIED_SINCE'])));  
90 - }  
91 - return time();  
92 - }  
93 -  
94 - /**  
95 - * Is Older Than  
96 - *  
97 - * You can call it like this:  
98 - * <code>  
99 - * $httpCache->isOlderThan(1, 'day');  
100 - * $httpCache->isOlderThan(47, 'days');  
101 - *  
102 - * $httpCache->isOlderThan(1, 'week');  
103 - * $httpCache->isOlderThan(3, 'weeks');  
104 - *  
105 - * $httpCache->isOlderThan(1, 'hour');  
106 - * $httpCache->isOlderThan(5, 'hours');  
107 - *  
108 - * $httpCache->isOlderThan(1, 'minute');  
109 - * $httpCache->isOlderThan(15, 'minutes');  
110 - *  
111 - * $httpCache->isOlderThan(1, 'second');  
112 - * $httpCache->isOlderThan(15);  
113 - * </code>  
114 - *  
115 - * If you specify something greater than "weeks" as time untit, it just  
116 - * works approximatly, because a month is taken to consist of 4.3 weeks.  
117 - *  
118 - * @access public  
119 - * @return bool Returns true if requested page is older than specified.  
120 - * @param int $time The amount of time.  
121 - * @param string $unit The unit of the time amount - (year[s], month[s],  
122 - * week[s], day[s], hour[s], minute[s], second[s]).  
123 - */  
124 - function isOlderThan($time = 0, $unit = 'seconds')  
125 - {  
126 - if (!isset($_SERVER['HTTP_IF_MODIFIED_SINCE']) || $this->isPost()) {  
127 - return true;  
128 - }  
129 - if (!$time) {  
130 - return false;  
131 - }  
132 -  
133 - switch (strtolower($unit))  
134 - {  
135 - case 'year':  
136 - case 'years':  
137 - $time *= 12;  
138 - case 'month':  
139 - case 'months':  
140 - $time *= 4.3;  
141 - case 'week':  
142 - case 'weeks':  
143 - $time *= 7;  
144 - case 'day':  
145 - case 'days':  
146 - $time *= 24;  
147 - case 'hour':  
148 - case 'hours':  
149 - $time *= 60;  
150 - case 'minute':  
151 - case 'minutes':  
152 - $time *= 60;  
153 - }  
154 -  
155 - return (time() - $this->getCacheStart()) > $time;  
156 - }  
157 -  
158 - /**  
159 - * Is Cached  
160 - *  
161 - * Check whether we can consider to be cached on the client side.  
162 - *  
163 - * @access public  
164 - * @return bool Whether the page/resource is considered to be cached.  
165 - * @param int $lastModified Unix timestamp of last modification.  
166 - */  
167 - function isCached($lastModified = 0)  
168 - {  
169 - if ($this->isPost()) {  
170 - return false;  
171 - }  
172 - if (isset($_SERVER['HTTP_IF_MODIFIED_SINCE']) && !$lastModified) {  
173 - return true;  
174 - }  
175 - if (!$seconds = time() - $lastModified) {  
176 - return false;  
177 - }  
178 - return !$this->isOlderThan($seconds);  
179 - }  
180 -  
181 - /**  
182 - * Is Post  
183 - *  
184 - * Check if request method is "POST".  
185 - *  
186 - * @access public  
187 - * @return bool  
188 - */  
189 - function isPost()  
190 - {  
191 - return isset($_SERVER['REQUEST_METHOD']) and  
192 - 'POST' == $_SERVER['REQUEST_METHOD'];  
193 - }  
194 -  
195 - /**  
196 - * Exit If Cached  
197 - *  
198 - * Exit with "HTTP 304 Not Modified" if we consider to be cached.  
199 - *  
200 - * @access public  
201 - * @return void  
202 - * @param int $lastModified Unix timestamp of last modification.  
203 - */  
204 - function exitIfCached($lastModified = 0)  
205 - {  
206 - if ($this->isCached($lastModified)) {  
207 - $this->exitCached();  
208 - }  
209 - }  
210 -  
211 - /**  
212 - * Exit Cached  
213 - *  
214 - * Exit with "HTTP 304 Not Modified".  
215 - *  
216 - * @access public  
217 - * @return void  
218 - */  
219 - function exitCached()  
220 - {  
221 - $this->sendHeaders();  
222 - $this->sendStatusCode(304);  
223 - exit;  
224 - }  
225 -  
226 - /**  
227 - * Set Last Modified  
228 - *  
229 - * @access public  
230 - * @return void  
231 - * @param int $lastModified The unix timestamp of last modification.  
232 - */  
233 - function setLastModified($lastModified = null)  
234 - {  
235 - $this->setHeader('Last-Modified', $lastModified);  
236 - }  
237 -}  
238 -?>  
thirdparty/pear/WebDAV/Request.php deleted
1 -<?php  
2 -// +-----------------------------------------------------------------------+  
3 -// | Copyright (c) 2002-2003, Richard Heyes |  
4 -// | All rights reserved. |  
5 -// | |  
6 -// | Redistribution and use in source and binary forms, with or without |  
7 -// | modification, are permitted provided that the following conditions |  
8 -// | are met: |  
9 -// | |  
10 -// | o Redistributions of source code must retain the above copyright |  
11 -// | notice, this list of conditions and the following disclaimer. |  
12 -// | o Redistributions in binary form must reproduce the above copyright |  
13 -// | notice, this list of conditions and the following disclaimer in the |  
14 -// | documentation and/or other materials provided with the distribution.|  
15 -// | o The names of the authors may not be used to endorse or promote |  
16 -// | products derived from this software without specific prior written |  
17 -// | permission. |  
18 -// | |  
19 -// | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS |  
20 -// | "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT |  
21 -// | LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR |  
22 -// | A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT |  
23 -// | OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, |  
24 -// | SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT |  
25 -// | LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |  
26 -// | DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |  
27 -// | THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |  
28 -// | (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE |  
29 -// | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |  
30 -// | |  
31 -// +-----------------------------------------------------------------------+  
32 -// | Author: Richard Heyes <richard@phpguru.org> |  
33 -// +-----------------------------------------------------------------------+  
34 -//  
35 -// $Id: Request.php 6819 2007-06-20 13:09:21Z kevin_fourie $  
36 -//  
37 -// HTTP_Request Class  
38 -//  
39 -// Simple example, (Fetches yahoo.com and displays it):  
40 -//  
41 -// $a = &new HTTP_Request('http://www.yahoo.com/');  
42 -// $a->sendRequest();  
43 -// echo $a->getResponseBody();  
44 -//  
45 -  
46 -require_once 'PEAR.php';  
47 -require_once 'Net/Socket.php';  
48 -require_once 'Net/URL.php';  
49 -  
50 -define('HTTP_REQUEST_METHOD_GET', 'GET', true);  
51 -define('HTTP_REQUEST_METHOD_HEAD', 'HEAD', true);  
52 -define('HTTP_REQUEST_METHOD_POST', 'POST', true);  
53 -define('HTTP_REQUEST_METHOD_PUT', 'PUT', true);  
54 -define('HTTP_REQUEST_METHOD_DELETE', 'DELETE', true);  
55 -define('HTTP_REQUEST_METHOD_OPTIONS', 'OPTIONS', true);  
56 -define('HTTP_REQUEST_METHOD_TRACE', 'TRACE', true);  
57 -  
58 -define('HTTP_REQUEST_HTTP_VER_1_0', '1.0', true);  
59 -define('HTTP_REQUEST_HTTP_VER_1_1', '1.1', true);  
60 -  
61 -class HTTP_Request {  
62 -  
63 - /**  
64 - * Instance of Net_URL  
65 - * @var object Net_URL  
66 - */  
67 - var $_url;  
68 -  
69 - /**  
70 - * Type of request  
71 - * @var string  
72 - */  
73 - var $_method;  
74 -  
75 - /**  
76 - * HTTP Version  
77 - * @var string  
78 - */  
79 - var $_http;  
80 -  
81 - /**  
82 - * Request headers  
83 - * @var array  
84 - */  
85 - var $_requestHeaders;  
86 -  
87 - /**  
88 - * Basic Auth Username  
89 - * @var string  
90 - */  
91 - var $_user;  
92 -  
93 - /**  
94 - * Basic Auth Password  
95 - * @var string  
96 - */  
97 - var $_pass;  
98 -  
99 - /**  
100 - * Socket object  
101 - * @var object Net_Socket  
102 - */  
103 - var $_sock;  
104 -  
105 - /**  
106 - * Proxy server  
107 - * @var string  
108 - */  
109 - var $_proxy_host;  
110 -  
111 - /**  
112 - * Proxy port  
113 - * @var integer  
114 - */  
115 - var $_proxy_port;  
116 -  
117 - /**  
118 - * Proxy username  
119 - * @var string  
120 - */  
121 - var $_proxy_user;  
122 -  
123 - /**  
124 - * Proxy password  
125 - * @var string  
126 - */  
127 - var $_proxy_pass;  
128 -  
129 - /**  
130 - * Post data  
131 - * @var array  
132 - */  
133 - var $_postData;  
134 -  
135 - /**  
136 - * Request body  
137 - * @var string  
138 - */  
139 - var $_body;  
140 -  
141 - /**  
142 - * A list of methods that MUST NOT have a request body, per RFC 2616  
143 - * @var array  
144 - */  
145 - var $_bodyDisallowed = array('TRACE');  
146 -  
147 - /**  
148 - * Files to post  
149 - * @var array  
150 - */  
151 - var $_postFiles = array();  
152 -  
153 - /**  
154 - * Connection timeout.  
155 - * @var float  
156 - */  
157 - var $_timeout;  
158 -  
159 - /**  
160 - * HTTP_Response object  
161 - * @var object HTTP_Response  
162 - */  
163 - var $_response;  
164 -  
165 - /**  
166 - * Whether to allow redirects  
167 - * @var boolean  
168 - */  
169 - var $_allowRedirects;  
170 -  
171 - /**  
172 - * Maximum redirects allowed  
173 - * @var integer  
174 - */  
175 - var $_maxRedirects;  
176 -  
177 - /**  
178 - * Current number of redirects  
179 - * @var integer  
180 - */  
181 - var $_redirects;  
182 -  
183 - /**  
184 - * Whether to append brackets [] to array variables  
185 - * @var bool  
186 - */  
187 - var $_useBrackets = true;  
188 -  
189 - /**  
190 - * Attached listeners  
191 - * @var array  
192 - */  
193 - var $_listeners = array();  
194 -  
195 - /**  
196 - * Whether to save response body in response object property  
197 - * @var bool  
198 - */  
199 - var $_saveBody = true;  
200 -  
201 - /**  
202 - * Timeout for reading from socket (array(seconds, microseconds))  
203 - * @var array  
204 - */  
205 - var $_readTimeout = null;  
206 -  
207 - /**  
208 - * Options to pass to Net_Socket::connect. See stream_context_create  
209 - * @var array  
210 - */  
211 - var $_socketOptions = null;  
212 -  
213 - /**  
214 - * Constructor  
215 - *  
216 - * Sets up the object  
217 - * @param string The url to fetch/access  
218 - * @param array Associative array of parameters which can have the following keys:  
219 - * <ul>  
220 - * <li>method - Method to use, GET, POST etc (string)</li>  
221 - * <li>http - HTTP Version to use, 1.0 or 1.1 (string)</li>  
222 - * <li>user - Basic Auth username (string)</li>  
223 - * <li>pass - Basic Auth password (string)</li>  
224 - * <li>proxy_host - Proxy server host (string)</li>  
225 - * <li>proxy_port - Proxy server port (integer)</li>  
226 - * <li>proxy_user - Proxy auth username (string)</li>  
227 - * <li>proxy_pass - Proxy auth password (string)</li>  
228 - * <li>timeout - Connection timeout in seconds (float)</li>  
229 - * <li>allowRedirects - Whether to follow redirects or not (bool)</li>  
230 - * <li>maxRedirects - Max number of redirects to follow (integer)</li>  
231 - * <li>useBrackets - Whether to append [] to array variable names (bool)</li>  
232 - * <li>saveBody - Whether to save response body in response object property (bool)</li>  
233 - * <li>readTimeout - Timeout for reading / writing data over the socket (array (seconds, microseconds))</li>  
234 - * <li>socketOptions - Options to pass to Net_Socket object (array)</li>  
235 - * </ul>  
236 - * @access public  
237 - */  
238 - function HTTP_Request($url = '', $params = array())  
239 - {  
240 - $this->_sock = &new Net_Socket();  
241 - $this->_method = HTTP_REQUEST_METHOD_GET;  
242 - $this->_http = HTTP_REQUEST_HTTP_VER_1_1;  
243 - $this->_requestHeaders = array();  
244 - $this->_postData = array();  
245 - $this->_body = null;  
246 -  
247 - $this->_user = null;  
248 - $this->_pass = null;  
249 -  
250 - $this->_proxy_host = null;  
251 - $this->_proxy_port = null;  
252 - $this->_proxy_user = null;  
253 - $this->_proxy_pass = null;  
254 -  
255 - $this->_allowRedirects = false;  
256 - $this->_maxRedirects = 3;  
257 - $this->_redirects = 0;  
258 -  
259 - $this->_timeout = null;  
260 - $this->_response = null;  
261 -  
262 - foreach ($params as $key => $value) {  
263 - $this->{'_' . $key} = $value;  
264 - }  
265 -  
266 - if (!empty($url)) {  
267 - $this->setURL($url);  
268 - }  
269 -  
270 - // Default useragent  
271 - $this->addHeader('User-Agent', 'PEAR HTTP_Request class ( http://pear.php.net/ )');  
272 -  
273 - // Make sure keepalives dont knobble us  
274 - $this->addHeader('Connection', 'close');  
275 -  
276 - // Basic authentication  
277 - if (!empty($this->_user)) {  
278 - $this->addHeader('Authorization', 'Basic ' . base64_encode($this->_user . ':' . $this->_pass));  
279 - }  
280 -  
281 - // Use gzip encoding if possible  
282 - // Avoid gzip encoding if using multibyte functions (see #1781)  
283 - if (HTTP_REQUEST_HTTP_VER_1_1 == $this->_http && extension_loaded('zlib') &&  
284 - 0 == (2 & ini_get('mbstring.func_overload'))) {  
285 -  
286 - $this->addHeader('Accept-Encoding', 'gzip');  
287 - }  
288 - }  
289 -  
290 - /**  
291 - * Generates a Host header for HTTP/1.1 requests  
292 - *  
293 - * @access private  
294 - * @return string  
295 - */  
296 - function _generateHostHeader()  
297 - {  
298 - if ($this->_url->port != 80 AND strcasecmp($this->_url->protocol, 'http') == 0) {  
299 - $host = $this->_url->host . ':' . $this->_url->port;  
300 -  
301 - } elseif ($this->_url->port != 443 AND strcasecmp($this->_url->protocol, 'https') == 0) {  
302 - $host = $this->_url->host . ':' . $this->_url->port;  
303 -  
304 - } elseif ($this->_url->port == 443 AND strcasecmp($this->_url->protocol, 'https') == 0 AND strpos($this->_url->url, ':443') !== false) {  
305 - $host = $this->_url->host . ':' . $this->_url->port;  
306 -  
307 - } else {  
308 - $host = $this->_url->host;  
309 - }  
310 -  
311 - return $host;  
312 - }  
313 -  
314 - /**  
315 - * Resets the object to its initial state (DEPRECATED).  
316 - * Takes the same parameters as the constructor.  
317 - *  
318 - * @param string $url The url to be requested  
319 - * @param array $params Associative array of parameters  
320 - * (see constructor for details)  
321 - * @access public  
322 - * @deprecated deprecated since 1.2, call the constructor if this is necessary  
323 - */  
324 - function reset($url, $params = array())  
325 - {  
326 - $this->HTTP_Request($url, $params);  
327 - }  
328 -  
329 - /**  
330 - * Sets the URL to be requested  
331 - *  
332 - * @param string The url to be requested  
333 - * @access public  
334 - */  
335 - function setURL($url)  
336 - {  
337 - $this->_url = &new Net_URL($url, $this->_useBrackets);  
338 -  
339 - if (!empty($this->_url->user) || !empty($this->_url->pass)) {  
340 - $this->setBasicAuth($this->_url->user, $this->_url->pass);  
341 - }  
342 -  
343 - if (HTTP_REQUEST_HTTP_VER_1_1 == $this->_http) {  
344 - $this->addHeader('Host', $this->_generateHostHeader());  
345 - }  
346 - }  
347 -  
348 - /**  
349 - * Sets a proxy to be used  
350 - *  
351 - * @param string Proxy host  
352 - * @param int Proxy port  
353 - * @param string Proxy username  
354 - * @param string Proxy password  
355 - * @access public  
356 - */  
357 - function setProxy($host, $port = 8080, $user = null, $pass = null)  
358 - {  
359 - $this->_proxy_host = $host;  
360 - $this->_proxy_port = $port;  
361 - $this->_proxy_user = $user;  
362 - $this->_proxy_pass = $pass;  
363 -  
364 - if (!empty($user)) {  
365 - $this->addHeader('Proxy-Authorization', 'Basic ' . base64_encode($user . ':' . $pass));  
366 - }  
367 - }  
368 -  
369 - /**  
370 - * Sets basic authentication parameters  
371 - *  
372 - * @param string Username  
373 - * @param string Password  
374 - */  
375 - function setBasicAuth($user, $pass)  
376 - {  
377 - $this->_user = $user;  
378 - $this->_pass = $pass;  
379 -  
380 - $this->addHeader('Authorization', 'Basic ' . base64_encode($user . ':' . $pass));  
381 - }  
382 -  
383 - /**  
384 - * Sets the method to be used, GET, POST etc.  
385 - *  
386 - * @param string Method to use. Use the defined constants for this  
387 - * @access public  
388 - */  
389 - function setMethod($method)  
390 - {  
391 - $this->_method = $method;  
392 - }  
393 -  
394 - /**  
395 - * Sets the HTTP version to use, 1.0 or 1.1  
396 - *  
397 - * @param string Version to use. Use the defined constants for this  
398 - * @access public  
399 - */  
400 - function setHttpVer($http)  
401 - {  
402 - $this->_http = $http;  
403 - }  
404 -  
405 - /**  
406 - * Adds a request header  
407 - *  
408 - * @param string Header name  
409 - * @param string Header value  
410 - * @access public  
411 - */  
412 - function addHeader($name, $value)  
413 - {  
414 - $this->_requestHeaders[strtolower($name)] = $value;  
415 - }  
416 -  
417 - /**  
418 - * Removes a request header  
419 - *  
420 - * @param string Header name to remove  
421 - * @access public  
422 - */  
423 - function removeHeader($name)  
424 - {  
425 - if (isset($this->_requestHeaders[strtolower($name)])) {  
426 - unset($this->_requestHeaders[strtolower($name)]);  
427 - }  
428 - }  
429 -  
430 - /**  
431 - * Adds a querystring parameter  
432 - *  
433 - * @param string Querystring parameter name  
434 - * @param string Querystring parameter value  
435 - * @param bool Whether the value is already urlencoded or not, default = not  
436 - * @access public  
437 - */  
438 - function addQueryString($name, $value, $preencoded = false)  
439 - {  
440 - $this->_url->addQueryString($name, $value, $preencoded);  
441 - }  
442 -  
443 - /**  
444 - * Sets the querystring to literally what you supply  
445 - *  
446 - * @param string The querystring data. Should be of the format foo=bar&x=y etc  
447 - * @param bool Whether data is already urlencoded or not, default = already encoded  
448 - * @access public  
449 - */  
450 - function addRawQueryString($querystring, $preencoded = true)  
451 - {  
452 - $this->_url->addRawQueryString($querystring, $preencoded);  
453 - }  
454 -  
455 - /**  
456 - * Adds postdata items  
457 - *  
458 - * @param string Post data name  
459 - * @param string Post data value  
460 - * @param bool Whether data is already urlencoded or not, default = not  
461 - * @access public  
462 - */  
463 - function addPostData($name, $value, $preencoded = false)  
464 - {  
465 - if ($preencoded) {  
466 - $this->_postData[$name] = $value;  
467 - } else {  
468 - $this->_postData[$name] = $this->_arrayMapRecursive('urlencode', $value);  
469 - }  
470 - }  
471 -  
472 - /**  
473 - * Recursively applies the callback function to the value  
474 - *  
475 - * @param mixed Callback function  
476 - * @param mixed Value to process  
477 - * @access private  
478 - * @return mixed Processed value  
479 - */  
480 - function _arrayMapRecursive($callback, $value)  
481 - {  
482 - if (!is_array($value)) {  
483 - return call_user_func($callback, $value);  
484 - } else {  
485 - $map = array();  
486 - foreach ($value as $k => $v) {  
487 - $map[$k] = $this->_arrayMapRecursive($callback, $v);  
488 - }  
489 - return $map;  
490 - }  
491 - }  
492 -  
493 - /**  
494 - * Adds a file to upload  
495 - *  
496 - * This also changes content-type to 'multipart/form-data' for proper upload  
497 - *  
498 - * @access public  
499 - * @param string name of file-upload field  
500 - * @param mixed file name(s)  
501 - * @param mixed content-type(s) of file(s) being uploaded  
502 - * @return bool true on success  
503 - * @throws PEAR_Error  
504 - */  
505 - function addFile($inputName, $fileName, $contentType = 'application/octet-stream')  
506 - {  
507 - if (!is_array($fileName) && !is_readable($fileName)) {  
508 - return PEAR::raiseError("File '{$fileName}' is not readable");  
509 - } elseif (is_array($fileName)) {  
510 - foreach ($fileName as $name) {  
511 - if (!is_readable($name)) {  
512 - return PEAR::raiseError("File '{$name}' is not readable");  
513 - }  
514 - }  
515 - }  
516 - $this->addHeader('Content-Type', 'multipart/form-data');  
517 - $this->_postFiles[$inputName] = array(  
518 - 'name' => $fileName,  
519 - 'type' => $contentType  
520 - );  
521 - return true;  
522 - }  
523 -  
524 - /**  
525 - * Adds raw postdata (DEPRECATED)  
526 - *  
527 - * @param string The data  
528 - * @param bool Whether data is preencoded or not, default = already encoded  
529 - * @access public  
530 - * @deprecated deprecated since 1.3.0, method addBody() should be used instead  
531 - */  
532 - function addRawPostData($postdata, $preencoded = true)  
533 - {  
534 - $this->_body = $preencoded ? $postdata : urlencode($postdata);  
535 - }  
536 -  
537 - /**  
538 - * Sets the request body (for POST, PUT and similar requests)  
539 - *  
540 - * @param string Request body  
541 - * @access public  
542 - */  
543 - function setBody($body)  
544 - {  
545 - $this->_body = $body;  
546 - }  
547 -  
548 - /**  
549 - * Clears any postdata that has been added (DEPRECATED).  
550 - *  
551 - * Useful for multiple request scenarios.  
552 - *  
553 - * @access public  
554 - * @deprecated deprecated since 1.2  
555 - */  
556 - function clearPostData()  
557 - {  
558 - $this->_postData = null;  
559 - }  
560 -  
561 - /**  
562 - * Appends a cookie to "Cookie:" header  
563 - *  
564 - * @param string $name cookie name  
565 - * @param string $value cookie value  
566 - * @access public  
567 - */  
568 - function addCookie($name, $value)  
569 - {  
570 - $cookies = isset($this->_requestHeaders['cookie']) ? $this->_requestHeaders['cookie']. '; ' : '';  
571 - $this->addHeader('Cookie', $cookies . $name . '=' . $value);  
572 - }  
573 -  
574 - /**  
575 - * Clears any cookies that have been added (DEPRECATED).  
576 - *  
577 - * Useful for multiple request scenarios  
578 - *  
579 - * @access public  
580 - * @deprecated deprecated since 1.2  
581 - */  
582 - function clearCookies()  
583 - {  
584 - $this->removeHeader('Cookie');  
585 - }  
586 -  
587 - /**  
588 - * Sends the request  
589 - *  
590 - * @access public  
591 - * @param bool Whether to store response body in Response object property,  
592 - * set this to false if downloading a LARGE file and using a Listener  
593 - * @return mixed PEAR error on error, true otherwise  
594 - */  
595 - function sendRequest($saveBody = true)  
596 - {  
597 - if (!is_a($this->_url, 'Net_URL')) {  
598 - return PEAR::raiseError('No URL given.');  
599 - }  
600 -  
601 - $host = isset($this->_proxy_host) ? $this->_proxy_host : $this->_url->host;  
602 - $port = isset($this->_proxy_port) ? $this->_proxy_port : $this->_url->port;  
603 -  
604 - // 4.3.0 supports SSL connections using OpenSSL. The function test determines  
605 - // we running on at least 4.3.0  
606 - if (strcasecmp($this->_url->protocol, 'https') == 0 AND function_exists('file_get_contents') AND extension_loaded('openssl')) {  
607 - if (isset($this->_proxy_host)) {  
608 - return PEAR::raiseError('HTTPS proxies are not supported.');  
609 - }  
610 - $host = 'ssl://' . $host;  
611 - }  
612 -  
613 - // magic quotes may fuck up file uploads and chunked response processing  
614 - $magicQuotes = ini_get('magic_quotes_runtime');  
615 - ini_set('magic_quotes_runtime', false);  
616 -  
617 - // If this is a second request, we may get away without  
618 - // re-connecting if they're on the same server  
619 - $err = $this->_sock->connect($host, $port, null, $this->_timeout, $this->_socketOptions);  
620 - PEAR::isError($err) or $err = $this->_sock->write($this->_buildRequest());  
621 -  
622 - if (!PEAR::isError($err)) {  
623 - if (!empty($this->_readTimeout)) {  
624 - $this->_sock->setTimeout($this->_readTimeout[0], $this->_readTimeout[1]);  
625 - }  
626 -  
627 - $this->_notify('sentRequest');  
628 -  
629 - // Read the response  
630 - $this->_response = &new HTTP_Response($this->_sock, $this->_listeners);  
631 - $err = $this->_response->process($this->_saveBody && $saveBody);  
632 - }  
633 -  
634 - ini_set('magic_quotes_runtime', $magicQuotes);  
635 -  
636 - if (PEAR::isError($err)) {  
637 - return $err;  
638 - }  
639 -  
640 -  
641 - // Check for redirection  
642 - if ( $this->_allowRedirects  
643 - AND $this->_redirects <= $this->_maxRedirects  
644 - AND $this->getResponseCode() > 300  
645 - AND $this->getResponseCode() < 399  
646 - AND !empty($this->_response->_headers['location'])) {  
647 -  
648 -  
649 - $redirect = $this->_response->_headers['location'];  
650 -  
651 - // Absolute URL  
652 - if (preg_match('/^https?:\/\//i', $redirect)) {  
653 - $this->_url = &new Net_URL($redirect);  
654 - $this->addHeader('Host', $this->_generateHostHeader());  
655 - // Absolute path  
656 - } elseif ($redirect{0} == '/') {  
657 - $this->_url->path = $redirect;  
658 -  
659 - // Relative path  
660 - } elseif (substr($redirect, 0, 3) == '../' OR substr($redirect, 0, 2) == './') {  
661 - if (substr($this->_url->path, -1) == '/') {  
662 - $redirect = $this->_url->path . $redirect;  
663 - } else {  
664 - $redirect = dirname($this->_url->path) . '/' . $redirect;  
665 - }  
666 - $redirect = Net_URL::resolvePath($redirect);  
667 - $this->_url->path = $redirect;  
668 -  
669 - // Filename, no path  
670 - } else {  
671 - if (substr($this->_url->path, -1) == '/') {  
672 - $redirect = $this->_url->path . $redirect;  
673 - } else {  
674 - $redirect = dirname($this->_url->path) . '/' . $redirect;  
675 - }  
676 - $this->_url->path = $redirect;  
677 - }  
678 -  
679 - $this->_redirects++;  
680 - return $this->sendRequest($saveBody);  
681 -  
682 - // Too many redirects  
683 - } elseif ($this->_allowRedirects AND $this->_redirects > $this->_maxRedirects) {  
684 - return PEAR::raiseError('Too many redirects');  
685 - }  
686 -  
687 - $this->_sock->disconnect();  
688 -  
689 - return true;  
690 - }  
691 -  
692 - /**  
693 - * Returns the response code  
694 - *  
695 - * @access public  
696 - * @return mixed Response code, false if not set  
697 - */  
698 - function getResponseCode()  
699 - {  
700 - return isset($this->_response->_code) ? $this->_response->_code : false;  
701 - }  
702 -  
703 - /**  
704 - * Returns either the named header or all if no name given  
705 - *  
706 - * @access public  
707 - * @param string The header name to return, do not set to get all headers  
708 - * @return mixed either the value of $headername (false if header is not present)  
709 - * or an array of all headers  
710 - */  
711 - function getResponseHeader($headername = null)  
712 - {  
713 - if (!isset($headername)) {  
714 - return isset($this->_response->_headers)? $this->_response->_headers: array();  
715 - } else {  
716 - $headername = strtolower($headername);  
717 - return isset($this->_response->_headers[$headername]) ? $this->_response->_headers[$headername] : false;  
718 - }  
719 - }  
720 -  
721 - /**  
722 - * Returns the body of the response  
723 - *  
724 - * @access public  
725 - * @return mixed response body, false if not set  
726 - */  
727 - function getResponseBody()  
728 - {  
729 - return isset($this->_response->_body) ? $this->_response->_body : false;  
730 - }  
731 -  
732 - /**  
733 - * Returns cookies set in response  
734 - *  
735 - * @access public  
736 - * @return mixed array of response cookies, false if none are present  
737 - */  
738 - function getResponseCookies()  
739 - {  
740 - return isset($this->_response->_cookies) ? $this->_response->_cookies : false;  
741 - }  
742 -  
743 - /**  
744 - * Builds the request string  
745 - *  
746 - * @access private  
747 - * @return string The request string  
748 - */  
749 - function _buildRequest()  
750 - {  
751 - $separator = ini_get('arg_separator.output');  
752 - ini_set('arg_separator.output', '&');  
753 - $querystring = ($querystring = $this->_url->getQueryString()) ? '?' . $querystring : '';  
754 - ini_set('arg_separator.output', $separator);  
755 -  
756 - $host = isset($this->_proxy_host) ? $this->_url->protocol . '://' . $this->_url->host : '';  
757 - $port = (isset($this->_proxy_host) AND $this->_url->port != 80) ? ':' . $this->_url->port : '';  
758 - $path = (empty($this->_url->path)? '/': $this->_url->path) . $querystring;  
759 - $url = $host . $port . $path;  
760 -  
761 - $request = $this->_method . ' ' . $url . ' HTTP/' . $this->_http . "\r\n";  
762 -  
763 - if (in_array($this->_method, $this->_bodyDisallowed) ||  
764 - (HTTP_REQUEST_METHOD_POST != $this->_method && empty($this->_body)) ||  
765 - (HTTP_REQUEST_METHOD_POST != $this->_method && empty($this->_postData) && empty($this->_postFiles))) {  
766 -  
767 - $this->removeHeader('Content-Type');  
768 - } else {  
769 - if (empty($this->_requestHeaders['content-type'])) {  
770 - // Add default content-type  
771 - $this->addHeader('Content-Type', 'application/x-www-form-urlencoded');  
772 - } elseif ('multipart/form-data' == $this->_requestHeaders['content-type']) {  
773 - $boundary = 'HTTP_Request_' . md5(uniqid('request') . microtime());  
774 - $this->addHeader('Content-Type', 'multipart/form-data; boundary=' . $boundary);  
775 - }  
776 - }  
777 -  
778 - // Request Headers  
779 - if (!empty($this->_requestHeaders)) {  
780 - foreach ($this->_requestHeaders as $name => $value) {  
781 - $canonicalName = implode('-', array_map('ucfirst', explode('-', $name)));  
782 - $request .= $canonicalName . ': ' . $value . "\r\n";  
783 - }  
784 - }  
785 -  
786 - // No post data or wrong method, so simply add a final CRLF  
787 - if (in_array($this->_method, $this->_bodyDisallowed) ||  
788 - (HTTP_REQUEST_METHOD_POST != $this->_method && empty($this->_body))) {  
789 -  
790 - $request .= "\r\n";  
791 -  
792 - // Post data if it's an array  
793 - } elseif (HTTP_REQUEST_METHOD_POST == $this->_method &&  
794 - (!empty($this->_postData) || !empty($this->_postFiles))) {  
795 -  
796 - // "normal" POST request  
797 - if (!isset($boundary)) {  
798 - $postdata = implode('&', array_map(  
799 - create_function('$a', 'return $a[0] . \'=\' . $a[1];'),  
800 - $this->_flattenArray('', $this->_postData)  
801 - ));  
802 -  
803 - // multipart request, probably with file uploads  
804 - } else {  
805 - $postdata = '';  
806 - if (!empty($this->_postData)) {  
807 - $flatData = $this->_flattenArray('', $this->_postData);  
808 - foreach ($flatData as $item) {  
809 - $postdata .= '--' . $boundary . "\r\n";  
810 - $postdata .= 'Content-Disposition: form-data; name="' . $item[0] . '"';  
811 - $postdata .= "\r\n\r\n" . urldecode($item[1]) . "\r\n";  
812 - }  
813 - }  
814 - foreach ($this->_postFiles as $name => $value) {  
815 - if (is_array($value['name'])) {  
816 - $varname = $name . ($this->_useBrackets? '[]': '');  
817 - } else {  
818 - $varname = $name;  
819 - $value['name'] = array($value['name']);  
820 - }  
821 - foreach ($value['name'] as $key => $filename) {  
822 - $fp = fopen($filename, 'r');  
823 - $data = fread($fp, filesize($filename));  
824 - fclose($fp);  
825 - $basename = basename($filename);  
826 - $type = is_array($value['type'])? @$value['type'][$key]: $value['type'];  
827 -  
828 - $postdata .= '--' . $boundary . "\r\n";  
829 - $postdata .= 'Content-Disposition: form-data; name="' . $varname . '"; filename="' . $basename . '"';  
830 - $postdata .= "\r\nContent-Type: " . $type;  
831 - $postdata .= "\r\n\r\n" . $data . "\r\n";  
832 - }  
833 - }  
834 - $postdata .= '--' . $boundary . "--\r\n";  
835 - }  
836 - $request .= 'Content-Length: ' . strlen($postdata) . "\r\n\r\n";  
837 - $request .= $postdata;  
838 -  
839 - // Explicitly set request body  
840 - } elseif (!empty($this->_body)) {  
841 -  
842 - $request .= 'Content-Length: ' . strlen($this->_body) . "\r\n\r\n";  
843 - $request .= $this->_body;  
844 - }  
845 -  
846 - return $request;  
847 - }  
848 -  
849 - /**  
850 - * Helper function to change the (probably multidimensional) associative array  
851 - * into the simple one.  
852 - *  
853 - * @param string name for item  
854 - * @param mixed item's values  
855 - * @return array array with the following items: array('item name', 'item value');  
856 - */  
857 - function _flattenArray($name, $values)  
858 - {  
859 - if (!is_array($values)) {  
860 - return array(array($name, $values));  
861 - } else {  
862 - $ret = array();  
863 - foreach ($values as $k => $v) {  
864 - if (empty($name)) {  
865 - $newName = $k;  
866 - } elseif ($this->_useBrackets) {  
867 - $newName = $name . '[' . $k . ']';  
868 - } else {  
869 - $newName = $name;  
870 - }  
871 - $ret = array_merge($ret, $this->_flattenArray($newName, $v));  
872 - }  
873 - return $ret;  
874 - }  
875 - }  
876 -  
877 -  
878 - /**  
879 - * Adds a Listener to the list of listeners that are notified of  
880 - * the object's events  
881 - *  
882 - * @param object HTTP_Request_Listener instance to attach  
883 - * @return boolean whether the listener was successfully attached  
884 - * @access public  
885 - */  
886 - function attach(&$listener)  
887 - {  
888 - if (!is_a($listener, 'HTTP_Request_Listener')) {  
889 - return false;  
890 - }  
891 - $this->_listeners[$listener->getId()] =& $listener;  
892 - return true;  
893 - }  
894 -  
895 -  
896 - /**  
897 - * Removes a Listener from the list of listeners  
898 - *  
899 - * @param object HTTP_Request_Listener instance to detach  
900 - * @return boolean whether the listener was successfully detached  
901 - * @access public  
902 - */  
903 - function detach(&$listener)  
904 - {  
905 - if (!is_a($listener, 'HTTP_Request_Listener') ||  
906 - !isset($this->_listeners[$listener->getId()])) {  
907 - return false;  
908 - }  
909 - unset($this->_listeners[$listener->getId()]);  
910 - return true;  
911 - }  
912 -  
913 -  
914 - /**  
915 - * Notifies all registered listeners of an event.  
916 - *  
917 - * Events sent by HTTP_Request object  
918 - * 'sentRequest': after the request was sent  
919 - * Events sent by HTTP_Response object  
920 - * 'gotHeaders': after receiving response headers (headers are passed in $data)  
921 - * 'tick': on receiving a part of response body (the part is passed in $data)  
922 - * 'gzTick': on receiving a gzip-encoded part of response body (ditto)  
923 - * 'gotBody': after receiving the response body (passes the decoded body in $data if it was gzipped)  
924 - *  
925 - * @param string Event name  
926 - * @param mixed Additional data  
927 - * @access private  
928 - */  
929 - function _notify($event, $data = null)  
930 - {  
931 - foreach (array_keys($this->_listeners) as $id) {  
932 - $this->_listeners[$id]->update($this, $event, $data);  
933 - }  
934 - }  
935 -}  
936 -  
937 -  
938 -/**  
939 -* Response class to complement the Request class  
940 -*/  
941 -class HTTP_Response  
942 -{  
943 - /**  
944 - * Socket object  
945 - * @var object  
946 - */  
947 - var $_sock;  
948 -  
949 - /**  
950 - * Protocol  
951 - * @var string  
952 - */  
953 - var $_protocol;  
954 -  
955 - /**  
956 - * Return code  
957 - * @var string  
958 - */  
959 - var $_code;  
960 -  
961 - /**  
962 - * Response headers  
963 - * @var array  
964 - */  
965 - var $_headers;  
966 -  
967 - /**  
968 - * Cookies set in response  
969 - * @var array  
970 - */  
971 - var $_cookies;  
972 -  
973 - /**  
974 - * Response body  
975 - * @var string  
976 - */  
977 - var $_body = '';  
978 -  
979 - /**  
980 - * Used by _readChunked(): remaining length of the current chunk  
981 - * @var string  
982 - */  
983 - var $_chunkLength = 0;  
984 -  
985 - /**  
986 - * Attached listeners  
987 - * @var array  
988 - */  
989 - var $_listeners = array();  
990 -  
991 - /**  
992 - * Constructor  
993 - *  
994 - * @param object Net_Socket socket to read the response from  
995 - * @param array listeners attached to request  
996 - * @return mixed PEAR Error on error, true otherwise  
997 - */  
998 - function HTTP_Response(&$sock, &$listeners)  
999 - {  
1000 - $this->_sock =& $sock;  
1001 - $this->_listeners =& $listeners;  
1002 - }  
1003 -  
1004 -  
1005 - /**  
1006 - * Processes a HTTP response  
1007 - *  
1008 - * This extracts response code, headers, cookies and decodes body if it  
1009 - * was encoded in some way  
1010 - *  
1011 - * @access public  
1012 - * @param bool Whether to store response body in object property, set  
1013 - * this to false if downloading a LARGE file and using a Listener.  
1014 - * This is assumed to be true if body is gzip-encoded.  
1015 - * @throws PEAR_Error  
1016 - * @return mixed true on success, PEAR_Error in case of malformed response  
1017 - */  
1018 - function process($saveBody = true)  
1019 - {  
1020 - do {  
1021 - $line = $this->_sock->readLine();  
1022 - if (sscanf($line, 'HTTP/%s %s', $http_version, $returncode) != 2) {  
1023 - return PEAR::raiseError('Malformed response.');  
1024 - } else {  
1025 - $this->_protocol = 'HTTP/' . $http_version;  
1026 - $this->_code = intval($returncode);  
1027 - }  
1028 - while ('' !== ($header = $this->_sock->readLine())) {  
1029 - $this->_processHeader($header);  
1030 - }  
1031 - } while (100 == $this->_code);  
1032 -  
1033 - $this->_notify('gotHeaders', $this->_headers);  
1034 -  
1035 - // If response body is present, read it and decode  
1036 - $chunked = isset($this->_headers['transfer-encoding']) && ('chunked' == $this->_headers['transfer-encoding']);  
1037 - $gzipped = isset($this->_headers['content-encoding']) && ('gzip' == $this->_headers['content-encoding']);  
1038 - $hasBody = false;  
1039 - if (!isset($this->_headers['content-length']) || 0 != $this->_headers['content-length']) {  
1040 - while (!$this->_sock->eof()) {  
1041 - if ($chunked) {  
1042 - $data = $this->_readChunked();  
1043 - } else {  
1044 - $data = $this->_sock->read(4096);  
1045 - }  
1046 - if ('' == $data) {  
1047 - break;  
1048 - } else {  
1049 - $hasBody = true;  
1050 - if ($saveBody || $gzipped) {  
1051 - $this->_body .= $data;  
1052 - }  
1053 - $this->_notify($gzipped? 'gzTick': 'tick', $data);  
1054 - }  
1055 - }  
1056 - }  
1057 - if ($hasBody) {  
1058 - // Uncompress the body if needed  
1059 - if ($gzipped) {  
1060 - $this->_body = gzinflate(substr($this->_body, 10));  
1061 - $this->_notify('gotBody', $this->_body);  
1062 - } else {  
1063 - $this->_notify('gotBody');  
1064 - }  
1065 - }  
1066 - return true;  
1067 - }  
1068 -  
1069 -  
1070 - /**  
1071 - * Processes the response header  
1072 - *  
1073 - * @access private  
1074 - * @param string HTTP header  
1075 - */  
1076 - function _processHeader($header)  
1077 - {  
1078 - list($headername, $headervalue) = explode(':', $header, 2);  
1079 - $headername = strtolower($headername);  
1080 - $headervalue = ltrim($headervalue);  
1081 -  
1082 - if ('set-cookie' != $headername) {  
1083 - if (isset($this->_headers[$headername])) {  
1084 - $this->_headers[$headername] .= ',' . $headervalue;  
1085 - } else {  
1086 - $this->_headers[$headername] = $headervalue;  
1087 - }  
1088 - } else {  
1089 - $this->_parseCookie($headervalue);  
1090 - }  
1091 - }  
1092 -  
1093 -  
1094 - /**  
1095 - * Parse a Set-Cookie header to fill $_cookies array  
1096 - *  
1097 - * @access private  
1098 - * @param string value of Set-Cookie header  
1099 - */  
1100 - function _parseCookie($headervalue)  
1101 - {  
1102 - $cookie = array(  
1103 - 'expires' => null,  
1104 - 'domain' => null,  
1105 - 'path' => null,  
1106 - 'secure' => false  
1107 - );  
1108 -  
1109 - // Only a name=value pair  
1110 - if (!strpos($headervalue, ';')) {  
1111 - $pos = strpos($headervalue, '=');  
1112 - $cookie['name'] = trim(substr($headervalue, 0, $pos));  
1113 - $cookie['value'] = trim(substr($headervalue, $pos + 1));  
1114 -  
1115 - // Some optional parameters are supplied  
1116 - } else {  
1117 - $elements = explode(';', $headervalue);  
1118 - $pos = strpos($elements[0], '=');  
1119 - $cookie['name'] = trim(substr($elements[0], 0, $pos));  
1120 - $cookie['value'] = trim(substr($elements[0], $pos + 1));  
1121 -  
1122 - for ($i = 1; $i < count($elements); $i++) {  
1123 - if (false === strpos($elements[$i], '=')) {  
1124 - $elName = trim($elements[$i]);  
1125 - $elValue = null;  
1126 - } else {  
1127 - list ($elName, $elValue) = array_map('trim', explode('=', $elements[$i]));  
1128 - }  
1129 - $elName = strtolower($elName);  
1130 - if ('secure' == $elName) {  
1131 - $cookie['secure'] = true;  
1132 - } elseif ('expires' == $elName) {  
1133 - $cookie['expires'] = str_replace('"', '', $elValue);  
1134 - } elseif ('path' == $elName || 'domain' == $elName) {  
1135 - $cookie[$elName] = urldecode($elValue);  
1136 - } else {  
1137 - $cookie[$elName] = $elValue;  
1138 - }  
1139 - }  
1140 - }  
1141 - $this->_cookies[] = $cookie;  
1142 - }  
1143 -  
1144 -  
1145 - /**  
1146 - * Read a part of response body encoded with chunked Transfer-Encoding  
1147 - *  
1148 - * @access private  
1149 - * @return string  
1150 - */  
1151 - function _readChunked()  
1152 - {  
1153 - // at start of the next chunk?  
1154 - if (0 == $this->_chunkLength) {  
1155 - $line = $this->_sock->readLine();  
1156 - if (preg_match('/^([0-9a-f]+)/i', $line, $matches)) {  
1157 - $this->_chunkLength = hexdec($matches[1]);  
1158 - // Chunk with zero length indicates the end  
1159 - if (0 == $this->_chunkLength) {  
1160 - $this->_sock->readLine(); // make this an eof()  
1161 - return '';  
1162 - }  
1163 - } else {  
1164 - return '';  
1165 - }  
1166 - }  
1167 - $data = $this->_sock->read($this->_chunkLength);  
1168 - $this->_chunkLength -= strlen($data);  
1169 - if (0 == $this->_chunkLength) {  
1170 - $this->_sock->readLine(); // Trailing CRLF  
1171 - }  
1172 - return $data;  
1173 - }  
1174 -  
1175 -  
1176 - /**  
1177 - * Notifies all registered listeners of an event.  
1178 - *  
1179 - * @param string Event name  
1180 - * @param mixed Additional data  
1181 - * @access private  
1182 - * @see HTTP_Request::_notify()  
1183 - */  
1184 - function _notify($event, $data = null)  
1185 - {  
1186 - foreach (array_keys($this->_listeners) as $id) {  
1187 - $this->_listeners[$id]->update($this, $event, $data);  
1188 - }  
1189 - }  
1190 -} // End class HTTP_Response  
1191 -?>  
thirdparty/pear/WebDAV/Request/Listener.php deleted
1 -<?php  
2 -// +-----------------------------------------------------------------------+  
3 -// | Copyright (c) 2002-2003, Richard Heyes |  
4 -// | All rights reserved. |  
5 -// | |  
6 -// | Redistribution and use in source and binary forms, with or without |  
7 -// | modification, are permitted provided that the following conditions |  
8 -// | are met: |  
9 -// | |  
10 -// | o Redistributions of source code must retain the above copyright |  
11 -// | notice, this list of conditions and the following disclaimer. |  
12 -// | o Redistributions in binary form must reproduce the above copyright |  
13 -// | notice, this list of conditions and the following disclaimer in the |  
14 -// | documentation and/or other materials provided with the distribution.|  
15 -// | o The names of the authors may not be used to endorse or promote |  
16 -// | products derived from this software without specific prior written |  
17 -// | permission. |  
18 -// | |  
19 -// | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS |  
20 -// | "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT |  
21 -// | LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR |  
22 -// | A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT |  
23 -// | OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, |  
24 -// | SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT |  
25 -// | LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |  
26 -// | DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |  
27 -// | THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |  
28 -// | (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE |  
29 -// | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |  
30 -// | |  
31 -// +-----------------------------------------------------------------------+  
32 -// | Author: Alexey Borzov <avb@php.net> |  
33 -// +-----------------------------------------------------------------------+  
34 -//  
35 -// $Id: Listener.php 6819 2007-06-20 13:09:21Z kevin_fourie $  
36 -//  
37 -  
38 -/**  
39 - * This class implements the Observer part of a Subject-Observer  
40 - * design pattern. It listens to the events sent by a  
41 - * HTTP_Request or HTTP_Response instance.  
42 - *  
43 - * @package HTTP_Request  
44 - * @author Alexey Borzov <avb@php.net>  
45 - * @version $Revision: 6819 $  
46 - */  
47 -class HTTP_Request_Listener  
48 -{  
49 - /**  
50 - * A listener's identifier  
51 - * @var string  
52 - */  
53 - var $_id;  
54 -  
55 - /**  
56 - * Constructor, sets the object's identifier  
57 - *  
58 - * @access public  
59 - */  
60 - function HTTP_Request_Listener()  
61 - {  
62 - $this->_id = md5(uniqid('http_request_', 1));  
63 - }  
64 -  
65 -  
66 - /**  
67 - * Returns the listener's identifier  
68 - *  
69 - * @access public  
70 - * @return string  
71 - */  
72 - function getId()  
73 - {  
74 - return $this->_id;  
75 - }  
76 -  
77 -  
78 - /**  
79 - * This method is called when Listener is notified of an event  
80 - *  
81 - * @access public  
82 - * @param object an object the listener is attached to  
83 - * @param string Event name  
84 - * @param mixed Additional data  
85 - * @abstract  
86 - */  
87 - function update(&$subject, $event, $data = null)  
88 - {  
89 - echo "Notified of event: '$event'\n";  
90 - if (null !== $data) {  
91 - echo "Additional data: ";  
92 - var_dump($data);  
93 - }  
94 - }  
95 -}  
96 -?>  
thirdparty/pear/WebDAV/Upload.php deleted
1 -<?php  
2 -// **********************************************  
3 -//  
4 -// This software is licensed by the LGPL  
5 -// -> http://www.gnu.org/copyleft/lesser.txt  
6 -// (c) 2001-2004 by Tomas Von Veschler Cox  
7 -//  
8 -// **********************************************  
9 -//  
10 -// $Id: Upload.php 6819 2007-06-20 13:09:21Z kevin_fourie $  
11 -  
12 -/*  
13 - * Pear File Uploader class. Easy and secure managment of files  
14 - * submitted via HTML Forms.  
15 - *  
16 - * Leyend:  
17 - * - you can add error msgs in your language in the HTTP_Upload_Error class  
18 - *  
19 - * TODO:  
20 - * - try to think a way of having all the Error system in other  
21 - * file and only include it when an error ocurrs  
22 - *  
23 - * -- Notes for users HTTP_Upload >= 0.9.0 --  
24 - *  
25 - * Error detection was enhanced, so you no longer need to  
26 - * check for PEAR::isError() in $upload->getFiles() or call  
27 - * $upload->isMissing(). Instead you'll  
28 - * get the error when do a check for $file->isError().  
29 - *  
30 - * Example:  
31 - *  
32 - * $upload = new HTTP_Upload('en');  
33 - * $file = $upload->getFiles('i_dont_exist_in_form_definition');  
34 - * if ($file->isError()) {  
35 - * die($file->getMessage());  
36 - * }  
37 - *  
38 - * --  
39 - *  
40 - */  
41 -  
42 -require_once 'PEAR.php';  
43 -  
44 -/**  
45 - * defines default chmod  
46 - */  
47 -define('HTTP_UPLOAD_DEFAULT_CHMOD', 0660);  
48 -  
49 -/**  
50 - * Error Class for HTTP_Upload  
51 - *  
52 - * @author Tomas V.V.Cox <cox@idecnet.com>  
53 - * @see http://vulcanonet.com/soft/index.php?pack=uploader  
54 - * @package HTTP_Upload  
55 - * @category HTTP  
56 - * @access public  
57 - */  
58 -class HTTP_Upload_Error extends PEAR  
59 -{  
60 - /**  
61 - * Selected language for error messages  
62 - * @var string  
63 - */  
64 - var $lang = 'en';  
65 -  
66 - /**  
67 - * Whether HTML entities shall be encoded automatically  
68 - * @var boolean  
69 - */  
70 - var $html = false;  
71 -  
72 - /**  
73 - * Constructor  
74 - *  
75 - * Creates a new PEAR_Error  
76 - *  
77 - * @param string $lang The language selected for error code messages  
78 - * @access public  
79 - */  
80 - function HTTP_Upload_Error($lang = null, $html = false)  
81 - {  
82 - $this->lang = ($lang !== null) ? $lang : $this->lang;  
83 - $this->html = ($html !== false) ? $html : $this->html;  
84 - $ini_size = preg_replace('/m/i', '000000', ini_get('upload_max_filesize'));  
85 -  
86 - if (function_exists('version_compare') &&  
87 - version_compare(phpversion(), '4.1', 'ge')) {  
88 - $maxsize = (isset($_POST['MAX_FILE_SIZE'])) ?  
89 - $_POST['MAX_FILE_SIZE'] : null;  
90 - } else {  
91 - global $HTTP_POST_VARS;  
92 - $maxsize = (isset($HTTP_POST_VARS['MAX_FILE_SIZE'])) ?  
93 - $HTTP_POST_VARS['MAX_FILE_SIZE'] : null;  
94 - }  
95 -  
96 - if (empty($maxsize) || ($maxsize > $ini_size)) {  
97 - $maxsize = $ini_size;  
98 - }  
99 - // XXXXX Add here error messages in your language  
100 - $this->error_codes = array(  
101 - 'TOO_LARGE' => array(  
102 - 'es' => "Fichero demasiado largo. El maximo permitido es: $maxsize bytes.",  
103 - 'en' => "File size too large. The maximum permitted size is: $maxsize bytes.",  
104 - 'de' => "Datei zu gro&szlig;. Die zul&auml;ssige Maximalgr&ouml;&szlig;e ist: $maxsize Bytes.",  
105 - 'nl' => "Het bestand is te groot, de maximale grootte is: $maxsize bytes.",  
106 - 'fr' => "Le fichier est trop gros. La taille maximum autoris&eacute;e est: $maxsize bytes.",  
107 - 'it' => "Il file &eacute; troppo grande. Il massimo permesso &eacute: $maxsize bytes.",  
108 - 'pt_BR' => "Arquivo muito grande. O tamanho m&aacute;ximo permitido &eacute; $maxsize bytes."  
109 - ),  
110 - 'MISSING_DIR' => array(  
111 - 'es' => 'Falta directorio destino.',  
112 - 'en' => 'Missing destination directory.',  
113 - 'de' => 'Kein Zielverzeichnis definiert.',  
114 - 'nl' => 'Geen bestemmings directory.',  
115 - 'fr' => 'Le r&eacute;pertoire de destination n\'est pas d&eacute;fini.',  
116 - 'it' => 'Manca la directory di destinazione.',  
117 - 'pt_BR' => 'Aus&ecirc;ncia de diret&oacute;rio de destino.'  
118 - ),  
119 - 'IS_NOT_DIR' => array(  
120 - 'es' => 'El directorio destino no existe o es un fichero regular.',  
121 - 'en' => 'The destination directory doesn\'t exist or is a regular file.',  
122 - 'de' => 'Das angebene Zielverzeichnis existiert nicht oder ist eine Datei.',  
123 - 'nl' => 'De doeldirectory bestaat niet, of is een gewoon bestand.',  
124 - 'fr' => 'Le r&eacute;pertoire de destination n\'existe pas ou il s\'agit d\'un fichier r&eacute;gulier.',  
125 - 'it' => 'La directory di destinazione non esiste o &eacute; un file.',  
126 - 'pt_BR' => 'O diret&oacute;rio de destino n&atilde;o existe ou &eacute; um arquivo.'  
127 - ),  
128 - 'NO_WRITE_PERMS' => array(  
129 - 'es' => 'El directorio destino no tiene permisos de escritura.',  
130 - 'en' => 'The destination directory doesn\'t have write perms.',  
131 - 'de' => 'Fehlende Schreibrechte f&uuml;r das Zielverzeichnis.',  
132 - 'nl' => 'Geen toestemming om te schrijven in de doeldirectory.',  
133 - 'fr' => 'Le r&eacute;pertoire de destination n\'a pas les droits en &eacute;criture.',  
134 - 'it' => 'Non si hanno i permessi di scrittura sulla directory di destinazione.',  
135 - 'pt_BR' => 'O diret&oacute;rio de destino n&atilde;o possui permiss&atilde;o para escrita.'  
136 - ),  
137 - 'NO_USER_FILE' => array(  
138 - 'es' => 'No se ha escogido fichero para el upload.',  
139 - 'en' => 'You haven\'t selected any file for uploading.',  
140 - 'de' => 'Es wurde keine Datei f&uuml;r den Upload ausgew&auml;hlt.',  
141 - 'nl' => 'Er is geen bestand opgegeven om te uploaden.',  
142 - 'fr' => 'Vous n\'avez pas s&eacute;lectionn&eacute; de fichier &agrave; envoyer.',  
143 - 'it' => 'Nessun file selezionato per l\'upload.',  
144 - 'pt_BR' => 'Nenhum arquivo selecionado para upload.'  
145 - ),  
146 - 'BAD_FORM' => array(  
147 - 'es' => 'El formulario no contiene method="post" enctype="multipart/form-data" requerido.',  
148 - 'en' => 'The html form doesn\'t contain the required method="post" enctype="multipart/form-data".',  
149 - 'de' => 'Das HTML-Formular enth&auml;lt nicht die Angabe method="post" enctype="multipart/form-data" '.  
150 - 'im &gt;form&lt;-Tag.',  
151 - 'nl' => 'Het HTML-formulier bevat niet de volgende benodigde '.  
152 - 'eigenschappen: method="post" enctype="multipart/form-data".',  
153 - 'fr' => 'Le formulaire HTML ne contient pas les attributs requis : '.  
154 - ' method="post" enctype="multipart/form-data".',  
155 - 'it' => 'Il modulo HTML non contiene gli attributi richiesti: "'.  
156 - ' method="post" enctype="multipart/form-data".',  
157 - 'pt_BR' => 'O formul&aacute;rio HTML n&atilde;o possui o method="post" enctype="multipart/form-data" requerido.'  
158 - ),  
159 - 'E_FAIL_COPY' => array(  
160 - 'es' => 'Fallo al copiar el fichero temporal.',  
161 - 'en' => 'Failed to copy the temporary file.',  
162 - 'de' => 'Tempor&auml;re Datei konnte nicht kopiert werden.',  
163 - 'nl' => 'Het tijdelijke bestand kon niet gekopieerd worden.',  
164 - 'fr' => 'L\'enregistrement du fichier temporaire a &eacute;chou&eacute;.',  
165 - 'it' => 'Copia del file temporaneo fallita.',  
166 - 'pt_BR' => 'Falha ao copiar o arquivo tempor&aacute;rio.'  
167 - ),  
168 - 'E_FAIL_MOVE' => array(  
169 - 'es' => 'No puedo mover el fichero.',  
170 - 'en' => 'Impossible to move the file.',  
171 - 'de' => 'Datei kann nicht verschoben werden.',  
172 - 'nl' => 'Het bestand kon niet verplaatst worden.',  
173 - 'fr' => 'Impossible de d&eacute;placer le fichier.',  
174 - 'pt_BR' => 'N&atilde;o foi poss&iacute;vel mover o arquivo.'  
175 - ),  
176 - 'FILE_EXISTS' => array(  
177 - 'es' => 'El fichero destino ya existe.',  
178 - 'en' => 'The destination file already exists.',  
179 - 'de' => 'Die zu erzeugende Datei existiert bereits.',  
180 - 'nl' => 'Het doelbestand bestaat al.',  
181 - 'fr' => 'Le fichier de destination existe d&eacute;j&agrave;.',  
182 - 'it' => 'File destinazione gi&agrave; esistente.',  
183 - 'pt_BR' => 'O arquivo de destino j&aacute; existe.'  
184 - ),  
185 - 'CANNOT_OVERWRITE' => array(  
186 - 'es' => 'El fichero destino ya existe y no se puede sobreescribir.',  
187 - 'en' => 'The destination file already exists and could not be overwritten.',  
188 - 'de' => 'Die zu erzeugende Datei existiert bereits und konnte nicht &uuml;berschrieben werden.',  
189 - 'nl' => 'Het doelbestand bestaat al, en kon niet worden overschreven.',  
190 - 'fr' => 'Le fichier de destination existe d&eacute;j&agrave; et ne peux pas &ecirc;tre remplac&eacute;.',  
191 - 'it' => 'File destinazione gi&agrave; esistente e non si pu&ograve; sovrascrivere.',  
192 - 'pt_BR' => 'O arquivo de destino j&aacute; existe e n&atilde;o p&ocirc;de ser sobrescrito.'  
193 - ),  
194 - 'NOT_ALLOWED_EXTENSION' => array(  
195 - 'es' => 'Extension de fichero no permitida.',  
196 - 'en' => 'File extension not permitted.',  
197 - 'de' => 'Unerlaubte Dateiendung.',  
198 - 'nl' => 'Niet toegestane bestands-extensie.',  
199 - 'fr' => 'Le fichier a une extension non autoris&eacute;e.',  
200 - 'it' => 'Estensione del File non permessa.',  
201 - 'pt_BR' => 'Extens&atilde;o de arquivo n&atilde;o permitida.'  
202 - ),  
203 - 'PARTIAL' => array(  
204 - 'es' => 'El fichero fue parcialmente subido',  
205 - 'en' => 'The file was only partially uploaded.',  
206 - 'de' => 'Die Datei wurde unvollst&auml;ndig &uuml;bertragen.',  
207 - 'nl' => 'Het bestand is slechts gedeeltelijk geupload.',  
208 - 'pt_BR' => 'O arquivo nรฃo foi enviado por completo.'  
209 - ),  
210 - 'ERROR' => array(  
211 - 'es' => 'Error en subida:',  
212 - 'en' => 'Upload error:',  
213 - 'de' => 'Fehler beim Upload:',  
214 - 'nl' => 'Upload fout:',  
215 - 'pt_BR' => 'Erro de upload:'  
216 - ),  
217 - 'DEV_NO_DEF_FILE' => array(  
218 - 'es' => 'No estรก definido en el formulario este nombre de fichero como &lt;input type="file" name=?&gt;.',  
219 - 'en' => 'This filename is not defined in the form as &lt;input type="file" name=?&gt;.',  
220 - 'de' => 'Dieser Dateiname ist im Formular nicht als &lt;input type="file" name=?&gt; definiert.',  
221 - 'nl' => 'Deze bestandsnaam is niett gedefineerd in het formulier als &lt;input type="file" name=?&gt;.'  
222 - )  
223 - );  
224 - }  
225 -  
226 - /**  
227 - * returns the error code  
228 - *  
229 - * @param string $e_code type of error  
230 - * @return string Error message  
231 - */  
232 - function errorCode($e_code)  
233 - {  
234 - if (!empty($this->error_codes[$e_code][$this->lang])) {  
235 - $msg = $this->html ?  
236 - html_entity_decode($this->error_codes[$e_code][$this->lang]) :  
237 - $this->error_codes[$e_code][$this->lang];  
238 - } else {  
239 - $msg = $e_code;  
240 - }  
241 -  
242 - if (!empty($this->error_codes['ERROR'][$this->lang])) {  
243 - $error = $this->error_codes['ERROR'][$this->lang];  
244 - } else {  
245 - $error = $this->error_codes['ERROR']['en'];  
246 - }  
247 - return $error.' '.$msg;  
248 - }  
249 -  
250 - /**  
251 - * Overwrites the PEAR::raiseError method  
252 - *  
253 - * @param string $e_code type of error  
254 - * @return object PEAR_Error a PEAR-Error object  
255 - * @access public  
256 - */  
257 - function raiseError($e_code)  
258 - {  
259 - return PEAR::raiseError($this->errorCode($e_code), $e_code);  
260 - }  
261 -}  
262 -  
263 -/**  
264 - * This class provides an advanced file uploader system  
265 - * for file uploads made from html forms  
266 -  
267 - *  
268 - * @author Tomas V.V.Cox <cox@idecnet.com>  
269 - * @see http://vulcanonet.com/soft/index.php?pack=uploader  
270 - * @package HTTP_Upload  
271 - * @category HTTP  
272 - * @access public  
273 - */  
274 -class HTTP_Upload extends HTTP_Upload_Error  
275 -{  
276 - /**  
277 - * Contains an array of "uploaded files" objects  
278 - * @var array  
279 - */  
280 - var $files = array();  
281 -  
282 - /**  
283 - * Contains the desired chmod for uploaded files  
284 - * @var int  
285 - * @access private  
286 - */  
287 - var $_chmod = HTTP_UPLOAD_DEFAULT_CHMOD;  
288 -  
289 - /**  
290 - * Constructor  
291 - *  
292 - * @param string $lang Language to use for reporting errors  
293 - * @see Upload_Error::error_codes  
294 - * @access public  
295 - */  
296 - function HTTP_Upload($lang = null)  
297 - {  
298 - $this->HTTP_Upload_Error($lang);  
299 - if (function_exists('version_compare') &&  
300 - version_compare(phpversion(), '4.1', 'ge'))  
301 - {  
302 - $this->post_files = $_FILES;  
303 - if (isset($_SERVER['CONTENT_TYPE'])) {  
304 - $this->content_type = $_SERVER['CONTENT_TYPE'];  
305 - }  
306 - } else {  
307 - global $HTTP_POST_FILES, $HTTP_SERVER_VARS;  
308 - $this->post_files = $HTTP_POST_FILES;  
309 - if (isset($HTTP_SERVER_VARS['CONTENT_TYPE'])) {  
310 - $this->content_type = $HTTP_SERVER_VARS['CONTENT_TYPE'];  
311 - }  
312 - }  
313 - }  
314 -  
315 - /**  
316 - * Get files  
317 - *  
318 - * @param mixed $file If:  
319 - * - not given, function will return array of upload_file objects  
320 - * - is int, will return the $file position in upload_file objects array  
321 - * - is string, will return the upload_file object corresponding  
322 - * to $file name of the form. For ex:  
323 - * if form is <input type="file" name="userfile">  
324 - * to get this file use: $upload->getFiles('userfile')  
325 - *  
326 - * @return mixed array or object (see @param $file above) or Pear_Error  
327 - * @access public  
328 - */  
329 - function &getFiles($file = null)  
330 - {  
331 - static $is_built = false;  
332 - //build only once for multiple calls  
333 - if (!$is_built) {  
334 - $files = &$this->_buildFiles();  
335 - if (PEAR::isError($files)) {  
336 - // there was an error with the form.  
337 - // Create a faked upload embedding the error  
338 - $this->files['_error'] = &new HTTP_Upload_File(  
339 - '_error', null,  
340 - null, null,  
341 - null, $files->getCode(),  
342 - $this->lang, $this->_chmod);  
343 - } else {  
344 - $this->files = $files;  
345 - }  
346 - $is_built = true;  
347 - }  
348 - if ($file !== null) {  
349 - if (is_int($file)) {  
350 - $pos = 0;  
351 - foreach ($this->files as $obj) {  
352 - if ($pos == $file) {  
353 - return $obj;  
354 - }  
355 - $pos++;  
356 - }  
357 - } elseif (is_string($file) && isset($this->files[$file])) {  
358 - return $this->files[$file];  
359 - }  
360 - if (isset($this->files['_error'])) {  
361 - return $this->files['_error'];  
362 - } else {  
363 - // developer didn't specify this name in the form  
364 - // warn him about it with a faked upload  
365 - return new HTTP_Upload_File(  
366 - '_error', null,  
367 - null, null,  
368 - null, 'DEV_NO_DEF_FILE',  
369 - $this->lang);  
370 - }  
371 - }  
372 - return $this->files;  
373 - }  
374 -  
375 - /**  
376 - * Creates the list of the uploaded file  
377 - *  
378 - * @return array of HTTP_Upload_File objects for every file  
379 - */  
380 - function &_buildFiles()  
381 - {  
382 - // Form method check  
383 - if (!isset($this->content_type) ||  
384 - strpos($this->content_type, 'multipart/form-data') !== 0)  
385 - {  
386 - return $this->raiseError('BAD_FORM');  
387 - }  
388 - // In 4.1 $_FILES isn't initialized when no uploads  
389 - // XXX (cox) afaik, in >= 4.1 and <= 4.3 only  
390 - if (function_exists('version_compare') &&  
391 - version_compare(phpversion(), '4.1', 'ge'))  
392 - {  
393 - $error = $this->isMissing();  
394 - if (PEAR::isError($error)) {  
395 - return $error;  
396 - }  
397 - }  
398 -  
399 - // map error codes from 4.2.0 $_FILES['userfile']['error']  
400 - if (function_exists('version_compare') &&  
401 - version_compare(phpversion(), '4.2.0', 'ge')) {  
402 - $uploadError = array(  
403 - 1 => 'TOO_LARGE',  
404 - 2 => 'TOO_LARGE',  
405 - 3 => 'PARTIAL',  
406 - 4 => 'NO_USER_FILE'  
407 - );  
408 - }  
409 -  
410 -  
411 - // Parse $_FILES (or $HTTP_POST_FILES)  
412 - $files = array();  
413 - foreach ($this->post_files as $userfile => $value) {  
414 - if (is_array($value['name'])) {  
415 - foreach ($value['name'] as $key => $val) {  
416 - $err = $value['error'][$key];  
417 - if (isset($err) && $err !== 0 && isset($uploadError[$err])) {  
418 - $error = $uploadError[$err];  
419 - } else {  
420 - $error = null;  
421 - }  
422 - $name = basename($value['name'][$key]);  
423 - $tmp_name = $value['tmp_name'][$key];  
424 - $size = $value['size'][$key];  
425 - $type = $value['type'][$key];  
426 - $formname = $userfile . "[$key]";  
427 - $files[$formname] = new HTTP_Upload_File($name, $tmp_name,  
428 - $formname, $type, $size, $error, $this->lang, $this->_chmod);  
429 - }  
430 - // One file  
431 - } else {  
432 - $err = $value['error'];  
433 - if (isset($err) && $err !== 0 && isset($uploadError[$err])) {  
434 - $error = $uploadError[$err];  
435 - } else {  
436 - $error = null;  
437 - }  
438 - $name = basename($value['name']);  
439 - $tmp_name = $value['tmp_name'];  
440 - $size = $value['size'];  
441 - $type = $value['type'];  
442 - $formname = $userfile;  
443 - $files[$formname] = new HTTP_Upload_File($name, $tmp_name,  
444 - $formname, $type, $size, $error, $this->lang, $this->_chmod);  
445 - }  
446 - }  
447 - return $files;  
448 - }  
449 -  
450 - /**  
451 - * Checks if the user submited or not some file  
452 - *  
453 - * @return mixed False when are files or PEAR_Error when no files  
454 - * @access public  
455 - * @see Read the note in the source code about this function  
456 - */  
457 - function isMissing()  
458 - {  
459 - if (count($this->post_files) < 1) {  
460 - return $this->raiseError('NO_USER_FILE');  
461 - }  
462 - //we also check if at least one file has more than 0 bytes :)  
463 - $files = array();  
464 - $size = 0;  
465 - foreach ($this->post_files as $userfile => $value) {  
466 - if (is_array($value['name'])) {  
467 - foreach ($value['name'] as $key => $val) {  
468 - $size += $value['size'][$key];  
469 - }  
470 - } else { //one file  
471 - $size = $value['size'];  
472 - }  
473 - }  
474 - if ($size == 0) {  
475 - $this->raiseError('NO_USER_FILE');  
476 - }  
477 - return false;  
478 - }  
479 -  
480 - /**  
481 - * Sets the chmod to be used for uploaded files  
482 - *  
483 - * @param int Desired mode  
484 - */  
485 - function setChmod($mode)  
486 - {  
487 - $this->_chmod = $mode;  
488 - }  
489 -}  
490 -  
491 -/**  
492 - * This class provides functions to work with the uploaded file  
493 - *  
494 - * @author Tomas V.V.Cox <cox@idecnet.com>  
495 - * @see http://vulcanonet.com/soft/index.php?pack=uploader  
496 - * @package HTTP_Upload  
497 - * @category HTTP  
498 - * @access public  
499 - */  
500 -class HTTP_Upload_File extends HTTP_Upload_Error  
501 -{  
502 - /**  
503 - * If the random seed was initialized before or not  
504 - * @var boolean;  
505 - */  
506 - var $_seeded = 0;  
507 -  
508 - /**  
509 - * Assoc array with file properties  
510 - * @var array  
511 - */  
512 - var $upload = array();  
513 -  
514 - /**  
515 - * If user haven't selected a mode, by default 'safe' will be used  
516 - * @var boolean  
517 - */  
518 - var $mode_name_selected = false;  
519 -  
520 - /**  
521 - * It's a common security risk in pages who has the upload dir  
522 - * under the document root (remember the hack of the Apache web?)  
523 - *  
524 - * @var array  
525 - * @access private  
526 - * @see HTTP_Upload_File::setValidExtensions()  
527 - */  
528 - var $_extensions_check = array('php', 'phtm', 'phtml', 'php3', 'inc');  
529 -  
530 - /**  
531 - * @see HTTP_Upload_File::setValidExtensions()  
532 - * @var string  
533 - * @access private  
534 - */  
535 - var $_extensions_mode = 'deny';  
536 -  
537 - /**  
538 - * Contains the desired chmod for uploaded files  
539 - * @var int  
540 - * @access private  
541 - */  
542 - var $_chmod = HTTP_UPLOAD_DEFAULT_CHMOD;  
543 -  
544 - /**  
545 - * Constructor  
546 - *  
547 - * @param string $name destination file name  
548 - * @param string $tmp temp file name  
549 - * @param string $formname name of the form  
550 - * @param string $type Mime type of the file  
551 - * @param string $size size of the file  
552 - * @param string $error error on upload  
553 - * @param string $lang used language for errormessages  
554 - * @access public  
555 - */  
556 - function HTTP_Upload_File($name = null, $tmp = null, $formname = null,  
557 - $type = null, $size = null, $error = null,  
558 - $lang = null, $chmod = HTTP_UPLOAD_DEFAULT_CHMOD)  
559 - {  
560 - $this->HTTP_Upload_Error($lang);  
561 - $ext = null;  
562 -  
563 - if (empty($name) || $size == 0) {  
564 - $error = 'NO_USER_FILE';  
565 - } elseif ($tmp == 'none') {  
566 - $error = 'TOO_LARGE';  
567 - } else {  
568 - // strpos needed to detect files without extension  
569 - if (($pos = strrpos($name, '.')) !== false) {  
570 - $ext = substr($name, $pos + 1);  
571 - }  
572 - }  
573 -  
574 - if (function_exists('version_compare') &&  
575 - version_compare(phpversion(), '4.1', 'ge')) {  
576 - if (isset($_POST['MAX_FILE_SIZE']) &&  
577 - $size > $_POST['MAX_FILE_SIZE']) {  
578 - $error = 'TOO_LARGE';  
579 - }  
580 - } else {  
581 - global $HTTP_POST_VARS;  
582 - if (isset($HTTP_POST_VARS['MAX_FILE_SIZE']) &&  
583 - $size > $HTTP_POST_VARS['MAX_FILE_SIZE']) {  
584 - $error = 'TOO_LARGE';  
585 - }  
586 - }  
587 -  
588 - $this->upload = array(  
589 - 'real' => $name,  
590 - 'name' => $name,  
591 - 'form_name' => $formname,  
592 - 'ext' => $ext,  
593 - 'tmp_name' => $tmp,  
594 - 'size' => $size,  
595 - 'type' => $type,  
596 - 'error' => $error  
597 - );  
598 -  
599 - $this->_chmod = $chmod;  
600 - }  
601 -  
602 - /**  
603 - * Sets the name of the destination file  
604 - *  
605 - * @param string $mode A valid mode: 'uniq', 'safe' or 'real' or a file name  
606 - * @param string $prepend A string to prepend to the name  
607 - * @param string $append A string to append to the name  
608 - *  
609 - * @return string The modified name of the destination file  
610 - * @access public  
611 - */  
612 - function setName($mode, $prepend = null, $append = null)  
613 - {  
614 - switch ($mode) {  
615 - case 'uniq':  
616 - $name = $this->nameToUniq();  
617 - $this->upload['ext'] = $this->nameToSafe($this->upload['ext'], 10);  
618 - $name .= '.' . $this->upload['ext'];  
619 - break;  
620 - case 'safe':  
621 - $name = $this->nameToSafe($this->upload['real']);  
622 - if (($pos = strrpos($name, '.')) !== false) {  
623 - $this->upload['ext'] = substr($name, $pos + 1);  
624 - } else {  
625 - $this->upload['ext'] = '';  
626 - }  
627 - break;  
628 - case 'real':  
629 - $name = $this->upload['real'];  
630 - break;  
631 - default:  
632 - $name = $mode;  
633 - }  
634 - $this->upload['name'] = $prepend . $name . $append;  
635 - $this->mode_name_selected = true;  
636 - return $this->upload['name'];  
637 - }  
638 -  
639 - /**  
640 - * Unique file names in the form: 9022210413b75410c28bef.html  
641 - * @see HTTP_Upload_File::setName()  
642 - */  
643 - function nameToUniq()  
644 - {  
645 - if (! $this->_seeded) {  
646 - srand((double) microtime() * 1000000);  
647 - $this->_seeded = 1;  
648 - }  
649 - $uniq = uniqid(rand());  
650 - return $uniq;  
651 - }  
652 -  
653 - /**  
654 - * Format a file name to be safe  
655 - *  
656 - * @param string $file The string file name  
657 - * @param int $maxlen Maximun permited string lenght  
658 - * @return string Formatted file name  
659 - * @see HTTP_Upload_File::setName()  
660 - */  
661 - function nameToSafe($name, $maxlen=250)  
662 - {  
663 - $noalpha = 'รร‰รร“รšรรกรฉรญรณรบรฝร‚รŠรŽร”ร›รขรชรฎรดรปร€รˆรŒร’ร™ร รจรฌรฒรนร„ร‹รร–รœรครซรฏรถรผรฟรƒรฃร•รตร…รฅร‘รฑร‡รง@ยฐยบยช';  
664 - $alpha = 'AEIOUYaeiouyAEIOUaeiouAEIOUaeiouAEIOUaeiouyAaOoAaNnCcaooa';  
665 -  
666 - $name = substr($name, 0, $maxlen);  
667 - $name = strtr($name, $noalpha, $alpha);  
668 - // not permitted chars are replaced with "_"  
669 - return preg_replace('/[^a-zA-Z0-9,._\+\()\-]/', '_', $name);  
670 - }  
671 -  
672 - /**  
673 - * The upload was valid  
674 - *  
675 - * @return bool If the file was submitted correctly  
676 - * @access public  
677 - */  
678 - function isValid()  
679 - {  
680 - if ($this->upload['error'] === null) {  
681 - return true;  
682 - }  
683 - return false;  
684 - }  
685 -  
686 - /**  
687 - * User haven't submit a file  
688 - *  
689 - * @return bool If the user submitted a file or not  
690 - * @access public  
691 - */  
692 - function isMissing()  
693 - {  
694 - if ($this->upload['error'] == 'NO_USER_FILE') {  
695 - return true;  
696 - }  
697 - return false;  
698 - }  
699 -  
700 - /**  
701 - * Some error occured during upload (most common due a file size problem,  
702 - * like max size exceeded or 0 bytes long).  
703 - * @return bool If there were errors submitting the file (probably  
704 - * because the file excess the max permitted file size)  
705 - * @access public  
706 - */  
707 - function isError()  
708 - {  
709 - if (in_array($this->upload['error'], array('TOO_LARGE', 'BAD_FORM','DEV_NO_DEF_FILE'))) {  
710 - return true;  
711 - }  
712 - return false;  
713 - }  
714 -  
715 - /**  
716 - * Moves the uploaded file to its destination directory.  
717 - *  
718 - * @param string $dir_dest Destination directory  
719 - * @param bool $overwrite Overwrite if destination file exists?  
720 - * @return mixed True on success or Pear_Error object on error  
721 - * @access public  
722 - */  
723 - function moveTo($dir_dest, $overwrite = true)  
724 - {  
725 - if (!$this->isValid()) {  
726 - return $this->raiseError($this->upload['error']);  
727 - }  
728 -  
729 - //Valid extensions check  
730 - if (!$this->_evalValidExtensions()) {  
731 - return $this->raiseError('NOT_ALLOWED_EXTENSION');  
732 - }  
733 -  
734 - $err_code = $this->_chk_dir_dest($dir_dest);  
735 - if ($err_code !== false) {  
736 - return $this->raiseError($err_code);  
737 - }  
738 - // Use 'safe' mode by default if no other was selected  
739 - if (!$this->mode_name_selected) {  
740 - $this->setName('safe');  
741 - }  
742 -  
743 - $name_dest = $dir_dest . DIRECTORY_SEPARATOR . $this->upload['name'];  
744 -  
745 - if (@is_file($name_dest)) {  
746 - if ($overwrite !== true) {  
747 - return $this->raiseError('FILE_EXISTS');  
748 - } elseif (!is_writable($name_dest)) {  
749 - return $this->raiseError('CANNOT_OVERWRITE');  
750 - }  
751 - }  
752 -  
753 - // copy the file and let php clean the tmp  
754 - if (!@move_uploaded_file($this->upload['tmp_name'], $name_dest)) {  
755 - return $this->raiseError('E_FAIL_MOVE');  
756 - }  
757 - @chmod($name_dest, $this->_chmod);  
758 - return $this->getProp('name');  
759 - }  
760 -  
761 - /**  
762 - * Check for a valid destination dir  
763 - *  
764 - * @param string $dir_dest Destination dir  
765 - * @return mixed False on no errors or error code on error  
766 - */  
767 - function _chk_dir_dest($dir_dest)  
768 - {  
769 - if (!$dir_dest) {  
770 - return 'MISSING_DIR';  
771 - }  
772 - if (!@is_dir ($dir_dest)) {  
773 - return 'IS_NOT_DIR';  
774 - }  
775 - if (!is_writeable ($dir_dest)) {  
776 - return 'NO_WRITE_PERMS';  
777 - }  
778 - return false;  
779 - }  
780 - /**  
781 - * Retrive properties of the uploaded file  
782 - * @param string $name The property name. When null an assoc array with  
783 - * all the properties will be returned  
784 - * @return mixed A string or array  
785 - * @see HTTP_Upload_File::HTTP_Upload_File()  
786 - * @access public  
787 - */  
788 - function getProp($name = null)  
789 - {  
790 - if ($name === null) {  
791 - return $this->upload;  
792 - }  
793 - return $this->upload[$name];  
794 - }  
795 -  
796 - /**  
797 - * Returns a error message, if a error occured  
798 - * (deprecated) Use getMessage() instead  
799 - * @return string a Error message  
800 - * @access public  
801 - */  
802 - function errorMsg()  
803 - {  
804 - return $this->errorCode($this->upload['error']);  
805 - }  
806 -  
807 - /**  
808 - * Returns a error message, if a error occured  
809 - * @return string a Error message  
810 - * @access public  
811 - */  
812 - function getMessage()  
813 - {  
814 - return $this->errorCode($this->upload['error']);  
815 - }  
816 -  
817 - /**  
818 - * Function to restrict the valid extensions on file uploads  
819 - *  
820 - * @param array $exts File extensions to validate  
821 - * @param string $mode The type of validation:  
822 - * 1) 'deny' Will deny only the supplied extensions  
823 - * 2) 'accept' Will accept only the supplied extensions  
824 - * as valid  
825 - * @access public  
826 - */  
827 - function setValidExtensions($exts, $mode = 'deny')  
828 - {  
829 - $this->_extensions_check = $exts;  
830 - $this->_extensions_mode = $mode;  
831 - }  
832 -  
833 - /**  
834 - * Evaluates the validity of the extensions set by setValidExtensions  
835 - *  
836 - * @return bool False on non valid extension, true if they are valid  
837 - * @access private  
838 - */  
839 - function _evalValidExtensions()  
840 - {  
841 - $exts = $this->_extensions_check;  
842 - settype($exts, 'array');  
843 - if ($this->_extensions_mode == 'deny') {  
844 - if (in_array($this->getProp('ext'), $exts)) {  
845 - return false;  
846 - }  
847 - // mode == 'accept'  
848 - } else {  
849 - if (!in_array($this->getProp('ext'), $exts)) {  
850 - return false;  
851 - }  
852 - }  
853 - return true;  
854 - }  
855 -}  
856 -?>  
857 \ No newline at end of file 0 \ No newline at end of file