/** * @param AJXP_Node $ajxpNode * @return null|string */ protected function extractIndexableContent($ajxpNode) { $ext = strtolower(pathinfo($ajxpNode->getLabel(), PATHINFO_EXTENSION)); if (in_array($ext, explode(",", $this->getFilteredOption("PARSE_CONTENT_TXT")))) { return file_get_contents($ajxpNode->getUrl()); } $unoconv = $this->getFilteredOption("UNOCONV"); $pipe = false; if (!empty($unoconv) && in_array($ext, array("doc", "odt", "xls", "ods"))) { $targetExt = "txt"; if (in_array($ext, array("xls", "ods"))) { $targetExt = "csv"; } else { if (in_array($ext, array("odp", "ppt"))) { $targetExt = "pdf"; $pipe = true; } } $realFile = call_user_func(array($ajxpNode->wrapperClassName, "getRealFSReference"), $ajxpNode->getUrl()); $unoconv = "HOME=" . AJXP_Utils::getAjxpTmpDir() . " " . $unoconv . " --stdout -f {$targetExt} " . escapeshellarg($realFile); if ($pipe) { $newTarget = str_replace(".{$ext}", ".pdf", $realFile); $unoconv .= " > {$newTarget}"; register_shutdown_function("unlink", $newTarget); } $output = array(); exec($unoconv, $output, $return); if (!$pipe) { $out = implode("\n", $output); $enc = 'ISO-8859-1'; $asciiString = iconv($enc, 'ASCII//TRANSLIT//IGNORE', $out); return $asciiString; } else { $ext = "pdf"; } } $pdftotext = $this->getFilteredOption("PDFTOTEXT"); if (!empty($pdftotext) && in_array($ext, array("pdf"))) { $realFile = call_user_func(array($ajxpNode->wrapperClassName, "getRealFSReference"), $ajxpNode->getUrl()); if ($pipe && isset($newTarget) && is_file($newTarget)) { $realFile = $newTarget; } $cmd = $pdftotext . " " . escapeshellarg($realFile) . " -"; $output = array(); exec($cmd, $output, $return); $out = implode("\n", $output); $enc = 'UTF8'; $asciiString = iconv($enc, 'ASCII//TRANSLIT//IGNORE', $out); return $asciiString; } return null; }
/** * @param AJXP_Node $node * @param string $cacheType * @param string $details * @return string */ public static function computeIdForNode($node, $cacheType, $details = '') { $repo = $node->getRepository(); if ($repo == null) { return "failed-id"; } $scope = $repo->securityScope(); $additional = ""; if ($scope === "USER") { $additional = AuthService::getLoggedUser()->getId() . "@"; } else { if ($scope == "GROUP") { $additional = ltrim(str_replace("/", "__", AuthService::getLoggedUser()->getGroupPath()), "__") . "@"; } } $scheme = parse_url($node->getUrl(), PHP_URL_SCHEME); return str_replace($scheme . "://", $cacheType . "://" . $additional, $node->getUrl()) . ($details ? "##" . $details : ""); }
/** * * @param AJXP_Node $ajxpNode */ public function extractMeta(&$ajxpNode, $contextNode = false, $details = false) { $currentFile = $ajxpNode->getUrl(); $metadata = $this->metaStore->retrieveMetadata($ajxpNode, "users_meta", false, AJXP_METADATA_SCOPE_GLOBAL); if (count($metadata)) { // @todo : Should be UTF8-IZED at output only !!?? // array_map(array("SystemTextEncoding", "toUTF8"), $metadata); } $metadata["meta_fields"] = $this->options["meta_fields"]; $metadata["meta_labels"] = $this->options["meta_labels"]; $ajxpNode->mergeMetadata($metadata); }
/** * @param AJXP_Node $ajxpNode */ public function videoAlternateVersions(&$ajxpNode) { if (!preg_match('/\\.mpg$|\\.mp4$|\\.ogv$|\\.webm$/i', $ajxpNode->getLabel())) { return; } if (file_exists(str_replace(".mpg", "_PREVIEW.mp4", $ajxpNode->getUrl()))) { $ajxpNode->mergeMetadata(array("video_altversion_mp4" => str_replace(".mpg", "_PREVIEW.mp4", $ajxpNode->getPath()))); } $rotating = array("mp4", "ogv", "webm"); foreach ($rotating as $ext) { if (preg_match('/\\.' . $ext . '$/i', $ajxpNode->getLabel())) { foreach ($rotating as $other) { if ($other == $ext) { continue; } if (file_exists(str_replace($ext, $other, $ajxpNode->getUrl()))) { $ajxpNode->mergeMetadata(array("video_altversion_" . $other => str_replace($ext, $other, $ajxpNode->getPath()))); } } } } }
/** * @param AJXP_Node $ajxpNode */ public function detectDLParts(&$ajxpNode) { if (!preg_match("/\\.dlpart\$/i", $ajxpNode->getUrl())) { return; } $basename = basename($ajxpNode->getUrl()); $newName = "__" . str_replace(".dlpart", ".ser", $basename); $hidFile = str_replace($basename, $newName, $ajxpNode->getUrl()); if (is_file($hidFile)) { $data = unserialize(file_get_contents($hidFile)); if ($data["totalSize"] != -1) { $ajxpNode->target_bytesize = $data["totalSize"]; $ajxpNode->target_filesize = AJXP_Utils::roundSize($data["totalSize"]); $ajxpNode->process_stoppable = isset($data["pid"]) ? "true" : "false"; } } }
public function switchAction($action, $httpVars, $filesVars) { $repository = ConfService::getRepository(); if (!$repository->detectStreamWrapper(true)) { return false; } $selection = new UserSelection($repository, $httpVars); $selectedNode = $selection->getUniqueNode(); $selectedNodeUrl = $selectedNode->getUrl(); if ($action == "post_to_server") { // Backward compat if (strpos($httpVars["file"], "base64encoded:") !== 0) { $legacyFilePath = AJXP_Utils::decodeSecureMagic(base64_decode($httpVars["file"])); $selectedNode = new AJXP_Node($selection->currentBaseUrl() . $legacyFilePath); $selectedNodeUrl = $selectedNode->getUrl(); } $target = rtrim(base64_decode($httpVars["parent_url"]), '/') . "/plugins/editor.pixlr"; $tmp = AJXP_MetaStreamWrapper::getRealFSReference($selectedNodeUrl); $tmp = SystemTextEncoding::fromUTF8($tmp); $this->logInfo('Preview', 'Sending content of ' . $selectedNodeUrl . ' to Pixlr server.', array("files" => $selectedNodeUrl)); AJXP_Controller::applyHook("node.read", array($selectedNode)); $saveTarget = $target . "/fake_save_pixlr.php"; if ($this->getFilteredOption("CHECK_SECURITY_TOKEN", $repository->getId())) { $saveTarget = $target . "/fake_save_pixlr_" . md5($httpVars["secure_token"]) . ".php"; } $params = array("referrer" => "Pydio", "method" => "get", "loc" => ConfService::getLanguage(), "target" => $saveTarget, "exit" => $target . "/fake_close_pixlr.php", "title" => urlencode(basename($selectedNodeUrl)), "locktarget" => "false", "locktitle" => "true", "locktype" => "source"); require_once AJXP_BIN_FOLDER . "/http_class/http_class.php"; $arguments = array(); $httpClient = new http_class(); $httpClient->request_method = "POST"; $httpClient->GetRequestArguments("https://pixlr.com/editor/", $arguments); $arguments["PostValues"] = $params; $arguments["PostFiles"] = array("image" => array("FileName" => $tmp, "Content-Type" => "automatic/name")); $err = $httpClient->Open($arguments); if (empty($err)) { $err = $httpClient->SendRequest($arguments); if (empty($err)) { $response = ""; while (true) { $header = array(); $error = $httpClient->ReadReplyHeaders($header, 1000); if ($error != "" || $header != null) { break; } $response .= $header; } } } header("Location: {$header['location']}"); //$response"); } else { if ($action == "retrieve_pixlr_image") { $file = AJXP_Utils::decodeSecureMagic($httpVars["original_file"]); $selectedNode = new AJXP_Node($selection->currentBaseUrl() . $file); $selectedNode->loadNodeInfo(); $this->logInfo('Edit', 'Retrieving content of ' . $file . ' from Pixlr server.', array("files" => $file)); AJXP_Controller::applyHook("node.before_change", array(&$selectedNode)); $url = $httpVars["new_url"]; $urlParts = parse_url($url); $query = $urlParts["query"]; if ($this->getFilteredOption("CHECK_SECURITY_TOKEN", $repository->getId())) { $scriptName = basename($urlParts["path"]); $token = str_replace(array("fake_save_pixlr_", ".php"), "", $scriptName); if ($token != md5($httpVars["secure_token"])) { throw new AJXP_Exception("Invalid Token, this could mean some security problem!"); } } $params = array(); parse_str($query, $params); $image = $params['image']; $headers = get_headers($image, 1); $content_type = explode("/", $headers['Content-Type']); if ($content_type[0] != "image") { throw new AJXP_Exception("Invalid File Type"); } $content_length = intval($headers["Content-Length"]); if ($content_length != 0) { AJXP_Controller::applyHook("node.before_change", array(&$selectedNode, $content_length)); } $orig = fopen($image, "r"); $target = fopen($selectedNode->getUrl(), "w"); if (is_resource($orig) && is_resource($target)) { while (!feof($orig)) { fwrite($target, fread($orig, 4096)); } fclose($orig); fclose($target); } clearstatcache(true, $selectedNode->getUrl()); $selectedNode->loadNodeInfo(true); AJXP_Controller::applyHook("node.change", array(&$selectedNode, &$selectedNode)); } } }
/** * @param AJXP_Node $ajxpNode */ public function extractMeta(&$ajxpNode) { $currentFile = $ajxpNode->getUrl(); if (!$ajxpNode->isLeaf() || preg_match("/\\.zip\\//", $currentFile)) { return; } if (!preg_match("/\\.jpg\$|\\.jpeg\$|\\.tif\$|\\.tiff\$/i", $currentFile)) { return; } $definitions = $this->getMetaDefinition(); if (!count($definitions)) { return; } if (!function_exists("exif_read_data")) { return; } //if(!exif_imagetype($currentFile)) return ; $realFile = $ajxpNode->getRealFile(); $exif = @exif_read_data($realFile, 0, TRUE); $iptc = $this->extractIPTC($realFile); if ($exif === false) { return; } $additionalMeta = array(); foreach ($definitions as $def => $label) { list($exifSection, $exifName) = explode("-", $def); if ($exifSection == "COMPUTED_GPS" && !isset($exif["COMPUTED_GPS"])) { $exif['COMPUTED_GPS'] = $this->convertGPSData($exif); } if (isset($exif[$exifSection]) && isset($exif[$exifSection][$exifName])) { $additionalMeta[$def] = $exif[$exifSection][$exifName]; } if ($exifSection == "IPTC" && isset($iptc[$exifName])) { $additionalMeta[$def] = $iptc[$exifName]; } } $ajxpNode->mergeMetadata($additionalMeta); }
/** * * @param AJXP_Node $ajxpNode */ public function enrichMetadata(&$ajxpNode) { $currentNode = $ajxpNode->getUrl(); $metadata = $ajxpNode->metadata; $parsed = parse_url($currentNode); if (isset($parsed["fragment"]) && strpos($parsed["fragment"], "attachments") === 0) { list(, $attachmentId) = explode("/", $parsed["fragment"]); $meta = imapAccessWrapper::getCurrentAttachmentsMetadata(); if ($meta != null) { foreach ($meta as $attach) { if ($attach["x-attachment-id"] == $attachmentId) { $metadata["text"] = $attach["filename"]; $metadata["icon"] = AJXP_Utils::mimetype($attach["filename"], "image", false); $metadata["mimestring"] = AJXP_Utils::mimetype($attach["filename"], "text", false); } } } } if (!$metadata["is_file"] && $currentNode != "") { $metadata["icon"] = "imap_images/ICON_SIZE/mail_folder_sent.png"; } if (basename($currentNode) == "INBOX") { $metadata["text"] = "Incoming Mails"; } if (strstr($currentNode, "__delim__") !== false) { $parts = explode("/", $currentNode); $metadata["text"] = str_replace("__delim__", "/", array_pop($parts)); } $ajxpNode->metadata = $metadata; }
/** * * @param AJXP_Node $node * @param int $depth * @throws Exception */ public function recursiveIndexation($node, $depth = 0) { $repository = $node->getRepository(); $user = $node->getUser(); $messages = ConfService::getMessages(); if ($user == null && AuthService::usersEnabled()) { $user = AuthService::getLoggedUser(); } if ($depth == 0) { $this->logDebug("Starting indexation - node.index.recursive.start - " . memory_get_usage(true) . " - " . $node->getUrl()); $this->setIndexStatus("RUNNING", str_replace("%s", $node->getPath(), $messages["core.index.8"]), $repository, $user); AJXP_Controller::applyHook("node.index.recursive.start", array($node)); } else { if ($this->isInterruptRequired($repository, $user)) { $this->logDebug("Interrupting indexation! - node.index.recursive.end - " . $node->getUrl()); AJXP_Controller::applyHook("node.index.recursive.end", array($node)); $this->releaseStatus($repository, $user); throw new Exception("User interrupted"); } } if (!ConfService::currentContextIsCommandLine()) { @set_time_limit(120); } $url = $node->getUrl(); $this->logDebug("Indexing Node parent node " . $url); $this->setIndexStatus("RUNNING", str_replace("%s", $node->getPath(), $messages["core.index.8"]), $repository, $user); try { AJXP_Controller::applyHook("node.index", array($node)); } catch (Exception $e) { $this->logDebug("Error Indexing Node " . $url . " (" . $e->getMessage() . ")"); } $handle = opendir($url); if ($handle !== false) { while (($child = readdir($handle)) != false) { if ($child[0] == ".") { continue; } $childNode = new AJXP_Node(rtrim($url, "/") . "/" . $child); $childUrl = $childNode->getUrl(); if (is_dir($childUrl)) { $this->logDebug("Entering recursive indexation for " . $childUrl); $this->recursiveIndexation($childNode, $depth + 1); } else { try { $this->logDebug("Indexing Node " . $childUrl); AJXP_Controller::applyHook("node.index", array($childNode)); } catch (Exception $e) { $this->logDebug("Error Indexing Node " . $childUrl . " (" . $e->getMessage() . ")"); } } } closedir($handle); } else { $this->logDebug("Cannot open {$url}!!"); } if ($depth == 0) { $this->logDebug("End indexation - node.index.recursive.end - " . memory_get_usage(true) . " - " . $node->getUrl()); $this->setIndexStatus("RUNNING", "Indexation finished, cleaning...", $repository, $user); AJXP_Controller::applyHook("node.index.recursive.end", array($node)); $this->releaseStatus($repository, $user); $this->logDebug("End indexation - After node.index.recursive.end - " . memory_get_usage(true) . " - " . $node->getUrl()); } }
/** * @param Zend_Search_Lucene_Interface $index * @param AJXP_Node $ajxpNode * @return Number */ public function getIndexedDocumentId($index, $ajxpNode) { $term = new Zend_Search_Lucene_Index_Term(SystemTextEncoding::toUTF8($ajxpNode->getUrl()), "node_url"); $docIds = $index->termDocs($term); if (!count($docIds)) { return null; } return $docIds[0]; }
public function extractArchiveItemPreCallback($status, $data) { $fullname = $data['filename']; $size = $data['size']; $realBase = call_user_func(array($this->wrapperClassName, "getRealFSReference"), $this->urlBase); $repoName = $this->urlBase . str_replace($realBase, "", $fullname); $toNode = new AJXP_Node($repoName); $toNode->setLeaf($data['folder'] ? false : true); if (file_exists($toNode->getUrl())) { AJXP_Controller::applyHook("node.before_change", array($toNode, $size)); } else { AJXP_Controller::applyHook("node.before_create", array($toNode, $size)); } return 1; }
/** * @param AJXP_Node $oldNode * @param AJXP_Node $newNode * @param bool $copy * @param string $targetNotif * @return AJXP_Notification */ public function generateNotificationFromChangeHook(AJXP_Node $oldNode = null, AJXP_Node $newNode = null, $copy = false, $targetNotif = "new") { $type = ""; $primaryNode = null; $secondNode = null; $notif = new AJXP_Notification(); if ($oldNode == null) { if ($targetNotif == "old") { return false; } $type = AJXP_NOTIF_NODE_ADD; $primaryNode = $newNode; } else { if ($newNode == null) { if ($targetNotif == "new") { return false; } $type = AJXP_NOTIF_NODE_DEL; $primaryNode = $oldNode; } else { if ($oldNode->getUrl() == $newNode->getUrl()) { $type = AJXP_NOTIF_NODE_CHANGE; $primaryNode = $newNode; } else { if (dirname($oldNode->getPath()) == dirname($newNode->getPath())) { $type = AJXP_NOTIF_NODE_RENAME; $primaryNode = $newNode; $secondNode = $oldNode; } else { if ($targetNotif == "new") { $type = $copy ? AJXP_NOTIF_NODE_COPY_FROM : AJXP_NOTIF_NODE_MOVE_FROM; $primaryNode = $newNode; $secondNode = $oldNode; } else { if ($targetNotif == "old") { $type = $copy ? AJXP_NOTIF_NODE_COPY_TO : AJXP_NOTIF_NODE_MOVE_TO; $primaryNode = $oldNode; $secondNode = $newNode; } else { if ($targetNotif == "unify") { $type = $copy ? AJXP_NOTIF_NODE_COPY : AJXP_NOTIF_NODE_MOVE; $primaryNode = $newNode; $secondNode = $oldNode; } } } } } } } $notif->setNode($primaryNode); $notif->setAction($type); if ($secondNode != null) { $notif->setSecondaryNode($secondNode); } return $notif; }
/** * @param AJXP_Node $ajxpNode * @param String $scope * @param String $userId */ protected function saveMetaFileData($ajxpNode, $scope, $userId) { $currentFile = $ajxpNode->getUrl(); $repositoryId = $ajxpNode->getRepositoryId(); $fileKey = $ajxpNode->getPath(); if (isset($this->options["METADATA_FILE_LOCATION"]) && $this->options["METADATA_FILE_LOCATION"] == "outside") { // Force scope $scope = AJXP_METADATA_SCOPE_REPOSITORY; } if ($scope == AJXP_METADATA_SCOPE_GLOBAL) { $metaFile = dirname($currentFile) . "/" . $this->options["METADATA_FILE"]; $fileKey = basename($fileKey); } else { if (!is_dir(dirname($this->globalMetaFile))) { mkdir(dirname($this->globalMetaFile), 0755, true); } $metaFile = $this->globalMetaFile . "_" . $repositoryId; $metaFile = $this->updateSecurityScope($metaFile, $ajxpNode->getRepositoryId(), $ajxpNode->getUser()); } if ($scope == AJXP_METADATA_SCOPE_REPOSITORY || @is_file($metaFile) && call_user_func(array($this->accessDriver, "isWriteable"), $metaFile) || call_user_func(array($this->accessDriver, "isWriteable"), dirname($metaFile))) { if (is_array(self::$metaCache) && count(self::$metaCache)) { if (!isset(self::$fullMetaCache[$metaFile])) { self::$fullMetaCache[$metaFile] = array(); } if (!isset(self::$fullMetaCache[$metaFile][$fileKey])) { self::$fullMetaCache[$metaFile][$fileKey] = array(); } if (!isset(self::$fullMetaCache[$metaFile][$fileKey][$userId])) { self::$fullMetaCache[$metaFile][$fileKey][$userId] = array(); } self::$fullMetaCache[$metaFile][$fileKey][$userId] = self::$metaCache; } else { // CLEAN if (isset(self::$fullMetaCache[$metaFile][$fileKey][$userId])) { unset(self::$fullMetaCache[$metaFile][$fileKey][$userId]); } if (isset(self::$fullMetaCache[$metaFile][$fileKey]) && !count(self::$fullMetaCache[$metaFile][$fileKey])) { unset(self::$fullMetaCache[$metaFile][$fileKey]); } } $fp = @fopen($metaFile, "w"); if ($fp !== false) { @fwrite($fp, serialize(self::$fullMetaCache[$metaFile]), strlen(serialize(self::$fullMetaCache[$metaFile]))); @fclose($fp); } else { $this->logError(__FUNCTION__, "Error while trying to open the meta file, maybe a permission problem?"); } if ($scope == AJXP_METADATA_SCOPE_GLOBAL) { AJXP_Controller::applyHook("version.commit_file", array($metaFile, $ajxpNode)); } } }
/** * Apply specific operation to set a node as hidden. * Can be overwritten, or will probably do nothing. * @param AJXP_Node $node */ public function setHiddenAttribute($node) { if (AJXP_MetaStreamWrapper::actualRepositoryWrapperClass($node->getRepositoryId()) == "fsAccessWrapper" && strtoupper(substr(PHP_OS, 0, 3)) === 'WIN') { $realPath = AJXP_MetaStreamWrapper::getRealFSReference($node->getUrl()); @shell_exec("attrib +H " . escapeshellarg($realPath)); } }
/** * Enrich node metadata * @param AJXP_Node $ajxpNode */ public function extractImageMetadata(&$ajxpNode) { $currentPath = $ajxpNode->getUrl(); $wrapperClassName = $ajxpNode->wrapperClassName; $isImage = AJXP_Utils::is_image($currentPath); $ajxpNode->is_image = $isImage; if (!$isImage) { return; } $setRemote = false; $remoteWrappers = $this->getFilteredOption("META_EXTRACTION_REMOTEWRAPPERS"); if (is_string($remoteWrappers)) { $remoteWrappers = explode(",", $remoteWrappers); } $remoteThreshold = $this->getFilteredOption("META_EXTRACTION_THRESHOLD"); if (in_array($wrapperClassName, $remoteWrappers)) { if ($remoteThreshold != 0 && isset($ajxpNode->bytesize)) { $setRemote = $ajxpNode->bytesize > $remoteThreshold; } else { $setRemote = true; } } if ($isImage) { if ($setRemote) { $ajxpNode->image_type = "N/A"; $ajxpNode->image_width = "N/A"; $ajxpNode->image_height = "N/A"; $ajxpNode->readable_dimension = ""; } else { $realFile = $ajxpNode->getRealFile(); list($width, $height, $type, $attr) = @getimagesize($realFile); if ($this->getFilteredOption("EXIF_ROTATION")) { require_once AJXP_INSTALL_PATH . "/plugins/editor.diaporama/PThumb.lib.php"; $pThumb = new PThumb($this->getFilteredOption["THUMBNAIL_QUALITY"], $this->getFilteredOption("EXIF_ROTATION")); $orientation = $pThumb->exiforientation($realFile, false); if ($pThumb->rotationsupported($orientation)) { $ajxpNode->image_exif_orientation = $orientation; if ($orientation > 4) { $tmp = $height; $height = $width; $width = $tmp; } } } $ajxpNode->image_type = image_type_to_mime_type($type); $ajxpNode->image_width = $width; $ajxpNode->image_height = $height; $ajxpNode->readable_dimension = $width . "px X " . $height . "px"; } } //$this->logDebug("CURRENT NODE IN EXTRACT IMAGE METADATA ", $ajxpNode); }
/** * @param AJXP_Node $fromNode * @param AJXP_Node $toNode * @param bool $copy * @param String $direction */ public function forwardEventToShares($fromNode = null, $toNode = null, $copy = false, $direction = null) { if (empty($direction) && $this->getFilteredOption("FORK_EVENT_FORWARDING")) { AJXP_Controller::applyActionInBackground(ConfService::getRepository()->getId(), "forward_change_event", array("from" => $fromNode === null ? "" : $fromNode->getUrl(), "to" => $toNode === null ? "" : $toNode->getUrl(), "copy" => $copy ? "true" : "false", "direction" => $direction)); return; } $fromMirrors = null; $toMirrors = null; if ($fromNode != null) { $fromMirrors = $this->findMirrorNodesInShares($fromNode, $direction); } if ($toNode != null) { $toMirrors = $this->findMirrorNodesInShares($toNode, $direction); } $this->applyForwardEvent($fromMirrors, $toMirrors, $copy, $direction); if (count($fromMirrors) || count($toMirrors)) { // Make sure to switch back to correct repository in memory if ($fromNode != null) { $fromNode->getRepository()->driverInstance = null; $fromNode->setDriver(null); $fromNode->getDriver(); } else { if ($toNode != null) { $toNode->getRepository()->driverInstance = null; $toNode->setDriver(null); $toNode->getDriver(); } } } }
/** * @param AJXP_Node $ajxpNode * @param String $scope * @param String $userId */ protected function saveMetaFileData($ajxpNode, $scope, $userId) { $currentFile = $ajxpNode->getUrl(); $repositoryId = $ajxpNode->getRepositoryId(); $fileKey = $ajxpNode->getPath(); if (isset($this->options["METADATA_FILE_LOCATION"]) && $this->options["METADATA_FILE_LOCATION"] == "outside") { // Force scope $scope = AJXP_METADATA_SCOPE_REPOSITORY; } if ($scope == AJXP_METADATA_SCOPE_GLOBAL) { $metaFile = dirname($currentFile) . "/" . $this->options["METADATA_FILE"]; $fileKey = basename($fileKey); } else { if (!is_dir(dirname($this->globalMetaFile))) { mkdir(dirname($this->globalMetaFile), 0755, true); } $metaFile = $this->globalMetaFile . "_" . $repositoryId; } if (@is_file($metaFile) && call_user_func(array($this->accessDriver, "isWriteable"), $metaFile) || call_user_func(array($this->accessDriver, "isWriteable"), dirname($metaFile)) || $scope == "repository") { if (!isset(self::$fullMetaCache[$fileKey])) { self::$fullMetaCache[$fileKey] = array(); } if (!isset(self::$fullMetaCache[$fileKey][$userId])) { self::$fullMetaCache[$fileKey][$userId] = array(); } self::$fullMetaCache[$fileKey][$userId] = self::$metaCache; $fp = fopen($metaFile, "w"); if ($fp !== false) { @fwrite($fp, serialize(self::$fullMetaCache), strlen(serialize(self::$fullMetaCache))); @fclose($fp); } if ($scope == AJXP_METADATA_SCOPE_GLOBAL) { AJXP_Controller::applyHook("version.commit_file", array($metaFile, $ajxpNode)); } } }
public function switchAction($action, $httpVars, $filesVars) { if (!isset($this->actions[$action])) { return false; } $repository = ConfService::getRepositoryById($httpVars["repository_id"]); if (!$repository->detectStreamWrapper(true)) { return false; } if (AuthService::usersEnabled()) { $loggedUser = AuthService::getLoggedUser(); if ($loggedUser === null && ConfService::getCoreConf("ALLOW_GUEST_BROWSING", "auth")) { AuthService::logUser("guest", null); $loggedUser = AuthService::getLoggedUser(); } if (!$loggedUser->canSwitchTo($repository->getId())) { echo "You do not have permissions to access this resource"; return false; } } $streamData = $repository->streamData; $destStreamURL = $streamData["protocol"] . "://" . $repository->getId(); $selection = new UserSelection($repository, $httpVars); if ($action == "open_file") { $file = $selection->getUniqueFile(); if (!file_exists($destStreamURL . $file)) { echo "File does not exist"; return false; } $node = new AJXP_Node($destStreamURL . $file); if (method_exists($node->getDriver(), "filesystemFileSize")) { $filesize = $node->getDriver()->filesystemFileSize($node->getUrl()); } else { $filesize = filesize($node->getUrl()); } $fp = fopen($destStreamURL . $file, "rb"); $fileMime = "application/octet-stream"; //Get mimetype with fileinfo PECL extension if (class_exists("finfo")) { $finfo = new finfo(FILEINFO_MIME); $fileMime = $finfo->buffer(fread($fp, 100)); } //Get mimetype with (deprecated) mime_content_type if (strpos($fileMime, "application/octet-stream") === 0 && function_exists("mime_content_type")) { $fileMime = @mime_content_type($fp); } //Guess mimetype based on file extension if (strpos($fileMime, "application/octet-stream") === 0) { $fileExt = substr(strrchr(basename($file), '.'), 1); if (empty($fileExt)) { $fileMime = "application/octet-stream"; } else { $regex = "/^([\\w\\+\\-\\.\\/]+)\\s+(\\w+\\s)*({$fileExt}\\s)/i"; $lines = file($this->getBaseDir() . "/resources/other/mime.types"); foreach ($lines as $line) { if (substr($line, 0, 1) == '#') { continue; } // skip comments $line = rtrim($line) . " "; if (!preg_match($regex, $line, $matches)) { continue; } // no match to the extension $fileMime = $matches[1]; } } } fclose($fp); // If still no mimetype, give up and serve application/octet-stream if (empty($fileMime)) { $fileMime = "application/octet-stream"; } //Send headers HTMLWriter::generateInlineHeaders(basename($file), $filesize, $fileMime); $class = $streamData["classname"]; $stream = fopen("php://output", "a"); call_user_func(array($streamData["classname"], "copyFileInStream"), $destStreamURL . $file, $stream); fflush($stream); fclose($stream); $node = new AJXP_Node($destStreamURL . $file); AJXP_Controller::applyHook("node.read", array($node)); $this->logInfo('Download', 'Read content of ' . $node->getUrl()); } }
/** * @param AJXP_Node $ajxpNode * @return Number */ public function getIndexedDocumentId($ajxpNode) { /* we used a term query that will check for the exact term (here is the path to a file) that can't be duplicate.Thus it will get the right result. */ $query = new Elastica\Query\Term(); $query->setTerm("node_url", $ajxpNode->getUrl()); /* returns a result set from the query */ $results = $this->currentIndex->search($query); if ($results->getTotalHits() == 0) { return null; } return $results->current()->getId(); }
/** * @param AJXP_Node $ajxpNode * @param Boolean $isParent */ public function extractMimeHeaders(&$ajxpNode, $isParent = false) { if ($isParent) { return; } $currentNode = $ajxpNode->getUrl(); $metadata = $ajxpNode->metadata; $wrapperClassName = $ajxpNode->wrapperClassName; $noMail = true; if ($metadata["is_file"] && ($wrapperClassName == "imapAccessWrapper" || preg_match("/\\.eml\$/i", $currentNode))) { $noMail = false; } if ($wrapperClassName == "imapAccessWrapper" && !$metadata["is_file"]) { $metadata["mimestring"] = "Mailbox"; } $parsed = parse_url($currentNode); if ($noMail || isset($parsed["fragment"]) && strpos($parsed["fragment"], "attachments") === 0) { EmlParser::$currentListingOnlyEmails = FALSE; return; } if (EmlParser::$currentListingOnlyEmails === NULL) { EmlParser::$currentListingOnlyEmails = true; } if ($wrapperClassName == "imapAccessWrapper") { $cachedFile = AJXP_Cache::getItem("eml_remote", $currentNode, null, array("EmlParser", "computeCacheId")); $realFile = $cachedFile->getId(); if (!is_file($realFile)) { $cachedFile->getData(); // trigger loading! } } else { $realFile = $ajxpNode->getRealFile(); } $cacheItem = AJXP_Cache::getItem("eml_mimes", $realFile, array($this, "mimeExtractorCallback")); $data = unserialize($cacheItem->getData()); $data["ajxp_mime"] = "eml"; $data["mimestring"] = "Email"; $metadata = array_merge($metadata, $data); if ($wrapperClassName == "imapAccessWrapper" && $metadata["eml_attachments"] != "0" && strpos($_SERVER["HTTP_USER_AGENT"], "ajaxplorer-ios") !== false) { $metadata["is_file"] = false; $metadata["nodeName"] = basename($currentNode) . "#attachments"; } $ajxpNode->metadata = $metadata; }
public function switchAction($action, $httpVars, $fileVars) { if (!isset($this->accessDriver)) { throw new Exception("Cannot find access driver!"); } if ($this->accessDriver->getId() == "access.demo") { $errorMessage = "This is a demo, all 'write' actions are disabled!"; if ($httpVars["sub_action"] == "delegate_repo") { return AJXP_XMLWriter::sendMessage(null, $errorMessage, false); } else { print $errorMessage; } return; } switch ($action) { //------------------------------------ // SHARING FILE OR FOLDER //------------------------------------ case "share": $subAction = isset($httpVars["sub_action"]) ? $httpVars["sub_action"] : ""; $file = AJXP_Utils::decodeSecureMagic($httpVars["file"]); $ajxpNode = new AJXP_Node($this->urlBase . $file); if (!file_exists($ajxpNode->getUrl())) { throw new Exception("Cannot share a non-existing file: " . $ajxpNode->getUrl()); } $metadata = null; if ($subAction == "delegate_repo") { header("Content-type:text/plain"); $result = $this->createSharedRepository($httpVars, $this->repository, $this->accessDriver); if (is_a($result, "Repository")) { $metadata = array("element" => $result->getUniqueId()); $numResult = 200; } else { $numResult = $result; } print $numResult; } else { if ($subAction == "create_minisite") { header("Content-type:text/plain"); $res = $this->createSharedMinisite($httpVars, $this->repository, $this->accessDriver); if (!is_array($res)) { $url = $res; } else { list($hash, $url) = $res; $metadata = array("element" => $hash, "minisite" => isset($httpVars["create_guest_user"]) ? "public" : "private"); } print $url; } else { $maxdownload = abs(intval($this->getFilteredOption("FILE_MAX_DOWNLOAD", $this->repository->getId()))); $download = isset($httpVars["downloadlimit"]) ? abs(intval($httpVars["downloadlimit"])) : 0; if ($maxdownload == 0) { $httpVars["downloadlimit"] = $download; } elseif ($maxdownload > 0 && $download == 0) { $httpVars["downloadlimit"] = $maxdownload; } else { $httpVars["downloadlimit"] = min($download, $maxdownload); } $maxexpiration = abs(intval($this->getFilteredOption("FILE_MAX_EXPIRATION", $this->repository->getId()))); $expiration = isset($httpVars["expiration"]) ? abs(intval($httpVars["expiration"])) : 0; if ($maxexpiration == 0) { $httpVars["expiration"] = $expiration; } elseif ($maxexpiration > 0 && $expiration == 0) { $httpVars["expiration"] = $maxexpiration; } else { $httpVars["expiration"] = min($expiration, $maxexpiration); } $data = $this->accessDriver->makePublicletOptions($file, $httpVars["password"], $httpVars["expiration"], $httpVars["downloadlimit"], $this->repository); $customData = array(); foreach ($httpVars as $key => $value) { if (substr($key, 0, strlen("PLUGINS_DATA_")) == "PLUGINS_DATA_") { $customData[substr($key, strlen("PLUGINS_DATA_"))] = $value; } } if (count($customData)) { $data["PLUGINS_DATA"] = $customData; } list($hash, $url) = $this->writePubliclet($data, $this->accessDriver, $this->repository); $metaArray = array(); if ($ajxpNode->hasMetaStore()) { $existingMeta = $ajxpNode->retrieveMetadata("ajxp_shared", true, AJXP_METADATA_SCOPE_REPOSITORY, true); if (isset($existingMeta) && is_array($existingMeta) && array_key_exists("element", $existingMeta)) { if (is_string($existingMeta["element"])) { $metaArray[$existingMeta["element"]] = array(); } else { $metaArray = $existingMeta["element"]; } } } $metaArray[$hash] = array(); $metadata = array("element" => $metaArray); if (isset($httpVars["format"]) && $httpVars["format"] == "json") { header("Content-type:application/json"); echo json_encode(array("element_id" => $hash, "publiclet_link" => $url)); } else { header("Content-type:text/plain"); echo $url; } flush(); } } if ($metadata != null && $ajxpNode->hasMetaStore()) { $ajxpNode->setMetadata("ajxp_shared", $metadata, true, AJXP_METADATA_SCOPE_REPOSITORY, true); } AJXP_Controller::applyHook("msg.instant", array("<reload_shared_elements/>", ConfService::getRepository()->getId())); // as the result can be quite small (e.g error code), make sure it's output in case of OB active. flush(); break; case "toggle_link_watch": $file = AJXP_Utils::decodeSecureMagic($httpVars["file"]); $watchValue = $httpVars["set_watch"] == "true" ? true : false; $folder = false; if (isset($httpVars["element_type"]) && $httpVars["element_type"] == "folder") { $folder = true; $node = new AJXP_Node($this->baseProtocol . "://" . $httpVars["repository_id"] . "/"); } else { $node = new AJXP_Node($this->urlBase . $file); } $metadata = $node->retrieveMetadata("ajxp_shared", true, AJXP_METADATA_SCOPE_REPOSITORY); $elementId = $metadata["element"]; if (isset($httpVars["element_id"]) && is_Array($metadata["element"]) && isset($metadata["element"][$httpVars["element_id"]])) { $elementId = $httpVars["element_id"]; } if ($this->watcher !== false) { if (!$folder) { if ($watchValue) { $this->watcher->setWatchOnFolder($node, AuthService::getLoggedUser()->getId(), MetaWatchRegister::$META_WATCH_USERS_READ, array($elementId)); } else { $this->watcher->removeWatchFromFolder($node, AuthService::getLoggedUser()->getId(), true, $elementId); } } else { if ($watchValue) { $this->watcher->setWatchOnFolder($node, AuthService::getLoggedUser()->getId(), MetaWatchRegister::$META_WATCH_BOTH); } else { $this->watcher->removeWatchFromFolder($node, AuthService::getLoggedUser()->getId()); } } } $mess = ConfService::getMessages(); AJXP_XMLWriter::header(); AJXP_XMLWriter::sendMessage($mess["share_center.47"], null); AJXP_XMLWriter::close(); break; case "load_shared_element_data": $file = AJXP_Utils::decodeSecureMagic($httpVars["file"]); $elementType = $httpVars["element_type"]; $messages = ConfService::getMessages(); $node = new AJXP_Node($this->urlBase . $file); $metadata = $node->retrieveMetadata("ajxp_shared", true, AJXP_METADATA_SCOPE_REPOSITORY); $elementWatch = false; if (count($metadata)) { header("Content-type:application/json"); if ($elementType == "file") { $elements = $metadata["element"]; if (is_string($elements)) { $elements = array($elements => true); } $jsonData = array(); foreach ($elements as $element => $elementData) { if (!is_array($elementData)) { $elementData = array(); } $pData = self::loadPublicletData($element); if (!count($pData)) { continue; } if ($pData["OWNER_ID"] != AuthService::getLoggedUser()->getId()) { throw new Exception($messages["share_center.48"]); } if (isset($elementData["short_form_url"])) { $link = $elementData["short_form_url"]; } else { $link = $this->buildPublicletLink($element); } if ($this->watcher != false) { $result = array(); $elementWatch = $this->watcher->hasWatchOnNode($node, AuthService::getLoggedUser()->getId(), MetaWatchRegister::$META_WATCH_USERS_NAMESPACE, $result); if ($elementWatch && !in_array($element, $result)) { $elementWatch = false; } } $jsonData[] = array_merge(array("element_id" => $element, "publiclet_link" => $link, "download_counter" => PublicletCounter::getCount($element), "download_limit" => $pData["DOWNLOAD_LIMIT"], "expire_time" => $pData["EXPIRE_TIME"] != 0 ? date($messages["date_format"], $pData["EXPIRE_TIME"]) : 0, "has_password" => !empty($pData["PASSWORD"]), "element_watch" => $elementWatch), $elementData); } } else { if ($elementType == "repository") { if (isset($metadata["minisite"])) { $minisiteData = self::loadPublicletData($metadata["element"]); $repoId = $minisiteData["REPOSITORY"]; $minisiteIsPublic = isset($minisiteData["PRELOG_USER"]); $dlDisabled = isset($minisiteData["DOWNLOAD_DISABLED"]); if (isset($metadata["short_form_url"])) { $minisiteLink = $metadata["short_form_url"]; } else { $minisiteLink = $this->buildPublicletLink($metadata["element"]); } } else { $repoId = $metadata["element"]; } $repo = ConfService::getRepositoryById($repoId); if ($repo == null || $repo->getOwner() != AuthService::getLoggedUser()->getId()) { //throw new Exception($messages["share_center.48"]); $jsonData = array("repositoryId" => $repoId, "label" => "Error - Cannot find shared data", "description" => "Cannot find repository", "entries" => array(), "element_watch" => false, "repository_url" => ""); echo json_encode($jsonData); break; } if ($this->watcher != false) { $elementWatch = $this->watcher->hasWatchOnNode(new AJXP_Node($this->baseProtocol . "://" . $repoId . "/"), AuthService::getLoggedUser()->getId(), MetaWatchRegister::$META_WATCH_NAMESPACE); } $sharedEntries = $this->computeSharedRepositoryAccessRights($repoId, true, $this->urlBase . $file); $jsonData = array("repositoryId" => $repoId, "label" => $repo->getDisplay(), "description" => $repo->getDescription(), "entries" => $sharedEntries, "element_watch" => $elementWatch, "repository_url" => AJXP_Utils::detectServerURL(true) . "?goto=" . $repo->getSlug() . "/"); if (isset($minisiteData)) { $jsonData["minisite"] = array("public" => $minisiteIsPublic ? "true" : "false", "public_link" => $minisiteLink, "disable_download" => $dlDisabled); } } } echo json_encode($jsonData); } break; case "unshare": $file = AJXP_Utils::decodeSecureMagic($httpVars["file"]); $ajxpNode = new AJXP_Node($this->urlBase . $file); $metadata = $ajxpNode->retrieveMetadata("ajxp_shared", true, AJXP_METADATA_SCOPE_REPOSITORY); if (count($metadata)) { $eType = $httpVars["element_type"]; if (isset($metadata["minisite"])) { $eType = "minisite"; } $elementId = $metadata["element"]; $updateMeta = false; if (isset($httpVars["element_id"])) { if (is_array($metadata["element"]) && isset($metadata["element"][$httpVars['element_id']])) { $elementId = $httpVars["element_id"]; unset($metadata["element"][$httpVars['element_id']]); if (count($metadata["element"]) > 0) { $updateMeta = true; } } } self::deleteSharedElement($eType, $elementId, AuthService::getLoggedUser()); if ($updateMeta) { $ajxpNode->setMetadata("ajxp_shared", $metadata, true, AJXP_METADATA_SCOPE_REPOSITORY, true); } else { $ajxpNode->removeMetadata("ajxp_shared", true, AJXP_METADATA_SCOPE_REPOSITORY, true); } } AJXP_Controller::applyHook("msg.instant", array("<reload_shared_elements/>", ConfService::getRepository()->getId())); break; case "reset_counter": $file = AJXP_Utils::decodeSecureMagic($httpVars["file"]); $ajxpNode = new AJXP_Node($this->urlBase . $file); $metadata = $ajxpNode->retrieveMetadata("ajxp_shared", true, AJXP_METADATA_SCOPE_REPOSITORY); if (isset($metadata["element"][$httpVars["element_id"]])) { PublicletCounter::reset($httpVars["element_id"]); } break; case "update_shared_element_data": $file = AJXP_Utils::decodeSecureMagic($httpVars["file"]); if (!in_array($httpVars["p_name"], array("counter", "tags"))) { } $ajxpNode = new AJXP_Node($this->urlBase . $file); $metadata = $ajxpNode->retrieveMetadata("ajxp_shared", true, AJXP_METADATA_SCOPE_REPOSITORY); if (isset($metadata["element"][$httpVars["element_id"]])) { if (!is_array($metadata["element"][$httpVars["element_id"]])) { $metadata["element"][$httpVars["element_id"]] = array(); } $metadata["element"][$httpVars["element_id"]][$httpVars["p_name"]] = $httpVars["p_value"]; $ajxpNode->setMetadata("ajxp_shared", $metadata, true, AJXP_METADATA_SCOPE_REPOSITORY); } break; default: break; } }
public function switchAction($action, $httpVars, $postProcessData) { if (!isset($this->actions[$action])) { return false; } $repository = ConfService::getRepository(); if (!$repository->detectStreamWrapper(false)) { return false; } $plugin = AJXP_PluginsService::findPlugin("access", $repository->getAccessType()); $streamData = $plugin->detectStreamWrapper(true); $destStreamURL = $streamData["protocol"] . "://" . $repository->getId() . "/"; if ($action == "audio_proxy") { $selection = new UserSelection($repository, $httpVars); // Backward compat $file = $selection->getUniqueFile(); if (!file_exists($destStreamURL . $file) && strpos($httpVars["file"], "base64encoded:") === false) { // May be a backward compatibility problem, try to base64decode the filepath $file = AJXP_Utils::decodeSecureMagic(base64_decode($httpVars["file"])); if (!file_exists($destStreamURL . $file)) { throw new Exception("Cannot find file!"); } } $cType = "audio/" . array_pop(explode(".", $file)); $localName = basename($file); $node = new AJXP_Node($destStreamURL . $file); if (method_exists($node->getDriver(), "filesystemFileSize")) { $size = $node->getDriver()->filesystemFileSize($node->getUrl()); } else { $size = filesize($node->getUrl()); } header("Content-Type: " . $cType . "; name=\"" . $localName . "\""); header("Content-Length: " . $size); $stream = fopen("php://output", "a"); call_user_func(array($streamData["classname"], "copyFileInStream"), $destStreamURL . $file, $stream); fflush($stream); fclose($stream); AJXP_Controller::applyHook("node.read", array($node)); $this->logInfo('Preview', 'Read content of ' . $node->getUrl()); //exit(1); } else { if ($action == "ls") { if (!isset($httpVars["playlist"])) { // This should not happen anyway, because of the applyCondition. AJXP_Controller::passProcessDataThrough($postProcessData); return; } // We transform the XML into XSPF $xmlString = $postProcessData["ob_output"]; $xmlDoc = new DOMDocument(); $xmlDoc->loadXML($xmlString); $xElement = $xmlDoc->documentElement; header("Content-Type:application/xspf+xml;charset=UTF-8"); print '<?xml version="1.0" encoding="UTF-8"?>'; print '<playlist version="1" xmlns="http://xspf.org/ns/0/">'; print "<trackList>"; foreach ($xElement->childNodes as $child) { $isFile = $child->getAttribute("is_file") == "true"; $label = $child->getAttribute("text"); $ar = explode(".", $label); $ext = strtolower(end($ar)); if (!$isFile || $ext != "mp3") { continue; } print "<track><location>" . AJXP_SERVER_ACCESS . "?secure_token=" . AuthService::getSecureToken() . "&get_action=audio_proxy&file=" . base64_encode($child->getAttribute("filename")) . "</location><title>" . $label . "</title></track>"; } print "</trackList>"; AJXP_XMLWriter::close("playlist"); } } }
/** * @param AJXP_Node $ajxpNode * @param boolean $create * @return String */ private function updateNodeMetaPath($ajxpNode, $create = false) { $folder = false; $trim = trim($ajxpNode->getPath(), "/"); if ($ajxpNode->is_file !== null) { $folder = !$ajxpNode->isLeaf(); } else { $folder = !is_file($ajxpNode->getUrl()); } if (!$folder) { return $trim; } $meta = is_file(rtrim($ajxpNode->getUrl(), "/") . "/.meta"); if (!$meta) { if ($create) { file_put_contents(rtrim($ajxpNode->getUrl(), "/") . "/.meta", "meta"); } else { return null; } } return $trim . "/.meta"; }
/** * @param AJXP_Node $node * @param float $offset * @param float $length * @return String md5 */ public function getPartialHash($node, $offset, $length) { $this->logDebug('Getting partial hash from ' . $offset . ' to ' . $length); $fp = fopen($node->getUrl(), "r"); $ctx = hash_init('md5'); if ($offset > 0) { fseek($fp, $offset); } hash_update_stream($ctx, $fp, $length); $hash = hash_final($ctx); $this->logDebug('Partial hash is ' . $hash); fclose($fp); return $hash; }
/** * * @param AJXP_Node $oldNode * @param AJXP_Node $newNode * @param Boolean $copy */ public function deleteImagickCache($oldNode, $newNode = null, $copy = false) { if ($oldNode == null) { return; } $oldFile = $oldNode->getUrl(); // Should remove imagick cache file if (!$this->handleMime($oldFile)) { return; } if ($newNode == null || $copy == false) { // Main Thumb AJXP_Cache::clearItem("imagick_thumb", $oldFile); // Unoconv small PDF $thumbCache = AJXP_Cache::getItem("imagick_thumb", $oldFile, false); $unoFile = pathinfo($thumbCache->getId(), PATHINFO_DIRNAME) . DIRECTORY_SEPARATOR . pathinfo($thumbCache->getId(), PATHINFO_FILENAME) . "_unoconv.pdf"; if (file_exists($unoFile)) { unlink($unoFile); } $cache = AJXP_Cache::getItem("imagick_full", $oldFile, false); // Unoconv full pdf $unoFile = pathinfo($cache->getId(), PATHINFO_DIRNAME) . DIRECTORY_SEPARATOR . pathinfo($cache->getId(), PATHINFO_FILENAME) . "_unoconv.pdf"; if (file_exists($unoFile)) { unlink($unoFile); } $prefix = str_replace("." . pathinfo($cache->getId(), PATHINFO_EXTENSION), "", $cache->getId()); // Additional Extracted pages $files = $this->listExtractedJpg($oldFile, $prefix); $cacheDir = (defined('AJXP_SHARED_CACHE_DIR') ? AJXP_SHARED_CACHE_DIR : AJXP_CACHE_DIR) . "/imagick_full"; foreach ($files as $file) { if (is_file($cacheDir . "/" . $file["file"])) { unlink($cacheDir . "/" . $file["file"]); } } } }
/** * * @param AJXP_Node $ajxpNode */ public function extractMeta(&$ajxpNode) { //if(isSet($_SESSION["SVN_COMMAND_RUNNING"]) && $_SESSION["SVN_COMMAND_RUNNING"] === true) return ; $realDir = dirname($ajxpNode->getRealFile()); if (SvnManager::$svnListDir == $realDir) { $entries = SvnManager::$svnListCache; } else { try { SvnManager::$svnListDir = $realDir; $entries = $this->svnListNode($realDir); SvnManager::$svnListCache = $entries; } catch (Exception $e) { $this->logError("ExtractMeta", $e->getMessage()); } } $fileId = SystemTextEncoding::toUTF8(basename($ajxpNode->getUrl())); if (isset($entries[$fileId])) { $ajxpNode->mergeMetadata($entries[$fileId]); } }
/** * @param AJXP_Node $oldNode * @param AJXP_Node $newNode * @param bool $copy */ public function updateNodesIndex($oldNode = null, $newNode = null, $copy = false) { if (!dibi::isConnected()) { dibi::connect($this->sqlDriver); } //$this->logInfo("Syncable index", array($oldNode == null?'null':$oldNode->getUrl(), $newNode == null?'null':$newNode->getUrl())); try { if ($newNode != null && $this->excludeNode($newNode)) { // CREATE if ($oldNode == null) { AJXP_Logger::debug("Ignoring " . $newNode->getUrl() . " for indexation"); return; } else { AJXP_Logger::debug("Target node is excluded, see it as a deletion: " . $newNode->getUrl()); $newNode = null; } } if ($newNode == null) { $repoId = $this->computeIdentifier($oldNode->getRepository(), $oldNode->getUser()); // DELETE $this->logDebug('DELETE', $oldNode->getUrl()); dibi::query("DELETE FROM [ajxp_index] WHERE [node_path] LIKE %like~ AND [repository_identifier] = %s", SystemTextEncoding::toUTF8($oldNode->getPath()), $repoId); } else { if ($oldNode == null || $copy) { // CREATE $stat = stat($newNode->getUrl()); $newNode->setLeaf(!($stat['mode'] & 040000)); $this->logDebug('INSERT', $newNode->getUrl()); dibi::query("INSERT INTO [ajxp_index]", array("node_path" => SystemTextEncoding::toUTF8($newNode->getPath()), "bytesize" => $stat["size"], "mtime" => $stat["mtime"], "md5" => $newNode->isLeaf() ? md5_file($newNode->getUrl()) : "directory", "repository_identifier" => $repoId = $this->computeIdentifier($newNode->getRepository(), $newNode->getUser()))); } else { $repoId = $this->computeIdentifier($oldNode->getRepository(), $oldNode->getUser()); if ($oldNode->getPath() == $newNode->getPath()) { // CONTENT CHANGE clearstatcache(); $stat = stat($newNode->getUrl()); $this->logDebug("Content changed", "current stat size is : " . $stat["size"]); $this->logDebug('UPDATE CONTENT', $newNode->getUrl()); dibi::query("UPDATE [ajxp_index] SET ", array("bytesize" => $stat["size"], "mtime" => $stat["mtime"], "md5" => md5_file($newNode->getUrl())), "WHERE [node_path] = %s AND [repository_identifier] = %s", SystemTextEncoding::toUTF8($oldNode->getPath()), $repoId); try { $rowCount = dibi::getAffectedRows(); if ($rowCount === 0) { $this->logError(__FUNCTION__, "There was an update event on a non-indexed node (" . $newNode->getPath() . "), creating index entry!"); $this->updateNodesIndex(null, $newNode, false); } } catch (Exception $e) { } } else { // PATH CHANGE ONLY $newNode->loadNodeInfo(); if ($newNode->isLeaf()) { $this->logDebug('UPDATE LEAF PATH', $newNode->getUrl()); dibi::query("UPDATE [ajxp_index] SET ", array("node_path" => SystemTextEncoding::toUTF8($newNode->getPath())), "WHERE [node_path] = %s AND [repository_identifier] = %s", SystemTextEncoding::toUTF8($oldNode->getPath()), $repoId); try { $rowCount = dibi::getAffectedRows(); if ($rowCount === 0) { $this->logError(__FUNCTION__, "There was an update event on a non-indexed node (" . $newNode->getPath() . "), creating index entry!"); $this->updateNodesIndex(null, $newNode, false); } } catch (Exception $e) { } } else { $this->logDebug('UPDATE FOLDER PATH', $newNode->getUrl()); dibi::query("UPDATE [ajxp_index] SET [node_path]=REPLACE( REPLACE(CONCAT('\$\$\$',[node_path]), CONCAT('\$\$\$', %s), CONCAT('\$\$\$', %s)) , '\$\$\$', '') ", $oldNode->getPath(), $newNode->getPath(), "WHERE [node_path] LIKE %like~ AND [repository_identifier] = %s", SystemTextEncoding::toUTF8($oldNode->getPath()), $repoId); try { $rowCount = dibi::getAffectedRows(); if ($rowCount === 0) { $this->logError(__FUNCTION__, "There was an update event on a non-indexed folder (" . $newNode->getPath() . "), relaunching a recursive indexation!"); AJXP_Controller::findActionAndApply("index", array("file" => $newNode->getPath()), array()); } } catch (Exception $e) { } } } } } } catch (Exception $e) { AJXP_Logger::error("[meta.syncable]", "Exception", $e->getTraceAsString()); AJXP_Logger::error("[meta.syncable]", "Indexation", $e->getMessage()); } }
public function switchAction($actionName, $httpVars, $fileVars) { $this->baseURL = rtrim($this->getFilteredOption("ETHERPAD_SERVER"), "/"); $this->apiKey = $this->getFilteredOption("ETHERPAD_APIKEY"); $userSelection = new UserSelection(ConfService::getRepository(), $httpVars); if ($userSelection->isEmpty()) { throw new Exception("Empty selection"); } $repository = ConfService::getRepository(); if (!$repository->detectStreamWrapper(false)) { return false; } $selectedNode = $userSelection->getUniqueNode(); $selectedNode->loadNodeInfo(); if (!$selectedNode->isLeaf()) { throw new Exception("Cannot handle folders, please select a file!"); } $nodeExtension = strtolower(pathinfo($selectedNode->getPath(), PATHINFO_EXTENSION)); // Determine pad ID if ($nodeExtension == "pad") { $padID = file_get_contents($selectedNode->getUrl()); } else { // TRY TO LOAD PAD ID FROM NODE SHARED METADATA $metadata = $selectedNode->retrieveMetadata("etherpad", AJXP_METADATA_ALLUSERS, AJXP_METADATA_SCOPE_GLOBAL, false); if (isset($metadata["pad_id"])) { $padID = $metadata["pad_id"]; } else { $padID = AJXP_Utils::generateRandomString(); $selectedNode->setMetadata("etherpad", array("pad_id" => $padID), AJXP_METADATA_ALLUSERS, AJXP_METADATA_SCOPE_GLOBAL, false); } } require_once "etherpad-client/etherpad-lite-client.php"; $client = new EtherpadLiteClient($this->apiKey, $this->baseURL . "/api"); $loggedUser = AuthService::getLoggedUser(); $userName = $loggedUser->getId(); $userLabel = $loggedUser->mergedRole->filterParameterValue("core.conf", "USER_DISPLAY_NAME", AJXP_REPO_SCOPE_ALL, $userName); $res = $client->createAuthorIfNotExistsFor($userName, $userLabel); $authorID = $res->authorID; $res2 = $client->createGroupIfNotExistsFor($loggedUser->getGroupPath()); $groupID = $res2->groupID; $fullId = $groupID . "\$" . $padID; if ($actionName == "etherpad_create") { $resP = $client->listPads($groupID); $currentContent = file_get_contents($selectedNode->getUrl()); if ($nodeExtension == "html" && strpos($currentContent, "<html>") === false) { $currentContent = "<html><head></head><body>{$currentContent}</body></html>"; } if (!in_array($fullId, $resP->padIDs)) { $client->createGroupPad($groupID, $padID, null); if ($nodeExtension == "html" && !empty($currentContent)) { $client->setHTML($fullId, $currentContent); } else { if ($nodeExtension != "pad") { $client->setText($fullId, $currentContent); } } } else { if ($nodeExtension != "pad") { // If someone is already connected, do not override. $existingAuthors = $client->listAuthorsOfPad($fullId); if (!count($existingAuthors->authorIDs)) { if ($nodeExtension == "html" && !empty($currentContent)) { $client->setHTML($fullId, $currentContent); } else { $client->setText($fullId, $currentContent); } } } } $res4 = $client->createSession($groupID, $authorID, time() + 14400); $sessionID = $res4->sessionID; setcookie('sessionID', $sessionID, null, "/"); $padID = $groupID . '$' . $padID; $data = array("url" => $this->baseURL . "/p/" . $padID, "padID" => $padID, "sessionID" => $sessionID); HTMLWriter::charsetHeader('application/json'); echo json_encode($data); } else { if ($actionName == "etherpad_save") { $padID = $httpVars["pad_id"]; if ($nodeExtension == "html" || $nodeExtension == "pad") { $res = $client->getHTML($padID); $content = $res->html; } else { $res = $client->getText($padID); $content = $res->text; } if ($nodeExtension == "pad") { // Create a new file and save the content in it. $origUrl = $selectedNode->getUrl(); $mess = ConfService::getMessages(); $dateStamp = date(" Y-m-d H:i", time()); $startUrl = preg_replace('"\\.pad$"', $dateStamp . '.html', $origUrl); $newNode = new AJXP_Node($startUrl); AJXP_Controller::applyHook("node.before_create", array($newNode, strlen($content))); file_put_contents($newNode->getUrl(), $content); AJXP_Controller::applyHook("node.change", array(null, $newNode)); } else { AJXP_Controller::applyHook("node.before_change", array($selectedNode, strlen($content))); file_put_contents($selectedNode->getUrl(), $content); clearstatcache(true, $selectedNode->getUrl()); $selectedNode->loadNodeInfo(true); AJXP_Controller::applyHook("node.change", array($selectedNode, $selectedNode)); } } else { if ($actionName == "etherpad_close") { // WE SHOULD DETECT IF THERE IS NOBODY CONNECTED ANYMORE, AND DELETE THE PAD. // BUT SEEMS LIKE THERE'S NO WAY TO PROPERLY REMOVE AN AUTHOR VIA API $sessionID = $httpVars["session_id"]; $client->deleteSession($sessionID); } else { if ($actionName == "etherpad_proxy_api") { if ($httpVars["api_action"] == "list_pads") { $res = $client->listPads($groupID); } else { if ($httpVars["api_action"] == "list_authors_for_pad") { $res = $client->listAuthorsOfPad($httpVars["pad_id"]); } } HTMLWriter::charsetHeader("application/json"); echo json_encode($res); } else { if ($actionName == "etherpad_get_content") { HTMLWriter::charsetHeader("text/plain"); echo $client->getText($httpVars["pad_id"])->text; } } } } } return null; }
/** * * @param AJXP_Node $oldNode * @param AJXP_Node $newNode * @param Boolean $copy */ public function deleteImagickCache($oldNode, $newNode = null, $copy = false) { if ($oldNode == null) { return; } $oldFile = $oldNode->getUrl(); // Should remove imagick cache file if (!$this->handleMime($oldFile)) { return; } if ($newNode == null || $copy == false) { AJXP_Cache::clearItem("imagick_thumb", $oldFile); $cache = AJXP_Cache::getItem("imagick_full", $oldFile, false); $prefix = str_replace("." . pathinfo($cache->getId(), PATHINFO_EXTENSION), "", $cache->getId()); $files = $this->listExtractedJpg($oldFile, $prefix); foreach ($files as $file) { if (is_file((defined('AJXP_SHARED_CACHE_DIR') ? AJXP_SHARED_CACHE_DIR : AJXP_CACHE_DIR) . "/" . $file["file"])) { unlink(AJXP_CACHE_DIR . "/" . $file["file"]); } } } }
public function switchAction($action, $httpVars, $filesVars) { if (!isset($this->actions[$action])) { return false; } $repository = ConfService::getRepository(); if (!$repository->detectStreamWrapper(true)) { return false; } $streamData = $repository->streamData; $destStreamURL = $streamData["protocol"] . "://" . $repository->getId(); if ($action == "post_to_zohoserver") { $sheetExt = explode(",", "xls,xlsx,ods,sxc,csv,tsv"); $presExt = explode(",", "ppt,pps,odp,sxi"); $docExt = explode(",", "doc,docx,rtf,odt,sxw"); require_once AJXP_BIN_FOLDER . "/http_class/http_class.php"; $selection = new UserSelection($repository, $httpVars); // Backward compat if (strpos($httpVars["file"], "base64encoded:") !== 0) { $file = AJXP_Utils::decodeSecureMagic(base64_decode($httpVars["file"])); } else { $file = $selection->getUniqueFile(); } $target = base64_decode($httpVars["parent_url"]); $tmp = call_user_func(array($streamData["classname"], "getRealFSReference"), $destStreamURL . $file); $tmp = SystemTextEncoding::fromUTF8($tmp); $node = new AJXP_Node($destStreamURL . $file); AJXP_Controller::applyHook("node.read", array($node)); $this->logInfo('Preview', 'Posting content of ' . $file . ' to Zoho server'); $extension = strtolower(pathinfo(urlencode(basename($file)), PATHINFO_EXTENSION)); $httpClient = new http_class(); $httpClient->request_method = "POST"; $secureToken = $httpVars["secure_token"]; $_SESSION["ZOHO_CURRENT_EDITED"] = $destStreamURL . $file; $_SESSION["ZOHO_CURRENT_UUID"] = md5(rand() . "-" . microtime()); if ($this->getFilteredOption("USE_ZOHO_AGENT", $repository->getId())) { $saveUrl = $this->getFilteredOption("ZOHO_AGENT_URL", $repository->getId()); } else { $saveUrl = $target . "/" . AJXP_PLUGINS_FOLDER . "/editor.zoho/agent/save_zoho.php"; } $b64Sig = $this->signID($_SESSION["ZOHO_CURRENT_UUID"]); $params = array('id' => $_SESSION["ZOHO_CURRENT_UUID"], 'apikey' => $this->getFilteredOption("ZOHO_API_KEY", $repository->getId()), 'output' => 'url', 'lang' => "en", 'filename' => urlencode(basename($file)), 'persistence' => 'false', 'format' => $extension, 'mode' => 'normaledit', 'saveurl' => $saveUrl . "?signature=" . $b64Sig); $service = "exportwriter"; if (in_array($extension, $sheetExt)) { $service = "sheet"; } else { if (in_array($extension, $presExt)) { $service = "show"; } else { if (in_array($extension, $docExt)) { $service = "exportwriter"; } } } $arguments = array(); $httpClient->GetRequestArguments("https://" . $service . ".zoho.com/remotedoc.im", $arguments); $arguments["PostValues"] = $params; $arguments["PostFiles"] = array("content" => array("FileName" => $tmp, "Content-Type" => "automatic/name")); $err = $httpClient->Open($arguments); if (empty($err)) { $err = $httpClient->SendRequest($arguments); if (empty($err)) { $response = ""; while (true) { $body = ""; $error = $httpClient->ReadReplyBody($body, 1000); if ($error != "" || strlen($body) == 0) { break; } $response .= $body; } $result = trim($response); $matchlines = explode("\n", $result); $resultValues = array(); foreach ($matchlines as $line) { list($key, $val) = explode("=", $line, 2); $resultValues[$key] = $val; } if ($resultValues["RESULT"] == "TRUE" && isset($resultValues["URL"])) { header("Location: " . $resultValues["URL"]); } else { echo "Zoho API Error " . $resultValues["ERROR_CODE"] . " : " . $resultValues["WARNING"]; echo "<script>window.parent.setTimeout(function(){parent.hideLightBox();}, 2000);</script>"; } } $httpClient->Close(); } } else { if ($action == "retrieve_from_zohoagent") { $targetFile = $_SESSION["ZOHO_CURRENT_EDITED"]; $id = $_SESSION["ZOHO_CURRENT_UUID"]; $ext = pathinfo($targetFile, PATHINFO_EXTENSION); $node = new AJXP_Node($targetFile); $node->loadNodeInfo(); AJXP_Controller::applyHook("node.before_change", array(&$node)); $b64Sig = $this->signID($id); if ($this->getFilteredOption("USE_ZOHO_AGENT", $repository->getId())) { $url = $this->getFilteredOption("ZOHO_AGENT_URL", $repository->getId()) . "?ajxp_action=get_file&name=" . $id . "&ext=" . $ext . "&signature=" . $b64Sig; $data = AJXP_Utils::getRemoteContent($url); if (strlen($data)) { file_put_contents($targetFile, $data); echo "MODIFIED"; } } else { if (is_file(AJXP_INSTALL_PATH . "/" . AJXP_PLUGINS_FOLDER . "/editor.zoho/agent/files/" . $id . "." . $ext)) { copy(AJXP_INSTALL_PATH . "/" . AJXP_PLUGINS_FOLDER . "/editor.zoho/agent/files/" . $id . "." . $ext, $targetFile); unlink(AJXP_INSTALL_PATH . "/" . AJXP_PLUGINS_FOLDER . "/editor.zoho/agent/files/" . $id . "." . $ext); echo "MODIFIED"; } } $this->logInfo('Edit', 'Retrieved content of ' . $node->getUrl()); AJXP_Controller::applyHook("node.change", array(null, &$node)); } } }