3 * Copyright (c) Institut TELECOM, 2010. All Rights Reserved.
5 * Originally written by Sabri LABBENE, 201O
7 * Codendi is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License, or
10 * (at your option) any later version.
12 * Codendi is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
17 * You should have received a copy of the GNU General Public License
18 * along with Codendi. If not, see <http://www.gnu.org/licenses/>.
21 require_once('OSLCConnector.php');
22 require_once(dirname(__FILE__) . '/../models/Codendi.inc.php');
24 require_once ('pre.php');
25 require_once ('session.php');
27 require_once ('common/tracker/Tracker.class.php');
28 require_once ('common/tracker/TrackerFactory.class.php');
29 require_once ('common/tracker/Tracker_Artifact.class.php');
30 require_once ('common/tracker/Tracker_ArtifactFactory.class.php');
31 require_once ('common/tracker/Tracker_FormElementFactory.class.php');
34 class CodendiOSLCConnector extends OSLCConnector {
38 * Filter parameters provided in the REST GET request to check whether mandatory ones are set.
40 * @param array $params
43 public function filterRequestParams($params) {
44 // Process the args provided by Zend REST
45 if (is_array($params)) {
46 if(!isset($params['project'])) {
47 throw new Exception('Missing project id !');
48 } elseif(!isset($params['tracker'])) {
49 throw new Exception('Missing tracker id resource for project '.$params['project'].' !');
57 * Checks whether a change request exists inside Codendi trackers.
58 * @param int $id change request id.
61 public function checkChangeRequestExists($changerequest_id) {
62 $af = Tracker_ArtifactFactory::instance();
63 $artifact = $af->getArtifactById($changerequest_id);
72 * Constructs the model from Codendi DB by fetching the requested changeRequests.
74 * @param array $params contains 'project' + 'tracker'
76 public function fetchChangeRequests($params) {
79 // what the DB will be queried on
83 if (isset($params['project'])) {
84 $group_id = $params['project'];
86 if (isset($params['tracker'])) {
87 $tracker_id = $params['tracker'];
89 if (isset($params['bug'])) {
90 $changerequest_id = $params['bug'];
91 $af = Tracker_ArtifactFactory::instance();
92 $changeRequest = $af->getArtifactById($changerequest_id);
93 $this->changerequests = new ChangeRequestsFusionForgeDb($changeRequest);
96 $project = new Project($group_id);
97 if (!$project->usesService('tracker')) {
98 throw new Exception('Error : Tracker service is not used for this project.', 'fetchChangeRequests');
101 $tf = TrackerFactory::instance();
103 throw new Exception('Error : Could Not Get TrackerFactory', 'fetchChangeRequests');
106 $tracker = $tf->getTrackerById($tracker_id);
108 if ($tracker == null) {
109 throw new Exception('Error : Could Not Get Tracker', 'fetchChangeRequests');
111 $af = Tracker_ArtifactFactory::instance();
112 $artifacts = $af->getArtifactsByTrackerId($tracker_id);
115 // instanciate the model from the returned artifacts
116 if(isset($params['fields'])){
117 $this->changerequests = new ChangeRequestsCodendiDb($artifacts, $params['fields']);
119 $this->changerequests = new ChangeRequestsCodendiDb($artifacts);
123 public function fetchChangeRequest($changerequest_id, $uri, $requested_fields=array()) {
124 $af = Tracker_ArtifactFactory::instance();
125 $artifact = $af->getArtifactById($changerequest_id);
128 throw new NotFoundException('Error : Change Request not found', 'fetchChangeRequest' );
130 $art = array($artifact);
132 $changerequest = new ChangeRequestsCodendiDb($art, $requested_fields);
134 return $this->prepareChangeRequest($changerequest[$changerequest_id], $uri);
138 * Updates an existant Codendi ChangeRequest in the tracker DataBase.
139 * @param int $identifier id of the ChangeRequest within Codendi tracker
140 * @param ChangeRequest the change request given as input for the PUT request.
141 * @param array $props array of the properties that PUT request is going to change
142 * @return boolean true if success, false otherwise.
144 public function updateChangeRequest($changerequest_id, $group_id, $tracker_id, $changerequest, $props) {
145 $user = UserManager::instance()->getCurrentUser();
146 $pm = ProjectManager::instance();
147 $project = $pm->getProject($group_id);
148 if (! $project || ! is_object($project)) {
149 throw new Exception('Error : Could Not Get Group','updateChangeRequest');
150 } elseif ($project->isError()) {
151 throw new Exception('Error : ' . $project->getErrorMessage(),'updateChangeRequest');
153 if ( ! checkRestrictedAccess($project)) {
154 throw new Exception('Error, Restricted user: permission denied.', 'updateChangeRequest');
157 $tf = TrackerFactory::instance();
158 $tracker = $tf->getTrackerById($tracker_id);
160 if ($tracker == null) {
161 throw new Exception('Error : Could not get Tracker.', 'updateChangeRequest');
162 } elseif ($tracker->getGroupId() != $group_id) {
163 throw new Exception('Error : Could not get Tracker.', 'updateChangeRequest');
166 $af = Tracker_ArtifactFactory::instance();
167 if ($artifact = $af->getArtifactById($changerequest_id)) {
168 if ($artifact->getTrackerId() != $tracker_id) {
169 throw new Exception('Error : Could not get Artifact.', 'updateChangeRequest');
173 // Get the artifact data using its ID.
174 $art_obj =& artifact_get_object($identifier);
175 $art = $art_obj->data_array;
177 $cm_request = $changerequest->container;
179 $terms = array('dc:','helios_bt:');
180 foreach($props as &$prop) {
181 $prop = str_replace($terms,"",$prop);
185 // Check all the mandatory fields for an artifact update request.
187 // dc:title ===> summary
188 if(in_array('title',$props))
190 if(isset($cm_request['title']))
192 $art['summary'] = $cm_request['title']; // mandatory
196 throw new BadRequestException("dc:title mentioned in the request query not found in request body!");
200 // dc:description ===> details
201 if(in_array('description',$props))
203 if(isset($cm_request['description']))
205 $art['details'] = $cm_request['description']; // mandatory
209 throw new BadRequestException("dc:decription mentioned in the request query not found in request body!");
213 // helios_bt:priority ===> priority
214 if(in_array('priority',$props))
216 if(isset($cm_request['priority']))
218 $art['priority'] = $cm_request['priority']; // mandatory
222 throw new BadRequestException("helios_bt:priority mentioned in the request query not found in request body!");
226 // helios_bt:status ===> status
227 if(in_array('status',$props))
229 if(isset($cm_request['status']))
231 $art['status_id'] = self::$status_arr[$cm_request['status']]; // mandatory
235 throw new BadRequestException("helios_bt:status mentioned in the request query not found in request body!");
239 //helios_bt:assigned_to ====> assigned_to
240 if(in_array('assigned_to', $props))
242 if(isset($cm_request['assigned_to']))
244 $art['assigned_to'] = $cm_request['assigned_to'];
248 throw new BadRequestException("helios_bt:assigned_to mentionned in the request query not found in request body!");
253 $canned_response=100;
255 // We assume that we don't change the artifact type (bug, task, etc)
257 $new_artifact_type_id = $art_obj->ArtifactType->getID();
259 //TODO: figure out if a follow up is in OSLC specs and if it is the case include it.
262 if(!$art_obj->update($art['priority'],$art['status_id'],$art['assigned_to'],$art['summary'],$canned_response,$follow_up_msg,$new_artifact_type_id,array(),$art['details']))
264 throw new Exception($art_obj->getErrorMessage());
269 * Returns the list of projects of the user.
270 * @todo fix this method.
272 public function getProjectsList() {
273 $uM = UserManager::instance();
274 $pM = ProjectManager::instance();
275 $user = $uM->getCurrentUser();
276 if($user->getId() != 0) {
277 $project_ids = $user->getProjects();
279 return $this->createProjectsArray($pM->getAllPublicProjects());
281 foreach($project_ids as $id) {
282 $projects[$id] = $pM->getProject($id);
285 return $this->createProjectsArray($projects);
289 * Converts projects objects into a single projects array.
290 * We only set the id and the public name of each project
292 * @param array $projects array of projects indexed by their relative ids
294 private function createProjectsArray($projects) {
296 foreach($projects as $prj_idx => $project){
297 $return[$prj_idx] = array(
299 'name' => $project->getPublicName()
306 * updateArtifact - update the artifact $artifact_id in tracker $tracker_id of the project $group_id with given values
308 * @param string $sessionKey the session hash associated with the session opened by the person who calls the service
309 * @param int $group_id the ID of the group we want to update the artifact
310 * @param int $tracker_id the ID of the tracker we want to update the artifact
311 * @param int $artifact_id the ID of the artifact to update
312 * @param array{SOAPArtifactFieldValue} $value the fields value to update
313 * @param string $comment the comment associated with the modification, or null if no follow-up comment.
315 * @return int The artifact id if update was fine,
316 * or a soap fault if :
317 * - group_id does not match with a valid project,
318 * - tracker_id does not match with a valid tracker,
319 * - artifact_id does not match with a valid artifact,
320 * - the given values are breaking a field dependency rule
321 * - the artifact modification failed.
323 function updateArtifact($sessionKey, $group_id, $tracker_id, $artifact_id, $value, $comment) {
324 if (session_continue($sessionKey)) {
325 $user = UserManager::instance()->getCurrentUser();
326 $pm = ProjectManager::instance();
327 $project = $pm->getProject($group_id);
328 if (! $project || ! is_object($project)) {
329 return new SoapFault(get_group_fault,'Could Not Get Group','updateArtifact');
330 } elseif ($project->isError()) {
331 return new SoapFault(get_group_fault, $project->getErrorMessage(),'updateArtifact');
333 if ( ! checkRestrictedAccess($project)) {
334 return new SoapFault(get_group_fault, 'Restricted user: permission denied.', 'updateArtifact');
337 $tf = TrackerFactory::instance();
338 $tracker = $tf->getTrackerById($tracker_id);
339 if ($tracker == null) {
340 return new SoapFault(get_tracker_fault, 'Could not get Tracker.', 'updateArtifact');
341 } elseif ($tracker->getGroupId() != $group_id) {
342 return new SoapFault(get_tracker_fault, 'Could not get Tracker.', 'updateArtifact');
345 $af = Tracker_ArtifactFactory::instance();
346 if ($artifact = $af->getArtifactById($artifact_id)) {
347 if ($artifact->getTrackerId() != $tracker_id) {
348 return new SoapFault(get_tracker_fault, 'Could not get Artifact.', 'updateArtifact');
351 //Check Field Dependencies
352 // TODO : implement it
353 /*require_once('common/tracker/ArtifactRulesManager.class.php');
354 $arm =& new ArtifactRulesManager();
355 if (!$arm->validate($ath->getID(), $data, $art_field_fact)) {
356 return new SoapFault(invalid_field_dependency_fault, 'Invalid Field Dependency', 'updateArtifact');
359 $fef = Tracker_FormElementFactory::instance();
361 $fields_data = array();
362 foreach ($value as $field_value) {
363 // field are identified by name, we need to retrieve the field id
364 if ($field_value->field_name) {
366 $field = $fef->getUsedFieldByName($tracker_id, $field_value->field_name);
369 $field_data = $field->getFieldData($field_value->field_value);
370 if ($field_data != null) {
371 // $field_value is an object: SOAP must cast it in ArtifactFieldValue
372 if (isset($fields_data[$field->getId()])) {
373 if ( ! is_array($fields_data[$field->getId()]) ) {
374 $fields_data[$field->getId()] = array($fields_data[$field->getId()]);
376 $fields_data[$field->getId()][] = $field_data;
378 $fields_data[$field->getId()] = $field_data;
381 return new SoapFault(update_artifact_fault, 'Unknown value ' . $field_value->field_value . ' for field: '.$field_value->field_name ,'addArtifact');
384 return new SoapFault(update_artifact_fault, 'Unknown field: '.$field_value->field_name ,'addArtifact');
389 if ($artifact->createNewChangeset($fields_data, $comment, $user, null)) {
392 $response = new Response();
393 if ($response->feedbackHasErrors()) {
394 return new SoapFault(update_artifact_fault, $response->getRawFeedback(),'updateArtifact');
396 return new SoapFault(update_artifact_fault, 'Unknown error','updateArtifact');
400 return new SoapFault(get_tracker_fault, 'Could not get Artifact.', 'updateArtifact');
404 return new SoapFault(invalid_session_fault,'Invalid Session ','updateArtifact');