/** * * @param AJXP_Node $oldFile * @param AJXP_Node $newFile * @param Boolean $copy */ public function moveMeta($oldFile, $newFile = null, $copy = false) { if ($oldFile == null) { return; } $feedStore = AJXP_PluginsService::getInstance()->getUniqueActivePluginForType("feed"); if ($feedStore !== false) { $feedStore->updateMetaObject($oldFile->getRepositoryId(), $oldFile->getPath(), $newFile != null ? $newFile->getPath() : null, $copy); return; } if (!$copy && $this->metaStore->inherentMetaMove()) { return; } $oldMeta = $this->metaStore->retrieveMetadata($oldFile, AJXP_META_SPACE_COMMENTS); if (!count($oldMeta)) { return; } // If it's a move or a delete, delete old data if (!$copy) { $this->metaStore->removeMetadata($oldFile, AJXP_META_SPACE_COMMENTS); } // If copy or move, copy data. if ($newFile != null) { $this->metaStore->setMetadata($newFile, AJXP_META_SPACE_COMMENTS, $oldMeta); } }
/** * @param String $action * @param Array $httpVars * @param Array $fileVars * @throws Exception */ public function receiveAction($action, $httpVars, $fileVars) { //VAR CREATION OUTSIDE OF ALL CONDITIONS, THEY ARE "MUST HAVE" VAR !! $messages = ConfService::getMessages(); $repository = ConfService::getRepository(); $userSelection = new UserSelection($repository, $httpVars); $nodes = $userSelection->buildNodes(); $currentDirPath = AJXP_Utils::safeDirname($userSelection->getUniqueNode()->getPath()); $currentDirPath = rtrim($currentDirPath, "/") . "/"; $currentDirUrl = $userSelection->currentBaseUrl() . $currentDirPath; if (empty($httpVars["compression_id"])) { $compressionId = sha1(rand()); $httpVars["compression_id"] = $compressionId; } else { $compressionId = $httpVars["compression_id"]; } $progressCompressionFileName = $this->getPluginCacheDir(false, true) . DIRECTORY_SEPARATOR . "progressCompressionID-" . $compressionId . ".txt"; if (empty($httpVars["extraction_id"])) { $extractId = sha1(rand()); $httpVars["extraction_id"] = $extractId; } else { $extractId = $httpVars["extraction_id"]; } $progressExtractFileName = $this->getPluginCacheDir(false, true) . DIRECTORY_SEPARATOR . "progressExtractID-" . $extractId . ".txt"; if ($action == "compression") { $archiveName = AJXP_Utils::sanitize(AJXP_Utils::decodeSecureMagic($httpVars["archive_name"]), AJXP_SANITIZE_FILENAME); $archiveFormat = $httpVars["type_archive"]; $tabTypeArchive = array(".tar", ".tar.gz", ".tar.bz2"); $acceptedExtension = false; foreach ($tabTypeArchive as $extensionArchive) { if ($extensionArchive == $archiveFormat) { $acceptedExtension = true; break; } } if ($acceptedExtension == false) { file_put_contents($progressCompressionFileName, "Error : " . $messages["compression.16"]); throw new AJXP_Exception($messages["compression.16"]); } $typeArchive = $httpVars["type_archive"]; //if we can run in background we do it if (ConfService::backgroundActionsSupported() && !ConfService::currentContextIsCommandLine()) { $archivePath = $currentDirPath . $archiveName; file_put_contents($progressCompressionFileName, $messages["compression.5"]); AJXP_Controller::applyActionInBackground($repository->getId(), "compression", $httpVars); AJXP_XMLWriter::header(); AJXP_XMLWriter::triggerBgAction("check_compression_status", array("repository_id" => $repository->getId(), "compression_id" => $compressionId, "archive_path" => SystemTextEncoding::toUTF8($archivePath)), $messages["compression.5"], true, 2); AJXP_XMLWriter::close(); return null; } else { $maxAuthorizedSize = 4294967296; $currentDirUrlLength = strlen($currentDirUrl); $tabFolders = array(); $tabAllRecursiveFiles = array(); $tabFilesNames = array(); foreach ($nodes as $node) { $nodeUrl = $node->getUrl(); if (is_file($nodeUrl) && filesize($nodeUrl) < $maxAuthorizedSize) { array_push($tabAllRecursiveFiles, $nodeUrl); array_push($tabFilesNames, substr($nodeUrl, $currentDirUrlLength)); } if (is_dir($nodeUrl)) { array_push($tabFolders, $nodeUrl); } } //DO A FOREACH OR IT'S GONNA HAVE SOME SAMES FILES NAMES foreach ($tabFolders as $value) { $dossiers = new RecursiveIteratorIterator(new RecursiveDirectoryIterator($value)); foreach ($dossiers as $file) { if ($file->isDir()) { continue; } array_push($tabAllRecursiveFiles, $file->getPathname()); array_push($tabFilesNames, substr($file->getPathname(), $currentDirUrlLength)); } } //WE STOP IF IT'S JUST AN EMPTY FOLDER OR NO FILES if (empty($tabFilesNames)) { file_put_contents($progressCompressionFileName, "Error : " . $messages["compression.17"]); throw new AJXP_Exception($messages["compression.17"]); } try { $tmpArchiveName = tempnam(AJXP_Utils::getAjxpTmpDir(), "tar-compression") . ".tar"; $archive = new PharData($tmpArchiveName); } catch (Exception $e) { file_put_contents($progressCompressionFileName, "Error : " . $e->getMessage()); throw $e; } $counterCompression = 0; //THE TWO ARRAY ARE MERGED FOR THE FOREACH LOOP $tabAllFiles = array_combine($tabAllRecursiveFiles, $tabFilesNames); foreach ($tabAllFiles as $fullPath => $fileName) { try { $archive->addFile(AJXP_MetaStreamWrapper::getRealFSReference($fullPath), $fileName); $counterCompression++; file_put_contents($progressCompressionFileName, sprintf($messages["compression.6"], round($counterCompression / count($tabAllFiles) * 100, 0, PHP_ROUND_HALF_DOWN) . " %")); } catch (Exception $e) { unlink($tmpArchiveName); file_put_contents($progressCompressionFileName, "Error : " . $e->getMessage()); throw $e; } } $finalArchive = $tmpArchiveName; if ($typeArchive != ".tar") { $archiveTypeCompress = substr(strrchr($typeArchive, "."), 1); file_put_contents($progressCompressionFileName, sprintf($messages["compression.7"], strtoupper($archiveTypeCompress))); if ($archiveTypeCompress == "gz") { $archive->compress(Phar::GZ); } elseif ($archiveTypeCompress == "bz2") { $archive->compress(Phar::BZ2); } $finalArchive = $tmpArchiveName . "." . $archiveTypeCompress; } $destArchive = AJXP_MetaStreamWrapper::getRealFSReference($currentDirUrl . $archiveName); rename($finalArchive, $destArchive); AJXP_Controller::applyHook("node.before_create", array($destArchive, filesize($destArchive))); if (file_exists($tmpArchiveName)) { unlink($tmpArchiveName); unlink(substr($tmpArchiveName, 0, -4)); } $newNode = new AJXP_Node($currentDirUrl . $archiveName); AJXP_Controller::applyHook("node.change", array(null, $newNode, false)); file_put_contents($progressCompressionFileName, "SUCCESS"); } } elseif ($action == "check_compression_status") { $archivePath = AJXP_Utils::decodeSecureMagic($httpVars["archive_path"]); $progressCompression = file_get_contents($progressCompressionFileName); $substrProgressCompression = substr($progressCompression, 0, 5); if ($progressCompression != "SUCCESS" && $substrProgressCompression != "Error") { AJXP_XMLWriter::header(); AJXP_XMLWriter::triggerBgAction("check_compression_status", array("repository_id" => $repository->getId(), "compression_id" => $compressionId, "archive_path" => SystemTextEncoding::toUTF8($archivePath)), $progressCompression, true, 5); AJXP_XMLWriter::close(); } elseif ($progressCompression == "SUCCESS") { $newNode = new AJXP_Node($userSelection->currentBaseUrl() . $archivePath); $nodesDiffs = array("ADD" => array($newNode), "REMOVE" => array(), "UPDATE" => array()); AJXP_Controller::applyHook("node.change", array(null, $newNode, false)); AJXP_XMLWriter::header(); AJXP_XMLWriter::sendMessage($messages["compression.8"], null); AJXP_XMLWriter::writeNodesDiff($nodesDiffs, true); AJXP_XMLWriter::close(); if (file_exists($progressCompressionFileName)) { unlink($progressCompressionFileName); } } elseif ($substrProgressCompression == "Error") { AJXP_XMLWriter::header(); AJXP_XMLWriter::sendMessage(null, $progressCompression); AJXP_XMLWriter::close(); if (file_exists($progressCompressionFileName)) { unlink($progressCompressionFileName); } } } elseif ($action == "extraction") { $fileArchive = AJXP_Utils::sanitize(AJXP_Utils::decodeSecureMagic($httpVars["file"]), AJXP_SANITIZE_DIRNAME); $fileArchive = substr(strrchr($fileArchive, DIRECTORY_SEPARATOR), 1); $authorizedExtension = array("tar" => 4, "gz" => 7, "bz2" => 8); $acceptedArchive = false; $extensionLength = 0; $counterExtract = 0; $currentAllPydioPath = $currentDirUrl . $fileArchive; $pharCurrentAllPydioPath = "phar://" . AJXP_MetaStreamWrapper::getRealFSReference($currentAllPydioPath); $pathInfoCurrentAllPydioPath = pathinfo($currentAllPydioPath, PATHINFO_EXTENSION); //WE TAKE ONLY TAR, TAR.GZ AND TAR.BZ2 ARCHIVES foreach ($authorizedExtension as $extension => $strlenExtension) { if ($pathInfoCurrentAllPydioPath == $extension) { $acceptedArchive = true; $extensionLength = $strlenExtension; break; } } if ($acceptedArchive == false) { file_put_contents($progressExtractFileName, "Error : " . $messages["compression.15"]); throw new AJXP_Exception($messages["compression.15"]); } $onlyFileName = substr($fileArchive, 0, -$extensionLength); $lastPosOnlyFileName = strrpos($onlyFileName, "-"); $tmpOnlyFileName = substr($onlyFileName, 0, $lastPosOnlyFileName); $counterDuplicate = substr($onlyFileName, $lastPosOnlyFileName + 1); if (!is_int($lastPosOnlyFileName) || !is_int($counterDuplicate)) { $tmpOnlyFileName = $onlyFileName; $counterDuplicate = 1; } while (file_exists($currentDirUrl . $onlyFileName)) { $onlyFileName = $tmpOnlyFileName . "-" . $counterDuplicate; $counterDuplicate++; } if (ConfService::backgroundActionsSupported() && !ConfService::currentContextIsCommandLine()) { file_put_contents($progressExtractFileName, $messages["compression.12"]); AJXP_Controller::applyActionInBackground($repository->getId(), "extraction", $httpVars); AJXP_XMLWriter::header(); AJXP_XMLWriter::triggerBgAction("check_extraction_status", array("repository_id" => $repository->getId(), "extraction_id" => $extractId, "currentDirUrl" => $currentDirUrl, "onlyFileName" => $onlyFileName), $messages["compression.12"], true, 2); AJXP_XMLWriter::close(); return null; } mkdir($currentDirUrl . $onlyFileName, 0777, true); chmod(AJXP_MetaStreamWrapper::getRealFSReference($currentDirUrl . $onlyFileName), 0777); try { $archive = new PharData(AJXP_MetaStreamWrapper::getRealFSReference($currentAllPydioPath)); $fichiersArchive = new RecursiveIteratorIterator(new RecursiveDirectoryIterator($pharCurrentAllPydioPath)); foreach ($fichiersArchive as $file) { $fileGetPathName = $file->getPathname(); if ($file->isDir()) { continue; } $fileNameInArchive = substr(strstr($fileGetPathName, $fileArchive), strlen($fileArchive) + 1); try { $archive->extractTo(AJXP_MetaStreamWrapper::getRealFSReference($currentDirUrl . $onlyFileName), $fileNameInArchive, false); } catch (Exception $e) { file_put_contents($progressExtractFileName, "Error : " . $e->getMessage()); throw new AJXP_Exception($e); } $counterExtract++; file_put_contents($progressExtractFileName, sprintf($messages["compression.13"], round($counterExtract / $archive->count() * 100, 0, PHP_ROUND_HALF_DOWN) . " %")); } } catch (Exception $e) { file_put_contents($progressExtractFileName, "Error : " . $e->getMessage()); throw new AJXP_Exception($e); } file_put_contents($progressExtractFileName, "SUCCESS"); $newNode = new AJXP_Node($currentDirUrl . $onlyFileName); AJXP_Controller::findActionAndApply("index", array("file" => $newNode->getPath()), array()); } elseif ($action == "check_extraction_status") { $currentDirUrl = $httpVars["currentDirUrl"]; $onlyFileName = $httpVars["onlyFileName"]; $progressExtract = file_get_contents($progressExtractFileName); $substrProgressExtract = substr($progressExtract, 0, 5); if ($progressExtract != "SUCCESS" && $progressExtract != "INDEX" && $substrProgressExtract != "Error") { AJXP_XMLWriter::header(); AJXP_XMLWriter::triggerBgAction("check_extraction_status", array("repository_id" => $repository->getId(), "extraction_id" => $extractId, "currentDirUrl" => $currentDirUrl, "onlyFileName" => $onlyFileName), $progressExtract, true, 4); AJXP_XMLWriter::close(); } elseif ($progressExtract == "SUCCESS") { $newNode = new AJXP_Node($currentDirUrl . $onlyFileName); $nodesDiffs = array("ADD" => array($newNode), "REMOVE" => array(), "UPDATE" => array()); AJXP_Controller::applyHook("node.change", array(null, $newNode, false)); AJXP_XMLWriter::header(); AJXP_XMLWriter::sendMessage(sprintf($messages["compression.14"], $onlyFileName), null); AJXP_XMLWriter::triggerBgAction("check_index_status", array("repository_id" => $newNode->getRepositoryId()), "starting indexation", true, 5); AJXP_XMLWriter::writeNodesDiff($nodesDiffs, true); AJXP_XMLWriter::close(); if (file_exists($progressExtractFileName)) { unlink($progressExtractFileName); } } elseif ($substrProgressExtract == "Error") { AJXP_XMLWriter::header(); AJXP_XMLWriter::sendMessage(null, $progressExtract); AJXP_XMLWriter::close(); if (file_exists($progressExtractFileName)) { unlink($progressExtractFileName); } } } }
/** * @param String $watchType * @param String $currentUserId * @param AJXP_Node $node * @param array|bool $watchMeta * @param array|bool $usersMeta * @return array */ private function loadWatchesFromMeta($watchType, $currentUserId, $node, $watchMeta = false, $usersMeta = false) { $IDS = array(); if ($usersMeta !== false) { if ($watchType == self::$META_WATCH_CHANGE && isset($usersMeta[self::$META_WATCH_USERS_CHANGE])) { $usersMeta = $usersMeta[self::$META_WATCH_USERS_CHANGE]; } else { if ($watchType == self::$META_WATCH_READ && isset($usersMeta[self::$META_WATCH_USERS_READ])) { $usersMeta = $usersMeta[self::$META_WATCH_USERS_READ]; } else { $usersMeta = null; } } } if (!empty($watchMeta) && is_array($watchMeta)) { foreach ($watchMeta as $id => $type) { if ($type == $watchType || $type == self::$META_WATCH_BOTH) { $IDS[] = $id; } } } if (!empty($usersMeta) && is_array($usersMeta)) { foreach ($usersMeta as $id => $targetUsers) { if (in_array($currentUserId, $targetUsers)) { $IDS[] = $id; } } } if (count($IDS)) { $changes = false; foreach ($IDS as $index => $id) { if ($currentUserId == $id && !AJXP_SERVER_DEBUG) { // In non-debug mode, do not send notifications to watcher! unset($IDS[$index]); continue; } if (!AuthService::userExists($id)) { unset($IDS[$index]); if (is_array($watchMeta)) { $changes = true; $watchMeta[$id] = AJXP_VALUE_CLEAR; } } else { // Make sure the user is still authorized on this node, otherwise remove it. $uObject = ConfService::getConfStorageImpl()->createUserObject($id); $acl = $uObject->mergedRole->getAcl($node->getRepositoryId()); $isOwner = $node->getRepository()->getOwner() == $uObject->getId(); if (!$isOwner && (empty($acl) || strpos($acl, "r") === FALSE)) { unset($IDS[$index]); if (is_array($watchMeta)) { $changes = true; $watchMeta[$id] = AJXP_VALUE_CLEAR; } } } } if ($changes) { $node->setMetadata(self::$META_WATCH_NAMESPACE, $watchMeta, false, AJXP_METADATA_SCOPE_REPOSITORY); } } return $IDS; }
/** * @param AJXP_Node $origNode * @param AJXP_Node $newNode * @param bool $copy */ public function publishNodeChange($origNode = null, $newNode = null, $copy = false) { $content = ""; $repo = ""; $targetUserId = null; $nodePathes = array(); $update = false; if ($newNode != null) { $repo = $newNode->getRepositoryId(); $targetUserId = $newNode->getUser(); $nodePathes[] = $newNode->getPath(); $update = false; $data = array(); if ($origNode != null && !$copy) { $update = true; $data[$origNode->getPath()] = $newNode; } else { $data[] = $newNode; } $content = AJXP_XMLWriter::writeNodesDiff(array($update ? "UPDATE" : "ADD" => $data)); } if ($origNode != null && !$update && !$copy) { $repo = $origNode->getRepositoryId(); $targetUserId = $origNode->getUser(); $nodePathes[] = $origNode->getPath(); $content = AJXP_XMLWriter::writeNodesDiff(array("REMOVE" => array($origNode->getPath()))); } if (!empty($content) && $repo != "") { $this->sendInstantMessage($content, $repo, $targetUserId, null, $nodePathes); } }
/** * @param array $shares * @param String $operation * @param AJXP_Node $oldNode * @param AJXP_Node $newNode * @param array $collectRepositories * @param string|null $parentRepositoryPath * @return array * @throws Exception */ public function moveSharesFromMeta($shares, $operation = "move", $oldNode, $newNode = null, &$collectRepositories = array(), $parentRepositoryPath = null) { $privateShares = array(); $publicShares = array(); foreach ($shares as $id => $data) { $type = $data["type"]; if ($operation == "delete") { $this->deleteShare($type, $id, false, true); continue; } if ($type == "minisite") { $share = $this->loadShare($id); $repo = ConfService::getRepositoryById($share["REPOSITORY"]); } else { if ($type == "repository") { $repo = ConfService::getRepositoryById($id); } else { if ($type == "file") { $publicLink = $this->loadShare($id); } } } if (isset($repo)) { $oldNodeLabel = SystemTextEncoding::toUTF8($oldNode->getLabel()); $newNodeLabel = SystemTextEncoding::toUTF8($newNode->getLabel()); if ($newNode != null && $newNodeLabel != $oldNodeLabel && $repo->getDisplay() == $oldNodeLabel) { $repo->setDisplay($newNodeLabel); } $cFilter = $repo->getContentFilter(); $path = $repo->getOption("PATH", true); $save = false; if (isset($cFilter)) { if ($parentRepositoryPath !== null) { $repo->addOption("PATH", $parentRepositoryPath); } else { $cFilter->movePath($oldNode->getPath(), $newNode->getPath()); $repo->setContentFilter($cFilter); } $save = true; } else { if (!empty($path)) { $oldNodePath = SystemTextEncoding::toUTF8($oldNode->getPath()); $newNodePath = SystemTextEncoding::toUTF8($newNode->getPath()); $path = preg_replace("#" . preg_quote($oldNodePath, "#") . "\$#", $newNodePath, $path); $repo->addOption("PATH", $path); $save = true; $collectRepositories[$repo->getId()] = $path; } } if ($save) { //ConfService::getConfStorageImpl()->saveRepository($repo, true); ConfService::replaceRepository($repo->getId(), $repo); } $access = $repo->getOption("SHARE_ACCESS"); if (!empty($access) && $access == "PUBLIC") { $publicShares[$id] = $data; } else { $privateShares[$id] = $data; } } else { if (isset($publicLink) && is_array($publicLink) && isset($publicLink["FILE_PATH"])) { $oldNodePath = SystemTextEncoding::toUTF8($oldNode->getPath()); $newNodePath = SystemTextEncoding::toUTF8($newNode->getPath()); $publicLink["FILE_PATH"] = str_replace($oldNodePath, $newNodePath, $publicLink["FILE_PATH"]); $this->deleteShare("file", $id); $this->storeShare($newNode->getRepositoryId(), $publicLink, "file", $id); $privateShares[$id] = $data; } } } return array($privateShares, $publicShares); }
/** * @param AJXP_Node $ajxpNode * @param Boolean $isParent */ public function extractMimeHeaders(&$ajxpNode, $isParent = false) { if ($isParent) { return; } $currentNode = $ajxpNode->getUrl(); $metadata = $ajxpNode->metadata; $wrapperClassName = AJXP_MetaStreamWrapper::actualRepositoryWrapperClass($ajxpNode->getRepositoryId()); $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; }
/** * * Hooked to node.change, this will update the index * if $oldNode = null => create node $newNode * if $newNode = null => delete node $oldNode * Else copy or move oldNode to newNode. * * @param AJXP_Node $oldNode * @param AJXP_Node $newNode * @param Boolean $copy * @param bool $recursive */ public function updateNodeIndex($oldNode, $newNode = null, $copy = false, $recursive = false) { if ($oldNode == null) { $this->loadIndex($newNode->getRepositoryId(), true, $newNode->getUser()); } else { $this->loadIndex($oldNode->getRepositoryId(), true, $oldNode->getUser()); } if ($oldNode != null && $copy == false) { $oldDocId = $this->getIndexedDocumentId($oldNode); if ($oldDocId != null) { $this->currentType->deleteById($oldDocId); $childrenHits = $this->getIndexedChildrenDocuments($newNode); if ($childrenHits != null) { $childrenHits = $childrenHits->getResults(); foreach ($childrenHits as $hit) { $this->currentType->deleteById($hit->getId()); } } } } if ($newNode != null) { // Make sure it does not already exists anyway $newDocId = $this->getIndexedDocumentId($newNode); if ($newDocId != null) { try { $this->currentType->deleteById($newDocId); } catch (Elastica\Exception\NotFoundException $eEx) { $this->logError(__FUNCTION__, "Trying to delete a non existing document"); } $childrenHits = $this->getIndexedChildrenDocuments($newNode); if ($childrenHits != null) { $childrenHits = $childrenHits->getResults(); foreach ($childrenHits as $hit) { try { $this->currentType->deleteById($hit->getId()); } catch (Elastica\Exception\NotFoundException $eEx) { $this->logError(__FUNCTION__, "Trying to delete a non existing document"); } } } } $this->createIndexedDocument($newNode); if ($recursive && $oldNode == null && is_dir($newNode->getUrl())) { $this->recursiveIndexation($newNode->getUrl()); } } if ($oldNode != null && $newNode != null && is_dir($newNode->getUrl())) { // Copy / Move / Rename // Get old node children docs, and update them manually, no need to scan real directory $childrenHits = $this->getIndexedChildrenDocuments($oldNode); if ($childrenHits != null) { $childrenHits = $childrenHits->getResults(); foreach ($childrenHits as $hit) { $oldChildURL = $this->currentType->getDocument($hit->getId())->get("node_url"); if ($copy == false) { $this->currentType->deleteById($hit->getId()); } $newChildURL = str_replace(SystemTextEncoding::toUTF8($oldNode->getUrl()), SystemTextEncoding::toUTF8($newNode->getUrl()), $oldChildURL); $newChildURL = SystemTextEncoding::fromUTF8($newChildURL); $this->createIndexedDocument(new AJXP_Node($newChildURL)); } } } }
/** * * Hooked to node.change, this will update the index * if $oldNode = null => create node $newNode * if $newNode = null => delete node $oldNode * Else copy or move oldNode to newNode. * * @param AJXP_Node $oldNode * @param AJXP_Node $newNode * @param Boolean $copy * @param bool $recursive */ public function updateNodeIndex($oldNode, $newNode = null, $copy = false, $recursive = false) { require_once "Zend/Search/Lucene.php"; if (isset($this->currentIndex)) { $oldIndex = $newIndex = $this->currentIndex; } else { if ($oldNode == null) { $newIndex = $oldIndex = $this->loadIndex($newNode->getRepositoryId(), true, $newNode->getUser()); } else { if ($newNode == null) { $oldIndex = $newIndex = $this->loadIndex($oldNode->getRepositoryId(), true, $oldNode->getUser()); } else { $newId = $newNode->getRepositoryId(); $oldId = $oldNode->getRepositoryId(); if ($newId == $oldId) { $newIndex = $oldIndex = $this->loadIndex($newNode->getRepositoryId(), true, $newNode->getUser()); } else { $newIndex = $this->loadIndex($newNode->getRepositoryId(), true, $newNode->getUser()); $oldIndex = $this->loadIndex($oldNode->getRepositoryId(), true, $oldNode->getUser()); } } } } $this->setDefaultAnalyzer(); if ($oldNode != null && $copy == false) { $oldDocId = $this->getIndexedDocumentId($oldIndex, $oldNode); if ($oldDocId != null) { $oldIndex->delete($oldDocId); if ($newNode == null) { // DELETION $childrenHits = $this->getIndexedChildrenDocuments($oldIndex, $oldNode); foreach ($childrenHits as $hit) { $oldIndex->delete($hit->id); } } } } if ($newNode != null) { // Make sure it does not already exists anyway $newDocId = $this->getIndexedDocumentId($newIndex, $newNode); if ($newDocId != null) { $newIndex->delete($newDocId); $childrenHits = $this->getIndexedChildrenDocuments($newIndex, $newNode); foreach ($childrenHits as $hit) { $newIndex->delete($hit->id); } } $this->createIndexedDocument($newNode, $newIndex); if ($recursive && $oldNode == null && is_dir($newNode->getUrl())) { $this->recursiveIndexation($newNode->getUrl()); } } if ($oldNode != null && $newNode != null && is_dir($newNode->getUrl()) && $newIndex == $oldIndex) { // Copy / Move / Rename // Get old node children docs, and update them manually, no need to scan real directory $childrenHits = $this->getIndexedChildrenDocuments($oldIndex, $oldNode); foreach ($childrenHits as $hit) { $oldChildURL = $oldIndex->getDocument($hit->id)->node_url; if ($copy == false) { $oldIndex->delete($hit->id); } $newChildURL = str_replace(SystemTextEncoding::toUTF8($oldNode->getUrl()), SystemTextEncoding::toUTF8($newNode->getUrl()), $oldChildURL); $newChildURL = SystemTextEncoding::fromUTF8($newChildURL); $this->createIndexedDocument(new AJXP_Node($newChildURL), $oldIndex); } } if (!isset($this->currentIndex)) { $oldIndex->commit(); if ($newIndex != $oldIndex) { $newIndex->commit(); } } }
/** * @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)); } } }
/** * @param AJXP_Node $oldNode * @param AJXP_Node $newNode * @param bool $copy */ public function updateNodeSharedData($oldNode = null, $newNode = null, $copy = false) { if ($oldNode != null && !$copy) { $this->logDebug("Should update node"); $delete = false; if ($newNode == null) { $delete = true; } else { $repo = $newNode->getRepository(); $recycle = $repo->getOption("RECYCLE_BIN"); if (!empty($recycle) && strpos($newNode->getPath(), $recycle) === 1) { $delete = true; } } $this->getSharesFromMeta($oldNode, $shares, true); if (empty($shares)) { return; } $newShares = array(); foreach ($shares as $id => $data) { $type = $data["type"]; if ($delete) { $this->getShareStore()->deleteShare($type, $id); continue; } if ($type == "minisite") { $share = $this->getShareStore()->loadShare($id); $repo = ConfService::getRepositoryById($share["REPOSITORY"]); } else { if ($type == "repository") { $repo = ConfService::getRepositoryById($id); } else { if ($type == "file") { $publicLink = $this->getShareStore()->loadShare($id); } } } if (isset($repo)) { $cFilter = $repo->getContentFilter(); $path = $repo->getOption("PATH", true); $save = false; if (isset($cFilter)) { $cFilter->movePath($oldNode->getPath(), $newNode->getPath()); $repo->setContentFilter($cFilter); $save = true; } else { if (!empty($path)) { $path = str_replace($oldNode->getPath(), $newNode->getPath(), $path); $repo->addOption("PATH", $path); $save = true; } } if ($save) { ConfService::getConfStorageImpl()->saveRepository($repo, true); $newShares[$id] = $data; } } else { if (isset($publicLink["FILE_PATH"])) { $publicLink["FILE_PATH"] = str_replace($oldNode->getPath(), $newNode->getPath(), $publicLink["FILE_PATH"]); $this->getShareStore()->deleteShare("file", $id); $this->getShareStore()->storeShare($newNode->getRepositoryId(), $publicLink, "file", $id); $newShares[$id] = $data; } } } $oldNode->removeMetadata("ajxp_shared", true, AJXP_METADATA_SCOPE_REPOSITORY, true); if ($newNode != null && count($newShares)) { $newNode->setMetadata("ajxp_shared", array("shares" => $newShares), true, AJXP_METADATA_SCOPE_REPOSITORY, true); } } }
/** * @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)); } }
/** * @param AJXP_Node $ajxpNode * @param string $nameSpace * @param string $userScope * @return array */ public function collectChildrenWithRepositoryMeta($ajxpNode, $nameSpace, $userScope) { $result = array(); $repositoryId = $ajxpNode->getRepositoryId(); $metaFile = $this->globalMetaFile . "_" . $repositoryId; $metaFile = $this->updateSecurityScope($metaFile, $ajxpNode->getRepositoryId(), $ajxpNode->getUser()); if (!is_file($metaFile)) { return $result; } $raw_data = file_get_contents($metaFile); if ($raw_data === false) { return $result; } $metadata = unserialize($raw_data); if ($metadata === false || !is_array($metadata)) { return $result; } $srcPath = $ajxpNode->getPath(); if ($srcPath == "/") { $srcPath = ""; } foreach ($metadata as $path => $data) { preg_match("#^" . preg_quote($srcPath, "#") . "/#", $path, $matches); if ($path == $srcPath || count($matches)) { $relativePath = substr($path, strlen($srcPath)); // REMOVE ORIGINAL NODE PATH if ($relativePath === false) { $relativePath = "/"; } foreach ($data as $userId => $meta) { if (($userScope == $userId || $userScope == AJXP_METADATA_ALLUSERS) && isset($meta[$nameSpace])) { if (!isset($result[$relativePath])) { $result[$relativePath] = array(); } $result[$relativePath][$userId] = $meta[$nameSpace]; } } } } return $result; }
public function persistChangeHookToFeed(AJXP_Node $oldNode = null, AJXP_Node $newNode = null, $copy = false, $targetNotif = "new") { if (!$this->eventStore) { return; } $nodes = []; if ($oldNode !== null && $newNode !== null && $oldNode->getRepositoryId() !== $newNode->getRepositoryId()) { $nodes[] = $oldNode; $nodes[] = $newNode; } else { $nodes[] = $oldNode === null ? $newNode : $oldNode; } foreach ($nodes as $n) { $repoId = $n->getRepositoryId(); $userGroup = null; if ($n->getUser()) { $userId = $n->getUser(); $obj = ConfService::getConfStorageImpl()->createUserObject($userId); if ($obj) { $userGroup = $obj->getGroupPath(); } } else { $userId = AuthService::getLoggedUser()->getId(); $userGroup = AuthService::getLoggedUser()->getGroupPath(); } $repository = ConfService::getRepositoryById($repoId); $repositoryScope = $repository->securityScope(); $repositoryScope = $repositoryScope !== false ? $repositoryScope : "ALL"; $repositoryOwner = $repository->hasOwner() ? $repository->getOwner() : null; AJXP_Controller::applyHook("msg.instant", array("<reload_user_feed/>", $repoId, $userId)); $this->eventStore->persistEvent("node.change", func_get_args(), $repoId, $repositoryScope, $repositoryOwner, $userId, $userGroup); } }