1 <?php
2 
3 namespace Sabre\DAV\FSExt;
4 
5 use Sabre\DAV;
6 use Sabre\DAV\FS\Node;
7 
8 /**
9  * File class
10  *
11  * @copyright Copyright (C) 2007-2015 fruux GmbH (https://fruux.com/).
12  * @author Evert Pot (http://evertpot.com/)
13  * @license http://sabre.io/license/ Modified BSD License
14  */
15 class 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