type]) && $allowed_node_types[$node->type]) { if ((arg(1) != 'edit') && (arg(1) != 'reply') && (arg(2) != 'edit') && (arg(2) != 'reply')) { $form['#prefix'] = '
'; // Overriding PID param so it will appear on the form. $form['pid']['#type'] = 'hidden'; $form['pid']['#default_value'] = $form['pid']['#value']; unset($form['pid']['#value']); // Node id for rebuilding form if needed $form['nid'] = array( '#type' => 'hidden', '#default_value' => $node->nid, ); // We should set specific ID to let ahah wrapper know what to wrap on ajax // loaded comment-form even if we have many submit buttons on the page. $form['preview']['#id'] = "ajax-comments-preview"; $form['preview']['#ahah'] = array( 'path' => 'ajax_comments/js', 'wrapper' => 'comment-preview', 'event' => 'click', 'method' => 'append', 'effect' => 'ajaxCommentsPreview', 'progress' => array('type' => '1bar', 'message' => t('Please wait...')), ); $form['submit']['#id'] = "ajax-comments-submit"; $form['submit']['#submit'] = array('ajax_comments_submit'); $form['submit']['#ahah'] = array( 'path' => 'ajax_comments/js', 'wrapper' => 'comment-form-content', 'event' => 'click', 'method' => 'before', 'effect' => 'ajaxCommentsSubmit', 'progress' => array('type' => '1bar', 'message' => t('Please wait...')), ); $path = drupal_get_path('module', 'ajax_comments'); drupal_add_css($path .'/ajax_comments.css'); // Language settings $mode = variable_get('language_negotiation', LANGUAGE_NEGOTIATION_NONE); $languages = language_list('enabled'); $languages = $languages[1]; drupal_add_js('misc/jquery.form.js'); drupal_add_js($path .'/ajax_comments.js', 'module'); drupal_add_js(array( 'language_mode' => $mode, 'language_list' => $languages, 'clean_url' => variable_get('clean_url', 0), 'rows_in_reply' => variable_get('ajax_comments_reply_row_count', 3), 'rows_default' => variable_get('ajax_comments_default_row_count', 5), 'always_expand_main_form' => variable_get('ajax_comments_always_expand_form', TRUE), 'blink_new' => variable_get('ajax_comments_blink_new', TRUE), 'comment_preview_required' => variable_get('comment_preview_'. $node->type, COMMENT_PREVIEW_REQUIRED) == COMMENT_PREVIEW_REQUIRED ), 'setting'); } } } /** * Implementation of hook_menu(). */ function ajax_comments_menu() { $items['admin/settings/ajax_comments'] = array( 'title' => 'AJAX comments', 'description' => 'AJAXifies comments on site.', 'page callback' => 'drupal_get_form', 'page arguments' => array('ajax_comments_settings'), 'access arguments' => array('administer site configuration'), 'file' => 'ajax_comments.admin.inc', ); $items['ajax_comments/instant_delete/%'] = array( 'page callback' => 'ajax_comments_instant_delete', 'page arguments' => array(2), 'access arguments' => array('administer comments'), 'type' => MENU_CALLBACK, ); $items['ajax_comments/js'] = array( 'page callback' => 'ajax_comments_js', 'access arguments' => array('access content'), 'type' => MENU_CALLBACK, ); $items['ajax_comments/js_reload/%'] = array( 'page callback' => 'ajax_comments_js_reload_form', 'page arguments' => array(2, 3), 'access arguments' => array('access content'), 'type' => MENU_CALLBACK, ); return $items; } /** * AHAH callback. */ function ajax_comments_js() { $form_state = array('storage' => NULL, 'submitted' => FALSE); $form_build_id = $_POST['form_build_id']; $form = ajax_comments_form_get_cache($form_build_id, $form_state); if($form) { $args = $form['#parameters']; $form_id = array_shift($args); } // Build form from scratch (e.g., Authcache module does not cache forms within the caching system) else { $form_id = 'comment_form'; $edit['nid'] = $_POST['nid']; $args = array($form_id, $edit); $form_state['post'] = $_POST; // Use a copy of the function's arguments for manipulation $args_temp = $args; $args_temp[0] = &$form_state; array_unshift($args_temp, $form_id); $form = call_user_func_array('drupal_retrieve_form', $args_temp); $form_build_id = 'form-'. md5(uniqid(mt_rand(), true)); $form['#build_id'] = $form_build_id; drupal_prepare_form($form_id, $form, $form_state); $original_form = $form; $cacheable = FALSE; // No need to cache; amost done //unset($form_state['post']); $form['#post'] = $_POST; } $form_state['post'] = $form['#post'] = $_POST; $form['#programmed'] = $form['#redirect'] = FALSE; if ($form_state['post']['op'] == t('Preview')) { $form['#after_build'] = array('comment_form_add_preview'); } else { unset($form['#after_build']); } drupal_process_form($form_id, $form, $form_state); $errors = form_get_errors(); if (!$errors) { // Prepare output if ($form_state['values']['op'] == t('Preview')) { $output = '
'. $form['comment_preview']['#value'] .'
'; if ($output && $form_state['values']['pid']) { $output = '
'. $output .'
'; } } elseif ($form_state['values']['op'] == t('Save')) { $output = '
'. $form_state['storage']['ajax_comment'] .'
'; } $form = form_builder($form_id, $form, $form_state); // Add Submit button if preview was required $node = node_load($form_state['values']['nid']); $op = $form_state['values']['op']; if (variable_get('comment_preview_'. $node->type, COMMENT_PREVIEW_REQUIRED) == COMMENT_PREVIEW_REQUIRED && ($op == t('Preview') || $op == t('Save'))) { $form['submit'] = array( '#type' => 'submit', '#value' => t('Save'), '#weight' => 19, '#executes_submit_callback' => TRUE, ); $form['submit']['#id'] = "ajax-comments-submit"; $form['submit']['#submit'] = array('ajax_comments_submit'); $form['submit']['#ahah'] = array( 'path' => 'ajax_comments/js', 'wrapper' => 'comment-form-content', 'event' => 'click', 'method' => 'before', 'effect' => 'ajaxCommentsSubmit', 'progress' => array('type' => '1bar', 'message' => t('Please wait...')), ); $form = form_builder($form_id, $form, $form_state); form_set_cache($form_build_id, $form, $form_state); } } unset($form['#suffix']); unset($form['#prefix']); $output = theme('status_messages') . $output; if ($output) { $javascript = drupal_add_js(NULL, NULL); if (isset($javascript['setting'])) { $output .= ''; } drupal_json(array( 'status' => TRUE, 'data' => $output, )); } } /** * Fetch a form from cache. */ function ajax_comments_form_get_cache($form_build_id, &$form_state) { global $user; if ($cached = ajax_comments_cache_get('form_'. $form_build_id, 'cache_form')) { $form = $cached->data; if ((isset($form['#cache_token']) && drupal_valid_token($form['#cache_token'])) || (!isset($form['#cache_token']) && !$user->uid)) { if ($cached = ajax_comments_cache_get('storage_'. $form_build_id, 'cache_form')) { $form_state['storage'] = $cached->data; } return $form; } } } /** * This one differs from standard by loading even expired cache instances. */ function ajax_comments_cache_get($cid, $table = 'cache') { global $user; // Garbage collection necessary when enforcing a minimum cache lifetime $cache_flush = variable_get('cache_flush', 0); if ($cache_flush && ($cache_flush + variable_get('cache_lifetime', 0) <= time())) { // Reset the variable immediately to prevent a meltdown in heavy load situations. variable_set('cache_flush', 0); // Time to flush old cache data // Support third-party caching systems such as CacheRouter if(variable_get('cache_inc', FALSE)) { cache_clear_all(NULL, $table); } // Drupal core caching tables else { db_query("DELETE FROM {". $table ."} WHERE expire != %d AND expire <= %d", CACHE_PERMANENT, $cache_flush); } } // Support third-party caching systems such as CacheRouter if(variable_get('cache_inc', FALSE)) { $cache = cache_get($cid, $table); if (isset($cache->data)) { return $cache; } } // Drupal core caching tables else { $cache = db_fetch_object(db_query("SELECT data, created, headers, expire, serialized FROM {". $table ."} WHERE cid = '%s'", $cid)); if (isset($cache->data)) { $cache->data = db_decode_blob($cache->data); if ($cache->serialized) { $cache->data = unserialize($cache->data); } return $cache; } } return 0; } /** * Delivers a new comments form after comment have been submitted. */ function ajax_comments_js_reload_form($nid, $pid = NULL) { drupal_set_header('Content-type: text/javascript; charset=utf-8'); $edit = array('nid' => $nid); if (isset($pid)) { $edit['pid'] = $pid; } print(drupal_get_form('comment_form', $edit, $title)); exit(); } /** * Comment submit routine. */ function ajax_comments_submit($form, &$form_state) { //remove self unset($form_state['submit_handlers']); // ..and standart comments submit handler foreach ($form['#submit'] as $key => $value) { if ($value == 'comment_form_submit') { unset($form['#submit'][$key]); } } //execute all others form_execute_handlers('submit', $form, $form_state); //save comment just like comments module do it $edit = $form_state['values']; _comment_form_submit($edit); if ($cid = comment_save($edit)) { $errors = form_get_errors(); if (!$errors) { $node = node_load($edit['nid']); // update node stats _comment_update_node_statistics($node->nid); node_tag_new($node->nid); $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.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; } $query = db_rewrite_sql($query, 'c', 'cid'); $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, 0); drupal_alter('link', $links, $node); //render our comment and get it back to AHAH handler $output .= theme('comment_view', $comment, $node, $links); $form_state['storage']['ajax_comment'] = $output; } } } return $output; } /** * Comments delete callback. */ function ajax_comments_instant_delete($cid = 0){ // Check token to avoid CSRF attack. if ($cid && isset($_GET['token']) && drupal_valid_token($_GET['token'], $cid)) { drupal_set_header('Content-type: text/javascript; charset=utf-8'); module_load_include('inc', 'comment', 'comment.admin'); $comment = _comment_load($cid); // Delete comment and its replies. _comment_delete_thread($comment); _comment_update_node_statistics($comment->nid); // Clear the cache so an anonymous user sees that his comment was deleted. cache_clear_all(); print('OK'); } exit(); } /** * Implementation of hook_link_alter(). */ function ajax_comments_link_alter(&$links, $comment) { $node = menu_get_object(); $allowed_node_types = variable_get('ajax_comments_node_types', array()); $all_allowed = TRUE; foreach ($allowed_node_types as $type) { if ($type) { $all_allowed = FALSE; break; } } if ($all_allowed || isset($allowed_node_types[$node->type]) && $allowed_node_types[$node->type]) { if (is_array($links) && isset($links['comment_delete'])) { $links['comment_delete'] = array( 'title' => t('delete'), 'href' => 'comment/delete/'. $comment->cid, 'query' => 'token='. drupal_get_token($comment->cid), ); } } } /** * Process variables for comment.tpl.php. */ function ajax_comments_preprocess_comment(&$variables) { $comment = $variables['comment']; // Insert proper delete links (fix until hook_link_alter will not work propertly) if ($variables['links'] && user_access('administer comments')) { $links = module_invoke_all('link', 'comment', $comment, 0); $links['comment_delete'] = array( 'title' => t('delete'), 'href' => 'comment/delete/'. $comment->cid, 'query' => 'token='. drupal_get_token($comment->cid), ); $variables['links'] = isset($links) ? theme('links', $links) : ''; } if (!$comment->cid) { $variables['new'] = t('preview'); $variables['comment']->new = TRUE; } else { $variables['title'] = l($comment->subject, 'node/'.$comment->nid, array('attributes' => array('class' => 'active'), 'fragment' => "comment-$comment->cid")); } }