// Modified by mac (zgqinv402@sneakemail.com) // No warranty is provided. Use at your own risk. // // Name: todo.php // Author: Julian I. Kamil // Created: 2005-03-17 // Description: // This is a PmWiki plugin that provides the capability // to manage a list of to do items. // // History: // 2005-06-22 mac Added "Asigned to" field // 2005-03-17 jik Created. // 2005-03-18 jik Added the ability to filter todo lists // by status and category. // Added simple list view with checkboxes // to complete items. // Sorted items in the list by its titles. // Added the ability to display a form // with a fixed category. // 2005-03-23 jik Merged changes made by Didier Lebrun, // which added the following capabilities: // - fixed URLs in ToDoList() // - sort on any field // - allow any group // - allow customized options lists // - allow custom labels // Fixed a bug in listing current pages // when creating a new item. // Fixed a bug that caused the category // name to disappear when a fixed category // is selected in the form. // Added the ability to select completed // items by month, sorted by date. // 2005-03-24 jik Fixed the problem with selection and // sorting in table and simple lists. // Sorted simple lists by priority * urgency // as a default. // Highlighted overdue items, which works // on PHP 5 but not on PHP 4. // 2005-03-28 jik Integrated changes proposed by Petko // Yotov which allow field titles that do // not strt with letters in the A-Za-z range. // This is useful for internationalized field // titles. // Made the link text decoration style // attribute to be specific to todo-list and // todo-simple-list. // // Initials: // jik - Julian I. Kamil // dl - Didier Lebrun // py - Petko Yotov // mac - Magnus Carlsson if (!defined('PmWiki')) { exit(); } define(TODO_VERSION, '0.3.5'); // These values can be customized in 'local/config.php'. // // START customizable values definition // SDV($ToDoGroup, 'TODO'); SDV( $todo_priority_names, array( '5' => 'High', '4' => 'Medium high', '3' => 'Medium', '2' => 'Medium low', '1' => 'Low' ) ); SDV( $todo_urgency_names, array( '5' => 'High', '4' => 'Medium high', '3' => 'Medium', '2' => 'Medium low', '1' => 'Low' ) ); SDV( $todo_status_names, array( 'Open', 'In progress', 'On hold', 'Completed', 'Overdue' ) ); SDV( $todo_category_names, array( 'Personal', 'Business', 'Other' ) ); SDV( $todo_field_names, array( 'ID', 'Category', 'Status', 'Priority', 'Urgency', 'Create Date', 'Due date', 'Assigned To', 'Description' ) ); SDV( $todo_delay_names, array( 'tomorrow', 'next week', ) ); SDV( $todo_assign_names, array( '-', 'Joe Smith', 'John Doe', 'Jane Doe' ) ); SDV($todo_date_format, 'Y-m-d'); SDV($todo_submit_button, 'submit'); SDV($todo_edit_button, 'edit'); // // END customizable values definition // markup( 'todoform', 'inline', '/\\(:todoform\\s*(.*?):\\)/e', "ToDoForm('', \$pagename, array('q' => PSS('$1')))" ); markup( 'todolist', 'directive', '/\\(:todolist\\s*(.*?):\\)/e', "ToDoList('', \$pagename, array('q' => PSS('$1')))" ); markup( 'todosimplelist', 'directive', '/\\(:todosimplelist\\s*(.*?):\\)/e', "ToDoSimpleList('', \$pagename, array('q' => PSS('$1')))" ); function CompareToDoListItem($item1, $item2) { if ($item1 == $item2) { return 1; } return ($item1 < $item2) ? -1 : 1; } function GetDirectiveArgs($arguments, $defaults = array()) { $terms = preg_split( '/((?\n" ; } for ($index = 1; $index <= count($todo_urgency_names); $index++) { $todo_urgency_code .= "\n" ; } $todo_status_code = ''; $todo_assign_code = ''; if (empty($selected_category)) { $todo_category_code = ''; } else { $todo_category_code = "$selected_category"; $todo_category_hidden_code = ""; } $todo_priority_low = $todo_priority_names[min(array_keys($todo_priority_names))]; $todo_priority_high = $todo_priority_names[max(array_keys($todo_priority_names))]; $todo_urgency_low = $todo_urgency_names[min(array_keys($todo_priority_names))]; $todo_urgency_high = $todo_urgency_names[max(array_keys($todo_priority_names))]; $create_date = date($todo_date_format); $tomorrow_date = date($todo_date_format, mktime(0, 0, 0, date('m'), date('d')+1, date('Y'))); $next_week_date = date($todo_date_format, mktime(0, 0, 0, date('m'), date('d')+7, date('Y'))); $output[] = <<< EOT
{$todo_category_hidden_code}
$todo_field_names[1]: {$todo_category_code}
$todo_field_names[2]: {$todo_status_code}
$todo_field_names[3]: {$todo_priority_low} {$todo_priorities_code} {$todo_priority_high}
$todo_field_names[4]: {$todo_urgency_low} {$todo_urgency_code} {$todo_urgency_high}
$todo_field_names[5]: {$create_date}:
$todo_field_names[6]:
{$tomorrow_date} $todo_delay_names[0]
{$next_week_date} $todo_delay_names[1]
$todo_field_names[7]: {$todo_assign_code}
$todo_field_names[8]:
EOT; return FmtPageName(implode('', $output), $pagename); } $HTMLStylesFmt[] = <<< EOT .todo-form { border: 1px none #aaa; text-decoration: none; } .todo-form tr td { font-weight: plain; text-align: left; padding: 4px; } .todo-form tr td.heading { text-align: right; width: 200px; padding-right: 6px; } .todo-simple-list { padding-left: 0px; list-style: none; } .todo-simple-list li { padding-bottom: 6px; } .todo-list { border: 1px solid #aaa; text-decoration: none; } .todo-list thead tr td { font-weight: plain; text-align: left; padding-top: 4px; padding-bottom: 4px; padding-left: 8px; padding-right: 8px; border-top: 1px solid #aaa; border-bottom: 1px solid #666; border-right: 1px solid #aaa; background-color: #ccc; } .todo-list thead tr td.first { border-left: 1px solid #aaa; } .todo-list tbody tr td { padding-top: 4px; padding-bottom: 4px; padding-left: 8px; padding-right: 8px; border-bottom: 1px solid #aaa; border-right: 1px solid #aaa; } .todo-list tbody tr td.first { border-left: 1px solid #aaa; } .todo-list tbody tr td.bottom { border-bottom: 1px solid #666; } .todo-list tbody tr td.description { background-color: #eee; } .todo-list tbody tr td div { padding: none; padding-top: 4px; padding-bottom: 4px; } .todo-list tbody tr td div.heading { border-bottom: 1px solid #aaa; } .todo-list a { text-decoration: none; } .todo-simple-list a { text-decoration: none; } EOT; include_once("$FarmD/scripts/author.php"); if ($action=='posttodo') { Lock(2); foreach(ListPages("/^$ToDoGroup\\.\\d/") as $i) { $todo = max(@$todo, substr($i, 5)); } $pagename = sprintf("$ToDoGroup.%05d", @$todo+1); $action = 'edit'; $_REQUEST['post'] = 1; $priority = $todo_priority_names[$_REQUEST['todo-priority']]; $urgency = $todo_urgency_names[$_REQUEST['todo-urgency']]; $_POST['text'] = <<< EOT $todo_field_names[1]: {$_REQUEST['todo-category']} $todo_field_names[2]: {$_REQUEST['todo-status']} $todo_field_names[3]: {$_REQUEST['todo-priority']} -- {$priority} $todo_field_names[4]: {$_REQUEST['todo-urgency']} -- {$urgency} $todo_field_names[5]: {$_REQUEST['todo-create-date']} $todo_field_names[6]: {$_REQUEST['todo-due-date']} $todo_field_names[7]: {$_REQUEST['todo-assign']} $todo_field_names[8]: {$_REQUEST['todo-description']} EOT; } else if ($action == 'completetodo') { $pagename= 'foobar'; $action = 'edit'; $_REQUEST['post'] = 1; $completed_items = $_REQUEST['complete']; foreach ($completed_items as $completed_item) { $page = ReadPage($completed_item); $replaced = preg_replace("/(^|\n)Status:( )*(\w+)( )*/", "\nStatus: Completed", $page['text']); $match_count = preg_match("/(^|\n)Completed date:( )*(\w+)( )*/", $replaced); $completed_date = $_REQUEST['todo-complete-date']; if ($match_count == 0) { $_POST['text'] .= "REPLACED\n" . $completed_item . "\n\n" . $replaced . "\n\nCompleted date: " . $completed_date . "\n" . "END REPLACED\n\n"; } else { $replaced = preg_replace("/(^|\n)Completed date:( )*(.+)( )*/", "\nCompleted date: $completed_date", $replaced); $_POST['text'] .= "REPLACED\n" . $completed_item . "\n\n" . $replaced . "END REPLACED\n\n"; } } } function ToDoList($format, $pagename, $options) { global $ToDoGroup, $todo_field_names; $settings['status'] = 'All'; $settings['category'] = 'All'; $arguments = GetDirectiveArgs($options, $settings); if (isset($_GET['order'])) { $order = $_GET['order']; } elseif (isset($_POST['order'])) { $order = $_POST['order']; } else { $order = ''; } $output[] = <<< EOT EOT; $output[] = <<< EOT EOT; $todo_list = ListPages("/^$ToDoGroup\\.\\d+$/"); foreach ($todo_list as $todo_item) { $page = ReadPage($todo_item); preg_match_all( "/(^|\n)([^:]*?):([^\n]*)/", // "/(^|\n)([A-Za-z][^:]*):([^\n]*)/", $page['text'], $match ); $title_parts = split('\.', $todo_item); $category = split(':', $match[0][0]); $status = split(':', $match[0][1]); $priority = split(':', $match[0][2]); $numeric_priority = split('--', $priority[1]); $urgency = split(':', $match[0][3]); $numeric_urgency = split('--', $urgency[1]); $create_date = split(':', $match[0][4]); $due_date = split(':', $match[0][5]); $description = split(':', $match[0][7]); $assign = split(':', $match[0][6]); $display = TRUE; if ( ! empty($arguments['assign']) && ! ($arguments['assign'] === 'All') && ! (trim($assign[1]) === $arguments['assign']) ) { $display = FALSE; } if ( ! empty($arguments['status']) && ! ($arguments['status'] === 'All') && ! (trim($status[1]) === $arguments['status']) ) { $display = FALSE; } if ( $display && ! empty($arguments['category']) && ! ($arguments['category'] === 'All') && ! (trim($category[1]) === $arguments['category']) ) { $display = FALSE; } if ($display) { $todo_items[] = array( id => $title_parts[1], category => $category[1], status => $status[1], priority => $priority[1], numeric_priority => $numeric_priority[0], urgency => $urgency[1], numeric_urgency => $numeric_urgency[0], create_date => $create_date[1], due_date => $due_date[1], description => $description[1], assign => $assign[1] ); if ($order) { $sort_field[] = ${$order}[1]; } } } if ($order) { array_multisort($sort_field, SORT_DESC, $todo_items); } if (count($todo_items) > 0) { foreach ($todo_items as $item) { $output[] = <<< EOT EOT; } } $output[] = <<< EOT
[[{$pagename}?order=id | $todo_field_names[0]]] [[{$pagename}?order=status | $todo_field_names[2]]] [[{$pagename}?order=priority | $todo_field_names[3]]] [[{$pagename}?order=urgency | $todo_field_names[4]]] [[{$pagename}?order=create_date | $todo_field_names[5]]] [[{$pagename}?order=due_date | $todo_field_names[6]]] [[{$pagename}?order=assign | $todo_field_names[7]]]
[[{$ToDoGroup}.{$item['id']} | {$item['id']}]]
[[{$ToDoGroup}.{$item['id']}?action=edit | {$todo_submit_button}]]
{$item['status']} {$item['numeric_priority']} {$item['numeric_urgency']} {$item['create_date']} {$item['due_date']} {$item['assign']}
{$item['category']} — {$item['description']}
EOT; return FmtPageName(implode('', $output), $pagename); } function ToDoSimpleList($format, $pagename, $options) { global $ToDoGroup, $todo_field_names; $settings['status'] = 'All'; $settings['category'] = 'All'; $settings['assign'] = 'All'; $arguments = GetDirectiveArgs($options, $settings); $todo_list = ListPages("/^$ToDoGroup\\.\\d+$/"); usort($todo_list, "CompareToDoListItem"); $sort_by_completed_date = FALSE; $sort_order = SORT_DESC; $unix_now_time = strtotime("now"); foreach ($todo_list as $todo_item) { $page = ReadPage($todo_item); preg_match_all( "/(^|\n)([^:]*?):([^\n]*)/", // "/(^|\n)([A-Za-z][^:]*):([^\n]*)/", $page['text'], $match ); $title_parts = split('\.', $todo_item); $category = split(':', $match[0][0]); $status = split(':', $match[0][1]); $priority = split(':', $match[0][2]); $numeric_priority = split('--', $priority[1]); $urgency = split(':', $match[0][3]); $numeric_urgency = split('--', $urgency[1]); $create_date = split(':', $match[0][4]); $due_date = split(':', $match[0][5]); $description = split(':', $match[0][7]); $completed_date = split(':', $match[0][8]); $assign = split(':', $match[0][6]); $description_text = trim($description[1]); $completed_date_text = str_replace("-", "", trim($completed_date[1])); $todo_rank = trim($numeric_priority[0]) * trim($numeric_urgency[0]); $display = TRUE; if ( ! empty($arguments['assign']) && ! ($arguments['assign'] === 'All') && ! (trim($assign[1]) === $arguments['assign']) ) { $display = FALSE; } if ( ! empty($arguments['status']) && ! ($arguments['status'] === 'All') && ! (trim($status[1]) === $arguments['status']) ) { $display = FALSE; } if ( $display && ! empty($arguments['category']) && ! ($arguments['category'] === 'All') && ! (trim($category[1]) === $arguments['category']) ) { $display = FALSE; } if ( $display && ! empty($arguments['month']) && ! ($arguments['month'] === 'All') ) { if (! empty($completed_date_text)) { $month_argument = explode("-", $arguments['month']); $unix_time = strtotime($completed_date_text); $display = ($month_argument[1] == date("m", $unix_time)) && ($month_argument[0] == date("Y", $unix_time)) ? TRUE : FALSE; $this_completed_date = substr(trim($completed_date[1]), 8, 2); $sort_by_completed_date = TRUE; $sort_order = SORT_ASC; $sort_field[] = $this_completed_date; $show_date_code = "[" . $this_completed_date . "] "; } else { $display = FALSE; } } if ($display) { $checked_flag = (trim($status[1]) === 'Completed') ? 'checked' : ''; $original_status = trim($status[1]); $original_status_code = ""; $unix_due_time = strtotime(trim($due_date[1])); $overdue = (($unix_due_time < $unix_now_time) && ! $checked_flag) ? TRUE : FALSE; if (! $sort_by_completed_date) { $sort_field[] = $todo_rank; if (! $overdue) { $show_date_code = "[" . trim($numeric_priority[0]) . "," . trim($numeric_urgency[0]) //. "," //. $unix_due_time //. "," //. $unix_now_time //. "," //. trim($due_date[1]) . "] " ; } else { $show_date_code = "%red%[" . trim($numeric_priority[0]) . "," . trim($numeric_urgency[0]) //. "," //. $unix_due_time //. "," //. $unix_now_time //. "," //. trim($due_date[1]) . "]%% " ; } } $todo_items[] = array( todo_rank => $todo_rank, id => $todo_item, status => trim($status[1]), original_status_code => $original_status_code, checked_flag => $checked_flag, completed_date_text => $completed_date_text, this_completed_date => $this_completed_date, show_date_code => $show_date_code, due_date => trim($due_date[1]), description_text => $description_text, assign => trim($assign[1]) ); } } $rc = array_multisort($sort_field, $sort_order, $todo_items); $output[] = <<< EOT
    EOT; foreach ($todo_items as $item) { $output[] = <<< EOT
  • {$item['show_date_code']}{$item['description_text']} (edit){$item['original_status_code']}
  • EOT; } if (count($todo_items) > 0) { $submit_code = ""; // ""; } else { $submit_code = "No matching to do items found."; } $output[] = <<< EOT
{$submit_code}
EOT; return FmtPageName(implode('', $output), $pagename); } ?>