3 * Copyright (C) 2013 Vitaliy Pylypiv <vitaliy.pylypiv@gmail.com>
4 * Copyright 2016, Stéphane-Eymeric Bredtthauer - TrivialDev
6 * This file is part of FusionForge.
8 * FusionForge is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published
10 * by the Free Software Foundation; either version 2 of the License,
11 * or (at your option) any later version.
13 * FusionForge is distributed in the hope that it will be useful, but
14 * WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * General Public License for more details.
18 * You should have received a copy of the GNU General Public License along
19 * with this program; if not, write to the Free Software Foundation, Inc.,
20 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
23 define('RELEASE_OF_TASK', 1);
24 define('RELEASE_OF_USER_STORY', 2);
26 require_once $gfcommon.'include/FFError.class.php';
27 require_once $gfplugins.'taskboard/common/TaskBoardColumn.class.php';
28 require_once $gfplugins.'taskboard/common/TaskBoardRelease.class.php';
31 * Factory method which creates a taskboard from a taskboard ID
33 * @param int The taskboard ID
34 * @param array The result array, if it's passed in
35 * @return object TaskBoard object
37 function &taskboard_get_object($taskboard_id, $data = false) {
38 static $trackers = array();
40 if( !array_key_exists($taskboard_id, $trackers)) {
41 $res = db_query_params('SELECT * FROM plugin_taskboard WHERE taskboard_id=$1', array($taskboard_id));
42 if (db_numrows($res) <1) {
45 $data = db_fetch_array($res);
47 $Group = group_get_object($data['group_id']);
48 $trackers[$taskboard_id] = new TaskBoard($Group, $data);
50 return $trackers[$taskboard_id];
54 * Initialize a task board
56 function &taskboard_init($group_id) {
58 $res = db_query_params('INSERT INTO plugin_taskboard(group_id) VALUES($1)', array($group_id));
60 $this->setError(db_error());
64 $taskboard_id=db_insertid($res,'plugin_taskboard','taskboard_id');
65 if ($taskboard_id==0) {
69 $Group = group_get_object($group_id);
74 $Taskboard = new TaskBoard($Group, $taskboard_id);
84 class TaskBoard extends FFError {
93 * Trackers adapter object
100 * Array of taskboard data.
102 * @var array $data_array.
106 function TaskBoard($Group, $data = false) {
107 parent::__construct();
108 if (!$Group || !is_object($Group)) {
109 $this->setError(_('Invalid Project'));
112 if ($Group->isError()) {
113 $this->setError(_('Task Board')._(': ').$Group->getErrorMessage());
117 $this->Group = $Group;
120 if (is_array($data)) {
121 $this->data_array =& $data;
122 if ($this->data_array['group_id'] != $this->Group->getID()) {
123 $this->setError('Group_id in db result does not match Group Object');
124 $this->data_array = null;
128 $this->fetchData($data);
132 $plugins_taskboard_trackers_adapter_class = forge_get_config('trackers_adapter_class', 'taskboard');
133 if( !isset($plugins_taskboard_trackers_adapter_class) ) {
134 $plugins_taskboard_trackers_adapter_class = 'TaskBoardBasicAdapter';
137 $plugins_taskboard_trackers_adapter_module = $gfplugins.'taskboard/common/adapters/' . $plugins_taskboard_trackers_adapter_class . '.class.php';
139 require_once( $plugins_taskboard_trackers_adapter_module );
140 $this->TrackersAdapter = new $plugins_taskboard_trackers_adapter_class( $this );
145 * create - create a row in the taskboards table
147 * @param array list of trackers IDs, linked to the taskboard
148 * @param array has of card background colors (key - tracker id, value - bg color)
149 * @param string Alias for of 'select' extra field used for release/sprint
150 * @param string Tracker type of extra field used for release/sprint (1 - task trackers, 2 - user story tracker)
151 * @param string Used for cost calculations together with remaining_cost_field_alias if specified
152 * @param string Used for cost calculations together with estimated_cost_field_alias if specified
154 * @return true on success / false on failure.
156 function create($name, $description = '', $trackers = array(), $bgcolors = array(), $release_field_alias = NULL, $release_field_tracker = 1,
157 $estimated_cost_field_alias = NULL, $remaining_cost_field_alias = '',
158 $user_stories_tracker = NULL, $user_stories_reference_field = NULL,
159 $user_stories_sort_field = NULL, $first_column_by_default = 1) {
161 //$estimated_cost_field = ''; // TODO define alias by default in configuration file
162 //$remaining_cost_field = ''; // TODO define alias by default in configuration file
163 //$user_stories_reference_field = ''; // TODO define alias by default in configuration file
164 //$user_stories_sort_field = ''; // TODO define alias by default in configuration file
169 if (!session_loggedin()) {
170 $this->setError(_('Must Be Logged In'));
176 $res = db_query_params(
177 'INSERT INTO plugin_taskboard(taskboard_name, description, group_id, release_field_alias, release_field_tracker, estimated_cost_field_alias,
178 remaining_cost_field_alias, user_stories_group_artifact_id, user_stories_reference_field_alias,user_stories_sort_field_alias,
179 first_column_by_default) VALUES($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11)',
180 array($name, $description, $this->Group->getID(), $release_field_alias, $release_field_tracker, $estimated_cost_field_alias,
181 $remaining_cost_field_alias, ( $user_stories_tracker ? $user_stories_tracker: NULL ),
182 $user_stories_reference_field, $user_stories_sort_field, $first_column_by_default)
185 $this->setError(_('Cannot create Task Board'));
188 $this->data_array['taskboard_id'] = db_insertid($res,'plugin_taskboard','taskboard_id');
191 if( $ret && is_array($trackers)) {
192 foreach( $trackers as $tracker_id ) {
193 $ret = $this->addUsedTracker( $tracker_id, ( array_key_exists($tracker_id, $bgcolors) ? $bgcolors[$tracker_id] : NULL) );
197 // TODO columns initialization
203 $this->data_array['taskboard_id'] = NULL;
210 * update - update a row in the taskboards table
212 * @param array list of trackers IDs, linked to the taskboard
213 * @param array has of card background colors (key - tracker id, value - bg color)
214 * @param string Alias for of 'select' extra field used for release/sprint
215 * @param string Tracke type of extra field used for release/sprint (1 - task trackers, 2 - user story tracker)
216 * @param string Used for cost calculations together with remaining_cost_field_alias if specified
217 * @param string Used for cost calculations together with estimated_cost_field_alias if specified
219 * @return true on success / false on failure.
221 function update($name, $description, $trackers=array(), $bgcolors=array(), $release_field_alias = NULL, $release_field_tracker = 1,
222 $estimated_cost_field_alias = NULL, $remaining_cost_field_alias = NULL,
223 $user_stories_tracker = NULL, $user_stories_reference_field = NULL, $user_stories_sort_field = NULL, $first_column_by_default = 1 ) {
227 if (!session_loggedin()) {
228 $this->setError(_('Must Be Logged In'));
232 if ($name!=$this->getName() || $description!=$this->getDescription()) {
233 $updateOnlyName = true;
235 $updateOnlyName = false;
238 if( count($trackers) == 0 && !$updateOnlyName) {
239 $this->setError(_('Task Board must be linked at least to one tracker'));
245 if($updateOnlyName) {
246 $res = db_query_params(
247 'UPDATE plugin_taskboard SET taskboard_name=$1, description=$2 WHERE taskboard_id=$3',
248 array($name, $description, $this->getID()));
250 $res = db_query_params(
251 'UPDATE plugin_taskboard SET taskboard_name=$1, description=$2, release_field_alias=$3, release_field_tracker=$4,
252 estimated_cost_field_alias=$5, remaining_cost_field_alias=$6, user_stories_group_artifact_id=$7,
253 user_stories_reference_field_alias=$8, user_stories_sort_field_alias=$9,
254 first_column_by_default=$10 WHERE taskboard_id=$11',
256 $name, $description, $release_field_alias, $release_field_tracker ,
257 $estimated_cost_field_alias, $remaining_cost_field_alias, ( $user_stories_tracker ? $user_stories_tracker: NULL),
258 $user_stories_reference_field, $user_stories_sort_field,
259 $first_column_by_default, $this->getID())
263 $this->setError(_('Cannot update Task Board'));
270 if($ret && !$updateOnlyName) {
271 $old_trackers = $this->getUsedTrackersIds();
272 foreach($trackers as $tracker_id) {
273 if(in_array($tracker_id, $old_trackers)) {
275 $ret = $this->updateUsedTracker(
277 (array_key_exists($tracker_id, $bgcolors) ? $bgcolors[$tracker_id] : NULL)
281 $ret = $this->addUsedTracker(
283 (array_key_exists($tracker_id, $bgcolors) ? $bgcolors[$tracker_id] : NULL)
288 foreach($old_trackers as $tracker_id){
289 if(!in_array($tracker_id, $trackers)) {
290 $ret = $this->deleteUsedTracker($tracker_id);
299 $this->data_array['taskboard_id'] = NULL;
307 * delete - delete taskboard
312 $res = db_query_params('DELETE FROM plugin_taskboard WHERE taskboard_id = $1', array($this->getID()));
314 $this->setError(_('Task Board')._(': ')._('Cannot delete Task Board'));
321 * _checkExtraFields() - check where extra field exists in the tracker
324 private function _checkExtraFields($group_artifacts, $alias) {
327 /* TODO How to get ArtifactType objects ?
328 foreach($group_artifacts as $group_artifacts) {
337 * fetchData - re-fetch the data for this TaskBoard from the database.
339 * @param int The taskboard ID.
340 * @return boolean success.
342 function fetchData($taskboard_id = NULL) {
344 $taskboard_id = $this->getID();
346 $res = db_query_params('SELECT * FROM plugin_taskboard WHERE taskboard_id=$1', array($taskboard_id));
347 if (!$res || db_numrows($res) < 1) {
348 $this->setError(_('Task Board')._(': ')._('Invalid TaskBoardID'));
351 $this->data_array = db_fetch_array($res);
352 db_free_result($res);
357 * getID - get this TaskBoardID.
359 * @return int The taskboard_id
362 return $this->data_array['taskboard_id'];
366 * getName - get this TaskBoard Name.
368 * @return string The taskboard_name
371 return $this->data_array['taskboard_name'];
375 * getDescription - get this TaskBoard Description.
377 * @return string The taskboard description
379 function getDescription() {
380 return $this->data_array['description'];
384 * getReleaseField - get alias of field, used for release/sprint
386 * @return string extra field alias
388 function getReleaseField() {
389 return $this->data_array['release_field_alias'];
393 * getReleaseFieldTracker - get a source tracker type of field, used for release/sprint
395 * @return integer 1 - tasks tracker, 2 - user story tracker
397 function getReleaseFieldTracker() {
398 return $this->data_array['release_field_tracker'];
402 * getEstimatedCostField - get alias of field, used for estimated cost value
404 * @return string extra field alias
406 function getEstimatedCostField() {
407 return $this->data_array['estimated_cost_field_alias'];
411 * getRemainingCostField - get alias of field, used for remaining cost value
413 * @return string extra field alias
415 function getRemainingCostField() {
416 return $this->data_array['remaining_cost_field_alias'];
420 * getUserStoriesTrackerID - get identifier of tracker, used for user stories
422 * @return integer tracker identifier
424 function getUserStoriesTrackerID() {
425 return $this->data_array['user_stories_group_artifact_id'];
429 * getUserStoriesReferenceField - get alias of field, used as a reference to user stiry artifact
431 * @return string extra field alias
433 function getUserStoriesReferenceField() {
434 return $this->data_array['user_stories_reference_field_alias'];
438 * getUserStoriesSortField - get alias of field, used as for user stories sorting (DESC)
440 * @return string extra field alias
442 function getUserStoriesSortField() {
443 return $this->data_array['user_stories_sort_field_alias'];
447 * getFirstColumnByDefault
451 function getFirstColumnByDefault() {
452 return $this->data_array['first_column_by_default'];
457 * getUsedTrackersIds - get identifiers of used trackers
461 function getUsedTrackersIds() {
462 $res = db_query_params('SELECT * FROM plugin_taskboard_trackers WHERE taskboard_id = $1', array ($this->getID()));
464 $this->setError(_('Task Board')._(': ')._('Cannot get list of used trackers.'));
469 while($row = db_fetch_array($res)) {
470 $trackers[] = $row['group_artifact_id'];
472 db_free_result($res);
477 * getUsedTrackersiData - get data of used trackers
481 function getUsedTrackersData() {
482 $res = db_query_params('SELECT * FROM plugin_taskboard_trackers WHERE taskboard_id = $1', array ($this->getID()));
484 $this->setError(_('Task Board')._(': ')._('Cannot get list of used trackers.'));
489 while( $row = db_fetch_array($res)) {
492 db_free_result($res);
497 * cleanUsedTrackers - empty list of trackers, used with taskboard
501 function cleanUsedTrackers() {
502 $res = db_query_params('DELETE FROM plugin_taskboard_trackers WHERE taskboard_id = $1', array ($this->getID()));
504 $this->setError(_('Task Board')._(': ')._('Cannot empty list of used trackers.'));
512 * addUsedTracker - add a tracker to use with taskboard
514 * @param int tracker identifier
515 * @param string optional card background color
519 function addUsedTracker($tracker_id, $bgcolor='') {
520 $res = db_query_params('INSERT INTO plugin_taskboard_trackers(taskboard_id, group_artifact_id, card_background_color) VALUES($1, $2, $3)', array($this->getID(), $tracker_id, $bgcolor));
522 $this->setError(_('Task Board')._(': ')._('Cannot add used tracker'));
530 * updateUsedTracker - update used tracker
532 * @param int tracker identifier
533 * @param string optional card background color
537 function updateUsedTracker($tracker_id, $bgcolor = '') {
538 $res = db_query_params('UPDATE plugin_taskboard_trackers SET card_background_color = $1 WHERE group_artifact_id = $2', array($bgcolor, $tracker_id));
540 $this->setError(_('Task Board')._(': ')._('Cannot update used tracker'));
548 * deleteUsedTracker - delete used tracker
550 * @param int tracker identifier
554 function deleteUsedTracker($tracker_id) {
555 $res = db_query_params('DELETE FROM plugin_taskboard_trackers WHERE group_artifact_id = $1', array($tracker_id));
557 $this->setError(_('Task Board')._(': ')._('Cannot delete used tracker'));
565 * getUserStories - get taskboard user stories
569 function getUserStories($release = NULL, $assigned_to = NULL) {
573 'title' => _('Unlinked tasks'),
574 'description' => _('Tasks, which are not linked to any user story'),
580 if($this->getReleaseFieldTracker() == RELEASE_OF_USER_STORY) {
581 $tasks_trackers = $this->getUsedTrackersData();
582 foreach($tasks_trackers as $tasks_tracker_data) {
583 $tasks = $this->TrackersAdapter->getTasks($tasks_tracker_data['group_artifact_id'], $assigned_to, NULL, NULL);
585 $this->setError($this->TrackersAdapter->getErrorMessage());
588 foreach($tasks as $task) {
589 $task_maped = $this->getMappedTask($task);
590 if ($task_maped['user_story']==0) {
591 $stories[0]['tasks'][] = $task_maped;
597 $user_stories_sort_field = $this->getUserStoriesSortField();
598 $user_stories_sort_extra_field_id = NULL;
599 if ($user_stories_sort_field) {
600 $ef = $this->TrackersAdapter->getFieldsIds($this->getUserStoriesTrackerID());
601 if ( array_key_exists($user_stories_sort_field ,$ef) ) {
602 $user_stories_sort_extra_field_id = $ef[ $user_stories_sort_field ];
604 $this->setError(_('Configured extra field for userstories sorting is not found.'));
609 $task_release = NULL;
610 $user_story_release = NULL;
612 if ($this->getReleaseFieldTracker() == RELEASE_OF_TASK) {
613 $task_release = $release;
615 $user_story_release = $release;
618 $us = $this->TrackersAdapter->getUserStories($release);
620 foreach($us as $story) {
621 $stories[$story->getID()] = array(
622 'id' => $story->getID(),
623 'title' => $story->getSummary(),
624 'description' => str_replace("\n", '<br>', util_gen_cross_ref($story->getDetails(),$this->Group->getID())),
625 'priority' => $story->getPriority(),
627 'url' => $this->TrackersAdapter->getTaskUrl($story)
630 if ($user_stories_sort_extra_field_id) {
631 $efd = $story ->getExtraFieldData();
632 $stories[$story->getID()]['order'] = $efd[$user_stories_sort_extra_field_id];
634 //sort by GF priority if another field for sorting is not defined
635 $stories[$story->getID()]['order'] = $stories[$story->getID()]['priority'];
638 if($this->getReleaseFieldTracker() == RELEASE_OF_USER_STORY) {
639 $tasks_trackers = $this->getUsedTrackersData();
640 foreach($tasks_trackers as $tasks_tracker_data) {
641 $tasks = $this->TrackersAdapter->getTasks($tasks_tracker_data['group_artifact_id'], $assigned_to, NULL, $story->getID());
642 foreach($tasks as $task) {
643 $stories[$story->getID()]['tasks'][] = $this->getMappedTask($task);;
649 if ($this->getReleaseFieldTracker() == RELEASE_OF_TASK) {
650 $tasks_trackers = $this->getUsedTrackersData();
651 foreach($tasks_trackers as $tasks_tracker_data) {
652 $tasks = $this->TrackersAdapter->getTasks($tasks_tracker_data['group_artifact_id'], $assigned_to, $task_release);
653 foreach($tasks as $task) {
654 $task_maped = $this->getMappedTask($task);
655 $stories[intval($task_maped['user_story'])]['tasks'][] = $task_maped;
660 $ret_stories = array_values($stories);
661 usort($ret_stories, array($this, 'sortUserStories'));
667 * getMappedTask - map artifact object into hash and add column and presentation specific fields
669 * @param Artifact artifact instance
673 function getMappedTask($task) {
674 static $_used_trackers_data = NULL;
675 static $_first_column_id = NULL;
677 if (!$_used_trackers_data) {
678 foreach($this->getUsedTrackersData() as $tasks_tracker_data) {
679 $_used_trackers_data[ $tasks_tracker_data['group_artifact_id'] ] = $tasks_tracker_data;
683 $task_maped = $this->_mapTask($task);
684 $column = taskboard_column_get_object_by_resolution($this, $task_maped['resolution']);
686 $task_maped['phase_id'] = $column->getID();
688 if($this->getFirstColumnByDefault()) {
689 if(!$_first_column_id) {
690 $columns = $this->getColumns();
691 $_first_column_id = $columns[0]->getID();
693 $task_maped['phase_id'] = $_first_column_id;
697 $card_title_background = $_used_trackers_data[$task->ArtifactType->getID()]['card_background_color'];
698 if( method_exists($this->TrackersAdapter, 'cardBackgroundColor' ) ) {
699 $task_maped['background'] = $this->TrackersAdapter->cardBackgroundColor($task, $card_title_background );
701 $task_maped['background'] = $card_title_background;
707 function sortUserStories($u1, $u2) {
710 usort( $u1['tasks'], array( $this, 'sortUserStoryTasks' ) );
712 if (!array_key_exists('order', $u1)) {
714 } elseif (!array_key_exists('order', $u2)) {
716 } elseif ($u1['order'] < $u2['order']) {
718 } elseif ($u1['order'] > $u2['order']) {
725 function sortUserStoryTasks($t1, $t2) {
728 if ($t1['priority'] < $t2['priority'] ) {
730 } elseif ( $t1['priority'] > $t2['priority'] ) {
737 function getMandatoryFieldsMapping() {
739 'resolution' => 'resolution',
740 'estimated_dev_effort' => $this->getEstimatedCostField(),
741 'remaining_dev_effort' => $this->getRemainingCostField(),
742 'user_story' => $this->getUserStoriesReferenceField()
747 * _mapTask - map artifact object into hash
749 * @param Artifact artifact instance
753 private function _mapTask($task) {
756 $ef_mapping = $this->getMandatoryFieldsMapping();
758 $fields_ids = $this->TrackersAdapter->getFieldsIds($task->ArtifactType->getID());
759 $extra_data = $task->getExtraFieldDataText();
761 $ret['id'] = $task->getID();
762 $ret['title'] = $task->getSummary();
763 $ret['description'] = str_replace("\n", '<br>', util_gen_cross_ref($task->getDetails(),$this->Group->getID()) );
764 $ret['assigned_to'] = $task->getAssignedRealName();
765 $ret['priority'] = $task->getPriority();
766 foreach( $ef_mapping as $k => $f){
768 if (array_key_exists($f, $fields_ids)) {
769 if (array_key_exists($fields_ids[$f], $extra_data)) {
770 $ret[$k] = $extra_data[$fields_ids[$f]]['value'];
775 if (!$ret['user_story']) {
776 // task is not assigend to any user story
777 $ret['user_story'] = 0;
780 $ret['url'] = $this->TrackersAdapter->getTaskUrl($task);
782 $params = array('user_id' => $task->getAssignedTo(), 'size' => 's', 'content' => '');
783 plugin_hook_by_reference("user_logo", $params);
784 if ($params['content']) {
785 $ret['assigned_to_face'] = $params['content'];
787 $ret['assigned_to_face'] = '';
794 * getColumns - get taskboard columns
798 function getColumns() {
799 $res = db_query_params('SELECT * FROM plugin_taskboard_columns WHERE taskboard_id=$1 ORDER BY order_num', array ($this->getID()));
801 $this->setError(_('Task Board')._(': ')._('Cannot get list of columns.'));
806 while($row = db_fetch_array($res)) {
807 $columns[] = new TaskBoardColumn($this, $row);
809 db_free_result($res);
814 * addColumn - add taskboard column
818 function addColumn($title, $title_bg_color, $column_bg_color, $max_tasks) {
821 $res = db_query_params('SELECT COUNT(*) as count FROM plugin_taskboard_columns WHERE taskboard_id=$1', array ($this->getID()));
826 $row = db_fetch_array($res);
827 $order = intval($row['count']) + 1;
828 db_free_result($res);
830 $res = db_query_params(
831 'INSERT INTO plugin_taskboard_columns(taskboard_id, title, title_background_color, column_background_color, max_tasks, order_num) VALUES($1,$2,$3,$4,$5,$6)',
844 $column_id = db_insertid($res, 'plugin_taskboard_columns', 'taskboard_column_id');
845 db_free_result($res);
851 * getExtraFields - get a list of extra fields, existing is all used task trackers
853 * @param array list of allowed extra fields types
854 * @param array list of excluded aliases
856 * @return array array of aliases
858 function getExtraFields($allowed_types = array(), $used_trackers = NULL, $excluded_aliases = array('resolution')) {
859 $atf = $this->TrackersAdapter->getArtifactTypeFactory();
860 if (!$atf || !is_object($atf) || $atf->isError()) {
861 return _('Could Not Get ArtifactTypeFactory');
864 if (!$used_trackers) {
865 $used_trackers = $this->getUsedTrackersIds();
868 $common_fields = array();
870 foreach ($allowed_types as $allowed_type) {
871 $common_fields[$allowed_type] = array();
874 $at_arr = $atf->getArtifactTypes();
876 for ($j = 0; $j < count($at_arr); $j++) {
877 if (!is_object($at_arr[$j])) {
879 } elseif ($at_arr[$j]->isError()) {
880 return $at_arr[$j]->getErrorMessage();
882 $tracker_id = $at_arr[$j]->getID();
884 if (in_array($tracker_id, $used_trackers)) {
885 // select common fields for the give types
886 $fields = $at_arr[$j]->getExtraFields($allowed_types);
888 foreach ($allowed_types as $allowed_type) {
889 $tmp[$allowed_type] = array();
892 foreach ($fields as $field) {
893 // exclude 'resolution' field
894 if (!in_array($field['alias'],$excluded_aliases)) {
896 if (in_array($field['field_type'], $allowed_types)) {
897 $tmp[$field['field_type']][$field['alias']] = $field['field_name'];
900 in_array($field['alias'], array_keys($common_fields[$field['field_type']])) &&
901 in_array($field['field_type'], $allowed_types)
903 $tmp[$field['field_type']][$field['alias']] = $field['field_name'];
907 $common_fields = $tmp;
912 return $common_fields;
916 * getExtraFieldValues - get hash of values, available for the given extra field
918 * @param string extra field alias
920 * @return array hash element_name => element_id
922 function getExtraFieldValues($extra_field_alias) {
925 $tasks_trackers = $this->getUsedTrackersIds();
926 foreach($tasks_trackers as $tracker_id) {
927 $ef_values = $this->TrackersAdapter->getExtraFieldValues($tracker_id, $extra_field_alias);
928 if (count($ret) == 0) {
932 foreach($ret as $name => $id) {
933 if( array_key_exists($name, $ef_values)) {
945 * getReleases - get taskboard releases
949 function getReleases() {
950 $res = db_query_params('SELECT * FROM plugin_taskboard_releases WHERE taskboard_id = $1 ORDER BY start_date, end_date', array($this->getID()));
952 $this->setError(_('Task Board')._(': ')._('Cannot get list of releases.'));
957 while( $row = db_fetch_array($res)) {
958 $releases[] = new TaskBoardRelease($this, $row);
960 db_free_result($res);
965 * getCurrentRelease - get current or the most recent release object
969 function getCurrentRelease() {
970 $current_release = NULL;
972 $res = db_query_params (
973 'SELECT * FROM plugin_taskboard_releases WHERE taskboard_id=$1 AND start_date < $2 ORDER BY start_date DESC LIMIT 1',
976 strtotime(date('Y-m-d'))
980 $this->setError(_('Task Board')._(': ')._('Cannot get current release.'));
983 $row = db_fetch_array($res);
985 $current_release = new TaskBoardRelease($this, $row);
988 db_free_result($res);
990 return $current_release;
994 * getReleaseValues - get list of all available reslease values
998 function getReleaseValues() {
1001 if ($this->getReleaseFieldTracker() == 1) {
1002 // get values from tasks trackers
1003 $ret = $this->getExtraFieldValues($this->getReleaseField());
1005 // get values from user stories trackers
1006 $ret = $this->TrackersAdapter->getExtraFieldValues($this->getUserStoriesTrackerID(), $this->getReleaseField());
1013 * getAvailableResolutions - get list of all available resolution values
1017 function getAvailableResolutions() {
1018 return array_keys($this->getExtraFieldValues('resolution'));
1022 * getUsedResolutions - get list of resolutions that are already used with taskboard columns
1026 function getUsedResolutions() {
1027 $res = db_query_params(
1028 'SELECT R.* FROM plugin_taskboard_columns_resolutions as R, plugin_taskboard_columns as C
1029 WHERE C.taskboard_id=$1 AND R.taskboard_column_id=C.taskboard_column_id',
1030 array($this->getID())
1033 $this->setError(_('Task Board')._(': ')._('Cannot get used resolutions'));
1037 $resolutions= array();
1038 while($row = db_fetch_array($res)) {
1039 $resolutions[$row['taskboard_column_resolution']] = $row['taskboard_column_resolution'];
1041 db_free_result($res);
1043 return array_keys($resolutions);
1047 * getUnusedResolutions - get list of resolutions that are not used with taskboard columns
1051 function getUnusedResolutions() {
1052 static $resolutions = NULL;
1054 if( !$resolutions ) {
1055 $all_resolutions = $this->getAvailableResolutions();
1056 $used_resolutions = $this->getUsedResolutions();
1058 $resolutions = array();
1059 if( $all_resolutions && count( $used_resolutions ) > 0 ) {
1060 $resolutions = array_diff( $all_resolutions, $used_resolutions );
1062 $resolutions = $all_resolutions;
1066 return $resolutions;