uc_order.rules.inc 23 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814
  1. <?php
  2. /**
  3. * @file
  4. * This file contains the Rules hooks and functions necessary to make the order
  5. * related entity, conditions, events, and actions work.
  6. */
  7. /**
  8. * Implements hook_rules_data_info().
  9. */
  10. function uc_order_rules_data_info() {
  11. $types['uc_order'] = array(
  12. 'label' => t('Ubercart order object'),
  13. 'wrap' => TRUE,
  14. 'group' => t('Ubercart'),
  15. );
  16. $types['uc_order_product'] = array(
  17. 'label' => t('Ubercart ordered product'),
  18. 'wrap' => TRUE,
  19. 'parent' => 'node',
  20. 'group' => t('Ubercart'),
  21. );
  22. $types['uc_line_item'] = array(
  23. 'label' => t('Order line item'),
  24. 'wrap' => TRUE,
  25. 'group' => t('Ubercart'),
  26. 'token type' => FALSE,
  27. );
  28. return $types;
  29. }
  30. /**
  31. * Implements hook_rules_event_info().
  32. */
  33. function uc_order_rules_event_info() {
  34. $events['uc_order_status_update'] = array(
  35. 'label' => t('Order status gets updated'),
  36. 'group' => t('Order'),
  37. 'variables' => array(
  38. 'order' => array(
  39. 'type' => 'uc_order',
  40. 'label' => t('Original order'),
  41. ),
  42. 'updated_order' => array(
  43. 'type' => 'uc_order',
  44. 'label' => t('Updated order'),
  45. ),
  46. ),
  47. );
  48. $events['uc_order_status_email_update'] = array(
  49. 'label' => t('E-mail requested for order status update'),
  50. 'group' => t('Order'),
  51. 'variables' => array(
  52. 'order' => array(
  53. 'type' => 'uc_order',
  54. 'label' => t('Order'),
  55. ),
  56. ),
  57. );
  58. $events['uc_order_delete'] = array(
  59. 'label' => t('An order is being deleted'),
  60. 'group' => t('Order'),
  61. 'variables' => array(
  62. 'order' => array(
  63. 'type' => 'uc_order',
  64. 'label' => t('Order'),
  65. ),
  66. ),
  67. );
  68. return $events;
  69. }
  70. /**
  71. * Implements hook_rules_condition_info().
  72. */
  73. function uc_order_rules_condition_info() {
  74. $conditions['uc_order_condition_order_state'] = array(
  75. 'label' => t("Check an order's state"),
  76. 'group' => t('Order'),
  77. 'parameter' => array(
  78. 'order' => array(
  79. 'type' => 'uc_order',
  80. 'label' => t('Order'),
  81. ),
  82. 'order_state' => array(
  83. 'type' => 'text',
  84. 'label' => t('Order state'),
  85. 'options list' => 'uc_order_condition_order_state_options',
  86. 'restriction' => 'input',
  87. ),
  88. ),
  89. );
  90. $conditions['uc_order_condition_delivery_country'] = array(
  91. 'label' => t("Check an order's shipping country"),
  92. 'group' => t('Order'),
  93. 'parameter' => array(
  94. 'order' => array(
  95. 'type' => 'uc_order',
  96. 'label' => t('Order'),
  97. ),
  98. 'countries' => array(
  99. 'type' => 'list<integer>',
  100. 'label' => t('Countries'),
  101. 'options list' => 'uc_country_option_list',
  102. 'restriction' => 'input',
  103. ),
  104. ),
  105. );
  106. $conditions['uc_order_condition_billing_country'] = array(
  107. 'label' => t("Check an order's billing country"),
  108. 'group' => t('Order'),
  109. 'parameter' => array(
  110. 'order' => array(
  111. 'type' => 'uc_order',
  112. 'label' => t('Order'),
  113. ),
  114. 'countries' => array(
  115. 'type' => 'list<integer>',
  116. 'label' => t('Countries'),
  117. 'options list' => 'uc_country_option_list',
  118. 'restriction' => 'input',
  119. ),
  120. ),
  121. );
  122. $conditions['uc_order_condition_has_products'] = array(
  123. 'label' => t("Check an order's products"),
  124. 'group' => t('Order: Product'),
  125. 'base' => 'uc_order_condition_has_products',
  126. 'parameter' => array(
  127. 'order' => array(
  128. 'type' => 'uc_order',
  129. 'label' => t('Order'),
  130. ),
  131. 'products' => array(
  132. 'type' => 'list<text>',
  133. 'label' => t('Products'),
  134. 'options list' => 'uc_order_condition_has_products_options',
  135. 'restriction' => 'input',
  136. ),
  137. 'required' => array(
  138. 'type' => 'boolean',
  139. 'label' => t('Require all selected products'),
  140. 'description' => t('Select to require that order must contain all selected products. Otherwise, order must contain at least one of the selected products.'),
  141. ),
  142. 'forbidden' => array(
  143. 'type' => 'boolean',
  144. 'label' => t('Forbid other products'),
  145. ),
  146. ),
  147. );
  148. $conditions['uc_order_condition_count_products'] = array(
  149. 'label' => t("Check an order's number of products"),
  150. 'group' => t('Order: Product'),
  151. 'base' => 'uc_order_condition_count_products',
  152. 'parameter' => array(
  153. 'order' => array(
  154. 'type' => 'uc_order',
  155. 'label' => t('Order'),
  156. ),
  157. 'products' => array(
  158. 'type' => 'list<integer>',
  159. 'label' => t('Products'),
  160. 'options list' => 'uc_order_condition_products_options',
  161. 'restriction' => 'input',
  162. ),
  163. 'product_count_value' => array(
  164. 'type' => 'integer',
  165. 'label' => t('Product count value'),
  166. ),
  167. 'product_count_comparison' => array(
  168. 'type' => 'text',
  169. 'label' => t('Operator'),
  170. 'options list' => 'uc_order_condition_value_operator_options',
  171. ),
  172. ),
  173. );
  174. $conditions['uc_order_condition_products_weight'] = array(
  175. 'label' => t("Check an order's total weight"),
  176. 'group' => t('Order: Product'),
  177. 'help' => t('Compare the weight of all of the products, or the weight of just one type in the order.'),
  178. 'base' => 'uc_order_condition_products_weight',
  179. 'parameter' => array(
  180. 'order' => array(
  181. 'type' => 'uc_order',
  182. 'label' => t('Order'),
  183. ),
  184. 'products' => array(
  185. 'type' => 'list<integer>',
  186. 'label' => t('Products'),
  187. 'options list' => 'uc_order_condition_products_options',
  188. 'restriction' => 'input',
  189. ),
  190. 'weight_units' => array(
  191. 'type' => 'text',
  192. 'label' => t('Unit of measurement'),
  193. 'options list' => 'uc_order_condition_weight_units_options',
  194. ),
  195. 'product_weight_value' => array(
  196. 'type' => 'decimal',
  197. 'label' => t('Product weight value'),
  198. ),
  199. 'product_weight_comparison' => array(
  200. 'type' => 'text',
  201. 'label' => t('Operator'),
  202. 'options list' => 'uc_order_condition_value_operator_options',
  203. ),
  204. ),
  205. );
  206. $conditions['uc_order_condition_is_shippable'] = array(
  207. 'label' => t('Check if an order can be shipped'),
  208. 'group' => t('Order'),
  209. 'base' => 'uc_order_condition_is_shippable',
  210. 'parameter' => array(
  211. 'order' => array(
  212. 'type' => 'uc_order',
  213. 'label' => t('Order'),
  214. ),
  215. ),
  216. );
  217. $conditions['uc_order_condition_has_product_class'] = array(
  218. 'label' => t("Check an order's product classes"),
  219. 'group' => t('Order: Product'),
  220. 'base' => 'uc_order_condition_has_product_class',
  221. 'parameter' => array(
  222. 'order' => array(
  223. 'type' => 'uc_order',
  224. 'label' => t('Order'),
  225. ),
  226. 'product_classes' => array(
  227. 'type' => 'list<text>',
  228. 'label' => t('Product Classes'),
  229. 'options list' => 'uc_order_condition_has_product_class_classes_options',
  230. 'restriction' => 'input',
  231. ),
  232. 'required' => array(
  233. 'type' => 'boolean',
  234. 'label' => t('Require all selected product classes'),
  235. 'description' => t('Select to require that order must contain all selected product classes. Otherwise, order must contain at least one of the selected product classes.'),
  236. ),
  237. 'forbidden' => array(
  238. 'type' => 'boolean',
  239. 'label' => t('Forbid other product classes'),
  240. ),
  241. ),
  242. );
  243. return $conditions;
  244. }
  245. /**
  246. * Implements hook_rules_action_info().
  247. */
  248. function uc_order_rules_action_info() {
  249. $order_arg = array(
  250. 'type' => 'uc_order',
  251. 'label' => t('Order'),
  252. );
  253. $actions['uc_order_update_status'] = array(
  254. 'label' => t('Update the order status'),
  255. 'group' => t('Order'),
  256. 'base' => 'uc_order_action_update_status',
  257. 'parameter' => array(
  258. 'order' => $order_arg,
  259. 'order_status' => array(
  260. 'type' => 'text',
  261. 'label' => t('Status'),
  262. 'options list' => 'uc_order_action_update_status_options',
  263. ),
  264. ),
  265. );
  266. $actions['uc_order_action_add_comment'] = array(
  267. 'label' => t('Add a comment to the order'),
  268. 'group' => t('Order'),
  269. 'base' => 'uc_order_action_add_comment',
  270. 'parameter' => array(
  271. 'order' => $order_arg,
  272. 'comment' => array(
  273. 'type' => 'text',
  274. 'label' => t('Comment'),
  275. ),
  276. 'comment_type' => array(
  277. 'type' => 'text',
  278. 'label' => t('Comment type'),
  279. 'restriction' => 'input',
  280. 'options list' => 'uc_order_action_order_comment_types',
  281. ),
  282. ),
  283. );
  284. $actions['uc_order_email'] = array(
  285. 'label' => t('Send an order email'),
  286. 'group' => t('Order'),
  287. 'base' => 'uc_order_action_email',
  288. 'parameter' => array(
  289. 'order' => $order_arg,
  290. 'from' => array(
  291. 'type' => 'text',
  292. 'label' => t('Sender'),
  293. 'description' => t("Enter the 'From' email address, or leave blank to use your store email address. You may use order tokens for dynamic email addresses."),
  294. 'optional' => TRUE,
  295. ),
  296. 'addresses' => array(
  297. 'type' => 'text',
  298. 'label' => t('Recipients'),
  299. 'description' => t('Enter the email addresses to receive the notifications, one on each line. You may use order tokens for dynamic email addresses.'),
  300. ),
  301. 'subject' => array(
  302. 'type' => 'text',
  303. 'label' => t('Subject'),
  304. 'translatable' => TRUE,
  305. ),
  306. 'message' => array(
  307. 'type' => 'text',
  308. 'label' => t('Message'),
  309. 'translatable' => TRUE,
  310. ),
  311. 'format' => array(
  312. 'type' => 'text',
  313. 'label' => t('Message format'),
  314. 'options list' => 'uc_order_message_formats',
  315. ),
  316. ),
  317. );
  318. $actions['uc_order_email_invoice'] = array(
  319. 'label' => t('Email an order invoice'),
  320. 'group' => t('Order'),
  321. 'base' => 'uc_order_action_email_invoice',
  322. 'parameter' => array(
  323. 'order' => $order_arg,
  324. 'from' => array(
  325. 'type' => 'text',
  326. 'label' => t('Sender'),
  327. 'description' => t("Enter the 'From' email address, or leave blank to use your store email address. You may use order tokens for dynamic email addresses."),
  328. 'optional' => TRUE,
  329. ),
  330. 'addresses' => array(
  331. 'type' => 'text',
  332. 'label' => t('Recipients'),
  333. 'description' => t('Enter the email addresses to receive the invoice, one on each line. You may use order tokens for dynamic email addresses.'),
  334. ),
  335. 'subject' => array(
  336. 'type' => 'text',
  337. 'label' => t('Subject'),
  338. 'translatable' => TRUE,
  339. ),
  340. 'template' => array(
  341. 'type' => 'text',
  342. 'label' => t('Invoice template'),
  343. 'options list' => 'uc_order_template_options',
  344. 'restriction' => 'input',
  345. ),
  346. 'view' => array(
  347. 'type' => 'text',
  348. 'label' => t('Included information'),
  349. 'options list' => 'uc_order_action_email_invoice_view_options',
  350. 'restriction' => 'input',
  351. ),
  352. ),
  353. );
  354. return $actions;
  355. }
  356. /**
  357. * Checks the current order state.
  358. */
  359. function uc_order_condition_order_state($order, $order_state) {
  360. return uc_order_status_data($order->order_status, 'state') == $order_state;
  361. }
  362. /**
  363. * Options callback.
  364. *
  365. * @see uc_order_condition_order_state()
  366. */
  367. function uc_order_condition_order_state_options() {
  368. foreach (uc_order_state_list('general') as $id => $state) {
  369. $options[$id] = $state['title'];
  370. }
  371. foreach (uc_order_state_list('specific') as $id => $state) {
  372. $options[$id] = $state['title'];
  373. }
  374. return $options;
  375. }
  376. /**
  377. * Checks that the order has one of the selected delivery countries.
  378. */
  379. function uc_order_condition_delivery_country($order, $countries) {
  380. return in_array($order->delivery_country, $countries);
  381. }
  382. /**
  383. * Checks that the order has one of the selected billing countries.
  384. */
  385. function uc_order_condition_billing_country($order, $countries) {
  386. return in_array($order->billing_country, $countries);
  387. }
  388. /**
  389. * Checks that the order has the selected combination of product classes.
  390. *
  391. * @param object $order
  392. * The order to check.
  393. * @param array $product_classes
  394. * An array of strings containing the product classes (node content
  395. * types) to check against.
  396. * @param boolean $required
  397. * TRUE to require all product classes be present in the order. FALSE
  398. * to require at least one be present.
  399. * @param boolean $forbidden
  400. * TRUE to require that only the listed product classes be present. FALSE
  401. * to allow products with other classes.
  402. *
  403. * @return boolean
  404. * Whether the order meets the specified conditions.
  405. */
  406. function uc_order_condition_has_product_class($order, $product_classes, $required, $forbidden) {
  407. $order_product_classes = array();
  408. foreach ($order->products as $product) {
  409. if (!empty($product->type)) {
  410. // If present, use the product type from {uc_order_products}.data.type.
  411. $order_product_classes[] = $product->type;
  412. }
  413. else {
  414. // Otherwise, use the node type. If the node can't be loaded, ignore
  415. // this product.
  416. $node = node_load($product->nid);
  417. if (!empty($node)) {
  418. $order_product_classes[] = $node->type;
  419. }
  420. }
  421. }
  422. $required_product_classes = array_intersect($product_classes, $order_product_classes);
  423. if ($required) {
  424. $required_check = ($required_product_classes == $product_classes);
  425. }
  426. else {
  427. $required_check = (bool) count($required_product_classes);
  428. }
  429. if ($forbidden) {
  430. $forbidden_product_classes = array_diff($order_product_classes, $product_classes);
  431. $forbidden_check = (bool) count($forbidden_product_classes);
  432. }
  433. else {
  434. $forbidden_check = FALSE;
  435. }
  436. return $required_check && !$forbidden_check;
  437. }
  438. /**
  439. * Options callback.
  440. *
  441. * @return array
  442. * Associative array of all Ubercart product classes indexed by class ID.
  443. *
  444. * @see uc_order_condition_has_product_class()
  445. */
  446. function uc_order_condition_has_product_class_classes_options() {
  447. $options = array();
  448. $result = db_query('SELECT * FROM {uc_product_classes}');
  449. foreach ($result as $class) {
  450. $options += array($class->pcid => $class->name);
  451. }
  452. return $options;
  453. }
  454. /**
  455. * Checks that the order has the selected combination of products.
  456. */
  457. function uc_order_condition_has_products($order, $products, $required, $forbidden) {
  458. $order_products = array();
  459. foreach ($order->products as $product) {
  460. $order_products[] = $product->model;
  461. }
  462. $required_products = array_intersect($products, $order_products);
  463. if ($required) {
  464. $required_check = $required_products == $products;
  465. }
  466. else {
  467. $required_check = (bool)count($required_products);
  468. }
  469. if ($forbidden) {
  470. $forbidden_products = array_diff($order_products, $products);
  471. $forbidden_check = (bool)count($forbidden_products);
  472. }
  473. else {
  474. $forbidden_check = FALSE;
  475. }
  476. return $required_check && !$forbidden_check;
  477. }
  478. /**
  479. * Options callback.
  480. *
  481. * @see uc_order_condition_has_products()
  482. */
  483. function uc_order_condition_has_products_options() {
  484. $options = array();
  485. $result = db_query('SELECT nid FROM {uc_products}');
  486. foreach ($result as $row) {
  487. $options += uc_product_get_models($row->nid, FALSE);
  488. }
  489. asort($options);
  490. return $options;
  491. }
  492. /**
  493. * Checks that the order has the selected number of products.
  494. *
  495. * @see uc_order_condition_count_products_form()
  496. */
  497. function uc_order_condition_count_products($order, $products, $count, $op) {
  498. $totals = array('all' => 0);
  499. $total = 0;
  500. foreach ($order->products as $product) {
  501. $totals['all'] += $product->qty;
  502. if (isset($totals[$product->nid])) {
  503. $totals[$product->nid] += $product->qty;
  504. }
  505. else {
  506. $totals[$product->nid] = $product->qty;
  507. }
  508. }
  509. if (in_array('all', $products)) {
  510. $total = $totals['all'];
  511. }
  512. else {
  513. foreach ($products as $product) {
  514. if (isset($totals[$product])) {
  515. $total += $totals[$product];
  516. }
  517. }
  518. }
  519. switch ($op) {
  520. case 'less':
  521. return $total < $count;
  522. case 'less_equal':
  523. return $total <= $count;
  524. case 'equal':
  525. return $total == $count;
  526. case 'greater_equal':
  527. return $total >= $count;
  528. case 'greater':
  529. return $total > $count;
  530. }
  531. }
  532. /**
  533. * Product options callback.
  534. */
  535. function uc_order_condition_products_options() {
  536. $options = array('all' => t('- All products -'));
  537. $options += db_query('SELECT nid, model FROM {uc_products} ORDER BY model')->fetchAllKeyed();
  538. return $options;
  539. }
  540. /**
  541. * Operator options callback.
  542. */
  543. function uc_order_condition_value_operator_options() {
  544. return array(
  545. 'less' => t('Total is less than specified value.'),
  546. 'less_equal' => t('Total is less than or equal to specified value.'),
  547. 'equal' => t('Total is equal to specified value.'),
  548. 'greater_equal' => t('Total is greater than or equal to specified value.'),
  549. 'greater' => t('Total is greater than specified value.'),
  550. );
  551. }
  552. /**
  553. * Checks the weight of the order's products.
  554. *
  555. * @see uc_order_condition_products_weight_form()
  556. */
  557. function uc_order_condition_products_weight($order, $products, $weight_units, $weight_value, $op) {
  558. $totals = array('all' => 0);
  559. $total = 0;
  560. foreach ($order->products as $product) {
  561. $unit_conversion = uc_weight_conversion($product->weight_units, $weight_units);
  562. $totals['all'] += $product->qty * $product->weight * $unit_conversion;
  563. $totals[$product->nid] = $product->qty * $product->weight * $unit_conversion;
  564. }
  565. if (in_array('all', $products)) {
  566. $total = $totals['all'];
  567. }
  568. else {
  569. foreach ($products as $product) {
  570. if (isset($totals[$product])) {
  571. $total += $totals[$product];
  572. }
  573. }
  574. }
  575. switch ($op) {
  576. case 'less':
  577. return $total < $weight_value;
  578. case 'less_equal':
  579. return $total <= $weight_value;
  580. case 'equal':
  581. return $total == $weight_value;
  582. case 'greater_equal':
  583. return $total >= $weight_value;
  584. case 'greater':
  585. return $total > $weight_value;
  586. }
  587. }
  588. /**
  589. * Weight units options callback.
  590. */
  591. function uc_order_condition_weight_units_options() {
  592. return array(
  593. 'lb' => t('Pounds'),
  594. 'kg' => t('Kilograms'),
  595. 'oz' => t('Ounces'),
  596. 'g' => t('Grams'),
  597. );
  598. }
  599. /**
  600. * Checks that the order is shippable.
  601. */
  602. function uc_order_condition_is_shippable($order, $settings) {
  603. return uc_order_is_shippable($order);
  604. }
  605. /**
  606. * Updates an order's status.
  607. *
  608. * @see uc_order_action_update_status_form()
  609. */
  610. function uc_order_action_update_status($order, $status) {
  611. if (uc_order_update_status($order->order_id, $status)) {
  612. $order->order_status = $status;
  613. }
  614. }
  615. /**
  616. * @see uc_order_action_update_status()
  617. */
  618. function uc_order_action_update_status_options() {
  619. $options = array();
  620. foreach (uc_order_status_list('general') as $status) {
  621. $options[$status['id']] = $status['title'];
  622. }
  623. foreach (uc_order_status_list('specific') as $status) {
  624. $options[$status['id']] = $status['title'];
  625. }
  626. return $options;
  627. }
  628. /**
  629. * Adds a comment to an order.
  630. *
  631. * @see uc_order_action_add_comment_form()
  632. */
  633. function uc_order_action_add_comment($order, $comment, $comment_type) {
  634. uc_order_comment_save($order->order_id, 0,
  635. token_replace($comment, array('uc_order' => $order)),
  636. $comment_type == 'admin' ? 'admin' : 'order',
  637. $order->order_status, $comment_type == 'notified');
  638. }
  639. /**
  640. * @see uc_order_action_add_comment()
  641. */
  642. function uc_order_action_order_comment_types() {
  643. return array(
  644. 'admin' => t('Enter this as an admin comment.'),
  645. 'order' => t('Enter this as a customer order comment.'),
  646. 'notified' => t('Enter this as a customer order comment with a notified icon.'),
  647. );
  648. }
  649. /**
  650. * Sends an email concerning an order.
  651. *
  652. * The 'Sender', 'Recipients', 'Subject', and 'Message' fields accept
  653. * order token replacements.
  654. *
  655. * @see uc_order_action_email_form()
  656. */
  657. function uc_order_action_email($order, $from, $addresses, $subject, $message, $format) {
  658. $settings = array(
  659. 'from' => $from,
  660. 'addresses' => $addresses,
  661. 'subject' => $subject,
  662. 'message' => $message,
  663. 'format' => $format,
  664. );
  665. // Token replacements for the subject and body
  666. $settings['replacements'] = array(
  667. 'uc_order' => $order,
  668. );
  669. // Apply token replacements to the 'from' e-mail address.
  670. $from = token_replace($settings['from'], $settings['replacements']);
  671. if (empty($from)) {
  672. $from = uc_store_email_from();
  673. }
  674. // Apply token replacements to 'recipient' e-mail addresses.
  675. $addresses = token_replace($settings['addresses'], $settings['replacements']);
  676. // Split up our recipient e-mail addresses.
  677. $recipients = array();
  678. foreach (explode("\n", $addresses) as $address) {
  679. $address = trim($address);
  680. // Remove blank lines
  681. if (!empty($address)) {
  682. $recipients[] = $address;
  683. }
  684. }
  685. foreach ($recipients as $email) {
  686. $sent = drupal_mail('uc_order', 'action-mail', $email, uc_store_mail_recipient_language($email), $settings, $from);
  687. if (!$sent['result']) {
  688. watchdog('uc_order', 'Attempt to e-mail @email concerning order @order_id failed.', array('@email' => $email, '@order_id' => $order->order_id), WATCHDOG_ERROR);
  689. }
  690. }
  691. }
  692. /**
  693. * Options list callback for message formats.
  694. */
  695. function uc_order_message_formats() {
  696. global $user;
  697. $options = array();
  698. $formats = filter_formats($user);
  699. foreach ($formats as $format) {
  700. $options[$format->format] = $format->name;
  701. }
  702. return $options;
  703. }
  704. /**
  705. * Emails an invoice.
  706. *
  707. * The 'Sender', 'Subject' and 'Addresses' fields take order token replacements.
  708. */
  709. function uc_order_action_email_invoice($order, $from, $addresses, $subject, $template, $view) {
  710. $settings = array(
  711. 'from' => $from,
  712. 'addresses' => $addresses,
  713. 'subject' => $subject,
  714. 'template' => $template,
  715. 'view' => $view,
  716. );
  717. // Token replacements for the from, subject and body
  718. $settings['replacements'] = array(
  719. 'uc_order' => $order,
  720. );
  721. // Apply token replacements to the 'from' e-mail address.
  722. $from = token_replace($settings['from'], $settings['replacements']);
  723. if (empty($from)) {
  724. $from = uc_store_email_from();
  725. }
  726. // Apply token replacements to 'recipient' e-mail addresses.
  727. $addresses = token_replace($settings['addresses'], $settings['replacements']);
  728. // Split up our recipient e-mail addresses.
  729. $recipients = array();
  730. foreach (explode("\n", $addresses) as $address) {
  731. $address = trim($address);
  732. // Remove blank lines
  733. if (!empty($address)) {
  734. $recipients[] = $address;
  735. }
  736. }
  737. $settings['message'] = theme('uc_order', array('order' => $order, 'op' => $settings['view'], 'template' => $settings['template']));
  738. foreach ($recipients as $email) {
  739. $sent = drupal_mail('uc_order', 'action-mail', $email, uc_store_mail_recipient_language($email), $settings, $from);
  740. if (!$sent['result']) {
  741. watchdog('uc_order', 'Attempt to e-mail invoice for order @order_id to @email failed.', array('@email' => $email, '@order_id' => $order->order_id), WATCHDOG_ERROR);
  742. }
  743. }
  744. }
  745. /**
  746. * @see uc_order_action_email_invoice()
  747. */
  748. function uc_order_action_email_invoice_view_options() {
  749. return array(
  750. 'print' => t('Show the business header and shipping method.'),
  751. 'admin-mail' => t('Show all of the above plus the help text, email text, and store footer.'),
  752. 'checkout-mail' => t('Show all of the above plus the "thank you" message.'),
  753. );
  754. }