function discussthis_create_form_submit in Discuss This! 6
\brief Save the new comment.
This function creates a new forum topic if this is the first comment on this node. Otherwise, it just adds the comment to the existing forum.
\todo We've got a problem here, if the administrator wants to moderate these comments, then we should not create the forum node. This is a similar problem to the one we see in creating the forum node before the comment is even posted to us.
I guess that the biggest problem is that a comment, to exist, needs to be attached to a node.
I see two potential solutions:
1) we handle our own comments
2) we create the comment on the node being discussed and move it later to the forum
\param[in] $form The form info \param[in] $form_state The current state of the form, including the values
1 string reference to 'discussthis_create_form_submit'
- discussthis_create_form in ./
discussthis.module - \brief Create a comment form.
File
- ./
discussthis.module, line 960 - Associations discussions in forums with specific nodes
Code
function discussthis_create_form_submit($form, &$form_state) {
global $user;
// we got a post, so we want to create the forum node
// load the node being discussed
$node = node_load($form_state['values']['discussthis_nid']);
if (!$node) {
// what shall we do here? the admin could delete the node while
// a user is trying to discuss it...
drupal_set_message(t('The node being discussed is not available anymore. (nid: @nid)', array(
'@nid' => $form_state['values']['discussthis_nid'],
)), 'error');
drupal_goto('');
}
// TODO:
//if (!user_access('post comments without approval')) {
// // The comment needs to be approved, save it in our discussthis_comment table
// // (this is annoying, but otherwise we get a post in the way?! maybe we could
// // have a flag in the settings of discussthis so users can choose how to handle
// // this case?)
// $sql = "INSERT INTO {discussthis_comment} (...) VALUES (...)";
// db_query($sql, ...);
//}
// some of the functions used to create a node require node pages include
module_load_include('inc', 'node', 'node.pages');
// The core defines a way to create a node which is to fill a form
// and then call drupal_execute() from includes/form.inc.
$sub_form_state = array();
// get the author of the node and pass that to the token_replace() call
$author = user_load(array(
'uid' => $node->uid,
));
// TITLE
$sub_form_state['values']['title'] = token_replace(variable_get('discussthis_newsubject', '[node-title]'), 'discussthis', $node);
if ($author) {
$sub_form_state['values']['title'] = token_replace($sub_form_state['values']['title'], 'user', $author);
}
// BODY
$default_body = DISCUSSTHIS_DEFAULT_NODE_MESSAGE;
$sub_form_state['values']['body'] = token_replace(variable_get('discussthis_newtemplate', $default_body), 'discussthis', $node);
if ($author) {
$sub_form_state['values']['body'] = token_replace($sub_form_state['values']['body'], 'user', $author);
}
// FORMAT
$sub_form_state['values']['format'] = NULL;
// FORUM TERM
$forum_vid = variable_get('forum_nav_vocabulary', 1);
$vocabulary = taxonomy_vocabulary_load($forum_vid);
$discussthis_forum = _discussthis_get_forum($node->nid, $node->type);
$tid = $discussthis_forum['forum_tid'];
if ($vocabulary->tags) {
// tags are a special case, also you cannot choose tags for a forum...
$sub_form_state['values']['taxonomy']['tags'][$vid] = taxonomy_implode_tags($tid, $forum_vid);
}
elseif ($vocabulary->multiple) {
// forums should never use multiple either
$sub_form_state['values']['taxonomy'][$forum_vid][$tid] = $tid;
}
else {
$sub_form_state['values']['taxonomy'][$forum_vid] = $tid;
}
// LOG
$sub_form_state['values']['log'] = t('Node automatically created by discussthis for comment @subject', array(
'@subject' => $form_state['values']['subject'],
));
// OPERATION
$sub_form_state['values']['op'] = t('Save');
// STATUS
// Although it would be better to keep the status to the default of the forum
// 1) the post here will include data that is under control (i.e. data from
// another node that was already agreed upon)
// 2) the post needs to be published for a comment to be appended
$sub_form_state['values']['status'] = 1;
// Values that will get proper defaults automatically
//$sub_form_state['values']['date'] = date('Y-m-d H:i:s O', time());
// A special value to recognize this form in the discussthis_form_alter() function
$sub_form_state['discussthis']['post'] = 1;
// FORUM POST
$topic = (object) array(
'type' => 'forum',
);
// IMPORTANT NOTE:
// This call generates a form for the current user, not the future user of
// the new topic. This is an important distinction since some parameters
// just cannot be passed to this function if we want it to work. For instance,
// the format is set to default so it works. Any other format could fail and
// the creation of the topic would fail. ("default" is available to all users!)
drupal_execute('forum_node_form', $sub_form_state, $topic);
$topic->nid = $sub_form_state['nid'];
if (!$topic->nid) {
// it did not work... hmmm...
drupal_set_message('Forum post could not be created for your comment to be published.', 'error');
drupal_goto();
}
// Now we can save the author in the new post as expected by the
// administrator; when we try to set the UID in the node info
// before calling drupal_execute() it is reset for security reason
// and the result is that the UID is set to 0 (anonymous)
//
// load the user that was setup by the admin for this post,
// if it fails, use the anonymous user
$format = NULL;
$author_name = variable_get('discussthis_author', $user->name);
if (!$author_name || $user->name == $author_name) {
$author = $user;
}
elseif ($author_name == '*') {
$author = user_load(array(
'uid' => $node->uid,
));
// if we keep the same author, we can keep the same format
// (although that author may not be authorized to use that
// format anymore, we consider this node as safe at this
// point...)
$format = $node->format;
}
else {
$author = user_load(array(
'name' => $author_name,
));
}
if (!$author) {
$author = array(
'uid' => 0,
);
}
$sql = "UPDATE {node} SET uid = %d WHERE nid = %d";
db_query($sql, $author->uid, $topic->nid);
// now that we have the right author, compute the right format
// note that we leave the format alone if the offered format
// is not otherwise allowed
if (is_null($format)) {
// get the format selected by the admin and verify its validity
$format = (int) variable_get('discussthis_format_' . $node->type, 0);
if ($format > 0) {
$allowed = user_access('administer filters', $author);
if (!$allowed) {
// make sure the new author role has permission for this format
$query = 'SELECT roles FROM {filter_formats} WHERE format = %d';
$result = db_query($query, $format);
$format_roles = db_fetch_array($result);
$allowed = count(array_intersect($author->roles, explode(',', $format_roles))) > 0;
}
if ($allowed) {
// allowed, make it the format for this node
$sql = "UPDATE {node_revisions} SET format = %d" . " WHERE nid = %d" . " AND vid = (SELECT vid FROM {node} WHERE nid = %d)";
db_query($sql, $format, $topic->nid, $topic->nid);
}
}
}
// now that we created the topic node, we want to link it to the
// node being discussed ($topic and $node)
//
// here we use a LOCK to make sure we can create the new row all
// alone, if the row actually exists, we actually had another user
// create a post ahead of us! so we're going to add the comment
// to that other node and we can delete the node we just created.
// make sure we INSERT alone!
db_lock_table('discussthis');
$sql = "SELECT topic_nid FROM {discussthis} WHERE nid = %d";
$other_topic_nid = db_result(db_query($sql, $node->nid));
if (!$other_topic_nid) {
// this is a new topic, we're the first to post!
// so attach the new forum post to the node being discussed
$sql = "INSERT INTO {discussthis} (nid, topic_nid) VALUES (%d, %d)";
db_query($sql, $node->nid, $topic->nid);
}
// COMMIT the result, no insert if a topic existed anyway...
db_unlock_tables();
if ($other_topic_nid) {
// What a waste! but I don't see any way around it.
// Plus if you have signals on node creation, you'll get an email
// and this deletes right after... so the email will point to
// a non-existant node... Argh!
node_delete($topic->nid);
// hmmm... should we add an alias from $topic->nid to $topic_nid?!
// we'll assume that this will be particularly rare!
// So, the new topic nid is really the other topic nid...
$topic->nid = $other_topic_nid;
}
// now we want to save the comment
$form_state['values']['nid'] = $topic->nid;
// before calling comment_save() they call this one:
_comment_form_submit($form_state['values']);
comment_form_submit($form, $form_state);
$form_state['redirect'] = 'node/' . $topic->nid;
// if you have boost, we want to reset the discussed node since
// now it will look "different" (the link and eventually the new
// comment)
if (function_exists('boost_expire_node')) {
boost_expire_node($node);
}
}