/** * Executes the command logic with the specified RPC parameters. * * @param Object $params Command parameters sent from client. * @return Object Result object to be passed back to client. */ public function execute($params) { $file = MOXMAN::getFile($params->path); $config = $file->getConfig(); $resolution = $params->resolution; if ($config->get('general.demo')) { throw new MOXMAN_Exception("This action is restricted in demo mode.", MOXMAN_Exception::DEMO_MODE); } $content = $this->getUrlContent($params->url, $config); // Fire before file action add event $args = $this->fireBeforeFileAction("add", $file, strlen($content)); $file = $args->getFile(); if (!$file->canWrite()) { throw new MOXMAN_Exception("No write access to file: " . $file->getPublicPath(), MOXMAN_Exception::NO_WRITE_ACCESS); } $filter = MOXMAN_Vfs_CombinedFileFilter::createFromConfig($config, "upload"); if (!$filter->accept($file, true)) { throw new MOXMAN_Exception("Invalid file name for: " . $file->getPublicPath(), MOXMAN_Exception::INVALID_FILE_NAME); } if ($resolution == "rename") { $file = MOXMAN_Util_FileUtils::uniqueFile($file); } else { if ($resolution == "overwrite") { MOXMAN::getPluginManager()->get("core")->deleteFile($file); } else { throw new MOXMAN_Exception("To file already exist: " . $file->getPublicPath(), MOXMAN_Exception::FILE_EXISTS); } } $stream = $file->open(MOXMAN_Vfs_IFileStream::WRITE); $stream->write($content); $stream->close(); $args = new MOXMAN_Vfs_FileActionEventArgs("add", $file); MOXMAN::getPluginManager()->get("core")->fire("FileAction", $args); return parent::fileToJson($file, true); }
/** * Executes the command logic with the specified RPC parameters. * * @param Object $params Command parameters sent from client. * @return Object Result object to be passed back to client. */ public function execute($params) { $paths = $params->paths; $result = array(); foreach ($paths as $path) { if ($this->hasPath($result, $path)) { continue; } $file = MOXMAN::getFile($path); $config = $file->getConfig(); if ($config->get('general.demo')) { throw new MOXMAN_Exception("This action is restricted in demo mode.", MOXMAN_Exception::DEMO_MODE); } if (!$file->exists()) { throw new MOXMAN_Exception("Path doesn't exist: " . $file->getPublicPath(), MOXMAN_Exception::FILE_DOESNT_EXIST); } $parentFile = $file->getParentFile(); if (!$parentFile || !$parentFile->canWrite()) { throw new MOXMAN_Exception("No write access to file: " . $file->getPublicPath(), MOXMAN_Exception::NO_WRITE_ACCESS); } $filter = MOXMAN_Vfs_CombinedFileFilter::createFromConfig($config, "delete"); if (!$filter->accept($file)) { throw new MOXMAN_Exception("Invalid file name for: " . $file->getPublicPath(), MOXMAN_Exception::INVALID_FILE_NAME); } $result[] = $this->fileToJson($file); if ($file->exists()) { $args = $this->fireBeforeFileAction(MOXMAN_Vfs_FileActionEventArgs::DELETE, $file); $result = array_merge($result, $this->filesToJson($args->getFileList())); $file->delete(true); $args = $this->fireFileAction(MOXMAN_Vfs_FileActionEventArgs::DELETE, $file); $result = array_merge($result, $this->filesToJson($args->getFileList())); } } return $result; }
/** * Executes the command logic with the specified RPC parameters. * * @param Object $params Command parameters sent from client. * @return Object Result object to be passed back to client. */ public function execute($params) { $file = MOXMAN::getFile($params->path); $config = $file->getConfig(); if ($config->get('general.demo')) { throw new MOXMAN_Exception("This action is restricted in demo mode.", MOXMAN_Exception::DEMO_MODE); } if (!$file->canWrite()) { throw new MOXMAN_Exception("No write access to file: " . $file->getPublicPath(), MOXMAN_Exception::NO_WRITE_ACCESS); } $filter = MOXMAN_Vfs_CombinedFileFilter::createFromConfig($config, "edit"); if ($filter->accept($file) !== MOXMAN_Vfs_CombinedFileFilter::ACCEPTED) { throw new MOXMAN_Exception("Invalid file name for: " . $file->getPublicPath(), MOXMAN_Exception::INVALID_FILE_NAME); } if ($file->exists()) { $file->delete(true); } // Write contents to file $stream = $file->open(MOXMAN_Vfs_IFileStream::WRITE); if ($stream) { $stream->write($params->content); $stream->close(); } $this->fireFileAction(MOXMAN_Core_FileActionEventArgs::ADD, $file); return $this->fileToJson($file); }
/** * Process a request using the specified context. * * @param MOXMAN_Http_Context $httpContext Context instance to pass to use for the handler. */ public function processRequest(MOXMAN_Http_Context $httpContext) { $request = $httpContext->getRequest(); $response = $httpContext->getResponse(); $path = $request->get("path"); $names = explode('/', $request->get("names", "")); $zipName = $request->get("zipname", "files.zip"); if (count($names) === 1) { $file = MOXMAN::getFile(MOXMAN_Util_PathUtils::combine($path, $names[0])); $filter = MOXMAN_Vfs_CombinedFileFilter::createFromConfig(MOXMAN::getFile($path)->getConfig(), "download"); if (!$filter->accept($file)) { throw new MOXMAN_Exception("Invalid file name for: " . $file->getPublicPath(), MOXMAN_Exception::INVALID_FILE_NAME); } if ($file->isFile()) { $response->sendFile($file, true); return; } } // Download multiple files as zip $zipWriter = new MOXMAN_Zip_ZipWriter(array("compressionLevel" => 0)); // Setup download headers $response->disableCache(); $response->setHeader("Content-type", "application/octet-stream"); $response->setHeader("Content-Disposition", 'attachment; filename="' . $zipName . '"'); $filter = MOXMAN_Vfs_CombinedFileFilter::createFromConfig(MOXMAN::getFile($path)->getConfig(), "download"); // Combine files to zip foreach ($names as $name) { $fromFile = MOXMAN::getFile(MOXMAN_Util_PathUtils::combine($path, $name)); $this->addZipFiles($fromFile, $fromFile->getParent(), $filter, $zipWriter); } $response->sendContent($zipWriter->toString()); }
/** @ignore */ private function moveFile($fromFile, $toFile) { $config = $toFile->getConfig(); if ($config->get('general.demo')) { throw new MOXMAN_Exception("This action is restricted in demo mode.", MOXMAN_Exception::DEMO_MODE); } if (!$fromFile->exists()) { throw new MOXMAN_Exception("From file doesn't exist: " . $fromFile->getPublicPath(), MOXMAN_Exception::FILE_DOESNT_EXIST); } if ($toFile->exists()) { if (strtolower($fromFile->getPath()) != strtolower($toFile->getPath()) || $fromFile->getName() == $toFile->getName()) { throw new MOXMAN_Exception("To file already exist: " . $toFile->getPublicPath(), MOXMAN_Exception::FILE_EXISTS); } } if (!$fromFile->canWrite()) { throw new MOXMAN_Exception("No write access to file: " . $fromFile->getPublicPath(), MOXMAN_Exception::NO_WRITE_ACCESS); } if (!$toFile->canWrite()) { throw new MOXMAN_Exception("No write access to file: " . $toFile->getPublicPath(), MOXMAN_Exception::NO_WRITE_ACCESS); } $filter = MOXMAN_Vfs_BasicFileFilter::createFromConfig($config); if ($filter->accept($fromFile, $fromFile->isFile()) !== MOXMAN_Vfs_BasicFileFilter::ACCEPTED) { throw new MOXMAN_Exception("Invalid file name for: " . $fromFile->getPublicPath(), MOXMAN_Exception::INVALID_FILE_NAME); } $filter = MOXMAN_Vfs_CombinedFileFilter::createFromConfig($config, "rename"); if ($filter->accept($toFile, $fromFile->isFile()) !== MOXMAN_Vfs_CombinedFileFilter::ACCEPTED) { throw new MOXMAN_Exception("Invalid file name for: " . $toFile->getPublicPath(), MOXMAN_Exception::INVALID_FILE_NAME); } // Fire before file action event $args = $this->fireBeforeTargetFileAction(MOXMAN_Core_FileActionEventArgs::MOVE, $fromFile, $toFile); $fromFile = $args->getFile(); $toFile = $args->getTargetFile(); $fromFile->moveTo($toFile); $this->fireTargetFileAction(MOXMAN_Core_FileActionEventArgs::MOVE, $fromFile, $toFile); }
/** * Executes the command logic with the specified RPC parameters. * * @param Object $params Command parameters sent from client. * @return Object Result object to be passed back to client. */ public function execute($params) { $file = MOXMAN::getFile($params->path); $config = $file->getConfig(); if ($config->get('general.demo')) { throw new MOXMAN_Exception("This action is restricted in demo mode.", MOXMAN_Exception::DEMO_MODE); } if (!$file->canWrite()) { throw new MOXMAN_Exception("No write access to file: " . $file->getPublicPath(), MOXMAN_Exception::NO_WRITE_ACCESS); } if ($file->exists()) { throw new MOXMAN_Exception("File already exist: " . $file->getPublicPath(), MOXMAN_Exception::FILE_EXISTS); } $filter = MOXMAN_Vfs_CombinedFileFilter::createFromConfig($config, "createdir"); if (!$filter->accept($file, false)) { throw new MOXMAN_Exception("Invalid file name for: " . $file->getPublicPath(), MOXMAN_Exception::INVALID_FILE_NAME); } if (isset($params->template)) { // TODO: Security audit this $templateFile = MOXMAN::getFile($params->template); if (!$templateFile->exists()) { throw new MOXMAN_Exception("Template file doesn't exists: " . $file->getPublicPath(), MOXMAN_Exception::FILE_DOESNT_EXIST); } $args = $this->fireBeforeTargetFileAction(MOXMAN_Vfs_FileActionEventArgs::COPY, $templateFile, $file); $file = $args->getTargetFile(); $templateFile->copyTo($file); $this->fireTargetFileAction(MOXMAN_Vfs_FileActionEventArgs::COPY, $templateFile, $file); } else { $args = $this->fireBeforeFileAction(MOXMAN_Vfs_FileActionEventArgs::ADD, $file); $file = $args->getFile(); $file->mkdir(); $this->fireFileAction(MOXMAN_Vfs_FileActionEventArgs::ADD, $file); } return $this->fileToJson($file, true); }
/** * Executes the command logic with the specified RPC parameters. * * @param Object $params Command parameters sent from client. * @return Object Result object to be passed back to client. */ public function execute($params) { $file = MOXMAN::getFile($params->path); $url = parse_url($params->url); $config = $file->getConfig(); if ($config->get('general.demo')) { throw new MOXMAN_Exception("This action is restricted in demo mode.", MOXMAN_Exception::DEMO_MODE); } if ($file->exists()) { throw new MOXMAN_Exception("To file already exist: " . $file->getPublicPath(), MOXMAN_Exception::FILE_EXISTS); } if (!$file->canWrite()) { throw new MOXMAN_Exception("No write access to file: " . $file->getPublicPath(), MOXMAN_Exception::NO_WRITE_ACCESS); } $filter = MOXMAN_Vfs_CombinedFileFilter::createFromConfig($config, "upload"); if (!$filter->accept($file, true)) { throw new MOXMAN_Exception("Invalid file name for: " . $file->getPublicPath(), MOXMAN_Exception::INVALID_FILE_NAME); } $port = ""; if (isset($url["port"])) { $port = ":" . $url["port"]; } $query = ""; if (isset($url["query"])) { $query = "?" . $url["query"]; } $path = $url["path"] . $query; $host = $url["scheme"] . "://" . $url["host"] . $port; $httpClient = new MOXMAN_Http_HttpClient($host); $request = $httpClient->createRequest($path); $response = $request->send(); // Handle redirects $location = $response->getHeader("location"); if ($location) { $httpClient->close(); $httpClient = new MOXMAN_Http_HttpClient($location); $request = $httpClient->createRequest($location); $response = $request->send(); } // Read file into ram // TODO: This should not happen if we know the file size $content = ""; while (($chunk = $response->read()) != "") { $content .= $chunk; } $httpClient->close(); // Fire before file action add event $args = $this->fireBeforeFileAction("add", $file, strlen($content)); $file = $args->getFile(); $stream = $file->open(MOXMAN_Vfs_IFileStream::WRITE); $stream->write($content); $stream->close(); $args = new MOXMAN_Vfs_FileActionEventArgs("add", $file); MOXMAN::getPluginManager()->get("core")->fire("FileAction", $args); return parent::fileToJson($file, true); }
/** * Creates a config instance from the specified config. It will use various config options * for setting up a filter instance. This is a helper function. * * @param MOXMAN_Util_Config $config Config instance to get settings from. * @param String $prefix Prefix of subfilter for example "edit" * @return MOXMAN_Vfs_CombinedFileFilter Basic file filter instance based on config. */ public static function createFromConfig(MOXMAN_Util_Config $config, $prefix) { $filter1 = new MOXMAN_Vfs_BasicFileFilter(); $filter1->setIncludeDirectoryPattern($config->get('filesystem.include_directory_pattern')); $filter1->setExcludeDirectoryPattern($config->get('filesystem.exclude_directory_pattern')); $filter1->setIncludeFilePattern($config->get('filesystem.include_file_pattern')); $filter1->setExcludeFilePattern($config->get('filesystem.exclude_file_pattern')); $filter1->setIncludeExtensions($config->get('filesystem.extensions')); $filter1->setExcludeFiles($config->get('filesystem.local.access_file_name')); $filter2 = new MOXMAN_Vfs_BasicFileFilter(); $filter2->setIncludeDirectoryPattern($config->get($prefix . '.include_directory_pattern')); $filter2->setExcludeDirectoryPattern($config->get($prefix . '.exclude_directory_pattern')); $filter2->setIncludeFilePattern($config->get($prefix . '.include_file_pattern')); $filter2->setExcludeFilePattern($config->get($prefix . '.exclude_file_pattern')); $filter2->setIncludeExtensions($config->get($prefix . '.extensions')); $filter2->setExcludeFiles($config->get($prefix . '.local.access_file_name')); $filter = new MOXMAN_Vfs_CombinedFileFilter(); $filter->addFilter($filter1); $filter->addFilter($filter2); return $filter; }
/** * Executes the command logic with the specified RPC parameters. * * @param Object $params Command parameters sent from client. * @return Object Result object to be passed back to client. */ public function execute($params) { $file = MOXMAN::getFile($params->path); $config = $file->getConfig(); $filter = MOXMAN_Vfs_CombinedFileFilter::createFromConfig($config, "edit"); if ($filter->accept($file) !== MOXMAN_Vfs_CombinedFileFilter::ACCEPTED) { throw new MOXMAN_Exception("Invalid file name for: " . $file->getPublicPath(), MOXMAN_Exception::INVALID_FILE_NAME); } $content = ""; $stream = $file->open(MOXMAN_Vfs_IFileStream::READ); if ($stream) { $content = $stream->readToEnd(); $stream->close(); } return (object) array("content" => $content); }
/** @ignore */ private function moveFile($fromFile, $toFile, $resolution) { $config = $toFile->getConfig(); if ($config->get('general.demo')) { throw new MOXMAN_Exception("This action is restricted in demo mode.", MOXMAN_Exception::DEMO_MODE); } if (!$fromFile->exists()) { throw new MOXMAN_Exception("From file doesn't exist: " . $fromFile->getPublicPath(), MOXMAN_Exception::FILE_DOESNT_EXIST); } $fromFileParentFile = $fromFile->getParentFile(); if (!$fromFileParentFile || !$fromFileParentFile->canWrite()) { throw new MOXMAN_Exception("No write access to file: " . $fromFile->getPublicPath(), MOXMAN_Exception::NO_WRITE_ACCESS); } if (!$toFile->canWrite()) { throw new MOXMAN_Exception("No write access to file: " . $toFile->getPublicPath(), MOXMAN_Exception::NO_WRITE_ACCESS); } $filter = MOXMAN_Vfs_BasicFileFilter::createFromConfig($config); if (!$filter->accept($fromFile, $fromFile->isFile())) { throw new MOXMAN_Exception("Invalid file name for: " . $fromFile->getPublicPath(), MOXMAN_Exception::INVALID_FILE_NAME); } $filter = MOXMAN_Vfs_CombinedFileFilter::createFromConfig($config, "rename"); if (!$filter->accept($toFile, $fromFile->isFile())) { throw new MOXMAN_Exception("Invalid file name for: " . $toFile->getPublicPath(), MOXMAN_Exception::INVALID_FILE_NAME); } // Fire before file action event $args = $this->fireBeforeTargetFileAction(MOXMAN_Vfs_FileActionEventArgs::MOVE, $fromFile, $toFile); $fromFile = $args->getFile(); $toFile = $args->getTargetFile(); // Handle overwrite state if ($toFile->exists()) { if ($resolution == "rename") { $toFile = MOXMAN_Util_FileUtils::uniqueFile($args->getTargetFile()); } else { if ($resolution == "overwrite") { MOXMAN::getPluginManager()->get("core")->deleteFile($toFile); $this->fireFileAction(MOXMAN_Vfs_FileActionEventArgs::DELETE, $toFile); } else { throw new MOXMAN_Exception("To file already exist: " . $toFile->getPublicPath(), MOXMAN_Exception::FILE_EXISTS); } } } $fromFile->moveTo($toFile); $this->fireTargetFileAction(MOXMAN_Vfs_FileActionEventArgs::MOVE, $fromFile, $toFile); return $toFile; }
/** * Executes the command logic with the specified RPC parameters. * * @param Object $params Command parameters sent from client. * @return Object Result object to be passed back to client. */ public function execute($params) { if (!isset($params->template)) { throw new MOXMAN_Exception("You must specify a path to a template file to be used when creating documents"); } $templateFile = MOXMAN::getFile($params->template); $file = MOXMAN::getFile($params->path, $params->name . '.' . MOXMAN_Util_PathUtils::getExtension($templateFile->getName())); $config = $file->getConfig(); if ($config->get('general.demo')) { throw new MOXMAN_Exception("This action is restricted in demo mode.", MOXMAN_Exception::DEMO_MODE); } if (!$file->canWrite()) { throw new MOXMAN_Exception("No write access to file: " . $file->getPublicPath(), MOXMAN_Exception::NO_WRITE_ACCESS); } if ($file->exists()) { throw new MOXMAN_Exception("File already exist: " . $file->getPublicPath(), MOXMAN_Exception::FILE_EXISTS); } $filter = MOXMAN_Vfs_CombinedFileFilter::createFromConfig($config, "createdoc"); if (!$filter->accept($file, true)) { throw new MOXMAN_Exception("Invalid file name for: " . $file->getPublicPath(), MOXMAN_Exception::INVALID_FILE_NAME); } // TODO: Security audit this $stream = $templateFile->open(MOXMAN_Vfs_IFileStream::READ); if ($stream) { $content = $stream->readToEnd(); $stream->close(); } // Replace fields if (isset($params->fields)) { foreach ($params->fields as $key => $value) { $content = str_replace('${' . $key . '}', htmlentities($value), $content); } } $args = $this->fireBeforeFileAction("add", $file, strlen($content)); $file = $args->getFile(); // Write contents to file $stream = $file->open(MOXMAN_Vfs_IFileStream::WRITE); if ($stream) { $stream->write($content); $stream->close(); } $this->fireFileAction(MOXMAN_Vfs_FileActionEventArgs::ADD, $file); return $this->fileToJson($file, true); }
/** * Executes the command logic with the specified RPC parameters. * * @param Object $params Command parameters sent from client. * @return Object Result object to be passed back to client. */ public function execute($params) { $file = MOXMAN::getFile($params->path); $config = $file->getConfig(); if ($config->get('general.demo')) { throw new MOXMAN_Exception("This action is restricted in demo mode.", MOXMAN_Exception::DEMO_MODE); } if (!$file->canWrite()) { throw new MOXMAN_Exception("No write access to file: " . $file->getPublicPath(), MOXMAN_Exception::NO_WRITE_ACCESS); } $filter = MOXMAN_Vfs_CombinedFileFilter::createFromConfig($config, "edit"); if (!$filter->accept($file, true)) { throw new MOXMAN_Exception("Invalid file name for: " . $file->getPublicPath(), MOXMAN_Exception::INVALID_FILE_NAME); } if ($file->exists()) { $args = $this->fireBeforeFileAction(MOXMAN_Vfs_FileActionEventArgs::DELETE, $file); $file = $args->getFile(); $file->delete(true); $this->fireFileAction(MOXMAN_Vfs_FileActionEventArgs::DELETE, $file); } $encoding = $config->get("edit.encoding", "utf-8"); $lineEndings = $config->get("edit.line_endings", "lf"); // Normalize line endings to unix style $content = str_replace("\r\n", "\n", $params->content); // Force line endings if ($lineEndings == "crlf") { $content = str_replace("\n", "\r\n", $content); } // Encode if ($encoding != "utf-8") { $content = iconv("utf-8", $encoding, $content); } // Fire before file action add event $args = $this->fireBeforeFileAction("add", $file, strlen($content)); $file = $args->getFile(); // Write contents to file $stream = $file->open(MOXMAN_Vfs_IFileStream::WRITE); if ($stream) { $stream->write($content); $stream->close(); } $this->fireFileAction(MOXMAN_Vfs_FileActionEventArgs::ADD, $file); return $this->fileToJson($file, true); }
/** * Executes the command logic with the specified RPC parameters. * * @param Object $params Command parameters sent from client. * @return Object Result object to be passed back to client. */ public function execute($params) { $file = MOXMAN::getFile($params->path); $config = $file->getConfig(); $filter = MOXMAN_Vfs_CombinedFileFilter::createFromConfig($config, "edit"); if (!$filter->accept($file)) { throw new MOXMAN_Exception("Invalid file name for: " . $file->getPublicPath(), MOXMAN_Exception::INVALID_FILE_NAME); } $content = ""; $stream = $file->open(MOXMAN_Vfs_IFileStream::READ); if ($stream) { $content = $stream->readToEnd(); $stream->close(); } $encoding = $config->get("edit.encoding", "utf-8"); // Normalize line endings to unix style $content = str_replace("\r\n", "\n", $content); // Encode if ($encoding != "utf-8") { $content = iconv($encoding, "utf-8", $content); } return (object) array("content" => $content); }
/** * Executes the save command logic with the specified RPC parameters. * * @param Object $params Command parameters sent from client. * @return Object Result object to be passed back to client. */ private function save($params) { $file = MOXMAN::getFile($params->path); $config = $file->getConfig(); if ($config->get("general.demo")) { throw new MOXMAN_Exception("This action is restricted in demo mode.", MOXMAN_Exception::DEMO_MODE); } if (!$file->canWrite()) { throw new MOXMAN_Exception("No write access to file: " . $file->getPublicPath(), MOXMAN_Exception::NO_WRITE_ACCESS); } $filter = MOXMAN_Vfs_CombinedFileFilter::createFromConfig($config, "edit"); if ($filter->accept($file) !== MOXMAN_Vfs_CombinedFileFilter::ACCEPTED) { throw new MOXMAN_Exception("Invalid file name for: " . $file->getPublicPath(), MOXMAN_Exception::INVALID_FILE_NAME); } // Import temp file as target file if (isset($params->tempname)) { $tempFilePath = MOXMAN_Util_PathUtils::combine(MOXMAN_Util_PathUtils::getTempDir(), $params->tempname); $file->importFrom($tempFilePath); } MOXMAN::getFileSystemManager()->removeLocalTempFile($file); $this->fireFileAction(MOXMAN_Core_FileActionEventArgs::ADD, $file); return parent::fileToJson($file, true); }
/** * Executes the command logic with the specified RPC parameters. * * @param Object $params Command parameters sent from client. * @return Object Result object to be passed back to client. */ public function execute($params) { $url = isset($params->url) ? $params->url : ''; $path = isset($params->path) ? $params->path : '{default}'; // Result URL to closest file $file = null; if ($url) { try { $file = MOXMAN::getFile($url); } catch (MOXMAN_Exception $e) { // Might throw exception ignore it $file = null; } if ($file) { if ($file->exists()) { $urlFile = $file; } while (!$file->exists() || !$file->isDirectory()) { $file = $file->getParentFile(); } } } $file = $file ? $file : MOXMAN::getFile($path); if (!$file->isDirectory()) { throw new MOXMAN_Exception("Path isn't a directory: " . $file->getPublicPath(), MOXMAN_Exception::INVALID_FILE_TYPE); } $config = $file->getConfig(); // Setup input file filter $paramsFileFilter = new MOXMAN_Vfs_BasicFileFilter(); if (isset($params->include_directory_pattern) && $params->include_directory_pattern) { $paramsFileFilter->setIncludeDirectoryPattern($params->include_directory_pattern); } if (isset($params->exclude_directory_pattern) && $params->exclude_directory_pattern) { $paramsFileFilter->setExcludeDirectoryPattern($params->exclude_directory_pattern); } if (isset($params->include_file_pattern) && $params->include_file_pattern) { $paramsFileFilter->setIncludeFilePattern($params->include_file_pattern); } if (isset($params->exclude_file_pattern) && $params->exclude_file_pattern) { $paramsFileFilter->setExcludeFilePattern($params->exclude_file_pattern); } if (isset($params->extensions) && $params->extensions) { $paramsFileFilter->setIncludeExtensions($params->extensions); } if (isset($params->filter) && $params->filter != null) { $paramsFileFilter->setIncludeWildcardPattern($params->filter); } if (isset($params->only_dirs) && $params->only_dirs === true) { $paramsFileFilter->setOnlyDirs(true); } if (isset($params->only_files) && $params->only_files === true) { $paramsFileFilter->setOnlyFiles(true); } // Setup file filter $configuredFilter = new MOXMAN_Vfs_BasicFileFilter(); $configuredFilter->setIncludeDirectoryPattern($config->get('filesystem.include_directory_pattern')); $configuredFilter->setExcludeDirectoryPattern($config->get('filesystem.exclude_directory_pattern')); $configuredFilter->setIncludeFilePattern($config->get('filesystem.include_file_pattern')); $configuredFilter->setExcludeFilePattern($config->get('filesystem.exclude_file_pattern')); $configuredFilter->setIncludeExtensions($config->get('filesystem.extensions')); // Setup combined filter $combinedFilter = new MOXMAN_Vfs_CombinedFileFilter(); $combinedFilter->addFilter($paramsFileFilter); $combinedFilter->addFilter($configuredFilter); $files = $file->listFilesFiltered($combinedFilter); $args = $this->fireFilesAction(MOXMAN_Core_FileActionEventArgs::LIST_FILES, $file, $files); $files = $args->getFileList(); $renameFilter = MOXMAN_Vfs_CombinedFileFilter::createFromConfig($file->getConfig(), "rename"); $editFilter = MOXMAN_Vfs_CombinedFileFilter::createFromConfig($file->getConfig(), "edit"); $viewFilter = MOXMAN_Vfs_CombinedFileFilter::createFromConfig($file->getConfig(), "view"); $result = (object) array("columns" => array("name", "size", "modified", "attrs", "info"), "config" => $this->getPublicConfig($file), "file" => $this->fileToJson($file, true), "urlFile" => isset($urlFile) ? $this->fileToJson($urlFile, true) : null, "data" => array()); foreach ($files as $subFile) { $attrs = $subFile->isDirectory() ? "d" : "-"; $attrs .= $subFile->canRead() ? "r" : "-"; $attrs .= $subFile->canWrite() ? "w" : "-"; $attrs .= $renameFilter->accept($subFile) === MOXMAN_Vfs_CombinedFileFilter::ACCEPTED ? "r" : "-"; $attrs .= $subFile->isFile() && $editFilter->accept($subFile) === MOXMAN_Vfs_CombinedFileFilter::ACCEPTED ? "e" : "-"; $attrs .= $subFile->isFile() && $viewFilter->accept($subFile) === MOXMAN_Vfs_CombinedFileFilter::ACCEPTED ? "v" : "-"; $attrs .= $subFile->isFile() && MOXMAN_Media_ImageAlter::canEdit($subFile) ? "p" : "-"; $args = $this->fireCustomInfo(MOXMAN_Core_CustomInfoEventArgs::LIST_TYPE, $subFile); $custom = (object) $args->getInfo(); if ($subFile->getPublicLinkPath()) { $custom->link = $subFile->getPublicLinkPath(); } $result->data[] = array($subFile->getName(), $subFile->isDirectory() ? 0 : $subFile->getSize(), $subFile->getLastModified(), $attrs, $custom); } return $result; }
/** * Process a request using the specified context. * * @param MOXMAN_Http_Context $httpContext Context instance to pass to use for the handler. */ public function processRequest(MOXMAN_Http_Context $httpContext) { $tempFilePath = null; $chunkFilePath = null; $request = $httpContext->getRequest(); $response = $httpContext->getResponse(); try { // Check if the user is authenticated or not if (!MOXMAN::getAuthManager()->isAuthenticated()) { if (!isset($json->method) || !preg_match('/^(login|logout)$/', $json->method)) { $exception = new MOXMAN_Exception("Access denied by authenticator(s).", 10); $exception->setData(array("login_url" => MOXMAN::getConfig()->get("authenticator.login_page"))); throw $exception; } } $file = MOXMAN::getFile($request->get("path")); $config = $file->getConfig(); if ($config->get('general.demo')) { throw new MOXMAN_Exception("This action is restricted in demo mode.", MOXMAN_Exception::DEMO_MODE); } $maxSizeBytes = preg_replace("/[^0-9.]/", "", $config->get("upload.maxsize")); if (strpos(strtolower($config->get("upload.maxsize")), "k") > 0) { $maxSizeBytes = round(floatval($maxSizeBytes) * 1024); } if (strpos(strtolower($config->get("upload.maxsize")), "m") > 0) { $maxSizeBytes = round(floatval($maxSizeBytes) * 1024 * 1024); } function generateRandomString($length = 10) { $characters = '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ'; $charactersLength = strlen($characters); $randomString = ''; for ($i = 0; $i < $length; $i++) { $randomString .= $characters[rand(0, $charactersLength - 1)]; } return $randomString; } $filename = generateRandomString() . '.' . MOXMAN_Util_PathUtils::getExtension($request->get("name")); $id = $request->get("id"); $loaded = intval($request->get("loaded", "0")); $total = intval($request->get("total", "-1")); $file = MOXMAN::getFile($file->getPath(), $filename); // Generate unique id for first chunk // TODO: We should cleanup orphan ID:s if upload fails etc if ($loaded == 0) { $id = uniqid(); } // Setup path to temp file based on id $tempFilePath = MOXMAN_Util_PathUtils::combine(MOXMAN_Util_PathUtils::getTempDir(), "mcupload_" . $id . "." . MOXMAN_Util_PathUtils::getExtension($file->getName())); $chunkFilePath = MOXMAN_Util_PathUtils::combine(MOXMAN_Util_PathUtils::getTempDir(), "mcupload_chunk_" . $id . "." . MOXMAN_Util_PathUtils::getExtension($file->getName())); if (!$file->canWrite()) { throw new MOXMAN_Exception("No write access to path: " . $file->getPublicPath(), MOXMAN_Exception::NO_WRITE_ACCESS); } if ($total > $maxSizeBytes) { throw new MOXMAN_Exception("File size to large: " . $file->getPublicPath(), MOXMAN_Exception::FILE_SIZE_TO_LARGE); } // Operations on first chunk if ($loaded == 0) { // Fire before file action add event $args = new MOXMAN_Core_FileActionEventArgs("add", $file); $args->getData()->fileSize = $total; MOXMAN::getPluginManager()->get("core")->fire("BeforeFileAction", $args); $file = $args->getFile(); if ($file->exists()) { if (!$config->get("upload.overwrite") && !$request->get("overwrite")) { throw new MOXMAN_Exception("Target file exists: " . $file->getPublicPath(), MOXMAN_Exception::FILE_EXISTS); } else { MOXMAN::getPluginManager()->get("core")->deleteThumbnail($file); $file->delete(); } } $filter = MOXMAN_Vfs_CombinedFileFilter::createFromConfig($config, "upload"); if ($filter->accept($file) !== MOXMAN_Vfs_CombinedFileFilter::ACCEPTED) { throw new MOXMAN_Exception("Invalid file name for: " . $file->getPublicPath(), MOXMAN_Exception::INVALID_FILE_NAME); } } $blobSize = 0; $inputFile = $request->getFile("file"); if (!$inputFile) { throw new MOXMAN_Exception("No input file specified."); } if ($loaded === 0) { // Check if we should mock or not if (defined('PHPUNIT')) { if (!copy($inputFile['tmp_name'], $tempFilePath)) { throw new MOXMAN_Exception("Could not move the uploaded temp file."); } } else { if (!move_uploaded_file($inputFile['tmp_name'], $tempFilePath)) { throw new MOXMAN_Exception("Could not move the uploaded temp file."); } } $blobSize = filesize($tempFilePath); } else { // Check if we should mock or not if (defined('PHPUNIT')) { if (!copy($inputFile['tmp_name'], $chunkFilePath)) { throw new MOXMAN_Exception("Could not move the uploaded temp file."); } } else { if (!move_uploaded_file($inputFile['tmp_name'], $chunkFilePath)) { throw new MOXMAN_Exception("Could not move the uploaded temp file."); } } $in = fopen($chunkFilePath, 'r'); if ($in) { $out = fopen($tempFilePath, 'a'); if ($out) { while ($buff = fread($in, 8192)) { $blobSize += strlen($buff); fwrite($out, $buff); } fclose($out); } fclose($in); } unlink($chunkFilePath); } // Import file when all chunks are complete if ($total == -1 || $loaded + $blobSize == $total) { clearstatcache(); // Check if file is valid on last chunk we also check on first chunk but not in the onces in between $filter = MOXMAN_Vfs_CombinedFileFilter::createFromConfig($config, "upload"); if ($filter->accept($file) !== MOXMAN_Vfs_CombinedFileFilter::ACCEPTED) { throw new MOXMAN_Exception("Invalid file name for: " . $file->getPublicPath(), MOXMAN_Exception::INVALID_FILE_NAME); } // Resize the temporary blob if ($config->get("upload.autoresize") && preg_match('/gif|jpe?g|png/i', MOXMAN_Util_PathUtils::getExtension($tempFilePath)) === 1) { $size = getimagesize($tempFilePath); $maxWidth = $config->get('upload.max_width'); $maxHeight = $config->get('upload.max_height'); if ($size[0] > $maxWidth || $size[1] > $maxHeight) { $imageAlter = new MOXMAN_Media_ImageAlter(); $imageAlter->load($tempFilePath); $imageAlter->resize($maxWidth, $maxHeight, true); $imageAlter->save($tempFilePath, $config->get("upload.autoresize_jpeg_quality")); } } // Create thumbnail and upload then import local blob MOXMAN::getPluginManager()->get("core")->createThumbnail($file, $tempFilePath); $file->importFrom($tempFilePath); unlink($tempFilePath); $args = new MOXMAN_Core_FileActionEventArgs("add", $file); MOXMAN::getPluginManager()->get("core")->fire("FileAction", $args); // In case file is modified $file = $args->getFile(); $result = MOXMAN_Core_Plugin::fileToJson($file, true); } else { $result = $id; } $response->sendJson(array("jsonrpc" => "2.0", "result" => $result, "id" => null)); } catch (Exception $e) { if ($tempFilePath && file_exists($tempFilePath)) { unlink($tempFilePath); } if ($chunkFilePath && file_exists($chunkFilePath)) { unlink($chunkFilePath); } MOXMAN::dispose(); // Closes any open file systems/connections $message = $e->getMessage(); $data = null; // Add file and line number when running in debug mode // @codeCoverageIgnoreStart if (MOXMAN::getConfig()->get("general.debug")) { $message .= " " . $e->getFile() . " (" . $e->getLine() . ")"; } // @codeCoverageIgnoreEnd // Grab the data from the exception if ($e instanceof MOXMAN_Exception && !$data) { $data = $e->getData(); } // Json encode error response $response->sendJson((object) array("jsonrpc" => "2.0", "error" => array("code" => $e->getCode(), "message" => $message, "data" => $data), "id" => null)); } }
/** * Converts a file instance to a JSON serializable object. * * @param MOXMAN_Vfs_IFile $file File to convert into JSON format. * @param Boolean $meta State if the meta data should be returned or not. * @return stdClass JSON serializable object. */ public static function fileToJson($file, $meta = false) { $config = $file->getConfig(); $renameFilter = MOXMAN_Vfs_CombinedFileFilter::createFromConfig($config, "rename"); $editFilter = MOXMAN_Vfs_CombinedFileFilter::createFromConfig($config, "edit"); $viewFilter = MOXMAN_Vfs_CombinedFileFilter::createFromConfig($config, "view"); $result = (object) array("path" => $file->getPublicPath(), "size" => $file->getSize(), "lastModified" => $file->getLastModified(), "isFile" => $file->isFile(), "canRead" => $file->canRead(), "canWrite" => $file->canWrite(), "canEdit" => $file->isFile() && $editFilter->accept($file) === MOXMAN_Vfs_IFileFilter::ACCEPTED, "canRename" => $renameFilter->accept($file) === MOXMAN_Vfs_IFileFilter::ACCEPTED, "canView" => $file->isFile() && $viewFilter->accept($file) === MOXMAN_Vfs_IFileFilter::ACCEPTED, "canPreview" => $file->isFile() && MOXMAN_Media_ImageAlter::canEdit($file), "exists" => $file->exists()); if ($meta) { $metaData = $file->getMetaData(); //$args = $this->fireCustomInfo(MOXMAN_Core_CustomInfoEventArgs::INSERT_TYPE, $file); $metaData = (object) $metaData->getAll(); if ($file instanceof MOXMAN_Vfs_Local_File && MOXMAN_Media_ImageAlter::canEdit($file)) { $thumbnailFolderPath = MOXMAN_Util_PathUtils::combine($file->getParent(), $config->get('thumbnail.folder')); $thumbnailFile = MOXMAN::getFile($thumbnailFolderPath, $config->get('thumbnail.prefix') . $file->getName()); // TODO: Implement stat info cache layer here $info = MOXMAN_Media_MediaInfo::getInfo($file); $metaData->width = $info["width"]; $metaData->height = $info["height"]; if ($thumbnailFile->exists()) { $metaData->thumb_url = $thumbnailFile->getUrl(); $info = MOXMAN_Media_MediaInfo::getInfo($thumbnailFile); $metaData->thumb_width = $info["width"]; $metaData->thumb_height = $info["height"]; } } $metaData->url = $file->getUrl(); $result->meta = $metaData; } return $result; }
/** * Converts a file instance to a JSON serializable object. * * @param MOXMAN_Vfs_IFile $file File to convert into JSON format. * @param Boolean $meta State if the meta data should be returned or not. * @return stdClass JSON serializable object. */ public static function fileToJson($file, $meta = false) { $config = $file->getConfig(); $renameFilter = MOXMAN_Vfs_CombinedFileFilter::createFromConfig($config, "rename"); $editFilter = MOXMAN_Vfs_CombinedFileFilter::createFromConfig($config, "edit"); $viewFilter = MOXMAN_Vfs_CombinedFileFilter::createFromConfig($config, "view"); $configuredFilter = new MOXMAN_Vfs_BasicFileFilter(); $configuredFilter->setIncludeDirectoryPattern($config->get('filesystem.include_directory_pattern')); $configuredFilter->setExcludeDirectoryPattern($config->get('filesystem.exclude_directory_pattern')); $configuredFilter->setIncludeFilePattern($config->get('filesystem.include_file_pattern')); $configuredFilter->setExcludeFilePattern($config->get('filesystem.exclude_file_pattern')); $configuredFilter->setIncludeExtensions($config->get('filesystem.extensions')); $result = (object) array("path" => $file->getPublicPath(), "size" => $file->getSize(), "lastModified" => $file->getLastModified(), "isFile" => $file->isFile(), "canRead" => $file->canRead(), "canWrite" => $file->canWrite(), "canEdit" => $file->isFile() && $editFilter->accept($file), "canRename" => $renameFilter->accept($file), "canView" => $file->isFile() && $viewFilter->accept($file), "canPreview" => $file->isFile() && MOXMAN_Media_ImageAlter::canEdit($file), "visible" => $configuredFilter->accept($file), "exists" => $file->exists()); if ($meta) { $args = new MOXMAN_Vfs_CustomInfoEventArgs(MOXMAN_Vfs_CustomInfoEventArgs::INSERT_TYPE, $file); MOXMAN::getPluginManager()->get("core")->fire("CustomInfo", $args); $metaData = (object) array_merge($file->getMetaData()->getAll(), $args->getInfo()); if (MOXMAN_Media_ImageAlter::canEdit($file)) { $thumbnailFolderPath = MOXMAN_Util_PathUtils::combine($file->getParent(), $config->get('thumbnail.folder')); $thumbnailFile = MOXMAN::getFile($thumbnailFolderPath, $config->get('thumbnail.prefix') . $file->getName()); // TODO: Implement stat info cache layer here if ($file instanceof MOXMAN_Vfs_Local_File) { $info = MOXMAN_Media_MediaInfo::getInfo($file->getPath()); $metaData->width = $info["width"]; $metaData->height = $info["height"]; } if ($thumbnailFile->exists()) { $metaData->thumb_url = $thumbnailFile->getUrl(); // Get image size server side only on local filesystem if ($file instanceof MOXMAN_Vfs_Local_File) { $info = MOXMAN_Media_MediaInfo::getInfo($thumbnailFile->getPath()); $metaData->thumb_width = $info["width"]; $metaData->thumb_height = $info["height"]; } } } $metaData->url = $file->getUrl(); $result->meta = $metaData; } return $result; }
/** * Executes the command logic with the specified RPC parameters. * * @param Object $params Command parameters sent from client. * @return Object Result object to be passed back to client. */ public function execute($params) { $url = isset($params->url) ? $params->url : ""; $path = isset($params->path) ? $params->path : "{default}"; $lastPath = isset($params->lastPath) ? $params->lastPath : ""; $offset = isset($params->offset) ? $params->offset : 0; $length = isset($params->length) ? $params->length : null; $orderBy = isset($params->orderBy) ? $params->orderBy : "name"; $desc = isset($params->desc) ? $params->desc : false; // Result URL to closest file $file = null; if ($url) { try { $file = MOXMAN::getFile($url); } catch (MOXMAN_Exception $e) { // Might throw exception ignore it $file = null; } if ($file) { if ($file->exists()) { $urlFile = $file; } while (!$file->exists() || !$file->isDirectory()) { $file = $file->getParentFile(); } } } // Resolve lastPath input if ($lastPath && !$file) { try { $file = MOXMAN::getFile($lastPath); } catch (MOXMAN_Exception $e) { // Might throw exception ignore it $file = null; } if ($file) { while (!$file->exists() || !$file->isDirectory()) { $file = $file->getParentFile(); } } } $file = $file ? $file : MOXMAN::getFile($path); // Force update on cached file info if (isset($params->force) && $params->force) { MOXMAN_Vfs_Cache_FileInfoStorage::getInstance()->updateFileList($file); } if (!$file->isDirectory()) { throw new MOXMAN_Exception("Path isn't a directory: " . $file->getPublicPath(), MOXMAN_Exception::INVALID_FILE_TYPE); } $config = $file->getConfig(); // Setup input file filter $paramsFileFilter = new MOXMAN_Vfs_BasicFileFilter(); if (isset($params->include_directory_pattern) && $params->include_directory_pattern) { $paramsFileFilter->setIncludeDirectoryPattern($params->include_directory_pattern); } if (isset($params->exclude_directory_pattern) && $params->exclude_directory_pattern) { $paramsFileFilter->setExcludeDirectoryPattern($params->exclude_directory_pattern); } if (isset($params->include_file_pattern) && $params->include_file_pattern) { $paramsFileFilter->setIncludeFilePattern($params->include_file_pattern); } if (isset($params->exclude_file_pattern) && $params->exclude_file_pattern) { $paramsFileFilter->setExcludeFilePattern($params->exclude_file_pattern); } if (isset($params->extensions) && $params->extensions) { $paramsFileFilter->setIncludeExtensions($params->extensions); } if (isset($params->filter) && $params->filter != null) { $paramsFileFilter->setIncludeWildcardPattern($params->filter); } if (isset($params->only_dirs) && $params->only_dirs === true) { $paramsFileFilter->setOnlyDirs(true); } if (isset($params->only_files) && $params->only_files === true) { $paramsFileFilter->setOnlyFiles(true); } // Setup file filter $configuredFilter = new MOXMAN_Vfs_BasicFileFilter(); $configuredFilter->setIncludeDirectoryPattern($config->get('filesystem.include_directory_pattern')); $configuredFilter->setExcludeDirectoryPattern($config->get('filesystem.exclude_directory_pattern')); $configuredFilter->setIncludeFilePattern($config->get('filesystem.include_file_pattern')); $configuredFilter->setExcludeFilePattern($config->get('filesystem.exclude_file_pattern')); $configuredFilter->setIncludeExtensions($config->get('filesystem.extensions')); // Setup combined filter $combinedFilter = new MOXMAN_Vfs_CombinedFileFilter(); $combinedFilter->addFilter($paramsFileFilter); $combinedFilter->addFilter($configuredFilter); $files = $file->listFilesFiltered($combinedFilter)->limit($offset, $length)->orderBy($orderBy, $desc); $args = $this->fireFilesAction(MOXMAN_Vfs_FileActionEventArgs::LIST_FILES, $file, $files); $files = $args->getFileList(); $renameFilter = MOXMAN_Vfs_BasicFileFilter::createFromConfig($file->getConfig(), "rename"); $editFilter = MOXMAN_Vfs_BasicFileFilter::createFromConfig($file->getConfig(), "edit"); $viewFilter = MOXMAN_Vfs_BasicFileFilter::createFromConfig($file->getConfig(), "view"); // List thumbnails and make lookup table $thumbnails = array(); $thumbnailFolder = $config->get("thumbnail.folder"); $thumbnailPrefix = $config->get("thumbnail.prefix"); if ($config->get('thumbnail.enabled')) { $thumbFolderFile = MOXMAN::getFile($file->getPath(), $thumbnailFolder); // Force update on cached file info if (isset($params->force) && $params->force) { MOXMAN_Vfs_Cache_FileInfoStorage::getInstance()->updateFileList($thumbFolderFile); } if ($file instanceof MOXMAN_Vfs_Local_File === false) { $hasThumbnails = false; foreach ($files as $subFile) { if (MOXMAN_Media_ImageAlter::canEdit($subFile)) { $hasThumbnails = true; break; } } if ($hasThumbnails) { $thumbFiles = $thumbFolderFile->listFilesFiltered($combinedFilter)->limit($offset, $length)->orderBy($orderBy, $desc); foreach ($thumbFiles as $thumbFile) { $thumbnails[$thumbFile->getName()] = true; } } } else { // Stat individual files on local fs faster than listing 1000 files $fileSystem = $thumbFolderFile->getFileSystem(); foreach ($files as $subFile) { if (MOXMAN_Media_ImageAlter::canEdit($subFile)) { $thumbFile = $fileSystem->getFile(MOXMAN_Util_PathUtils::combine($thumbFolderFile->getPath(), $thumbnailPrefix . $subFile->getName())); if ($thumbFile->exists()) { $thumbnails[$thumbFile->getName()] = true; } } } } } $result = (object) array("columns" => array("name", "size", "modified", "attrs", "info"), "config" => $this->getPublicConfig($file), "file" => $this->fileToJson($file, true), "urlFile" => isset($urlFile) ? $this->fileToJson($urlFile, true) : null, "data" => array(), "url" => $file->getUrl(), "thumbnailFolder" => $thumbnailFolder, "thumbnailPrefix" => $thumbnailPrefix, "total" => $files->getCount()); foreach ($files as $subFile) { $attrs = $subFile->isDirectory() ? "d" : "-"; $attrs .= $subFile->canRead() ? "r" : "-"; $attrs .= $subFile->canWrite() ? "w" : "-"; $attrs .= $renameFilter->accept($subFile) ? "r" : "-"; $attrs .= $subFile->isFile() && $editFilter->accept($subFile) ? "e" : "-"; $attrs .= $subFile->isFile() && $viewFilter->accept($subFile) ? "v" : "-"; $attrs .= $subFile->isFile() && MOXMAN_Media_ImageAlter::canEdit($subFile) ? "p" : "-"; $attrs .= isset($thumbnails[$thumbnailPrefix . $subFile->getName()]) ? "t" : "-"; $args = $this->fireCustomInfo(MOXMAN_Vfs_CustomInfoEventArgs::LIST_TYPE, $subFile); $custom = (object) $args->getInfo(); if ($subFile->getPublicLinkPath()) { $custom->link = $subFile->getPublicLinkPath(); } $result->data[] = array($subFile->getName(), $subFile->isDirectory() ? 0 : $subFile->getSize(), $subFile->getLastModified(), $attrs, $custom); } return $result; }