/** * Get an appropriate backend object from a storage path * * @param string $storagePath * @return FileBackend|null Backend or null on failure */ public function backendFromPath($storagePath) { list($backend, , ) = FileBackend::splitStoragePath($storagePath); if ($backend !== null && isset($this->backends[$backend])) { return $this->get($backend); } return null; }
/** * Translate legacy "title" paths to their "sha1" counterparts * * E.g. mwstore://local-backend/local-public/a/ab/<name>.jpg * => mwstore://local-backend/local-original/x/y/z/<sha1>.jpg * * @param array $paths * @param bool $latest * @return array Translated paths in same order */ public function getBackendPaths(array $paths, $latest = true) { $db = $this->getDB($latest ? DB_MASTER : DB_SLAVE); $origBasePath = $this->backend->getContainerStoragePath("{$this->repoName}-original"); // @TODO: batching $resolved = array(); foreach ($paths as $i => $path) { if (!$latest && $this->resolvedPathCache->has($path, 'target', 10)) { $resolved[$i] = $this->resolvedPathCache->get($path, 'target'); continue; } list(, $container, $rel) = FileBackend::splitStoragePath($path); if ($container === "{$this->repoName}-public") { $name = basename($path); if (strpos($path, '!') !== false) { $sha1 = $db->selectField('oldimage', 'oi_sha1', array('oi_archive_name' => $name), __METHOD__); } else { $sha1 = $db->selectField('image', 'img_sha1', array('img_name' => $name), __METHOD__); } if (!strlen($sha1)) { $resolved[$i] = $path; // give up continue; } $resolved[$i] = $this->getPathForSHA1($sha1); $this->resolvedPathCache->set($path, 'target', $resolved[$i]); } elseif ($container === "{$this->repoName}-deleted") { $name = basename($path); // <hash>.<ext> $sha1 = substr($name, 0, strpos($name, '.')); // ignore extension $resolved[$i] = $this->getPathForSHA1($sha1); $this->resolvedPathCache->set($path, 'target', $resolved[$i]); } else { $resolved[$i] = $path; } } $res = array(); foreach ($paths as $i => $path) { $res[$i] = $resolved[$i]; } return $res; }
/** * Creates a directory with the appropriate zone permissions. * Callers are responsible for doing read-only and "writable repo" checks. * * @param string $dir Virtual URL (or storage path) of directory to clean * @return Status */ protected function initDirectory($dir) { $path = $this->resolveToStoragePath($dir); list(, $container, ) = FileBackend::splitStoragePath($path); $params = array('dir' => $path); if ($this->isPrivate || $container === $this->zones['deleted']['container']) { # Take all available measures to prevent web accessibility of new deleted # directories, in case the user has not configured offline storage $params = array('noAccess' => true, 'noListing' => true) + $params; } return $this->backend->prepare($params); }
/** * @dataProvider provider_testSplitStoragePath */ public function testSplitStoragePath($path, $res) { $this->assertEquals($res, FileBackend::splitStoragePath($path), "FileBackend::splitStoragePath on path '{$path}'"); }
/** * @see FileBackendStore::getFileListInternal() * @param string $fullCont * @param string $dirRel * @param array $params * @return array|FSFileBackendFileList|null */ public function getFileListInternal($fullCont, $dirRel, array $params) { list(, $shortCont, ) = FileBackend::splitStoragePath($params['dir']); $contRoot = $this->containerFSRoot($shortCont, $fullCont); // must be valid $dir = $dirRel != '' ? "{$contRoot}/{$dirRel}" : $contRoot; $exists = is_dir($dir); if (!$exists) { wfDebug(__METHOD__ . "() given directory does not exist: '{$dir}'\n"); return array(); // nothing under this dir } elseif (!is_readable($dir)) { wfDebug(__METHOD__ . "() given directory is unreadable: '{$dir}'\n"); return null; // bad permissions? } return new FSFileBackendFileList($dir, $params); }