/** * Copie 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 pour retourner les éléments à copier * - returnPastedElements pour retourner les éléments copiés (ceux présent dans la destination), échec et succès * - keepRights pour également copier les droits des éléments sources * On peut se retrouver avec la structure de retour suivante: * array( * 'operationSuccess' => true ou false * 'error' => 'message d'erreur', * 'impactedElements' => array(), * 'pastedElements' => array(), * 'failedToPaste' => array() * ) * @author Alban Truc & Harry Bellod * @param string|MongoId $idElement * @param string|MongoId $idUser * @param string $path * @param array $options * @since 07/06/2014 * @return array * @todo optimisation: découpage en plusieurs fonctions de moins de 80 lignes * @todo meilleure prise en charge des conflits de noms: actuellement l'extension n'est pas prise en compte */ function copyHandler($idElement, $idUser, $path, $options = array()) { $idElement = new MongoId($idElement); $idUser = new MongoId($idUser); $impactedElements = array(); $pastedElements = array(); $failedToPaste = 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 $elementPdoManager = new ElementPdoManager(); $element = $elementPdoManager->findById($idElement); if ($element instanceof Element) { if ($element->getState() == 1) { if ($path != $element->getServerPath()) { $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 = $elementPdoManager->findOne($elementCriteria, array('_id' => TRUE)); if (array_key_exists('error', $idDestinationFolder)) { return prepareCopyReturn($options, $operationSuccess, $idDestinationFolder, $impactedElements, $pastedElements, $failedToPaste); } 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 prepareCopyReturn($options, $operationSuccess, $hasRightOnDestination, $impactedElements, $pastedElements, $failedToPaste); } elseif ($hasRightOnDestination == FALSE) { return prepareCopyReturn($options, $operationSuccess, array('error' => 'Access denied in destination'), $impactedElements, $pastedElements, $failedToPaste); } } } } $elementNameInDestination = avoidNameCollision($path, $element->getName(), $idUser); if (is_string($elementNameInDestination)) { //File Server -- 13/06/2014 $refElementPdoManager = new RefElementPdoManager(); $refElementFieldsToReturn = array('code' => TRUE, 'extension' => TRUE); $refElement = $refElementPdoManager->findById($element->getRefElement(), $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->getName(); $completeDestinationName = $elementNameInDestination; } else { $completeSourceName = $element->getName() . $refElement['extension']; $completeDestinationName = $elementNameInDestination . $refElement['extension']; } $FSCopyResult = copyFSElement($idUser, $element->getServerPath(), $completeSourceName, $path, $completeDestinationName); if (!is_bool($FSCopyResult) || $FSCopyResult != TRUE) { return $FSCopyResult; } //Fin File Server //récupérer la valeur de storage de l'utilisateur $accountPdoManager = new AccountPdoManager(); $accountCriteria = array('state' => (int) 1, 'idUser' => $idUser); $fieldsToReturn = array('storage' => TRUE, 'idRefPlan' => TRUE); $account = $accountPdoManager->findOne($accountCriteria, $fieldsToReturn); if (!array_key_exists('error', $account)) { $currentUserStorage = $account['storage']; //récupérer le stockage maximum autorisé par le plan de l'utilisateur $refPlanPdoManager = new RefPlanPdoManager(); $refPlan = $refPlanPdoManager->findById($account['idRefPlan'], array('maxStorage' => TRUE)); if (!array_key_exists('error', $refPlan)) { $maxStorageAllowed = $refPlan['maxStorage']; } else { return prepareCopyReturn($options, $operationSuccess, $refPlan, $impactedElements, $pastedElements, $failedToPaste); } } else { return prepareCopyReturn($options, $operationSuccess, $account, $impactedElements, $pastedElements, $failedToPaste); } if ($refElement['code'] != '4002' && preg_match('/^4/', $refElement['code'])) { $serverPath = $element->getServerPath() . $element->getName() . '/'; //récupération des éléments contenus dans le dossier $seekElementsInFolder = array('state' => (int) 1, 'serverPath' => new MongoRegex("/^{$serverPath}/i"), 'idOwner' => $idUser); $elementsInFolder = $elementPdoManager->find($seekElementsInFolder); } if (isset($elementsInFolder) && !array_key_exists('error', $elementsInFolder)) { $impactedElements = $elementsInFolder; } $impactedElements[] = $element; $totalSize = sumSize($impactedElements); //calcul de la taille du contenu if ($currentUserStorage + $totalSize <= $maxStorageAllowed) { $count = 0; foreach ($impactedElements as $key => $impactedElement) { //préparation de la copie $elementCopy = clone $impactedElement; $elementCopy->setId(new MongoId()); if (count($impactedElements) != $key + 1) { $explode = explode($serverPath, $elementCopy->getServerPath()); if (isset($explode[1]) && $explode[1] != '') { $elementPath = $path . $elementNameInDestination . '/' . $explode[1]; $elementCopy->setServerPath($elementPath); } else { $elementCopy->setServerPath($path . $elementNameInDestination . '/'); } } else { $elementCopy->setName($elementNameInDestination); $elementCopy->setServerPath($path); } $elementCopy->setDownloadLink(''); //insertion de la copie $copyResult = $elementPdoManager->create($elementCopy); //gestion des erreurs if (!is_bool($copyResult)) { $failedToPaste[$count]['elementToCopy'] = $impactedElement; $failedToPaste[$count]['elementCopy'] = $elementCopy; $failedToPaste[$count]['error'] = $copyResult['error']; $count++; } elseif ($copyResult == TRUE) { $pastedElements[] = $elementCopy; } } if ($totalSize > 0) { $updateCriteria = array('_id' => $account['_id'], 'state' => (int) 1); $storageUpdate = array('$inc' => array('storage' => $totalSize)); $accountUpdate = $accountPdoManager->update($updateCriteria, $storageUpdate); if (is_array($accountUpdate) && array_key_exists('error', $accountUpdate)) { $errorMessage = 'Error when trying to add ' . $totalSize . ' to user account'; return prepareCopyReturn($options, $operationSuccess, $errorMessage, $impactedElements, $pastedElements, $failedToPaste); } } // Lors de copie dans un dossier, on vérifie si le dossier était empty. Au quel cas on le passe à NotEmpty updateFolderStatus($path, $idUser); if (array_key_exists('keepRights', $options) && $options['keepRights'] == TRUE) { copyRights($impactedElements, $pastedElements); } $operationSuccess = TRUE; return prepareCopyReturn($options, $operationSuccess, array(), $impactedElements, $pastedElements, $failedToPaste); } else { $errorMessage = 'Not enough space available for your account to proceed action'; return prepareCopyReturn($options, $operationSuccess, $errorMessage, $impactedElements, $pastedElements, $failedToPaste); } } else { return prepareCopyReturn($options, $operationSuccess, $elementNameInDestination, $impactedElements, $pastedElements, $failedToPaste); } } else { return prepareCopyReturn($options, $operationSuccess, array('error' => 'Element inactivated, nothing to do'), $impactedElements, $pastedElements, $failedToPaste); } } else { return prepareCopyReturn($options, $operationSuccess, $element, $impactedElements, $pastedElements, $failedToPaste); } } else { return prepareCopyReturn($options, $operationSuccess, array('error' => 'Access denied'), $impactedElements, $pastedElements, $failedToPaste); } } else { return prepareCopyReturn($options, $operationSuccess, $hasRight, $impactedElements, $pastedElements, $failedToPaste); } }
var_dump($updatedAccount); echo '____------<br />'; $fields = NULL; $options = array('remove' => true); //supprimera au lieu de faire un update echo '____account que l\'on supprime'; $result = $accountPdoManager->findAndModify($searchQuery, $updateCriteria, $fields, $options); var_dump($result); echo '____---------------------<br />'; $account->setState(0); echo '____Reinsertion de l\'objet precedemment supprime'; $add = $accountPdoManager->create($account); var_dump($add); echo '----------------------------------------<br />'; echo 'Utilisation du create, affiche true en cas de succes'; $newInsert = array('test' => TRUE); $createResult = $accountPdoManager->create($newInsert); var_dump($createResult); echo '----------------------------------------<br />'; echo 'Utilisation de l\'update, affiche true en cas de succes'; $criteria = array('test' => TRUE); $update = array('$set' => array('number' => (int) 500)); $updateResult = $accountPdoManager->update($criteria, $update); var_dump($updateResult); // true si l'update a réussi echo '----------------------------------------<br />'; echo 'Utilisation du remove, affiche true en cas de succes'; $criteria = array('test' => TRUE); $removeResult = $accountPdoManager->remove($criteria); var_dump($removeResult); echo '----------------------------------------<br />';