1<?php 2 3namespace Sabre\DAV\FSExt; 4 5use Sabre\DAV; 6use Sabre\DAV\FS\Node; 7 8/** 9 * File class 10 * 11 * @copyright Copyright (C) fruux GmbH (https://fruux.com/) 12 * @author Evert Pot (http://evertpot.com/) 13 * @license http://sabre.io/license/ Modified BSD License 14 */ 15class File extends Node implements DAV\PartialUpdate\IPatchSupport { 16 17 /** 18 * Updates the data 19 * 20 * Data is a readable stream resource. 21 * 22 * @param resource|string $data 23 * @return string 24 */ 25 function put($data) { 26 27 file_put_contents($this->path, $data); 28 clearstatcache(true, $this->path); 29 return $this->getETag(); 30 31 } 32 33 /** 34 * Updates the file based on a range specification. 35 * 36 * The first argument is the data, which is either a readable stream 37 * resource or a string. 38 * 39 * The second argument is the type of update we're doing. 40 * This is either: 41 * * 1. append 42 * * 2. update based on a start byte 43 * * 3. update based on an end byte 44 *; 45 * The third argument is the start or end byte. 46 * 47 * After a successful put operation, you may choose to return an ETag. The 48 * ETAG must always be surrounded by double-quotes. These quotes must 49 * appear in the actual string you're returning. 50 * 51 * Clients may use the ETag from a PUT request to later on make sure that 52 * when they update the file, the contents haven't changed in the mean 53 * time. 54 * 55 * @param resource|string $data 56 * @param int $rangeType 57 * @param int $offset 58 * @return string|null 59 */ 60 function patch($data, $rangeType, $offset = null) { 61 62 switch ($rangeType) { 63 case 1 : 64 $f = fopen($this->path, 'a'); 65 break; 66 case 2 : 67 $f = fopen($this->path, 'c'); 68 fseek($f, $offset); 69 break; 70 case 3 : 71 $f = fopen($this->path, 'c'); 72 fseek($f, $offset, SEEK_END); 73 break; 74 } 75 if (is_string($data)) { 76 fwrite($f, $data); 77 } else { 78 stream_copy_to_stream($data, $f); 79 } 80 fclose($f); 81 clearstatcache(true, $this->path); 82 return $this->getETag(); 83 84 } 85 86 /** 87 * Returns the data 88 * 89 * @return resource 90 */ 91 function get() { 92 93 return fopen($this->path, 'r'); 94 95 } 96 97 /** 98 * Delete the current file 99 * 100 * @return bool 101 */ 102 function delete() { 103 104 return unlink($this->path); 105 106 } 107 108 /** 109 * Returns the ETag for a file 110 * 111 * An ETag is a unique identifier representing the current version of the file. If the file changes, the ETag MUST change. 112 * The ETag is an arbitrary string, but MUST be surrounded by double-quotes. 113 * 114 * Return null if the ETag can not effectively be determined 115 * 116 * @return string|null 117 */ 118 function getETag() { 119 120 return '"' . sha1( 121 fileinode($this->path) . 122 filesize($this->path) . 123 filemtime($this->path) 124 ) . '"'; 125 126 } 127 128 /** 129 * Returns the mime-type for a file 130 * 131 * If null is returned, we'll assume application/octet-stream 132 * 133 * @return string|null 134 */ 135 function getContentType() { 136 137 return null; 138 139 } 140 141 /** 142 * Returns the size of the file, in bytes 143 * 144 * @return int 145 */ 146 function getSize() { 147 148 return filesize($this->path); 149 150 } 151 152} 153