uc_termsofservice.module 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444
  1. <?php
  2. /**
  3. * @file
  4. * Ubercart Terms of Service.
  5. */
  6. // Include the conditional actions for displaying the panes.
  7. // TODO: need to port to Drupal 7 with Rules integration
  8. // require_once('uc_termsofservice.ca.inc');
  9. /**
  10. * Implements hook_menu().
  11. */
  12. function uc_termsofservice_menu() {
  13. $items = array();
  14. $items['uc_termsofservice/node/autocomplete'] = array(
  15. 'title' => 'Autocomplete of nodes',
  16. 'page callback' => 'uc_termsofservice_node_autocomplete',
  17. 'access callback' => TRUE,
  18. 'type' => MENU_CALLBACK,
  19. );
  20. // modalframe callback items
  21. if (module_exists('modalframe')) {
  22. $items['uc_termsofservice/show/%node'] = array(
  23. 'title' => 'Show Terms of Service',
  24. 'title callback' => 'uc_termsofservice_title_callback',
  25. 'title arguments' => array(2),
  26. 'page callback' => 'drupal_get_form',
  27. 'page arguments' => array('uc_termsofservice_general_form'),
  28. 'access callback' => TRUE,
  29. 'type' => MENU_CALLBACK,
  30. // 'file' => 'uc_termsofservice.admin.inc',
  31. );
  32. }
  33. return $items;
  34. }
  35. /**
  36. * Implements hook_theme().
  37. */
  38. function uc_termsofservice_theme() {
  39. return array(
  40. 'uc_termsofservice_agreement_form' => array(
  41. 'variables' => array(
  42. 'form' => NULL
  43. ),
  44. 'template' => 'uc_termsofservice_agreement_form',
  45. ),
  46. );
  47. }
  48. /**
  49. * Ubercart hooks.
  50. */
  51. /**
  52. * Implements hook_uc_cart_pane().
  53. */
  54. function uc_termsofservice_uc_cart_pane($items) {
  55. $node = uc_termsofservice_get_node('cart');
  56. $title = t('Terms of Service');
  57. if (isset($node->title)) {
  58. $title = $node->title;
  59. }
  60. $panes[] = array(
  61. 'id' => 'uc_termsofservice_agreement_cart',
  62. 'title' => t('@title', array('@title' => $title)),
  63. 'desc' => t("Please confirm if you agree with our terms and conditions that apply on all our purchases."),
  64. 'weight' => 6,
  65. 'body' => !is_null($items) ? drupal_get_form('uc_termsofservice_agreement_cart_callback', $items) : '',
  66. );
  67. return $panes;
  68. }
  69. /**
  70. * Implements hook_uc_checkout_pane().
  71. */
  72. function uc_termsofservice_uc_checkout_pane() {
  73. $node = uc_termsofservice_get_node('checkout');
  74. $title = t('Terms of Service');
  75. if (isset($node->title)) {
  76. $title = $node->title;
  77. }
  78. $panes[] = array(
  79. 'id' => 'uc_termsofservice_agreement_checkout',
  80. 'callback' => 'uc_termsofservice_checkout_pane_callback',
  81. 'title' => t('@title', array('@title' => $title)),
  82. 'desc' => t("Please confirm if you agree with our terms and conditions that apply on all our purchases."),
  83. 'weight' => 6,
  84. 'collapsible' => TRUE,
  85. );
  86. return $panes;
  87. }
  88. /**
  89. * Callback form for cart pane.
  90. */
  91. function uc_termsofservice_agreement_cart_callback($items) {
  92. if (module_exists('modalframe') && variable_get('uc_termsofservice_cart_popup', 0)) {
  93. // If the modalframe module is enabled and the config for popups is
  94. // then the ToS is shown in a popup.
  95. modalframe_parent_js();
  96. drupal_add_js(drupal_get_path('module', 'uc_termsofservice') . '/uc_termsofservice.js');
  97. $node = uc_termsofservice_get_node('cart');
  98. $width = variable_get('uc_termsofservice_cart_popup_width', 500);
  99. $height = variable_get('uc_termsofservice_cart_popup_height', 300);
  100. $form = uc_termsofservice_get_item('cart', $node->title, 'uc_termsofservice/show/' . $node->nid, "$width,$height");
  101. }
  102. else {
  103. $form = uc_termsofservice_general_form(array(), 'cart');
  104. }
  105. return $form;
  106. }
  107. /**
  108. * General form for both checkout & cart modes.
  109. *
  110. * @see uc_termsofservice_general_form_submit()
  111. */
  112. function uc_termsofservice_general_form($form_state, $type = NULL) {
  113. $form = array();
  114. if (!$type) {
  115. $type = arg(2);
  116. }
  117. $node = uc_termsofservice_get_node($type);
  118. if ($node) {
  119. $display_mode = variable_get('uc_termsofservice_' . $type . '_display', 'teaser');
  120. $display_title = variable_get('uc_termsofservice_' . $type . '_title', TRUE);
  121. if (! $display_title) {
  122. $node->title = '';
  123. }
  124. $view = node_view($node, $display_mode);
  125. $form['tos_text'] = array(
  126. '#markup' => drupal_render($view),
  127. );
  128. $form['tos_agree'] = array(
  129. '#type' => 'checkboxes',
  130. '#options' => array('agreed' => t('I agree with the terms above')),
  131. );
  132. //$form['#theme'] = 'uc_termsofservice_agreement_form';
  133. if (module_exists('modalframe') && variable_get('uc_termsofservice_' . $type . '_popup', 0)) {
  134. // Send the Modal Frame javascript for child windows to the page.
  135. modalframe_child_js();
  136. $form['submit'] = array(
  137. '#type' => 'submit',
  138. '#value' => t('Submit'),
  139. );
  140. $form['tos_agree']['#attributes'] = array('onclick' => 'this.form.submit();');
  141. }
  142. return $form;
  143. }
  144. return;
  145. }
  146. /**
  147. * Submit handler for uc_termsofservice_general_form().
  148. *
  149. * @see uc_termsofservice_general_form()
  150. */
  151. function uc_termsofservice_general_form_submit($form, &$form_state) {
  152. modalframe_close_dialog(array('tos_selected' => $form_state['values']['tos_agree']));
  153. }
  154. /**
  155. * Callback form for checkout pane.
  156. */
  157. function uc_termsofservice_checkout_pane_callback($op) {
  158. switch ($op) {
  159. case 'view':
  160. if (module_exists('modalframe') && variable_get('uc_termsofservice_checkout_popup', 0)) {
  161. // If the modalframe module is enabled and the config for popups is
  162. // then the ToS is shown in a popup.
  163. modalframe_parent_js();
  164. drupal_add_js(drupal_get_path('module', 'uc_termsofservice') . '/uc_termsofservice.js');
  165. $node = uc_termsofservice_get_node('checkout');
  166. $width = variable_get('uc_termsofservice_checkout_popup_width', 500);
  167. $height = variable_get('uc_termsofservice_checkout_popup_height', 300);
  168. $form = uc_termsofservice_get_item('checkout', $node->title, 'uc_termsofservice/show/' . $node->nid, "$width,$height");
  169. }
  170. else {
  171. $form = uc_termsofservice_general_form(array(), 'checkout');
  172. }
  173. return array('contents' => $form);
  174. case 'settings':
  175. $form = uc_termsofservice_admin_form('checkout');
  176. return $form;
  177. break;
  178. }
  179. }
  180. /**
  181. * Function that filters the node nid from the autocomplete string.
  182. */
  183. function uc_termsofservice_get_nid_from_variable($type = NULL) {
  184. $nid = 0;
  185. $tos_node = variable_get('uc_termsofservice_' . $type . '_node', $nid);
  186. $preg_matches = array();
  187. $match = preg_match('/\[nid: (\d+)\]/', $tos_node, $preg_matches);
  188. if ($match) {
  189. $nid = $preg_matches[1];
  190. }
  191. return $nid;
  192. }
  193. /**
  194. * Retrieves the ToS node from database.
  195. */
  196. function uc_termsofservice_get_node($type = NULL, $nid = NULL) {
  197. if (!$nid) {
  198. $nid = uc_termsofservice_get_nid_from_variable($type);
  199. }
  200. if ($nid) {
  201. if (module_exists('translation')) {
  202. global $language;
  203. $translations = translation_node_get_translations($nid);
  204. if (isset($translations[$language->language])) {
  205. $nid = $translations[$language->language]->nid;
  206. }
  207. }
  208. $node = node_load($nid);
  209. return $node;
  210. }
  211. return;
  212. }
  213. /**
  214. * Helper function for ModalFrame to build links to popup page.
  215. */
  216. function uc_termsofservice_get_item($type = NULL, $title, $path, $size = NULL) {
  217. $options = array('attributes' => array('class' => 'uc_termsofservice-child' . (!empty($size) ? ' uc_termsofservice-size[' . $size . ']' : '')));
  218. $form['tos_agree_popup'] = array(
  219. '#type' => 'checkboxes',
  220. '#options' => array('agreed' => t('I agree with the !tos', array('!tos' => l($title, $path . '/' . $type, $options)))),
  221. );
  222. return $form;
  223. }
  224. /**
  225. * Settings form for checkout & cart panes.
  226. */
  227. function uc_termsofservice_admin_form($type = NULL) {
  228. if ($type) {
  229. $form = array();
  230. // Required option only for checkout by the moment.
  231. if ($type == 'checkout') {
  232. $form['uc_termsofservice_' . $type . '_required'] = array(
  233. '#type' => 'checkbox',
  234. '#title' => t('ToS agreement is required'),
  235. '#default_value' => variable_get('uc_termsofservice_' . $type . '_required', 0),
  236. '#weight' => 1,
  237. );
  238. }
  239. // Autocomplete textfield for selecting the ToS node.
  240. $form['uc_termsofservice_' . $type . '_node'] = array(
  241. '#type' => 'textfield',
  242. '#title' => t('Select the node that corresponds to the Terms of Service. Note that this node will be shown regardless of node access permissions.'),
  243. '#autocomplete_path' => 'uc_termsofservice/node/autocomplete',
  244. '#default_value' => variable_get('uc_termsofservice_' . $type . '_node', NULL),
  245. '#weight' => 0,
  246. );
  247. // Hide node title
  248. $form['uc_termsofservice_' . $type . '_title'] = array(
  249. '#type' => 'select',
  250. '#title' => t('Show the node title?'),
  251. '#description' => t('Showing the node title will render it as a link.'),
  252. '#options' => array(1 => t('Yes'), 0 => t('No')),
  253. '#default_value' => variable_get('uc_termsofservice_' . $type . '_title', 1),
  254. );
  255. // ToS node display mode
  256. $entity_info = entity_get_info();
  257. $display_types = array();
  258. foreach ($entity_info['node']['view modes'] as $key => $val) {
  259. $display_types[$key] = $val['label'];
  260. }
  261. $form['uc_termsofservice_' . $type . '_display'] = array(
  262. '#type' => 'select',
  263. '#title' => t('Node display'),
  264. '#description' => t('Display type to use to display the node (usually Teaser or Full content).'),
  265. '#options' => $display_types,
  266. '#default_value' => variable_get('uc_termsofservice_' . $type . '_display', 'teaser'),
  267. );
  268. // Container for advanced settings.
  269. $form['uc_termsofservice_advanced_settings'] = array(
  270. '#type' => 'fieldset',
  271. '#title' => t('Advanced settings'),
  272. '#weight' => 2,
  273. '#collapsible' => TRUE,
  274. '#collapsed' => FALSE,
  275. );
  276. // Checkbox to enable Rules.
  277. $form['uc_termsofservice_advanced_settings']['uc_termsofservice_' . $type . '_rules'] = array(
  278. '#type' => 'checkbox',
  279. '#title' => t('Enable Rules'),
  280. '#description' => t('You can set the conditions under which the pane will be displayed with <a href="@url">Rules</a>', array('@url' => url('admin/workflow/rules/uc_termsofservice_display_pane/edit/conditions'))),
  281. '#default_value' => variable_get('uc_termsofservice_' . $type . '_rules', 0),
  282. );
  283. // Handle ToS in a popup window.
  284. if (module_exists('modalframe')) {
  285. $form['uc_termsofservice_advanced_settings']['uc_termsofservice_' . $type . '_popup'] = array(
  286. '#type' => 'checkbox',
  287. '#title' => t('Open ToS in a popup modal window.'),
  288. '#default_value' => variable_get('uc_termsofservice_' . $type . '_popup', 0),
  289. );
  290. $form['uc_termsofservice_advanced_settings']['uc_termsofservice_' . $type . '_popup_width'] = array(
  291. '#type' => 'textfield',
  292. '#title' => t('Width of the popup window'),
  293. '#default_value' => variable_get('uc_termsofservice_' . $type . '_popup_width', NULL),
  294. '#size' => 4,
  295. );
  296. $form['uc_termsofservice_advanced_settings']['uc_termsofservice_' . $type . '_popup_height'] = array(
  297. '#type' => 'textfield',
  298. '#title' => t('Height of the popup window'),
  299. '#default_value' => variable_get('uc_termsofservice_' . $type . '_popup_height', NULL),
  300. '#size' => 4,
  301. );
  302. }
  303. return $form;
  304. }
  305. }
  306. /**
  307. * Implements hook_form_FORM_ID_alter() for uc_cart_cart_panes_form.
  308. */
  309. function uc_termsofservice_form_uc_cart_cart_panes_form_alter(&$form, &$form_state) {
  310. $form['uc_termsofservice'] = array(
  311. '#type' => 'fieldset',
  312. '#title' => t('Terms of Service settings'),
  313. '#weight' => 98,
  314. '#collapsible' => TRUE,
  315. '#collapsed' => FALSE,
  316. );
  317. $form['uc_termsofservice'] += uc_termsofservice_admin_form('cart');
  318. $form['buttons']['#weight'] = 99;
  319. }
  320. /**
  321. * Implements hook_form_FORM_ID_alter() for uc_cart_checkout_form.
  322. *
  323. * Adds validation function to check required agreement.
  324. */
  325. function uc_termsofservice_form_uc_cart_checkout_form_alter(&$form, $form_state) {
  326. $form['#validate'][] = 'uc_termsofservice_checkout_form_validate';
  327. }
  328. /**
  329. * Validate function for checkout, if required by our configuration.
  330. *
  331. * This way, we can display a better 'required' message than the default
  332. * Form API message for a required element.
  333. */
  334. function uc_termsofservice_checkout_form_validate($form, &$form_state) {
  335. // Only check for validation when the pane really exists.
  336. if (isset($form_state['values']['panes']['uc_termsofservice_agreement_checkout'])) {
  337. $required = variable_get('uc_termsofservice_checkout_required', 0);
  338. if ($required) {
  339. $popup = variable_get('uc_termsofservice_checkout_popup', 0);
  340. if (!$popup) {
  341. $agreed = $form_state['values']['panes']['uc_termsofservice_agreement_checkout']['tos_agree']['agreed'];
  342. }
  343. else {
  344. $agreed = $form_state['values']['panes']['uc_termsofservice_agreement_checkout']['tos_agree_popup']['agreed'];
  345. }
  346. if (!$agreed) {
  347. $node = uc_termsofservice_get_node('checkout');
  348. // Issue #1818992 : the ID used in form_set_error is not a typo
  349. form_set_error('panes][uc_termsofservice_agreement_checkout][tos_agree', t("In order to continue with the checkout process you must first accept the !tos", array('!tos' => $node->title)));
  350. }
  351. }
  352. }
  353. }
  354. /**
  355. * Autocomplete callback, taken from panels module.
  356. */
  357. function uc_termsofservice_node_autocomplete($string) {
  358. // If there are node_types passed, we'll use those in a MySQL IN query.
  359. if ($string != '') {
  360. $query = db_select('node', 'n')
  361. ->fields('n', array('nid', 'title'))
  362. ->addTag('node_access');
  363. $query->join('users', 'u', 'u.uid = n.uid');
  364. $query->fields('u', array('name'));
  365. // Build query conditions.
  366. $preg_matches = array();
  367. $match = preg_match('/\[nid: (\d+)\]/', $string, $preg_matches);
  368. if (!$match) {
  369. $match = preg_match('/^nid: (\d+)/', $string, $preg_matches);
  370. }
  371. if ($match) {
  372. $query->condition('n.nid', $preg_matches[1]);
  373. }
  374. else {
  375. $query->condition('n.title', '%' . db_like($string) . '%', 'LIKE');
  376. }
  377. if (!user_access('administer nodes')) {
  378. $query->condition('n.status', 1);
  379. }
  380. // Execute the query.
  381. $result = $query->execute();
  382. $matches = array();
  383. foreach ($result as $node) {
  384. $name = empty($node->name) ? variable_get('anonymous', t('Anonymous')) : check_plain($node->name);
  385. $matches[$node->title . " [nid: $node->nid]"] = '<span class="autocomplete_title">' . check_plain($node->title) . '</span> <span class="autocomplete_user">(' . t('by @user', array('@user' => $name)) . ')</span>';
  386. }
  387. // Return the results to the form in json.
  388. drupal_json_output($matches);
  389. }
  390. }
  391. /**
  392. * Menu title callback.
  393. */
  394. function uc_termsofservice_title_callback($node = NULL) {
  395. $title = t('Terms of Service');
  396. if ($node->title) {
  397. $title = $node->title;
  398. }
  399. return t('@title', array('@title' => $title));
  400. }