t('Date'), 'field' => 'j.timestamp', 'sort' => 'desc'), array('data' => t('User'), 'field' => 'u.name'), t('Message'), t('Location'), ); $tablesort = tablesort_sql($header); $result = pager_query($sql . $tablesort, 50); return journal_output($result, 'table', $header); } /** * Output a sortable table containing all recorded patches. */ function journal_patch_view() { $header = array( array('data' => t('Date'), 'field' => 'j.timestamp', 'sort' => 'desc'), array('data' => t('Module'), 'field' => 'j.module'), array('data' => t('User'), 'field' => 'u.name'), t('Description'), t('Issue'), t('Status'), t('Operations'), ); $sql = "SELECT j.*, u.name FROM {journal_patch} j INNER JOIN {users} u ON j.uid = u.uid"; $result = pager_query($sql . tablesort_sql($header), 25); $module_list = module_list(FALSE, FALSE); $rows = array(); while ($entry = db_fetch_object($result)) { $modules = array(); foreach (explode(',', $entry->module) as $module) { $info = drupal_parse_info_file(drupal_get_path('module', $module) .'/'. $module .'.info'); if (isset($info['project'])) { $url = 'http://drupal.org/project/issues/'. $info['project']; $modules[] = l($info['name'], $url); } else { $modules[] = $info['name']; } } if ($entry->url != '') { if (preg_match('@drupal.org/node/(\d+)@', $entry->url, $issue_title)) { $issue_link = l('#'. $issue_title[1], $entry->url); } else { $issue_link = l(t('View'), $entry->url); } } else { $issue_link = ''; } $rows[] = array( format_date($entry->timestamp, 'small'), implode(', ', $modules), theme('username', $entry), filter_xss_admin($entry->description), $issue_link, t($entry->status), l(t('edit'), "admin/reports/journal/patches/edit/$entry->pid"), ); } if (empty($rows)) { $rows[] = array(array('data' => t('No patch entries available.'), 'colspan' => 7)); } $output = drupal_get_form('journal_patch_form'); $output .= theme('table', $header, $rows); $output .= theme('pager', NULL, 50, 0); return $output; } /** * Form builder function for patches. */ function journal_patch_form($form_state, $pid = NULL) { drupal_add_css(drupal_get_path('module', 'journal') .'/journal_patch.css', 'module', 'all', FALSE); $patch = array(); if (isset($pid)) { $patch = db_fetch_array(db_query("SELECT j.* FROM {journal_patch} j WHERE j.pid = %d", $pid)); } $patch += array( 'module' => '', 'description' => '', 'url' => '', 'status' => 'open', ); $form = array(); $form['patch'] = array( '#type' => 'fieldset', '#title' => t('Add patch record'), '#tree' => TRUE, ); $form['patch']['module'] = array( '#type' => 'select', '#title' => t('Affected modules'), '#options' => module_list(FALSE, FALSE, TRUE), '#multiple' => TRUE, '#default_value' => explode(',', $patch['module']), '#size' => 8, '#required' => TRUE, '#prefix' => '
', '#suffix' => '
', ); $form['patch']['description'] = array( '#type' => 'textarea', '#title' => t('Description'), '#default_value' => $patch['description'], '#required' => TRUE, '#prefix' => '
', '#suffix' => '
', ); $form['patch']['url'] = array( '#type' => 'textfield', '#title' => t('Issue URL'), '#default_value' => $patch['url'], '#prefix' => '
', ); $form['patch']['status'] = array( '#type' => 'select', '#title' => t('Status'), '#options' => array('open' => t('open'), 'fixed' => t('fixed'), "won't fix" => t("won't fix")), '#default_value' => $patch['status'], '#suffix' => '
', ); if (!empty($patch['pid'])) { $form['patch']['pid'] = array( '#type' => 'value', '#value' => $patch['pid'], ); } $form['patch']['submit'] = array( '#type' => 'submit', '#value' => isset($patch['pid']) ? t('Save') : t('Add'), ); if (!empty($patch['pid'])) { $form['patch']['delete'] = array( '#type' => 'submit', '#value' => t('Delete'), ); } return $form; } /** * Submit handler for journal patch form. */ function journal_patch_form_submit($form, &$form_state) { global $user; $patch = $form_state['values']['patch']; if (preg_match('@^#\d+@', $patch['url'])) { $patch['url'] = 'http://drupal.org/node/'. substr($patch['url'], 1); } if ($form_state['values']['op'] == t('Add')) { db_query("INSERT INTO {journal_patch} (uid, module, description, url, status, timestamp) VALUES (%d, '%s', '%s', '%s', '%s', %d)", $user->uid, implode(',', $patch['module']), $patch['description'], $patch['url'], $patch['status'], time()); } else if ($form_state['values']['op'] == t('Save')) { db_query("UPDATE {journal_patch} SET uid = %d, module = '%s', description = '%s', url = '%s', status = '%s' WHERE pid = %d", $user->uid, implode(',', $patch['module']), $patch['description'], $patch['url'], $patch['status'], $patch['pid']); $form_state['redirect'] = 'admin/reports/journal/patches'; } else if ($form_state['values']['op'] == t('Delete')) { $form_state['redirect'] = 'admin/reports/journal/patches/delete/'. $patch['pid']; } } /** * Confirmation form to delete a patch record. */ function journal_patch_delete_confirm($form_state, $pid) { $form = array(); $form['pid'] = array('#type' => 'value', '#value' => $pid); $description = db_result(db_query("SELECT description FROM {journal_patch} WHERE pid = %d", $pid)); $form['patch_description'] = array( '#type' => 'item', '#title' => t('Description'), '#value' => filter_xss_admin($description), ); return confirm_form($form, t('Are you sure you want to delete this patch record?'), 'admin/reports/journal/patches', t('This action cannot be undone.'), t('Delete'), t('Cancel') ); } /** * Form submit callback for patch record delete confirm form. */ function journal_patch_delete_confirm_submit($form, &$form_state) { db_query("DELETE FROM {journal_patch} WHERE pid = %d", $form_state['values']['pid']); $form_state['redirect'] = 'admin/reports/journal/patches'; }