public function filterNodeName($nodePath, $nodeName, &$isLeaf, $lsOptions) { $showHiddenFiles = $this->getFilteredOption("SHOW_HIDDEN_FILES", $this->repository->getId()); $isLeaf = is_file($nodePath . "/" . $nodeName) || AJXP_Utils::isBrowsableArchive($nodeName); if (AJXP_Utils::isHidden($nodeName) && !$showHiddenFiles) { return false; } $nodeType = "d"; if ($isLeaf) { if (AJXP_Utils::isBrowsableArchive($nodeName)) { $nodeType = "z"; } else { $nodeType = "f"; } } if (!$lsOptions[$nodeType]) { return false; } if ($nodeType == "d") { if (RecycleBinManager::recycleEnabled() && $nodePath . "/" . $nodeName == RecycleBinManager::getRecyclePath()) { return false; } return !$this->filterFolder($nodeName); } else { if ($nodeName == "." || $nodeName == "..") { return false; } if (RecycleBinManager::recycleEnabled() && $nodePath == RecycleBinManager::getRecyclePath() && $nodeName == RecycleBinManager::getCacheFileName()) { return false; } return !$this->filterFile($nodeName); } }
public function switchAction($action, $httpVars, $fileVars) { parent::accessPreprocess($action, $httpVars, $fileVars); $selection = new UserSelection($this->repository); $dir = AJXP_Utils::sanitize($httpVars["dir"], AJXP_SANITIZE_DIRNAME) or ""; if (AJXP_MetaStreamWrapper::actualRepositoryWrapperClass($this->repository->getId()) == "fsAccessWrapper") { $dir = fsAccessWrapper::patchPathForBaseDir($dir); } $dir = AJXP_Utils::securePath($dir); if ($action != "upload") { $dir = AJXP_Utils::decodeSecureMagic($dir); } $selection->initFromHttpVars($httpVars); if (!$selection->isEmpty()) { $this->filterUserSelectionToHidden($selection->getFiles()); } $mess = ConfService::getMessages(); $newArgs = RecycleBinManager::filterActions($action, $selection, $dir, $httpVars); if (isset($newArgs["action"])) { $action = $newArgs["action"]; } if (isset($newArgs["dest"])) { $httpVars["dest"] = SystemTextEncoding::toUTF8($newArgs["dest"]); } //Re-encode! // FILTER DIR PAGINATION ANCHOR $page = null; if (isset($dir) && strstr($dir, "%23") !== false) { $parts = explode("%23", $dir); $dir = $parts[0]; $page = $parts[1]; } $pendingSelection = ""; $logMessage = null; $reloadContextNode = false; switch ($action) { //------------------------------------ // DOWNLOAD //------------------------------------ case "download": $this->logInfo("Download", array("files" => $this->addSlugToPath($selection))); @set_error_handler(array("HTMLWriter", "javascriptErrorHandler"), E_ALL & ~E_NOTICE); @register_shutdown_function("restore_error_handler"); $zip = false; if ($selection->isUnique()) { if (is_dir($this->urlBase . $selection->getUniqueFile())) { $zip = true; $base = basename($selection->getUniqueFile()); $uniqDir = dirname($selection->getUniqueFile()); if (!empty($uniqDir) && $uniqDir != "/") { $dir = dirname($selection->getUniqueFile()); } } else { if (!file_exists($this->urlBase . $selection->getUniqueFile())) { throw new Exception("Cannot find file!"); } } $node = $selection->getUniqueNode(); } else { $zip = true; } if ($zip) { // Make a temp zip and send it as download $loggedUser = AuthService::getLoggedUser(); $file = AJXP_Utils::getAjxpTmpDir() . "/" . ($loggedUser ? $loggedUser->getId() : "shared") . "_" . time() . "tmpDownload.zip"; $zipFile = $this->makeZip($selection->getFiles(), $file, empty($dir) ? "/" : $dir); if (!$zipFile) { throw new AJXP_Exception("Error while compressing"); } if (!$this->getFilteredOption("USE_XSENDFILE", $this->repository) && !$this->getFilteredOption("USE_XACCELREDIRECT", $this->repository)) { register_shutdown_function("unlink", $file); } $localName = ($base == "" ? "Files" : $base) . ".zip"; if (isset($httpVars["archive_name"])) { $localName = AJXP_Utils::decodeSecureMagic($httpVars["archive_name"]); } $this->readFile($file, "force-download", $localName, false, false, true); } else { $localName = ""; AJXP_Controller::applyHook("dl.localname", array($this->urlBase . $selection->getUniqueFile(), &$localName)); $this->readFile($this->urlBase . $selection->getUniqueFile(), "force-download", $localName); } if (isset($node)) { AJXP_Controller::applyHook("node.read", array(&$node)); } break; case "prepare_chunk_dl": $chunkCount = intval($httpVars["chunk_count"]); $node = $selection->getUniqueNode(); $fileId = $node->getUrl(); $sessionKey = "chunk_file_" . md5($fileId . time()); $totalSize = filesize($fileId); $chunkSize = intval($totalSize / $chunkCount); $realFile = AJXP_MetaStreamWrapper::getRealFSReference($fileId, true); $chunkData = array("localname" => basename($fileId), "chunk_count" => $chunkCount, "chunk_size" => $chunkSize, "total_size" => $totalSize, "file_id" => $sessionKey); $_SESSION[$sessionKey] = array_merge($chunkData, array("file" => $realFile)); HTMLWriter::charsetHeader("application/json"); print json_encode($chunkData); AJXP_Controller::applyHook("node.read", array(&$node)); break; case "download_chunk": $chunkIndex = intval($httpVars["chunk_index"]); $chunkKey = $httpVars["file_id"]; $sessData = $_SESSION[$chunkKey]; $realFile = $sessData["file"]; $chunkSize = $sessData["chunk_size"]; $offset = $chunkSize * $chunkIndex; if ($chunkIndex == $sessData["chunk_count"] - 1) { // Compute the last chunk real length $chunkSize = $sessData["total_size"] - $chunkSize * ($sessData["chunk_count"] - 1); if (AJXP_MetaStreamWrapper::wrapperIsRemote($this->urlBase)) { register_shutdown_function("unlink", $realFile); } } $this->readFile($realFile, "force-download", $sessData["localname"] . "." . sprintf("%03d", $chunkIndex + 1), false, false, true, $offset, $chunkSize); break; case "compress": // Make a temp zip and send it as download $loggedUser = AuthService::getLoggedUser(); if (isset($httpVars["archive_name"])) { $localName = AJXP_Utils::decodeSecureMagic($httpVars["archive_name"]); $this->filterUserSelectionToHidden(array($localName)); } else { $localName = (basename($dir) == "" ? "Files" : basename($dir)) . ".zip"; } $file = AJXP_Utils::getAjxpTmpDir() . "/" . ($loggedUser ? $loggedUser->getId() : "shared") . "_" . time() . "tmpCompression.zip"; if (isset($httpVars["compress_flat"])) { $baseDir = "__AJXP_ZIP_FLAT__/"; } else { $baseDir = $dir; } $zipFile = $this->makeZip($selection->getFiles(), $file, $baseDir); if (!$zipFile) { throw new AJXP_Exception("Error while compressing file {$localName}"); } register_shutdown_function("unlink", $file); $tmpFNAME = $this->urlBase . $dir . "/" . str_replace(".zip", ".tmp", $localName); copy($file, $tmpFNAME); try { AJXP_Controller::applyHook("node.before_create", array(new AJXP_Node($tmpFNAME), filesize($tmpFNAME))); } catch (Exception $e) { @unlink($tmpFNAME); throw $e; } @rename($tmpFNAME, $this->urlBase . $dir . "/" . $localName); AJXP_Controller::applyHook("node.change", array(null, new AJXP_Node($this->urlBase . $dir . "/" . $localName), false)); //$reloadContextNode = true; //$pendingSelection = $localName; $newNode = new AJXP_Node($this->urlBase . $dir . "/" . $localName); if (!isset($nodesDiffs)) { $nodesDiffs = $this->getNodesDiffArray(); } $nodesDiffs["ADD"][] = $newNode; break; case "stat": clearstatcache(); header("Content-type:application/json"); if ($selection->isUnique()) { $stat = @stat($this->urlBase . $selection->getUniqueFile()); if (!$stat || !is_readable($selection->getUniqueNode()->getUrl())) { print '{}'; } else { print json_encode($stat); } } else { $files = $selection->getFiles(); print '{'; foreach ($files as $index => $path) { $stat = @stat($this->urlBase . $path); if (!$stat || !is_readable($this->urlBase . $path)) { $stat = '{}'; } else { $stat = json_encode($stat); } print json_encode($path) . ':' . $stat . ($index < count($files) - 1 ? "," : ""); } print '}'; } break; //------------------------------------ // ONLINE EDIT //------------------------------------ //------------------------------------ // ONLINE EDIT //------------------------------------ case "get_content": $node = $selection->getUniqueNode(); $dlFile = $node->getUrl(); if (!is_readable($dlFile)) { throw new Exception("Cannot access file!"); } $this->logInfo("Get_content", array("files" => $this->addSlugToPath($selection))); if (AJXP_Utils::getStreamingMimeType(basename($dlFile)) !== false) { $this->readFile($node->getUrl(), "stream_content"); } else { $this->readFile($node->getUrl(), "plain"); } AJXP_Controller::applyHook("node.read", array(&$node)); break; case "put_content": if (!isset($httpVars["content"])) { break; } // Load "code" variable directly from POST array, do not "securePath" or "sanitize"... $code = $httpVars["content"]; $currentNode = $selection->getUniqueNode(); $fileName = $currentNode->getUrl(); $this->logInfo("Online Edition", array("files" => $this->addSlugToPath($fileName))); if (isset($httpVars["encode"]) && $httpVars["encode"] == "base64") { $code = base64_decode($code); } else { $code = str_replace("<", "<", SystemTextEncoding::magicDequote($code)); } try { AJXP_Controller::applyHook("node.before_change", array(&$currentNode, strlen($code))); } catch (Exception $e) { header("Content-Type:text/plain"); print $e->getMessage(); return; } if (!is_file($fileName) || !$this->isWriteable($fileName, "file")) { header("Content-Type:text/plain"); print !$this->isWriteable($fileName, "file") ? "1001" : "1002"; return; } $fp = fopen($fileName, "w"); fputs($fp, $code); fclose($fp); clearstatcache(true, $fileName); AJXP_Controller::applyHook("node.change", array($currentNode, $currentNode, false)); header("Content-Type:text/plain"); print $mess[115]; break; //------------------------------------ // COPY / MOVE //------------------------------------ //------------------------------------ // COPY / MOVE //------------------------------------ case "copy": case "move": if ($selection->isEmpty()) { throw new AJXP_Exception("", 113); } $loggedUser = AuthService::getLoggedUser(); if ($loggedUser != null && !$loggedUser->canWrite(ConfService::getCurrentRepositoryId())) { throw new AJXP_Exception("You are not allowed to write", 207); } $success = $error = array(); $dest = AJXP_Utils::decodeSecureMagic($httpVars["dest"]); $this->filterUserSelectionToHidden(array($httpVars["dest"])); if ($selection->inZip()) { // Set action to copy anycase (cannot move from the zip). $action = "copy"; $this->extractArchive($dest, $selection, $error, $success); } else { $move = $action == "move" ? true : false; if ($move && isset($httpVars["force_copy_delete"])) { $move = false; } $this->copyOrMove($dest, $selection->getFiles(), $error, $success, $move); } if (count($error)) { throw new AJXP_Exception(SystemTextEncoding::toUTF8(join("\n", $error))); } else { if (isset($httpVars["force_copy_delete"])) { $errorMessage = $this->delete($selection->getFiles(), $logMessages); if ($errorMessage) { throw new AJXP_Exception(SystemTextEncoding::toUTF8($errorMessage)); } $this->logInfo("Copy/Delete", array("files" => $this->addSlugToPath($selection), "destination" => $this->addSlugToPath($dest))); } else { $this->logInfo($action == "move" ? "Move" : "Copy", array("files" => $this->addSlugToPath($selection), "destination" => $this->addSlugToPath($dest))); } $logMessage = join("\n", $success); } if (!isset($nodesDiffs)) { $nodesDiffs = $this->getNodesDiffArray(); } // Assume new nodes are correctly created $selectedItems = $selection->getFiles(); foreach ($selectedItems as $selectedPath) { $newPath = $this->urlBase . $dest . "/" . basename($selectedPath); $newNode = new AJXP_Node($newPath); $nodesDiffs["ADD"][] = $newNode; if ($action == "move") { $nodesDiffs["REMOVE"][] = $selectedPath; } } if (!(RecycleBinManager::getRelativeRecycle() == $dest && $this->getFilteredOption("HIDE_RECYCLE", $this->repository) == true)) { //$reloadDataNode = $dest; } break; //------------------------------------ // DELETE //------------------------------------ //------------------------------------ // DELETE //------------------------------------ case "delete": if ($selection->isEmpty()) { throw new AJXP_Exception("", 113); } $logMessages = array(); $errorMessage = $this->delete($selection->getFiles(), $logMessages); if (count($logMessages)) { $logMessage = join("\n", $logMessages); } if ($errorMessage) { throw new AJXP_Exception(SystemTextEncoding::toUTF8($errorMessage)); } $this->logInfo("Delete", array("files" => $this->addSlugToPath($selection))); if (!isset($nodesDiffs)) { $nodesDiffs = $this->getNodesDiffArray(); } $nodesDiffs["REMOVE"] = array_merge($nodesDiffs["REMOVE"], $selection->getFiles()); break; case "purge": $hardPurgeTime = intval($this->repository->getOption("PURGE_AFTER")) * 3600 * 24; $softPurgeTime = intval($this->repository->getOption("PURGE_AFTER_SOFT")) * 3600 * 24; $shareCenter = AJXP_PluginsService::findPluginById('action.share'); if (!($shareCenter && $shareCenter->isEnabled())) { //action.share is disabled, don't look at the softPurgeTime $softPurgeTime = 0; } if ($hardPurgeTime > 0 || $softPurgeTime > 0) { $this->recursivePurge($this->urlBase, $hardPurgeTime, $softPurgeTime); } break; //------------------------------------ // RENAME //------------------------------------ //------------------------------------ // RENAME //------------------------------------ case "rename": $file = $selection->getUniqueFile(); $filename_new = AJXP_Utils::decodeSecureMagic($httpVars["filename_new"]); $dest = null; if (isset($httpVars["dest"])) { $dest = AJXP_Utils::decodeSecureMagic($httpVars["dest"]); $filename_new = ""; } $this->filterUserSelectionToHidden(array($filename_new)); $this->rename($file, $filename_new, $dest); $logMessage = SystemTextEncoding::toUTF8($file) . " {$mess['41']} " . SystemTextEncoding::toUTF8($filename_new); //$reloadContextNode = true; //$pendingSelection = $filename_new; if (!isset($nodesDiffs)) { $nodesDiffs = $this->getNodesDiffArray(); } if ($dest == null) { $dest = AJXP_Utils::safeDirname($file); } $nodesDiffs["UPDATE"][$file] = new AJXP_Node($this->urlBase . $dest . "/" . $filename_new); $this->logInfo("Rename", array("files" => $this->addSlugToPath($file), "original" => $this->addSlugToPath($file), "new" => $filename_new)); break; //------------------------------------ // CREER UN REPERTOIRE / CREATE DIR //------------------------------------ //------------------------------------ // CREER UN REPERTOIRE / CREATE DIR //------------------------------------ case "mkdir": $messtmp = ""; $files = $selection->getFiles(); if (isset($httpVars["dirname"])) { $files[] = $dir . "/" . AJXP_Utils::decodeSecureMagic($httpVars["dirname"], AJXP_SANITIZE_FILENAME); } if (!isset($nodesDiffs)) { $nodesDiffs = $this->getNodesDiffArray(); } $messages = array(); $errors = array(); $max_length = ConfService::getCoreConf("NODENAME_MAX_LENGTH"); foreach ($files as $newDirPath) { $parentDir = AJXP_Utils::safeDirname($newDirPath); $basename = AJXP_Utils::safeBasename($newDirPath); $basename = substr($basename, 0, $max_length); $this->filterUserSelectionToHidden(array($basename)); try { AJXP_Controller::applyHook("node.before_create", array(new AJXP_Node($parentDir . "/" . $basename), -2)); } catch (AJXP_Exception $e) { $errors[] = $e->getMessage(); continue; } $error = $this->mkDir($parentDir, $basename, isset($httpVars["ignore_exists"]) ? true : false); if (isset($error)) { //throw new AJXP_Exception($error); $errors[] = $error; continue; } $messtmp .= "{$mess['38']} " . SystemTextEncoding::toUTF8($basename) . " {$mess['39']} "; if ($parentDir == "") { $messtmp .= "/"; } else { $messtmp .= SystemTextEncoding::toUTF8($parentDir); } $messages[] = $messtmp; $newNode = new AJXP_Node($this->urlBase . $parentDir . "/" . $basename); array_push($nodesDiffs["ADD"], $newNode); $this->logInfo("Create Dir", array("dir" => $this->addSlugToPath($parentDir) . "/" . $basename, "files" => $this->addSlugToPath($parentDir) . "/" . $basename)); } if (count($errors)) { if (!count($messages)) { throw new AJXP_Exception(implode('', $errors)); } else { $errorMessage = implode("<br>", $errors); } } $logMessage = implode("<br>", $messages); break; //------------------------------------ // CREER UN FICHIER / CREATE FILE //------------------------------------ //------------------------------------ // CREER UN FICHIER / CREATE FILE //------------------------------------ case "mkfile": $messtmp = ""; if (empty($httpVars["filename"]) && isset($httpVars["node"])) { $filename = AJXP_Utils::decodeSecureMagic($httpVars["node"]); } else { $filename = AJXP_Utils::decodeSecureMagic($httpVars["filename"], AJXP_SANITIZE_FILENAME); } $filename = substr($filename, 0, ConfService::getCoreConf("NODENAME_MAX_LENGTH")); $this->filterUserSelectionToHidden(array($filename)); $content = ""; if (isset($httpVars["content"])) { $content = $httpVars["content"]; } $forceCreation = false; if (isset($httpVars["force"]) && $httpVars["force"] == "true") { $forceCreation = true; } $error = $this->createEmptyFile($dir, $filename, $content, $forceCreation); if (isset($error)) { throw new AJXP_Exception($error); } $messtmp .= "{$mess['34']} " . SystemTextEncoding::toUTF8($filename) . " {$mess['39']} "; if ($dir == "") { $messtmp .= "/"; } else { $messtmp .= SystemTextEncoding::toUTF8($dir); } $logMessage = $messtmp; //$reloadContextNode = true; //$pendingSelection = $dir."/".$filename; $this->logInfo("Create File", array("files" => $this->addSlugToPath($dir) . "/" . $filename)); $newNode = new AJXP_Node($this->urlBase . $dir . "/" . $filename); if (!isset($nodesDiffs)) { $nodesDiffs = $this->getNodesDiffArray(); } array_push($nodesDiffs["ADD"], $newNode); break; //------------------------------------ // CHANGE FILE PERMISSION //------------------------------------ //------------------------------------ // CHANGE FILE PERMISSION //------------------------------------ case "chmod": $files = $selection->getFiles(); $changedFiles = array(); $chmod_value = $httpVars["chmod_value"]; $recursive = $httpVars["recursive"]; $recur_apply_to = $httpVars["recur_apply_to"]; foreach ($files as $fileName) { $this->chmod($fileName, $chmod_value, $recursive == "on", $recursive == "on" ? $recur_apply_to : "both", $changedFiles); } $logMessage = "Successfully changed permission to " . $chmod_value . " for " . count($changedFiles) . " files or folders"; $this->logInfo("Chmod", array("dir" => $this->addSlugToPath($dir), "files" => $this->addSlugToPath($dir), "filesCount" => count($changedFiles))); if (!isset($nodesDiffs)) { $nodesDiffs = $this->getNodesDiffArray(); } $nodesDiffs["UPDATE"] = array_merge($nodesDiffs["UPDATE"], $selection->buildNodes()); break; //------------------------------------ // UPLOAD //------------------------------------ //------------------------------------ // UPLOAD //------------------------------------ case "upload": $repoData = array('base_url' => $this->urlBase, 'chmod' => $this->repository->getOption('CHMOD_VALUE'), 'recycle' => $this->repository->getOption('RECYCLE_BIN')); $this->logDebug("Upload Files Data", $fileVars); $destination = $this->urlBase . AJXP_Utils::decodeSecureMagic($dir); $this->logDebug("Upload inside", array("destination" => $this->addSlugToPath($destination))); if (!$this->isWriteable($destination)) { $errorCode = 412; $errorMessage = "{$mess['38']} " . SystemTextEncoding::toUTF8($dir) . " {$mess['99']}."; $this->logDebug("Upload error 412", array("destination" => $this->addSlugToPath($destination))); return array("ERROR" => array("CODE" => $errorCode, "MESSAGE" => $errorMessage)); } $partialUpload = false; $partialTargetSize = -1; $originalAppendTo = ""; $createdNode = null; foreach ($fileVars as $boxName => $boxData) { if (substr($boxName, 0, 9) != "userfile_") { continue; } try { // CHECK PHP UPLOAD ERRORS AJXP_Utils::parseFileDataErrors($boxData, true); // FIND PROPER FILE NAME $userfile_name = AJXP_Utils::sanitize(SystemTextEncoding::fromPostedFileName($boxData["name"]), AJXP_SANITIZE_FILENAME); if (isset($httpVars["urlencoded_filename"])) { $userfile_name = AJXP_Utils::sanitize(SystemTextEncoding::fromUTF8(urldecode($httpVars["urlencoded_filename"])), AJXP_SANITIZE_FILENAME); } $userfile_name = substr($userfile_name, 0, ConfService::getCoreConf("NODENAME_MAX_LENGTH")); if (isset($httpVars["auto_rename"])) { $userfile_name = self::autoRenameForDest($destination, $userfile_name); } $this->logDebug("User filename " . $userfile_name); // CHECK IF THIS IS A FORBIDDEN FILENAME $this->filterUserSelectionToHidden(array($userfile_name)); // APPLY PRE-UPLOAD HOOKS $already_existed = false; try { if (file_exists($destination . "/" . $userfile_name)) { $already_existed = true; AJXP_Controller::applyHook("node.before_change", array(new AJXP_Node($destination . "/" . $userfile_name), $boxData["size"])); } else { AJXP_Controller::applyHook("node.before_create", array(new AJXP_Node($destination . "/" . $userfile_name), $boxData["size"])); } AJXP_Controller::applyHook("node.before_change", array(new AJXP_Node($destination))); } catch (Exception $e) { throw new Exception($e->getMessage(), 507); } // PARTIAL UPLOAD CASE - PREPPEND .dlpart extension if (isset($httpVars["partial_upload"]) && $httpVars["partial_upload"] == 'true' && isset($httpVars["partial_target_bytesize"])) { $partialUpload = true; $partialTargetSize = intval($httpVars["partial_target_bytesize"]); if (!isset($httpVars["appendto_urlencoded_part"])) { $userfile_name .= ".dlpart"; } } // NOW DO THE ACTUAL COPY $this->copyUploadedData($boxData, $destination, $userfile_name, $mess); // PARTIAL UPLOAD - PART II: APPEND DATA TO EXISTING PART if (isset($httpVars["appendto_urlencoded_part"])) { $appendTo = AJXP_Utils::sanitize(SystemTextEncoding::fromUTF8(urldecode($httpVars["appendto_urlencoded_part"])), AJXP_SANITIZE_FILENAME); if (isset($httpVars["partial_upload"]) && $httpVars["partial_upload"] == 'true') { $originalAppendTo = $appendTo; $appendTo .= ".dlpart"; } $this->logDebug("AppendTo FILE" . $appendTo); $already_existed = $this->appendUploadedData($destination, $userfile_name, $appendTo); $userfile_name = $appendTo; if ($partialUpload && $partialTargetSize == filesize($destination . "/" . $userfile_name)) { // This was the last part. We can now rename to the original name. if (is_file($destination . "/" . $originalAppendTo)) { unlink($destination . "/" . $originalAppendTo); } $result = @rename($destination . "/" . $userfile_name, $destination . "/" . $originalAppendTo); if ($result === false) { throw new Exception("Error renaming " . $destination . "/" . $userfile_name . " to " . $destination . "/" . $originalAppendTo); } $userfile_name = $originalAppendTo; $partialUpload = false; // Send a create event! $already_existed = false; } } // NOW PREPARE POST-UPLOAD EVENTS $this->changeMode($destination . "/" . $userfile_name, $repoData); $createdNode = new AJXP_Node($destination . "/" . $userfile_name); clearstatcache(true, $createdNode->getUrl()); $createdNode->loadNodeInfo(true); $logMessage .= "{$mess['34']} " . SystemTextEncoding::toUTF8($userfile_name) . " {$mess['35']} {$dir}"; $logFile = $this->addSlugToPath(SystemTextEncoding::fromUTF8($dir)) . "/" . $userfile_name; $this->logInfo("Upload File", array("file" => $logFile, "files" => $logFile)); if ($partialUpload) { $this->logDebug("Return Partial Upload: SUCESS but no event yet"); if (isset($already_existed) && $already_existed === true) { return array("SUCCESS" => true, "PARTIAL_NODE" => $createdNode); } } else { $this->logDebug("Return success"); if (isset($already_existed) && $already_existed === true) { return array("SUCCESS" => true, "UPDATED_NODE" => $createdNode); } else { return array("SUCCESS" => true, "CREATED_NODE" => $createdNode); } } } catch (Exception $e) { $errorCode = $e->getCode(); if (empty($errorCode)) { $errorCode = 411; } return array("ERROR" => array("CODE" => $errorCode, "MESSAGE" => $e->getMessage())); } } break; case "lsync": if (!ConfService::currentContextIsCommandLine()) { //die("This command must be accessed via CLI only."); } $fromNode = null; $toNode = null; $copyOrMove = false; if (isset($httpVars["from"])) { $fromNode = new AJXP_Node($this->urlBase . AJXP_Utils::decodeSecureMagic($httpVars["from"])); } if (isset($httpVars["to"])) { $toNode = new AJXP_Node($this->urlBase . AJXP_Utils::decodeSecureMagic($httpVars["to"])); } if (isset($httpVars["copy"]) && $httpVars["copy"] == "true") { $copyOrMove = true; } AJXP_Controller::applyHook("node.change", array($fromNode, $toNode, $copyOrMove)); break; //------------------------------------ // XML LISTING //------------------------------------ //------------------------------------ // XML LISTING //------------------------------------ case "ls": if (!isset($dir) || $dir == "/") { $dir = ""; } $lsOptions = $this->parseLsOptions(isset($httpVars["options"]) ? $httpVars["options"] : "a"); $startTime = microtime(); $dir = AJXP_Utils::securePath($dir); $path = $this->urlBase . ($dir != "" ? ($dir[0] == "/" ? "" : "/") . $dir : ""); $nonPatchedPath = $path; if (AJXP_MetaStreamWrapper::actualRepositoryWrapperClass($this->repository->getId()) == "fsAccessWrapper") { $nonPatchedPath = fsAccessWrapper::unPatchPathForBaseDir($path); } $testPath = @stat($path); if ($testPath === null || $testPath === false) { throw new Exception("There was a problem trying to open folder " . $path . ", please check your Administrator"); } if (!is_readable($path) && !is_writeable($path)) { throw new Exception("You are not allowed to access folder " . $path); } // Backward compat if ($selection->isUnique() && strpos($selection->getUniqueFile(), "/") !== 0) { $selection->setFiles(array($dir . "/" . $selection->getUniqueFile())); } $orderField = $orderDirection = null; $threshold = 500; $limitPerPage = 200; $defaultOrder = $this->repository->getOption("REMOTE_SORTING_DEFAULT_COLUMN"); $defaultDirection = $this->repository->getOption("REMOTE_SORTING_DEFAULT_DIRECTION"); if ($this->repository->getOption("REMOTE_SORTING")) { $orderDirection = isset($httpVars["order_direction"]) ? strtolower($httpVars["order_direction"]) : $defaultDirection; $orderField = isset($httpVars["order_column"]) ? $httpVars["order_column"] : $defaultOrder; if ($orderField != null && !in_array($orderField, array("ajxp_label", "filesize", "ajxp_modiftime", "mimestring"))) { $orderField = $defaultOrder; } } if (isset($httpVars["recursive"]) && $httpVars["recursive"] == "true") { $max_depth = isset($httpVars["max_depth"]) ? intval($httpVars["max_depth"]) : 0; $max_nodes = isset($httpVars["max_nodes"]) ? intval($httpVars["max_nodes"]) : 0; $crt_depth = isset($httpVars["crt_depth"]) ? intval($httpVars["crt_depth"]) + 1 : 1; $crt_nodes = isset($httpVars["crt_nodes"]) ? intval($httpVars["crt_nodes"]) : 0; } else { $threshold = $this->repository->getOption("PAGINATION_THRESHOLD"); if (!isset($threshold) || intval($threshold) == 0) { $threshold = 500; } $limitPerPage = $this->repository->getOption("PAGINATION_NUMBER"); if (!isset($limitPerPage) || intval($limitPerPage) == 0) { $limitPerPage = 200; } } if (!$selection->isEmpty()) { $uniqueNodes = $selection->buildNodes(); $parentAjxpNode = new AJXP_Node($this->urlBase . "/", array()); AJXP_Controller::applyHook("node.read", array(&$parentAjxpNode)); if (AJXP_XMLWriter::$headerSent == "tree") { AJXP_XMLWriter::renderAjxpNode($parentAjxpNode, false); } else { AJXP_XMLWriter::renderAjxpHeaderNode($parentAjxpNode); } foreach ($uniqueNodes as $node) { if (!file_exists($node->getUrl()) || !is_readable($node->getUrl()) && !is_writable($node->getUrl())) { continue; } $nodeName = $node->getLabel(); if (!$this->filterNodeName($node->getPath(), $nodeName, $isLeaf, $lsOptions)) { continue; } if (RecycleBinManager::recycleEnabled() && $node->getPath() == RecycleBinManager::getRecyclePath()) { continue; } $node->loadNodeInfo(false, false, $lsOptions["l"] ? "all" : "minimal"); if (!empty($node->metaData["nodeName"]) && $node->metaData["nodeName"] != $nodeName) { $node->setUrl(dirname($node->getUrl()) . "/" . $node->metaData["nodeName"]); } if (!empty($node->metaData["hidden"]) && $node->metaData["hidden"] === true) { continue; } if (!empty($node->metaData["mimestring_id"]) && array_key_exists($node->metaData["mimestring_id"], $mess)) { $node->mergeMetadata(array("mimestring" => $mess[$node->metaData["mimestring_id"]])); } if (isset($httpVars["page_position"]) && $httpVars["page_position"] == "true") { // Detect page position: we have to loading "siblings" $parentPath = AJXP_Utils::safeDirname($node->getPath()); $siblings = scandir($this->urlBase . $parentPath); foreach ($siblings as $i => $s) { if ($this->filterFile($s, true)) { unset($siblings[$i]); } if ($this->filterFolder($s)) { unset($siblings[$i]); } } if (count($siblings) > $threshold) { //usort($siblings, "strcasecmp"); $siblings = $this->orderNodes($siblings, $this->urlBase . $parentPath, $orderField, $orderDirection); $index = array_search($node->getLabel(), $siblings); $node->mergeMetadata(array("page_position" => floor($index / $limitPerPage) + 1)); } } if ($this->repository->hasContentFilter()) { $externalPath = $this->repository->getContentFilter()->externalPath($node); $node->setUrl($this->urlBase . $externalPath); } AJXP_XMLWriter::renderAjxpNode($node); } AJXP_XMLWriter::close(); break; } $streamIsSeekable = AJXP_MetaStreamWrapper::wrapperIsSeekable($path); $sharedHandle = null; if ($streamIsSeekable) { $handle = opendir($path); $sharedHandle = $handle; } $countFiles = $this->countFiles($path, !$lsOptions["f"], false, $sharedHandle); if (isset($sharedHandle)) { rewind($handle); } if (isset($crt_nodes)) { $crt_nodes += $countFiles; } $totalPages = $crtPage = 1; if (isset($threshold) && isset($limitPerPage) && $countFiles > $threshold) { $offset = 0; $crtPage = 1; if (isset($page)) { $offset = (intval($page) - 1) * $limitPerPage; $crtPage = $page; } $totalPages = floor($countFiles / $limitPerPage) + 1; } else { $offset = $limitPerPage = 0; } $metaData = array(); if (RecycleBinManager::recycleEnabled() && $dir == "") { $metaData["repo_has_recycle"] = "true"; } $parentAjxpNode = new AJXP_Node($nonPatchedPath, $metaData); $parentAjxpNode->loadNodeInfo(false, true, $lsOptions["l"] ? "all" : "minimal"); AJXP_Controller::applyHook("node.read", array(&$parentAjxpNode)); if (AJXP_XMLWriter::$headerSent == "tree") { AJXP_XMLWriter::renderAjxpNode($parentAjxpNode, false); } else { AJXP_XMLWriter::renderAjxpHeaderNode($parentAjxpNode); } if (isset($totalPages) && isset($crtPage) && ($totalPages > 1 || !AJXP_Utils::userAgentIsNativePydioApp())) { $remoteOptions = null; if ($this->getFilteredOption("REMOTE_SORTING")) { $remoteOptions = array("remote_order" => "true", "currentOrderCol" => isset($orderField) ? $orderField : $defaultOrder, "currentOrderDir" => isset($orderDirection) ? $orderDirection : $defaultDirection); } $foldersCounts = $this->countFiles($path, TRUE, false, $sharedHandle); if (isset($sharedHandle)) { rewind($sharedHandle); } AJXP_XMLWriter::renderPaginationData($countFiles, $crtPage, $totalPages, $foldersCounts, $remoteOptions); if (!$lsOptions["f"]) { AJXP_XMLWriter::close(); if (isset($sharedHandle)) { closedir($sharedHandle); } break; } } $cursor = 0; if (isset($sharedHandle)) { $handle = $sharedHandle; } else { $handle = opendir($path); } if (!$handle) { throw new AJXP_Exception("Cannot open dir " . $nonPatchedPath); } $nodes = array(); while (strlen($file = readdir($handle)) > 0) { $nodes[] = $file; } closedir($handle); $fullList = array("d" => array(), "z" => array(), "f" => array()); //$nodes = scandir($path); $nodes = $this->orderNodes($nodes, $nonPatchedPath, $orderField, $orderDirection); foreach ($nodes as $nodeName) { if ($nodeName == "." || $nodeName == "..") { continue; } $isLeaf = ""; if (!$this->filterNodeName($path, $nodeName, $isLeaf, $lsOptions)) { continue; } if (RecycleBinManager::recycleEnabled() && $dir == "" && "/" . $nodeName == RecycleBinManager::getRecyclePath()) { continue; } if ($offset > 0 && $cursor < $offset) { $cursor++; continue; } if ($limitPerPage > 0 && $cursor - $offset >= $limitPerPage) { break; } $currentFile = $nonPatchedPath . "/" . $nodeName; $meta = array(); if ($isLeaf != "") { $meta = array("is_file" => $isLeaf ? "1" : "0"); } $node = new AJXP_Node($currentFile, $meta); $node->setLabel($nodeName); $node->loadNodeInfo(false, false, $lsOptions["l"] ? "all" : "minimal"); if (!empty($node->metaData["nodeName"]) && $node->metaData["nodeName"] != $nodeName) { $node->setUrl($nonPatchedPath . "/" . $node->metaData["nodeName"]); } if (!empty($node->metaData["hidden"]) && $node->metaData["hidden"] === true) { continue; } if (!empty($node->metaData["mimestring_id"]) && array_key_exists($node->metaData["mimestring_id"], $mess)) { $node->mergeMetadata(array("mimestring" => $mess[$node->metaData["mimestring_id"]])); } if (isset($originalLimitPerPage) && $cursor > $originalLimitPerPage) { $node->mergeMetadata(array("page_position" => floor($cursor / $originalLimitPerPage) + 1)); } $nodeType = "d"; if ($node->isLeaf()) { if (AJXP_Utils::isBrowsableArchive($nodeName)) { if ($lsOptions["f"] && $lsOptions["z"]) { $nodeType = "f"; } else { $nodeType = "z"; } } else { $nodeType = "f"; } } // There is a special sorting, cancel the reordering of files & folders. if (isset($orderField) && $orderField != "ajxp_label" && !(isset($httpVars["recursive"]) && $httpVars["recursive"] == "true")) { $nodeType = "f"; } if ($this->repository->hasContentFilter()) { $externalPath = $this->repository->getContentFilter()->externalPath($node); $node->setUrl($this->urlBase . $externalPath); } $fullList[$nodeType][$nodeName] = $node; $cursor++; } if (isset($httpVars["recursive"]) && $httpVars["recursive"] == "true") { $breakNow = false; if (isset($max_depth) && $max_depth > 0 && $crt_depth >= $max_depth) { $breakNow = true; } if (isset($max_nodes) && $max_nodes > 0 && $crt_nodes >= $max_nodes) { $breakNow = true; } foreach ($fullList["d"] as &$nodeDir) { if ($breakNow) { $nodeDir->mergeMetadata(array("ajxp_has_children" => $this->countFiles($nodeDir->getUrl(), false, true) ? "true" : "false")); AJXP_XMLWriter::renderAjxpNode($nodeDir, true); continue; } $this->switchAction("ls", array("dir" => SystemTextEncoding::toUTF8($nodeDir->getPath()), "options" => $httpVars["options"], "recursive" => "true", "max_depth" => $max_depth, "max_nodes" => $max_nodes, "crt_depth" => $crt_depth, "crt_nodes" => $crt_nodes), array()); } } else { array_map(array("AJXP_XMLWriter", "renderAjxpNode"), $fullList["d"]); } array_map(array("AJXP_XMLWriter", "renderAjxpNode"), $fullList["z"]); array_map(array("AJXP_XMLWriter", "renderAjxpNode"), $fullList["f"]); // ADD RECYCLE BIN TO THE LIST if ($dir == "" && RecycleBinManager::recycleEnabled() && $this->getFilteredOption("HIDE_RECYCLE", $this->repository) !== true) { $recycleBinOption = RecycleBinManager::getRelativeRecycle(); if (file_exists($this->urlBase . $recycleBinOption)) { $recycleNode = new AJXP_Node($this->urlBase . $recycleBinOption); $recycleNode->loadNodeInfo(); AJXP_XMLWriter::renderAjxpNode($recycleNode); } } $this->logDebug("LS Time : " . intval((microtime() - $startTime) * 1000) . "ms"); AJXP_XMLWriter::close(); break; } $xmlBuffer = ""; if (isset($logMessage) || isset($errorMessage)) { $xmlBuffer .= AJXP_XMLWriter::sendMessage(isset($logMessage) ? $logMessage : null, isset($errorMessage) ? $errorMessage : null, false); } if ($reloadContextNode) { if (!isset($pendingSelection)) { $pendingSelection = ""; } $xmlBuffer .= AJXP_XMLWriter::reloadDataNode("", $pendingSelection, false); } if (isset($reloadDataNode)) { $xmlBuffer .= AJXP_XMLWriter::reloadDataNode($reloadDataNode, "", false); } if (isset($nodesDiffs)) { $xmlBuffer .= AJXP_XMLWriter::writeNodesDiff($nodesDiffs, false); } return $xmlBuffer; }
function filterNodeName($nodePath, $nodeName, $isLeaf, $lsOptions) { if (AJXP_Utils::isHidden($nodeName) && !$this->driverConf["SHOW_HIDDEN_FILES"]) { return false; } $nodeType = "d"; if ($isLeaf) { if (AJXP_Utils::isBrowsableArchive($nodeName)) { $nodeType = "z"; } else { $nodeType = "f"; } } if (!$lsOptions[$nodeType]) { return false; } if ($nodeType == "d") { if (RecycleBinManager::recycleEnabled() && $nodePath . "/" . $nodeName == RecycleBinManager::getRecyclePath()) { return false; } return !$this->filterFolder($nodeName); } else { if ($nodeName == "." || $nodeName == "..") { return false; } if (RecycleBinManager::recycleEnabled() && $nodePath == RecycleBinManager::getRecyclePath() && $nodeName == RecycleBinManager::getCacheFileName()) { return false; } return !$this->filterFile($nodeName); } }
function saveCache($value) { if (!RecycleBinManager::recycleEnabled()) { return null; } $cachePath = RecycleBinManager::getRecyclePath() . "/" . RecycleBinManager::getCacheFileName(); $fp = fopen($cachePath, "w"); if ($fp) { fwrite($fp, serialize($value)); fflush($fp); fclose($fp); } }