Index: feedback.module
===================================================================
RCS file: /cvs/drupal/contributions/modules/feedback/feedback.module,v
retrieving revision 1.75
diff -u -r1.75 /cvs/drupal/contributions/modules/feedback/feedback.module
--- /cvs/drupal/contributions/modules/feedback/feedback.module	21 Mar 2009 20:22:14 -0000	1.75
+++ /cvs/drupal/contributions/modules/feedback/feedback.module	15 May 2009 17:46:48 -0000
@@ -10,7 +10,7 @@
  * Implementation of hook_perm().
  */
 function feedback_perm() {
-  return array('access feedback form', 'view feedback messages');
+  return array('access feedback form', 'view feedback messages', 'administer feedback triggers');
 }
 
 /**
@@ -143,6 +143,8 @@
 function feedback_form_submit($form, &$form_state) {
   feedback_add_entry($form_state['values']['message'], $form_state['values']['location']);
   $message = t('Thanks for your feedback!');
+  //Fire Feedback Submitted Trigger
+  module_invoke_all('feedback_changed', 'submitted', $user);
   if ($form_state['values']['ajax']) {
     echo drupal_to_js(array('message' => $message));
     exit;
@@ -347,7 +349,239 @@
   }
   // Update status of entries in database.
   foreach ($update as $fid => $value) {
+    if ($value == 1) {
+      //Fire Feedback Submitted Trigger
+      module_invoke_all('feedback_changed', 'processed', $user);
+    }
     db_query("UPDATE {feedback} SET status = %d WHERE fid = %d", $value, $fid);
   }
 }
 
+/**
+ * Implementation of hook_menu_alter
+ */
+function feedback_menu_alter(&$items) {
+  // By default, the trigger system uses the module name
+  // (i.e. example) as the access for the trigger
+  // configuration menu item.  we want to change that.
+  $items['admin/build/trigger/feedback']['access arguments'] = array('administer feedback triggers');
+}
+
+/**
+ * Implementation of hook_hook_info().
+ */
+function feedback_hook_info() {
+  return array(
+    'feedback' => array(
+      'feedback' => array(
+        'submitted' => array(
+          'runs when' => t('After feedback has been submitted'),
+        ),
+        'processed' => array(
+          'runs when' => t('After feedback has been processed'),
+        ),
+      ),
+    ),
+  );
+}
+
+/**
+ * Implementation of hook_feedback_changed().
+ */
+function feedback_feedback_changed($op, $user) {
+  // We support a subset of operations.
+  if (!in_array($op, array('submitted', 'processed'))) {
+    return;
+  }
+  $aids = _trigger_get_hook_aids('feedback', $op);
+  $context = array(
+    'hook' => 'feedback',
+    'op' => $op,
+    'user' => $user,
+  );
+  actions_do(array_keys($aids), $user, $context);
+}
+
+/**
+ * Implementation of hook_info_alter().
+ */
+function feedback_action_info_alter(&$info) {
+  foreach ($info as $type => $data) {
+    if (stripos($type, "user_") === 0 || stripos($type, "system_") === 0) {
+      if (isset($info[$type]['hooks']['feedback'])) {
+        array_merge($info[$type]['hooks']['feedback'], array('submitted', 'processed'));
+      }
+      else {
+        $info[$type]['hooks']['feedback'] = array('submitted', 'processed');
+      }
+    }
+  }
+}
+
+/**
+ * Implementation of hook_action_info().
+ */
+function feedback_action_info() {
+  return array(
+    'feedback_send_curret_user_email_action' => array(
+      'description' => t('Send current user an e-mail'),
+      'type' => 'feedback',
+      'configurable' => TRUE,
+      'hooks' => array('feedback' => array('submitted', 'processed')),
+    ),
+  );
+}
+
+/**
+ * Return a form definition so the Send email action can be configured.
+ *
+ * @see feedback_send_curret_user_email_action_validate()
+ * @see feedback_send_curret_user_email_action_submit()
+ * @param $context
+ *   Default values (if we are editing an existing action instance).
+ * @return
+ *   Form definition.
+ */
+function feedback_send_curret_user_email_action_form($context) {
+  if (!isset($context['subject'])) {
+    $context['subject'] = '';
+  }
+  if (!isset($context['message'])) {
+    $context['message'] = '';
+  }
+
+  $form['subject'] = array(
+    '#type' => 'textfield',
+    '#title' => t('Subject'),
+    '#default_value' => $context['subject'],
+    '#maxlength' => '254',
+    '#description' => t('The subject of the message.'),
+  );
+  $form['message'] = array(
+    '#type' => 'textarea',
+    '#title' => t('Message'),
+    '#default_value' => $context['message'],
+    '#cols' => '80',
+    '#rows' => '20',
+    '#description' => t('The message that should be sent. You may include the following variables: %site_name, %username, %node_url, %node_type, %title, %teaser, %body. Not all variables will be available in all contexts.'),
+  );
+  return $form;
+}
+
+/**
+ * Process system_send_email_action form submissions.
+ */
+function feedback_send_curret_user_email_action_submit($form, $form_state) {
+  $form_values = $form_state['values'];
+  // Process the HTML form to store configuration. The keyed array that
+  // we return will be serialized to the database.
+  $params = array(
+    'subject'   => $form_values['subject'],
+    'message'   => $form_values['message'],
+  );
+  return $params;
+}
+
+/**
+ * Implementation of a configurable Drupal action. Sends an email.
+ */
+function feedback_send_curret_user_email_action($object, $context) {
+  global $user;
+
+  switch ($context['hook']) {
+    case 'nodeapi':
+      // Because this is not an action of type 'node' the node
+      // will not be passed as $object, but it will still be available
+      // in $context.
+      $node = $context['node'];
+      break;
+    // The comment hook provides nid, in $context.
+    case 'comment':
+      $comment = $context['comment'];
+      $node = node_load($comment->nid);
+      break;
+    case 'user':
+      // Because this is not an action of type 'user' the user
+      // object is not passed as $object, but it will still be available
+      // in $context.
+      $account = $context['account'];
+      if (isset($context['node'])) {
+        $node = $context['node'];
+      }
+      elseif ($context['recipient'] == '%author') {
+        // If we don't have a node, we don't have a node author.
+        watchdog('error', 'Cannot use %author token in this context.');
+        return;
+      }
+      break;
+    default:
+      // We are being called directly.
+      $node = $object;
+  }
+
+  $recipient = $user->mail;
+
+  if (isset($node)) {
+    if (!isset($account)) {
+      $account = user_load(array('uid' => $node->uid));
+    }
+  }
+
+  if (!isset($account)) {
+    $account = $user;
+
+  }
+  $language = user_preferred_language($account);
+  $params = array('account' => $account, 'object' => $object, 'context' => $context);
+  if (isset($node)) {
+    $params['node'] = $node;
+  }
+
+  if (drupal_mail('system', 'action_send_current_user_email', $recipient, $language, $params)) {
+    watchdog('action', 'Sent email to %recipient', array('%recipient' => $recipient));
+  }
+  else {
+    watchdog('error', 'Unable to send email to %recipient', array('%recipient' => $recipient));
+  }
+}
+
+/**
+ * Implementation of hook_mail().
+ */
+function feedback_mail($key, &$message, $params) {
+  $account = $params['account'];
+  $context = $params['context'];
+  $variables = array(
+    '%site_name' => variable_get('site_name', 'Drupal'),
+    '%username' => $account->name,
+  );
+  if ($context['hook'] == 'taxonomy') {
+    $object = $params['object'];
+    $vocabulary = taxonomy_vocabulary_load($object->vid);
+    $variables += array(
+      '%term_name' => $object->name,
+      '%term_description' => $object->description,
+      '%term_id' => $object->tid,
+      '%vocabulary_name' => $vocabulary->name,
+      '%vocabulary_description' => $vocabulary->description,
+      '%vocabulary_id' => $vocabulary->vid,
+    );
+  }
+
+  // Node-based variable translation is only available if we have a node.
+  if (isset($params['node'])) {
+    $node = $params['node'];
+    $variables += array(
+      '%uid' => $node->uid,
+      '%node_url' => url('node/'. $node->nid, array('absolute' => TRUE)),
+      '%node_type' => node_get_types('name', $node),
+      '%title' => $node->title,
+      '%teaser' => $node->teaser,
+      '%body' => $node->body,
+    );
+  }
+  $subject = strtr($context['subject'], $variables);
+  $body = strtr($context['message'], $variables);
+  $message['subject'] .= str_replace(array("\r", "\n"), '', $subject);
+  $message['body'][] = drupal_html_to_text($body);
+}

