simplenews.subscription.inc 29 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849
  1. <?php
  2. /**
  3. * @file
  4. * (Un)subscription and (un)subscription confirmation
  5. *
  6. * FAPI subscription form cases:
  7. * - ACCOUNT
  8. * self/admin action: authenticated user
  9. * via hook_user form: category=newsletter
  10. *
  11. * - BLOCK
  12. * self action: anonymous / authenticated user
  13. * via hook_block: block
  14. *
  15. * - PAGE
  16. * self action: anonymous / authenticated user
  17. * callback: newsletter/subscriptions
  18. *
  19. * - MULTI BLOCK
  20. * self action: anonymous / authenticated user
  21. * authenticated user
  22. * via hook_block: multi_block
  23. * using PAGE handlers
  24. *
  25. * - ADMIN
  26. * admin action: authenticated user
  27. * via hook_menu: admin
  28. *
  29. * FAPI additional form cases:
  30. * - CONFIRM ADD
  31. * - CONFIRM REMOVAL
  32. *
  33. * @ingroup simplenews
  34. */
  35. /**
  36. * FAPI ACCOUNT subscription form.
  37. *
  38. * Finally _account_ cases inject into hook_user and won't work on its own.
  39. * Note that our basis is:
  40. * drupal_get_form('user_profile_form', ...);
  41. * and NOT:
  42. * drupal_get_form('simplenews_subscriptions_account', ...);
  43. *
  44. * see also user/user.module and user/user.pages.inc
  45. *
  46. * @see simplenews_subscriptions_account_form_validate()
  47. * @see simplenews_subscriptions_account_form_submit()
  48. */
  49. function simplenews_subscriptions_account_form(&$form, &$form_state, $subscriber) {
  50. $options = array();
  51. $default_value = array();
  52. // Get newsletters for subscription form checkboxes.
  53. // Newsletters with opt-in/out method 'hidden' will not be listed.
  54. foreach (simplenews_category_get_visible() as $newsletter) {
  55. $options[$newsletter->tid] = check_plain(_simplenews_newsletter_name($newsletter));
  56. $default_value[$newsletter->tid] = FALSE;
  57. }
  58. if ($subscriber) {
  59. $default_value = array_merge($default_value, $subscriber->tids);
  60. }
  61. $form['subscriptions'] = array(
  62. '#type' => 'fieldset',
  63. '#description' => t('Select your newsletter subscriptions.'),
  64. );
  65. $form['subscriptions']['newsletters'] = array(
  66. '#type' => 'checkboxes',
  67. '#options' => $options,
  68. '#default_value' => $default_value,
  69. );
  70. $form['subscriptions']['#title'] = t('Current newsletter subscriptions');
  71. // if we don't override #validate, see user_profile_form_validate
  72. // adding an own #submit leads to the situation where drupal omits execution of user_profile_form_submit completely
  73. $form['#submit'][] = 'simplenews_subscriptions_account_form_submit';
  74. }
  75. /**
  76. * FAPI ACCOUNT subscription form_submit.
  77. */
  78. function simplenews_subscriptions_account_form_submit($form, &$form_state) {
  79. global $user;
  80. $account = $form['#user'];
  81. // We first subscribe, then unsubscribe. This prevents deletion of subscriptions
  82. // when unsubscribed from the
  83. arsort($form_state['values']['newsletters'], SORT_NUMERIC);
  84. foreach ($form_state['values']['newsletters'] as $tid => $checked) {
  85. if ($checked) {
  86. simplenews_subscribe_user($account->mail, $tid, FALSE, 'website');
  87. }
  88. else {
  89. simplenews_unsubscribe_user($account->mail, $tid, FALSE, 'website');
  90. }
  91. }
  92. if ($user->uid == $account->uid) {
  93. drupal_set_message(t('Your newsletter subscriptions have been updated.'));
  94. }
  95. else {
  96. drupal_set_message(t('The newsletter subscriptions for user %account have been updated.', array('%account' => $account->name)));
  97. }
  98. }
  99. /**
  100. * FAPI BLOCK subscription form.
  101. *
  102. * @param $tid term id of selected newsletter.
  103. *
  104. * @see simplenews_block_form_validate()
  105. * @see simplenews_block_form_submit()
  106. */
  107. function simplenews_block_form($form, &$form_state, $tid) {
  108. global $user;
  109. $form = array();
  110. $submit_text = t('Subscribe');
  111. if ($user->uid) {
  112. if (simplenews_user_is_subscribed($user->mail, $tid)) {
  113. $submit_text = t('Unsubscribe');
  114. $form['action'] = array('#type' => 'value', '#value' => 'unsubscribe');
  115. $form['#attributes'] = array('class' => array('simplenews-unsubscribe'));
  116. }
  117. else {
  118. $form['action'] = array('#type' => 'value', '#value' => 'subscribe');
  119. $form['#attributes'] = array('class' => array('simplenews-subscribe'));
  120. }
  121. $form['mail'] = array('#type' => 'value', '#value' => $user->mail);
  122. }
  123. else {
  124. $form['mail'] = array(
  125. '#type' => 'textfield',
  126. '#title' => t('E-mail'),
  127. '#size' => 20,
  128. '#maxlength' => 128,
  129. '#required' => TRUE,
  130. );
  131. $form['action'] = array('#type' => 'value', '#value' => 'subscribe');
  132. $form['#attributes'] = array('class' => array('simplenews-subscribe'));
  133. }
  134. // All block forms use the same validate and submit function.
  135. // #tid carries the tid for processing of the right newsletter issue term.
  136. $form['#tid'] = $tid;
  137. $form['#validate'][] = 'simplenews_block_form_validate';
  138. $form['#submit'][] = 'simplenews_block_form_submit';
  139. $form['submit'] = array(
  140. '#type' => 'submit',
  141. '#value' => $submit_text,
  142. );
  143. return $form;
  144. }
  145. /*
  146. * FAPI BLOCK subscription form_validate.
  147. */
  148. function simplenews_block_form_validate($form, &$form_state) {
  149. if (!valid_email_address($form_state['values']['mail'])) {
  150. form_set_error('mail', t("The e-mail address you supplied is not valid."));
  151. }
  152. }
  153. /*
  154. * FAPI BLOCK subscription form_submit.
  155. */
  156. function simplenews_block_form_submit($form, &$form_state) {
  157. $tid = $form['#tid'];
  158. $account = simplenews_load_user_by_mail($form_state['values']['mail']);
  159. $confirm = simplenews_require_double_opt_in($tid, $account);
  160. switch ($form_state['values']['action']) {
  161. case 'subscribe':
  162. simplenews_subscribe_user($form_state['values']['mail'], $tid, $confirm, 'website');
  163. if ($confirm) {
  164. drupal_set_message(t('You will receive a confirmation e-mail shortly containing further instructions on how to complete your subscription.'));
  165. }
  166. else {
  167. drupal_set_message(t('You have been subscribed.'));
  168. }
  169. break;
  170. case 'unsubscribe':
  171. simplenews_unsubscribe_user($form_state['values']['mail'], $tid, $confirm, 'website');
  172. if ($confirm) {
  173. drupal_set_message(t('You will receive a confirmation e-mail shortly containing further instructions on how to cancel your subscription.'));
  174. }
  175. else {
  176. drupal_set_message(t('You have been unsubscribed.'));
  177. }
  178. break;
  179. }
  180. }
  181. /**
  182. * FAPI PAGE subscription form.
  183. *
  184. * @see simplenews_subscriptions_page_form_validate()
  185. * @see simplenews_subscriptions_page_form_submit()
  186. */
  187. function simplenews_subscriptions_page_form($form, &$form_state, $code = NULL) {
  188. global $user;
  189. $subscriber = $mail = FALSE;
  190. if (!empty($user->mail)) {
  191. $subscriber = simplenews_subscriber_load_by_mail($user->mail);
  192. $mail = $user->mail;
  193. }
  194. // If a hash is provided, try to load the corresponding subscriber.
  195. elseif ($code) {
  196. if (!$subscriber = simplenews_subscriber_load_by_hash($code)) {
  197. drupal_not_found();
  198. return;
  199. }
  200. $mail = $subscriber->mail;
  201. }
  202. $form = array();
  203. $options = array();
  204. $default_value = array();
  205. // Get newsletters for subscription form checkboxes.
  206. // Newsletters with opt-in/out method 'hidden' will not be listed.
  207. foreach (simplenews_category_get_visible() as $newsletter) {
  208. $options[$newsletter->tid] = check_plain($newsletter->name);
  209. $default_value[$newsletter->tid] = FALSE;
  210. }
  211. if ($subscriber) {
  212. // If there is an existing subscriber object, use the existing settings.
  213. $default_value = array_merge($default_value, $subscriber->tids);
  214. }
  215. $form['subscriptions'] = array(
  216. '#type' => 'fieldset',
  217. );
  218. $form['subscriptions']['newsletters'] = array(
  219. '#type' => 'checkboxes',
  220. '#options' => $options,
  221. '#default_value' => $default_value
  222. );
  223. // If we have a mail address, which is either from a logged in user or a
  224. // subscriber identified through the hash code, display the mail address
  225. // instead of a textfield. Anonymous uses will still have to confirm any
  226. // changes.
  227. if ($mail) {
  228. $form['subscriptions']['#title'] = t('Subscriptions for %mail', array('%mail' => $mail));
  229. $form['subscriptions']['#description'] = t('Check the newsletters you want to subscribe to. Uncheck the ones you want to unsubscribe from.');
  230. $form['subscriptions']['mail'] = array('#type' => 'value', '#value' => $mail);
  231. $form['update'] = array(
  232. '#type' => 'submit',
  233. '#value' => t('Update'),
  234. '#weight' => 20,
  235. // @todo: add clean submit handler
  236. );
  237. }
  238. else {
  239. $form['subscriptions']['#title'] = t('Manage your newsletter subscriptions');
  240. $form['subscriptions']['#description'] = t('Select the newsletter(s) to which you want to subscribe or unsubscribe.');
  241. $form['subscriptions']['mail'] = array(
  242. '#type' => 'textfield',
  243. '#title' => t('E-mail'),
  244. '#size' => 20,
  245. '#maxlength' => 128,
  246. '#weight' => 10,
  247. '#required' => TRUE,
  248. );
  249. $form['subscribe'] = array(
  250. '#type' => 'submit',
  251. '#value' => t('Subscribe'),
  252. '#weight' => 20,
  253. // @todo: add clean submit handler
  254. );
  255. $form['unsubscribe'] = array(
  256. '#type' => 'submit',
  257. '#value' => t('Unsubscribe'),
  258. '#weight' => 30,
  259. // @todo: add clean submit handler
  260. );
  261. }
  262. $form['#validate'][] = 'simplenews_subscriptions_page_form_validate';
  263. $form['#submit'][] = 'simplenews_subscriptions_page_form_submit';
  264. return $form;
  265. }
  266. /**
  267. * FAPI PAGE subscription form_validate.
  268. */
  269. function simplenews_subscriptions_page_form_validate($form, &$form_state) {
  270. $valid_email = valid_email_address($form_state['values']['mail']);
  271. if (!$valid_email) {
  272. form_set_error('mail', t('The e-mail address you supplied is not valid.'));
  273. }
  274. $checked_newsletters = array_filter($form_state['values']['newsletters']);
  275. // Unless we're in update mode, at least one checkbox must be checked.
  276. if (!count($checked_newsletters) && $form_state['values']['op'] != t('Update')) {
  277. form_set_error('newsletters', t('You must select at least one newsletter.'));
  278. }
  279. }
  280. /**
  281. * FAPI PAGE subscription form_submit.
  282. */
  283. function simplenews_subscriptions_page_form_submit($form, &$form_state) {
  284. $mail = $form_state['values']['mail'];
  285. $account = simplenews_load_user_by_mail($mail);
  286. // Group confirmation mails as necessary and configured.
  287. simplenews_confirmation_combine(TRUE);
  288. switch ($form_state['values']['op']) {
  289. case t('Update'):
  290. // We first subscribe, then unsubscribe. This prevents deletion of subscriptions
  291. // when unsubscribed from the
  292. arsort($form_state['values']['newsletters'], SORT_NUMERIC);
  293. foreach ($form_state['values']['newsletters'] as $tid => $checked) {
  294. $confirm = simplenews_require_double_opt_in($tid, $account);
  295. if ($checked) {
  296. simplenews_subscribe_user($mail, $tid, $confirm, 'website');
  297. }
  298. else {
  299. simplenews_unsubscribe_user($mail, $tid, $confirm, 'website');
  300. }
  301. }
  302. if (simplenews_confirmation_send_combined()) {
  303. drupal_set_message(t('You will receive a confirmation e-mail shortly containing further instructions on how to complete your subscription.'));
  304. }
  305. else {
  306. drupal_set_message(t('The newsletter subscriptions for %mail have been updated.', array('%mail' => $form_state['values']['mail'])));
  307. }
  308. break;
  309. case t('Subscribe'):
  310. foreach ($form_state['values']['newsletters'] as $tid => $checked) {
  311. if ($checked) {
  312. $confirm = simplenews_require_double_opt_in($tid, $account);
  313. simplenews_subscribe_user($mail, $tid, $confirm, 'website');
  314. }
  315. }
  316. if (simplenews_confirmation_send_combined()) {
  317. drupal_set_message(t('You will receive a confirmation e-mail shortly containing further instructions on how to complete your subscription.'));
  318. }
  319. else {
  320. drupal_set_message(t('The newsletter subscriptions for %mail have been updated.', array('%mail' => $form_state['values']['mail'])));
  321. }
  322. break;
  323. case t('Unsubscribe'):
  324. foreach ($form_state['values']['newsletters'] as $tid => $checked) {
  325. if ($checked) {
  326. $confirm = simplenews_require_double_opt_in($tid, $account);
  327. simplenews_unsubscribe_user($mail, $tid, $confirm, 'website');
  328. }
  329. }
  330. if (simplenews_confirmation_send_combined()) {
  331. drupal_set_message(t('You will receive a confirmation e-mail shortly containing further instructions on how to cancel your subscription.'));
  332. }
  333. else {
  334. drupal_set_message(t('The newsletter subscriptions for %mail have been updated.', array('%mail' => $form_state['values']['mail'])));
  335. }
  336. break;
  337. }
  338. }
  339. /**
  340. * FAPI MULTI BLOCK subscription form.
  341. *
  342. * Menu callback: Generates the subscription form for users for the multisignup block.
  343. *
  344. * @see simplenews_subscriptions_multi_block_form_validate()
  345. * @see simplenews_subscriptions_multi_block_form_submit()
  346. */
  347. function simplenews_subscriptions_multi_block_form($form, &$form_state) {
  348. global $user;
  349. $subscriber = !empty($user->mail) ? simplenews_subscriber_load_by_mail($user->mail) : FALSE;
  350. // If someone not authorized to edit their subscription, return empty form.
  351. if (!user_access('subscribe to newsletters')) {
  352. return;
  353. }
  354. $form = array();
  355. $options = array();
  356. $default_value = array();
  357. // Get newsletters for subscription form checkboxes.
  358. // Newsletters with opt-in/out method 'hidden' will not be listed.
  359. foreach (simplenews_category_get_visible() as $newsletter) {
  360. $options[$newsletter->tid] = check_plain($newsletter->name);
  361. $default_value[$newsletter->tid] = FALSE;
  362. }
  363. if ($subscriber) {
  364. // If there is an existing subscriber object, use the existing settings.
  365. $default_value = array_merge($default_value, $subscriber->tids);
  366. }
  367. $form['newsletters'] = array(
  368. '#type' => 'checkboxes',
  369. '#options' => $options,
  370. '#default_value' => $default_value,
  371. );
  372. // If current user is logged in, just display email.
  373. // Anonymous users see an email box and will receive confirmations
  374. if (user_is_logged_in()) {
  375. // @todo why not simply Manage your subscriptions?
  376. $form['mail'] = array('#type' => 'value', '#value' => $user->mail);
  377. $form['update'] = array(
  378. '#type' => 'submit',
  379. '#value' => t('Update'),
  380. '#weight' => 20,
  381. // @todo: add clean submit handler
  382. );
  383. }
  384. else {
  385. $form['mail'] = array(
  386. '#type' => 'textfield',
  387. '#title' => t('E-mail'),
  388. '#size' => 20,
  389. '#maxlength' => 128,
  390. '#weight' => 10,
  391. '#required' => TRUE,
  392. );
  393. $form['subscribe'] = array(
  394. '#type' => 'submit',
  395. '#value' => t('Subscribe'),
  396. '#weight' => 20,
  397. // @todo: add clean submit handler
  398. );
  399. $form['unsubscribe'] = array(
  400. '#type' => 'submit',
  401. '#value' => t('Unsubscribe'),
  402. '#weight' => 30,
  403. // @todo: add clean submit handler
  404. );
  405. }
  406. $form['#validate'][] = 'simplenews_subscriptions_page_form_validate';
  407. $form['#submit'][] = 'simplenews_subscriptions_page_form_submit';
  408. return $form;
  409. }
  410. /**
  411. * Menu callback: confirm the user's (un)subscription request
  412. *
  413. * This function is called by clicking the confirm link in the confirmation
  414. * email or the unsubscribe link in the footer of the newsletter. It handles
  415. * both subscription addition and subscription removal.
  416. *
  417. * Calling URLs are:
  418. * newsletter/confirm/add
  419. * newsletter/confirm/add/$HASH
  420. * newsletter/confirm/remove
  421. * newsletter/confirm/remove/$HASH
  422. *
  423. * @see simplenews_confirm_add_form()
  424. * @see simplenews_confirm_removal_form()
  425. */
  426. /**
  427. * Menu callback: confirm the user's (un)subscription request
  428. *
  429. * This function is called by clicking the confirm link in the confirmation
  430. * email or the unsubscribe link in the footer of the newsletter. It handles
  431. * both subscription addition and subscription removal.
  432. *
  433. * @see simplenews_confirm_add_form()
  434. * @see simplenews_confirm_removal_form()
  435. *
  436. * @todo Add parameter description here.
  437. */
  438. function simplenews_confirm_subscription() {
  439. $arguments = func_get_args();
  440. $op = array_shift($arguments);
  441. $code = array_shift($arguments);
  442. // Prevent search engines from indexing this page.
  443. $noindex = array(
  444. '#tag' => 'meta',
  445. '#attributes' => array(
  446. 'name' => 'robots',
  447. 'content' => 'noindex',
  448. ),
  449. );
  450. drupal_add_html_head($noindex, 'simplenews-noindex');
  451. if ($subscriber = simplenews_subscriber_load_by_hash($code)) {
  452. // Extract the category id.
  453. list($snid, $tid) = explode('t', drupal_substr($code, 10));
  454. if ($tid > 0) {
  455. $category = simplenews_category_load($tid);
  456. }
  457. // The confirmation page called with two arguments will display a confirmation question.
  458. // When called with three of more arguments the user will be directed to the
  459. // (un)subscribe confirmation page. The additional arguments will be passed on
  460. // to the confirmation page.
  461. if (empty($arguments)) {
  462. if ($op == 'remove') {
  463. return drupal_get_form('simplenews_confirm_removal_form', $subscriber->mail, $category);
  464. }
  465. elseif ($op == 'add') {
  466. return drupal_get_form('simplenews_confirm_add_form', $subscriber->mail, $category);
  467. }
  468. elseif ($op == 'combined') {
  469. // Redirect and display message if no changes are available.
  470. if (empty($subscriber->changes)) {
  471. drupal_set_message(t('All changes to your subscriptions where already applied. No changes made.'));
  472. drupal_goto(variable_get('site_frontpage', 'node'));
  473. }
  474. else {
  475. return drupal_get_form('simplenews_confirm_multi_form', $subscriber);
  476. }
  477. }
  478. }
  479. else {
  480. if ($op == 'remove') {
  481. simplenews_unsubscribe_user($subscriber->mail, $tid, FALSE, 'website');
  482. if ($path = variable_get('simplenews_confirm_unsubscribe_page', '')) {
  483. $path = $path . '/' . implode('/', $arguments);
  484. drupal_goto($path);
  485. }
  486. drupal_set_message(t('%user was unsubscribed from the %newsletter mailing list.', array('%user' => $subscriber->mail, '%newsletter' => _simplenews_newsletter_name($category))));
  487. drupal_goto(variable_get('site_frontpage', 'node'));
  488. }
  489. elseif ($op == 'add') {
  490. simplenews_subscribe_user($subscriber->mail, $tid, FALSE, 'website');
  491. if ($path = variable_get('simplenews_confirm_subscribe_page', '')) {
  492. $path = $path . '/' . implode('/', $arguments);
  493. drupal_goto($path);
  494. }
  495. drupal_set_message(t('%user was added to the %newsletter mailing list.', array('%user' => $subscriber->mail, '%newsletter' => _simplenews_newsletter_name($category))));
  496. drupal_goto(variable_get('site_frontpage', 'node'));
  497. }
  498. elseif ($op == 'combined') {
  499. // Redirect and display message if no changes are available.
  500. if (empty($subscriber->changes)) {
  501. drupal_set_message(t('All changes to your subscriptions where already applied. No changes made.'));
  502. drupal_goto(variable_get('site_frontpage', 'node'));
  503. }
  504. else {
  505. foreach ($subscriber->changes as $tid => $action) {
  506. if ($action == 'subscribe') {
  507. simplenews_subscribe_user($subscriber->mail, $tid, FALSE, 'website');
  508. }
  509. elseif ($action == 'unsubscribe') {
  510. simplenews_unsubscribe_user($subscriber->mail, $tid, FALSE, 'website');
  511. }
  512. }
  513. // Clear changes.
  514. $subscriber->changes = array();
  515. simplenews_subscriber_save($subscriber);
  516. drupal_set_message(t('Subscription changes confirmed for %user.', array('%user' => $subscriber->mail)));
  517. drupal_goto(variable_get('site_frontpage', 'node'));
  518. }
  519. }
  520. }
  521. }
  522. // If md5 didn't match, do a not found.
  523. drupal_not_found();
  524. return;
  525. }
  526. /**
  527. * Generate the confirm subscription form.
  528. *
  529. * @see simplenews_confirm_add_form_submit()
  530. */
  531. function simplenews_confirm_add_form($form, &$form_state, $mail, $newsletter) {
  532. $form = array();
  533. $form['question'] = array(
  534. '#markup' => '<p>' . t('Are you sure you want to add %user to the %newsletter mailing list?', array('%user' => simplenews_mask_mail($mail), '%newsletter' => _simplenews_newsletter_name($newsletter))) . "<p>\n",
  535. );
  536. $form['mail'] = array(
  537. '#type' => 'value',
  538. '#value' => $mail,
  539. );
  540. $form['newsletter'] = array(
  541. '#type' => 'value',
  542. '#value' => $newsletter,
  543. );
  544. return confirm_form($form, t('Confirm subscription'), '', t('You can always unsubscribe later.'), t('Subscribe'), t('Cancel')
  545. );
  546. }
  547. function simplenews_confirm_add_form_submit($form, &$form_state) {
  548. simplenews_subscribe_user($form_state['values']['mail'], $form_state['values']['newsletter']->tid, FALSE, 'website');
  549. if (!$path = variable_get('simplenews_confirm_subscribe_page', '')) {
  550. $path = variable_get('site_frontpage', 'node');
  551. drupal_set_message(t('%user was added to the %newsletter mailing list.', array('%user' => $form_state['values']['mail'], '%newsletter' => _simplenews_newsletter_name($form_state['values']['newsletter']))));
  552. }
  553. $form_state['redirect'] = $path;
  554. }
  555. /**
  556. * Generate the confirm subscription form.
  557. *
  558. * @see simplenews_confirm_add_form_submit()
  559. */
  560. function simplenews_confirm_multi_form($form, &$form_state, $subscriber) {
  561. $form = array();
  562. $form['question'] = array(
  563. '#markup' => '<p>' . t('Are you sure you want to confirm the following subscription changes for %user?', array('%user' => simplenews_mask_mail($subscriber->mail))) . "<p>\n",
  564. );
  565. $form['changes'] = array(
  566. '#theme' => 'item_list',
  567. '#items' => simplenews_confirmation_get_changes_list($subscriber),
  568. );
  569. $form['subscriber'] = array(
  570. '#type' => 'value',
  571. '#value' => $subscriber,
  572. );
  573. return confirm_form($form, t('Confirm subscription'), '', t('You can always change your subscriptions later.'), t('Confirm'), t('Cancel')
  574. );
  575. }
  576. function simplenews_confirm_multi_form_submit($form, &$form_state) {
  577. $subscriber = $form_state['values']['subscriber'];
  578. foreach ($subscriber->changes as $tid => $action) {
  579. if ($action == 'subscribe') {
  580. simplenews_subscribe_user($subscriber->mail, $tid, FALSE, 'website');
  581. }
  582. elseif ($action == 'unsubscribe') {
  583. simplenews_unsubscribe_user($subscriber->mail, $tid, FALSE, 'website');
  584. }
  585. }
  586. // Clear changes.
  587. $subscriber->changes = array();
  588. simplenews_subscriber_save($subscriber);
  589. drupal_set_message(t('Subscription changes confirmed for %user.', array('%user' => $subscriber->mail)));
  590. $form_state['redirect'] = variable_get('site_frontpage', 'node');
  591. }
  592. /**
  593. * Mask a mail address.
  594. *
  595. * For example, name@example.org will be masked as n*****@e*****.org.
  596. *
  597. * @param $mail
  598. * A valid mail address to mask.
  599. *
  600. * @return
  601. * The masked mail address.
  602. */
  603. function simplenews_mask_mail($mail) {
  604. if (preg_match('/^(.).*@(.).*(\..+)$/', $mail)) {
  605. return preg_replace('/^(.).*@(.).*(\..+)$/', '$1*****@$2*****$3', $mail);
  606. }
  607. else {
  608. // Missing top-level domain.
  609. return preg_replace('/^(.).*@(.).*$/', '$1*****@$2*****', $mail);
  610. }
  611. }
  612. /**
  613. * Generate the confirm unsubscription form.
  614. *
  615. * @see simplenews_confirm_removal_form_submit()
  616. */
  617. function simplenews_confirm_removal_form($form, &$form_state, $mail, $newsletter) {
  618. $form = array();
  619. $form['question'] = array(
  620. '#markup' => '<p>' . t('Are you sure you want to remove %user from the %newsletter mailing list?', array('%user' => simplenews_mask_mail($mail), '%newsletter' => _simplenews_newsletter_name($newsletter))) . "<p>\n",
  621. );
  622. $form['mail'] = array(
  623. '#type' => 'value',
  624. '#value' => $mail,
  625. );
  626. $form['newsletter'] = array(
  627. '#type' => 'value',
  628. '#value' => $newsletter,
  629. );
  630. return confirm_form($form, t('Confirm remove subscription'), '', t('This action will unsubscribe you from the newsletter mailing list.'), t('Unsubscribe'), t('Cancel')
  631. );
  632. }
  633. function simplenews_confirm_removal_form_submit($form, &$form_state) {
  634. simplenews_unsubscribe_user($form_state['values']['mail'], $form_state['values']['newsletter']->tid, FALSE, 'website');
  635. if (!$path = variable_get('simplenews_confirm_unsubscribe_page', '')) {
  636. $path = variable_get('site_frontpage', 'node');
  637. drupal_set_message(t('%user was unsubscribed from the %newsletter mailing list.', array('%user' => $form_state['values']['mail'], '%newsletter' => _simplenews_newsletter_name($form_state['values']['newsletter']))));
  638. }
  639. $form_state['redirect'] = $path;
  640. }
  641. /**
  642. * FAPI ADMIN subscription form.
  643. *
  644. * Menu callback: handle the edit subscription page and a subscription
  645. * page for anonymous users.
  646. *
  647. * @see simplenews_subscriptions_admin_form_validate()
  648. * @see simplenews_subscriptions_admin_form_submit()
  649. */
  650. function simplenews_subscriptions_admin_form($form, &$form_state, $snid) {
  651. $subscriber = simplenews_subscriber_load($snid);
  652. $form = array();
  653. $options = array();
  654. $default_value = array();
  655. // Get newsletters for subscription form checkboxes.
  656. // Newsletters with opt-in/out method 'hidden' will not be listed.
  657. foreach (simplenews_category_get_visible() as $newsletter) {
  658. $options[$newsletter->tid] = check_plain($newsletter->name);
  659. $default_value[$newsletter->tid] = FALSE;
  660. }
  661. $form['subscriptions'] = array(
  662. '#title' => t('Subscriptions for %mail', array('%mail' => $subscriber->mail)),
  663. '#type' => 'fieldset',
  664. '#description' => t('Select the newsletter(s) to add/remove from subscription.'),
  665. );
  666. $form['subscriptions']['newsletters'] = array(
  667. '#type' => 'checkboxes',
  668. '#options' => $options,
  669. '#default_value' => array_merge($default_value, $subscriber->tids),
  670. );
  671. $form['activated'] = array(
  672. '#title' => t('Activation'),
  673. '#type' => 'fieldset',
  674. '#description' => t('Activate or inactivate account.'),
  675. );
  676. $form['activated']['activated'] = array(
  677. '#type' => 'checkbox',
  678. '#title' => t('Activated'),
  679. '#default_value' => $subscriber->activated,
  680. );
  681. if ((variable_get('language_count', 1) > 1)) {
  682. $languages = language_list('enabled');
  683. foreach ($languages[1] as $langcode => $item) {
  684. $name = t($item->name);
  685. $language_options[$langcode] = $name . ($item->native != $name ? ' (' . $item->native . ')' : '');
  686. }
  687. $form['language'] = array(
  688. '#type' => 'fieldset',
  689. '#title' => 'Preferred language',
  690. '#description' => t('The e-mails will be localized in language chosen. Real users have their preference in account settings.'),
  691. '#disabled' => FALSE,
  692. );
  693. if ($subscriber->uid) {
  694. // Fallback if user has not defined a language.
  695. $language_default = t('Site default language (@name)', array('@name' => $language_options[language_default()->language]));
  696. $form['language']['language'] = array(
  697. '#type' => 'item',
  698. '#title' => t('User language'),
  699. '#markup' => isset($language_options[$subscriber->language]) ? $language_options[$subscriber->language] : $language_default,
  700. );
  701. }
  702. else {
  703. $form['language']['language'] = array(
  704. '#type' => 'select',
  705. '#default_value' => $subscriber->language,
  706. '#options' => $language_options,
  707. );
  708. }
  709. }
  710. $form['subscriptions']['mail'] = array('#type' => 'value', '#value' => $subscriber->mail);
  711. $form['update'] = array(
  712. '#type' => 'submit',
  713. '#value' => t('Update'),
  714. '#weight' => 20,
  715. );
  716. $form['#validate'][] = 'simplenews_subscriptions_admin_form_validate';
  717. $form['#submit'][] = 'simplenews_subscriptions_admin_form_submit';
  718. $form['#redirect'] = 'admin/content/simplenews/users';
  719. return $form;
  720. }
  721. /**
  722. * FAPI ADMIN subscription form_validate.
  723. */
  724. function simplenews_subscriptions_admin_form_validate($form, &$form_state) {
  725. $subscriber = simplenews_subscriber_load_by_mail($form_state['values']['mail']);
  726. $valid_email = valid_email_address($form_state['values']['mail']);
  727. if (!$valid_email) {
  728. form_set_error('mail', t('The e-mail address you supplied is not valid.'));
  729. }
  730. $checked_newsletters = array_filter($form_state['values']['newsletters']);
  731. if (!count($checked_newsletters) && !$subscriber) {
  732. form_set_error('newsletters', t('You must select at least one newsletter.'));
  733. }
  734. $languages = language_list('enabled');
  735. if (!empty($form_state['values']['language'])
  736. && !isset($languages[1][$form_state['values']['language']])) {
  737. form_set_error('language', t('Please choose a language from the list.'));
  738. }
  739. }
  740. /**
  741. * FAPI ADMIN subscription form_submit.
  742. */
  743. function simplenews_subscriptions_admin_form_submit($form, &$form_state) {
  744. $subscriber = simplenews_subscriber_load_by_mail($form_state['values']['mail']);
  745. // update subscriptions
  746. arsort($form_state['values']['newsletters'], SORT_NUMERIC);
  747. foreach ($form_state['values']['newsletters'] as $tid => $checked) {
  748. if ($checked) {
  749. simplenews_subscribe_user($form_state['values']['mail'], $tid, FALSE, 'website');
  750. }
  751. else {
  752. simplenews_unsubscribe_user($form_state['values']['mail'], $tid, FALSE, 'website');
  753. }
  754. }
  755. // update subscriber
  756. $data = array();
  757. $subscriber->activated = $form_state['values']['activated'];
  758. if (!$subscriber->uid) {
  759. if (isset($form_state['values']['language'])) {
  760. $subscriber->language = $form_state['values']['language'];
  761. }
  762. }
  763. simplenews_subscriber_save($subscriber);
  764. drupal_set_message(t('The newsletter subscriptions for %mail have been updated.', array('%mail' => $form_state['values']['mail'])));
  765. }