1 --- eventum-r3721/include/class.display_column.php~ 2008-09-09 22:45:13.000000000 +0300
2 +++ eventum-r3721/include/class.display_column.php 2008-09-09 22:46:04.000000000 +0300
5 "iss_expected_resolution_date" => array(
6 "title" => ev_gettext("Expected Resolution Date")
9 + "isu_order" => array(
10 + "title" => ev_gettext("Issue Order")
14 return $columns[$page];
15 --- eventum-1.7.0/include/class.issue.php 2005-12-29 21:27:25.000000000 +0200
16 +++ eventum/include/class.issue.php 2006-03-27 15:33:02.000000000 +0300
18 Error_Handler::logError(array($res->getMessage(), $res->getDebugInfo()), __FILE__, __LINE__);
21 + Issue::moveOrderForAllUsers($issue_id, 1000);
22 $prj_id = Issue::getProjectID($issue_id);
24 // add note with the reason to close the issue
26 $assignment_notifications[] = $assignee;
27 $assignments_changed = true;
29 - $assignments_changed = true;
31 if (count($assignment_notifications) > 0) {
32 Notification::notifyNewAssignment($assignment_notifications, $issue_id);
33 @@ -1596,16 +1596,33 @@
35 $issue_id = Misc::escapeInteger($issue_id);
36 $assignee_usr_id = Misc::escapeInteger($assignee_usr_id);
38 + // move all orders down to free "order space" for this new association
40 + " . APP_DEFAULT_DB . "." . APP_TABLE_PREFIX . "issue_user
42 + isu_order = isu_order + 1
44 + isu_usr_id = $assignee_usr_id AND
45 + isu_order >= $order";
46 + $res = $GLOBALS["db_api"]->dbh->query($stmt);
47 + if (PEAR::isError($res)) {
48 + Error_Handler::logError(array($res->getMessage(), $res->getDebugInfo()), __FILE__, __LINE__);
51 + // insert the new association
53 " . APP_DEFAULT_DB . "." . APP_TABLE_PREFIX . "issue_user
63 - '" . Date_API::getCurrentDateGMT() . "'
64 + '" . Date_API::getCurrentDateGMT() . "',
67 $res = $GLOBALS["db_api"]->dbh->query($stmt);
68 if (PEAR::isError($res)) {
69 @@ -1620,6 +1637,78 @@
74 + * Method used to get the order list to be rearranged
77 + * @param string $issue_id The issue ID or a comma seperated list of IDs already prepared for giving to mysql
78 + * @param string $usr_id The user to remove. When not specified, all users are taken as to be removed for that issue
79 + * @return mixed delete order list to be rearranged. Used as a parameter to the method of rearranging the order.
81 + function getDeleteUserAssociationOrderList($issue_id, $usr_id = "")
83 + // find all affected associantion orders
84 + $stmt = "SELECT isu_usr_id, isu_order FROM
85 + " . APP_DEFAULT_DB . "." . APP_TABLE_PREFIX . "issue_user
87 + isu_iss_id IN ($issue_id)";
88 + if ($usr_id !== FALSE) {
89 + $stmt.= " AND isu_usr_id IN ($usr_id)";
91 + $stmt.= "ORDER BY isu_order";
92 + $res = $GLOBALS["db_api"]->dbh->getAll($stmt, DB_FETCHMODE_ASSOC);
93 + if (PEAR::isError($res)) {
94 + Error_Handler::logError(array($res->getMessage(), $res->getDebugInfo()), __FILE__, __LINE__);
97 + $deleted_orders = array();
98 + foreach ($res as $row) {
99 + if (empty($deleted_orders[$row['isu_usr_id']])) {
100 + $deleted_orders[$row['isu_usr_id']] = array();
102 + $deleted_orders[$row['isu_usr_id']] [] = $row['isu_order'];
104 + return $deleted_orders;
110 + * Method used to rearrange order list in the db according to known deleted records
113 + * @param mixed deleteorder list
116 + function rearrangeDeleteUserAssociationOrderList($delete_order_list)
118 + if (empty($delete_order_list) || (!is_array($delete_order_list))) {
121 + foreach ($delete_order_list as $isu_usr_id => $orders) {
122 + for ($i = 0; $i < count($orders); $i++) { // traverse all deleted orders
123 + // move the orders after them up to take the "order space" of the deleted records
125 + " . APP_DEFAULT_DB . "." . APP_TABLE_PREFIX . "issue_user
127 + isu_order = isu_order - " . ($i+1) . "
129 + isu_usr_id = $isu_usr_id AND
130 + isu_order > " . $orders[$i];
131 + if ($i < count($orders) - 1) {
133 + isu_order < " . $orders[$i+1];
135 + $res = $GLOBALS["db_api"]->dbh->query($stmt);
136 + if (PEAR::isError($res)) {
137 + Error_Handler::logError(array($res->getMessage(), $res->getDebugInfo()), __FILE__, __LINE__);
147 * Method used to delete all user assignments for a specific issue.
148 @@ -1635,6 +1724,7 @@
149 if (is_array($issue_id)) {
150 $issue_id = implode(", ", $issue_id);
152 + $deleted_order_list = Issue::getDeleteUserAssociationOrderList($issue_id);
154 " . APP_DEFAULT_DB . "." . APP_TABLE_PREFIX . "issue_user
156 @@ -1647,6 +1737,7 @@
158 History::add($issue_id, $usr_id, History::getTypeID('user_all_unassociated'), 'Issue assignments removed by ' . User::getFullName($usr_id));
160 + Issue::rearrangeDeleteUserAsssociationOrderList($deleted_order_list);
164 @@ -1665,6 +1756,7 @@
166 $issue_id = Misc::escapeInteger($issue_id);
167 $usr_id = Misc::escapeInteger($usr_id);
168 + $delete_order_list = Issue::getDeleteUserAssociationOrderList($issue_id, $usr_id);
170 " . APP_DEFAULT_DB . "." . APP_TABLE_PREFIX . "issue_user
172 @@ -1679,6 +1771,7 @@
173 History::add($issue_id, Auth::getUserID(), History::getTypeID('user_unassociated'),
174 User::getFullName($usr_id) . ' removed from issue by ' . User::getFullName(Auth::getUserID()));
176 + Issue::rearrangeDeleteUserAssociationOrderList($delete_order_list);
180 @@ -2047,14 +2140,6 @@
184 - if (count($users) > 0) {
185 - // automatically change the status to 'Assigned'
186 - Issue::setStatus($new_issue_id, Status::getStatusID('Assigned'), FALSE);
188 - // set this special variable to false, to avoid triggering
189 - // another status update on the workflow class
190 - $has_assignee = false;
193 // now process any files being uploaded
195 @@ -2161,6 +2246,11 @@
197 $sort_by = Issue::getParam('sort_by');
198 $sort_order = Issue::getParam('sort_order');
199 + $users = Issue::getParam('users');
200 + if (empty($users) && ($sort_by == 'isu_order')) { // Sorting by isu_order is impossible when no user specified
202 + unset($sort_order);
204 $rows = Issue::getParam('rows');
205 $hide_closed = Issue::getParam('hide_closed');
206 if ($hide_closed === '') {
207 @@ -2261,7 +2351,8 @@
211 - "iss_expected_resolution_date"
212 + "iss_expected_resolution_date",
217 @@ -2975,6 +3066,8 @@
218 $ids = implode(", ", $ids);
225 " . APP_DEFAULT_DB . "." . APP_TABLE_PREFIX . "issue_user,
226 @@ -2986,6 +3079,7 @@
227 if (PEAR::isError($res)) {
228 Error_Handler::logError(array($res->getMessage(), $res->getDebugInfo()), __FILE__, __LINE__);
230 + // gather names of the users assigned to each issue
232 for ($i = 0; $i < count($res); $i++) {
233 if (!empty($t[$res[$i]['isu_iss_id']])) {
234 @@ -2994,9 +3088,18 @@
235 $t[$res[$i]['isu_iss_id']] = $res[$i]['usr_full_name'];
240 + for ($i = 0; $i < count($res); $i++) {
241 + if (empty($o[$res[$i]['isu_iss_id']])) {
242 + $o[$res[$i]['isu_iss_id']] = array();
244 + $o[$res[$i]['isu_iss_id']][$res[$i]['isu_usr_id']] = $res[$i]['isu_order'];
246 // now populate the $result variable again
247 for ($i = 0; $i < count($result); $i++) {
248 @$result[$i]['assigned_users'] = $t[$result[$i]['iss_id']];
249 + @$result[$i]['assigned_users_order'] = $o[$result[$i]['iss_id']];
253 @@ -3963,6 +4066,7 @@
254 Error_Handler::logError(array($res->getMessage(), $res->getDebugInfo()), __FILE__, __LINE__);
257 + Issue::moveOrderForAllUsers($issue_id, 1);
261 @@ -4021,8 +4125,91 @@
263 return $returns[$msg_id];
267 + * Reorders user's issues as requested by user
269 + * @param $usr_id User to be reordered
270 + * @param $issue_id Issue or array of issues to be moved
271 + * @param $neworder The new order of the issues
274 + function reorderUserIssues($usr_id, $issue_id, $neworder)
276 + if (!isset($usr_id) || !isset($issue_id) || !isset($neworder)) {
279 + if (!is_numeric($usr_id) || !is_numeric($neworder)) {
282 + $usr_id = Misc::escapeInteger($usr_id);
283 + $issue_id = Misc::escapeInteger($issue_id);
284 + $neworder = Misc::escapeInteger($neworder);
285 + if (is_array($issue_id)) {
286 + $issue_count = count($issue_id);
287 + $issue_id_str = implode(", ", $issue_id);
290 + $issue_id_str = $issue_id;
291 + $issue_id = array($issue_id);
293 + // do a nasty pretending to be deleting stuff so that reordering happens as if these elements were deleted
294 + $orderlist = Issue::getDeleteUserAssociationOrderList($issue_id_str, $usr_id);
295 + Issue::rearrangeDeleteUserAssociationOrderList($orderlist);
296 + // move down the orders to free the "order space" needed
298 + " . APP_DEFAULT_DB . "." . APP_TABLE_PREFIX . "issue_user
300 + isu_order = isu_order + $issue_count
302 + isu_usr_id = $usr_id AND
303 + isu_order >= $neworder";
304 + $res = $GLOBALS["db_api"]->dbh->query($stmt);
305 + if (PEAR::isError($res)) {
306 + Error_Handler::logError(array($res->getMessage(), $res->getDebugInfo()), __FILE__, __LINE__);
309 + //update the order for the issues being moved
311 + foreach ($issue_id as $iss_id) {
313 + " . APP_DEFAULT_DB . "." . APP_TABLE_PREFIX . "issue_user
315 + isu_order = " . ($neworder + $i) . "
317 + isu_usr_id = $usr_id AND
318 + isu_iss_id = $iss_id";
319 + $res = $GLOBALS["db_api"]->dbh->query($stmt);
320 + if (PEAR::isError($res)) {
321 + Error_Handler::logError(array($res->getMessage(), $res->getDebugInfo()), __FILE__, __LINE__);
328 + function moveOrderForAllUsers($issue_id, $neworder)
330 + // Move the issue to the top priority for the ppl it's assigned to
331 + $stmt = "SELECT isu_usr_id FROM
332 + " . APP_DEFAULT_DB . "." . APP_TABLE_PREFIX . "issue_user
334 + isu_iss_id = " . Misc::escapeInteger($issue_id);
335 + $res = $GLOBALS["db_api"]->dbh->getAll($stmt, DB_FETCHMODE_ASSOC);
336 + if (PEAR::isError($res)) {
337 + Error_Handler::logError(array($res->getMessage(), $res->getDebugInfo()), __FILE__, __LINE__);
340 + foreach ($res as $row) {
341 + Issue::reorderUserIssues($row["isu_usr_id"], $issue_id, $neworder);
350 // benchmarking the included file (aka setup time)
352 $GLOBALS['bench']->setMarker('Included Issue Class');
353 diff -ru eventum-1.7.0/list.php eventum/list.php
354 --- eventum-1.7.0/list.php 2005-12-29 21:27:24.000000000 +0200
355 +++ eventum/list.php 2006-03-30 14:57:06.000000000 +0300
357 $profile['sort_by'] . "&sort_order=" . $profile['sort_order']);
360 +@$reorder_usr_id = $_REQUEST["reorder_user"];
361 +@$reorder_issue_id = $_REQUEST["reorder_source"];
362 +@$reorder_neworder = $_REQUEST["reorder_neworder"];
363 +Issue::reorderUserIssues($reorder_usr_id, $reorder_issue_id, $reorder_neworder);
365 $options = Issue::saveSearchParams();
366 $tpl->assign("options", $options);
367 $tpl->assign("sorting", Issue::getSortingInfo($options));
372 +// get the isu_order (assignated users) ordering user
373 +if (!empty($options["users"])) {
374 + if ($options["users"] == -2) {
375 + $isu_order_user = $usr_id;
377 + if ($options["users"] > 0) {
378 + $isu_order_user = $options["users"];
380 + unset($isu_order_user);
383 + unset($isu_order_user);
385 +$tpl->assign("isu_order_user", $isu_order_user);
387 $list = Issue::getListing($prj_id, $options, $pagerRow, $rows);
388 $tpl->assign("list", $list["list"]);
389 $tpl->assign("list_info", $list["info"]);
390 --- eventum-1.7.0/templates/list.tpl.html 2005-12-29 21:27:24.000000000 +0200
391 +++ eventum/templates/list.tpl.html 2006-03-23 16:28:30.000000000 +0200
396 +function reorderBulk(order_user, neworder)
398 + url = page_url + "?";
399 + url += "reorder_user=" + order_user;
401 + items = document.getElementsByName("item[]");
403 + for (var i = 0; i < items.length; i++) {
404 + if (items[i].checked) {
405 + url += "&reorder_source[" + checkedcount + "]=" + items[i].value;
409 + if (checkedcount == 0) {
410 + alert('{/literal}{t escape=js}Please choose which issues to move to the new place.{/t}{literal}');
414 + url += "&reorder_neworder=" + neworder;
416 + window.location.href = url;
418 function hideClosed(f)
420 if (f.hide_closed.checked) {
422 <td align="{$column.align|default:'center'}" class="default_white" nowrap>
423 {$fld_title|escape:"html"}
428 + {elseif $field_name != 'isu_order' || $isu_order_user}
429 <td align="{$column.align|default:'center'}" class="default_white" nowrap {if $column.width != ''}width="{$column.width}"{/if}>
430 {if $field_name == 'iss_summary'}
431 <table cellspacing="0" cellpadding="1" width="100%">
435 {elseif $sorting.links[$field_name] != ''}
436 - <a title="{t}sort by{/t} {$column.title}" href="{$sorting.links[$field_name]}" class="white_link">{$column.title}</a>
437 - {if $sorting.images[$field_name] != ""}<a title="{t}sort by{/t} {$column.title}" href="{$sorting.links[$field_name]}" class="white_link"><img border="0" src="{$sorting.images[$field_name]}"></a>{/if}
438 + <a title="{t}sort by{/t} {$column.title}" href="{$sorting.links[$field_name]}" class="white_link">{$column.title}</a>
439 + {if $field_name == 'isu_order'}
440 + <br>{$users[$isu_order_user]}
442 + {if $sorting.images[$field_name] != ""}<a title="{t}sort by{/t} {$column.title}" href="{$sorting.links[$field_name]}" class="white_link"><img border="0" src="{$sorting.images[$field_name]}"></a>{/if}
447 {$fld_value|formatCustomValue:$fld_id:$list[i].iss_id}
451 + {elseif $field_name != 'isu_order' || $isu_order_user}
452 <td bgcolor="{$list[i].status_color}" align="{$column.align|default:'center'}" class="default">
453 {if $field_name == 'iss_id'}
454 <a href="view.php?id={$list[i].iss_id}" class="link" title="view issue details">{$list[i].iss_id}</a>
457 {if $list[i].iss_private == 1}
461 + {elseif $field_name == 'isu_order'}
462 + {if $isu_order_user}
463 + {assign var="order" value=$list[i].assigned_users_order[$isu_order_user]}
465 + <a class="link" title="{t}hide / show reordering options{/t}" href="javascript:void(null);" onClick="javascript:toggleVisibility('order{$list[i].iss_id}_');">{$order}</a>
466 + <div id="order{$list[i].iss_id}_1" style="display: none">
469 + <td class="default">{if $order > 1}<a class="link" title="{t}move up{/t}" href="list.php?reorder_user={$isu_order_user}&reorder_source[0]={$list[i].iss_id}&reorder_neworder={math equation="x - 1" x=$order}">{t}Up{/t}</a>{/if}</td>
470 + <td class="default"><a class="link" title="{t}move up{/t}" href="list.php?reorder_user={$isu_order_user}&reorder_source[0]={$list[i].iss_id}&reorder_neworder={math equation="x + 1" x=$order}">{t}Down{/t}</a></td>
473 + <td class="default"><a class="link" title="{t}move here{/t}" href="javascript:void(null);" onClick="javascript:reorderBulk({$isu_order_user}, {$order})">{t}Move here{/t}</a></td>
481 --- /dev/null 2006-03-28 14:00:37.000000000 +0300
482 +++ ./order_patch-patch.sql 2008-08-27 17:16:21.444016830 +0300
484 +ALTER TABLE eventum_issue_user
485 + ADD isu_order int(11) NOT NULL DEFAULT '0' AFTER isu_assigned_date,
486 + ADD INDEX isu_order (isu_order);