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