/** * Partial re-order of backlog items plus update of children * * Define the priorities of some children of a given Backlog Item * * <br> * Example: * <pre> * "order": { * "ids" : [123, 789, 1001], * "direction": "before", * "compared_to": 456 * } * </pre> * * <br> * Resulting order will be: <pre>[…, 123, 789, 1001, 456, …]</pre> * * <br> * Add example: * <pre> * "add": [ * { * "id": 34 * "remove_from": 56 * }, * ... * ] * </pre> * * <br> * Will remove element id 34 from 56 children and add it to current backlog_items children * * @url PATCH {id}/children * * @param int $id Id of the Backlog Item * @param \Tuleap\AgileDashboard\REST\v1\OrderRepresentation $order Order of the children {@from body} * @param array $add Ids to add to backlog_items content {@from body} * * @throws 400 * @throws 404 * @throws 409 */ protected function patch($id, OrderRepresentation $order = null, array $add = null) { $artifact = $this->getArtifact($id); $user = $this->getCurrentUser(); try { $indexed_children_ids = $this->getChildrenArtifactIds($user, $artifact); if ($add) { $this->resources_patcher->startTransaction(); $to_add = $this->resources_patcher->removeArtifactFromSource($user, $add); if (count($to_add)) { $validator = new PatchAddRemoveValidator($indexed_children_ids, new PatchAddBacklogItemsValidator($this->artifact_factory, $this->tracker_factory->getPossibleChildren($artifact->getTracker()), $id)); $backlog_items_ids = $validator->validate($id, array(), $to_add); $this->artifactlink_updater->updateArtifactLinks($user, $artifact, $backlog_items_ids, array()); $indexed_children_ids = array_flip($backlog_items_ids); } $this->resources_patcher->commit(); } if ($order) { $order->checkFormat($order); $order_validator = new OrderValidator($indexed_children_ids); $order_validator->validate($order); $this->resources_patcher->updateArtifactPriorities($order, $id, null); } } catch (IdsFromBodyAreNotUniqueException $exception) { throw new RestException(409, $exception->getMessage()); } catch (OrderIdOutOfBoundException $exception) { throw new RestException(409, $exception->getMessage()); } catch (ArtifactCannotBeChildrenOfException $exception) { throw new RestException(409, $exception->getMessage()); } catch (Tracker_Artifact_Exception_CannotRankWithMyself $exception) { throw new RestException(400, $exception->getMessage()); } catch (\Exception $exception) { throw new RestException(400, $exception->getMessage()); } }
/** * Partial re-order of Kanban items * * Partial re-order of Kanban items * * <pre> * /!\ Kanban REST routes are under construction and subject to changes /!\ * </pre> * * @url PATCH {id}/items * * @param int $id Id of the Kanban * @param int $column_id Id of the column the item belongs to {@from query} * @param \Tuleap\AgileDashboard\REST\v1\OrderRepresentation $order Order of the items {@from body} * @param \Tuleap\AgileDashboard\REST\v1\Kanban\KanbanAddRepresentation $add Ids to add to the column {@from body} */ protected function patchItems($id, $column_id, OrderRepresentation $order = null, KanbanAddRepresentation $add = null) { $current_user = UserManager::instance()->getCurrentUser(); $kanban = $this->kanban_factory->getKanban($current_user, $id); if (!$this->columnIsInTracker($kanban, $current_user, $column_id)) { throw new RestException(404); } if ($add) { $add->checkFormat(); $this->validateIdsInAddAreInKanbanTracker($kanban, $add); $this->resources_patcher->startTransaction(); try { $this->moveArtifactsInColumn($kanban, $current_user, $add, $column_id); $this->resources_patcher->commit(); } catch (Tracker_NoChangeException $exception) { $this->resources_patcher->rollback(); } catch (Tracker_Workflow_GlobalRulesViolationException $exception) { $this->resources_patcher->rollback(); throw new RestException(400, $exception->getMessage()); } catch (Exception $exception) { $this->resources_patcher->rollback(); throw new RestException(500, $exception->getMessage()); } } if ($order) { $order->checkFormat(); $kanban_column_items = $this->getItemsInColumn($kanban->getTrackerId(), $column_id); $order_validator = new OrderValidator($kanban_column_items); try { $order_validator->validate($order); } catch (IdsFromBodyAreNotUniqueException $exception) { throw new RestException(409, $exception->getMessage()); } catch (OrderIdOutOfBoundException $exception) { throw new RestException(409, $exception->getMessage()); } catch (Exception $exception) { throw new RestException(500, $exception->getMessage()); } $this->resources_patcher->updateArtifactPriorities($order, Tracker_Artifact_PriorityHistoryChange::NO_CONTEXT, $this->getProjectIdForKanban($kanban)); } if ($add || $order) { $this->statistics_aggregator->addCardDragAndDropHit($this->getProjectIdForKanban($kanban)); $this->sendMessageForDroppingItem($current_user, $kanban, $order, $add, $column_id); } }
public function patch(PFUser $user, Project $project, OrderRepresentationBase $order = null, array $add = null) { $this->checkIfUserCanChangePrioritiesInMilestone($user, $project); if ($add) { try { $this->resources_patcher->removeArtifactFromSource($user, $add); } catch (\Exception $exception) { throw new RestException(400, $exception->getMessage()); } } if ($order) { $order->checkFormat($order); $all_ids = array_merge(array($order->compared_to), $order->ids); $this->validateArtifactIdsAreInUnassignedTopBacklog($all_ids, $user, $project); try { $this->resources_patcher->updateArtifactPriorities($order, self::TOP_BACKLOG_IDENTIFIER, $project->getId()); } catch (Tracker_Artifact_Exception_CannotRankWithMyself $exception) { throw new RestException(400, $exception->getMessage()); } } }
/** * Partial re-order of milestone backlog relative to one element. * * <br> * Example: * <pre> * "order": { * "ids" : [123, 789, 1001], * "direction": "before", * "compared_to": 456 * }, * "add": { * [123] * } * </pre> * * <br> * Resulting order will be: <pre>[…, 123, 789, 1001, 456, …]</pre> * * <br> * Add example: * <pre> * "add": [ * { * "id": 34 * "remove_from": 56 * }, * ... * ] * </pre> * * <br> * Will remove element id 34 from milestone 56 backlog and add it to current backlog * * @url PATCH {id}/backlog * * @param int $id Id of the milestone Item * @param \Tuleap\AgileDashboard\REST\v1\OrderRepresentation $order Order of the children {@from body} * @param array $add Ids to add/move to milestone backlog {@from body} * * @throw 400 * @throw 403 * @throw 404 * @throw 409 */ protected function patchBacklog($id, OrderRepresentation $order = null, array $add = null) { $user = $this->getCurrentUser(); $milestone = $this->getMilestoneById($user, $id); $this->checkIfUserCanChangePrioritiesInMilestone($milestone, $user); $to_add = array(); try { if ($add) { $this->resources_patcher->startTransaction(); $to_add = $this->resources_patcher->removeArtifactFromSource($user, $add); if (count($to_add)) { $valid_to_add = $this->milestone_validator->validateArtifactIdsCanBeAddedToBacklog($to_add, $milestone, $user); $this->addMissingElementsToBacklog($milestone, $user, $valid_to_add); } $this->resources_patcher->commit(); } } catch (Tracker_NoChangeException $exception) { // nothing to do } catch (\Exception $exception) { throw new RestException(400, $exception->getMessage()); } try { if ($order) { $order->checkFormat($order); $this->milestone_validator->validateArtifactIdsAreInUnplannedMilestone($this->filterOutAddedElements($order, $to_add), $milestone, $user); $this->resources_patcher->updateArtifactPriorities($order, $id, $milestone->getProject()->getId()); } } catch (IdsFromBodyAreNotUniqueException $exception) { throw new RestException(409, $exception->getMessage()); } catch (ArtifactIsNotInUnplannedBacklogItemsException $exception) { throw new RestException(409, $exception->getMessage()); } catch (Tracker_Artifact_Exception_CannotRankWithMyself $exception) { throw new RestException(400, $exception->getMessage()); } catch (\Exception $exception) { throw new RestException(400, $exception->getMessage()); } }