function renderHeaderNode($nodeName, $nodeLabel, $isLeaf, $metaData = array())
 {
     header('Content-Type: text/xml; charset=UTF-8');
     header('Cache-Control: no-cache');
     print '<?xml version="1.0" encoding="UTF-8"?>';
     AJXP_XMLWriter::renderNode($nodeName, $nodeLabel, $isLeaf, $metaData, false);
 }
예제 #2
0
 /**
  * List all bookmmarks as XML
  * @static
  * @param $allBookmarks
  * @param bool $print
  * @param string $format legacy|node_list
  * @return string
  */
 public static function writeBookmarks($allBookmarks, $print = true, $format = "legacy")
 {
     $driver = false;
     if ($format == "node_list") {
         $driver = ConfService::loadRepositoryDriver();
         if (!is_a($driver, "AjxpWrapperProvider")) {
             $driver = false;
         }
     }
     $buffer = "";
     foreach ($allBookmarks as $bookmark) {
         $path = "";
         $title = "";
         if (is_array($bookmark)) {
             $path = $bookmark["PATH"];
             $title = $bookmark["TITLE"];
         } else {
             if (is_string($bookmark)) {
                 $path = $bookmark;
                 $title = basename($bookmark);
             }
         }
         if ($format == "node_list") {
             if ($driver) {
                 $node = new AJXP_Node($driver->getResourceUrl($path));
                 $buffer .= AJXP_XMLWriter::renderAjxpNode($node, true, false);
             } else {
                 $buffer .= AJXP_XMLWriter::renderNode($path, $title, false, array('icon' => "mime_empty.png"), true, false);
             }
         } else {
             $buffer .= "<bookmark path=\"" . AJXP_Utils::xmlEntities($path, true) . "\" title=\"" . AJXP_Utils::xmlEntities($title, true) . "\"/>";
         }
     }
     if ($print) {
         print $buffer;
         return null;
     } else {
         return $buffer;
     }
 }
예제 #3
0
 public function applyActions($actionName, $httpVars, $fileVars)
 {
     $git = new VersionControl_Git($this->repoBase);
     switch ($actionName) {
         case "git_history":
             $file = AJXP_Utils::decodeSecureMagic($httpVars["file"]);
             $file = ltrim($file, "/");
             $res = $this->gitHistory($git, $file);
             AJXP_XMLWriter::header();
             $ic = AJXP_Utils::mimetype($file, "image", false);
             $index = count($res);
             $mess = ConfService::getMessages();
             foreach ($res as &$commit) {
                 unset($commit["DETAILS"]);
                 $commit["icon"] = $ic;
                 $commit["index"] = $index;
                 $commit["EVENT"] = $mess["meta.git." . $commit["EVENT"]];
                 $index--;
                 AJXP_XMLWriter::renderNode("/" . $commit["ID"], basename($commit["FILE"]), true, $commit);
             }
             AJXP_XMLWriter::close();
             break;
             break;
         case "git_revertfile":
             $originalFile = AJXP_Utils::decodeSecureMagic($httpVars["original_file"]);
             $file = AJXP_Utils::decodeSecureMagic($httpVars["file"]);
             $commitId = $httpVars["commit_id"];
             $command = $git->getCommand("cat-file");
             $command->setOption("s", true);
             $command->addArgument($commitId . ":" . $file);
             $size = $command->execute();
             $command = $git->getCommand("show");
             $command->addArgument($commitId . ":" . $file);
             $commandLine = $command->createCommandString();
             $outputStream = fopen($this->repoBase . $originalFile, "w");
             $this->executeCommandInStreams($git, $commandLine, $outputStream);
             fclose($outputStream);
             $this->commitChanges();
             AJXP_XMLWriter::header();
             AJXP_XMLWriter::reloadDataNode();
             AJXP_XMLWriter::close();
             break;
         case "git_getfile":
             $file = AJXP_Utils::decodeSecureMagic($httpVars["file"]);
             $commitId = $httpVars["commit_id"];
             $attach = $httpVars["attach"];
             $command = $git->getCommand("cat-file");
             $command->setOption("s", true);
             $command->addArgument($commitId . ":" . $file);
             $size = $command->execute();
             $command = $git->getCommand("show");
             $command->addArgument($commitId . ":" . $file);
             $commandLine = $command->createCommandString();
             if ($attach == "inline") {
                 $fileExt = substr(strrchr(basename($file), '.'), 1);
                 if (empty($fileExt)) {
                     $fileMime = "application/octet-stream";
                 } else {
                     $regex = "/^([\\w\\+\\-\\.\\/]+)\\s+(\\w+\\s)*({$fileExt}\\s)/i";
                     $lines = file(AJXP_INSTALL_PATH . "/" . AJXP_PLUGINS_FOLDER . "/editor.browser/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];
                     }
                 }
                 if (empty($fileMime)) {
                     $fileMime = "application/octet-stream";
                 }
                 HTMLWriter::generateInlineHeaders(basename($file), $size, $fileMime);
             } else {
                 HTMLWriter::generateAttachmentsHeader(basename($file), $size, false, false);
             }
             $outputStream = fopen("php://output", "a");
             $this->executeCommandInStreams($git, $commandLine, $outputStream);
             fclose($outputStream);
             break;
             break;
         default:
             break;
     }
 }
 function listRepositories()
 {
     $repos = ConfService::getRepositoriesList();
     AJXP_XMLWriter::sendFilesListComponentConfig('<columns switchGridMode="filelist"><column messageId="ajxp_conf.8" attributeName="ajxp_label" sortType="String"/><column messageId="ajxp_conf.9" attributeName="accessType" sortType="String"/><column messageId="ajxp_shared.9" attributeName="repo_accesses" sortType="String"/></columns>');
     $repoArray = array();
     $childRepos = array();
     $loggedUser = AuthService::getLoggedUser();
     $users = AuthService::listUsers();
     foreach ($repos as $repoIndex => $repoObject) {
         if ($repoObject->getAccessType() == "ajxp_conf") {
             continue;
         }
         if (!$repoObject->hasOwner() || $repoObject->getOwner() != $loggedUser->getId()) {
             continue;
         }
         if (is_numeric($repoIndex)) {
             $repoIndex = "" . $repoIndex;
         }
         $name = AJXP_Utils::xmlEntities(SystemTextEncoding::toUTF8($repoObject->getDisplay()));
         $repoArray[$name] = $repoIndex;
     }
     // Sort the list now by name
     ksort($repoArray);
     // Append child repositories
     $sortedArray = array();
     foreach ($repoArray as $name => $repoIndex) {
         $sortedArray[$name] = $repoIndex;
         if (isset($childRepos[$repoIndex]) && is_array($childRepos[$repoIndex])) {
             foreach ($childRepos[$repoIndex] as $childData) {
                 $sortedArray[$childData["name"]] = $childData["index"];
             }
         }
     }
     foreach ($sortedArray as $name => $repoIndex) {
         $repoObject =& $repos[$repoIndex];
         $repoAccesses = array();
         foreach ($users as $userId => $userObject) {
             if (!$userObject->hasParent()) {
                 continue;
             }
             if ($userObject->canWrite($repoIndex)) {
                 $repoAccesses[] = $userId . " (rw)";
             } else {
                 if ($userObject->canRead($repoIndex)) {
                     $repoAccesses[] = $userId . " (r)";
                 }
             }
         }
         $metaData = array("repository_id" => $repoIndex, "accessType" => $repoObject->getAccessType(), "icon" => "document_open_remote.png", "openicon" => "document_open_remote.png", "parentname" => "/repositories", "repo_accesses" => implode(", ", $repoAccesses), "ajxp_mime" => "shared_repository");
         AJXP_XMLWriter::renderNode("/repositories/{$repoIndex}", $name, true, $metaData);
     }
 }
