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';
33 class CodendiOSLCConnector extends OSLCConnector {
36 * Filter parameters provided in the REST GET request to check whether mandatory ones are set.
38 * @param array $params
41 public function filterRequestParams($params) {
42 // Process the args provided by Zend REST
43 if (is_array($params)) {
44 if(!isset($params['project'])) {
45 throw new Exception('Missing project id !');
46 } elseif(!isset($params['tracker'])) {
47 throw new Exception('Missing tracker id resource for project '.$params['project'].' !');
55 * Checks whether a change request exists inside Codendi trackers.
56 * @param int $id change request id.
59 public function checkChangeRequestExists($changerequest_id) {
60 $af = Tracker_ArtifactFactory::instance();
61 $artifact = $af->getArtifactById($changerequest_id);
70 * Constructs the model from Codendi DB by fetching the requested changeRequests.
72 * @param array $params contains 'project' + 'tracker'
74 public function fetchChangeRequests($params) {
77 // what the DB will be queried on
81 if (isset($params['project'])) {
82 $group_id = $params['project'];
84 if (isset($params['tracker'])) {
85 $tracker_id = $params['tracker'];
87 if (isset($params['bug'])) {
88 $changerequest_id = $params['bug'];
89 $af = Tracker_ArtifactFactory::instance();
90 $changeRequest = $af->getArtifactById($changerequest_id);
91 $this->changerequests = new ChangeRequestsFusionForgeDb($changeRequest);
94 $project = group_get_object($group_id);
95 if (!$project->usesService('tracker')) {
96 throw new Exception('Error : Tracker service is not used for this project.', 'fetchChangeRequests');
99 $tf = TrackerFactory::instance();
101 throw new Exception('Error : Could Not Get TrackerFactory', 'fetchChangeRequests');
104 $tracker = $tf->getTrackerById($tracker_id);
106 if ($tracker == null) {
107 throw new Exception('Error : Could Not Get Tracker', 'fetchChangeRequests');
109 $af = Tracker_ArtifactFactory::instance();
110 $artifacts = $af->getArtifactsByTrackerId($tracker_id);
113 // instanciate the model from the returned artifacts
114 if(isset($params['fields'])){
115 $this->changerequests = new ChangeRequestsCodendiDb($artifacts, $params['fields']);
117 $this->changerequests = new ChangeRequestsCodendiDb($artifacts);
121 public function fetchChangeRequest($changerequest_id, $uri, $requested_fields=array()) {
122 $af = Tracker_ArtifactFactory::instance();
123 $artifact = $af->getArtifactById($changerequest_id);
126 throw new NotFoundException('Error : Change Request not found', 'fetchChangeRequest' );
128 $art = array($artifact);
130 $changerequest = new ChangeRequestsCodendiDb($art, $requested_fields);
132 return $this->prepareChangeRequest($changerequest[$changerequest_id], $uri);
136 * Updates an existant Codendi ChangeRequest in the tracker DataBase.
137 * @param int $identifier id of the ChangeRequest within Codendi tracker
138 * @param ChangeRequest the change request given as input for the PUT request.
139 * @param array $props array of the properties that PUT request is going to change
140 * @return boolean true if success, false otherwise.
142 public function updateChangeRequest($changerequest_id, $group_id, $tracker_id, $changerequest, $props) {
143 $project = group_get_object($group_id);
144 if (! $project || ! is_object($project)) {
145 throw new Exception('Error : Could Not Get Group','updateChangeRequest');
146 } elseif ($project->isError()) {
147 throw new Exception('Error : ' . $project->getErrorMessage(),'updateChangeRequest');
149 if ( ! checkRestrictedAccess($project)) {
150 throw new Exception('Error, Restricted user: permission denied.', 'updateChangeRequest');
153 $tf = TrackerFactory::instance();
154 $tracker = $tf->getTrackerById($tracker_id);
156 if ($tracker == null) {
157 throw new Exception('Error : Could not get Tracker.', 'updateChangeRequest');
158 } elseif ($tracker->getGroupId() != $group_id) {
159 throw new Exception('Error : Could not get Tracker.', 'updateChangeRequest');
162 $af = Tracker_ArtifactFactory::instance();
163 if ($artifact = $af->getArtifactById($changerequest_id)) {
164 if ($artifact->getTrackerId() != $tracker_id) {
165 throw new Exception('Error : Could not get Artifact.', 'updateChangeRequest');
169 // Get the artifact data using its ID.
170 $art_obj =& artifact_get_object($identifier);
171 $art = $art_obj->data_array;
173 $cm_request = $changerequest->container;
175 $terms = array('dc:','helios_bt:');
176 foreach($props as &$prop) {
177 $prop = str_replace($terms,"",$prop);
181 // Check all the mandatory fields for an artifact update request.
183 // dc:title ===> summary
184 if(in_array('title',$props)) {
185 if(isset($cm_request['title'])) {
186 $art['summary'] = $cm_request['title']; // mandatory
188 throw new BadRequestException("dc:title mentioned in the request query not found in request body!");
192 // dc:description ===> details
193 if(in_array('description',$props)) {
194 if(isset($cm_request['description'])) {
195 $art['details'] = $cm_request['description']; // mandatory
197 throw new BadRequestException("dc:decription mentioned in the request query not found in request body!");
201 // helios_bt:priority ===> priority
202 if(in_array('priority',$props)) {
203 if(isset($cm_request['priority'])) {
204 $art['priority'] = $cm_request['priority']; // mandatory
206 throw new BadRequestException("helios_bt:priority mentioned in the request query not found in request body!");
210 // helios_bt:status ===> status
211 if(in_array('status',$props)) {
212 if(isset($cm_request['status'])) {
213 $art['status_id'] = self::$status_arr[$cm_request['status']]; // mandatory
215 throw new BadRequestException("helios_bt:status mentioned in the request query not found in request body!");
219 //helios_bt:assigned_to ====> assigned_to
220 if(in_array('assigned_to', $props)) {
221 if(isset($cm_request['assigned_to'])) {
222 $art['assigned_to'] = $cm_request['assigned_to'];
224 throw new BadRequestException("helios_bt:assigned_to mentionned in the request query not found in request body!");
228 $canned_response=100;
230 // We assume that we don't change the artifact type (bug, task, etc)
232 $new_artifact_type_id = $art_obj->ArtifactType->getID();
234 //TODO: figure out if a follow up is in OSLC specs and if it is the case include it.
237 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'])) {
238 throw new Exception($art_obj->getErrorMessage());
243 * Returns the list of projects of the user.
244 * @todo fix this method.
246 public function getProjectsList() {
247 $user = session_get_user();
248 if($user->getId() != 0) {
249 $project_ids = $user->getProjects();
251 return $this->createProjectsArray(group_get_public_active_projects_asc());
253 foreach($project_ids as $id) {
254 $projects[$id] = group_get_object($id);
256 return $this->createProjectsArray($projects);
260 * Converts projects objects into a single projects array.
261 * We only set the id and the public name of each project
263 * @param array $projects array of projects indexed by their relative ids
265 private function createProjectsArray($projects) {
267 foreach($projects as $prj_idx => $project){
268 $return[$prj_idx] = array(
270 'name' => $project->getPublicName()
277 * updateArtifact - update the artifact $artifact_id in tracker $tracker_id of the project $group_id with given values
279 * @param string $sessionKey the session hash associated with the session opened by the person who calls the service
280 * @param int $group_id the ID of the group we want to update the artifact
281 * @param int $tracker_id the ID of the tracker we want to update the artifact
282 * @param int $artifact_id the ID of the artifact to update
283 * @param array{SOAPArtifactFieldValue} $value the fields value to update
284 * @param string $comment the comment associated with the modification, or null if no follow-up comment.
286 * @return int The artifact id if update was fine,
287 * or a soap fault if :
288 * - group_id does not match with a valid project,
289 * - tracker_id does not match with a valid tracker,
290 * - artifact_id does not match with a valid artifact,
291 * - the given values are breaking a field dependency rule
292 * - the artifact modification failed.
294 function updateArtifact($sessionKey, $group_id, $tracker_id, $artifact_id, $value, $comment) {
295 if (session_continue($sessionKey)) {
296 $user = session_get_user();
297 $project = group_get_object($group_id);
298 if (! $project || ! is_object($project)) {
299 return new SoapFault(get_group_fault,'Could Not Get Group','updateArtifact');
300 } elseif ($project->isError()) {
301 return new SoapFault(get_group_fault, $project->getErrorMessage(),'updateArtifact');
303 if ( ! checkRestrictedAccess($project)) {
304 return new SoapFault(get_group_fault, 'Restricted user: permission denied.', 'updateArtifact');
307 $tf = TrackerFactory::instance();
308 $tracker = $tf->getTrackerById($tracker_id);
309 if ($tracker == null) {
310 return new SoapFault(get_tracker_fault, 'Could not get Tracker.', 'updateArtifact');
311 } elseif ($tracker->getGroupId() != $group_id) {
312 return new SoapFault(get_tracker_fault, 'Could not get Tracker.', 'updateArtifact');
315 $af = Tracker_ArtifactFactory::instance();
316 if ($artifact = $af->getArtifactById($artifact_id)) {
317 if ($artifact->getTrackerId() != $tracker_id) {
318 return new SoapFault(get_tracker_fault, 'Could not get Artifact.', 'updateArtifact');
321 //Check Field Dependencies
322 // TODO : implement it
323 /*require_once('common/tracker/ArtifactRulesManager.class.php');
324 $arm =& new ArtifactRulesManager();
325 if (!$arm->validate($ath->getID(), $data, $art_field_fact)) {
326 return new SoapFault(invalid_field_dependency_fault, 'Invalid Field Dependency', 'updateArtifact');
329 $fef = Tracker_FormElementFactory::instance();
331 $fields_data = array();
332 foreach ($value as $field_value) {
333 // field are identified by name, we need to retrieve the field id
334 if ($field_value->field_name) {
336 $field = $fef->getUsedFieldByName($tracker_id, $field_value->field_name);
339 $field_data = $field->getFieldData($field_value->field_value);
340 if ($field_data != null) {
341 // $field_value is an object: SOAP must cast it in ArtifactFieldValue
342 if (isset($fields_data[$field->getId()])) {
343 if ( ! is_array($fields_data[$field->getId()]) ) {
344 $fields_data[$field->getId()] = array($fields_data[$field->getId()]);
346 $fields_data[$field->getId()][] = $field_data;
348 $fields_data[$field->getId()] = $field_data;
351 return new SoapFault(update_artifact_fault, 'Unknown value ' . $field_value->field_value . ' for field: '.$field_value->field_name ,'addArtifact');
354 return new SoapFault(update_artifact_fault, 'Unknown field: '.$field_value->field_name ,'addArtifact');
359 if ($artifact->createNewChangeset($fields_data, $comment, $user, null)) {
362 $response = new Response();
363 if ($response->feedbackHasErrors()) {
364 return new SoapFault(update_artifact_fault, $response->getRawFeedback(),'updateArtifact');
366 return new SoapFault(update_artifact_fault, 'Unknown error','updateArtifact');
370 return new SoapFault(get_tracker_fault, 'Could not get Artifact.', 'updateArtifact');
374 return new SoapFault(invalid_session_fault,'Invalid Session ','updateArtifact');