X-Git-Url: http://git.pld-linux.org/?a=blobdiff_plain;f=eventum-order.patch;h=5764514ba18bbecb6b4ef71b611d190aebb24fb3;hb=371b276ab631c8d0f88f9387e6f31dffa7ad386a;hp=eaecf6f52aafb607d8ea9fb70808890844d4a961;hpb=d95f9b261d8c641c344cbfc951b91c54e93158fa;p=packages%2Feventum.git diff --git a/eventum-order.patch b/eventum-order.patch index eaecf6f..5764514 100644 --- a/eventum-order.patch +++ b/eventum-order.patch @@ -1,49 +1,572 @@ ---- eventum-r3721/include/class.display_column.php~ 2008-09-09 22:45:13.000000000 +0300 -+++ eventum-r3721/include/class.display_column.php 2008-09-09 22:46:04.000000000 +0300 -@@ -229,7 +229,10 @@ +--- eventum-2.2/htdocs/ajax/order.php 1970-01-01 02:00:00.000000000 +0200 ++++ eventum-2.2-order/htdocs/ajax/order.php 2009-10-12 22:10:36.429185594 +0300 +@@ -0,0 +1,69 @@ ++ $nID) { ++ if ($nID != $before_filterd[$key]) { ++ if ($nID) { ++ $stmt = "UPDATE ++ " . APP_DEFAULT_DB . "." . APP_TABLE_PREFIX . "issue_user ++ SET ++ isu_order = " . $order[$before_filterd[$key]] . " ++ WHERE ++ isu_iss_id = $nID AND ++ isu_usr_id = $usr_id"; ++ $res = DB_Helper::getInstance()->query($stmt); ++ if (PEAR::isError($res)) { ++ Error_Handler::logError(array($res->getMessage(), $res->getDebugInfo()), __FILE__, __LINE__); ++ die('update failed'); ++ } ++ } ++ } ++} +--- eventum-2.3.1/htdocs/css/style.css~ 2011-09-15 09:36:55.000000000 +0300 ++++ eventum-2.3.1/htdocs/css/style.css 2011-09-15 09:38:23.668223576 +0300 +@@ -177,6 +177,24 @@ + cursor: pointer; + } + ++.tDnD_whileDrag td { ++ background-color: #ffffdd; ++} ++.tDnD_whileDrag td { ++ border: 1px solid red; ++} ++.inline_date_pick { ++ cursor: pointer; ++} ++.custom_field { ++ cursor: pointer; ++} ++.showDragHandle { ++ cursor: move; ++ background-image: url(../images/updown2.gif); ++ background-repeat: no-repeat; ++ background-position: center center; ++} + + ul.excerpts { + list-style: none; +@@ -187,4 +205,4 @@ + ul.excerpts ul { + list-style-type: none; + padding-left: 1em; +-} +\ No newline at end of file ++} +--- eventum-2.2/htdocs/js/jquery/jquery.tablednd.js 1970-01-01 02:00:00.000000000 +0200 ++++ eventum-2.2-order/htdocs/js/jquery/jquery.tablednd.js 2009-10-12 22:10:36.435851675 +0300 +@@ -0,0 +1,382 @@ ++/** ++ * TableDnD plug-in for JQuery, allows you to drag and drop table rows ++ * You can set up various options to control how the system will work ++ * Copyright (c) Denis Howlett ++ * Licensed like jQuery, see http://docs.jquery.com/License. ++ * ++ * Configuration options: ++ * ++ * onDragStyle ++ * This is the style that is assigned to the row during drag. There are limitations to the styles that can be ++ * associated with a row (such as you can't assign a border--well you can, but it won't be ++ * displayed). (So instead consider using onDragClass.) The CSS style to apply is specified as ++ * a map (as used in the jQuery css(...) function). ++ * onDropStyle ++ * This is the style that is assigned to the row when it is dropped. As for onDragStyle, there are limitations ++ * to what you can do. Also this replaces the original style, so again consider using onDragClass which ++ * is simply added and then removed on drop. ++ * onDragClass ++ * This class is added for the duration of the drag and then removed when the row is dropped. It is more ++ * flexible than using onDragStyle since it can be inherited by the row cells and other content. The default ++ * is class is tDnD_whileDrag. So to use the default, simply customise this CSS class in your ++ * stylesheet. ++ * onDrop ++ * Pass a function that will be called when the row is dropped. The function takes 2 parameters: the table ++ * and the row that was dropped. You can work out the new order of the rows by using ++ * table.rows. ++ * onDragStart ++ * Pass a function that will be called when the user starts dragging. The function takes 2 parameters: the ++ * table and the row which the user has started to drag. ++ * onAllowDrop ++ * Pass a function that will be called as a row is over another row. If the function returns true, allow ++ * dropping on that row, otherwise not. The function takes 2 parameters: the dragged row and the row under ++ * the cursor. It returns a boolean: true allows the drop, false doesn't allow it. ++ * scrollAmount ++ * This is the number of pixels to scroll if the user moves the mouse cursor to the top or bottom of the ++ * window. The page should automatically scroll up or down as appropriate (tested in IE6, IE7, Safari, FF2, ++ * FF3 beta ++ * dragHandle ++ * This is the name of a class that you assign to one or more cells in each row that is draggable. If you ++ * specify this class, then you are responsible for setting cursor: move in the CSS and only these cells ++ * will have the drag behaviour. If you do not specify a dragHandle, then you get the old behaviour where ++ * the whole row is draggable. ++ * ++ * Other ways to control behaviour: ++ * ++ * Add class="nodrop" to any rows for which you don't want to allow dropping, and class="nodrag" to any rows ++ * that you don't want to be draggable. ++ * ++ * Inside the onDrop method you can also call $.tableDnD.serialize() this returns a string of the form ++ * []=&[]= so that you can send this back to the server. The table must have ++ * an ID as must all the rows. ++ * ++ * Other methods: ++ * ++ * $("...").tableDnDUpdate() ++ * Will update all the matching tables, that is it will reapply the mousedown method to the rows (or handle cells). ++ * This is useful if you have updated the table rows using Ajax and you want to make the table draggable again. ++ * The table maintains the original configuration (so you don't have to specify it again). ++ * ++ * $("...").tableDnDSerialize() ++ * Will serialize and return the serialized string as above, but for each of the matching tables--so it can be ++ * called from anywhere and isn't dependent on the currentTable being set up correctly before calling ++ * ++ * Known problems: ++ * - Auto-scoll has some problems with IE7 (it scrolls even when it shouldn't), work-around: set scrollAmount to 0 ++ * ++ * Version 0.2: 2008-02-20 First public version ++ * Version 0.3: 2008-02-07 Added onDragStart option ++ * Made the scroll amount configurable (default is 5 as before) ++ * Version 0.4: 2008-03-15 Changed the noDrag/noDrop attributes to nodrag/nodrop classes ++ * Added onAllowDrop to control dropping ++ * Fixed a bug which meant that you couldn't set the scroll amount in both directions ++ * Added serialize method ++ * Version 0.5: 2008-05-16 Changed so that if you specify a dragHandle class it doesn't make the whole row ++ * draggable ++ * Improved the serialize method to use a default (and settable) regular expression. ++ * Added tableDnDupate() and tableDnDSerialize() to be called when you are outside the table ++ */ ++jQuery.tableDnD = { ++ /** Keep hold of the current table being dragged */ ++ currentTable : null, ++ /** Keep hold of the current drag object if any */ ++ dragObject: null, ++ /** The current mouse offset */ ++ mouseOffset: null, ++ /** Remember the old value of Y so that we don't do too much processing */ ++ oldY: 0, ++ ++ /** Actually build the structure */ ++ build: function(options) { ++ // Set up the defaults if any ++ ++ this.each(function() { ++ // This is bound to each matching table, set up the defaults and override with user options ++ this.tableDnDConfig = jQuery.extend({ ++ onDragStyle: null, ++ onDropStyle: null, ++ // Add in the default class for whileDragging ++ onDragClass: "tDnD_whileDrag", ++ onDrop: null, ++ onDragStart: null, ++ scrollAmount: 5, ++ serializeRegexp: /[^\-]*$/, // The regular expression to use to trim row IDs ++ serializeParamName: null, // If you want to specify another parameter name instead of the table ID ++ dragHandle: null // If you give the name of a class here, then only Cells with this class will be draggable ++ }, options || {}); ++ // Now make the rows draggable ++ jQuery.tableDnD.makeDraggable(this); ++ }); ++ ++ // Now we need to capture the mouse up and mouse move event ++ // We can use bind so that we don't interfere with other event handlers ++ jQuery(document) ++ .bind('mousemove', jQuery.tableDnD.mousemove) ++ .bind('mouseup', jQuery.tableDnD.mouseup); ++ ++ // Don't break the chain ++ return this; ++ }, ++ ++ /** This function makes all the rows on the table draggable apart from those marked as "NoDrag" */ ++ makeDraggable: function(table) { ++ var config = table.tableDnDConfig; ++ if (table.tableDnDConfig.dragHandle) { ++ // We only need to add the event to the specified cells ++ var cells = jQuery("td."+table.tableDnDConfig.dragHandle, table); ++ cells.each(function() { ++ // The cell is bound to "this" ++ jQuery(this).mousedown(function(ev) { ++ jQuery.tableDnD.dragObject = this.parentNode; ++ jQuery.tableDnD.currentTable = table; ++ jQuery.tableDnD.mouseOffset = jQuery.tableDnD.getMouseOffset(this, ev); ++ if (config.onDragStart) { ++ // Call the onDrop method if there is one ++ config.onDragStart(table, this); ++ } ++ return false; ++ }); ++ }) ++ } else { ++ // For backwards compatibility, we add the event to the whole row ++ var rows = jQuery("tr", table); // get all the rows as a wrapped set ++ rows.each(function() { ++ // Iterate through each row, the row is bound to "this" ++ var row = jQuery(this); ++ if (! row.hasClass("nodrag")) { ++ row.mousedown(function(ev) { ++ if (ev.target.tagName == "TD") { ++ jQuery.tableDnD.dragObject = this; ++ jQuery.tableDnD.currentTable = table; ++ jQuery.tableDnD.mouseOffset = jQuery.tableDnD.getMouseOffset(this, ev); ++ if (config.onDragStart) { ++ // Call the onDrop method if there is one ++ config.onDragStart(table, this); ++ } ++ return false; ++ } ++ }).css("cursor", "move"); // Store the tableDnD object ++ } ++ }); ++ } ++ }, ++ ++ updateTables: function() { ++ this.each(function() { ++ // this is now bound to each matching table ++ if (this.tableDnDConfig) { ++ jQuery.tableDnD.makeDraggable(this); ++ } ++ }) ++ }, ++ ++ /** Get the mouse coordinates from the event (allowing for browser differences) */ ++ mouseCoords: function(ev){ ++ if(ev.pageX || ev.pageY){ ++ return {x:ev.pageX, y:ev.pageY}; ++ } ++ return { ++ x:ev.clientX + document.body.scrollLeft - document.body.clientLeft, ++ y:ev.clientY + document.body.scrollTop - document.body.clientTop ++ }; ++ }, ++ ++ /** Given a target element and a mouse event, get the mouse offset from that element. ++ To do this we need the element's position and the mouse position */ ++ getMouseOffset: function(target, ev) { ++ ev = ev || window.event; ++ ++ var docPos = this.getPosition(target); ++ var mousePos = this.mouseCoords(ev); ++ return {x:mousePos.x - docPos.x, y:mousePos.y - docPos.y}; ++ }, ++ ++ /** Get the position of an element by going up the DOM tree and adding up all the offsets */ ++ getPosition: function(e){ ++ var left = 0; ++ var top = 0; ++ /** Safari fix -- thanks to Luis Chato for this! */ ++ if (e.offsetHeight == 0) { ++ /** Safari 2 doesn't correctly grab the offsetTop of a table row ++ this is detailed here: ++ http://jacob.peargrove.com/blog/2006/technical/table-row-offsettop-bug-in-safari/ ++ the solution is likewise noted there, grab the offset of a table cell in the row - the firstChild. ++ note that firefox will return a text node as a first child, so designing a more thorough ++ solution may need to take that into account, for now this seems to work in firefox, safari, ie */ ++ e = e.firstChild; // a table cell ++ } ++ ++ while (e.offsetParent){ ++ left += e.offsetLeft; ++ top += e.offsetTop; ++ e = e.offsetParent; ++ } ++ ++ left += e.offsetLeft; ++ top += e.offsetTop; ++ ++ return {x:left, y:top}; ++ }, ++ ++ mousemove: function(ev) { ++ if (jQuery.tableDnD.dragObject == null) { ++ return; ++ } ++ ++ var dragObj = jQuery(jQuery.tableDnD.dragObject); ++ var config = jQuery.tableDnD.currentTable.tableDnDConfig; ++ var mousePos = jQuery.tableDnD.mouseCoords(ev); ++ var y = mousePos.y - jQuery.tableDnD.mouseOffset.y; ++ //auto scroll the window ++ var yOffset = window.pageYOffset; ++ if (document.all) { ++ // Windows version ++ //yOffset=document.body.scrollTop; ++ if (typeof document.compatMode != 'undefined' && ++ document.compatMode != 'BackCompat') { ++ yOffset = document.documentElement.scrollTop; ++ } ++ else if (typeof document.body != 'undefined') { ++ yOffset=document.body.scrollTop; ++ } ++ ++ } ++ ++ if (mousePos.y-yOffset < config.scrollAmount) { ++ window.scrollBy(0, -config.scrollAmount); ++ } else { ++ var windowHeight = window.innerHeight ? window.innerHeight ++ : document.documentElement.clientHeight ? document.documentElement.clientHeight : document.body.clientHeight; ++ if (windowHeight-(mousePos.y-yOffset) < config.scrollAmount) { ++ window.scrollBy(0, config.scrollAmount); ++ } ++ } ++ ++ ++ if (y != jQuery.tableDnD.oldY) { ++ // work out if we're going up or down... ++ var movingDown = y > jQuery.tableDnD.oldY; ++ // update the old value ++ jQuery.tableDnD.oldY = y; ++ // update the style to show we're dragging ++ if (config.onDragClass) { ++ dragObj.addClass(config.onDragClass); ++ } else { ++ dragObj.css(config.onDragStyle); ++ } ++ // If we're over a row then move the dragged row to there so that the user sees the ++ // effect dynamically ++ var currentRow = jQuery.tableDnD.findDropTargetRow(dragObj, y); ++ if (currentRow) { ++ // TODO worry about what happens when there are multiple TBODIES ++ if (movingDown && jQuery.tableDnD.dragObject != currentRow) { ++ jQuery.tableDnD.dragObject.parentNode.insertBefore(jQuery.tableDnD.dragObject, currentRow.nextSibling); ++ } else if (! movingDown && jQuery.tableDnD.dragObject != currentRow) { ++ jQuery.tableDnD.dragObject.parentNode.insertBefore(jQuery.tableDnD.dragObject, currentRow); ++ } ++ } ++ } ++ ++ return false; ++ }, ++ ++ /** We're only worried about the y position really, because we can only move rows up and down */ ++ findDropTargetRow: function(draggedRow, y) { ++ var rows = jQuery.tableDnD.currentTable.rows; ++ for (var i=0; i rowY - rowHeight) && (y < (rowY + rowHeight))) { ++ // that's the row we're over ++ // If it's the same as the current row, ignore it ++ if (row == draggedRow) {return null;} ++ var config = jQuery.tableDnD.currentTable.tableDnDConfig; ++ if (config.onAllowDrop) { ++ if (config.onAllowDrop(draggedRow, row)) { ++ return row; ++ } else { ++ return null; ++ } ++ } else { ++ // If a row has nodrop class, then don't allow dropping (inspired by John Tarr and Famic) ++ var nodrop = jQuery(row).hasClass("nodrop"); ++ if (! nodrop) { ++ return row; ++ } else { ++ return null; ++ } ++ } ++ return row; ++ } ++ } ++ return null; ++ }, ++ ++ mouseup: function(e) { ++ if (jQuery.tableDnD.currentTable && jQuery.tableDnD.dragObject) { ++ var droppedRow = jQuery.tableDnD.dragObject; ++ var config = jQuery.tableDnD.currentTable.tableDnDConfig; ++ // If we have a dragObject, then we need to release it, ++ // The row will already have been moved to the right place so we just reset stuff ++ if (config.onDragClass) { ++ jQuery(droppedRow).removeClass(config.onDragClass); ++ } else { ++ jQuery(droppedRow).css(config.onDropStyle); ++ } ++ jQuery.tableDnD.dragObject = null; ++ if (config.onDrop) { ++ // Call the onDrop method if there is one ++ config.onDrop(jQuery.tableDnD.currentTable, droppedRow); ++ } ++ jQuery.tableDnD.currentTable = null; // let go of the table too ++ } ++ }, ++ ++ serialize: function() { ++ if (jQuery.tableDnD.currentTable) { ++ return jQuery.tableDnD.serializeTable(jQuery.tableDnD.currentTable); ++ } else { ++ return "Error: No Table id set, you need to set an id on your table and every row"; ++ } ++ }, ++ ++ serializeTable: function(table) { ++ var result = ""; ++ var tableId = table.id; ++ var rows = table.rows; ++ for (var i=0; i 0) result += "&"; ++ var rowId = rows[i].id; ++ if (rowId && rowId && table.tableDnDConfig && table.tableDnDConfig.serializeRegexp) { ++ rowId = rowId.match(table.tableDnDConfig.serializeRegexp)[0]; ++ } ++ ++ result += tableId + '[]=' + rowId; ++ } ++ return result; ++ }, ++ ++ serializeTables: function() { ++ var result = ""; ++ this.each(function() { ++ // this is now bound to each matching table ++ result += jQuery.tableDnD.serializeTable(this); ++ }); ++ return result; ++ } ++ ++} ++ ++jQuery.fn.extend( ++ { ++ tableDnD : jQuery.tableDnD.build, ++ tableDnDUpdate : jQuery.tableDnD.updateTables, ++ tableDnDSerialize: jQuery.tableDnD.serializeTables ++ } ++); +\ No newline at end of file +--- eventum-2.3.2/htdocs/list.php~ 2012-03-09 18:19:56.000000000 +0200 ++++ eventum-2.3.2/htdocs/list.php 2012-03-09 18:32:43.998284397 +0200 +@@ -67,6 +67,11 @@ + } + } + ++@$reorder_usr_id = $_REQUEST["reorder_user"]; ++@$reorder_issue_id = $_REQUEST["reorder_source"]; ++@$reorder_neworder = $_REQUEST["reorder_neworder"]; ++Issue::reorderUserIssues($reorder_usr_id, $reorder_issue_id, $reorder_neworder); ++ + if (!empty($_REQUEST['nosave'])) { + $options = Search::saveSearchParams(false); + } else { +@@ -92,6 +97,24 @@ + } + $assign_options += $users; + ++// get the isu_order (assigned users) ordering user ++if (!empty($options["users"])) { ++ if ($options["users"] == -2) { ++ $isu_order_user = $usr_id; ++ } else ++ if ($options["users"] > 0) { ++ $isu_order_user = $options["users"]; ++ } else { ++ unset($isu_order_user); ++ } ++} else { ++ unset($isu_order_user); ++} ++ ++if (isset($isu_order_user)) { ++ $tpl->assign("isu_order_user", $isu_order_user); ++} ++ + $list = Search::getListing($prj_id, $options, $pagerRow, $rows); + $tpl->assign("list", $list["list"]); + $tpl->assign("list_info", $list["info"]); +--- eventum-2.2/lib/eventum/class.display_column.php 2009-09-14 18:07:55.000000000 +0300 ++++ eventum-2.2-order/lib/eventum/class.display_column.php 2009-10-12 22:10:36.429185594 +0300 +@@ -230,7 +230,10 @@ ), "iss_expected_resolution_date" => array( "title" => ev_gettext("Expected Resolution Date") - ) + ), + "isu_order" => array( -+ "title" => ev_gettext("Issue Order") ++ "title" => ev_gettext("Order") + ), ) ); return $columns[$page]; ---- eventum-1.7.0/include/class.issue.php 2005-12-29 21:27:25.000000000 +0200 -+++ eventum/include/class.issue.php 2006-03-27 15:33:02.000000000 +0300 -@@ -1245,6 +1245,7 @@ - Error_Handler::logError(array($res->getMessage(), $res->getDebugInfo()), __FILE__, __LINE__); +--- eventum-2.3.1/lib/eventum/class.issue.php~ 2011-09-15 09:36:55.000000000 +0300 ++++ eventum-2.3.1/lib/eventum/class.issue.php 2011-09-15 09:42:02.844032474 +0300 +@@ -1374,6 +1374,7 @@ return -1; - } else { -+ Issue::moveOrderForAllUsers($issue_id, 1000); - $prj_id = Issue::getProjectID($issue_id); + } - // add note with the reason to close the issue -@@ -1349,7 +1350,6 @@ - $assignment_notifications[] = $assignee; - $assignments_changed = true; - } -- $assignments_changed = true; - } - if (count($assignment_notifications) > 0) { - Notification::notifyNewAssignment($assignment_notifications, $issue_id); -@@ -1596,16 +1596,33 @@ ++ self::moveOrderForAllUsers($issue_id, 1000); + $prj_id = self::getProjectID($issue_id); + + // record the change +@@ -1800,16 +1801,33 @@ { $issue_id = Misc::escapeInteger($issue_id); $assignee_usr_id = Misc::escapeInteger($assignee_usr_id); + $order = 1; + // move all orders down to free "order space" for this new association -+ $stmt = "UPDATE ++ $stmt = "UPDATE + " . APP_DEFAULT_DB . "." . APP_TABLE_PREFIX . "issue_user + SET + isu_order = isu_order + 1 + WHERE + isu_usr_id = $assignee_usr_id AND + isu_order >= $order"; -+ $res = $GLOBALS["db_api"]->dbh->query($stmt); ++ $res = DB_Helper::getInstance()->query($stmt); + if (PEAR::isError($res)) { + Error_Handler::logError(array($res->getMessage(), $res->getDebugInfo()), __FILE__, __LINE__); + return -1; @@ -60,13 +583,13 @@ ) VALUES ( $issue_id, $assignee_usr_id, -- '" . Date_API::getCurrentDateGMT() . "' -+ '" . Date_API::getCurrentDateGMT() . "', +- '" . Date_Helper::getCurrentDateGMT() . "' ++ '" . Date_Helper::getCurrentDateGMT() . "', + $order )"; - $res = $GLOBALS["db_api"]->dbh->query($stmt); + $res = DB_Helper::getInstance()->query($stmt); if (PEAR::isError($res)) { -@@ -1620,6 +1637,78 @@ +@@ -1824,6 +1842,78 @@ } } @@ -85,11 +608,11 @@ + " . APP_DEFAULT_DB . "." . APP_TABLE_PREFIX . "issue_user + WHERE + isu_iss_id IN ($issue_id)"; -+ if ($usr_id !== FALSE) { ++ if (!empty($usr_id)) { + $stmt.= " AND isu_usr_id IN ($usr_id)"; + } + $stmt.= "ORDER BY isu_order"; -+ $res = $GLOBALS["db_api"]->dbh->getAll($stmt, DB_FETCHMODE_ASSOC); ++ $res = DB_Helper::getInstance()->getAll($stmt, DB_FETCHMODE_ASSOC); + if (PEAR::isError($res)) { + Error_Handler::logError(array($res->getMessage(), $res->getDebugInfo()), __FILE__, __LINE__); + return -1; @@ -132,7 +655,7 @@ + $stmt.= " AND + isu_order < " . $orders[$i+1]; + } -+ $res = $GLOBALS["db_api"]->dbh->query($stmt); ++ $res = DB_Helper::getInstance()->query($stmt); + if (PEAR::isError($res)) { + Error_Handler::logError(array($res->getMessage(), $res->getDebugInfo()), __FILE__, __LINE__); + return -1; @@ -145,76 +668,31 @@ /** * Method used to delete all user assignments for a specific issue. -@@ -1635,6 +1724,7 @@ +@@ -1839,6 +1929,7 @@ if (is_array($issue_id)) { $issue_id = implode(", ", $issue_id); } -+ $deleted_order_list = Issue::getDeleteUserAssociationOrderList($issue_id); ++ $deleted_order_list = self::getDeleteUserAssociationOrderList($issue_id); $stmt = "DELETE FROM " . APP_DEFAULT_DB . "." . APP_TABLE_PREFIX . "issue_user WHERE -@@ -1647,6 +1737,7 @@ - if ($usr_id) { - History::add($issue_id, $usr_id, History::getTypeID('user_all_unassociated'), 'Issue assignments removed by ' . User::getFullName($usr_id)); - } -+ Issue::rearrangeDeleteUserAsssociationOrderList($deleted_order_list); - return 1; - } - } -@@ -1665,6 +1756,7 @@ +@@ -1869,6 +1960,7 @@ { $issue_id = Misc::escapeInteger($issue_id); $usr_id = Misc::escapeInteger($usr_id); -+ $delete_order_list = Issue::getDeleteUserAssociationOrderList($issue_id, $usr_id); ++ $delete_order_list = self::getDeleteUserAssociationOrderList($issue_id, $usr_id); $stmt = "DELETE FROM " . APP_DEFAULT_DB . "." . APP_TABLE_PREFIX . "issue_user WHERE -@@ -1679,6 +1771,7 @@ - History::add($issue_id, Auth::getUserID(), History::getTypeID('user_unassociated'), - User::getFullName($usr_id) . ' removed from issue by ' . User::getFullName(Auth::getUserID())); - } -+ Issue::rearrangeDeleteUserAssociationOrderList($delete_order_list); - return 1; +@@ -2020,6 +2021,7 @@ + History::add($issue_id, Auth::getUserID(), History::getTypeID('user_unassociated'), + User::getFullName($usr_id) . ' removed from issue by ' . User::getFullName(Auth::getUserID())); } ++ self::rearrangeDeleteUserAssociationOrderList($delete_order_list); + return 1; } -@@ -2047,14 +2140,6 @@ - } - } - } -- if (count($users) > 0) { -- // automatically change the status to 'Assigned' -- Issue::setStatus($new_issue_id, Status::getStatusID('Assigned'), FALSE); -- -- // set this special variable to false, to avoid triggering -- // another status update on the workflow class -- $has_assignee = false; -- } - // now process any files being uploaded - $found = 0; -@@ -2161,6 +2246,11 @@ - { - $sort_by = Issue::getParam('sort_by'); - $sort_order = Issue::getParam('sort_order'); -+ $users = Issue::getParam('users'); -+ if (empty($users) && ($sort_by == 'isu_order')) { // Sorting by isu_order is impossible when no user specified -+ unset($sort_by); -+ unset($sort_order); -+ } - $rows = Issue::getParam('rows'); - $hide_closed = Issue::getParam('hide_closed'); - if ($hide_closed === '') { -@@ -2261,7 +2351,8 @@ - "iss_summary", - "last_action_date", - "usr_full_name", -- "iss_expected_resolution_date" -+ "iss_expected_resolution_date", -+ "isu_order" - ); - $items = array( - "links" => array(), -@@ -2975,6 +3066,8 @@ +@@ -3253,6 +3352,8 @@ $ids = implode(", ", $ids); $stmt = "SELECT isu_iss_id, @@ -223,7 +701,7 @@ usr_full_name FROM " . APP_DEFAULT_DB . "." . APP_TABLE_PREFIX . "issue_user, -@@ -2986,6 +3079,7 @@ +@@ -3264,6 +3365,7 @@ if (PEAR::isError($res)) { Error_Handler::logError(array($res->getMessage(), $res->getDebugInfo()), __FILE__, __LINE__); } else { @@ -231,7 +709,7 @@ $t = array(); for ($i = 0; $i < count($res); $i++) { if (!empty($t[$res[$i]['isu_iss_id']])) { -@@ -2994,9 +3088,18 @@ +@@ -3272,9 +3374,18 @@ $t[$res[$i]['isu_iss_id']] = $res[$i]['usr_full_name']; } } @@ -250,17 +728,17 @@ } } } -@@ -3963,6 +4066,7 @@ +@@ -4247,6 +4358,7 @@ Error_Handler::logError(array($res->getMessage(), $res->getDebugInfo()), __FILE__, __LINE__); return -1; } -+ Issue::moveOrderForAllUsers($issue_id, 1); ++ self::moveOrderForAllUsers($issue_id, 1); } -@@ -4021,8 +4125,91 @@ - } - return $returns[$msg_id]; +@@ -4346,4 +4458,120 @@ + History::add($issue_id, Auth::getUserID(), History::getTypeID('user_associated'), + "Issue assignment to changed (" . History::formatChanges(join(', ', $old_assignee_names), join(', ', $assignee_names)) . ") by " . User::getFullName(Auth::getUserID())); } + + /** @@ -291,8 +769,8 @@ + $issue_id = array($issue_id); + } + // do a nasty pretending to be deleting stuff so that reordering happens as if these elements were deleted -+ $orderlist = Issue::getDeleteUserAssociationOrderList($issue_id_str, $usr_id); -+ Issue::rearrangeDeleteUserAssociationOrderList($orderlist); ++ $orderlist = self::getDeleteUserAssociationOrderList($issue_id_str, $usr_id); ++ self::rearrangeDeleteUserAssociationOrderList($orderlist); + // move down the orders to free the "order space" needed + $stmt = "UPDATE + " . APP_DEFAULT_DB . "." . APP_TABLE_PREFIX . "issue_user @@ -301,7 +779,7 @@ + WHERE + isu_usr_id = $usr_id AND + isu_order >= $neworder"; -+ $res = $GLOBALS["db_api"]->dbh->query($stmt); ++ $res = DB_Helper::getInstance()->query($stmt); + if (PEAR::isError($res)) { + Error_Handler::logError(array($res->getMessage(), $res->getDebugInfo()), __FILE__, __LINE__); + return -1; @@ -316,7 +794,7 @@ + WHERE + isu_usr_id = $usr_id AND + isu_iss_id = $iss_id"; -+ $res = $GLOBALS["db_api"]->dbh->query($stmt); ++ $res = DB_Helper::getInstance()->query($stmt); + if (PEAR::isError($res)) { + Error_Handler::logError(array($res->getMessage(), $res->getDebugInfo()), __FILE__, __LINE__); + return -1; @@ -325,6 +803,42 @@ + } + } + ++ ++ /** ++ * Get users issue order list ++ * @access public ++ * @param $user_id User ++ * @param $order_list Order of the issues ++ * @return void ++ */ ++ function getIssueOrderByUser($usr_id) { ++ ++ if (!is_numeric($usr_id)) { ++ return false; ++ } ++ ++ $stmt = "SELECT ++ isu_iss_id, isu_order ++ FROM ++ " . APP_DEFAULT_DB . "." . APP_TABLE_PREFIX . "issue_user ++ WHERE ++ isu_usr_id = " . $usr_id ; ++ ++ $order_list = array(); ++ ++ $res = DB_Helper::getInstance()->getAll($stmt, DB_FETCHMODE_ASSOC); ++ ++ if (PEAR::isError($res)) { ++ Error_Handler::logError(array($res->getMessage(), $res->getDebugInfo()), __FILE__, __LINE__); ++ return array(); ++ } else { ++ foreach ($res as $row) { ++ $order_list[$row["isu_iss_id"]] = $row["isu_order"]; ++ } ++ } ++ return $order_list; ++ } ++ + function moveOrderForAllUsers($issue_id, $neworder) + { + // Move the issue to the top priority for the ppl it's assigned to @@ -332,64 +846,53 @@ + " . APP_DEFAULT_DB . "." . APP_TABLE_PREFIX . "issue_user + WHERE + isu_iss_id = " . Misc::escapeInteger($issue_id); -+ $res = $GLOBALS["db_api"]->dbh->getAll($stmt, DB_FETCHMODE_ASSOC); ++ $res = DB_Helper::getInstance()->getAll($stmt, DB_FETCHMODE_ASSOC); + if (PEAR::isError($res)) { + Error_Handler::logError(array($res->getMessage(), $res->getDebugInfo()), __FILE__, __LINE__); + return -1; + } + foreach ($res as $row) { -+ Issue::reorderUserIssues($row["isu_usr_id"], $issue_id, $neworder); ++ self::reorderUserIssues($row["isu_usr_id"], $issue_id, $neworder); + } + } + } +--- eventum-2.3.1/lib/eventum/class.search.php~ 2011-04-20 17:22:15.000000000 +0300 ++++ eventum-2.3.1/lib/eventum/class.search.php 2011-04-20 17:44:34.498519260 +0300 +@@ -63,6 +63,12 @@ + { + $sort_by = self::getParam('sort_by'); + $sort_order = self::getParam('sort_order'); ++ $users = self::getParam('users'); ++ if (empty($users) && $sort_by === 'isu_order') { ++ // Sorting by isu_order is impossible when no user specified ++ unset($sort_by); ++ unset($sort_order); ++ } + $rows = self::getParam('rows'); + $hide_closed = self::getParam('hide_closed'); + if ($hide_closed === '') { +@@ -174,6 +174,7 @@ + "iss_expected_resolution_date" => "desc", + "pre_title" => "asc", + "assigned" => "asc", ++ "isu_order" => "desc", + ); -+ -+ -+ - // benchmarking the included file (aka setup time) - if (APP_BENCHMARK) { - $GLOBALS['bench']->setMarker('Included Issue Class'); -diff -ru eventum-1.7.0/list.php eventum/list.php ---- eventum-1.7.0/list.php 2005-12-29 21:27:24.000000000 +0200 -+++ eventum/list.php 2006-03-30 14:57:06.000000000 +0300 -@@ -67,6 +67,11 @@ - $profile['sort_by'] . "&sort_order=" . $profile['sort_order']); - } - -+@$reorder_usr_id = $_REQUEST["reorder_user"]; -+@$reorder_issue_id = $_REQUEST["reorder_source"]; -+@$reorder_neworder = $_REQUEST["reorder_neworder"]; -+Issue::reorderUserIssues($reorder_usr_id, $reorder_issue_id, $reorder_neworder); -+ - $options = Issue::saveSearchParams(); - $tpl->assign("options", $options); - $tpl->assign("sorting", Issue::getSortingInfo($options)); -@@ -104,6 +109,21 @@ - } - } - -+// get the isu_order (assignated users) ordering user -+if (!empty($options["users"])) { -+ if ($options["users"] == -2) { -+ $isu_order_user = $usr_id; -+ } else -+ if ($options["users"] > 0) { -+ $isu_order_user = $options["users"]; -+ } else { -+ unset($isu_order_user); -+ } -+} else { -+ unset($isu_order_user); -+} -+$tpl->assign("isu_order_user", $isu_order_user); -+ - $list = Issue::getListing($prj_id, $options, $pagerRow, $rows); - $tpl->assign("list", $list["list"]); - $tpl->assign("list_info", $list["info"]); ---- eventum-1.7.0/templates/list.tpl.html 2005-12-29 21:27:24.000000000 +0200 -+++ eventum/templates/list.tpl.html 2006-03-23 16:28:30.000000000 +0200 -@@ -89,6 +89,28 @@ + foreach ($custom_fields as $fld_id => $fld_name) { +--- eventum-2.3.1/templates/header.tpl.html~ 2011-09-15 09:36:55.000000000 +0300 ++++ eventum-2.3.1/templates/header.tpl.html 2011-09-15 09:43:49.318473817 +0300 +@@ -18,6 +18,7 @@ + + + ++ + + + +--- eventum-2.2/templates/list.tpl.html 2009-09-14 18:07:55.000000000 +0300 ++++ eventum-2.2-order/templates/list.tpl.html 2009-10-12 22:10:36.439185157 +0300 +@@ -92,6 +92,28 @@ f.target = '_popup'; f.submit(); } @@ -418,69 +921,132 @@ diff -ru eventum-1.7.0/list.php eventum/list.php function hideClosed(f) { if (f.hide_closed.checked) { -@@ -202,8 +224,8 @@ - - {$fld_title|escape:"html"} +@@ -153,6 +175,13 @@ + f.go.disabled = true; + } + } ++function updateCustomFields(issue_id) ++{ ++ var features = 'width=560,height=460,top=30,left=30,resizable=yes,scrollbars=yes,toolbar=no,location=no,menubar=no,status=no'; ++ var customWin = window.open('custom_fields.php?issue_id=' + issue_id, '_custom_fields', features); ++ customWin.focus(); ++ return false; ++} + //--> + + {/literal} +@@ -169,11 +198,11 @@ + + + +- +- ++
++ + + +- ++ + {if $current_role > $roles.developer} + -- {/foreach} + {/foreach} - {else} -+ {/foreach} + {elseif $field_name != 'isu_order' || $isu_order_user} ++ + {section name="i" loop=$list} +- = $roles.developer AND $list[i].iqu_status > 0}style="text-decoration: line-through;"{/if}> ++ = $roles.developer AND $list[i].iqu_status > 0}style="text-decoration: line-through;"{/if} id="{$list[i].iss_id}" {if !$list[i].assigned_users_order[$current_user_id]}class="nodrag"{/if}> + {if $current_role > $roles.developer} + + {/if} +@@ -280,8 +281,8 @@ {$fld_value|formatCustomValue:$fld_id:$list[i].iss_id} {/foreach} - {else} +- {/if} ---- /dev/null 2006-03-28 14:00:37.000000000 +0300 -+++ ./order_patch-patch.sql 2008-08-27 17:16:21.444016830 +0300 -@@ -0,0 +1,3 @@ -+ALTER TABLE eventum_issue_user -+ ADD isu_order int(11) NOT NULL DEFAULT '0' AFTER isu_assigned_date, -+ ADD INDEX isu_order (isu_order); +@@ -300,10 +332,11 @@ + + + {/section} +- ++ ++ +
+ +- ++ +
+ {t}Search Results{/t} ({$list_info.total_rows} {t}issues found{/t}{if $list_info.end_offset > 0}, {math equation="x + 1" x=$list_info.start_offset} - {$list_info.end_offset} {t}shown{/t}{/if}) + {include file="help_link.tpl.html" topic="list"} +@@ -193,7 +222,7 @@ +
+
+ +@@ -208,7 +237,7 @@ + {if $sorting.images[$fld_name_id] != ""}{/if} {if $field_name == 'iss_summary'} -@@ -218,8 +240,11 @@ - -
- {elseif $sorting.links[$field_name] != ''} -- {$column.title} -- {if $sorting.images[$field_name] != ""}{/if} -+ {$column.title} -+ {if $field_name == 'isu_order'} -+
{$users[$isu_order_user]} -+ {/if} -+ {if $sorting.images[$field_name] != ""}{/if} - {else} - {$column.title} - {/if} -@@ -239,7 +264,7 @@ +@@ -268,8 +268,9 @@ + {/if} + {/foreach} +
+ {elseif $field_name != 'isu_order' || $isu_order_user} - ++ {if $field_name == 'iss_id'} - {$list[i].iss_id} -@@ -278,7 +303,24 @@ - {/if} + {$list[i].iss_id} + {elseif $field_name == 'pri_rank'} +@@ -288,6 +318,8 @@ {if $list[i].iss_private == 1} [Private] -- {/if} -+ {/if} -+ {elseif $field_name == 'isu_order'} -+ {if $isu_order_user} -+ {assign var="order" value=$list[i].assigned_users_order[$isu_order_user]} -+ {if $order} -+ {$order} -+
+ +- ++ +
+ {if $current_role > $roles.developer} + +@@ -355,6 +388,35 @@ + +
+
+- ++ + {include file="app_info.tpl.html"} + {include file="footer.tpl.html"}