Index: includes/menu.inc =================================================================== RCS file: /cvs/drupal/drupal/includes/menu.inc,v retrieving revision 1.163 diff -u -p -r1.163 menu.inc --- includes/menu.inc 24 Apr 2007 08:26:58 -0000 1.163 +++ includes/menu.inc 30 Apr 2007 06:38:28 -0000 @@ -343,6 +343,10 @@ function menu_get_item($path = NULL, $it */ function menu_execute_active_handler() { if ($item = menu_get_item()) { + //dsm($item); + if ($item->includes) { + include_once($item->includes); + } return $item->access ? call_user_func_array($item->page_callback, $item->page_arguments) : MENU_ACCESS_DENIED; } return MENU_NOT_FOUND; @@ -777,10 +781,16 @@ function menu_rebuild() { $item['page callback'] = $parent['page callback']; if (!isset($item['page arguments']) && isset($parent['page arguments'])) { $item['page arguments'] = $parent['page arguments']; + if (empty($item['includes'])) { + $item['includes'] = $parent['includes']; + } } } } } + if (!isset($item['includes'])) { + $item['includes'] = ''; + } if (!isset($item['access callback'])) { $item['access callback'] = isset($item['access arguments']) ? 'user_access' : 0; } @@ -843,15 +853,16 @@ function menu_rebuild() { if (!empty($item['disabled'])) { $item['_visible'] = FALSE; } + db_query("INSERT INTO {menu} ( mid, pid, path, load_functions, to_arg_functions, access_callback, access_arguments, page_callback, page_arguments, fit, number_parts, visible, parents, depth, has_children, tab, title, parent, type, mleft, mright, block_callback, description, position, - link_path, attributes, query, fragment, absolute, html) + link_path, attributes, query, fragment, absolute, html, includes) VALUES (%d, %d, '%s', '%s', '%s', '%s', '%s', '%s', '%s', %d, %d, %d, '%s', %d, %d, %d, '%s', '%s', '%s', %d, %d, '%s', '%s', '%s', - '%s', '%s', '%s', '%s', %d, %d)", + '%s', '%s', '%s', '%s', %d, %d, '%s')", $item['_mid'], $item['_pid'], $path, $item['load_functions'], $item['to_arg_functions'], $item['access callback'], serialize($item['access arguments']), $item['page callback'], @@ -862,7 +873,7 @@ function menu_rebuild() { $item['_mright'], $item['block callback'], $item['description'], $item['position'], $link_path, $item['attributes'], $item['query'], $item['fragment'], - $item['absolute'], $item['html']); + $item['absolute'], $item['html'], $item['includes']); } } Index: modules/block/block.module =================================================================== RCS file: /cvs/drupal/drupal/modules/block/block.module,v retrieving revision 1.257 diff -u -p -r1.257 block.module --- modules/block/block.module 17 Apr 2007 07:19:38 -0000 1.257 +++ modules/block/block.module 30 Apr 2007 06:38:29 -0000 @@ -76,6 +76,7 @@ function block_menu() { 'page callback' => 'drupal_get_form', 'page arguments' => array('block_admin_display'), 'access arguments' => array('administer blocks'), + 'includes' => drupal_get_path('module', 'block') . '/block.pages.inc', ); $items['admin/build/block/list'] = array( 'title' => t('List'), @@ -96,6 +97,7 @@ function block_menu() { 'title' => t('Add block'), 'page arguments' => array('block_add_block_form'), 'type' => MENU_LOCAL_TASK, + 'includes' => drupal_get_path('module', 'block') . '/block.pages.inc', ); $default = variable_get('theme_default', 'garland'); foreach (list_themes() as $key => $theme) { @@ -146,6 +148,42 @@ function block_block($op = 'list', $delt } } + +/** + * Implementation of hook_user(). + * + * Allow users to decide which custom blocks to display when they visit + * the site. + */ +function block_user($type, $edit, &$user, $category = NULL) { + global $user; + switch ($type) { + case 'form': + if ($category == 'account') { + $result = db_query("SELECT DISTINCT b.* FROM {blocks} b LEFT JOIN {blocks_roles} r ON b.module = r.module AND b.delta = r.delta WHERE b.status = 1 AND b.custom != 0 AND (r.rid IN (%s) OR r.rid IS NULL) ORDER BY b.weight, b.module", implode(',', array_keys($user->roles))); + $form['block'] = array('#type' => 'fieldset', '#title' => t('Block configuration'), '#weight' => 3, '#collapsible' => TRUE, '#tree' => TRUE); + while ($block = db_fetch_object($result)) { + $data = module_invoke($block->module, 'block', 'list'); + if ($data[$block->delta]['info']) { + $return = TRUE; + $form['block'][$block->module][$block->delta] = array('#type' => 'checkbox', '#title' => check_plain($data[$block->delta]['info']), '#default_value' => isset($user->block[$block->module][$block->delta]) ? $user->block[$block->module][$block->delta] : ($block->custom == 1)); + } + } + + if (!empty($return)) { + return $form; + } + } + + break; + case 'validate': + if (empty($edit['block'])) { + $edit['block'] = array(); + } + return $edit; + } +} + /** * Update the 'blocks' DB table with the blocks currently exported by modules. * @@ -214,450 +252,6 @@ function _block_rehash() { } /** - * Generate main block administration form. - */ -function block_admin_display($theme = NULL) { - global $theme_key, $custom_theme; - - // Add CSS - drupal_add_css(drupal_get_path('module', 'block') .'/block.css', 'module', 'all', FALSE); - - // If non-default theme configuration has been selected, set the custom theme. - if ($theme) { - $custom_theme = $theme; - } - else { - $custom_theme = variable_get('theme_default', 'garland'); - } - init_theme(); - - // Fetch and sort blocks - $blocks = _block_rehash(); - usort($blocks, '_block_compare'); - - $throttle = module_exists('throttle'); - $block_regions = array(BLOCK_REGION_NONE => '<'. t('none') .'>') + system_region_list($theme_key); - - // Build form tree - $form['#action'] = arg(3) ? url('admin/build/block/list/'. $theme_key) : url('admin/build/block'); - $form['#tree'] = TRUE; - foreach ($blocks as $i => $block) { - $form[$i]['module'] = array('#type' => 'value', '#value' => $block['module']); - $form[$i]['delta'] = array('#type' => 'value', '#value' => $block['delta']); - $form[$i]['info'] = array('#value' => check_plain($block['info'])); - $form[$i]['theme'] = array('#type' => 'hidden', '#value' => $theme_key); - $form[$i]['weight'] = array('#type' => 'weight', '#default_value' => $block['weight']); - $form[$i]['region'] = array('#type' => 'select', - '#default_value' => $block['status'] ? (isset($block['region']) ? $block['region'] : system_default_region($theme_key)) : BLOCK_REGION_NONE, - '#options' => $block_regions, - ); - - if ($throttle) { - $form[$i]['throttle'] = array('#type' => 'checkbox', '#default_value' => isset($block['throttle']) ? $block['throttle'] : FALSE); - } - $form[$i]['configure'] = array('#value' => l(t('configure'), 'admin/build/block/configure/'. $block['module'] .'/'. $block['delta'])); - if ($block['module'] == 'block') { - $form[$i]['delete'] = array('#value' => l(t('delete'), 'admin/build/block/delete/'. $block['delta'])); - } - } - $form['submit'] = array('#type' => 'submit', '#value' => t('Save blocks')); - - return $form; -} - -/** - * Helper function for sorting blocks on admin/build/block. - * - * Active blocks are sorted by region, then by weight. - * Disabled blocks are sorted by name. - */ -function _block_compare($a, $b) { - $status = $b['status'] - $a['status']; - // Separate enabled from disabled. - if ($status) { - return $status; - } - // Enabled blocks - if ($a['status']) { - $place = strcmp($a['region'], $b['region']); - return $place ? $place : ($a['weight'] - $b['weight']); - } - // Disabled blocks - else { - return strcmp($a['info'], $b['info']); - } -} - -/** - * Process main block administration form submission. - */ -function block_admin_display_submit($form_id, $form_values) { - foreach ($form_values as $block) { - $block['status'] = $block['region'] != BLOCK_REGION_NONE; - $block['region'] = $block['status'] ? $block['region'] : ''; - db_query("UPDATE {blocks} SET status = %d, weight = %d, region = '%s', throttle = %d WHERE module = '%s' AND delta = '%s' AND theme = '%s'", $block['status'], $block['weight'], $block['region'], $block['throttle'], $block['module'], $block['delta'], $block['theme']); - } - drupal_set_message(t('The block settings have been updated.')); - cache_clear_all(); -} - -/** - * Theme main block administration form submission. - * - * Note: the blocks are already sorted in the right order, - * grouped by status, region and weight. - */ -function theme_block_admin_display($form) { - global $theme_key; - - $throttle = module_exists('throttle'); - $block_regions = system_region_list($theme_key); - - // Highlight regions on page to provide visual reference. - foreach ($block_regions as $key => $value) { - drupal_set_content($key, '
TRUE (PHP-mode, experts only).');
- $description .= ' '. t('If the PHP-mode is chosen, enter PHP code between %php. Note that executing incorrect PHP-code can break your Drupal site.', array('%php' => ''));
- }
- $form['page_vis_settings']['visibility'] = array(
- '#type' => 'radios',
- '#title' => t('Show block on specific pages'),
- '#options' => $options,
- '#default_value' => $edit['visibility'],
- );
- $form['page_vis_settings']['pages'] = array(
- '#type' => 'textarea',
- '#title' => t('Pages'),
- '#default_value' => $edit['pages'],
- '#description' => $description,
- );
- }
-
- $form['submit'] = array(
- '#type' => 'submit',
- '#value' => t('Save block'),
- );
-
- return $form;
-}
-
-function block_admin_configure_validate($form_id, $form_values) {
- if ($form_values['module'] == 'block') {
- if (empty($form_values['info']) || db_num_rows(db_query("SELECT bid FROM {boxes} WHERE bid != %d AND info = '%s'", $form_values['delta'], $form_values['info']))) {
- form_set_error('info', t('Please ensure that each block description is unique.'));
- }
- }
-}
-
-function block_admin_configure_submit($form_id, $form_values) {
- if (!form_get_errors()) {
- db_query("UPDATE {blocks} SET visibility = %d, pages = '%s', custom = %d, title = '%s' WHERE module = '%s' AND delta = '%s'", $form_values['visibility'], trim($form_values['pages']), $form_values['custom'], $form_values['title'], $form_values['module'], $form_values['delta']);
- db_query("DELETE FROM {blocks_roles} WHERE module = '%s' AND delta = '%s'", $form_values['module'], $form_values['delta']);
- foreach (array_filter($form_values['roles']) as $rid) {
- db_query("INSERT INTO {blocks_roles} (rid, module, delta) VALUES (%d, '%s', '%s')", $rid, $form_values['module'], $form_values['delta']);
- }
- module_invoke($form_values['module'], 'block', 'save', $form_values['delta'], $form_values);
- drupal_set_message(t('The block configuration has been saved.'));
- cache_clear_all();
- return 'admin/build/block';
- }
-}
-
-/**
- * Menu callback: display the custom block addition form.
- */
-function block_add_block_form() {
- return block_admin_configure('block', NULL);
-}
-
-function block_add_block_form_validate($form_id, $form_values) {
- if (empty($form_values['info']) || db_num_rows(db_query("SELECT info FROM {boxes} WHERE info = '%s'", $form_values['info']))) {
- form_set_error('info', t('Please ensure that each block description is unique.'));
- }
-}
-
-/**
- * Save the new custom block.
- */
-function block_add_block_form_submit($form_id, $form_values) {
- $delta = db_next_id('{boxes}_bid');
-
- foreach (list_themes() as $key => $theme) {
- if ($theme->status) {
- db_query("INSERT INTO {blocks} (visibility, pages, custom, title, module, theme, status, weight, delta) VALUES(%d, '%s', %d, '%s', '%s', '%s', %d, %d, %d)", $form_values['visibility'], trim($form_values['pages']), $form_values['custom'], $form_values['title'], $form_values['module'], $theme->name, 0, 0, $delta);
- }
- }
-
- foreach (array_filter($form_values['roles']) as $rid) {
- db_query("INSERT INTO {blocks_roles} (rid, module, delta) VALUES (%d, '%s', '%s')", $rid, $form_values['module'], $delta);
- }
-
- db_query("INSERT INTO {boxes} (bid, body, info, format) VALUES (%d, '%s', '%s', %d)", $delta, $form_values['body'], $form_values['info'], $form_values['format']);
-
- drupal_set_message(t('The block has been created.'));
- cache_clear_all();
-
- return 'admin/build/block';
-}
-
-/**
- * Menu callback; confirm deletion of custom blocks.
- */
-function block_box_delete($bid = 0) {
- $box = block_box_get($bid);
- $form['info'] = array('#type' => 'hidden', '#value' => $box['info'] ? $box['info'] : $box['title']);
- $form['bid'] = array('#type' => 'hidden', '#value' => $bid);
-
- return confirm_form($form, t('Are you sure you want to delete the block %name?', array('%name' => $box['info'])), 'admin/build/block', '', t('Delete'), t('Cancel'));
-}
-
-/**
- * Deletion of custom blocks.
- */
-function block_box_delete_submit($form_id, $form_values) {
- db_query('DELETE FROM {boxes} WHERE bid = %d', $form_values['bid']);
- db_query("DELETE FROM {blocks} WHERE module = 'block' AND delta = %d", $form_values['bid']);
- drupal_set_message(t('The block %name has been removed.', array('%name' => $form_values['info'])));
- cache_clear_all();
- return 'admin/build/block';
-};
-
-/**
- * Define the custom block form.
- */
-function block_box_form($edit = array()) {
- $edit += array(
- 'info' => '',
- 'body' => '',
- );
- $form['info'] = array(
- '#type' => 'textfield',
- '#title' => t('Block description'),
- '#default_value' => $edit['info'],
- '#maxlength' => 64,
- '#description' => t('A brief description of your block. Used on the block overview page.', array('@overview' => url('admin/build/block'))),
- '#required' => TRUE,
- '#weight' => -19,
- );
- $form['body_field']['#weight'] = -17;
- $form['body_field']['body'] = array(
- '#type' => 'textarea',
- '#title' => t('Block body'),
- '#default_value' => $edit['body'],
- '#rows' => 15,
- '#description' => t('The content of the block as shown to the user.'),
- '#weight' => -17,
- );
- if (!isset($edit['format'])) {
- $edit['format'] = FILTER_FORMAT_DEFAULT;
- }
- $form['body_field']['format'] = filter_form($edit['format'], -16);
-
- return $form;
-}
-
-function block_box_save($edit, $delta) {
- if (!filter_access($edit['format'])) {
- $edit['format'] = FILTER_FORMAT_DEFAULT;
- }
-
- db_query("UPDATE {boxes} SET body = '%s', info = '%s', format = %d WHERE bid = %d", $edit['body'], $edit['info'], $edit['format'], $delta);
-
- return TRUE;
-}
-
-/**
- * Implementation of hook_user().
- *
- * Allow users to decide which custom blocks to display when they visit
- * the site.
- */
-function block_user($type, $edit, &$user, $category = NULL) {
- global $user;
- switch ($type) {
- case 'form':
- if ($category == 'account') {
- $result = db_query("SELECT DISTINCT b.* FROM {blocks} b LEFT JOIN {blocks_roles} r ON b.module = r.module AND b.delta = r.delta WHERE b.status = 1 AND b.custom != 0 AND (r.rid IN (%s) OR r.rid IS NULL) ORDER BY b.weight, b.module", implode(',', array_keys($user->roles)));
- $form['block'] = array('#type' => 'fieldset', '#title' => t('Block configuration'), '#weight' => 3, '#collapsible' => TRUE, '#tree' => TRUE);
- while ($block = db_fetch_object($result)) {
- $data = module_invoke($block->module, 'block', 'list');
- if ($data[$block->delta]['info']) {
- $return = TRUE;
- $form['block'][$block->module][$block->delta] = array('#type' => 'checkbox', '#title' => check_plain($data[$block->delta]['info']), '#default_value' => isset($user->block[$block->module][$block->delta]) ? $user->block[$block->module][$block->delta] : ($block->custom == 1));
- }
- }
-
- if (!empty($return)) {
- return $form;
- }
- }
-
- break;
- case 'validate':
- if (empty($edit['block'])) {
- $edit['block'] = array();
- }
- return $edit;
- }
-}
-
-/**
* Return all blocks in the specified region for the current user.
*
* @param $region
Index: modules/block/block.pages.inc
===================================================================
RCS file: modules/block/block.pages.inc
diff -N modules/block/block.pages.inc
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ modules/block/block.pages.inc 30 Apr 2007 06:38:29 -0000
@@ -0,0 +1,417 @@
+ '<'. t('none') .'>') + system_region_list($theme_key);
+
+ // Build form tree
+ $form['#action'] = arg(3) ? url('admin/build/block/list/'. $theme_key) : url('admin/build/block');
+ $form['#tree'] = TRUE;
+ foreach ($blocks as $i => $block) {
+ $form[$i]['module'] = array('#type' => 'value', '#value' => $block['module']);
+ $form[$i]['delta'] = array('#type' => 'value', '#value' => $block['delta']);
+ $form[$i]['info'] = array('#value' => check_plain($block['info']));
+ $form[$i]['theme'] = array('#type' => 'hidden', '#value' => $theme_key);
+ $form[$i]['weight'] = array('#type' => 'weight', '#default_value' => $block['weight']);
+ $form[$i]['region'] = array('#type' => 'select',
+ '#default_value' => $block['status'] ? (isset($block['region']) ? $block['region'] : system_default_region($theme_key)) : BLOCK_REGION_NONE,
+ '#options' => $block_regions,
+ );
+
+ if ($throttle) {
+ $form[$i]['throttle'] = array('#type' => 'checkbox', '#default_value' => isset($block['throttle']) ? $block['throttle'] : FALSE);
+ }
+ $form[$i]['configure'] = array('#value' => l(t('configure'), 'admin/build/block/configure/'. $block['module'] .'/'. $block['delta']));
+ if ($block['module'] == 'block') {
+ $form[$i]['delete'] = array('#value' => l(t('delete'), 'admin/build/block/delete/'. $block['delta']));
+ }
+ }
+ $form['submit'] = array('#type' => 'submit', '#value' => t('Save blocks'));
+
+ return $form;
+}
+
+/**
+ * Helper function for sorting blocks on admin/build/block.
+ *
+ * Active blocks are sorted by region, then by weight.
+ * Disabled blocks are sorted by name.
+ */
+function _block_compare($a, $b) {
+ $status = $b['status'] - $a['status'];
+ // Separate enabled from disabled.
+ if ($status) {
+ return $status;
+ }
+ // Enabled blocks
+ if ($a['status']) {
+ $place = strcmp($a['region'], $b['region']);
+ return $place ? $place : ($a['weight'] - $b['weight']);
+ }
+ // Disabled blocks
+ else {
+ return strcmp($a['info'], $b['info']);
+ }
+}
+
+/**
+ * Process main block administration form submission.
+ */
+function block_admin_display_submit($form_id, $form_values) {
+ foreach ($form_values as $block) {
+ $block['status'] = $block['region'] != BLOCK_REGION_NONE;
+ $block['region'] = $block['status'] ? $block['region'] : '';
+ db_query("UPDATE {blocks} SET status = %d, weight = %d, region = '%s', throttle = %d WHERE module = '%s' AND delta = '%s' AND theme = '%s'", $block['status'], $block['weight'], $block['region'], $block['throttle'], $block['module'], $block['delta'], $block['theme']);
+ }
+ drupal_set_message(t('The block settings have been updated.'));
+ cache_clear_all();
+}
+
+/**
+ * Theme main block administration form submission.
+ *
+ * Note: the blocks are already sorted in the right order,
+ * grouped by status, region and weight.
+ */
+function theme_block_admin_display($form) {
+ global $theme_key;
+
+ $throttle = module_exists('throttle');
+ $block_regions = system_region_list($theme_key);
+
+ // Highlight regions on page to provide visual reference.
+ foreach ($block_regions as $key => $value) {
+ drupal_set_content($key, 'TRUE (PHP-mode, experts only).');
+ $description .= ' '. t('If the PHP-mode is chosen, enter PHP code between %php. Note that executing incorrect PHP-code can break your Drupal site.', array('%php' => ''));
+ }
+ $form['page_vis_settings']['visibility'] = array(
+ '#type' => 'radios',
+ '#title' => t('Show block on specific pages'),
+ '#options' => $options,
+ '#default_value' => $edit['visibility'],
+ );
+ $form['page_vis_settings']['pages'] = array(
+ '#type' => 'textarea',
+ '#title' => t('Pages'),
+ '#default_value' => $edit['pages'],
+ '#description' => $description,
+ );
+ }
+
+ $form['submit'] = array(
+ '#type' => 'submit',
+ '#value' => t('Save block'),
+ );
+
+ return $form;
+}
+
+function block_admin_configure_validate($form_id, $form_values) {
+ if ($form_values['module'] == 'block') {
+ if (empty($form_values['info']) || db_num_rows(db_query("SELECT bid FROM {boxes} WHERE bid != %d AND info = '%s'", $form_values['delta'], $form_values['info']))) {
+ form_set_error('info', t('Please ensure that each block description is unique.'));
+ }
+ }
+}
+
+function block_admin_configure_submit($form_id, $form_values) {
+ if (!form_get_errors()) {
+ db_query("UPDATE {blocks} SET visibility = %d, pages = '%s', custom = %d, title = '%s' WHERE module = '%s' AND delta = '%s'", $form_values['visibility'], trim($form_values['pages']), $form_values['custom'], $form_values['title'], $form_values['module'], $form_values['delta']);
+ db_query("DELETE FROM {blocks_roles} WHERE module = '%s' AND delta = '%s'", $form_values['module'], $form_values['delta']);
+ foreach (array_filter($form_values['roles']) as $rid) {
+ db_query("INSERT INTO {blocks_roles} (rid, module, delta) VALUES (%d, '%s', '%s')", $rid, $form_values['module'], $form_values['delta']);
+ }
+ module_invoke($form_values['module'], 'block', 'save', $form_values['delta'], $form_values);
+ drupal_set_message(t('The block configuration has been saved.'));
+ cache_clear_all();
+ return 'admin/build/block';
+ }
+}
+
+/**
+ * Menu callback: display the custom block addition form.
+ */
+function block_add_block_form() {
+ return block_admin_configure('block', NULL);
+}
+
+function block_add_block_form_validate($form_id, $form_values) {
+ if (empty($form_values['info']) || db_num_rows(db_query("SELECT info FROM {boxes} WHERE info = '%s'", $form_values['info']))) {
+ form_set_error('info', t('Please ensure that each block description is unique.'));
+ }
+}
+
+/**
+ * Save the new custom block.
+ */
+function block_add_block_form_submit($form_id, $form_values) {
+ $delta = db_next_id('{boxes}_bid');
+
+ foreach (list_themes() as $key => $theme) {
+ if ($theme->status) {
+ db_query("INSERT INTO {blocks} (visibility, pages, custom, title, module, theme, status, weight, delta) VALUES(%d, '%s', %d, '%s', '%s', '%s', %d, %d, %d)", $form_values['visibility'], trim($form_values['pages']), $form_values['custom'], $form_values['title'], $form_values['module'], $theme->name, 0, 0, $delta);
+ }
+ }
+
+ foreach (array_filter($form_values['roles']) as $rid) {
+ db_query("INSERT INTO {blocks_roles} (rid, module, delta) VALUES (%d, '%s', '%s')", $rid, $form_values['module'], $delta);
+ }
+
+ db_query("INSERT INTO {boxes} (bid, body, info, format) VALUES (%d, '%s', '%s', %d)", $delta, $form_values['body'], $form_values['info'], $form_values['format']);
+
+ drupal_set_message(t('The block has been created.'));
+ cache_clear_all();
+
+ return 'admin/build/block';
+}
+
+/**
+ * Menu callback; confirm deletion of custom blocks.
+ */
+function block_box_delete($bid = 0) {
+ $box = block_box_get($bid);
+ $form['info'] = array('#type' => 'hidden', '#value' => $box['info'] ? $box['info'] : $box['title']);
+ $form['bid'] = array('#type' => 'hidden', '#value' => $bid);
+
+ return confirm_form($form, t('Are you sure you want to delete the block %name?', array('%name' => $box['info'])), 'admin/build/block', '', t('Delete'), t('Cancel'));
+}
+
+/**
+ * Deletion of custom blocks.
+ */
+function block_box_delete_submit($form_id, $form_values) {
+ db_query('DELETE FROM {boxes} WHERE bid = %d', $form_values['bid']);
+ db_query("DELETE FROM {blocks} WHERE module = 'block' AND delta = %d", $form_values['bid']);
+ drupal_set_message(t('The block %name has been removed.', array('%name' => $form_values['info'])));
+ cache_clear_all();
+ return 'admin/build/block';
+};
+
+/**
+ * Define the custom block form.
+ */
+function block_box_form($edit = array()) {
+ $edit += array(
+ 'info' => '',
+ 'body' => '',
+ );
+ $form['info'] = array(
+ '#type' => 'textfield',
+ '#title' => t('Block description'),
+ '#default_value' => $edit['info'],
+ '#maxlength' => 64,
+ '#description' => t('A brief description of your block. Used on the block overview page.', array('@overview' => url('admin/build/block'))),
+ '#required' => TRUE,
+ '#weight' => -19,
+ );
+ $form['body_field']['#weight'] = -17;
+ $form['body_field']['body'] = array(
+ '#type' => 'textarea',
+ '#title' => t('Block body'),
+ '#default_value' => $edit['body'],
+ '#rows' => 15,
+ '#description' => t('The content of the block as shown to the user.'),
+ '#weight' => -17,
+ );
+ if (!isset($edit['format'])) {
+ $edit['format'] = FILTER_FORMAT_DEFAULT;
+ }
+ $form['body_field']['format'] = filter_form($edit['format'], -16);
+
+ return $form;
+}
+
+function block_box_save($edit, $delta) {
+ if (!filter_access($edit['format'])) {
+ $edit['format'] = FILTER_FORMAT_DEFAULT;
+ }
+
+ db_query("UPDATE {boxes} SET body = '%s', info = '%s', format = %d WHERE bid = %d", $edit['body'], $edit['info'], $edit['format'], $delta);
+
+ return TRUE;
+}
Index: modules/comment/comment.module
===================================================================
RCS file: /cvs/drupal/drupal/modules/comment/comment.module,v
retrieving revision 1.540
diff -u -p -r1.540 comment.module
--- modules/comment/comment.module 27 Apr 2007 07:42:54 -0000 1.540
+++ modules/comment/comment.module 30 Apr 2007 06:38:29 -0000
@@ -201,6 +201,7 @@ function comment_menu() {
'description' => t('List and edit site comments and the comment moderation queue.'),
'page callback' => 'comment_admin',
'access arguments' => array('administer comments'),
+ 'includes' => drupal_get_path('module', 'comment') . '/comment.pages.inc',
);
// Tabs:
@@ -220,6 +221,7 @@ function comment_menu() {
'title' => t('Approval queue'),
'page arguments' => array('approval'),
'type' => MENU_LOCAL_TASK,
+ 'includes' => drupal_get_path('module', 'comment') . '/comment.pages.inc',
);
$items['admin/content/comment/settings'] = array(
@@ -228,6 +230,7 @@ function comment_menu() {
'page arguments' => array('comment_admin_settings'),
'weight' => 10,
'type' => MENU_LOCAL_TASK,
+ 'includes' => drupal_get_path('module', 'comment') . '/comment.pages.inc',
);
$items['comment/delete'] = array(
@@ -235,6 +238,7 @@ function comment_menu() {
'page callback' => 'comment_delete',
'access arguments' => array('administer comments'),
'type' => MENU_CALLBACK,
+ 'includes' => drupal_get_path('module', 'comment') . '/comment.pages.inc',
);
$items['comment/edit'] = array(
@@ -242,6 +246,7 @@ function comment_menu() {
'page callback' => 'comment_edit',
'access arguments' => array('post comments'),
'type' => MENU_CALLBACK,
+ 'includes' => drupal_get_path('module', 'comment') . '/comment.pages.inc',
);
$items['comment/reply/%node'] = array(
'title' => t('Reply to comment'),
@@ -250,6 +255,7 @@ function comment_menu() {
'access callback' => 'node_access',
'access arguments' => array('view', 2),
'type' => MENU_CALLBACK,
+ 'includes' => drupal_get_path('module', 'comment') . '/comment.pages.inc',
);
$items['node/%node/%'] = array(
'title' => t('View'),
@@ -258,6 +264,7 @@ function comment_menu() {
'access callback' => '_comment_view_access',
'access arguments' => array(1, 2),
'type' => MENU_CALLBACK,
+ 'includes' => drupal_get_path('module', 'comment') . '/comment.pages.inc',
);
return $items;
@@ -287,6 +294,7 @@ function comment_block($op = 'list', $de
}
}
+
/**
* Find a number of recent comments. This is done in two steps.
* 1. Find the n (specified by $number) nodes that have the most recent
@@ -511,1557 +519,108 @@ function comment_user($type, $edit, &$us
}
/**
- * Menu callback; presents the comment settings page.
- */
-function comment_admin_settings() {
- $form['viewing_options'] = array(
- '#type' => 'fieldset',
- '#title' => t('Viewing options'),
- '#collapsible' => TRUE,
- );
-
- $form['viewing_options']['comment_default_mode'] = array(
- '#type' => 'radios',
- '#title' => t('Default display mode'),
- '#default_value' => variable_get('comment_default_mode', COMMENT_MODE_THREADED_EXPANDED),
- '#options' => _comment_get_modes(),
- '#description' => t('The default view for comments. Expanded views display the body of the comment. Threaded views keep replies together.'),
- );
-
- $form['viewing_options']['comment_default_order'] = array(
- '#type' => 'radios',
- '#title' => t('Default display order'),
- '#default_value' => variable_get('comment_default_order', COMMENT_ORDER_NEWEST_FIRST),
- '#options' => _comment_get_orders(),
- '#description' => t('The default sorting for new users and anonymous users while viewing comments. These users may change their view using the comment control panel. For registered users, this change is remembered as a persistent user preference.'),
- );
-
- $form['viewing_options']['comment_default_per_page'] = array(
- '#type' => 'select',
- '#title' => t('Default comments per page'),
- '#default_value' => variable_get('comment_default_per_page', 50),
- '#options' => _comment_per_page(),
- '#description' => t('Default number of comments for each page: more comments are distributed in several pages.'),
- );
-
- $form['viewing_options']['comment_controls'] = array(
- '#type' => 'radios',
- '#title' => t('Comment controls'),
- '#default_value' => variable_get('comment_controls', COMMENT_CONTROLS_HIDDEN),
- '#options' => array(
- t('Display above the comments'),
- t('Display below the comments'),
- t('Display above and below the comments'),
- t('Do not display')),
- '#description' => t('Position of the comment controls box. The comment controls let the user change the default display mode and display order of comments.'),
- );
-
- $form['posting_settings'] = array(
- '#type' => 'fieldset',
- '#title' => t('Posting settings'),
- '#collapsible' => TRUE,
- );
-
- $form['posting_settings']['comment_anonymous'] = array(
- '#type' => 'radios',
- '#title' => t('Anonymous commenting'),
- '#default_value' => variable_get('comment_anonymous', COMMENT_ANONYMOUS_MAYNOT_CONTACT),
- '#options' => array(
- COMMENT_ANONYMOUS_MAYNOT_CONTACT => t('Anonymous posters may not enter their contact information'),
- COMMENT_ANONYMOUS_MAY_CONTACT => t('Anonymous posters may leave their contact information'),
- COMMENT_ANONYMOUS_MUST_CONTACT => t('Anonymous posters must leave their contact information')),
- '#description' => t('This option is enabled when anonymous users have permission to post comments on the permissions page.', array('@url' => url('admin/user/access', array('fragment' => 'module-comment')))),
- );
- if (!user_access('post comments', user_load(array('uid' => 0)))) {
- $form['posting_settings']['comment_anonymous']['#disabled'] = TRUE;
- }
-
- $form['posting_settings']['comment_subject_field'] = array(
- '#type' => 'radios',
- '#title' => t('Comment subject field'),
- '#default_value' => variable_get('comment_subject_field', 1),
- '#options' => array(t('Disabled'), t('Enabled')),
- '#description' => t('Can users provide a unique subject for their comments?'),
- );
-
- $form['posting_settings']['comment_preview'] = array(
- '#type' => 'radios',
- '#title' => t('Preview comment'),
- '#default_value' => variable_get('comment_preview', COMMENT_PREVIEW_REQUIRED),
- '#options' => array(t('Optional'), t('Required')),
- );
-
- $form['posting_settings']['comment_form_location'] = array(
- '#type' => 'radios',
- '#title' => t('Location of comment submission form'),
- '#default_value' => variable_get('comment_form_location', COMMENT_FORM_SEPARATE_PAGE),
- '#options' => array(t('Display on separate page'), t('Display below post or comments')),
- );
-
- return system_settings_form($form);
-}
-
-/**
- * This is *not* a hook_access() implementation. This function is called
- * to determine whether the current user has access to a particular comment.
+ * Invoke a hook_comment() operation in all modules.
*
- * Authenticated users can edit their comments as long they have not been
- * replied to. This prevents people from changing or revising their
- * statements based on the replies to their posts.
+ * @param &$comment
+ * A comment object.
+ * @param $op
+ * A string containing the name of the comment operation.
+ * @return
+ * The returned value of the invoked hooks.
*/
-function comment_access($op, $comment) {
- global $user;
-
- if ($op == 'edit') {
- return ($user->uid && $user->uid == $comment->uid && comment_num_replies($comment->cid) == 0) || user_access('administer comments');
+function comment_invoke_comment(&$comment, $op) {
+ $return = array();
+ foreach (module_implements('comment') as $name) {
+ $function = $name .'_comment';
+ $result = $function($comment, $op);
+ if (isset($result) && is_array($result)) {
+ $return = array_merge($return, $result);
+ }
+ else if (isset($result)) {
+ $return[] = $result;
+ }
}
+ return $return;
}
-function comment_node_url() {
- return arg(0) .'/'. arg(1);
-}
-
-function comment_edit($cid) {
- global $user;
-
- $comment = db_fetch_object(db_query('SELECT c.*, u.uid, u.name AS registered_name, u.data FROM {comments} c INNER JOIN {users} u ON c.uid = u.uid WHERE c.cid = %d', $cid));
- $comment = drupal_unpack($comment);
- $comment->name = $comment->uid ? $comment->registered_name : $comment->name;
- if (comment_access('edit', $comment)) {
- return comment_form_box((array)$comment);
- }
- else {
- drupal_access_denied();
- }
-}
/**
- * This function is responsible for generating a comment reply form.
- * There are several cases that have to be handled, including:
- * - replies to comments
- * - replies to nodes
- * - attempts to reply to nodes that can no longer accept comments
- * - respecting access permissions ('access comments', 'post comments', etc.)
- *
- * The node or comment that is being replied to must appear above the comment
- * form to provide the user context while authoring the comment.
+ * Generate vancode.
*
- * @param $node
- * Every comment belongs to a node. This is that node.
- * @param $pid
- * Some comments are replies to other comments. In those cases, $pid is the parent
- * comment's cid.
+ * Consists of a leading character indicating length, followed by N digits
+ * with a numerical value in base 36. Vancodes can be sorted as strings
+ * without messing up numerical order.
*
- * @return $output
- * The rendered parent node or comment plus the new comment form.
+ * It goes:
+ * 00, 01, 02, ..., 0y, 0z,
+ * 110, 111, ... , 1zy, 1zz,
+ * 2100, 2101, ..., 2zzy, 2zzz,
+ * 31000, 31001, ...
*/
-function comment_reply($node, $pid = NULL) {
- // Set the breadcrumb trail.
- menu_set_location(array(array('path' => "node/$node->nid", 'title' => $node->title), array('path' => "comment/reply/$node->nid")));
-
- $op = isset($_POST['op']) ? $_POST['op'] : '';
-
- $output = '';
-
- if (user_access('access comments')) {
- // The user is previewing a comment prior to submitting it.
- if ($op == t('Preview comment')) {
- if (user_access('post comments')) {
- $output .= comment_form_box(array('pid' => $pid, 'nid' => $node->nid), NULL);
- }
- else {
- drupal_set_message(t('You are not authorized to post comments.'), 'error');
- drupal_goto("node/$node->nid");
- }
- }
- else {
- // $pid indicates that this is a reply to a comment.
- if ($pid) {
- // load the comment whose cid = $pid
- if ($comment = db_fetch_object(db_query('SELECT c.*, u.uid, u.name AS registered_name, u.signature, u.picture, u.data FROM {comments} c INNER JOIN {users} u ON c.uid = u.uid WHERE c.cid = %d AND c.status = %d', $pid, COMMENT_PUBLISHED))) {
- // If that comment exists, make sure that the current comment and the parent comment both
- // belong to the same parent node.
- if ($comment->nid != $node->nid) {
- // Attempting to reply to a comment not belonging to the current nid.
- drupal_set_message(t('The comment you are replying to does not exist.'), 'error');
- drupal_goto("node/$node->nid");
- }
- // Display the parent comment
- $comment = drupal_unpack($comment);
- $comment->name = $comment->uid ? $comment->registered_name : $comment->name;
- $output .= theme('comment_view', $comment);
- }
- else {
- drupal_set_message(t('The comment you are replying to does not exist.'), 'error');
- drupal_goto("node/$node->nid");
- }
- }
- // This is the case where the comment is in response to a node. Display the node.
- else if (user_access('access content')) {
- $output .= node_view($node);
- }
-
- // Should we show the reply box?
- if (node_comment_mode($node->nid) != COMMENT_NODE_READ_WRITE) {
- drupal_set_message(t("This discussion is closed: you can't post new comments."), 'error');
- drupal_goto("node/$node->nid");
- }
- else if (user_access('post comments')) {
- $output .= comment_form_box(array('pid' => $pid, 'nid' => $node->nid), t('Reply'));
- }
- else {
- drupal_set_message(t('You are not authorized to post comments.'), 'error');
- drupal_goto("node/$node->nid");
- }
- }
- }
- else {
- drupal_set_message(t('You are not authorized to view comments.'), 'error');
- drupal_goto("node/$node->nid");
- }
-
- return $output;
+function int2vancode($i = 0) {
+ $num = base_convert((int)$i, 10, 36);
+ $length = strlen($num);
+ return chr($length + ord('0') - 1) . $num;
}
/**
- * Accepts a submission of new or changed comment content.
- *
- * @param $edit
- * A comment array.
- *
- * @return
- * If the comment is successfully saved the comment ID is returned. If the comment
- * is not saved, FALSE is returned.
+ * Decode vancode back to an integer.
*/
-function comment_save($edit) {
- global $user;
- if (user_access('post comments') && (user_access('administer comments') || node_comment_mode($edit['nid']) == COMMENT_NODE_READ_WRITE)) {
- if (!form_get_errors()) {
- if ($edit['cid']) {
- // Update the comment in the database.
- db_query("UPDATE {comments} SET status = %d, timestamp = %d, subject = '%s', comment = '%s', format = %d, uid = %d, name = '%s', mail = '%s', homepage = '%s' WHERE cid = %d", $edit['status'], $edit['timestamp'], $edit['subject'], $edit['comment'], $edit['format'], $edit['uid'], $edit['name'], $edit['mail'], $edit['homepage'], $edit['cid']);
-
- _comment_update_node_statistics($edit['nid']);
-
- // Allow modules to respond to the updating of a comment.
- comment_invoke_comment($edit, 'update');
-
- // Add an entry to the watchdog log.
- watchdog('content', 'Comment: updated %subject.', array('%subject' => $edit['subject']), WATCHDOG_NOTICE, l(t('view'), 'node/'. $edit['nid'], array('fragment' => 'comment-'. $edit['cid'])));
- }
- else {
- // Check for duplicate comments. Note that we have to use the
- // validated/filtered data to perform such check.
- $duplicate = db_result(db_query("SELECT COUNT(cid) FROM {comments} WHERE pid = %d AND nid = %d AND subject = '%s' AND comment = '%s'", $edit['pid'], $edit['nid'], $edit['subject'], $edit['comment']), 0);
- if ($duplicate != 0) {
- watchdog('content', 'Comment: duplicate %subject.', array('%subject' => $edit['subject']), WATCHDOG_WARNING);
- }
-
- // Add the comment to database.
- $status = user_access('post comments without approval') ? COMMENT_PUBLISHED : COMMENT_NOT_PUBLISHED;
- $roles = variable_get('comment_roles', array());
- $score = 0;
-
- foreach (array_intersect(array_keys($roles), array_keys($user->roles)) as $rid) {
- $score = max($roles[$rid], $score);
- }
-
- $users = serialize(array(0 => $score));
-
- // Here we are building the thread field. See the documentation for
- // comment_render().
- if ($edit['pid'] == 0) {
- // This is a comment with no parent comment (depth 0): we start
- // by retrieving the maximum thread level.
- $max = db_result(db_query('SELECT MAX(thread) FROM {comments} WHERE nid = %d', $edit['nid']));
-
- // Strip the "/" from the end of the thread.
- $max = rtrim($max, '/');
-
- // Finally, build the thread field for this new comment.
- $thread = int2vancode(vancode2int($max) + 1) .'/';
- }
- else {
- // This is comment with a parent comment: we increase
- // the part of the thread value at the proper depth.
-
- // Get the parent comment:
- $parent = _comment_load($edit['pid']);
-
- // Strip the "/" from the end of the parent thread.
- $parent->thread = (string) rtrim((string) $parent->thread, '/');
-
- // Get the max value in _this_ thread.
- $max = db_result(db_query("SELECT MAX(thread) FROM {comments} WHERE thread LIKE '%s.%%' AND nid = %d", $parent->thread, $edit['nid']));
-
- if ($max == '') {
- // First child of this parent.
- $thread = $parent->thread .'.'. int2vancode(0) .'/';
- }
- else {
- // Strip the "/" at the end of the thread.
- $max = rtrim($max, '/');
-
- // We need to get the value at the correct depth.
- $parts = explode('.', $max);
- $parent_depth = count(explode('.', $parent->thread));
- $last = $parts[$parent_depth];
-
- // Finally, build the thread field for this new comment.
- $thread = $parent->thread .'.'. int2vancode(vancode2int($last) + 1) .'/';
- }
- }
-
- $edit['cid'] = db_next_id('{comments}_cid');
- $edit['timestamp'] = time();
-
- if ($edit['uid'] === $user->uid) { // '===' because we want to modify anonymous users too
- $edit['name'] = $user->name;
- }
-
- $edit += array('mail' => '', 'homepage' => '');
- db_query("INSERT INTO {comments} (cid, nid, pid, uid, subject, comment, format, hostname, timestamp, status, score, users, thread, name, mail, homepage) VALUES (%d, %d, %d, %d, '%s', '%s', %d, '%s', %d, %d, %d, '%s', '%s', '%s', '%s', '%s')", $edit['cid'], $edit['nid'], $edit['pid'], $edit['uid'], $edit['subject'], $edit['comment'], $edit['format'], $_SERVER['REMOTE_ADDR'], $edit['timestamp'], $status, $score, $users, $thread, $edit['name'], $edit['mail'], $edit['homepage']);
-
- _comment_update_node_statistics($edit['nid']);
-
- // Tell the other modules a new comment has been submitted.
- comment_invoke_comment($edit, 'insert');
+function vancode2int($c = '00') {
+ return base_convert(substr($c, 1), 36, 10);
+}
- // Add an entry to the watchdog log.
- watchdog('content', 'Comment: added %subject.', array('%subject' => $edit['subject']), WATCHDOG_NOTICE, l(t('view'), 'node/'. $edit['nid'], array('fragment' => 'comment-'. $edit['cid'])));
- }
+/**
+ * Load the entire comment by cid.
+ */
+function _comment_load($cid) {
+ return db_fetch_object(db_query('SELECT * FROM {comments} WHERE cid = %d', $cid));
+}
- // Clear the cache so an anonymous user can see his comment being added.
- cache_clear_all();
+function comment_num_all($nid) {
+ static $cache;
- // Explain the approval queue if necessary, and then
- // redirect the user to the node he's commenting on.
- if ($status == COMMENT_NOT_PUBLISHED) {
- drupal_set_message(t('Your comment has been queued for moderation by site administrators and will be published after approval.'));
- }
- return $edit['cid'];
- }
- else {
- return FALSE;
- }
- }
- else {
- watchdog('content', 'Comment: unauthorized comment submitted or comment submitted to a closed node %subject.', array('%subject' => $edit['subject']), WATCHDOG_WARNING);
- drupal_set_message(t('Comment: unauthorized comment submitted or comment submitted to a closed node %subject.', array('%subject' => $edit['subject'])), 'error');
- return FALSE;
+ if (!isset($cache[$nid])) {
+ $cache[$nid] = db_result(db_query('SELECT comment_count FROM {node_comment_statistics} WHERE nid = %d', $nid));
}
+ return $cache[$nid];
}
-function comment_links($comment, $return = 1) {
- global $user;
-
- $links = array();
-
- // If we are viewing just this comment, we link back to the node.
- if ($return) {
- $links['comment_parent'] = array(
- 'title' => t('parent'),
- 'href' => comment_node_url(),
- 'fragment' => "comment-$comment->cid"
- );
- }
+function comment_num_replies($pid) {
+ static $cache;
- if (node_comment_mode($comment->nid) == COMMENT_NODE_READ_WRITE) {
- if (user_access('administer comments') && user_access('post comments')) {
- $links['comment_delete'] = array(
- 'title' => t('delete'),
- 'href' => "comment/delete/$comment->cid"
- );
- $links['comment_edit'] = array(
- 'title' => t('edit'),
- 'href' => "comment/edit/$comment->cid"
- );
- $links['comment_reply'] = array(
- 'title' => t('reply'),
- 'href' => "comment/reply/$comment->nid/$comment->cid"
- );
- }
- else if (user_access('post comments')) {
- if (comment_access('edit', $comment)) {
- $links['comment_edit'] = array(
- 'title' => t('edit'),
- 'href' => "comment/edit/$comment->cid"
- );
- }
- $links['comment_reply'] = array(
- 'title' => t('reply'),
- 'href' => "comment/reply/$comment->nid/$comment->cid"
- );
- }
- else {
- $links['comment_forbidden']['title'] = theme('comment_post_forbidden', $comment->nid);
- }
+ if (!isset($cache[$pid])) {
+ $cache[$pid] = db_result(db_query('SELECT COUNT(cid) FROM {comments} WHERE pid = %d AND status = %d', $pid, COMMENT_PUBLISHED));
}
- return $links;
+ return $cache[$pid];
}
/**
- * Renders comment(s).
- *
- * @param $node
- * The node which comment(s) needs rendering.
- * @param $cid
- * Optional, if given, only one comment is rendered.
- *
- * To display threaded comments in the correct order we keep a 'thread' field
- * and order by that value. This field keeps this data in
- * a way which is easy to update and convenient to use.
- *
- * A "thread" value starts at "1". If we add a child (A) to this comment,
- * we assign it a "thread" = "1.1". A child of (A) will have "1.1.1". Next
- * brother of (A) will get "1.2". Next brother of the parent of (A) will get
- * "2" and so on.
- *
- * First of all note that the thread field stores the depth of the comment:
- * depth 0 will be "X", depth 1 "X.X", depth 2 "X.X.X", etc.
- *
- * Now to get the ordering right, consider this example:
- *
- * 1
- * 1.1
- * 1.1.1
- * 1.2
- * 2
- *
- * If we "ORDER BY thread ASC" we get the above result, and this is the
- * natural order sorted by time. However, if we "ORDER BY thread DESC"
- * we get:
- *
- * 2
- * 1.2
- * 1.1.1
- * 1.1
- * 1
- *
- * Clearly, this is not a natural way to see a thread, and users will get
- * confused. The natural order to show a thread by time desc would be:
- *
- * 2
- * 1
- * 1.2
- * 1.1
- * 1.1.1
- *
- * which is what we already did before the standard pager patch. To achieve
- * this we simply add a "/" at the end of each "thread" value. This way out
- * thread fields will look like depicted below:
- *
- * 1/
- * 1.1/
- * 1.1.1/
- * 1.2/
- * 2/
+ * get number of new comments for current user and specified node
*
- * we add "/" since this char is, in ASCII, higher than every number, so if
- * now we "ORDER BY thread DESC" we get the correct order. However this would
- * spoil the reverse ordering, "ORDER BY thread ASC" -- here, we do not need
- * to consider the trailing "/" so we use a substring only.
+ * @param $nid node-id to count comments for
+ * @param $timestamp time to count from (defaults to time of last user access
+ * to node)
*/
-function comment_render($node, $cid = 0) {
+function comment_num_new($nid, $timestamp = 0) {
global $user;
- $output = '';
-
- if (user_access('access comments')) {
- // Pre-process variables.
- $nid = $node->nid;
- if (empty($nid)) {
- $nid = 0;
- }
-
- $mode = _comment_get_display_setting('mode');
- $order = _comment_get_display_setting('sort');
- $comments_per_page = _comment_get_display_setting('comments_per_page');
-
- if ($cid) {
- // Single comment view.
- $query = 'SELECT c.cid, c.pid, c.nid, c.subject, c.comment, c.format, c.timestamp, c.name, c.mail, c.homepage, u.uid, u.name AS registered_name, u.signature, u.picture, u.data, c.score, c.users, c.status FROM {comments} c INNER JOIN {users} u ON c.uid = u.uid WHERE c.cid = %d';
- $query_args = array($cid);
- if (!user_access('administer comments')) {
- $query .= ' AND c.status = %d';
- $query_args[] = COMMENT_PUBLISHED;
- }
-
- $result = db_query($query, $query_args);
-
- if ($comment = db_fetch_object($result)) {
- $comment->name = $comment->uid ? $comment->registered_name : $comment->name;
- $links = module_invoke_all('link', 'comment', $comment, 1);
- drupal_alter('link', $links, $node);
-
- $output .= theme('comment_view', $comment, $links);
- }
- }
- else {
- // Multiple comment view
- $query_count = 'SELECT COUNT(*) FROM {comments} WHERE nid = %d';
- $query = 'SELECT c.cid as cid, c.pid, c.nid, c.subject, c.comment, c.format, c.timestamp, c.name, c.mail, c.homepage, u.uid, u.name AS registered_name, u.signature, u.picture, u.data, c.score, c.users, c.thread, c.status FROM {comments} c INNER JOIN {users} u ON c.uid = u.uid WHERE c.nid = %d';
-
- $query_args = array($nid);
- if (!user_access('administer comments')) {
- $query .= ' AND c.status = %d';
- $query_count .= ' AND status = %d';
- $query_args[] = COMMENT_PUBLISHED;
- }
-
- if ($order == COMMENT_ORDER_NEWEST_FIRST) {
- if ($mode == COMMENT_MODE_FLAT_COLLAPSED || $mode == COMMENT_MODE_FLAT_EXPANDED) {
- $query .= ' ORDER BY c.timestamp DESC';
- }
- else {
- $query .= ' ORDER BY c.thread DESC';
- }
- }
- else if ($order == COMMENT_ORDER_OLDEST_FIRST) {
- if ($mode == COMMENT_MODE_FLAT_COLLAPSED || $mode == COMMENT_MODE_FLAT_EXPANDED) {
- $query .= ' ORDER BY c.timestamp';
- }
- else {
-
- /*
- ** See comment above. Analysis learns that this doesn't cost
- ** too much. It scales much much better than having the whole
- ** comment structure.
- */
-
- $query .= ' ORDER BY SUBSTRING(c.thread, 1, (LENGTH(c.thread) - 1))';
- }
- }
-
- // Start a form, for use with comment control.
- $result = pager_query($query, $comments_per_page, 0, $query_count, $query_args);
- if (db_num_rows($result) && (variable_get('comment_controls', COMMENT_CONTROLS_HIDDEN) == COMMENT_CONTROLS_ABOVE || variable_get('comment_controls', COMMENT_CONTROLS_HIDDEN) == COMMENT_CONTROLS_ABOVE_BELOW)) {
- $output .= drupal_get_form('comment_controls', $mode, $order, $comments_per_page);
- }
-
- $divs = 0;
- $last_depth = 0;
- drupal_add_css(drupal_get_path('module', 'comment') .'/comment.css');
- while ($comment = db_fetch_object($result)) {
- $comment = drupal_unpack($comment);
- $comment->name = $comment->uid ? $comment->registered_name : $comment->name;
- $comment->depth = count(explode('.', $comment->thread)) - 1;
-
- if ($mode == COMMENT_MODE_THREADED_COLLAPSED || $mode == COMMENT_MODE_THREADED_EXPANDED) {
- if ($comment->depth > $last_depth) {
- $divs++;
- $output .= 'http://example.com/directory.'));
- }
- }
- }
- }
-
- return $edit;
-}
-
-/*
-** Generate the basic commenting form, for appending to a node or display on a separate page.
-** This is rendered by theme_comment_form.
-*/
-
-function comment_form($edit, $title = NULL) {
- global $user;
-
- $op = isset($_POST['op']) ? $_POST['op'] : '';
-
- if ($user->uid) {
- if (!empty($edit['cid']) && user_access('administer comments')) {
- if (!empty($edit['author'])) {
- $author = $edit['author'];
- }
- elseif (!empty($edit['name'])) {
- $author = $edit['name'];
- }
- else {
- $author = $edit['registered_name'];
- }
-
- if (!empty($edit['status'])) {
- $status = $edit['status'];
- }
- else {
- $status = 0;
- }
-
- if (!empty($edit['date'])) {
- $date = $edit['date'];
- }
- else {
- $date = format_date($edit['timestamp'], 'custom', 'Y-m-d H:i O');
- }
-
- $form['admin'] = array(
- '#type' => 'fieldset',
- '#title' => t('Administration'),
- '#collapsible' => TRUE,
- '#collapsed' => TRUE,
- '#weight' => -2,
- );
-
- if ($edit['registered_name'] != '') {
- // The comment is by a registered user
- $form['admin']['author'] = array(
- '#type' => 'textfield',
- '#title' => t('Authored by'),
- '#size' => 30,
- '#maxlength' => 60,
- '#autocomplete_path' => 'user/autocomplete',
- '#default_value' => $author,
- '#weight' => -1,
- );
- }
- else {
- // The comment is by an anonymous user
- $form['is_anonymous'] = array(
- '#type' => 'value',
- '#value' => TRUE,
- );
- $form['admin']['name'] = array(
- '#type' => 'textfield',
- '#title' => t('Authored by'),
- '#size' => 30,
- '#maxlength' => 60,
- '#default_value' => $author,
- '#weight' => -1,
- );
- $form['admin']['mail'] = array(
- '#type' => 'textfield',
- '#title' => t('E-mail'),
- '#maxlength' => 64,
- '#size' => 30,
- '#default_value' => $edit['mail'],
- '#description' => t('The content of this field is kept private and will not be shown publicly.'),
- );
-
- $form['admin']['homepage'] = array(
- '#type' => 'textfield',
- '#title' => t('Homepage'),
- '#maxlength' => 255,
- '#size' => 30,
- '#default_value' => $edit['homepage'],
- );
- }
-
- $form['admin']['date'] = array('#type' => 'textfield', '#parents' => array('date'), '#title' => t('Authored on'), '#size' => 20, '#maxlength' => 25, '#default_value' => $date, '#weight' => -1);
-
- $form['admin']['status'] = array('#type' => 'radios', '#parents' => array('status'), '#title' => t('Status'), '#default_value' => $status, '#options' => array(t('Published'), t('Not published')), '#weight' => -1);
-
- }
- else {
- $form['_author'] = array('#type' => 'item', '#title' => t('Your name'), '#value' => theme('username', $user)
- );
- $form['author'] = array('#type' => 'value', '#value' => $user->name);
- }
- }
- else if (variable_get('comment_anonymous', COMMENT_ANONYMOUS_MAYNOT_CONTACT) == COMMENT_ANONYMOUS_MAY_CONTACT) {
- $form['name'] = array('#type' => 'textfield', '#title' => t('Your name'), '#maxlength' => 60, '#size' => 30, '#default_value' => $edit['name'] ? $edit['name'] : variable_get('anonymous', t('Anonymous'))
- );
-
- $form['mail'] = array('#type' => 'textfield', '#title' => t('E-mail'), '#maxlength' => 64, '#size' => 30, '#default_value' => $edit['mail'], '#description' => t('The content of this field is kept private and will not be shown publicly.')
- );
-
- $form['homepage'] = array('#type' => 'textfield', '#title' => t('Homepage'), '#maxlength' => 255, '#size' => 30, '#default_value' => $edit['homepage']);
- }
- else if (variable_get('comment_anonymous', COMMENT_ANONYMOUS_MAYNOT_CONTACT) == COMMENT_ANONYMOUS_MUST_CONTACT) {
- $form['name'] = array('#type' => 'textfield', '#title' => t('Your name'), '#maxlength' => 60, '#size' => 30, '#default_value' => $edit['name'] ? $edit['name'] : variable_get('anonymous', t('Anonymous')), '#required' => TRUE);
-
- $form['mail'] = array('#type' => 'textfield', '#title' => t('E-mail'), '#maxlength' => 64, '#size' => 30, '#default_value' => $edit['mail'], '#description' => t('The content of this field is kept private and will not be shown publicly.'), '#required' => TRUE);
-
- $form['homepage'] = array('#type' => 'textfield', '#title' => t('Homepage'), '#maxlength' => 255, '#size' => 30, '#default_value' => $edit['homepage']);
- }
-
- if (variable_get('comment_subject_field', 1) == 1) {
- $form['subject'] = array('#type' => 'textfield', '#title' => t('Subject'), '#maxlength' => 64, '#default_value' => !empty($edit['subject']) ? $edit['subject'] : '');
- }
-
- if (!empty($edit['comment'])) {
- $default = $edit['comment'];
- }
- else {
- $default = '';
- }
-
- $form['comment_filter']['comment'] = array(
- '#type' => 'textarea',
- '#title' => t('Comment'),
- '#rows' => 15,
- '#default_value' => $default,
- '#required' => TRUE,
- );
- if (!isset($edit['format'])) {
- $edit['format'] = FILTER_FORMAT_DEFAULT;
- }
- $form['comment_filter']['format'] = filter_form($edit['format']);
-
- $form['cid'] = array('#type' => 'value', '#value' => !empty($edit['cid']) ? $edit['cid'] : NULL);
- $form['pid'] = array('#type' => 'value', '#value' => $edit['pid']);
- $form['nid'] = array('#type' => 'value', '#value' => $edit['nid']);
- $form['uid'] = array('#type' => 'value', '#value' => !empty($edit['uid']) ? $edit['uid'] : NULL);
-
- $form['preview'] = array('#type' => 'button', '#value' => t('Preview comment'), '#weight' => 19);
- $form['#token'] = 'comment'. $edit['nid'] . $edit['pid'];
-
- // Only show post button if preview is optional or if we are in preview mode.
- // We show the post button in preview mode even if there are form errors so that
- // optional form elements (e.g., captcha) can be updated in preview mode.
- if (!form_get_errors() && ((variable_get('comment_preview', COMMENT_PREVIEW_REQUIRED) == COMMENT_PREVIEW_OPTIONAL) || ($op == t('Preview comment')) || ($op == t('Post comment')))) {
- $form['submit'] = array('#type' => 'submit', '#value' => t('Post comment'), '#weight' => 20);
- }
-
- if ($op == t('Preview comment')) {
- $form['#after_build'] = array('comment_form_add_preview');
- }
-
- if (!empty($_REQUEST['destination'])) {
- $form['#attributes']['destination'] = $_REQUEST['destination'];
- }
-
- if (empty($edit['cid']) && empty($edit['pid'])) {
- $form['#action'] = url('comment/reply/'. $edit['nid']);
- }
-
- // Graft in extra form additions
- $form = array_merge($form, comment_invoke_comment($form, 'form'));
- return $form;
-}
-
-function comment_form_box($edit, $title = NULL) {
- return theme('box', $title, drupal_get_form('comment_form', $edit, $title));
-}
-
-function comment_form_add_preview($form, $edit) {
- global $user;
-
- drupal_set_title(t('Preview comment'));
-
- $output = '';
-
- // Invoke full validation for the form, to protect against cross site
- // request forgeries (CSRF) and setting arbitrary values for fields such as
- // the input format. Preview the comment only when form validation does not
- // set any errors.
- drupal_validate_form($form['form_id']['#value'], $form);
- if (!form_get_errors()) {
- $comment = (object)_comment_form_submit($edit);
-
- // Attach the user and time information.
- if ($edit['author']) {
- $account = user_load(array('name' => $edit['author']));
- }
- elseif ($user->uid && !isset($edit['is_anonymous'])) {
- $account = $user;
- }
- if ($account) {
- $comment->uid = $account->uid;
- $comment->name = check_plain($account->name);
- }
- else {
- $comment->name = variable_get('anonymous', t('Anonymous'));
- }
- $comment->timestamp = !empty($edit['timestamp']) ? $edit['timestamp'] : time();
- $output .= theme('comment_view', $comment);
- }
- $form['comment_preview'] = array(
- '#value' => $output,
- '#weight' => -100,
- '#prefix' => '