1<?php 2 3namespace Sabre\DAV\FSExt; 4 5use Sabre\DAV; 6use Sabre\DAV\FS\Node; 7 8/** 9 * Directory 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 */ 15class Directory extends Node implements DAV\ICollection, DAV\IQuota, DAV\IMoveTarget { 16 17 /** 18 * Creates a new file in the directory 19 * 20 * Data will either be supplied as a stream resource, or in certain cases 21 * as a string. Keep in mind that you may have to support either. 22 * 23 * After successful creation of the file, you may choose to return the ETag 24 * of the new file here. 25 * 26 * The returned ETag must be surrounded by double-quotes (The quotes should 27 * be part of the actual string). 28 * 29 * If you cannot accurately determine the ETag, you should not return it. 30 * If you don't store the file exactly as-is (you're transforming it 31 * somehow) you should also not return an ETag. 32 * 33 * This means that if a subsequent GET to this new file does not exactly 34 * return the same contents of what was submitted here, you are strongly 35 * recommended to omit the ETag. 36 * 37 * @param string $name Name of the file 38 * @param resource|string $data Initial payload 39 * @return null|string 40 */ 41 function createFile($name, $data = null) { 42 43 // We're not allowing dots 44 if ($name == '.' || $name == '..') throw new DAV\Exception\Forbidden('Permission denied to . and ..'); 45 $newPath = $this->path . '/' . $name; 46 file_put_contents($newPath, $data); 47 clearstatcache(true, $newPath); 48 49 return '"' . sha1( 50 fileinode($newPath) . 51 filesize($newPath) . 52 filemtime($newPath) 53 ) . '"'; 54 55 } 56 57 /** 58 * Creates a new subdirectory 59 * 60 * @param string $name 61 * @return void 62 */ 63 function createDirectory($name) { 64 65 // We're not allowing dots 66 if ($name == '.' || $name == '..') throw new DAV\Exception\Forbidden('Permission denied to . and ..'); 67 $newPath = $this->path . '/' . $name; 68 mkdir($newPath); 69 clearstatcache(true, $newPath); 70 71 } 72 73 /** 74 * Returns a specific child node, referenced by its name 75 * 76 * This method must throw Sabre\DAV\Exception\NotFound if the node does not 77 * exist. 78 * 79 * @param string $name 80 * @throws DAV\Exception\NotFound 81 * @return DAV\INode 82 */ 83 function getChild($name) { 84 85 $path = $this->path . '/' . $name; 86 87 if (!file_exists($path)) throw new DAV\Exception\NotFound('File could not be located'); 88 if ($name == '.' || $name == '..') throw new DAV\Exception\Forbidden('Permission denied to . and ..'); 89 90 if (is_dir($path)) { 91 92 return new self($path); 93 94 } else { 95 96 return new File($path); 97 98 } 99 100 } 101 102 /** 103 * Checks if a child exists. 104 * 105 * @param string $name 106 * @return bool 107 */ 108 function childExists($name) { 109 110 if ($name == '.' || $name == '..') 111 throw new DAV\Exception\Forbidden('Permission denied to . and ..'); 112 113 $path = $this->path . '/' . $name; 114 return file_exists($path); 115 116 } 117 118 /** 119 * Returns an array with all the child nodes 120 * 121 * @return DAV\INode[] 122 */ 123 function getChildren() { 124 125 $nodes = []; 126 $iterator = new \FilesystemIterator( 127 $this->path, 128 \FilesystemIterator::CURRENT_AS_SELF 129 | \FilesystemIterator::SKIP_DOTS 130 ); 131 132 foreach ($iterator as $entry) { 133 134 $node = $entry->getFilename(); 135 136 if ($node === '.sabredav') 137 continue; 138 139 $nodes[] = $this->getChild($node); 140 141 } 142 return $nodes; 143 144 } 145 146 /** 147 * Deletes all files in this directory, and then itself 148 * 149 * @return bool 150 */ 151 function delete() { 152 153 // Deleting all children 154 foreach ($this->getChildren() as $child) $child->delete(); 155 156 // Removing resource info, if its still around 157 if (file_exists($this->path . '/.sabredav')) unlink($this->path . '/.sabredav'); 158 159 // Removing the directory itself 160 rmdir($this->path); 161 162 return true; 163 164 } 165 166 /** 167 * Returns available diskspace information 168 * 169 * @return array 170 */ 171 function getQuotaInfo() { 172 173 $total = disk_total_space(realpath($this->path)); 174 $free = disk_free_space(realpath($this->path)); 175 176 return [ 177 $total - $free, 178 $free 179 ]; 180 } 181 182 /** 183 * Moves a node into this collection. 184 * 185 * It is up to the implementors to: 186 * 1. Create the new resource. 187 * 2. Remove the old resource. 188 * 3. Transfer any properties or other data. 189 * 190 * Generally you should make very sure that your collection can easily move 191 * the move. 192 * 193 * If you don't, just return false, which will trigger sabre/dav to handle 194 * the move itself. If you return true from this function, the assumption 195 * is that the move was successful. 196 * 197 * @param string $targetName New local file/collection name. 198 * @param string $sourcePath Full path to source node 199 * @param DAV\INode $sourceNode Source node itself 200 * @return bool 201 */ 202 function moveInto($targetName, $sourcePath, DAV\INode $sourceNode) { 203 204 // We only support FSExt\Directory or FSExt\File objects, so 205 // anything else we want to quickly reject. 206 if (!$sourceNode instanceof self && !$sourceNode instanceof File) { 207 return false; 208 } 209 210 // PHP allows us to access protected properties from other objects, as 211 // long as they are defined in a class that has a shared inheritence 212 // with the current class. 213 rename($sourceNode->path, $this->path . '/' . $targetName); 214 215 return true; 216 217 } 218 219} 220