예제 #5
0
 public function listTasks($nodeName, $baseDir)
 {
     $mess = ConfService::getMessages();
     AJXP_XMLWriter::renderHeaderNode("/{$baseDir}/{$nodeName}", "Scheduler", false, array("icon" => "scheduler/ICON_SIZE/player_time.png"));
     AJXP_XMLWriter::sendFilesListComponentConfig('<columns switchGridMode="filelist" switchDisplayMode="list"  template_name="action.scheduler_list">
              <column messageId="action.scheduler.12" attributeName="ajxp_label" sortType="String"/>
              <column messageId="action.scheduler.2" attributeName="schedule" sortType="String"/>
              <column messageId="action.scheduler.1" attributeName="action_name" sortType="String"/>
              <column messageId="action.scheduler.4s" attributeName="repository_id" sortType="String"/>
              <column messageId="action.scheduler.17" attributeName="user_id" sortType="String"/>
              <column messageId="action.scheduler.3" attributeName="NEXT_EXECUTION" sortType="String"/>
              <column messageId="action.scheduler.14" attributeName="LAST_EXECUTION" sortType="String"/>
              <column messageId="action.scheduler.13" attributeName="STATUS" sortType="String"/>
     </columns>');
     $tasks = AJXP_Utils::loadSerialFile($this->getDbFile(), false, "json");
     foreach ($tasks as $task) {
         $timeArray = $this->getTimeArray($task["schedule"]);
         $res = $this->getNextExecutionTimeForScript(time(), $timeArray);
         $task["NEXT_EXECUTION"] = date($mess["date_format"], $res);
         $task["PARAMS"] = implode(", ", $task["PARAMS"]);
         $task["icon"] = "scheduler/ICON_SIZE/task.png";
         $task["ajxp_mime"] = "scheduler_task";
         $sFile = AJXP_CACHE_DIR . "/cmd_outputs/task_" . $task["task_id"] . ".status";
         if (is_file($sFile)) {
             $s = $this->getTaskStatus($task["task_id"]);
             $task["STATUS"] = implode(":", $s);
             $task["LAST_EXECUTION"] = date($mess["date_format"], filemtime($sFile));
         } else {
             $task["STATUS"] = "n/a";
             $task["LAST_EXECUTION"] = "n/a";
         }
         AJXP_XMLWriter::renderNode("/admin/scheduler/" . $task["task_id"], isset($task["label"]) ? $task["label"] : "Action " . $task["action_name"], true, $task);
     }
     AJXP_XMLWriter::close();
 }
예제 #6
0
 function listLayers($nodeList, $xPath, $replaceCallback = null)
 {
     foreach ($nodeList as $key => $node) {
         $name = $xPath->evaluate("Name", $node)->item(0)->nodeValue;
         $title = $xPath->evaluate("Title", $node)->item(0)->nodeValue;
         $srs = $xPath->evaluate("SRS", $node)->item(0)->nodeValue;
         $metaData = array("icon" => "wms_images/mimes/ICON_SIZE/domtreeviewer.png", "parentname" => "/", "name" => $name, "title" => $title, "ajxp_mime" => "wms_layer", "srs" => $srs, "wms_url" => $this->repository->getOption("HOST"));
         $style = $xPath->query("Style/Name", $node)->item(0)->nodeValue;
         $metaData["style"] = $style;
         $keys = array();
         $keywordList = $xPath->query("KeywordList/Keyword", $node);
         if ($keywordList->length) {
             foreach ($keywordList as $keyword) {
                 $keys[] = $keyword->nodeValue;
             }
         }
         $metaData["keywords"] = implode(",", $keys);
         $metaData["queryable"] = $node->attributes->item(0)->value == "1" ? "True" : "False";
         $bBoxAttributes = array();
         try {
             $bBoxAttributes = $xPath->query("LatLonBoundingBox", $node)->item(0)->attributes;
             $attributes = $xPath->query("BoundingBox", $node)->item(0)->attributes;
             if (isset($attributes)) {
                 $bBoxAttributes = $attributes;
             }
         } catch (Exception $e) {
         }
         foreach ($bBoxAttributes as $domAttr) {
             $metaData["bbox_" . $domAttr->name] = $domAttr->value;
         }
         if ($replaceCallback != null) {
             $metaData = call_user_func($replaceCallback, $key, $metaData);
         }
         AJXP_XMLWriter::renderNode("/" . $metaData["name"], $title, true, $metaData);
     }
 }
 public function listHooks($dir, $root = NULL, $hash = null, $returnNodes = false)
 {
     $jsonContent = json_decode(file_get_contents(AJXP_Utils::getHooksFile()), true);
     $config = '<columns switchDisplayMode="full" template_name="hooks.list">
             <column messageId="ajxp_conf.17" attributeName="ajxp_label" sortType="String" defaultWidth="20%"/>
             <column messageId="ajxp_conf.18" attributeName="description" sortType="String" defaultWidth="20%"/>
             <column messageId="ajxp_conf.19" attributeName="triggers" sortType="String" defaultWidth="25%"/>
             <column messageId="ajxp_conf.20" attributeName="listeners" sortType="String" defaultWidth="25%"/>
             <column messageId="ajxp_conf.21" attributeName="sample" sortType="String" defaultWidth="10%"/>
         </columns>';
     if (!$returnNodes) {
         AJXP_XMLWriter::sendFilesListComponentConfig($config);
     }
     $allNodes = array();
     foreach ($jsonContent as $hookName => $hookData) {
         $metadata = array("icon" => "preferences_plugin.png", "description" => $hookData["DESCRIPTION"], "sample" => $hookData["PARAMETER_SAMPLE"]);
         $trigs = array();
         foreach ($hookData["TRIGGERS"] as $trigger) {
             $trigs[] = "<span>" . $trigger["FILE"] . " (" . $trigger["LINE"] . ")</span>";
         }
         $metadata["triggers"] = implode("<br/>", $trigs);
         $listeners = array();
         foreach ($hookData["LISTENERS"] as $listener) {
             $listeners[] = "<span>Plugin " . $listener["PLUGIN_ID"] . ", in method " . $listener["METHOD"] . "</span>";
         }
         $metadata["listeners"] = implode("<br/>", $listeners);
         $nodeKey = "/{$root}/hooks/{$hookName}/{$hookName}";
         if (in_array($nodeKey, $this->currentBookmarks)) {
             $metadata = array_merge($metadata, array("ajxp_bookmarked" => "true", "overlay_icon" => "bookmark.png"));
         }
         $xml = AJXP_XMLWriter::renderNode($nodeKey, $hookName, true, $metadata, true, false);
         if ($returnNodes) {
             $allNodes[$nodeKey] = $xml;
         } else {
             print $xml;
         }
     }
     return $allNodes;
 }
 function switchAction($action, $httpVars, $fileVars)
 {
     if (!isset($this->actions[$action])) {
         return;
     }
     parent::accessPreprocess($action, $httpVars, $fileVars);
     $selection = new UserSelection();
     $dir = $httpVars["dir"] or "";
     $dir = AJXP_Utils::securePath($dir);
     if ($action != "upload") {
         $dir = SystemTextEncoding::fromPostedFileName($dir);
     }
     $selection->initFromHttpVars($httpVars);
     $mess = ConfService::getMessages();
     $newArgs = RecycleBinManager::filterActions($action, $selection, $dir);
     if (isset($newArgs["action"])) {
         $action = $newArgs["action"];
     }
     if (isset($newArgs["dest"])) {
         $httpVars["dest"] = SystemTextEncoding::toUTF8($newArgs["dest"]);
     }
     //Re-encode!
     // FILTER DIR PAGINATION ANCHOR
     $page = null;
     if (isset($dir) && strstr($dir, "#") !== false) {
         $parts = explode("#", $dir);
         $dir = $parts[0];
         $page = $parts[1];
     }
     $pendingSelection = "";
     $logMessage = null;
     $reloadContextNode = false;
     switch ($action) {
         //------------------------------------
         //	DOWNLOAD
         //------------------------------------
         case "download":
             AJXP_Logger::logAction("Download", array("files" => $selection));
             @set_error_handler(array("HTMLWriter", "javascriptErrorHandler"), E_ALL & ~E_NOTICE);
             @register_shutdown_function("restore_error_handler");
             $zip = false;
             if ($selection->isUnique()) {
                 if (is_dir($this->urlBase . $selection->getUniqueFile())) {
                     $zip = true;
                     $base = basename($selection->getUniqueFile());
                     $dir .= "/" . dirname($selection->getUniqueFile());
                 }
             } else {
                 $zip = true;
             }
             if ($zip) {
                 // Make a temp zip and send it as download
                 $loggedUser = AuthService::getLoggedUser();
                 $file = USERS_DIR . "/" . ($loggedUser ? $loggedUser->getId() : "shared") . "/" . time() . "tmpDownload.zip";
                 $zipFile = $this->makeZip($selection->getFiles(), $file, $dir);
                 if (!$zipFile) {
                     throw new AJXP_Exception("Error while compressing");
                 }
                 register_shutdown_function("unlink", $file);
                 $localName = ($base == "" ? "Files" : $base) . ".zip";
                 $this->readFile($file, "force-download", $localName, false, false, true);
             } else {
                 $this->readFile($this->urlBase . $selection->getUniqueFile(), "force-download");
             }
             exit(0);
             break;
         case "compress":
             // Make a temp zip and send it as download
             $loggedUser = AuthService::getLoggedUser();
             if (isset($httpVars["archive_name"])) {
                 $localName = AJXP_Utils::decodeSecureMagic($httpVars["archive_name"]);
             } else {
                 $localName = (basename($dir) == "" ? "Files" : basename($dir)) . ".zip";
             }
             $file = USERS_DIR . "/" . ($loggedUser ? $loggedUser->getId() : "shared") . "/" . time() . "tmpCompression.zip";
             $zipFile = $this->makeZip($selection->getFiles(), $file, $dir);
             if (!$zipFile) {
                 throw new AJXP_Exception("Error while compressing file {$localName}");
             }
             register_shutdown_function("unlink", $file);
             copy($file, $this->urlBase . $dir . "/" . str_replace(".zip", ".tmp", $localName));
             @rename($this->urlBase . $dir . "/" . str_replace(".zip", ".tmp", $localName), $this->urlBase . $dir . "/" . $localName);
             $reloadContextNode = true;
             $pendingSelection = $localName;
             break;
         case "stat":
             clearstatcache();
             $stat = @stat($this->urlBase . AJXP_Utils::decodeSecureMagic($httpVars["file"]));
             header("Content-type:application/json");
             if (!$stat) {
                 print '{}';
             } else {
                 print json_encode($stat);
             }
             exit(1);
             break;
             //------------------------------------
             //	ONLINE EDIT
             //------------------------------------
         //------------------------------------
         //	ONLINE EDIT
         //------------------------------------
         case "get_content":
             $this->readFile($this->urlBase . AJXP_Utils::decodeSecureMagic($httpVars["file"]), "plain");
             exit(0);
             break;
         case "put_content":
             if (!isset($httpVars["content"])) {
                 break;
             }
             // Reload "code" variable directly from POST array, do not "securePath"...
             $code = $httpVars["content"];
             $file = AJXP_Utils::decodeSecureMagic($httpVars["file"]);
             AJXP_Logger::logAction("Online Edition", array("file" => $file));
             if (isset($httpVars["encode"]) && $httpVars["encode"] == "base64") {
                 $code = base64_decode($code);
             } else {
                 $code = stripslashes($code);
                 $code = str_replace("&lt;", "<", $code);
             }
             $fileName = $this->urlBase . $file;
             if (!is_file($fileName) || !is_writable($fileName)) {
                 header("Content-Type:text/plain");
                 print !is_writable($fileName) ? "1001" : "1002";
                 exit(1);
             }
             $fp = fopen($fileName, "w");
             fputs($fp, $code);
             fclose($fp);
             header("Content-Type:text/plain");
             print $mess[115];
             exit(0);
             break;
             //------------------------------------
             //	COPY / MOVE
             //------------------------------------
         //------------------------------------
         //	COPY / MOVE
         //------------------------------------
         case "copy":
         case "move":
             if ($selection->isEmpty()) {
                 throw new AJXP_Exception("", 113);
             }
             $success = $error = array();
             $dest = AJXP_Utils::decodeSecureMagic($httpVars["dest"]);
             if ($selection->inZip()) {
                 // Set action to copy anycase (cannot move from the zip).
                 $action = "copy";
             }
             $this->copyOrMove($dest, $selection->getFiles(), $error, $success, $action == "move" ? true : false);
             if (count($error)) {
                 throw new AJXP_Exception(join("\n", $error));
             } else {
                 $logMessage = join("\n", $success);
                 AJXP_Logger::logAction($action == "move" ? "Move" : "Copy", array("files" => $selection, "destination" => $dest));
             }
             $reloadContextNode = true;
             $reloadDataNode = $dest;
             break;
             //------------------------------------
             //	SUPPRIMER / DELETE
             //------------------------------------
         //------------------------------------
         //	SUPPRIMER / DELETE
         //------------------------------------
         case "delete":
             if ($selection->isEmpty()) {
                 throw new AJXP_Exception("", 113);
             }
             $logMessages = array();
             $errorMessage = $this->delete($selection->getFiles(), $logMessages);
             if (count($logMessages)) {
                 $logMessage = join("\n", $logMessages);
             }
             if ($errorMessage) {
                 throw new AJXP_Exception($errorMessage);
             }
             AJXP_Logger::logAction("Delete", array("files" => $selection));
             $reloadContextNode = true;
             break;
             //------------------------------------
             //	RENOMMER / RENAME
             //------------------------------------
         //------------------------------------
         //	RENOMMER / RENAME
         //------------------------------------
         case "rename":
             $file = AJXP_Utils::decodeSecureMagic($httpVars["file"]);
             $filename_new = AJXP_Utils::decodeSecureMagic($httpVars["filename_new"]);
             $this->rename($file, $filename_new);
             $logMessage = SystemTextEncoding::toUTF8($file) . " {$mess['41']} " . SystemTextEncoding::toUTF8($filename_new);
             $reloadContextNode = true;
             $pendingSelection = $filename_new;
             AJXP_Logger::logAction("Rename", array("original" => $file, "new" => $filename_new));
             break;
             //------------------------------------
             //	CREER UN REPERTOIRE / CREATE DIR
             //------------------------------------
         //------------------------------------
         //	CREER UN REPERTOIRE / CREATE DIR
         //------------------------------------
         case "mkdir":
             $messtmp = "";
             $dirname = AJXP_Utils::processFileName(SystemTextEncoding::fromUTF8($httpVars["dirname"]));
             $error = $this->mkDir($dir, $dirname);
             if (isset($error)) {
                 throw new AJXP_Exception($error);
             }
             $messtmp .= "{$mess['38']} " . SystemTextEncoding::toUTF8($dirname) . " {$mess['39']} ";
             if ($dir == "") {
                 $messtmp .= "/";
             } else {
                 $messtmp .= SystemTextEncoding::toUTF8($dir);
             }
             $logMessage = $messtmp;
             $pendingSelection = $dirname;
             $reloadContextNode = true;
             AJXP_Logger::logAction("Create Dir", array("dir" => $dir . "/" . $dirname));
             break;
             //------------------------------------
             //	CREER UN FICHIER / CREATE FILE
             //------------------------------------
         //------------------------------------
         //	CREER UN FICHIER / CREATE FILE
         //------------------------------------
         case "mkfile":
             $messtmp = "";
             $filename = AJXP_Utils::processFileName(SystemTextEncoding::fromUTF8($httpVars["filename"]));
             $error = $this->createEmptyFile($dir, $filename);
             if (isset($error)) {
                 throw new AJXP_Exception($error);
             }
             $messtmp .= "{$mess['34']} " . SystemTextEncoding::toUTF8($filename) . " {$mess['39']} ";
             if ($dir == "") {
                 $messtmp .= "/";
             } else {
                 $messtmp .= SystemTextEncoding::toUTF8($dir);
             }
             $logMessage = $messtmp;
             $reloadContextNode = true;
             $pendingSelection = $dir . "/" . $filename;
             AJXP_Logger::logAction("Create File", array("file" => $dir . "/" . $filename));
             break;
             //------------------------------------
             //	CHANGE FILE PERMISSION
             //------------------------------------
         //------------------------------------
         //	CHANGE FILE PERMISSION
         //------------------------------------
         case "chmod":
             $messtmp = "";
             $files = $selection->getFiles();
             $changedFiles = array();
             $chmod_value = $httpVars["chmod_value"];
             $recursive = $httpVars["recursive"];
             $recur_apply_to = $httpVars["recur_apply_to"];
             foreach ($files as $fileName) {
                 $error = $this->chmod($fileName, $chmod_value, $recursive == "on", $recursive == "on" ? $recur_apply_to : "both", $changedFiles);
             }
             if (isset($error)) {
                 throw new AJXP_Exception($error);
             }
             //$messtmp.="$mess[34] ".SystemTextEncoding::toUTF8($filename)." $mess[39] ";
             $logMessage = "Successfully changed permission to " . $chmod_value . " for " . count($changedFiles) . " files or folders";
             $reloadContextNode = true;
             AJXP_Logger::logAction("Chmod", array("dir" => $dir, "filesCount" => count($changedFiles)));
             break;
             //------------------------------------
             //	UPLOAD
             //------------------------------------
         //------------------------------------
         //	UPLOAD
         //------------------------------------
         case "upload":
             AJXP_Logger::debug("Upload Files Data", $fileVars);
             $destination = $this->urlBase . SystemTextEncoding::fromPostedFileName($dir);
             AJXP_Logger::debug("Upload inside", array("destination" => $destination));
             if (!$this->isWriteable($destination)) {
                 $errorCode = 412;
                 $errorMessage = "{$mess['38']} " . SystemTextEncoding::toUTF8($dir) . " {$mess['99']}.";
                 AJXP_Logger::debug("Upload error 412", array("destination" => $destination));
                 return array("ERROR" => array("CODE" => $errorCode, "MESSAGE" => $errorMessage));
             }
             foreach ($fileVars as $boxName => $boxData) {
                 if (substr($boxName, 0, 9) != "userfile_") {
                     continue;
                 }
                 $err = AJXP_Utils::parseFileDataErrors($boxData);
                 if ($err != null) {
                     $errorCode = $err[0];
                     $errorMessage = $err[1];
                     break;
                 }
                 $userfile_name = $boxData["name"];
                 $userfile_name = AJXP_Utils::processFileName($userfile_name);
                 if (isset($httpVars["auto_rename"])) {
                     $userfile_name = self::autoRenameForDest($destination, $userfile_name);
                 }
                 if (isset($boxData["input_upload"])) {
                     try {
                         AJXP_Logger::debug("Begining reading INPUT stream");
                         $input = fopen("php://input", "r");
                         $output = fopen("{$destination}/" . $userfile_name, "w");
                         $sizeRead = 0;
                         while ($sizeRead < intval($boxData["size"])) {
                             $chunk = fread($input, 4096);
                             $sizeRead += strlen($chunk);
                             fwrite($output, $chunk, strlen($chunk));
                         }
                         fclose($input);
                         fclose($output);
                         AJXP_Logger::debug("End reading INPUT stream");
                     } catch (Exception $e) {
                         $errorCode = 411;
                         $errorMessage = $e->getMessage();
                         break;
                     }
                 } else {
                     if (!move_uploaded_file($boxData["tmp_name"], "{$destination}/" . $userfile_name)) {
                         $errorCode = 411;
                         $errorMessage = "{$mess['33']} " . $userfile_name;
                         break;
                     }
                 }
                 $this->changeMode($destination . "/" . $userfile_name);
                 $logMessage .= "{$mess['34']} " . SystemTextEncoding::toUTF8($userfile_name) . " {$mess['35']} {$dir}";
                 AJXP_Logger::logAction("Upload File", array("file" => SystemTextEncoding::fromUTF8($dir) . "/" . $userfile_name));
             }
             if (isset($errorMessage)) {
                 AJXP_Logger::debug("Return error {$errorCode} {$errorMessage}");
                 return array("ERROR" => array("CODE" => $errorCode, "MESSAGE" => $errorMessage));
             } else {
                 AJXP_Logger::debug("Return success");
                 return array("SUCCESS" => true);
             }
             return;
             break;
             //------------------------------------
             // Public URL
             //------------------------------------
         //------------------------------------
         // Public URL
         //------------------------------------
         case "public_url":
             $file = AJXP_Utils::decodeSecureMagic($httpVars["file"]);
             $url = $this->makePubliclet($file, $httpVars["password"], $httpVars["expiration"]);
             header("Content-type:text/plain");
             echo $url;
             exit(1);
             break;
             //------------------------------------
             //	XML LISTING
             //------------------------------------
         //------------------------------------
         //	XML LISTING
         //------------------------------------
         case "ls":
             if (!isset($dir) || $dir == "/") {
                 $dir = "";
             }
             $lsOptions = $this->parseLsOptions(isset($httpVars["options"]) ? $httpVars["options"] : "a");
             $startTime = microtime();
             $dir = AJXP_Utils::securePath(SystemTextEncoding::magicDequote($dir));
             $path = $this->urlBase . ($dir != "" ? "/" . $dir : "");
             $threshold = $this->repository->getOption("PAGINATION_THRESHOLD");
             if (!isset($threshold) || intval($threshold) == 0) {
                 $threshold = 500;
             }
             $limitPerPage = $this->repository->getOption("PAGINATION_NUMBER");
             if (!isset($limitPerPage) || intval($limitPerPage) == 0) {
                 $limitPerPage = 200;
             }
             $countFiles = $this->countFiles($path, !$lsOptions["f"]);
             if ($countFiles > $threshold) {
                 $offset = 0;
                 $crtPage = 1;
                 if (isset($page)) {
                     $offset = (intval($page) - 1) * $limitPerPage;
                     $crtPage = $page;
                 }
                 $totalPages = floor($countFiles / $limitPerPage) + 1;
             } else {
                 $offset = $limitPerPage = 0;
             }
             $metaData = array();
             $crtLabel = AJXP_Utils::xmlEntities(basename($dir), true);
             if (RecycleBinManager::recycleEnabled()) {
                 if (RecycleBinManager::currentLocationIsRecycle($dir)) {
                     $metaData["ajxp_mime"] = "ajxp_recycle";
                     $crtLabel = AJXP_Utils::xmlEntities($mess[122]);
                 } else {
                     if ($dir == "") {
                         $metaData["repo_has_recycle"] = "true";
                     }
                 }
             }
             AJXP_XMLWriter::renderHeaderNode(AJXP_Utils::xmlEntities($dir, true), $crtLabel, false, $metaData);
             if (isset($totalPages) && isset($crtPage)) {
                 AJXP_XMLWriter::renderPaginationData($countFiles, $crtPage, $totalPages);
                 if (!$lsOptions["f"]) {
                     AJXP_XMLWriter::close();
                     exit(1);
                 }
             }
             $cursor = 0;
             $handle = opendir($path);
             if (!$handle) {
                 throw new AJXP_Exception("Cannot open dir " . $path);
             }
             $fullList = array("d" => array(), "z" => array(), "f" => array());
             while (strlen($nodeName = readdir($handle)) > 0) {
                 if ($nodeName == "." || $nodeName == "..") {
                     continue;
                 }
                 $isLeaf = is_file($path . "/" . $nodeName) || AJXP_Utils::isBrowsableArchive($nodeName);
                 if (!$this->filterNodeName($path, $nodeName, $isLeaf, $lsOptions)) {
                     continue;
                 }
                 if (RecycleBinManager::recycleEnabled() && $dir == "" && "/" . $nodeName == RecycleBinManager::getRecyclePath()) {
                     continue;
                 }
                 $nodeType = "d";
                 if ($isLeaf) {
                     if (AJXP_Utils::isBrowsableArchive($nodeName)) {
                         if ($lsOptions["f"] && $lsOptions["z"]) {
                             // See archives as files
                             $nodeType = "f";
                         } else {
                             $nodeType = "z";
                         }
                     } else {
                         $nodeType = "f";
                     }
                 }
                 if ($offset > 0 && $cursor < $offset) {
                     $cursor++;
                     continue;
                 }
                 if ($limitPerPage > 0 && $cursor - $offset >= $limitPerPage) {
                     break;
                 }
                 $metaData = array();
                 $currentFile = $path . "/" . $nodeName;
                 $metaData["is_file"] = $isLeaf ? "1" : "0";
                 $metaData["filename"] = AJXP_Utils::xmlEntities(SystemTextEncoding::toUTF8($dir . "/" . $nodeName));
                 $metaData["icon"] = AJXP_Utils::mimetype($nodeName, "image", !$isLeaf);
                 if ($metaData["icon"] == "folder.png") {
                     $metaData["openicon"] = "folder_open.png";
                 }
                 if (!is_file($currentFile) || AJXP_Utils::isBrowsableArchive($nodeName)) {
                     $link = SystemTextEncoding::toUTF8(SERVER_ACCESS . "?get_action=ls&options=dz&dir=" . $dir . "/" . $nodeName);
                     $link = urlencode($link);
                     $metaData["src"] = $link;
                 }
                 if ($lsOptions["l"]) {
                     $metaData["file_group"] = @filegroup($currentFile) || "unknown";
                     $metaData["file_owner"] = @fileowner($currentFile) || "unknown";
                     $fPerms = @fileperms($currentFile);
                     if ($fPerms !== false) {
                         $fPerms = substr(decoct($fPerms), $isLeaf ? 2 : 1);
                     } else {
                         $fPerms = '0000';
                     }
                     $metaData["file_perms"] = $fPerms;
                     $metaData["mimestring"] = AJXP_Utils::mimetype($currentFile, "type", !$isLeaf);
                     $datemodif = $this->date_modif($currentFile);
                     $metaData["ajxp_modiftime"] = $datemodif ? $datemodif : "0";
                     $metaData["bytesize"] = 0;
                     if ($isLeaf) {
                         $metaData["bytesize"] = filesize($currentFile);
                     }
                     $metaData["filesize"] = AJXP_Utils::roundSize($metaData["bytesize"]);
                     if (AJXP_Utils::isBrowsableArchive($nodeName)) {
                         $metaData["ajxp_mime"] = "ajxp_browsable_archive";
                     }
                     $realFile = null;
                     // A reference to the real file.
                     AJXP_Controller::applyHook("ls.metadata", array($currentFile, &$metaData, $this->wrapperClassName, &$realFile));
                 }
                 $attributes = "";
                 foreach ($metaData as $key => $value) {
                     $attributes .= "{$key}=\"{$value}\" ";
                 }
                 $renderNodeData = array(AJXP_Utils::xmlEntities($dir . "/" . $nodeName, true), AJXP_Utils::xmlEntities($nodeName, true), $isLeaf, $metaData);
                 $fullList[$nodeType][$nodeName] = $renderNodeData;
                 $cursor++;
             }
             foreach ($fullList as $key => $list) {
                 uksort($list, 'strnatcasecmp');
                 $fullList[$key] = $list;
             }
             $allNodes = array_merge($fullList["d"], $fullList["z"], $fullList["f"]);
             array_map(array("AJXP_XMLWriter", "renderNodeArray"), $fullList["d"]);
             array_map(array("AJXP_XMLWriter", "renderNodeArray"), $fullList["z"]);
             array_map(array("AJXP_XMLWriter", "renderNodeArray"), $fullList["f"]);
             // ADD RECYCLE BIN TO THE LIST
             if ($dir == "" && RecycleBinManager::recycleEnabled()) {
                 $recycleBinOption = RecycleBinManager::getRelativeRecycle();
                 if (file_exists($this->urlBase . $recycleBinOption)) {
                     $recycleIcon = $this->countFiles($this->urlBase . $recycleBinOption, false, true) > 0 ? "trashcan_full.png" : "trashcan.png";
                     AJXP_XMLWriter::renderNode($recycleBinOption, AJXP_Utils::xmlEntities($mess[122]), false, array("ajxp_modiftime" => $this->date_modif($this->urlBase . $recycleBinOption), "mimestring" => AJXP_Utils::xmlEntities($mess[122]), "icon" => "{$recycleIcon}", "filesize" => "-", "ajxp_mime" => "ajxp_recycle"));
                 }
             }
             AJXP_Logger::debug("LS Time : " . intval((microtime() - $startTime) * 1000) . "ms");
             AJXP_XMLWriter::close();
             return;
             break;
     }
     $xmlBuffer = "";
     if (isset($logMessage) || isset($errorMessage)) {
         $xmlBuffer .= AJXP_XMLWriter::sendMessage(isset($logMessage) ? $logMessage : null, isset($errorMessage) ? $errorMessage : null, false);
     }
     if ($reloadContextNode) {
         if (!isset($pendingSelection)) {
             $pendingSelection = "";
         }
         $xmlBuffer .= AJXP_XMLWriter::reloadDataNode("", $pendingSelection, false);
     }
     if (isset($reloadDataNode)) {
         $xmlBuffer .= AJXP_XMLWriter::reloadDataNode($reloadDataNode, "", false);
     }
     return $xmlBuffer;
 }
    function listSharedFiles()
    {
        AJXP_XMLWriter::sendFilesListComponentConfig('<columns switchGridMode="filelist" template_name="ajxp_conf.shared">
				<column messageId="ajxp_shared.4" attributeName="ajxp_label" sortType="String" defaultWidth="30%"/>
				<column messageId="ajxp_shared.27" attributeName="owner" sortType="String" defaultWidth="10%"/>
				<column messageId="ajxp_shared.17" attributeName="download_url" sortType="String" defaultWidth="40%"/>
				<column messageId="ajxp_shared.6" attributeName="password" sortType="String" defaultWidth="4%"/>
				<column messageId="ajxp_shared.7" attributeName="expiration" sortType="String" defaultWidth="4%"/>
				<column messageId="ajxp_shared.20" attributeName="expired" sortType="String" defaultWidth="4%"/>
				<column messageId="ajxp_shared.14" attributeName="integrity" sortType="String" defaultWidth="4%" hidden="true"/>
			</columns>');
        $dlFolder = ConfService::getCoreConf("PUBLIC_DOWNLOAD_FOLDER");
        if (!is_dir($dlFolder)) {
            return;
        }
        $files = glob($dlFolder . "/*.php");
        if ($files === false) {
            return;
        }
        $mess = ConfService::getMessages();
        $loggedUser = AuthService::getLoggedUser();
        $userId = $loggedUser->getId();
        $dlURL = ConfService::getCoreConf("PUBLIC_DOWNLOAD_URL");
        if ($dlURL != "") {
            $downloadBase = rtrim($dlURL, "/");
        } else {
            $fullUrl = AJXP_Utils::detectServerURL() . dirname($_SERVER['REQUEST_URI']);
            $downloadBase = str_replace("\\", "/", $fullUrl . rtrim(str_replace(AJXP_INSTALL_PATH, "", $dlFolder), "/"));
        }
        foreach ($files as $file) {
            $publicletData = $this->loadPublicletData($file);
            AJXP_XMLWriter::renderNode(str_replace(".php", "", basename($file)), "" . SystemTextEncoding::toUTF8($publicletData["REPOSITORY"]->getDisplay()) . ":/" . SystemTextEncoding::toUTF8($publicletData["FILE_PATH"]), true, array("icon" => "html.png", "password" => $publicletData["PASSWORD"] != "" ? $publicletData["PASSWORD"] : "******", "expiration" => $publicletData["EXPIRE_TIME"] != 0 ? date($mess["date_format"], $publicletData["EXPIRE_TIME"]) : "-", "expired" => $publicletData["EXPIRE_TIME"] != 0 ? $publicletData["EXPIRE_TIME"] < time() ? $mess["ajxp_shared.21"] : $mess["ajxp_shared.22"] : "-", "integrity" => !$publicletData["SECURITY_MODIFIED"] ? $mess["ajxp_shared.15"] : $mess["ajxp_shared.16"], "download_url" => $downloadBase . "/" . basename($file), "owner" => isset($publicletData["OWNER_ID"]) ? $publicletData["OWNER_ID"] : "-", "ajxp_mime" => "shared_file"));
        }
    }
 public function listRepositories()
 {
     AJXP_XMLWriter::sendFilesListComponentConfig('<columns switchGridMode="filelist"><column messageId="ajxp_conf.8" attributeName="ajxp_label" sortType="String"/><column messageId="user_dash.9" attributeName="parent_label" sortType="String"/><column messageId="user_dash.9" attributeName="repo_accesses" sortType="String"/></columns>');
     $repoArray = array();
     $loggedUser = AuthService::getLoggedUser();
     $count = 0;
     $repos = ConfService::listRepositoriesWithCriteria(array("owner_user_id" => $loggedUser->getId()), $count);
     $searchAll = ConfService::getCoreConf("CROSSUSERS_ALLGROUPS", "conf");
     $displayAll = ConfService::getCoreConf("CROSSUSERS_ALLGROUPS_DISPLAY", "conf");
     if ($searchAll || $displayAll) {
         $baseGroup = "/";
     } else {
         $baseGroup = AuthService::filterBaseGroup("/");
     }
     AuthService::setGroupFiltering(false);
     $users = AuthService::listUsers($baseGroup);
     $minisites = $this->listSharedFiles("minisites");
     foreach ($repos as $repoIndex => $repoObject) {
         if ($repoObject->getAccessType() == "ajxp_conf") {
             continue;
         }
         if (!$repoObject->hasOwner() || $repoObject->getOwner() != $loggedUser->getId()) {
             continue;
         }
         if (is_numeric($repoIndex)) {
             $repoIndex = "" . $repoIndex;
         }
         $name = (isset($minisites[$repoIndex]) ? "[Minisite] " : "") . AJXP_Utils::xmlEntities(SystemTextEncoding::toUTF8($repoObject->getDisplay()));
         $repoArray[$name] = $repoIndex;
     }
     // Sort the list now by name
     ksort($repoArray);
     foreach ($repoArray as $name => $repoIndex) {
         $repoObject =& $repos[$repoIndex];
         $repoAccesses = array();
         foreach ($users as $userId => $userObject) {
             if ($userObject->getId() == $loggedUser->getId()) {
                 continue;
             }
             $label = $userObject->personalRole->filterParameterValue("core.conf", "USER_DISPLAY_NAME", AJXP_REPO_SCOPE_ALL, $userId);
             if (empty($label)) {
                 $label = $userId;
             }
             $acl = $userObject->mergedRole->getAcl($repoObject->getId());
             if (!empty($acl)) {
                 $repoAccesses[] = $label . " (" . $acl . ")";
             }
         }
         $parent = $repoObject->getParentId();
         $parentRepo =& $repos[$parent];
         $parentLabel = $this->metaIcon("folder-open") . $parentRepo->getDisplay();
         $repoPath = $repoObject->getOption("PATH");
         $parentPath = $parentRepo->getOption("PATH");
         $parentLabel .= " (" . str_replace($parentPath, "", $repoPath) . ")";
         $metaData = array("repository_id" => $repoIndex, "icon" => "document_open_remote.png", "openicon" => "document_open_remote.png", "parentname" => "/repositories", "parent_label" => $parentLabel, "repo_accesses" => count($repoAccesses) ? $this->metaIcon("share-sign") . implode(", ", $repoAccesses) : "", "ajxp_mime" => "shared_repository");
         AJXP_XMLWriter::renderNode("/repositories/{$repoIndex}", $name, true, $metaData);
     }
 }
예제 #11
0
 /**
  * List available log files in XML
  *
  * @param String [optional] $nodeName
  * @param String [optional] $year
  * @param String [optional] $month
  */
 public function xmlListLogFiles($nodeName = "file", $year = null, $month = null, $rootPath = "/logs", $print = true)
 {
     $xml_strings = array();
     switch ($this->sqlDriver["driver"]) {
         case "sqlite":
         case "sqlite3":
             $yFunc = "strftime('%Y', [logdate])";
             $mFunc = "strftime('%m', [logdate])";
             $dFunc = "date([logdate])";
             break;
         case "mysql":
             $yFunc = "YEAR([logdate])";
             $mFunc = "MONTH([logdate])";
             $dFunc = "DATE([logdate])";
             break;
         case "postgre":
             $yFunc = "EXTRACT(YEAR FROM [logdate])";
             $mFunc = "EXTRACT(MONTH FROM [logdate])";
             $dFunc = "DATE([logdate])";
             break;
         default:
             echo "ERROR!, DB driver " + $this->sqlDriver["driver"] + " not supported yet in __FUNCTION__";
             exit(1);
     }
     try {
         if ($month != null) {
             // Get days
             //cal_days_in_month(CAL_GREGORIAN, $month, $year)
             $start_time = mktime(0, 0, 0, $month, 1, $year);
             $end_time = mktime(0, 0, 0, $month + 1, 1, $year);
             $q = 'SELECT
                 DISTINCT ' . $dFunc . ' AS logdate
                 FROM [ajxp_log]
                 WHERE [logdate] >= %t AND [logdate] < %t';
             $result = dibi::query($q, $start_time, $end_time);
             foreach ($result as $r) {
                 $log_time = strtotime($r['logdate']);
                 $fullYear = date('Y', $log_time);
                 $fullMonth = date('F', $log_time);
                 $logM = date('m', $log_time);
                 $date = $r['logdate'];
                 if (is_a($date, "DibiDateTime")) {
                     $date = $date->format("Y-m-d");
                 }
                 $path = "{$rootPath}/{$fullYear}/{$logM}/{$date}";
                 $metadata = array("icon" => "toggle_log.png", "date" => $date, "ajxp_mime" => "datagrid", "grid_datasource" => "get_action=ls&dir=" . urlencode($path), "grid_header_title" => "Application Logs for {$date}", "grid_actions" => "refresh,copy_as_text");
                 $xml_strings[$date] = AJXP_XMLWriter::renderNode($path, $date, true, $metadata, true, false);
             }
         } else {
             if ($year != null) {
                 // Get months
                 $year_start_time = mktime(0, 0, 0, 1, 1, $year);
                 $year_end_time = mktime(0, 0, 0, 1, 1, $year + 1);
                 $q = 'SELECT
                 DISTINCT ' . $yFunc . ' AS year,
                 ' . $mFunc . ' AS month
                 FROM [ajxp_log]
                 WHERE [logdate] >= %t AND [logdate] < %t';
                 $result = dibi::query($q, $year_start_time, $year_end_time);
                 foreach ($result as $r) {
                     /* We always recreate a unix timestamp while looping because it provides us with a uniform way to format the date.
                      * The month returned by the database will not be zero-padded and causes problems down the track when DateTime zero pads things */
                     $month_time = mktime(0, 0, 0, $r['month'], 1, $r['year']);
                     $fullYear = date('Y', $month_time);
                     $fullMonth = date('F', $month_time);
                     $logMDisplay = date('F', $month_time);
                     $logM = date('m', $month_time);
                     $xml_strings[$r['month']] = $this->formatXmlLogList($nodeName, 'x-office-calendar.png', $logM, $logMDisplay, $logMDisplay, "{$rootPath}/{$fullYear}/{$logM}");
                     //"<$nodeName icon=\"x-office-calendar.png\" date=\"$fullMonth\" display=\"$logM\" text=\"$fullMonth\" is_file=\"0\" filename=\"/logs/$fullYear/$fullMonth\"/>";
                 }
             } else {
                 // Append Analytics Node
                 $xml_strings['0000'] = AJXP_XMLWriter::renderNode($rootPath . "/all_analytics", "Analytics Dashboard", true, array("icon" => "graphs_viewer/ICON_SIZE/analytics.png", "ajxp_mime" => "ajxp_graphs"), true, false);
                 // Get years
                 $q = 'SELECT
                 DISTINCT ' . $yFunc . ' AS year
                 FROM [ajxp_log]';
                 $result = dibi::query($q);
                 foreach ($result as $r) {
                     $year_time = mktime(0, 0, 0, 1, 1, $r['year']);
                     $fullYear = $r['year'];
                     $xml_strings[$r['year']] = $this->formatXmlLogList($nodeName, 'x-office-calendar.png', $fullYear, $fullYear, $fullYear, "{$rootPath}/{$fullYear}");
                     //"<$nodeName icon=\"x-office-calendar.png\" date=\"$fullYear\" display=\"$fullYear\" text=\"$fullYear\" is_file=\"0\" filename=\"/logs/$fullYear\"/>";
                 }
             }
         }
     } catch (DibiException $e) {
         echo get_class($e), ': ', $e->getMessage(), "\n";
         exit(1);
     }
     if ($print) {
         foreach ($xml_strings as $s) {
             print $s;
         }
     }
     return $xml_strings;
 }
 function listRepositories()
 {
     $repos = ConfService::getRepositoriesList();
     AJXP_XMLWriter::sendFilesListComponentConfig('<columns switchGridMode="filelist"><column messageId="ajxp_conf.8" attributeName="ajxp_label" sortType="String"/><column messageId="ajxp_conf.9" attributeName="accessType" sortType="String"/></columns>');
     $repoArray = array();
     foreach ($repos as $repoIndex => $repoObject) {
         if ($repoObject->getAccessType() == "ajxp_conf") {
             continue;
         }
         $name = AJXP_Utils::xmlEntities(SystemTextEncoding::toUTF8($repoObject->getDisplay()));
         $repoArray[$name] = $repoIndex;
     }
     // Sort the list now by name
     ksort($repoArray);
     foreach ($repoArray as $name => $repoIndex) {
         $repoObject =& $repos[$repoIndex];
         $metaData = array("repository_id" => $repoIndex, "accessType" => $repoObject->getAccessType(), "icon" => "folder_red.png", "openicon" => "folder_red.png", "parentname" => "/repositories", "ajxp_mime" => "repository" . ($repoObject->isWriteable() ? "_editable" : ""));
         AJXP_XMLWriter::renderNode("/repositories/{$repoIndex}", $name, true, $metaData);
     }
 }
 /**
  * @static
  * @param AJXP_Node $ajxpNode
  * @param bool $close
  * @return void
  */
 static function renderAjxpNode($ajxpNode, $close = true)
 {
     AJXP_XMLWriter::renderNode($ajxpNode->getPath(), $ajxpNode->getLabel(), $ajxpNode->isLeaf(), $ajxpNode->metadata, $close);
 }