--- worklog.module.orig 2007-03-15 21:52:15.000000000 -0400 +++ worklog.module 2007-03-15 21:55:26.000000000 -0400 @@ -16,12 +16,7 @@ */ function worklog_help($section) { switch ($section) { - case 'admin/modules#description': - return t('Keep track of time spent working.'); - case 'node/add#worklog': - return t('Log time spent working on something.'); - case 'node/add#worklog-invoice': - return t('A collection of worklog entries.'); + } } @@ -30,9 +25,12 @@ * Implementation of hook_node_info(). */ function worklog_node_info() { - return array('worklog' => array('name' => t('worklog'), 'base' => 'worklog'), - 'worklog-invoice' => array('name' => t('worklog invoice'), - 'base' => 'worklog')); + return array('worklog' => array('name' => t('worklog'), + 'module' => 'worklog', + 'description' => 'Log time spent working on something.'), + 'worklog_invoice' => array('name' => t('worklog invoice'), + 'module' => 'worklog_invoice', + 'description' => 'A collection of worklog entries.')); } /** @@ -41,9 +39,9 @@ define ('WORKLOG_PERM_CREATE', 'create worklog'); define ('WORKLOG_PERM_EDIT', 'edit own worklog'); define ('WORKLOG_PERM_VIEW_OTHERS', 'view others worklog'); +define ('WORKLOG_PERM_ADMIN', 'admin worklog settings'); function worklog_perm() { - return array(WORKLOG_PERM_EDIT, WORKLOG_PERM_CREATE, - WORKLOG_PERM_VIEW_OTHERS); + return array(WORKLOG_PERM_EDIT, WORKLOG_PERM_CREATE, WORKLOG_PERM_VIEW_OTHERS, WORKLOG_PERM_ADMIN); } /** @@ -74,14 +72,16 @@ $items = array(); if ($may_cache) { - $items[] = array('path' => 'node/add/worklog', 'title' => t('worklog'), - 'access' => user_access(WORKLOG_PERM_CREATE)); - $items[] = array('path' => 'node/add/worklog-invoice', - 'title' => t('worklog invoice'), - 'access' => user_access(WORKLOG_PERM_CREATE) - ); + $items[] = array('path' => 'admin/settings/worklog', + 'title' => t('Worklog settings'), + 'description' => t('Configure worklog settings'), + 'callback' => 'drupal_get_form', + 'callback arguments' => array('worklog_settings'), + 'access' => user_access(WORKLOG_PERM_ADMIN), + 'type' => MENU_NORMAL_ITEM + ); } - + return $items; } @@ -94,7 +94,7 @@ if (!user_access(WORKLOG_PERM_VIEW_OTHERS)) { global $user; if ($primary_table == 'n' || $primary_table == 'node') { - $where = "$primary_table.type != 'worklog' OR $primary_table.type != 'worklog-invoice' OR $primary_table.uid=$user->uid"; + $where = "$primary_table.type != 'worklog' OR $primary_table.type != 'worklog_invoice' OR $primary_table.uid=$user->uid"; return array('where' => $where); } } @@ -112,13 +112,6 @@ * Implementation of hook_insert(). */ function worklog_insert($node) { - if ($node->type == 'worklog') - return _worklog_insert($node); - else if ($node->type == 'worklog-invoice') - return _worklog_invoice_insert($node); -} - -function _worklog_insert($node) { $form_values = $node->worklog; if ($form_values['wlid']) // if worklog row already exists, simply update @@ -130,40 +123,17 @@ db_query('INSERT INTO {worklog} (nid, started, elapsed, name, rate) VALUES (%d, %d, %d, \'%s\', %d)', $node->nid, $started, $elapsed, $node->title, $form_values['rate']); - - if (count($node->worklog_invoice)) { - if ($invoice_nid = $node->worklog_invoice['invoice_nid']) { - db_query('INSERT INTO {worklog_invoice_map} (invoice_nid, worklog_nid) VALUES (%d, %d)', $invoice_nid, $node->nid); - } - } - } -function _worklog_invoice_insert($node) { +function worklog_invoice_insert($node) { db_query('INSERT INTO {worklog_invoice} (nid, closed) VALUES (%d, %d)', $node->nid, $node->worklog['closed']); - - if (count($node->worklog_invoice) && - count($node->worklog_invoice['worklog_nids'])) { - foreach ($node->worklog_invoice['worklog_nids'] as $worklog_nid => $checked) { - if ($checked) - db_query('INSERT INTO {worklog_invoice_map} (invoice_nid, worklog_nid) VALUES (%d, %d)', $node->nid, $worklog_nid); - } - } - } /** * Implementation of hook_update(). */ function worklog_update($node) { - if ($node->type == 'worklog') - return _worklog_update($node); - else if ($node->type == 'worklog-invoice') - return _worklog_invoice_update($node); -} - -function _worklog_update($node) { $form_values = $node->worklog; $elapsed = $form_values['elapsed']; $started = $form_values['started']; @@ -171,30 +141,12 @@ db_query('REPLACE INTO {worklog} (wlid, nid, started, elapsed, name, rate) VALUES (%d, %d, %d, %d, \'%s\', %f)', $form_values['wlid'], $node->nid, $started, $elapsed, $node->title, $form_values['rate']); - db_query('DELETE FROM {worklog_invoice_map} WHERE worklog_nid = %d', $node->nid); - if (count($node->worklog_invoice)) { - if ($invoice_nid = $node->worklog_invoice['invoice_nid']) { - db_query('INSERT INTO {worklog_invoice_map} (invoice_nid, worklog_nid) VALUES (%d, %d)', $invoice_nid, $node->nid); - } - } - - } -function _worklog_invoice_update($node) { +function worklog_invoice_update($node) { // will this work if new revision created? db_query('REPLACE INTO {worklog_invoice} (nid, closed) VALUES (%d, %d)', $node->nid, $node->worklog['closed']); - - db_query('DELETE FROM {worklog_invoice_map} WHERE invoice_nid = %d', $node->nid); - if (count($node->worklog_invoice) && - count($node->worklog_invoice['worklog_nids'])) { - foreach ($node->worklog_invoice['worklog_nids'] as $worklog_nid => $checked) { - if ($checked) - db_query('INSERT INTO {worklog_invoice_map} (invoice_nid, worklog_nid) VALUES (%d, %d)', $node->nid, $worklog_nid); - } - } - } @@ -202,50 +154,38 @@ * Implementation of hook_delete(). */ function worklog_delete($node) { - if ($node->type == 'worklog') { - db_query('DELETE FROM {worklog} WHERE wlid=%d', $node->worklog->wlid); - db_query('DELETE FROM {worklog_invoice_map} WHERE worklog_nid=%d', $node->nid); - } - else if ($node->type == 'worklog-invoice') { - // TODO: what should happen to orphaned worklog entries? - db_query('DELETE FROM {worklog_invoice_map} WHERE invoice_nid=%d', $node->nid); - db_query('DELETE FROM {worklog_invoice} WHERE nid=%d', $node->nid); - } + db_query('DELETE FROM {worklog} WHERE wlid=%d', $node->worklog->wlid); + db_query('DELETE FROM {worklog_invoice_map} WHERE worklog_nid=%d', $node->nid); +} +function worklog_invoice_delete($node) { + // TODO: what should happen to orphaned worklog entries? + db_query('DELETE FROM {worklog_invoice_map} WHERE invoice_nid=%d', $node->nid); + db_query('DELETE FROM {worklog_invoice} WHERE nid=%d', $node->nid); } /** * Implementation of hook_load(). */ function worklog_load($node) { - if ($node->type == 'worklog') { - $worklog = db_fetch_object(db_query('SELECT * FROM {worklog} WHERE nid=%d', $node->nid)); - $invoice = db_result(db_query('SELECT invoice_nid FROM {worklog_invoice_map} WHERE worklog_nid = %d', $node->nid)); - $worklog->invoice_nid = $invoice; - - return array('worklog' => $worklog); - } - - else if ($node->type == 'worklog-invoice') { - $invoice_map = db_query('SELECT * FROM {worklog_invoice_map} WHERE invoice_nid = %d', $node->nid); - $invoice = db_fetch_object(db_query('SELECT * FROM {worklog_invoice} WHERE nid=%d', $node->nid)); - while ($row = db_fetch_object($invoice_map)) { - $invoice->worklog_nids[] = $row->worklog_nid; - } - return array('worklog' => $invoice); + $worklog = db_fetch_object(db_query('SELECT * FROM {worklog} WHERE nid=%d', $node->nid)); + $invoice = db_result(db_query('SELECT invoice_nid FROM {worklog_invoice_map} WHERE worklog_nid = %d', $node->nid)); + $worklog->invoice_nid = $invoice; + + return array('worklog' => $worklog); +} +function worklog_invoice_load($node) { + $invoice_map = db_query('SELECT * FROM {worklog_invoice_map} WHERE invoice_nid = %d', $node->nid); + $invoice = db_fetch_object(db_query('SELECT * FROM {worklog_invoice} WHERE nid=%d', $node->nid)); + while ($row = db_fetch_object($invoice_map)) { + $invoice->worklog_nids[] = $row->worklog_nid; } + return array('worklog' => $invoice); } /** * Implementation of hook_form(). */ function worklog_form(&$node) { - if ($node->type == 'worklog') - return _worklog_form($node); - else if ($node->type == 'worklog-invoice') - return _worklog_invoice_form($node); -} - -function _worklog_form(&$node) { // if we are creating a new node, get default values from wlid passed in if (!isset($node->nid) && !isset($node->worklog)) { $timer = _worklog_get_timer($_REQUEST['wlid']); @@ -286,98 +226,21 @@ $form['body'] = array('#type' => 'textarea', '#title' => t('Description'), '#default_value' => $node->body, '#rows' => 5, '#required' => false); $form['format'] = filter_form($node->format); - // mapping between worklog and invoice - $invoice_nid = $node->worklog->invoice_nid; - $invoice = new stdClass(); - if ($invoice_nid) { - $invoice = node_load($invoice_nid); - if ($invoice->worklog->closed) { - drupal_set_message(t('This worklog entry may have already been invoiced.')); - $form['worklog_invoice'] = - array('#type' => 'fieldset', - '#title' => t('Invoice'), - '#description' => t('This worklog entry is included in the invoice %invoice_link. The invoice has been marked closed. It is recommended not to make any changes to this entry.', - array('%invoice_link' => $invoice->title)), - ); - } - } - if (!$invoice_nid || !$invoice->worklog->closed) { - // let user assign a worklog to an invoice - $form['worklog_invoice'] = - array('#type' => 'fieldset', - '#title' => t('Invoice'), - '#tree' => TRUE, - '#collapsible' => TRUE, - ); - - $result = db_query(db_rewrite_sql('SELECT n.title, n.nid FROM {node} n LEFT JOIN {worklog_invoice} wi ON n.nid = wi.nid WHERE n.type=\'worklog-invoice\' AND n.status = 1 AND (wi.closed = 0 OR n.nid=%d)'), $invoice_nid); - $options = array(0 => t('no invoice')); - while ($row = db_fetch_object($result)) { - $options[$row->nid] = t('%title', - array('%title' =>$row->title, - ) - ); - } - $form['worklog_invoice']['invoice_nid'] = - array('#type' => 'radios', - '#title' => t('Select invoice'), - '#options' => $options, - '#default_value' => $invoice_nid, - '#description' => t('This item will be included in the chosen invoice.'), - ); - - } - return $form; } -function _worklog_invoice_form(&$node) { +function worklog_invoice_form(&$node) { $form['title'] = array('#type' => 'textfield', '#title' => t('Title'), '#required' => TRUE, '#default_value' => $node->title); - $form['worklog'] = array('#tree' => true, - '#weight' => -1, - ); + $form['worklog'] = array('#tree' => true, '#weight' => -1,); $form['worklog']['closed'] = array('#type' => 'checkbox', '#title' => t('Closed to new entries'), '#default_value' => $node->worklog->closed, '#description' => t('Check this box when you will not add more worklog entries to this invoice. For example, after you have sent the invoice to a client.'), ); - $form['body'] = array('#type' => 'textarea', '#title' => t('Description'), '#default_value' => $node->body, '#rows' => 5, '#required' => false); $form['format'] = filter_form($node->format); - // on invoice form, allow choice of all non-invoiced worklogs - $result = db_query(db_rewrite_sql('SELECT n.title, w.* FROM {node} n LEFT JOIN {worklog} w ON n.nid = w.nid LEFT JOIN {worklog_invoice_map} wim ON wim.worklog_nid = n.nid WHERE n.type=\'worklog\' AND n.status = 1 AND (wim.invoice_nid IS NULL OR wim.invoice_nid = %d)'), $node->nid); - $options = array(); - while ($row = db_fetch_object($result)) { - // TODO: show more than title, perhaps build a table. - $options[$row->nid] = t('%title (%hours @ %rate = %amount)', - array('%title' =>$row->title, - '%hours' => _worklog_format_duration($row->elapsed), - '%rate' => $row->rate, - '%amount' => _worklog_calculate_bill($row->elapsed, $row->rate) - )); - } - $form['worklog_invoice'] = - array('#type' => 'fieldset', - '#title' => t('Invoice items'), - '#tree' => TRUE, - '#collapsible' => TRUE, - ); - if (count($options)) { - //drupal_set_message(dprint_r($form['#node'], 1)); - $form['worklog_invoice']['worklog_nids'] = - array('#type' => 'checkboxes', - '#title' => t('Select items'), - '#options' => $options, - '#default_value' => $node->worklog->worklog_nids, - '#description' => t('Choose the items to include in this invoice.'), - ); - } - else { - $form['worklog_invoice']['#description'] = t('There are no worklog entries to include in this invoice.'); - } - return $form; } @@ -401,89 +264,103 @@ define('WORKLOG_BUTTON_RESUME', t('Resume')); define('WORKLOG_BUTTON_SAVE', t('Save')); +function worklog_forms() { + $forms['worklog_paused_form']= array( + 'callback' => 'worklog_paused_form', + 'callback arguments' => array('worklog_paused_form'), + ); + $forms['worklog_stop_form']= array( + 'callback' => 'worklog_stop', + 'callback arguments' => array('worklog_stop_form'), + ); + $forms['worklog_start_form']= array( + 'callback' => 'worklog_start', + 'callback arguments' => array('worklog_start_form'), + ); + return $forms; +} + +function worklog_stop_form($timer) { + $form['name'] = array('#type' => 'markup', + '#value' => "
$timer->name
" + ); + $form['wlid'] = array('#type' => 'hidden', + '#value' => $timer->wlid); + $form['buttons'][] = array('#type' => 'submit', + '#name' => 'op', + '#value' => WORKLOG_BUTTON_PAUSE + ); + $form['buttons'][] = array('#type' => 'submit', + '#name' => 'op', + '#value' => WORKLOG_BUTTON_STOP + ); + return $form; +} +function worklog_start_form() { + // the form to start a new timer + $form['name'] = array('#type' => 'textfield', + '#title' => t('Task name'), + '#size' => 20, + ); + $form['submit'] = array('#type' => 'submit', + '#value' => t('Start Timer') + ); + // $form['#attributes'] = array('target' => '_blank'); // new window + return $form; +} + +function worklog_paused_form($timer) { + $form[$timer->wlid] = array('#type' => 'fieldset'); + $form[$timer->wlid][] = array('#type' => 'markup', '#value' => "$timer->name
"); - $form['wlid'] = array('#type' => 'hidden', - '#value' => $timer->wlid); - $form['buttons'][] = array('#type' => 'submit', - '#name' => 'op', - '#value' => WORKLOG_BUTTON_PAUSE, - ); - $form['buttons'][] = array('#type' => 'submit', - '#name' => 'op', - '#value' => WORKLOG_BUTTON_STOP, - ); - $block['content'] = drupal_get_form('worklog_stop_form', $form); - $block['subject'] = t('Worklog Timer'); - } - else { - // the form to start a new timer - $form['name'] = array('#type' => 'textfield', - '#title' => t('Task name'), - '#size' => 20, - ); - $form['submit'] = array('#type' => 'submit', - '#value' => t('Start Timer') - ); - // $form['#attributes'] = array('target' => '_blank'); // new window - $block['content'] = drupal_get_form('worklog_start_form', $form); - $block['subject'] = t('Worklog New Timer'); - } - return $block; - case WORKLOG_BLOCK_PAUSED: + case WORKLOG_BLOCK_TIMER && user_access(WORKLOG_PERM_CREATE): + if($timer = _worklog_current_timer()) { + $block['content'] = drupal_get_form('worklog_stop_form',$timer); + } + else { + $block['content'] = drupal_get_form('worklog_start_form'); + } + $block['subject'] = t('Worklog New Timer'); + return $block; + case WORKLOG_BLOCK_PAUSED && user_access(WORKLOG_PERM_EDIT): global $user; - if (!user_access(WORKLOG_PERM_EDIT)) - return; - // give user control over paused timers $result = db_query("SELECT * FROM {worklog} WHERE nid IS NULL AND timer_start = 0 AND uid=%d", $user->uid); if (!db_num_rows($result)) return; - - $form = array(); $current_timer = _worklog_current_timer(); if ($current_timer) - $resume_attrs = array('disabled' => 1); + $resume_attrs = array('disabled' => 1); while ($timer = db_fetch_object($result)) { - $form[$timer->wlid] = array('#type' => 'fieldset'); - $form[$timer->wlid][] = array('#type' => 'markup', - '#value' => "