0001-patched-for-email-sending-on-each-feedback-creation-.patch 41 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305
  1. From 235e57d8e944175ddfd7907598ada29c5c2ebb3d Mon Sep 17 00:00:00 2001
  2. From: Bachir Soussi Chiadmi <bachir@g-u-i.net>
  3. Date: Sat, 12 Oct 2013 13:27:26 +0200
  4. Subject: [PATCH] patched for email sending on each feedback creation
  5. https://drupal.org/node/353548#comment-7130746
  6. ---
  7. feedback-353548-45.patch | 338 +++++++++++++++++++++++++++
  8. feedback.module | 229 ++++++++++++++++++
  9. feedback.module.orig | 593 +++++++++++++++++++++++++++++++++++++++++++++++
  10. tests/feedback.test | 75 +++++-
  11. 4 files changed, 1231 insertions(+), 4 deletions(-)
  12. create mode 100644 feedback-353548-45.patch
  13. mode change 100755 => 100644 feedback.module
  14. create mode 100755 feedback.module.orig
  15. mode change 100755 => 100644 tests/feedback.test
  16. diff --git a/feedback-353548-45.patch b/feedback-353548-45.patch
  17. new file mode 100644
  18. index 0000000..999e88a
  19. --- /dev/null
  20. +++ b/feedback-353548-45.patch
  21. @@ -0,0 +1,338 @@
  22. +diff --git a/feedback.module b/feedback.module
  23. +index 9763575..ef5b24a 100644
  24. +--- a/feedback.module
  25. ++++ b/feedback.module
  26. +@@ -534,6 +534,235 @@ function feedback_user_delete($account) {
  27. + }
  28. +
  29. + /**
  30. ++ * Implements hook_action_info().
  31. ++ */
  32. ++function feedback_action_info() {
  33. ++ return array(
  34. ++ 'feedback_process_action' => array(
  35. ++ 'label' => t('Process entry'),
  36. ++ 'type' => 'feedback',
  37. ++ 'configurable' => FALSE,
  38. ++ 'behavior' => array('changes_property'),
  39. ++ 'triggers' => array('feedback_insert', 'feedback_update'),
  40. ++ ),
  41. ++ 'feedback_open_action' => array(
  42. ++ 'label' => t('Open entry'),
  43. ++ 'type' => 'feedback',
  44. ++ 'configurable' => FALSE,
  45. ++ 'behavior' => array('changes_property'),
  46. ++ 'triggers' => array('feedback_insert', 'feedback_update'),
  47. ++ ),
  48. ++ 'feedback_delete_action' => array(
  49. ++ 'label' => t('Delete entry'),
  50. ++ 'type' => 'feedback',
  51. ++ 'configurable' => FALSE,
  52. ++ 'triggers' => array('feedback_insert', 'feedback_update'),
  53. ++ ),
  54. ++ 'feedback_send_email_action' => array(
  55. ++ 'label' => t('Send e-mail of feedback'),
  56. ++ 'type' => 'feedback',
  57. ++ 'configurable' => TRUE,
  58. ++ 'triggers' => array('feedback_insert', 'feedback_update'),
  59. ++ ),
  60. ++ );
  61. ++}
  62. ++
  63. ++/**
  64. ++* Implements hook_trigger_info().
  65. ++*/
  66. ++function feedback_trigger_info() {
  67. ++ return array(
  68. ++ 'feedback' => array(
  69. ++ 'feedback_insert' => array(
  70. ++ 'label' => t('New feedback is added.'),
  71. ++ ),
  72. ++ 'feedback_update' => array(
  73. ++ 'label' => t('Feedback is marked processed or open.'),
  74. ++ ),
  75. ++ ),
  76. ++ );
  77. ++}
  78. ++
  79. ++/**
  80. ++ * Implements hook_feedback_insert().
  81. ++ */
  82. ++function feedback_feedback_insert($entry) {
  83. ++ $aids = trigger_get_assigned_actions('feedback_insert');
  84. ++ if (!$aids) {
  85. ++ return;
  86. ++ }
  87. ++
  88. ++ $context = array(
  89. ++ 'group' => 'feedback',
  90. ++ 'hook' => 'feedback_insert',
  91. ++ );
  92. ++
  93. ++ foreach ($aids as $aid => $info) {
  94. ++ actions_do($aid, $entry, $context);
  95. ++ }
  96. ++}
  97. ++
  98. ++/**
  99. ++ * Implements hook_feedback_update().
  100. ++ */
  101. ++function feedback_feedback_update($entry) {
  102. ++ $aids = trigger_get_assigned_actions('feedback_update');
  103. ++ if (!$aids) {
  104. ++ return;
  105. ++ }
  106. ++
  107. ++ $context = array(
  108. ++ 'group' => 'feedback',
  109. ++ 'hook' => 'feedback_update',
  110. ++ );
  111. ++
  112. ++ foreach ($aids as $aid => $info) {
  113. ++ actions_do($aid, $entry, $context);
  114. ++ }
  115. ++}
  116. ++
  117. ++/**
  118. ++ * Sets the status of an entry to processed.
  119. ++ *
  120. ++ * @ingroup actions
  121. ++ */
  122. ++function feedback_process_action($entry, $context) {
  123. ++ $entry->status = FEEDBACK_PROCESSED;
  124. ++ drupal_write_record('feedback', $entry, 'fid');
  125. ++}
  126. ++
  127. ++/**
  128. ++ * Sets the status of an entry to open.
  129. ++ *
  130. ++ * @ingroup actions
  131. ++ */
  132. ++function feedback_open_action($entry, $context) {
  133. ++ $entry->status = FEEDBACK_OPEN;
  134. ++ drupal_write_record('feedback', $entry, 'fid');
  135. ++}
  136. ++
  137. ++/**
  138. ++ * Deletes a feedback entry.
  139. ++ *
  140. ++ * @ingroup actions
  141. ++ */
  142. ++function feedback_delete_action($entry, $context) {
  143. ++ feedback_delete($entry->fid);
  144. ++}
  145. ++
  146. ++/**
  147. ++ * Return a form definition so the Feedback send email action can be configured.
  148. ++ *
  149. ++ * @param $context
  150. ++ * Default values (if we are editing an existing action instance).
  151. ++ * @return
  152. ++ * Form definition.
  153. ++ */
  154. ++function feedback_send_email_action_form($context = array()) {
  155. ++ // Set default values for form.
  156. ++ $context += array(
  157. ++ 'recipients' => '',
  158. ++ 'subject' => '',
  159. ++ 'message' => '',
  160. ++ );
  161. ++
  162. ++ $form['recipients'] = array(
  163. ++ '#type' => 'textarea',
  164. ++ '#title' => t('Recipients'),
  165. ++ '#default_value' => $context['recipients'],
  166. ++ '#description' => t("Example: 'webmaster@example.com' or 'dev@example.com,support@example.com'. To specify multiple recipients, separate each e-mail address with a comma."),
  167. ++ '#required' => TRUE,
  168. ++ );
  169. ++ $form['subject'] = array(
  170. ++ '#type' => 'textfield',
  171. ++ '#title' => t('Subject'),
  172. ++ '#default_value' => $context['subject'],
  173. ++ '#maxlength' => '254',
  174. ++ '#description' => t('The subject of the message.'),
  175. ++ '#required' => TRUE,
  176. ++ );
  177. ++ $form['message'] = array(
  178. ++ '#type' => 'textarea',
  179. ++ '#title' => t('Message'),
  180. ++ '#default_value' => $context['message'],
  181. ++ '#cols' => '80',
  182. ++ '#rows' => '20',
  183. ++ '#description' => t('The message that should be sent. You may include the following variables: !uid, !username, !usermail, !useragent (of the user who gave the feedback), !site_name, !status, !message, !url, !date.'),
  184. ++ '#required' => TRUE,
  185. ++ );
  186. ++ return $form;
  187. ++}
  188. ++
  189. ++/**
  190. ++ * Validate the send e-mail action form submission.
  191. ++ */
  192. ++function feedback_send_email_action_validate($form, &$form_state) {
  193. ++ if (empty($form_state['values']['recipients'])) {
  194. ++ form_set_error('recipients', t('You must enter one or more recipients.'));
  195. ++ }
  196. ++ else {
  197. ++ $recipients = explode(',', $form_state['values']['recipients']);
  198. ++ foreach ($recipients as $recipient) {
  199. ++ if (!valid_email_address(trim($recipient))) {
  200. ++ form_set_error('recipients', t('%recipient is an invalid e-mail address.', array('%recipient' => $recipient)));
  201. ++ }
  202. ++ }
  203. ++ }
  204. ++}
  205. ++
  206. ++/**
  207. ++ * Process the send e-mail action form submission.
  208. ++ */
  209. ++function feedback_send_email_action_submit($form, $form_state) {
  210. ++ // Process the HTML form to store configuration. The keyed array that
  211. ++ // we return will be serialized to the database.
  212. ++ $params = array(
  213. ++ 'recipients' => $form_state['values']['recipients'],
  214. ++ 'subject' => $form_state['values']['subject'],
  215. ++ 'message' => $form_state['values']['message'],
  216. ++ );
  217. ++ return $params;
  218. ++}
  219. ++
  220. ++/**
  221. ++ * Implements the feedback send e-mail action.
  222. ++ */
  223. ++function feedback_send_email_action($entry, $context) {
  224. ++ $account = user_load($entry->uid);
  225. ++ $from = variable_get('site_name', 'Drupal') . ' <' . variable_get('site_mail', '') . '>';
  226. ++ $params = array('entry' => $entry, 'account' => $account, 'context' => $context);
  227. ++ // Send the e-mail to the recipients using the site default language.
  228. ++ drupal_mail('feedback', 'send_email_action', $context['recipients'], language_default(), $params, $from);
  229. ++ watchdog('feedback', 'Feedback information sent to %recipients', array('%recipients' => $context['recipients']));
  230. ++}
  231. ++
  232. ++/**
  233. ++ * Implements hook_mail().
  234. ++ */
  235. ++function feedback_mail($key, &$message, $params) {
  236. ++ $language = $message['language'];
  237. ++ $entry = $params['entry'];
  238. ++ $account = $params['account'];
  239. ++ $context = $params['context'];
  240. ++ $variables = array(
  241. ++ '!site_name' => variable_get('site_name', 'Drupal'),
  242. ++ '!uid' => $account->uid,
  243. ++ '!username' => $account->name ? $account->name : t('Anonymous'),
  244. ++ '!usermail' => $account->mail ? $account->mail : t('unknown'),
  245. ++ '!status' => $entry->status ? t('Processed') : t('Open'),
  246. ++ '!message' => $entry->message,
  247. ++ '!url' => url($entry->location, array('absolute' => TRUE, 'language' => $language)),
  248. ++ '!useragent' => $entry->useragent,
  249. ++ '!date' => format_date($entry->timestamp, 'small', '', NULL, $language->language),
  250. ++ );
  251. ++ $subject = strtr($context['subject'], $variables);
  252. ++ $body = strtr($context['message'], $variables);
  253. ++ $message['subject'] .= str_replace(array("\r", "\n"), '', $subject);
  254. ++ $message['body'][] = drupal_html_to_text($body);
  255. ++}
  256. ++
  257. ++
  258. ++/**
  259. + * Implements hook_mollom_form_list().
  260. + */
  261. + function feedback_mollom_form_list() {
  262. +diff --git a/tests/feedback.test b/tests/feedback.test
  263. +index 4d4244c..09ce922 100644
  264. +--- a/tests/feedback.test
  265. ++++ b/tests/feedback.test
  266. +@@ -20,8 +20,7 @@ class FeedbackTestCase extends DrupalWebTestCase {
  267. + }
  268. +
  269. + function setUp() {
  270. +- // @todo Remove soft-dependency on Block.
  271. +- parent::setUp(array('block', 'feedback'));
  272. ++ parent::setUp(array('feedback', 'trigger'));
  273. +
  274. + $this->admin_user = $this->drupalCreateUser(array('access feedback form', 'view feedback messages', 'administer feedback'));
  275. + $this->web_user = $this->drupalCreateUser(array('access feedback form'));
  276. +@@ -49,7 +48,7 @@ class FeedbackTestCase extends DrupalWebTestCase {
  277. + $edit = array(
  278. + 'feedback-messages[0][1]' => TRUE,
  279. + );
  280. +- $this->drupalPost(NULL, $edit, t('Submit'));
  281. ++ $this->drupalPost(NULL, $edit, t('Update'));
  282. + $this->assertFieldByName('feedback-messages[1][1]', 1, t('Processed message found.'));
  283. + }
  284. +
  285. +@@ -89,4 +88,72 @@ class FeedbackTestCase extends DrupalWebTestCase {
  286. + $this->assertNoLinkByHref('admin/reports/feedback/1/delete');
  287. + $this->assertNoRaw(check_plain($message), t('Message not found.'));
  288. + }
  289. +-}
  290. ++
  291. ++ /**
  292. ++ * Test the feedback triggers and actions.
  293. ++ */
  294. ++ function testFeedbackEmailAction() {
  295. ++ $test_user = $this->drupalCreateUser(array('administer actions', 'administer feedback', 'access feedback form'));
  296. ++ $this->drupalLogin($test_user);
  297. ++ $this->assignFeedbackEmailAction('feedback_insert', $test_user->mail);
  298. ++
  299. ++ // Insert a feedback entry.
  300. ++ $message = $this->randomString();
  301. ++ $edit = array(
  302. ++ 'message' => $message,
  303. ++ );
  304. ++ $this->drupalPost('node', $edit, t('Send feedback'));
  305. ++ $this->assertFeedbackEmailTokenReplacement($test_user->mail, $message);
  306. ++
  307. ++ $this->assignFeedbackEmailAction('feedback_update', $test_user->mail);
  308. ++
  309. ++ // Update a feedback entry.
  310. ++ $fid = db_query("SELECT fid FROM {feedback} LIMIT 0,1")->fetchField();
  311. ++ $entry = feedback_load($fid);
  312. ++ feedback_save($entry);
  313. ++ $this->assertFeedbackEmailTokenReplacement($test_user->mail, $entry->message);
  314. ++ }
  315. ++
  316. ++ /**
  317. ++ * Assigns a system_send_email_action to the passed-in trigger.
  318. ++ *
  319. ++ * @param $trigger
  320. ++ * For example, 'user_login'
  321. ++ */
  322. ++ function assignFeedbackEmailAction($trigger, $mail) {
  323. ++ $form_name = "trigger_{$trigger}_assign_form";
  324. ++ $form_html_id = strtr($form_name, '_', '-');
  325. ++
  326. ++ $edit = array(
  327. ++ 'actions_label' => $trigger . "_feedback_send_email_action",
  328. ++ 'recipients' => $mail,
  329. ++ 'subject' => $this->randomName(),
  330. ++ 'message' => '!message',
  331. ++ );
  332. ++
  333. ++ $hash = drupal_hash_base64('feedback_send_email_action');
  334. ++ $this->drupalPost("admin/config/system/actions/configure/$hash", $edit, t('Save'));
  335. ++ $this->assertText(t('The action has been successfully saved.'));
  336. ++
  337. ++ // Now we have to find out the action ID of what we created.
  338. ++ $aid = db_query('SELECT aid FROM {actions} WHERE callback = :callback AND label = :label', array(':callback' => 'feedback_send_email_action', ':label' => $edit['actions_label']))->fetchField();
  339. ++
  340. ++ $edit = array('aid' => drupal_hash_base64($aid));
  341. ++ $this->drupalPost('admin/structure/trigger/feedback', $edit, t('Assign'), array(), array(), $form_html_id);
  342. ++ }
  343. ++
  344. ++
  345. ++ /**
  346. ++ * Asserts correct token replacement for the given trigger and account.
  347. ++ *
  348. ++ * @param $account
  349. ++ * The user account which triggered the action.
  350. ++ * @param $email_depth
  351. ++ * Number of emails to scan, starting with most recent.
  352. ++ */
  353. ++ function assertFeedbackEmailTokenReplacement($mail, $message, $email_depth = 1) {
  354. ++ $this->verboseEmail($email_depth);
  355. ++ $this->assertMailString('body', $message, $email_depth);
  356. ++ $this->assertMail('to', $mail, t('Mail sent to correct destination'));
  357. ++ }
  358. ++}
  359. +\ No newline at end of file
  360. diff --git a/feedback.module b/feedback.module
  361. old mode 100755
  362. new mode 100644
  363. index a4acfc0..fef1eda
  364. --- a/feedback.module
  365. +++ b/feedback.module
  366. @@ -550,6 +550,235 @@ function feedback_user_delete($account) {
  367. }
  368. /**
  369. + * Implements hook_action_info().
  370. + */
  371. +function feedback_action_info() {
  372. + return array(
  373. + 'feedback_process_action' => array(
  374. + 'label' => t('Process entry'),
  375. + 'type' => 'feedback',
  376. + 'configurable' => FALSE,
  377. + 'behavior' => array('changes_property'),
  378. + 'triggers' => array('feedback_insert', 'feedback_update'),
  379. + ),
  380. + 'feedback_open_action' => array(
  381. + 'label' => t('Open entry'),
  382. + 'type' => 'feedback',
  383. + 'configurable' => FALSE,
  384. + 'behavior' => array('changes_property'),
  385. + 'triggers' => array('feedback_insert', 'feedback_update'),
  386. + ),
  387. + 'feedback_delete_action' => array(
  388. + 'label' => t('Delete entry'),
  389. + 'type' => 'feedback',
  390. + 'configurable' => FALSE,
  391. + 'triggers' => array('feedback_insert', 'feedback_update'),
  392. + ),
  393. + 'feedback_send_email_action' => array(
  394. + 'label' => t('Send e-mail of feedback'),
  395. + 'type' => 'feedback',
  396. + 'configurable' => TRUE,
  397. + 'triggers' => array('feedback_insert', 'feedback_update'),
  398. + ),
  399. + );
  400. +}
  401. +
  402. +/**
  403. +* Implements hook_trigger_info().
  404. +*/
  405. +function feedback_trigger_info() {
  406. + return array(
  407. + 'feedback' => array(
  408. + 'feedback_insert' => array(
  409. + 'label' => t('New feedback is added.'),
  410. + ),
  411. + 'feedback_update' => array(
  412. + 'label' => t('Feedback is marked processed or open.'),
  413. + ),
  414. + ),
  415. + );
  416. +}
  417. +
  418. +/**
  419. + * Implements hook_feedback_insert().
  420. + */
  421. +function feedback_feedback_insert($entry) {
  422. + $aids = trigger_get_assigned_actions('feedback_insert');
  423. + if (!$aids) {
  424. + return;
  425. + }
  426. +
  427. + $context = array(
  428. + 'group' => 'feedback',
  429. + 'hook' => 'feedback_insert',
  430. + );
  431. +
  432. + foreach ($aids as $aid => $info) {
  433. + actions_do($aid, $entry, $context);
  434. + }
  435. +}
  436. +
  437. +/**
  438. + * Implements hook_feedback_update().
  439. + */
  440. +function feedback_feedback_update($entry) {
  441. + $aids = trigger_get_assigned_actions('feedback_update');
  442. + if (!$aids) {
  443. + return;
  444. + }
  445. +
  446. + $context = array(
  447. + 'group' => 'feedback',
  448. + 'hook' => 'feedback_update',
  449. + );
  450. +
  451. + foreach ($aids as $aid => $info) {
  452. + actions_do($aid, $entry, $context);
  453. + }
  454. +}
  455. +
  456. +/**
  457. + * Sets the status of an entry to processed.
  458. + *
  459. + * @ingroup actions
  460. + */
  461. +function feedback_process_action($entry, $context) {
  462. + $entry->status = FEEDBACK_PROCESSED;
  463. + drupal_write_record('feedback', $entry, 'fid');
  464. +}
  465. +
  466. +/**
  467. + * Sets the status of an entry to open.
  468. + *
  469. + * @ingroup actions
  470. + */
  471. +function feedback_open_action($entry, $context) {
  472. + $entry->status = FEEDBACK_OPEN;
  473. + drupal_write_record('feedback', $entry, 'fid');
  474. +}
  475. +
  476. +/**
  477. + * Deletes a feedback entry.
  478. + *
  479. + * @ingroup actions
  480. + */
  481. +function feedback_delete_action($entry, $context) {
  482. + feedback_delete($entry->fid);
  483. +}
  484. +
  485. +/**
  486. + * Return a form definition so the Feedback send email action can be configured.
  487. + *
  488. + * @param $context
  489. + * Default values (if we are editing an existing action instance).
  490. + * @return
  491. + * Form definition.
  492. + */
  493. +function feedback_send_email_action_form($context = array()) {
  494. + // Set default values for form.
  495. + $context += array(
  496. + 'recipients' => '',
  497. + 'subject' => '',
  498. + 'message' => '',
  499. + );
  500. +
  501. + $form['recipients'] = array(
  502. + '#type' => 'textarea',
  503. + '#title' => t('Recipients'),
  504. + '#default_value' => $context['recipients'],
  505. + '#description' => t("Example: 'webmaster@example.com' or 'dev@example.com,support@example.com'. To specify multiple recipients, separate each e-mail address with a comma."),
  506. + '#required' => TRUE,
  507. + );
  508. + $form['subject'] = array(
  509. + '#type' => 'textfield',
  510. + '#title' => t('Subject'),
  511. + '#default_value' => $context['subject'],
  512. + '#maxlength' => '254',
  513. + '#description' => t('The subject of the message.'),
  514. + '#required' => TRUE,
  515. + );
  516. + $form['message'] = array(
  517. + '#type' => 'textarea',
  518. + '#title' => t('Message'),
  519. + '#default_value' => $context['message'],
  520. + '#cols' => '80',
  521. + '#rows' => '20',
  522. + '#description' => t('The message that should be sent. You may include the following variables: !uid, !username, !usermail, !useragent (of the user who gave the feedback), !site_name, !status, !message, !url, !date.'),
  523. + '#required' => TRUE,
  524. + );
  525. + return $form;
  526. +}
  527. +
  528. +/**
  529. + * Validate the send e-mail action form submission.
  530. + */
  531. +function feedback_send_email_action_validate($form, &$form_state) {
  532. + if (empty($form_state['values']['recipients'])) {
  533. + form_set_error('recipients', t('You must enter one or more recipients.'));
  534. + }
  535. + else {
  536. + $recipients = explode(',', $form_state['values']['recipients']);
  537. + foreach ($recipients as $recipient) {
  538. + if (!valid_email_address(trim($recipient))) {
  539. + form_set_error('recipients', t('%recipient is an invalid e-mail address.', array('%recipient' => $recipient)));
  540. + }
  541. + }
  542. + }
  543. +}
  544. +
  545. +/**
  546. + * Process the send e-mail action form submission.
  547. + */
  548. +function feedback_send_email_action_submit($form, $form_state) {
  549. + // Process the HTML form to store configuration. The keyed array that
  550. + // we return will be serialized to the database.
  551. + $params = array(
  552. + 'recipients' => $form_state['values']['recipients'],
  553. + 'subject' => $form_state['values']['subject'],
  554. + 'message' => $form_state['values']['message'],
  555. + );
  556. + return $params;
  557. +}
  558. +
  559. +/**
  560. + * Implements the feedback send e-mail action.
  561. + */
  562. +function feedback_send_email_action($entry, $context) {
  563. + $account = user_load($entry->uid);
  564. + $from = variable_get('site_name', 'Drupal') . ' <' . variable_get('site_mail', '') . '>';
  565. + $params = array('entry' => $entry, 'account' => $account, 'context' => $context);
  566. + // Send the e-mail to the recipients using the site default language.
  567. + drupal_mail('feedback', 'send_email_action', $context['recipients'], language_default(), $params, $from);
  568. + watchdog('feedback', 'Feedback information sent to %recipients', array('%recipients' => $context['recipients']));
  569. +}
  570. +
  571. +/**
  572. + * Implements hook_mail().
  573. + */
  574. +function feedback_mail($key, &$message, $params) {
  575. + $language = $message['language'];
  576. + $entry = $params['entry'];
  577. + $account = $params['account'];
  578. + $context = $params['context'];
  579. + $variables = array(
  580. + '!site_name' => variable_get('site_name', 'Drupal'),
  581. + '!uid' => $account->uid,
  582. + '!username' => $account->name ? $account->name : t('Anonymous'),
  583. + '!usermail' => $account->mail ? $account->mail : t('unknown'),
  584. + '!status' => $entry->status ? t('Processed') : t('Open'),
  585. + '!message' => $entry->message,
  586. + '!url' => url($entry->location, array('absolute' => TRUE, 'language' => $language)),
  587. + '!useragent' => $entry->useragent,
  588. + '!date' => format_date($entry->timestamp, 'small', '', NULL, $language->language),
  589. + );
  590. + $subject = strtr($context['subject'], $variables);
  591. + $body = strtr($context['message'], $variables);
  592. + $message['subject'] .= str_replace(array("\r", "\n"), '', $subject);
  593. + $message['body'][] = drupal_html_to_text($body);
  594. +}
  595. +
  596. +
  597. +/**
  598. * Implements hook_mollom_form_list().
  599. */
  600. function feedback_mollom_form_list() {
  601. diff --git a/feedback.module.orig b/feedback.module.orig
  602. new file mode 100755
  603. index 0000000..a4acfc0
  604. --- /dev/null
  605. +++ b/feedback.module.orig
  606. @@ -0,0 +1,593 @@
  607. +<?php
  608. +
  609. +/**
  610. + * @file
  611. + * Allows site visitors and users to report issues about this site.
  612. + */
  613. +
  614. +/**
  615. + * Open state (unprocessed) for feedback entries.
  616. + */
  617. +define('FEEDBACK_OPEN', 0);
  618. +
  619. +/**
  620. + * Processed state for feedback entries.
  621. + */
  622. +define('FEEDBACK_PROCESSED', 1);
  623. +
  624. +/**
  625. + * Implements hook_theme().
  626. + */
  627. +function feedback_theme() {
  628. + return array(
  629. + 'feedback_admin_view_form' => array(
  630. + 'render element' => 'form',
  631. + ),
  632. + 'feedback_entry' => array(
  633. + 'render element' => 'elements',
  634. + 'template' => 'feedback-entry',
  635. + 'file' => 'feedback.admin.inc',
  636. + ),
  637. + 'feedback_form_display' => array(
  638. + 'template' => 'feedback-form-display',
  639. + 'variables' => array('title' => NULL, 'content' => NULL),
  640. + ),
  641. + );
  642. +}
  643. +
  644. +/**
  645. + * Implements hook_entity_info().
  646. + */
  647. +function feedback_entity_info() {
  648. + $return = array(
  649. + 'feedback' => array(
  650. + 'label' => t('Feedback'),
  651. + 'controller class' => 'FeedbackController',
  652. + 'base table' => 'feedback',
  653. + 'uri callback' => 'feedback_uri',
  654. + 'fieldable' => TRUE,
  655. + 'entity keys' => array(
  656. + 'id' => 'fid',
  657. + ),
  658. + 'bundles' => array(
  659. + 'feedback' => array(
  660. + 'label' => t('Feedback'),
  661. + 'admin' => array(
  662. + 'path' => 'admin/config/user-interface/feedback',
  663. + 'access arguments' => array('administer feedback'),
  664. + ),
  665. + ),
  666. + ),
  667. + 'view modes' => array(
  668. + 'full' => array(
  669. + 'label' => t('Full feedback entry'),
  670. + 'custom settings' => FALSE,
  671. + ),
  672. + 'teaser' => array(
  673. + 'label' => t('Teaser'),
  674. + 'custom settings' => FALSE,
  675. + ),
  676. + 'widget' => array(
  677. + 'label' => t('Widget'),
  678. + 'custom settings' => FALSE,
  679. + ),
  680. + ),
  681. + // Disable Metatags (metatag) module's entity form additions.
  682. + 'metatags' => FALSE,
  683. + ),
  684. + );
  685. +
  686. + return $return;
  687. +}
  688. +
  689. +/**
  690. + * Implements hook_field_extra_fields().
  691. + */
  692. +function feedback_field_extra_fields() {
  693. + $extras['feedback']['feedback']['form']['help'] = array(
  694. + 'label' => t('Help'),
  695. + 'description' => t('Feedback submission guidelines'),
  696. + 'weight' => -10,
  697. + );
  698. + $extras['feedback']['feedback']['form']['messages'] = array(
  699. + 'label' => t('Entries'),
  700. + 'description' => t('Existing feedback entries for the current page'),
  701. + 'weight' => -5,
  702. + );
  703. + $extras['feedback']['feedback']['form']['message'] = array(
  704. + 'label' => t('Message'),
  705. + 'description' => t('Feedback message form text field'),
  706. + 'weight' => 0,
  707. + );
  708. +
  709. + $extras['feedback']['feedback']['display']['location'] = array(
  710. + 'label' => t('Location'),
  711. + 'description' => t('The URL of the page the message was submitted on'),
  712. + 'weight' => -15,
  713. + );
  714. + $extras['feedback']['feedback']['display']['date'] = array(
  715. + 'label' => t('Date'),
  716. + 'description' => t('The submission date of the message'),
  717. + 'weight' => -10,
  718. + );
  719. + $extras['feedback']['feedback']['display']['user'] = array(
  720. + 'label' => t('User'),
  721. + 'description' => t('The name of the user who submitted the message'),
  722. + 'weight' => -5,
  723. + );
  724. + $extras['feedback']['feedback']['display']['message'] = array(
  725. + 'label' => t('Message'),
  726. + 'description' => t('The main feedback message'),
  727. + 'weight' => 0,
  728. + );
  729. + return $extras;
  730. +}
  731. +
  732. +/**
  733. + * Entity uri callback.
  734. + */
  735. +function feedback_uri($entry) {
  736. + return array(
  737. + 'path' => 'admin/reports/feedback/' . $entry->fid,
  738. + );
  739. +}
  740. +
  741. +/**
  742. + * Implements hook_permission().
  743. + */
  744. +function feedback_permission() {
  745. + return array(
  746. + 'access feedback form' => array(
  747. + 'title' => t('Access feedback form'),
  748. + 'description' => t('Submit feedback messages.'),
  749. + ),
  750. + 'view feedback messages' => array(
  751. + 'title' => t('View feedback messages'),
  752. + 'description' => t('View, process, and delete submitted feedback messages.'),
  753. + ),
  754. + 'administer feedback' => array(
  755. + 'title' => t('Administer feedback settings'),
  756. + ),
  757. + );
  758. +}
  759. +
  760. +/**
  761. + * Implements hook_menu().
  762. + */
  763. +function feedback_menu() {
  764. + $items['admin/reports/feedback'] = array(
  765. + 'title' => 'Feedback messages',
  766. + 'description' => 'View feedback messages.',
  767. + 'page callback' => 'drupal_get_form',
  768. + 'page arguments' => array('feedback_admin_view_form'),
  769. + 'access arguments' => array('view feedback messages'),
  770. + 'file' => 'feedback.admin.inc',
  771. + );
  772. + $items['admin/reports/feedback/%feedback'] = array(
  773. + 'title' => 'Feedback entry',
  774. + 'page callback' => 'feedback_view',
  775. + 'page arguments' => array(3),
  776. + 'access arguments' => array('view feedback messages'),
  777. + 'file' => 'feedback.admin.inc',
  778. + );
  779. + $items['admin/reports/feedback/%feedback/view'] = array(
  780. + 'title' => 'View',
  781. + 'type' => MENU_DEFAULT_LOCAL_TASK,
  782. + 'weight' => -10,
  783. + );
  784. + $items['admin/reports/feedback/%feedback/edit'] = array(
  785. + 'title' => 'Edit',
  786. + 'page callback' => 'drupal_get_form',
  787. + 'page arguments' => array('feedback_entry_form', 3),
  788. + 'access arguments' => array('view feedback messages'),
  789. + 'type' => MENU_LOCAL_TASK,
  790. + 'file' => 'feedback.admin.inc',
  791. + );
  792. + $items['admin/reports/feedback/%feedback/delete'] = array(
  793. + 'title' => 'Delete feedback entry',
  794. + 'page callback' => 'drupal_get_form',
  795. + 'page arguments' => array('feedback_delete_confirm', 3),
  796. + 'access arguments' => array('view feedback messages'),
  797. + 'type' => MENU_CALLBACK,
  798. + 'file' => 'feedback.admin.inc',
  799. + );
  800. + $items['admin/config/user-interface/feedback'] = array(
  801. + 'title' => 'Feedback',
  802. + 'description' => 'Administer feedback settings.',
  803. + 'page callback' => 'drupal_get_form',
  804. + 'page arguments' => array('feedback_admin_settings_form'),
  805. + 'access arguments' => array('administer feedback'),
  806. + 'file' => 'feedback.admin.inc',
  807. + );
  808. + $items['admin/config/user-interface/feedback/settings'] = array(
  809. + 'title' => 'Settings',
  810. + 'type' => MENU_DEFAULT_LOCAL_TASK,
  811. + 'weight' => -10,
  812. + );
  813. +
  814. + return $items;
  815. +}
  816. +
  817. +/**
  818. + * Implements hook_page_build().
  819. + */
  820. +function feedback_page_build(&$page) {
  821. + if (user_access('access feedback form') && !feedback_match_path(variable_get('feedback_excluded_paths', 'admin/reports/feedback'))) {
  822. + $page['page_bottom']['feedback'] = array(
  823. + '#theme' => 'feedback_form_display',
  824. + '#title' => t('Feedback'),
  825. + '#content' => drupal_get_form('feedback_form'),
  826. + );
  827. + $path = drupal_get_path('module', 'feedback');
  828. + $page['page_bottom']['feedback']['#attached']['css'][] = $path . '/feedback.css';
  829. + $page['page_bottom']['feedback']['#attached']['js'][] = $path . '/feedback.js';
  830. + }
  831. +}
  832. +
  833. +/**
  834. + * Check if the current path matches any pattern in a set of patterns.
  835. + *
  836. + * @param $patterns
  837. + * String containing a set of patterns separated by \n, \r or \r\n.
  838. + *
  839. + * @return
  840. + * Boolean value: TRUE if the current path or alias matches a pattern.
  841. + */
  842. +function feedback_match_path($patterns) {
  843. + // Convert path to lowercase. This allows comparison of the same path
  844. + // with different case. Ex: /Page, /page, /PAGE.
  845. + $patterns = drupal_strtolower($patterns);
  846. +
  847. + // Convert the current path to lowercase.
  848. + $path = drupal_strtolower(drupal_get_path_alias($_GET['q']));
  849. +
  850. + // Compare the lowercase internal and lowercase path alias (if any).
  851. + $page_match = drupal_match_path($path, $patterns);
  852. + if ($path != $_GET['q']) {
  853. + $page_match = $page_match || drupal_match_path($_GET['q'], $patterns);
  854. + }
  855. +
  856. + return $page_match;
  857. +}
  858. +
  859. +/**
  860. + * Form constructor for the feedback form.
  861. + *
  862. + * @see feedback_form_submit()
  863. + * @ingroup forms
  864. + */
  865. +function feedback_form($form, &$form_state) {
  866. + $form['#attributes']['class'] = array('feedback-form');
  867. +
  868. + // Store the path on which this form is displayed.
  869. + if (!isset($form_state['inline']['location'])) {
  870. + $form_state['inline']['location'] = $_GET['q'];
  871. + }
  872. + $form['location'] = array(
  873. + '#type' => 'value',
  874. + '#value' => $form_state['inline']['location'],
  875. + );
  876. +
  877. + $form['help'] = array(
  878. + '#prefix' => '<div class="feedback-help">',
  879. + '#markup' => t('If you experience a bug or would like to see an addition on the current page, feel free to leave us a message.'),
  880. + '#suffix' => '</div>',
  881. + );
  882. + if (user_access('view feedback messages')) {
  883. + if (arg(0) != 'node') {
  884. + $feedbacks = feedback_load_multiple(array(), array('status' => FEEDBACK_OPEN, 'location_masked' => feedback_mask_path($_GET['q'])));
  885. + }
  886. + else {
  887. + $feedbacks = feedback_load_multiple(array(), array('status' => FEEDBACK_OPEN, 'location' => $_GET['q']));
  888. + }
  889. + if ($feedbacks) {
  890. + form_load_include($form_state, 'inc', 'feedback', 'feedback.admin');
  891. + $form['messages'] = array(
  892. + '#prefix' => '<div class="feedback-messages">',
  893. + '#suffix' => '</div>',
  894. + );
  895. + foreach ($feedbacks as $fid => $feedback) {
  896. + $form['messages'][$fid]['#feedback'] = $feedback;
  897. + $form['messages'][$fid]['submitted'] = array('#markup' => t('@feedback-author !feedback-date:', array('@feedback-author' => format_username($feedback), '!feedback-date' => format_date($feedback->timestamp, 'small'))));
  898. + $form['messages'][$fid]['submitted']['#prefix'] = '<div class="feedback-submitted">';
  899. + $form['messages'][$fid]['submitted']['#suffix'] = '</div>';
  900. + $form['messages'][$fid]['body'] = feedback_build_content($feedback, 'widget');
  901. + $form['messages'][$fid]['body']['#prefix'] = '<div class="feedback-body">';
  902. + $form['messages'][$fid]['body']['#suffix'] = '</div>';
  903. + }
  904. + }
  905. + }
  906. + $form['message'] = array(
  907. + '#type' => 'textarea',
  908. + '#attributes' => array('class' => array('feedback-message')),
  909. + '#cols' => 20,
  910. + '#title' => t('Message'),
  911. + '#required' => TRUE,
  912. + '#wysiwyg' => FALSE,
  913. + );
  914. +
  915. + $entry = new stdClass();
  916. + field_attach_form('feedback', $entry, $form, $form_state);
  917. +
  918. + $form['actions'] = array(
  919. + '#type' => 'actions',
  920. + // Without clearfix, the AJAX throbber wraps in an ugly way.
  921. + // @todo Patch #type actions in core?
  922. + '#attributes' => array('class' => array('clearfix')),
  923. + );
  924. + $form['actions']['submit'] = array(
  925. + '#type' => 'submit',
  926. + '#value' => t('Send feedback'),
  927. + '#id' => 'feedback-submit',
  928. + '#ajax' => array(
  929. + 'wrapper' => 'feedback-form',
  930. + 'callback' => 'feedback_form_ajax_callback',
  931. + 'progress' => array(
  932. + 'type' => 'throbber',
  933. + 'message' => '',
  934. + ),
  935. + ),
  936. + );
  937. +
  938. + return $form;
  939. +}
  940. +
  941. +/**
  942. + * Form submission handler for feedback_form().
  943. + */
  944. +function feedback_form_submit($form, &$form_state) {
  945. + $entry = new stdClass();
  946. + entity_form_submit_build_entity('feedback', $entry, $form, $form_state);
  947. + $entry->message = $form_state['values']['message'];
  948. + $entry->location = $form_state['values']['location'];
  949. + feedback_save($entry);
  950. +
  951. + drupal_set_message(t('Thanks for your feedback!'));
  952. +}
  953. +
  954. +/**
  955. + * AJAX callback for feedback_form() submissions.
  956. + */
  957. +function feedback_form_ajax_callback($form, &$form_state) {
  958. + // If there was a form validation error, re-render the entire form.
  959. + if (!$form_state['executed']) {
  960. + return $form;
  961. + }
  962. +
  963. + // Otherwise, return a fresh copy of the form, so the user may post additional
  964. + // feedback.
  965. + // Reset the static cache of drupal_html_id().
  966. + // @see drupal_process_form()
  967. + // @see drupal_html_id()
  968. + $seen_ids = &drupal_static('drupal_html_id');
  969. + $seen_ids = array();
  970. +
  971. + // Prevent the form from being processed again.
  972. + // @see drupal_build_form()
  973. + list($form, $new_form_state) = ajax_get_form();
  974. + $new_form_state['input'] = array();
  975. + drupal_process_form($form['#form_id'], $form, $new_form_state);
  976. +
  977. + // Return AJAX commands in order to output the special success message.
  978. + // @see ajax_deliver()
  979. + $build = array('#type' => 'ajax');
  980. + $html = drupal_render($form);
  981. + $build['#commands'][] = ajax_command_insert(NULL, $html);
  982. +
  983. + // A successful form submission normally means that there were no errors, so
  984. + // we only render status messages.
  985. + $messages = drupal_get_messages();
  986. + $messages += array('status' => array());
  987. + $messages = implode('<br />', $messages['status']);
  988. + $html = '<div id="feedback-status-message">' . $messages . '</div>';
  989. + $build['#commands'][] = ajax_command_append('#block-feedback-form', $html);
  990. + return $build;
  991. +}
  992. +
  993. +/**
  994. + * Loads a feedback entry from the database.
  995. + *
  996. + * @param $fid
  997. + * Integer specifying the feedback ID to load.
  998. + *
  999. + * @return
  1000. + * A loaded feedback entry object upon successful load, or FALSE if the entry
  1001. + * cannot be loaded.
  1002. + *
  1003. + * @see feedback_load_multiple()
  1004. + */
  1005. +function feedback_load($fid) {
  1006. + $entries = feedback_load_multiple(array($fid));
  1007. + return (isset($entries[$fid]) ? $entries[$fid] : FALSE);
  1008. +}
  1009. +
  1010. +/**
  1011. + * Loads feedback entries from the database.
  1012. + *
  1013. + * @param $fids
  1014. + * An array of feedback entry IDs.
  1015. + * @param $conditions
  1016. + * An associative array of conditions on the {feedback} table, where the keys
  1017. + * are the database fields and the values are the values those fields
  1018. + * must have.
  1019. + *
  1020. + * @return
  1021. + * An array of feedback entry objects indexed by fid.
  1022. + *
  1023. + * @see hook_feedback_load()
  1024. + * @see feedback_load()
  1025. + * @see entity_load()
  1026. + * @see EntityFieldQuery
  1027. + */
  1028. +function feedback_load_multiple($fids = array(), $conditions = array()) {
  1029. + return entity_load('feedback', $fids, $conditions);
  1030. +}
  1031. +
  1032. +/**
  1033. + * Saves changes to a feedback entry or adds a new feedback entry.
  1034. + *
  1035. + * @param $entry
  1036. + * The feedback entry object to modify or add. If $entry->fid is omitted, a
  1037. + * new entry will be added.
  1038. + *
  1039. + * @see hook_feedback_insert()
  1040. + * @see hook_feedback_update()
  1041. + */
  1042. +function feedback_save($entry) {
  1043. + global $user;
  1044. +
  1045. + // Load the stored entity, if any.
  1046. + if (!empty($entry->fid) && !isset($entry->original)) {
  1047. + $entry->original = entity_load_unchanged('feedback', $entry->fid);
  1048. + }
  1049. +
  1050. + field_attach_presave('feedback', $entry);
  1051. +
  1052. + // Allow modules to alter the feedback entry before saving.
  1053. + module_invoke_all('feedback_presave', $entry);
  1054. + module_invoke_all('entity_presave', $entry, 'feedback');
  1055. +
  1056. + if (empty($entry->fid)) {
  1057. + $entry->message = trim($entry->message);
  1058. +
  1059. + $defaults = array(
  1060. + 'uid' => $user->uid,
  1061. + 'location_masked' => feedback_mask_path($entry->location),
  1062. + 'url' => url($entry->location, array('absolute' => TRUE)),
  1063. + 'timestamp' => REQUEST_TIME,
  1064. + 'useragent' => $_SERVER['HTTP_USER_AGENT'],
  1065. + );
  1066. + foreach ($defaults as $key => $default) {
  1067. + if (!isset($entry->$key)) {
  1068. + $entry->$key = $default;
  1069. + }
  1070. + }
  1071. +
  1072. + $status = drupal_write_record('feedback', $entry);
  1073. + field_attach_insert('feedback', $entry);
  1074. + module_invoke_all('feedback_insert', $entry);
  1075. + module_invoke_all('entity_insert', $entry, 'feedback');
  1076. + }
  1077. + else {
  1078. + $status = drupal_write_record('feedback', $entry, 'fid');
  1079. +
  1080. + field_attach_update('feedback', $entry);
  1081. + module_invoke_all('feedback_update', $entry);
  1082. + module_invoke_all('entity_update', $entry, 'feedback');
  1083. + }
  1084. + unset($entry->original);
  1085. +
  1086. + return $status;
  1087. +}
  1088. +
  1089. +/**
  1090. + * Deletes a feedback entry.
  1091. + *
  1092. + * @param $fid
  1093. + * A feedback entry ID.
  1094. + */
  1095. +function feedback_delete($fid) {
  1096. + feedback_delete_multiple(array($fid));
  1097. +}
  1098. +
  1099. +/**
  1100. + * Deletes multiple feedback entries.
  1101. + *
  1102. + * @param $fids
  1103. + * An array of feedback entry IDs.
  1104. + */
  1105. +function feedback_delete_multiple($fids) {
  1106. + if (!empty($fids)) {
  1107. + $entries = feedback_load_multiple($fids);
  1108. + foreach ($entries as $fid => $entry) {
  1109. + field_attach_delete('feedback', $entry);
  1110. + module_invoke_all('feedback_delete', $entry);
  1111. + module_invoke_all('entity_delete', $entry, 'feedback');
  1112. + }
  1113. + db_delete('feedback')
  1114. + ->condition('fid', $fids, 'IN')
  1115. + ->execute();
  1116. + }
  1117. +}
  1118. +
  1119. +/**
  1120. + * 'Mask' a path, i.e. replace all numeric arguments in a path with '%' placeholders.
  1121. + *
  1122. + * Please note that only numeric arguments with a preceding slash will be
  1123. + * replaced.
  1124. + *
  1125. + * @param $path
  1126. + * An internal Drupal path, f.e. 'user/123/edit'.
  1127. + * @return
  1128. + * A 'masked' path, for above example 'user/%/edit'.
  1129. + *
  1130. + * @todo Use the untranslated patch of menu_get_item() instead.
  1131. + */
  1132. +function feedback_mask_path($path) {
  1133. + return preg_replace('@/\d+@', '/%', $path);
  1134. +}
  1135. +
  1136. +/**
  1137. + * Implements hook_user_cancel().
  1138. + */
  1139. +function feedback_user_cancel($edit, $account, $method) {
  1140. + switch ($method) {
  1141. + case 'user_cancel_reassign':
  1142. + db_update('feedback')
  1143. + ->fields(array('uid' => 0))
  1144. + ->condition('uid', $account->uid)
  1145. + ->execute();
  1146. + break;
  1147. + }
  1148. +}
  1149. +
  1150. +/**
  1151. + * Implements hook_user_delete().
  1152. + */
  1153. +function feedback_user_delete($account) {
  1154. + $fids = db_query('SELECT fid FROM {feedback} WHERE uid = :uid', array(':uid' => $account->uid))->fetchCol();
  1155. + feedback_delete_multiple($fids);
  1156. +}
  1157. +
  1158. +/**
  1159. + * Implements hook_mollom_form_list().
  1160. + */
  1161. +function feedback_mollom_form_list() {
  1162. + $forms['feedback_form'] = array(
  1163. + 'title' => t('Feedback form'),
  1164. + 'entity' => 'feedback',
  1165. + 'bundle' => 'feedback',
  1166. + 'entity delete multiple callback' => 'feedback_delete_multiple',
  1167. + 'delete form' => 'feedback_delete_confirm',
  1168. + 'delete form file' => array(
  1169. + 'name' => 'feedback.admin',
  1170. + ),
  1171. + 'report access' => array('view feedback messages'),
  1172. + );
  1173. + return $forms;
  1174. +}
  1175. +
  1176. +/**
  1177. + * Implements hook_mollom_form_info().
  1178. + */
  1179. +function feedback_mollom_form_info($form_id) {
  1180. + $form_info = array(
  1181. + 'mode' => MOLLOM_MODE_ANALYSIS,
  1182. + 'bypass access' => array('administer feedback'),
  1183. + 'elements' => array(
  1184. + 'message' => t('Message'),
  1185. + ),
  1186. + );
  1187. + mollom_form_info_add_fields($form_info, 'feedback', 'feedback');
  1188. + return $form_info;
  1189. +}
  1190. +
  1191. +/**
  1192. + * Implements hook_views_api();
  1193. + */
  1194. +function feedback_views_api() {
  1195. + return array(
  1196. + 'api' => 3.0,
  1197. + 'path' => drupal_get_path('module', 'feedback') . '/views',
  1198. + );
  1199. +}
  1200. diff --git a/tests/feedback.test b/tests/feedback.test
  1201. old mode 100755
  1202. new mode 100644
  1203. index 4d4244c..09ce922
  1204. --- a/tests/feedback.test
  1205. +++ b/tests/feedback.test
  1206. @@ -20,8 +20,7 @@ class FeedbackTestCase extends DrupalWebTestCase {
  1207. }
  1208. function setUp() {
  1209. - // @todo Remove soft-dependency on Block.
  1210. - parent::setUp(array('block', 'feedback'));
  1211. + parent::setUp(array('feedback', 'trigger'));
  1212. $this->admin_user = $this->drupalCreateUser(array('access feedback form', 'view feedback messages', 'administer feedback'));
  1213. $this->web_user = $this->drupalCreateUser(array('access feedback form'));
  1214. @@ -49,7 +48,7 @@ class FeedbackTestCase extends DrupalWebTestCase {
  1215. $edit = array(
  1216. 'feedback-messages[0][1]' => TRUE,
  1217. );
  1218. - $this->drupalPost(NULL, $edit, t('Submit'));
  1219. + $this->drupalPost(NULL, $edit, t('Update'));
  1220. $this->assertFieldByName('feedback-messages[1][1]', 1, t('Processed message found.'));
  1221. }
  1222. @@ -89,4 +88,72 @@ class FeedbackTestCase extends DrupalWebTestCase {
  1223. $this->assertNoLinkByHref('admin/reports/feedback/1/delete');
  1224. $this->assertNoRaw(check_plain($message), t('Message not found.'));
  1225. }
  1226. -}
  1227. +
  1228. + /**
  1229. + * Test the feedback triggers and actions.
  1230. + */
  1231. + function testFeedbackEmailAction() {
  1232. + $test_user = $this->drupalCreateUser(array('administer actions', 'administer feedback', 'access feedback form'));
  1233. + $this->drupalLogin($test_user);
  1234. + $this->assignFeedbackEmailAction('feedback_insert', $test_user->mail);
  1235. +
  1236. + // Insert a feedback entry.
  1237. + $message = $this->randomString();
  1238. + $edit = array(
  1239. + 'message' => $message,
  1240. + );
  1241. + $this->drupalPost('node', $edit, t('Send feedback'));
  1242. + $this->assertFeedbackEmailTokenReplacement($test_user->mail, $message);
  1243. +
  1244. + $this->assignFeedbackEmailAction('feedback_update', $test_user->mail);
  1245. +
  1246. + // Update a feedback entry.
  1247. + $fid = db_query("SELECT fid FROM {feedback} LIMIT 0,1")->fetchField();
  1248. + $entry = feedback_load($fid);
  1249. + feedback_save($entry);
  1250. + $this->assertFeedbackEmailTokenReplacement($test_user->mail, $entry->message);
  1251. + }
  1252. +
  1253. + /**
  1254. + * Assigns a system_send_email_action to the passed-in trigger.
  1255. + *
  1256. + * @param $trigger
  1257. + * For example, 'user_login'
  1258. + */
  1259. + function assignFeedbackEmailAction($trigger, $mail) {
  1260. + $form_name = "trigger_{$trigger}_assign_form";
  1261. + $form_html_id = strtr($form_name, '_', '-');
  1262. +
  1263. + $edit = array(
  1264. + 'actions_label' => $trigger . "_feedback_send_email_action",
  1265. + 'recipients' => $mail,
  1266. + 'subject' => $this->randomName(),
  1267. + 'message' => '!message',
  1268. + );
  1269. +
  1270. + $hash = drupal_hash_base64('feedback_send_email_action');
  1271. + $this->drupalPost("admin/config/system/actions/configure/$hash", $edit, t('Save'));
  1272. + $this->assertText(t('The action has been successfully saved.'));
  1273. +
  1274. + // Now we have to find out the action ID of what we created.
  1275. + $aid = db_query('SELECT aid FROM {actions} WHERE callback = :callback AND label = :label', array(':callback' => 'feedback_send_email_action', ':label' => $edit['actions_label']))->fetchField();
  1276. +
  1277. + $edit = array('aid' => drupal_hash_base64($aid));
  1278. + $this->drupalPost('admin/structure/trigger/feedback', $edit, t('Assign'), array(), array(), $form_html_id);
  1279. + }
  1280. +
  1281. +
  1282. + /**
  1283. + * Asserts correct token replacement for the given trigger and account.
  1284. + *
  1285. + * @param $account
  1286. + * The user account which triggered the action.
  1287. + * @param $email_depth
  1288. + * Number of emails to scan, starting with most recent.
  1289. + */
  1290. + function assertFeedbackEmailTokenReplacement($mail, $message, $email_depth = 1) {
  1291. + $this->verboseEmail($email_depth);
  1292. + $this->assertMailString('body', $message, $email_depth);
  1293. + $this->assertMail('to', $mail, t('Mail sent to correct destination'));
  1294. + }
  1295. +}
  1296. \ No newline at end of file
  1297. --
  1298. 2.3.5