/**
  * Enter description here...
  *
  */
 public function stream_close()
 {
     if ($this->fp !== null) {
         fclose($this->fp);
         if (self::$linkNode !== null) {
             ConfService::loadDriverForRepository(self::$linkNode->getRepository());
         }
     }
 }
 /**
  * @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 $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());
     }
 }
 /**
  * @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 $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());
     }
 }
 /**
  * Hook node.change
  * @param AJXP_Node $oldNode
  * @param AJXP_Node $newNode
  * @param bool $copy
  */
 public function updateNodeSharedData($oldNode = null, $newNode = null, $copy = false)
 {
     if ($oldNode == null || $copy) {
         // Create or copy, do nothing
         return;
     }
     if ($oldNode != null && $newNode != null && $oldNode->getUrl() == $newNode->getUrl()) {
         // Same path => must be a content update, do nothing
         return;
     }
     $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;
         }
     }
     $shareStore = $this->getShareStore();
     $modifiedNodes = $shareStore->moveSharesFromMetaRecursive($oldNode, $delete, $oldNode->getPath(), $newNode != null ? $newNode->getPath() : null);
     // Force switching back to correct driver!
     if ($modifiedNodes > 0) {
         $oldNode->getRepository()->driverInstance = null;
         $oldNode->setDriver(null);
         $oldNode->getDriver();
     }
     return;
 }
 public static function getNodes($checkStats = false, $touch = true)
 {
     if (isset(self::$output)) {
         return self::$output;
     }
     $mess = ConfService::getMessages();
     $repos = ConfService::getAccessibleRepositories();
     $output = array();
     $touchReposIds = array();
     foreach ($repos as $repo) {
         if (!$repo->hasOwner() || !$repo->hasContentFilter()) {
             continue;
         }
         $repoId = $repo->getId();
         if (strpos("ocs_remote_share_", $repoId) !== 0) {
             $touchReposIds[] = $repoId;
         }
         $url = "pydio://" . $repoId . "/";
         $meta = array("shared_repository_id" => $repoId, "ajxp_description" => "File shared by " . $repo->getOwner() . " " . AJXP_Utils::relativeDate($repo->getOption("CREATION_TIME"), $mess), "share_meta_type" => 1);
         $cFilter = $repo->getContentFilter();
         $filter = $cFilter instanceof ContentFilter ? array_keys($cFilter->filters)[0] : $cFilter;
         if (!is_array($filter)) {
             $label = basename($filter);
         } else {
             $label = $repo->getDisplay();
         }
         if (strpos($repoId, "ocs_remote_share") !== 0) {
             // FOR REMOTE SHARES, DO NOT APPEND THE DOCUMENTNAME, WE STAT THE ROOT DIRECTLY
             $url .= $label;
         }
         $status = null;
         $remoteShare = null;
         $name = pathinfo($label, PATHINFO_FILENAME);
         $ext = pathinfo($label, PATHINFO_EXTENSION);
         $node = new AJXP_Node($url);
         $node->setLabel($label);
         if ($checkStats) {
             $node->getRepository()->driverInstance = null;
             try {
                 ConfService::loadDriverForRepository($node->getRepository());
             } catch (Exception $e) {
                 $ext = "error";
                 $meta["ajxp_mime"] = "error";
             }
             $node->getRepository()->detectStreamWrapper(true);
             $stat = @stat($url);
             if ($stat === false) {
                 $ext = "error";
                 $meta["ajxp_mime"] = "error";
                 $meta["share_meta_type"] = 2;
             } else {
                 if (strpos($repoId, "ocs_remote_share_") === 0) {
                     // Check Status
                     $linkId = str_replace("ocs_remote_share_", "", $repoId);
                     $ocsStore = new \Pydio\OCS\Model\SQLStore();
                     $remoteShare = $ocsStore->remoteShareById($linkId);
                     $status = $remoteShare->getStatus();
                     if ($status == OCS_INVITATION_STATUS_PENDING) {
                         $stat = stat(AJXP_Utils::getAjxpTmpDir());
                         $ext = "invitation";
                         $meta["ajxp_mime"] = "invitation";
                         $meta["share_meta_type"] = 0;
                     } else {
                         $meta["remote_share_accepted"] = "true";
                     }
                     $meta["remote_share_id"] = $remoteShare->getId();
                 }
             }
             if ($ext == "invitation") {
                 $label .= " (" . $mess["inbox_driver.4"] . ")";
             } else {
                 if ($ext == "error") {
                     $label .= " (" . $mess["inbox_driver.5"] . ")";
                 }
             }
             if (is_array($stat) && AuthService::getLoggedUser() != null) {
                 $acl = AuthService::getLoggedUser()->mergedRole->getAcl($repoId);
                 if ($acl == "r") {
                     self::disableWriteInStat($stat);
                 }
             }
         }
         $index = 0;
         $suffix = "";
         while (isset($output[$name . $suffix . "." . $ext])) {
             $index++;
             $suffix = " ({$index})";
         }
         $output[$name . $suffix . "." . $ext] = ["label" => $label, "url" => $url, "remote_share" => $remoteShare, "meta" => $meta];
         if (isset($stat)) {
             $output[$name . $suffix . "." . $ext]['stat'] = $stat;
         }
     }
     ConfService::loadDriverForRepository(ConfService::getRepository());
     self::$output = $output;
     if ($touch) {
         if (count($touchReposIds) && AuthService::getLoggedUser() != null) {
             $uPref = AuthService::getLoggedUser()->getPref("repository_last_connected");
             if (empty($uPref)) {
                 $uPref = array();
             }
             foreach ($touchReposIds as $rId) {
                 $uPref[$rId] = time();
             }
             AuthService::getLoggedUser()->setPref("repository_last_connected", $uPref);
         }
     }
     return $output;
 }
 public function loadUserAlerts($actionName, $httpVars, $fileVars)
 {
     if (!$this->eventStore) {
         return;
     }
     $u = AuthService::getLoggedUser();
     $userId = $u->getId();
     $repositoryFilter = null;
     if (isset($httpVars["repository_id"]) && $u->mergedRole->canRead($httpVars["repository_id"])) {
         $repositoryFilter = $httpVars["repository_id"];
     }
     if ($repositoryFilter == null) {
         $repositoryFilter = ConfService::getRepository()->getId();
     }
     $res = $this->eventStore->loadAlerts($userId, $repositoryFilter);
     if (!count($res)) {
         return;
     }
     // Recompute children notifs
     $format = $httpVars["format"];
     $skipContainingTags = isset($httpVars["skip_container_tags"]);
     $mess = ConfService::getMessages();
     if (!$skipContainingTags) {
         if ($format == "html") {
             echo "<h2>" . $mess["notification_center.3"] . "</h2>";
             echo "<ul class='notification_list'>";
         } else {
             AJXP_XMLWriter::header();
         }
     }
     $parentRepository = ConfService::getRepositoryById($repositoryFilter);
     $parentRoot = $parentRepository->getOption("PATH");
     $cumulated = array();
     foreach ($res as $notification) {
         if ($format == "html") {
             echo "<li>";
             echo $notification->getDescriptionLong(true);
             echo "</li>";
         } else {
             $node = $notification->getNode();
             $path = $node->getPath();
             $nodeRepo = $node->getRepository();
             if ($nodeRepo != null && $nodeRepo->hasParent() && $nodeRepo->getParentId() == $repositoryFilter) {
                 $currentRoot = $nodeRepo->getOption("PATH");
                 $contentFilter = $nodeRepo->getContentFilter();
                 if (isset($contentFilter)) {
                     $nodePath = $contentFilter->filterExternalPath($node->getPath());
                     if ($nodePath == "/") {
                         $k = array_keys($contentFilter->filters);
                         $nodePath = $k[0];
                     }
                 } else {
                     $nodePath = $node->getPath();
                 }
                 $relative = rtrim(substr($currentRoot, strlen($parentRoot)), "/") . rtrim($nodePath, "/");
                 $parentNodeURL = $node->getScheme() . "://" . $repositoryFilter . $relative;
                 $this->logDebug("action.share", "Recompute alert to " . $parentNodeURL);
                 $node = new AJXP_Node($parentNodeURL);
             }
             if (isset($cumulated[$path])) {
                 $cumulated[$path]->event_occurence++;
                 continue;
             }
             try {
                 $node->loadNodeInfo();
             } catch (Exception $e) {
                 if ($notification->alert_id) {
                     $this->eventStore->dismissAlertById($notification->alert_id);
                 }
                 continue;
             }
             $node->event_is_alert = true;
             $node->event_description = ucfirst($notification->getDescriptionBlock()) . " " . $mess["notification.tpl.block.user_link"] . " " . $notification->getAuthorLabel();
             $node->event_description_long = $notification->getDescriptionLong(true);
             $node->event_date = SystemTextEncoding::fromUTF8(AJXP_Utils::relativeDate($notification->getDate(), $mess));
             $node->event_type = "alert";
             $node->alert_id = $notification->alert_id;
             if ($node->getRepository() != null) {
                 $node->repository_id = '' . $node->getRepository()->getId();
                 if ($node->repository_id != $repositoryFilter && $node->getRepository()->getDisplay() != null) {
                     $node->event_repository_label = "[" . $node->getRepository()->getDisplay() . "]";
                 }
             } else {
                 $node->event_repository_label = "[N/A]";
             }
             $node->event_author = $notification->getAuthor();
             $node->event_occurence = 1;
             $cumulated[$path] = $node;
         }
     }
     $index = 1;
     foreach ($cumulated as $nodeToSend) {
         $nodeOcc = $nodeToSend->event_occurence > 1 ? "(" . $nodeToSend->event_occurence . ")" : "";
         if (isset($httpVars["merge_description"]) && $httpVars["merge_description"] == "true") {
             if (isset($httpVars["description_as_label"]) && $httpVars["description_as_label"] == "true") {
                 $nodeToSend->setLabel($nodeToSend->event_description . " " . $nodeOcc . " " . $nodeToSend->event_date);
             } else {
                 $nodeToSend->setLabel(basename($nodeToSend->getPath()) . " " . $nodeOcc . " " . " <small class='notif_desc'>" . $nodeToSend->event_description . " " . $nodeToSend->event_date . "</small>");
             }
         } else {
             $nodeToSend->setLabel(basename($nodeToSend->getPath()) . $nodeOcc);
         }
         // Replace PATH
         $nodeToSend->real_path = $path;
         //$url = parse_url($nodeToSend->getUrl());
         //$nodeToSend->setUrl($url["scheme"]."://".$url["host"]."/alert_".$index);
         $index++;
         AJXP_XMLWriter::renderAjxpNode($nodeToSend);
     }
     if (!$skipContainingTags) {
         if ($format == "html") {
             echo "</ul>";
         } else {
             AJXP_XMLWriter::close();
         }
     }
 }
 /**
  * @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 $oldNode
  * @param AJXP_Node $newNode
  * @param bool $copy
  */
 public function updateNodesIndex($oldNode = null, $newNode = null, $copy = false)
 {
     require_once AJXP_BIN_FOLDER . "/dibi.compact.php";
     try {
         if ($newNode == null) {
             $repoId = $this->computeIdentifier($oldNode->getRepository());
             // DELETE
             dibi::query("DELETE FROM [ajxp_index] WHERE [node_path] LIKE %like~ AND [repository_identifier] = %s", $oldNode->getPath(), $repoId);
         } else {
             if ($oldNode == null) {
                 // CREATE
                 $stat = stat($newNode->getUrl());
                 $res = dibi::query("INSERT INTO [ajxp_index]", array("node_path" => $newNode->getPath(), "bytesize" => $stat["size"], "mtime" => $stat["mtime"], "md5" => $newNode->isLeaf() ? md5_file($newNode->getUrl()) : "directory", "repository_identifier" => $repoId = $this->computeIdentifier($newNode->getRepository())));
             } else {
                 $repoId = $this->computeIdentifier($oldNode->getRepository());
                 if ($oldNode->getPath() == $newNode->getPath()) {
                     // CONTENT CHANGE
                     clearstatcache();
                     $stat = stat($newNode->getUrl());
                     $this->logDebug("Content changed", "current stat size is : " . $stat["size"]);
                     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", $oldNode->getPath(), $repoId);
                 } else {
                     // PATH CHANGE ONLY
                     $newNode->loadNodeInfo();
                     if ($newNode->isLeaf()) {
                         dibi::query("UPDATE [ajxp_index] SET ", array("node_path" => $newNode->getPath()), "WHERE [node_path] = %s AND [repository_identifier] = %s", $oldNode->getPath(), $repoId);
                     } else {
                         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", $oldNode->getPath(), $repoId);
                     }
                 }
             }
         }
     } catch (Exception $e) {
         AJXP_Logger::error("[meta.syncable]", "Indexation", $e->getMessage());
     }
 }