array('name' => t('task'), 'base' => 'tasks'), ); } // Implementation of hook_perm(). function tasks_perm() { return array('create task', 'edit own task', 'edit all tasks', 'access tasks main page'); } // Implementation of hook_access(). function tasks_access($op, $node) { global $user; if ($op == 'create') { return user_access('create task'); } if ($op == 'update' || $op == 'delete') { if (user_access('edit all tasks') || (user_access('edit own tasks') && ($user->uid == $node->uid))) { return TRUE; } } } // Implementation of hook_menu(). function tasks_menu($may_cache) { $items = array(); if ($may_cache) { $items[] = array( 'path' => 'node/add/tasks', 'title' => t('task'), 'access' => user_access('create task') ); $items[] = array( 'path' => 'tasks', 'title' => t('Tasks'), 'callback' => '_tasks_main', 'access' => user_access('access tasks main page'), 'type' => MENU_CALLBACK ); } return $items; } // hook_user implementations function tasks_user($op, &$edit, &$user, $category = NULL) { if($op == "form") { $form['tasklist'] = array( '#type' => 'fieldset', '#title' => t('Tasklist'), '#collapsible' => TRUE, '#weight' => 4 ); $form['tasklist']['tasks_colour'] = array( '#type' => 'textfield', '#title' => t('Colour'), '#default_value' => $edit['tasks_colour'], '#description' => t('This will be the colour this user\'s tasks will appear in. Hexdecimal or recognized colour name (e.g. #eee or just \'blue\')') ); return $form; } } // Implementation of hook_form(). function tasks_form(&$node) { drupal_add_js(drupal_get_path('module', 'tasks').'/tasks.js'); theme_add_style(drupal_get_path('module', 'tasks').'/tasks.css'); $bc = drupal_get_breadcrumb(); $bc[] = l(t('Tasks'), 'tasks'); drupal_set_breadcrumb($bc); $form = array(); // Get a list of tasklists to choose a parent tasklist if (!isset($node->parent) || $node->parent != 0) { $result = db_query("SELECT n.*, t.* FROM {node} n INNER JOIN {tasks} t ON n.nid = t.nid WHERE n.type='tasks' AND t.completed = '0000-00-00' ORDER BY IF(t.parent = 0,0,1), n.title ASC"); while ($tasklist = db_fetch_object($result)) { if ($tasklist->parent == 0) { $tasklist->title = t('-- MASTER TASKLIST --'); } $tasklists[$tasklist->nid] = $tasklist->title; $not_master = 1; } if (!$not_master) $tasklists[0] = t('NO PARENT - THIS IS THE MASTER TASKLIST'); if (isset($_GET['edit']['parent'])) { $node->parent = $_GET['edit']['parent']; } $form['parent'] = array( '#type' => 'select', '#title' => t('Parent Tasklist'), '#default_value' => $node->parent, '#options' => $tasklists, '#weight' => -10 ); } else { // parent tasklist $form['parent'] = array( '#type' => 'value', '#value' => 0 ); } $form['title'] = array( '#type' => 'textfield', '#title' => t('Task Name'), '#required' => TRUE, '#default_value' => $node->title ); $form['body'] = array( '#type' => 'textarea', '#title' => t('About this task'), '#default_value' => $node->body, '#rows' => 10 ); $form['format'] = filter_form($node->format); $sql = 'SELECT u.uid, u.name, u.status, u.created, u.access FROM {users} u WHERE uid != 0'; $result = db_query($sql); $users[0] = t('-- Unassigned --'); while ($account = db_fetch_object($result)) { $users[$account->uid] = $account->name; } $form['assigned_to'] = array( '#type' => 'select', '#title' => t('Assign to user'), '#default_value' => $node->assigned_to, '#options' => $users ); $form['completed'] = array( '#type' => 'checkbox', '#title' => t('Completed?'), '#default_value' => ($node->completed > 0)?1:0, '#attributes' => array("onclick"=>"toggletasks();") ); $form['completed_date'] = array( '#type' => 'date', '#title' => t('Date Completed'), '#prefix' => '
', '#suffix' => '
' ); if ($node->completed != '0000-00-00') $form['completed_date']['#default_value'] = $node->completed_date; $form['from'] = array( '#type' => 'hidden', '#value' => arg(3) ); if ($node->parent) { $result = db_query("SELECT n.*, t.* FROM {node} n, {tasks} t WHERE n.type='tasks' AND t.nid = n.nid AND t.completed = '0000-00-00' AND t.parent = $node->parent ORDER BY t.order_by ASC"); while ($tasklist = db_fetch_object($result)) { if ($tasklist->nid == $node->nid) { $tasks[$tasklist->order_by] = t('*************** NO CHANGE ***************'); } else { $tasks[$tasklist->order_by] = $tasklist->title; } } $tasks['10000'] = t('*** bottom of list ***'); $form['order_by'] = array( '#type' => 'select', '#title' => t('Place in tasklist above'), '#default_value' => $node->order_by, '#options' => $tasks, '#prefix' => '
', '#suffix' => '
' ); } else { $form['order_by'] = array( '#type' => 'hidden', '#value' => 1, '#prefix' => '
', '#suffix' => '
' ); } return $form; } // Implementation of hooks_forms_alter so we don't see preview or delete buttons for tasks function tasks_form_alter($form_id, &$form) { global $user; if ($form_id == 'tasks_node_form') { unset($form['preview']); //unset($form['delete']); } } function tasks_link($type, $node = NULL, $teaser = FALSE) { $links = array(); if ($type == 'node' && $node->type == 'tasks') { if (!$teaser) { $links[] = l(t('add new sub-task'), "node/add/tasks", array('title' => t('Add a new task to this task list')), "edit[parent]=$node->nid"); } } return $links; } // Implementation of hook_insert(). function tasks_insert($node) { $node->order_by -= 0.1; if (!$node->completed) { $node->completed_date['year'] = "0000"; $node->completed_date['month'] = "00"; $node->completed_date['day'] = "00"; } db_query("INSERT INTO {tasks} (nid, parent, assigned_to, order_by, completed) VALUES (%d, %d, %d, '%s', '%s')", $node->nid, $node->parent, $node->assigned_to, $node->order_by, $node->completed_date['year'].'-'.$node->completed_date['month'].'-'.$node->completed_date['day']); _tasks_order_by($node); } // Implementation of hook_update(). function tasks_update($node) { $node->order_by -= 0.1; if (!$node->completed) { $node->completed_date['year'] = "0000"; $node->completed_date['month'] = "00"; $node->completed_date['day'] = "00"; } db_query("UPDATE {tasks} SET parent = %d, assigned_to = %d, order_by = '%s', completed = '%s' WHERE nid = %d", $node->parent, $node->assigned_to, $node->order_by, $node->completed_date['year'].'-'.$node->completed_date['month'].'-'.$node->completed_date['day'], $node->nid); _tasks_order_by($node); // Redirect to the tasks home page? if ($node->from) drupal_goto('tasks'); } // Implementation of hook_delete(). function tasks_delete($node) { db_query('DELETE FROM {tasks} WHERE nid = %d', $node->nid); } // Implementation of hook_load(). function tasks_load($node) { $additions = db_fetch_object(db_query('SELECT parent, assigned_to, order_by, completed FROM {tasks} WHERE nid = %d', $node->nid)); $additions->completed_date['year'] = substr($additions->completed,0,4); $additions->completed_date['month'] = substr($additions->completed,5,2); $additions->completed_date['day'] = substr($additions->completed,8,2); return $additions; } /* Implementation of hook_view(). We want to view the task, and list any sub tasks */ function tasks_view(&$node, $teaser = FALSE, $page = FALSE) { theme_add_style(drupal_get_path('module', 'tasks').'/tasks.css'); drupal_add_js(drupal_get_path('module', 'tasks').'/tasks_view.js'); if ($page) { // The page should show the task and any subtasks $bc = drupal_get_breadcrumb(); $bc[] = l(t('Tasks'), 'tasks'); drupal_set_breadcrumb($bc); // Look to see if we need to change node order in this list if (($action = $_GET['action']) && ($tid = $_GET['task'])) { $task = node_load(array('nid'=>$tid)); if ($action == 'up') { $task->order_by -= 1.3; drupal_set_message(t('Task %task has been moved up the tasklist.', array('%task' => $task->title))); } elseif ($action == 'down') { $task->order_by += 1.3; drupal_set_message(t('Task %task has been moved down the tasklist.', array('%task' => $task->title))); } node_save($task); drupal_goto("node/$node->nid",null,'task'.$task->nid); } $node = node_prepare($node, $teaser); $output = ''; // Now show subtasks if there are any // Filter the tasks shown if ($_POST['edit']['filter'] == 0) { // incomplete tasks $complete = 'AND t.completed = 0'; $order_by = 't.order_by'; } elseif ($_POST['edit']['filter'] == 1) { // complete tasks $complete = 'AND t.completed > 0'; $order_by = 't.completed DESC'; } else { // all tasks $order_by = 'IF(t.completed = 0, 0, 1), t.completed DESC, t.order_by'; } // Get the list of tasks to display //$result = db_query("SELECT n.*, t.*, u.name AS assigned_name, u.data FROM {node} n INNER JOIN {tasks} t ON t.nid = n.nid LEFT JOIN {users} u ON u.uid = t.assigned_to WHERE n.status = 1 AND n.type='tasks' AND t.parent = %d %s ORDER BY %s", $node->nid, $complete, $order_by); $result = db_query("SELECT n.nid, u.name AS assigned_name, u.data FROM {node} n INNER JOIN {tasks} t ON t.nid = n.nid LEFT JOIN {users} u ON u.uid = t.assigned_to WHERE n.status = 1 AND n.type='tasks' AND t.parent = %d %s ORDER BY %s", $node->nid, $complete, $order_by); if ($num_rows = db_num_rows($result)) { // Enable the list of tasks to be filtered $form['filter'] = array( '#type' => 'select', '#title' => t('Showing %num_rows tasks. Filter',array('%num_rows'=>$num_rows)), '#default_value' => 0, '#options' => array(0=>t('Incomplete Tasks'),1=>t('Complete Tasks'),-1=>t('All Tasks')) ); $form['submit'] = array( '#type' => 'submit', '#value' => t('Filter') ); $form['#action'] = "node/$node->nid"; $form['#attributes'] = array('id'=>'tasks-filter'); $output .= drupal_get_form('task_filter',$form); while ($task = db_fetch_object($result)) { $assigned_name = $task->assigned_name; //$tasks_colour = drupal_unpack($task)->tasks_colour; $extra = drupal_unpack($task); $tasks_colour = $extra->tasks_colour; $task = node_load(array('nid'=>$task->nid)); $rows[] = array( 'data' => array( array('data' => $assigned_name, 'style' => "width:25px;".($tasks_colour ? "background:$tasks_colour;":'')), array('data' => l($task->title, "node/$task->nid", array('name'=>'task'.$task->nid)), 'style'=>($task->completed>0)?'text-decoration: line-through;':''), array('data' => ($task->completed>0) ? $task->completed : t('No')), array('data' => "nid');\">". t('Expand') ." ".l("", "node/$task->nid/edit/home",array(),null,null,false,true).' '.l(t('Up'),"node/$node->nid",array(),"action=up&task=$task->nid").' '.l(t('Down'),"node/$node->nid",array(),"action=down&task=$task->nid")), ) ); $task = node_prepare($task); $rows[] = array( 'data' => array( array('data' => $task->body, 'colspan' => '4'), ), 'class' => 'task-expand', 'id' => "row-$task->nid", 'style' => 'display:none;' ); } $header = array(t('Assigned'),t('Task'), t('Complete?'), t('Edit')); $output .= theme('table', $header, $rows, array("id"=>"task-list")); } $node->body .= $output; } } // PRIVATE FUNCTIONS /* FUNCTION tasks_main() This function redirects to the master tasklist if one exists, or creates one if it doesn't */ function _tasks_main() { // Get the list of tasks to display $result = db_query("SELECT t.* FROM {tasks} t WHERE t.parent = 0"); if ($num_rows = db_num_rows($result)) { if ($num_rows != 1) { drupal_set_message(t('WARNING: more than one master tasklists. Please delete all but one nodes of type tasks where parent = 0')); print theme('page',''); } else { while ($node = db_fetch_object($result)) { drupal_goto('node/'.$node->nid); } } } else { // There are no tasks. Create the master task(list) drupal_set_message(t('

There are no tasks yet, so creating a top-level tasklist.

')); $node->title = t('Tasklist'); $node->uid = 1; $node->filter = variable_get('filter_default_format', 1); $node->status = 1; $node->type = 'tasks'; node_save($node); drupal_goto('node/'.$node->nid); } } function _tasks_order_by($node) { // done either on insert or update of a task. we want to make order by values into integers to get in the updated one and remain consistent $result = db_query("SELECT n.*, t.* FROM {node} n, {tasks} t WHERE n.type='tasks' AND t.nid = n.nid AND t.order_by != 0 AND t.parent = %d ORDER BY t.order_by ASC", $node->parent); $i = 1; while ($task = db_fetch_object($result)) { if ($task->completed != '0000-00-00') $task->order_by = 0; else { $task->order_by = $i; $i++; } db_query("UPDATE {tasks} SET order_by = %d WHERE nid = %d", $task->order_by, $task->nid); } }