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);
}
}