uc_order.rules.inc 26 KB

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