/** * Rend un élément inaccessible (en BDD, ne comporte pas d'action sur le serveur de fichier). * @author Alban Truc * @param MongoId|string $idElement * @param MongoId|string $idUser * @param string $returnImpactedElements si 'TRUE', retourne les éléments impactés par l'action * @since 31/05/2014 * @return array|Element * @todo appel de la fonction qui fait diverses tâches (cf. documentation) sur le serveur de fichier */ function disableHandler($idElement, $idUser, $returnImpactedElements = 'false') { $idElement = new MongoId($idElement); $idUser = new MongoId($idUser); // 11 correspond au droit de lecture et écriture $hasRight = actionAllowed($idElement, $idUser, array('11')); if (!is_array($hasRight)) { if ($hasRight === TRUE) { //récupère l'élément $elementManager = new ElementManager(); $element = $elementManager->findById($idElement); if (!array_key_exists('error', $element)) { if ($element['state'] == 1) { //récupère le code du refElement de notre élément $refElementManager = new RefElementManager(); $refElement = $refElementManager->findById($element['idRefElement'], array('code' => TRUE)); if (!array_key_exists('error', $refElement)) { //si le code commence par un 4 (les codes de dossier commencent par un 4) if (preg_match('/^4/', $refElement['code'])) { $serverPath = $element['serverPath'] . $element['name'] . '/'; //notre criteria inclut tous les éléments se trouvant dans le dossier et ses dossiers enfants $elementCriteria = array('state' => (int) 1, 'idOwner' => $idUser, '$or' => array(array('_id' => $idElement), array('serverPath' => new MongoRegex("/^{$serverPath}/i")))); } else { $elementCriteria = array('_id' => $idElement, 'state' => (int) 1); } //pour mettre à jour tous les documents et pas uniquement le premier répondant au critère $options = array('multiple' => TRUE); //désactivation de l'élément et suppression du lien de téléchargement $elementUpdate = array('$set' => array('state' => (int) 0, 'downloadLink' => '')); /* * obligatoirement à récupérer avant la mise à jour, sinon aucun document ne devrait être trouvé * en cas de réussite de cette mise à jour. On ne peut pas non plus faire le même critère avec à la * place un état de 0 parce qu'il se peut qu'il y ait déjà des éléments désactivés en base. * L'id est récupérer pour le critère de mise à jour des droits et le size pour la déduction du * stockage occupé par les éléments (mise à jour du storage du compte utilisateur). */ $impactedElements = $elementManager->find($elementCriteria, array('_id' => TRUE, 'size' => TRUE)); $elementUpdateResult = $elementManager->update($elementCriteria, $elementUpdate, $options); if (!is_array($elementUpdateResult)) { if ($elementUpdateResult === TRUE) { $updateFolderStatus = updateFolderStatus($element['serverPath'], $idUser); if (is_bool($updateFolderStatus) && $updateFolderStatus === TRUE) { //séparation en deux tableaux $idImpactedElements = array(); $sizeImpactedElements = array(); foreach ($impactedElements as $impactedElement) { //création d'un tableau contenant uniquement les id des éléments impactés if (isset($impactedElement['_id'])) { $idImpactedElements[]['idElementImpacted'] = $impactedElement['_id']; } //création d'un tableau contenant uniquement la taille de chaque élément impacté if (isset($impactedElement['size'])) { $sizeImpactedElements[] = $impactedElement['size']; } } //var_dump($idImpactedElements); //désactivation des droits sur ces éléments $rightUpdate = array('$set' => array('state' => (int) 0)); $rightManager = new RightManager(); foreach ($idImpactedElements as $id) { $rightCriteria = array('state' => (int) 1, 'idElement' => $id['idElementImpacted']); //l'opération n'étant pas bloquante, on ne se soucie pour l'instant pas d'un potentiel échec $rightManager->update($rightCriteria, $rightUpdate, $options); } //déduction du stockage occupé par ces éléments dans la collection account $totalSize = array_sum($sizeImpactedElements); //http://www.php.net/manual/function.array-sum.php //var_dump($totalSize); exit(); $accountManager = new AccountManager(); $accountCriteria = array('state' => (int) 1, 'idUser' => $idUser); $accountUpdate = array('$inc' => array('storage' => -$totalSize)); $accountUpdateResult = $accountManager->update($accountCriteria, $accountUpdate); if (!is_array($accountUpdateResult)) { if ($accountUpdateResult === TRUE) { if ($returnImpactedElements == 'true') { return $idImpactedElements; } else { return TRUE; } } else { return array('error' => 'Did not manage to update the storage value.'); } } else { return $accountUpdateResult; } } else { return $updateFolderStatus; } } else { return array('error' => 'Did not manage to update all elements. The elements that we couldn\'t updates are in this array at the index \'notUpdated\'', 'notUpdated' => $elementManager->find($elementCriteria, array('_id' => TRUE))); } } else { return $elementUpdateResult; } //message d'erreur } else { return $refElement; } //message d'erreur } else { return array('error' => 'Element already inactivated'); } } else { return $element; } //message d'erreur } else { return array('error' => 'Access denied'); } } else { return $hasRight; } }
/** * Déplace l'élément (et ce qu'il contient dans le cas d'un dossier) dans la destination indiquée. * $options est un tableau de booléens avec comme indexes possibles: * - returnImpactedElements à true pour retourner les éléments à déplacer * - returnMovedElements à true pour retourner les éléments déplacés * - keepRights à false pour ne pas conserver les droits sur les éléments * - keepDownloadLinks à false pour ne pas conserver les liens de téléchargement * On peut se retrouver avec la structure de retour suivante: * array( * 'operationSuccess' => true ou false, * 'error' => 'message d'erreur', * 'impactedElements' => array(), * 'movedElements' => array(), * 'failedToMove' => array() * ) * @author Alban Truc * @param string|MongoId $idElement * @param string|MongoId $idUser * @param string $path * @param array $options * @since 08/06/2014 * @return array * @todo mêmes améliorations que pour la fonction copyHandler */ function moveHandler($idElement, $idUser, $path, $options = array()) { $idElement = new MongoId($idElement); $idUser = new MongoId($idUser); $impactedElements = array(); $movedElements = array(); $failedToMove = array(); $operationSuccess = FALSE; /* * 11 correspond au droit de lecture et écriture. * Si on souhaite accepter la copie avec des droits de plus bas niveau, il suffit d'ajouter les codes correspondant * au tableau en 3e paramètre ci-dessous. */ $hasRight = actionAllowed($idElement, $idUser, array('11')); if (!is_array($hasRight)) { if ($hasRight === TRUE) { //récupère l'élément $elementManager = new ElementManager(); $element = $elementManager->findById($idElement); if (!array_key_exists('error', $element)) { if ($element['state'] == 1) { if ($path != $element['serverPath']) { $elementCriteria = array('state' => (int) 1, 'idOwner' => $idUser); /* * extraction de l'emplacement du dossier de destination à partir de $path * @see http://www.php.net/manual/en/function.implode.php * @see http://www.php.net/manual/en/function.explode.php */ $destinationFolderPath = implode('/', explode('/', $path, -2)) . '/'; $elementCriteria['serverPath'] = $destinationFolderPath; /** * la racine n'ayant pas d'enregistrement pour elle même, on a un serverPath "/" mais de nom. * il faut donc distinguer les cas de copies d'un élément dans la racine des autres cas. */ if ($path != "/") { /* * extraction du nom du dossier de destination à partir du $path * @see http://www.php.net/manual/en/function.array-slice.php */ $destinationFolderName = implode(array_slice(explode('/', $path), -2, 1)); $elementCriteria['name'] = $destinationFolderName; //récupération de l'id de l'élément en base correspondant au dossier de destination $idDestinationFolder = $elementManager->findOne($elementCriteria, array('_id' => TRUE)); if (array_key_exists('error', $idDestinationFolder)) { return prepareMoveReturn($options, $operationSuccess, $idDestinationFolder, $impactedElements, $movedElements, $failedToMove); } else { //vérification des droits dans la destination $hasRightOnDestination = actionAllowed($idDestinationFolder['_id'], $idUser, array('11')); if (is_array($hasRightOnDestination) && array_key_exists('error', $hasRightOnDestination)) { return prepareMoveReturn($options, $operationSuccess, $hasRightOnDestination, $impactedElements, $movedElements, $failedToMove); } elseif ($hasRightOnDestination == FALSE) { return prepareMoveReturn($options, $operationSuccess, array('error' => 'Access denied in destination'), $impactedElements, $movedElements, $failedToMove); } } } } $elementNameInDestination = avoidNameCollision($path, $element['name'], $idUser); if (is_string($elementNameInDestination)) { //File Server 14/06/2014 $refElementManager = new RefElementManager(); $refElementFieldsToReturn = array('code' => TRUE, 'extension' => TRUE); $refElement = $refElementManager->findById($element['idRefElement'], $refElementFieldsToReturn); if (array_key_exists('error', $refElement)) { return $refElement; } //dossier ou non reconnu, pas d'extension à rajouter if (preg_match('/^4/', $refElement['code']) || preg_match('/^9/', $refElement['code'])) { $completeSourceName = $element['name']; $completeDestinationName = $elementNameInDestination; } else { $completeSourceName = $element['name'] . $refElement['extension']; $completeDestinationName = $elementNameInDestination . $refElement['extension']; } $FSMoveResult = moveFSElement($idUser, $element['serverPath'], $completeSourceName, $path, $completeDestinationName); if (!is_bool($FSMoveResult) || $FSMoveResult != TRUE) { return $FSMoveResult; } //Fin File Server if ($refElement['code'] != '4002' && preg_match('/^4/', $refElement['code'])) { $serverPath = $element['serverPath'] . $element['name'] . '/'; //récupération des éléments contenus dans le dossier $seekElementsInFolder = array('state' => (int) 1, 'serverPath' => new MongoRegex("/^{$serverPath}/i"), 'idOwner' => $idUser); $elementsInFolder = $elementManager->find($seekElementsInFolder); } if (isset($elementsInFolder) && !array_key_exists('error', $elementsInFolder)) { $impactedElements = $elementsInFolder; } $impactedElements[] = $element; $count = 0; foreach ($impactedElements as $key => $impactedElement) { $updateCriteria = array('_id' => $impactedElement['_id'], 'state' => (int) 1); //préparation de la copie $elementCopy = $impactedElement; if (count($impactedElements) != $key + 1) { $explode = explode($serverPath, $elementCopy['serverPath']); if (isset($explode[1]) && $explode[1] != '') { $elementPath = $path . $elementNameInDestination . '/' . $explode[1]; $elementCopy['serverPath'] = $elementPath; } else { $elementCopy['serverPath'] = $path . $elementNameInDestination . '/'; } } else { $elementCopy['name'] = $elementNameInDestination; $elementCopy['serverPath'] = $path; } if (array_key_exists('keepDownloadLinks', $options) && $options['keepDownloadLinks'] == 'FALSE') { $elementCopy['downloadLink'] = ''; } //mise à jour $updateResult = $elementManager->update($updateCriteria, $elementCopy); //gestion des erreurs if (!is_bool($updateResult)) { $failedToPaste[$count]['elementToMove'] = $impactedElement; $failedToPaste[$count]['elementMoved'] = $elementCopy; $failedToPaste[$count]['error'] = $updateResult['error']; $count++; } elseif ($updateResult == TRUE) { $movedElements[] = $elementCopy; } } /* * Si le déplacement vide un dossier ou rempli un dossier qui était vide, * on met à jour son refElement */ updateFolderStatus($path, $idUser); updateFolderStatus($element['serverPath'], $idUser); if (array_key_exists('keepRights', $options) && $options['keepRights'] == 'FALSE') { disableRights($impactedElements); } $operationSuccess = TRUE; return prepareMoveReturn($options, $operationSuccess, array(), $impactedElements, $movedElements, $failedToMove); } else { return prepareMoveReturn($options, $operationSuccess, $elementNameInDestination, $impactedElements, $movedElements, $failedToMove); } } else { return prepareMoveReturn($options, $operationSuccess, array('error' => 'Element inactivated, nothing to do'), $impactedElements, $movedElements, $failedToMove); } } else { return prepareMoveReturn($options, $operationSuccess, $element, $impactedElements, $movedElements, $failedToMove); } } else { return prepareMoveReturn($options, $operationSuccess, array('error' => 'Access denied'), $impactedElements, $movedElements, $failedToMove); } } else { return prepareMoveReturn($options, $operationSuccess, $hasRight, $impactedElements, $movedElements, $failedToMove); } }
/** * Retourne le droit, le refRight, l'élément, le refElement et le propriétaire * @author Alban Truc * @param string|MongoId $idUser * @param string $path emplacement sur le serveur des éléments * @param NULL|string $elementName nom de l'élément * @since 01/05/2014 * @return array */ public function returnSharedElementsDetails($idUser, $path = 'all', $elementName = NULL) { $idUser = new MongoId($idUser); $criteria = array('state' => (int) 1, 'idUser' => $idUser); //récupération des droits sur les éléments $rightManager = new RightManager(); $rights = $rightManager->find($criteria); $userManager = new UserManager(); $refRightManager = new RefRightManager(); $refElementManager = new RefElementManager(); if (is_array($rights) && !array_key_exists('error', $rights)) { foreach ($rights as $key => $right) { $owner = NULL; $refRight = NULL; //Récupération de l'élément. On enlève le droit de la liste si l'élément n'est pas disponible $elementCriteria = array('_id' => new MongoId($right['idElement']), 'state' => (int) 1); if ($path != 'all') { $elementCriteria['serverPath'] = $path; } if ($elementName != NULL) { $elementCriteria['name'] = $elementName; } unset($right['idElement']); $element = self::findOne($elementCriteria); if (is_array($element) && !array_key_exists('error', $element)) { $idOwner = $element['idOwner']; unset($element['idOwner']); //récupération du refElement. On enlève le droit de la liste si le refElement n'est pas trouvé $refElement = $refElementManager->findById($element['idRefElement']); unset($element['idRefElement']); if (is_array($refElement) && !array_key_exists('error', $refElement)) { $element['refElement'] = $refElement; $right['element'] = $element; } else { unset($rights[$key]); continue; } } else { unset($rights[$key]); continue; } /* * Récupération de l'utilisateur propriétaire. * Si son état n'est pas à 1, le droit n'aurait pas du être à 1; donc on enlève ce droit de la liste. */ $userCriteria = array('_id' => new MongoId($idOwner), 'state' => (int) 1); $fieldsToReturn = array('firstName' => 1, 'lastName' => 1); unset($right['idUser']); $owner = $userManager->findOne($userCriteria, $fieldsToReturn); if (is_array($owner) && !array_key_exists('error', $owner)) { $right['owner'] = $owner; } else { unset($rights[$key]); continue; } //Récupération du refRight. S'il n'existe pas on enlève ce droit de la liste. $refRight = $refRightManager->findById($right['idRefRight']); unset($right['idRefRight']); if (is_array($refRight) && !array_key_exists('error', $refRight)) { $right['refRight'] = $refRight; } else { unset($rights[$key]); continue; } $rights[$key] = $right; } if (empty($rights)) { return array('error' => 'No match found.'); } } return $rights; }