3 * Copyright (C) 2013 Vitaliy Pylypiv <vitaliy.pylypiv@gmail.com>
5 * This file is part of FusionForge.
7 * FusionForge is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published
9 * by the Free Software Foundation; either version 2 of the License,
10 * or (at your option) any later version.
12 * FusionForge is distributed in the hope that it will be useful, but
13 * WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * General Public License for more details.
17 * You should have received a copy of the GNU General Public License along
18 * with this program; if not, write to the Free Software Foundation, Inc.,
19 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
22 define('RELEASE_OF_TASK', 1);
23 define('RELEASE_OF_USER_STORY', 2);
25 require_once $gfcommon.'include/FFError.class.php';
26 require_once $gfplugins.'taskboard/common/TaskBoardColumn.class.php';
27 require_once $gfplugins.'taskboard/common/TaskBoardRelease.class.php';
30 * Factory method which creates a taskboard from a taskboard ID
32 * @param int The taskboard ID
33 * @param array The result array, if it's passed in
34 * @return object TaskBoard object
36 function &taskboard_get_object($taskboard_id, $data = false) {
37 static $trackers = array();
39 if( !array_key_exists($taskboard_id, $trackers)) {
40 $res = db_query_params('SELECT * FROM plugin_taskboard WHERE taskboard_id=$1', array($taskboard_id));
41 if (db_numrows($res) <1) {
44 $data = db_fetch_array($res);
46 $Group = group_get_object($data['group_id']);
47 $trackers[$taskboard_id] = new TaskBoard($Group, $data);
49 return $trackers[$taskboard_id];
53 * Initialize a task board
55 function &taskboard_init($group_id) {
56 $res = db_query_params('INSERT INTO plugin_taskboard(group_id) VALUES($1)', array($group_id));
61 $Group = group_get_object($data['group_id']);
63 $Taskboard = new TaskBoard($Group, $data);
68 class TaskBoard extends FFError {
77 * Trackers adapter object
84 * Array of artifact data.
86 * @var array $data_array.
90 function TaskBoard($Group, $arr = false) {
91 parent::__construct();
92 if (!$Group || !is_object($Group)) {
93 $this->setError(_('No Valid Group Object'));
96 if ($Group->isError()) {
97 $this->setError(_('Taskboard')._(': ').$Group->getErrorMessage());
101 $this->Group = $Group;
102 if (!$arr || !is_array($arr)) {
103 if (!$this->fetchDataByGroup()) {
107 $this->data_array =& $arr;
108 if ($this->data_array['group_id'] != $this->Group->getID()) {
109 $this->setError('Group_id in db result does not match Group Object');
110 $this->data_array = null;
115 $plugins_taskboard_trackers_adapter_class = forge_get_config('trackers_adapter_class', 'taskboard');
116 if( !isset($plugins_taskboard_trackers_adapter_class) ) {
117 $plugins_taskboard_trackers_adapter_class = 'TaskBoardBasicAdapter';
120 $plugins_taskboard_trackers_adapter_module = $gfplugins.'taskboard/common/adapters/' . $plugins_taskboard_trackers_adapter_class . '.class.php';
122 require_once( $plugins_taskboard_trackers_adapter_module );
123 $this->TrackersAdapter = new $plugins_taskboard_trackers_adapter_class( $this );
128 * create - create a row in the taskboards table
130 * @param array list of trackers IDs, linked to the taskboard
131 * @param array has of card background colors (key - tracker id, value - bg color)
132 * @param string Alias for of 'select' extra field used for release/sprint
133 * @param string Tracke type of extra field used for release/sprint (1 - task trackers, 2 - user story tracker)
134 * @param string Used for cost calculations together with remaining_cost_field_alias if specified
135 * @param string Used for cost calculations together with estimated_cost_field_alias if specified
137 * @return true on success / false on failure.
139 function create($trackers, $bgcolors, $release_field_alias = NULL, $release_field_tracker = 1,
140 $estimated_cost_field_alias = NULL, $remaining_cost_field_alias = NULL,
141 $user_stories_tracker = NULL, $user_stories_reference_field = NULL,
142 $user_stories_sort_field = NULL, $first_column_by_default = 1) {
146 if (!session_loggedin()) {
147 $this->setError(_('Must Be Logged In'));
151 if (count($trackers) == 0) {
152 $this->setError(_('Taskboard must be linked at least to one tracker'));
158 $res = db_query_params(
159 'INSERT INTO plugin_taskboard(group_id, release_field_alias, release_field_tracker, estimated_cost_field_alias,
160 remaining_cost_field_alias, user_stories_group_artifact_id, user_stories_reference_field_alias,user_stories_sort_field_alias,
161 first_column_by_default) VALUES($1, $2, $3, $4, $5, $6, $7, $8)',
162 array( $release_field_alias, $release_field_tracker, $estimated_cost_field_alias,
163 $remaining_cost_field_alias, ( $user_stories_tracker ? $user_stories_tracker: NULL ),
164 $user_stories_reference_field, $user_stories_sort_field, $first_column_by_default)
167 $this->setError(_('Cannot create taskboard'));
170 $this->data_array['taskboard_id'] = db_insertid($res,'plugin_taskboard','taskboard_id');
174 foreach( $trackers as $tracker_id ) {
175 $ret = $this->addUsedTracker( $tracker_id, ( array_key_exists($tracker_id, $bgcolors) ? $bgcolors[$tracker_id] : NULL) );
179 // TODO columns initialization
185 $this->data_array['taskboard_id'] = NULL;
192 * update - update a row in the taskboards table
194 * @param array list of trackers IDs, linked to the taskboard
195 * @param array has of card background colors (key - tracker id, value - bg color)
196 * @param string Alias for of 'select' extra field used for release/sprint
197 * @param string Tracke type of extra field used for release/sprint (1 - task trackers, 2 - user story tracker)
198 * @param string Used for cost calculations together with remaining_cost_field_alias if specified
199 * @param string Used for cost calculations together with estimated_cost_field_alias if specified
201 * @return true on success / false on failure.
203 function update($trackers, $bgcolors, $release_field_alias = NULL, $release_field_tracker = 1,
204 $estimated_cost_field_alias = NULL, $remaining_cost_field_alias = NULL,
205 $user_stories_tracker = NULL, $user_stories_reference_field = NULL, $user_stories_sort_field = NULL, $first_column_by_default = 1 ) {
209 if (!session_loggedin()) {
210 $this->setError(_('Must Be Logged In'));
214 if( count($trackers) == 0 ) {
215 $this->setError(_('Taskboard must be linked at least to one tracker'));
221 $res = db_query_params(
222 'UPDATE plugin_taskboard SET release_field_alias=$1, release_field_tracker=$2, estimated_cost_field_alias=$3, remaining_cost_field_alias=$4,
223 user_stories_group_artifact_id=$5, user_stories_reference_field_alias=$6, user_stories_sort_field_alias=$7,
224 first_column_by_default=$8 WHERE taskboard_id=$9',
226 $release_field_alias, $release_field_tracker , $estimated_cost_field_alias, $remaining_cost_field_alias,
227 ( $user_stories_tracker ? $user_stories_tracker: NULL), $user_stories_reference_field, $user_stories_sort_field,
228 $first_column_by_default, $this->getID())
231 $this->setError(_('Cannot update taskboard'));
239 $old_trackers = $this->getUsedTrackersIds();
240 foreach($trackers as $tracker_id) {
241 if(in_array($tracker_id, $old_trackers)) {
243 $ret = $this->updateUsedTracker(
245 (array_key_exists($tracker_id, $bgcolors) ? $bgcolors[$tracker_id] : NULL)
249 $ret = $this->addUsedTracker(
251 (array_key_exists($tracker_id, $bgcolors) ? $bgcolors[$tracker_id] : NULL)
256 foreach($old_trackers as $tracker_id){
257 if(!in_array($tracker_id, $trackers)) {
258 $ret = $this->deleteUsedTracker($tracker_id);
267 $this->data_array['taskboard_id'] = NULL;
275 * _checkExtraFields() - check where extra field exists in the tracker
278 private function _checkExtraFields($group_artifacts, $alias) {
281 /* TODO How to get ArtifactType objects ?
282 foreach($group_artifacts as $group_artifacts) {
291 * fetchData - re-fetch the data for this TaskBoard from the database.
293 * @param int The taskboard ID.
294 * @return boolean success.
296 function fetchData($taskboard_id = NULL) {
298 $taskboard_id = $this->getID();
300 $res = db_query_params('SELECT * FROM plugin_taskboard WHERE taskboard_id=$1', array($taskboard_id));
301 if (!$res || db_numrows($res) < 1) {
302 $this->setError(_('Taskboard')._(': ')._('Invalid TaskBoardID'));
305 $this->data_array = db_fetch_array($res);
306 db_free_result($res);
311 * fetchDataByGroup - re-fetch the data for this TaskBoard from the database by group ID.
313 * @return boolean success.
315 function fetchDataByGroup() {
316 $res = db_query_params('SELECT * FROM plugin_taskboard WHERE group_id=$1', array ($this->Group->getID()));
317 if (!$res || db_numrows($res) < 1) {
318 $this->setError(_('Taskboard')._(': ')._('Not configured for this project yet. Please, initialize plugin on the plugin admin page.'));
321 $this->data_array = db_fetch_array($res);
322 db_free_result($res);
327 * getID - get this TaskBoardID.
329 * @return int The taskboard_id
332 return $this->data_array['taskboard_id'];
336 * getReleaseField - get alias of field, used for release/sprint
338 * @return string extra field alias
340 function getReleaseField() {
341 return $this->data_array['release_field_alias'];
345 * getReleaseFieldTracker - get a source tracker type of field, used for release/sprint
347 * @return integer 1 - tasks tracker, 2 - user story tracker
349 function getReleaseFieldTracker() {
350 return $this->data_array['release_field_tracker'];
354 * getEstimatedCostField - get alias of field, used for estimated cost value
356 * @return string extra field alias
358 function getEstimatedCostField() {
359 return $this->data_array['estimated_cost_field_alias'];
363 * getRemainingCostField - get alias of field, used for remaining cost value
365 * @return string extra field alias
367 function getRemainingCostField() {
368 return $this->data_array['remaining_cost_field_alias'];
372 * getUserStoriesTrackerID - get identifier of tracker, used for user stories
374 * @return integer tracker identifier
376 function getUserStoriesTrackerID() {
377 return $this->data_array['user_stories_group_artifact_id'];
381 * getUserStoriesReferenceField - get alias of field, used as a reference to user stiry artifact
383 * @return string extra field alias
385 function getUserStoriesReferenceField() {
386 return $this->data_array['user_stories_reference_field_alias'];
390 * getUserStoriesSortField - get alias of field, used as for user stories sorting (DESC)
392 * @return string extra field alias
394 function getUserStoriesSortField() {
395 return $this->data_array['user_stories_sort_field_alias'];
399 * getFirstColumnByDefault
403 function getFirstColumnByDefault() {
404 return $this->data_array['first_column_by_default'];
409 * getUsedTrackersIds - get identifiers of used trackers
413 function getUsedTrackersIds() {
414 $res = db_query_params('SELECT * FROM plugin_taskboard_trackers WHERE taskboard_id = $1', array ($this->getID()));
416 $this->setError(_('Taskboard')._(': ')._('Cannot get list of used trackers.'));
421 while($row = db_fetch_array($res)) {
422 $trackers[] = $row['group_artifact_id'];
424 db_free_result($res);
429 * getUsedTrackersiData - get data of used trackers
433 function getUsedTrackersData() {
434 $res = db_query_params('SELECT * FROM plugin_taskboard_trackers WHERE taskboard_id = $1', array ($this->getID()));
436 $this->setError(_('Taskboard')._(': ')._('Cannot get list of used trackers.'));
441 while( $row = db_fetch_array($res)) {
444 db_free_result($res);
449 * cleanUsedTrackers - empty list of trackers, used with taskboard
453 function cleanUsedTrackers() {
454 $res = db_query_params('DELETE FROM plugin_taskboard_trackers WHERE taskboard_id = $1', array ($this->getID()));
456 $this->setError(_('Taskboard')._(': ')._('Cannot empty list of used trackers.'));
464 * addUsedTracker - add a tracker to use with taskboard
466 * @param int tracker identifier
467 * @param string optional card background color
471 function addUsedTracker($tracker_id, $bgcolor='') {
472 $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));
474 $this->setError(_('Taskboard')._(': ')._('Cannot add used tracker'));
482 * updateUsedTracker - update used tracker
484 * @param int tracker identifier
485 * @param string optional card background color
489 function updateUsedTracker($tracker_id, $bgcolor = '') {
490 $res = db_query_params('UPDATE plugin_taskboard_trackers SET card_background_color = $1 WHERE group_artifact_id = $2', array($bgcolor, $tracker_id));
492 $this->setError(_('Taskboard')._(': ')._('Cannot update used tracker'));
500 * deleteUsedTracker - delete used tracker
502 * @param int tracker identifier
506 function deleteUsedTracker($tracker_id) {
507 $res = db_query_params('DELETE FROM plugin_taskboard_trackers WHERE group_artifact_id = $1', array($tracker_id));
509 $this->setError(_('Taskboard')._(': ')._('Cannot delete used tracker'));
517 * getUserStories - get taskboard user stories
521 function getUserStories($release = NULL, $assigned_to = NULL) {
525 'title' => _('Unlinked tasks'),
526 'description' => _('Tasks, which are not linked to any user story'),
532 $user_stories_sort_field = $this->getUserStoriesSortField();
533 $user_stories_sort_extra_field_id = NULL;
534 if ($user_stories_sort_field) {
535 $ef = $this->TrackersAdapter->getFieldsIds($this->getUserStoriesTrackerID());
536 if ( array_key_exists($user_stories_sort_field ,$ef) ) {
537 $user_stories_sort_extra_field_id = $ef[ $user_stories_sort_field ];
539 $this->setError(_('Configured extra field for userstories sorting is not found.'));
544 $task_release = NULL;
545 $user_story_release = NULL;
547 if ($this->getReleaseFieldTracker() == RELEASE_OF_TASK) {
548 $task_release = $release;
550 $user_story_release = $release;
553 $us = $this->TrackersAdapter->getUserStories($release);
555 foreach($us as $story) {
556 $stories[$story->getID()] = array(
557 'id' => $story->getID(),
558 'title' => $story->getSummary(),
559 'description' => str_replace("\n", '<br>', $story->getDetails()),
560 'priority' => $story->getPriority(),
562 'url' => $this->TrackersAdapter->getTaskUrl($story)
565 if ($user_stories_sort_extra_field_id) {
566 $efd = $story ->getExtraFieldData();
567 $stories[$story->getID()]['order'] = $efd[$user_stories_sort_extra_field_id];
569 //sort by GF priority if another field for sorting is not defined
570 $stories[$story->getID()]['order'] = $stories[$story->getID()]['priority'];
573 if($this->getReleaseFieldTracker() == RELEASE_OF_USER_STORY) {
574 $tasks_trackers = $this->getUsedTrackersData();
575 foreach($tasks_trackers as $tasks_tracker_data) {
576 $tasks = $this->TrackersAdapter->getTasks($tasks_tracker_data['group_artifact_id'], $assigned_to, NULL, $story->getID());
577 foreach($tasks as $task) {
578 $task_maped = $this->getMappedTask($task);
579 $stories[$story->getID()]['tasks'][] = $task_maped;
585 if ($this->getReleaseFieldTracker() == RELEASE_OF_TASK) {
586 $tasks_trackers = $this->getUsedTrackersData();
587 foreach($tasks_trackers as $tasks_tracker_data) {
588 $tasks = $this->TrackersAdapter->getTasks($tasks_tracker_data['group_artifact_id'], $assigned_to, $task_release);
589 foreach($tasks as $task) {
590 $task_maped = $this->getMappedTask($task);
591 $stories[intval($task_maped['user_story'])]['tasks'][] = $task_maped;
596 $but = array_values($stories);
598 //leave only stories, having not empty tasks list
599 $ret_stories = array();
600 foreach($but as $us) {
601 if (count($us['tasks']) > 0 ) {
602 $ret_stories[] = $us;
606 usort($ret_stories, array($this, 'sortUserStories'));
612 * getMappedTask - map artifact object into hash and add column and presentation specific fields
614 * @param Artifact artifact instance
618 function getMappedTask($task) {
619 static $_used_trackers_data = NULL;
620 static $_first_column_id = NULL;
622 if (!$_used_trackers_data) {
623 foreach($this->getUsedTrackersData() as $tasks_tracker_data) {
624 $_used_trackers_data[ $tasks_tracker_data['group_artifact_id'] ] = $tasks_tracker_data;
628 $task_maped = $this->_mapTask($task);
629 $column = taskboard_column_get_object_by_resolution($this, $task_maped['resolution']);
631 $task_maped['phase_id'] = $column->getID();
633 if($this->getFirstColumnByDefault()) {
634 if(!$_first_column_id) {
635 $columns = $this->getColumns();
636 $_first_column_id = $columns[0]->getID();
638 $task_maped['phase_id'] = $_first_column_id;
642 $card_title_background = $_used_trackers_data[$task->ArtifactType->getID()]['card_background_color'];
643 if( method_exists($this->TrackersAdapter, 'cardBackgroundColor' ) ) {
644 $task_maped['background'] = $this->TrackersAdapter->cardBackgroundColor($task, $card_title_background );
646 $task_maped['background'] = $card_title_background;
652 function sortUserStories($u1, $u2) {
655 usort( $u1['tasks'], array( $this, 'sortUserStoryTasks' ) );
657 if (!array_key_exists('order', $u1)) {
659 } elseif (!array_key_exists('order', $u2)) {
661 } elseif ($u1['order'] < $u2['order']) {
663 } elseif ($u1['order'] > $u2['order']) {
670 function sortUserStoryTasks($t1, $t2) {
673 if ($t1['priority'] < $t2['priority'] ) {
675 } elseif ( $t1['priority'] > $t2['priority'] ) {
682 function getMandatoryFieldsMapping() {
684 'resolution' => 'resolution',
685 'estimated_dev_effort' => $this->getEstimatedCostField(),
686 'remaining_dev_effort' => $this->getRemainingCostField(),
687 'user_story' => $this->getUserStoriesReferenceField()
692 * _mapTask - map artifact object into hash
694 * @param Artifact artifact instance
698 private function _mapTask($task) {
701 $ef_mapping = $this->getMandatoryFieldsMapping();
703 $fields_ids = $this->TrackersAdapter->getFieldsIds($task->ArtifactType->getID());
704 $extra_data = $task->getExtraFieldDataText();
706 $ret['id'] = $task->getID();
707 $ret['title'] = $task->getSummary();
708 $ret['description'] = str_replace("\n", '<br>', $task->getDetails() );
709 $ret['assigned_to'] = $task->getAssignedRealName();
710 $ret['priority'] = $task->getPriority();
711 foreach( $ef_mapping as $k => $f){
713 if (array_key_exists($f, $fields_ids)) {
714 if (array_key_exists($fields_ids[$f], $extra_data)) {
715 $ret[$k] = $extra_data[$fields_ids[$f]]['value'];
720 if (!$ret['user_story']) {
721 // task is not assigend to any user story
722 $ret['user_story'] = 0;
725 $ret['url'] = $this->TrackersAdapter->getTaskUrl($task);
727 $params = array('user_id' => $task->getAssignedTo(), 'size' => 's', 'content' => '');
728 plugin_hook_by_reference("user_logo", $params);
729 if ($params['content']) {
730 $ret['assigned_to_face'] = $params['content'];
732 $ret['assigned_to_face'] = '';
739 * getColumns - get taskboard columns
743 function getColumns() {
744 $res = db_query_params('SELECT * FROM plugin_taskboard_columns WHERE taskboard_id=$1 ORDER BY order_num', array ($this->getID()));
746 $this->setError(_('Taskboard')._(': ')._('Cannot get list of columns.'));
751 while($row = db_fetch_array($res)) {
752 $columns[] = new TaskBoardColumn($this, $row);
754 db_free_result($res);
759 * addColumn - add taskboard column
763 function addColumn($title, $title_bg_color, $column_bg_color, $max_tasks) {
766 $res = db_query_params('SELECT COUNT(*) as count FROM plugin_taskboard_columns WHERE taskboard_id=$1', array ($this->getID()));
771 $row = db_fetch_array($res);
772 $order = intval($row['count']) + 1;
773 db_free_result($res);
775 $res = db_query_params(
776 '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)',
789 $column_id = db_insertid($res, 'plugin_taskboard_columns', 'taskboard_column_id');
790 db_free_result($res);
796 * getExtraFields - get a list of extra fields, existing is all used task trackers
798 * @param array list of allowed extra fields types
799 * @param array list of excluded aliases
801 * @return array array of aliases
803 function getExtraFields($allowed_types = array(), $used_trackers = NULL, $excluded_aliases = array('resolution')) {
804 $atf = $this->TrackersAdapter->getArtifactTypeFactory();
805 if (!$atf || !is_object($atf) || $atf->isError()) {
806 return _('Could Not Get ArtifactTypeFactory');
809 if (!$used_trackers) {
810 $used_trackers = $this->getUsedTrackersIds();
813 $common_fields = array();
815 foreach ($allowed_types as $allowed_type) {
816 $common_fields[$allowed_type] = array();
819 $at_arr = $atf->getArtifactTypes();
821 for ($j = 0; $j < count($at_arr); $j++) {
822 if (!is_object($at_arr[$j])) {
824 } elseif ($at_arr[$j]->isError()) {
825 return $at_arr[$j]->getErrorMessage();
827 $tracker_id = $at_arr[$j]->getID();
829 if (in_array($tracker_id, $used_trackers)) {
830 // select common fields for the give types
831 $fields = $at_arr[$j]->getExtraFields($allowed_types);
833 foreach ($allowed_types as $allowed_type) {
834 $tmp[$allowed_type] = array();
837 foreach ($fields as $field) {
838 // exclude 'resolution' field
839 if (!in_array($field['alias'],$excluded_aliases)) {
841 if (in_array($field['field_type'], $allowed_types)) {
842 $tmp[$field['field_type']][$field['alias']] = $field['field_name'];
845 in_array($field['alias'], array_keys($common_fields[$field['field_type']])) &&
846 in_array($field['field_type'], $allowed_types)
848 $tmp[$field['field_type']][$field['alias']] = $field['field_name'];
852 $common_fields = $tmp;
857 return $common_fields;
861 * getExtraFieldValues - get hash of values, available for the given extra field
863 * @param string extra field alias
865 * @return array hash element_name => element_id
867 function getExtraFieldValues($extra_field_alias) {
870 $tasks_trackers = $this->getUsedTrackersIds();
871 foreach($tasks_trackers as $tracker_id) {
872 $ef_values = $this->TrackersAdapter->getExtraFieldValues($tracker_id, $extra_field_alias);
873 if (count($ret) == 0) {
877 foreach($ret as $name => $id) {
878 if( array_key_exists($name, $ef_values)) {
890 * getReleases - get taskboard releases
894 function getReleases() {
895 $res = db_query_params('SELECT * FROM plugin_taskboard_releases WHERE taskboard_id = $1 ORDER BY start_date, end_date', array($this->getID()));
897 $this->setError(_('Taskboard')._(': ')._('Cannot get list of releases.'));
902 while( $row = db_fetch_array($res)) {
903 $releases[] = new TaskBoardRelease($this, $row);
905 db_free_result($res);
910 * getCurrentRelease - get current or the most recent release object
914 function getCurrentRelease() {
915 $current_release = NULL;
917 $res = db_query_params (
918 'SELECT * FROM plugin_taskboard_releases WHERE taskboard_id=$1 AND start_date < $2 ORDER BY start_date DESC LIMIT 1',
921 strtotime(date('Y-m-d'))
925 $this->setError(_('Taskboard')._(': ')._('Cannot get current release.'));
928 $row = db_fetch_array($res);
930 $current_release = new TaskBoardRelease($this, $row);
933 db_free_result($res);
935 return $current_release;
939 * getReleaseValues - get list of all available reslease values
943 function getReleaseValues() {
946 if ($this->getReleaseFieldTracker() == 1) {
947 // get values from tasks trackers
948 $ret = $this->getExtraFieldValues($this->getReleaseField());
950 // get values from user stories trackers
951 $ret = $this->TrackersAdapter->getExtraFieldValues($this->getUserStoriesTrackerID(), $this->getReleaseField());
958 * getAvailableResolutions - get list of all available resolution values
962 function getAvailableResolutions() {
963 return array_keys($this->getExtraFieldValues('resolution'));
967 * getUsedResolutions - get list of resolutions that are already used with taskboard columns
971 function getUsedResolutions() {
972 $res = db_query_params(
973 'SELECT R.* FROM plugin_taskboard_columns_resolutions as R, plugin_taskboard_columns as C
974 WHERE C.taskboard_id=$1 AND R.taskboard_column_id=C.taskboard_column_id',
975 array($this->getID())
978 $this->setError(_('Taskboard')._(': ')._('Cannot get used resolutions'));
982 $resolutions= array();
983 while($row = db_fetch_array($res)) {
984 $resolutions[$row['taskboard_column_resolution']] = $row['taskboard_column_resolution'];
986 db_free_result($res);
988 return array_keys($resolutions);
992 * getUnusedResolutions - get list of resolutions that are not used with taskboard columns
996 function getUnusedResolutions() {
997 static $resolutions = NULL;
999 if( !$resolutions ) {
1000 $all_resolutions = $this->getAvailableResolutions();
1001 $used_resolutions = $this->getUsedResolutions();
1003 $resolutions = array();
1004 if( $all_resolutions && count( $used_resolutions ) > 0 ) {
1005 $resolutions = array_diff( $all_resolutions, $used_resolutions );
1007 $resolutions = $all_resolutions;
1011 return $resolutions;