dirpath = $dirpath; } /** * Safely convert a store key to a file path. */ function _keyToPath($key) { // Figure out the filesystem root path and the path for the desired key. $root_path = realpath($this->dirpath); $path = realpath($this->dirpath.$key); // Ensure the resolved path is within the data directory. if (!startsWith($path, $root_path)) throw new Exception("Invalid key, resolves to outside allowed file path: $path."); return $path; } /** * Return a record of metadata for this key; */ function getMeta($key) { // Return FALSE for non-existent keys. if (!$this->isCollection($key) && !$this->isResource($key)) { return FALSE; } // Force collection keys to have trailing slash. if ($this->isCollection($key) && !endsWith($key, "/")) { $key = $key."/"; } // Gather metadata and return the structure. $path = $this->_keyToPath($key); $stat = stat($path); $puid = posix_getpwuid($stat['uid']); $meta = array( 'key' => $key, 'is_collection' => is_dir($path), 'owner' => $puid['name'], 'mtime' => $stat['mtime'], 'size' => $stat['size'] ); return $meta; } /** * Fetch the contents of a file, return it. */ function get($key) { $path = $this->_keyToPath($key); return file_get_contents($path); } /** * Write data to file. */ function put($key, $data) { $path = $this->_keyToPath($key); $base = dirname($path); $name = basename($path); if (!is_dir($base)) $this->MakeDirectory($base); if ($this->SAVE_BACKUPS) file_put_contents($base."/backups/$name-".date('Ymd-His'), $data); return file_put_contents($path, $data); } function MakeDirectory($dir, $mode = 0755) { if (is_dir($dir) || @mkdir($dir,$mode)) return TRUE; if (!MakeDirectory(dirname($dir),$mode)) return FALSE; return @mkdir($dir,$mode); } /** * Delete a given key. */ function delete($key) { if ($this->isCollection($key)) return FALSE; $path = $this->_keyToPath($key); return unlink($path); } /** * Given a key, return an array of contents. */ function listCollection($key) { // Ensure the key ends with a slash. if (!endsWith($key, "/")) { $key = $key."/"; } // Don't attempt to list if this isn't a collection if (!$this->isCollection($key)) { return false; } // Grab a handle on the directory holding the collection. $path = $this->_keyToPath($key); $d = dir($path); // Iterate through all the directory entries to collect items. $items = array(); while (false !== ($e = $d->read())) { // Skip the '.' and '..' directories. if ($e=='.' || $e=='..') continue; // Skip files starting with '.' if (substr($e, 0, 1) == '.') continue; // Push this collection item onto the pile. array_push($items, $this->getMeta($key.$e)); } return $items; } /** * Return whether a given key is a collection. */ function isCollection($key) { return is_dir($this->_keyToPath($key)); } /** * Return whether a given key is a single resource. */ function isResource($key) { return is_file($this->_keyToPath($key)); } } ?>