diff options
Diffstat (limited to 'lib/private/files/mapper.php')
-rw-r--r-- | lib/private/files/mapper.php | 305 |
1 files changed, 0 insertions, 305 deletions
diff --git a/lib/private/files/mapper.php b/lib/private/files/mapper.php deleted file mode 100644 index 2c8760ba40e..00000000000 --- a/lib/private/files/mapper.php +++ /dev/null @@ -1,305 +0,0 @@ -<?php -/** - * @author infoneo <infoneo@yahoo.pl> - * @author Joas Schilling <nickvergessen@owncloud.com> - * @author Jörn Friedrich Dreyer <jfd@butonic.de> - * @author Lukas Reschke <lukas@owncloud.com> - * @author Robin McCorkell <rmccorkell@karoshi.org.uk> - * @author Thomas Müller <thomas.mueller@tmit.eu> - * - * @copyright Copyright (c) 2015, ownCloud, Inc. - * @license AGPL-3.0 - * - * This code is free software: you can redistribute it and/or modify - * it under the terms of the GNU Affero General Public License, version 3, - * as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Affero General Public License for more details. - * - * You should have received a copy of the GNU Affero General Public License, version 3, - * along with this program. If not, see <http://www.gnu.org/licenses/> - * - */ -namespace OC\Files; - -/** - * class Mapper is responsible to translate logical paths to physical paths and reverse - */ -class Mapper -{ - private $unchangedPhysicalRoot; - - public function __construct($rootDir) { - $this->unchangedPhysicalRoot = $rootDir; - } - - /** - * @param string $logicPath - * @param bool $create indicates if the generated physical name shall be stored in the database or not - * @return string the physical path - */ - public function logicToPhysical($logicPath, $create) { - $physicalPath = $this->resolveLogicPath($logicPath); - if ($physicalPath !== null) { - return $physicalPath; - } - - return $this->create($logicPath, $create); - } - - /** - * @param string $physicalPath - * @return string - */ - public function physicalToLogic($physicalPath) { - $logicPath = $this->resolvePhysicalPath($physicalPath); - if ($logicPath !== null) { - return $logicPath; - } - - $this->insert($physicalPath, $physicalPath); - return $physicalPath; - } - - /** - * @param string $path - * @param bool $isLogicPath indicates if $path is logical or physical - * @param boolean $recursive - * @return void - */ - public function removePath($path, $isLogicPath, $recursive) { - if ($recursive) { - $path=$path.'%'; - } - - if ($isLogicPath) { - \OC_DB::executeAudited('DELETE FROM `*PREFIX*file_map` WHERE `logic_path` LIKE ?', array($path)); - } else { - \OC_DB::executeAudited('DELETE FROM `*PREFIX*file_map` WHERE `physic_path` LIKE ?', array($path)); - } - } - - /** - * @param string $path1 - * @param string $path2 - * @throws \Exception - */ - public function copy($path1, $path2) - { - $path1 = $this->resolveRelativePath($path1); - $path2 = $this->resolveRelativePath($path2); - $physicPath1 = $this->logicToPhysical($path1, true); - $physicPath2 = $this->logicToPhysical($path2, true); - - $sql = 'SELECT * FROM `*PREFIX*file_map` WHERE `logic_path` LIKE ?'; - $result = \OC_DB::executeAudited($sql, array($path1.'%')); - $updateQuery = \OC_DB::prepare('UPDATE `*PREFIX*file_map`' - .' SET `logic_path` = ?' - .' , `logic_path_hash` = ?' - .' , `physic_path` = ?' - .' , `physic_path_hash` = ?' - .' WHERE `logic_path` = ?'); - while( $row = $result->fetchRow()) { - $currentLogic = $row['logic_path']; - $currentPhysic = $row['physic_path']; - $newLogic = $path2.$this->stripRootFolder($currentLogic, $path1); - $newPhysic = $physicPath2.$this->stripRootFolder($currentPhysic, $physicPath1); - if ($path1 !== $currentLogic) { - try { - \OC_DB::executeAudited($updateQuery, array($newLogic, md5($newLogic), $newPhysic, md5($newPhysic), - $currentLogic)); - } catch (\Exception $e) { - error_log('Mapper::Copy failed '.$currentLogic.' -> '.$newLogic.'\n'.$e); - throw $e; - } - } - } - } - - /** - * @param string $path - * @param string $root - * @return false|string - */ - public function stripRootFolder($path, $root) { - if (strpos($path, $root) !== 0) { - // throw exception ??? - return false; - } - if (strlen($path) > strlen($root)) { - return substr($path, strlen($root)); - } - - return ''; - } - - /** - * @param string $logicPath - * @return null - * @throws \OC\DatabaseException - */ - private function resolveLogicPath($logicPath) { - $logicPath = $this->resolveRelativePath($logicPath); - $sql = 'SELECT * FROM `*PREFIX*file_map` WHERE `logic_path_hash` = ?'; - $result = \OC_DB::executeAudited($sql, array(md5($logicPath))); - $result = $result->fetchRow(); - if ($result === false) { - return null; - } - - return $result['physic_path']; - } - - private function resolvePhysicalPath($physicalPath) { - $physicalPath = $this->resolveRelativePath($physicalPath); - $sql = \OC_DB::prepare('SELECT * FROM `*PREFIX*file_map` WHERE `physic_path_hash` = ?'); - $result = \OC_DB::executeAudited($sql, array(md5($physicalPath))); - $result = $result->fetchRow(); - - return $result['logic_path']; - } - - private function resolveRelativePath($path) { - $explodedPath = explode('/', $path); - $pathArray = array(); - foreach ($explodedPath as $pathElement) { - if (empty($pathElement) || ($pathElement == '.')) { - continue; - } elseif ($pathElement == '..') { - if (count($pathArray) == 0) { - return false; - } - array_pop($pathArray); - } else { - array_push($pathArray, $pathElement); - } - } - if (substr($path, 0, 1) == '/') { - $path = '/'; - } else { - $path = ''; - } - return $path.implode('/', $pathArray); - } - - /** - * @param string $logicPath - * @param bool $store - * @return string - */ - private function create($logicPath, $store) { - $logicPath = $this->resolveRelativePath($logicPath); - $index = 0; - - // create the slugified path - $physicalPath = $this->slugifyPath($logicPath); - - // detect duplicates - while ($this->resolvePhysicalPath($physicalPath) !== null) { - $physicalPath = $this->slugifyPath($logicPath, $index++); - } - - // insert the new path mapping if requested - if ($store) { - $this->insert($logicPath, $physicalPath); - } - - return $physicalPath; - } - - private function insert($logicPath, $physicalPath) { - $sql = 'INSERT INTO `*PREFIX*file_map` (`logic_path`, `physic_path`, `logic_path_hash`, `physic_path_hash`) - VALUES (?, ?, ?, ?)'; - \OC_DB::executeAudited($sql, array($logicPath, $physicalPath, md5($logicPath), md5($physicalPath))); - } - - /** - * @param string $path - * @param int $index - * @return string - */ - public function slugifyPath($path, $index = null) { - $path = $this->stripRootFolder($path, $this->unchangedPhysicalRoot); - - $pathElements = explode('/', $path); - $sluggedElements = array(); - - foreach ($pathElements as $pathElement) { - // remove empty elements - if (empty($pathElement)) { - continue; - } - - $sluggedElements[] = $this->slugify($pathElement); - } - - // apply index to file name - if ($index !== null) { - $last = array_pop($sluggedElements); - - // if filename contains periods - add index number before last period - if (preg_match('~\.[^\.]+$~i', $last, $extension)) { - array_push($sluggedElements, substr($last, 0, -(strlen($extension[0]))) . '-' . $index . $extension[0]); - } else { - // if filename doesn't contain periods add index ofter the last char - array_push($sluggedElements, $last . '-' . $index); - } - } - - $sluggedPath = $this->unchangedPhysicalRoot.implode('/', $sluggedElements); - return $this->resolveRelativePath($sluggedPath); - } - - /** - * Modifies a string to remove all non ASCII characters and spaces. - * - * @param string $text - * @return string - */ - private function slugify($text) { - $originalText = $text; - // replace non letter or digits or dots by - - $text = preg_replace('~[^\\pL\d\.]+~u', '-', $text); - - // trim - $text = trim($text, '-'); - - // transliterate - if (function_exists('iconv')) { - $text = iconv('utf-8', 'us-ascii//TRANSLIT//IGNORE', $text); - } - - // lowercase - $text = strtolower($text); - - // remove unwanted characters - $text = preg_replace('~[^-\w\.]+~', '', $text); - - // trim ending dots (for security reasons and win compatibility) - $text = preg_replace('~\.+$~', '', $text); - - if (empty($text) || \OC\Files\Filesystem::isFileBlacklisted($text)) { - /** - * Item slug would be empty. Previously we used uniqid() here. - * However this means that the behaviour is not reproducible, so - * when uploading files into a "empty" folder, the folders name is - * different. - * - * The other case is, that the slugified name would be a blacklisted - * filename. In this case we just use the same workaround by - * returning the secure md5 hash of the original name. - * - * - * If there would be a md5() hash collision, the deduplicate check - * will spot this and append an index later, so this should not be - * a problem. - */ - return md5($originalText); - } - - return $text; - } -} |