login_destination.admin.inc 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589
  1. <?php
  2. /**
  3. * @file
  4. * Admin page callback file for the Login Destination module.
  5. */
  6. /**
  7. * Form for editing an entire login destination at once.
  8. *
  9. * Shows list of all login destination.
  10. */
  11. function login_destination_overview_form($form, &$form_state) {
  12. // Get all login destination rules from the database.
  13. $result = db_select('login_destination', 'l')
  14. ->fields('l', array(
  15. 'id',
  16. 'triggers',
  17. 'roles',
  18. 'pages_type',
  19. 'pages',
  20. 'destination',
  21. 'weight',
  22. 'enabled',
  23. ))
  24. ->orderBy('weight')
  25. ->execute()
  26. ->fetchAll();
  27. $form['#tree'] = TRUE;
  28. // Loop through the categories and add them to the table.
  29. foreach ($result as $data) {
  30. $triggers = array_map('check_plain', unserialize($data->triggers));
  31. if (empty($triggers)) {
  32. $triggers = array();
  33. }
  34. $roles = array_map('check_plain', unserialize($data->roles));
  35. if (empty($roles)) {
  36. $roles = array();
  37. }
  38. $form[$data->id]['destination']['#markup'] = theme('login_destination_destination', array('destination' => $data->destination));
  39. $form[$data->id]['triggers']['#markup'] = theme('login_destination_triggers', array('items' => $triggers));
  40. $form[$data->id]['pages']['#markup'] = theme('login_destination_pages', array(
  41. 'pages' => $data->pages,
  42. 'pages_type' => $data->pages_type,
  43. ));
  44. $form[$data->id]['roles']['#markup'] = theme('login_destination_roles', array('items' => $roles));
  45. $form[$data->id]['weight'] = array(
  46. '#type' => 'weight',
  47. '#title' => t('Weight'),
  48. '#delta' => 50,
  49. '#default_value' => $data->weight,
  50. '#title_display' => 'invisible',
  51. );
  52. $form[$data->id]['enabled'] = array(
  53. '#type' => 'checkbox',
  54. '#title' => t('Enabled'),
  55. '#default_value' => $data->enabled,
  56. '#title_display' => 'invisible',
  57. );
  58. // Build a list of operations.
  59. $operations = array();
  60. $operations['edit'] = array(
  61. '#type' => 'link',
  62. '#title' => t('edit'),
  63. '#href' => 'admin/config/people/login-destination/edit/' . $data->id,
  64. );
  65. $operations['delete'] = array(
  66. '#type' => 'link',
  67. '#title' => t('delete'),
  68. '#href' => 'admin/config/people/login-destination/delete/' . $data->id,
  69. );
  70. $form[$data->id]['operations'] = $operations;
  71. }
  72. if (element_children($form)) {
  73. $form['actions'] = array('#type' => 'actions');
  74. $form['actions']['submit'] = array(
  75. '#type' => 'submit',
  76. '#value' => t('Save configuration'),
  77. );
  78. }
  79. else {
  80. $form['#empty_text'] = t('There is no Login Destination Rule.');
  81. }
  82. return $form;
  83. }
  84. /**
  85. * Returns HTML for a login destination list.
  86. *
  87. * @param array $variables
  88. * An associative array containing:
  89. * - form: A render element representing the form.
  90. *
  91. * @ingroup themeable
  92. *
  93. * @return string
  94. */
  95. function theme_login_destination_overview_form($variables) {
  96. $form = $variables['form'];
  97. drupal_add_tabledrag('login-destination-overview', 'order', 'sibling', 'login-destination-weight');
  98. $header = array(
  99. t('Destination'),
  100. t('Triggers'),
  101. t('Pages'),
  102. t('Roles'),
  103. array('data' => t('Enabled'), 'class' => array('checkbox')),
  104. t('Weight'),
  105. array('data' => t('Operations'), 'colspan' => '2'),
  106. );
  107. $rows = array();
  108. foreach (element_children($form) as $ldid) {
  109. if (!isset($form[$ldid]['enabled'])) {
  110. continue;
  111. }
  112. $element = &$form[$ldid];
  113. $operations = array();
  114. foreach (element_children($element['operations']) as $op) {
  115. $operations[] = array(
  116. 'data' => drupal_render($element['operations'][$op]),
  117. 'class' => array('login-destination-operations'),
  118. );
  119. }
  120. while (count($operations) < 2) {
  121. $operations[] = '';
  122. }
  123. $row = array();
  124. $row[] = drupal_render($element['destination']);
  125. $row[] = drupal_render($element['triggers']);
  126. $row[] = drupal_render($element['pages']);
  127. $row[] = drupal_render($element['roles']);
  128. $row[] = array(
  129. 'data' => drupal_render($element['enabled']),
  130. 'class' => array(
  131. 'checkbox',
  132. 'login-destination-enabled',
  133. ),
  134. );
  135. $form[$ldid]['weight']['#attributes']['class'] = array('login-destination-weight');
  136. $row[] = drupal_render($element['weight']);
  137. $row = array_merge($row, $operations);
  138. $row = array_merge(array('data' => $row), array());
  139. $row['class'][] = 'draggable';
  140. $rows[] = $row;
  141. }
  142. $output = '';
  143. if (empty($rows)) {
  144. $rows[] = array(
  145. array(
  146. 'data' => $form['#empty_text'],
  147. 'colspan' => '7',
  148. ),
  149. );
  150. }
  151. $table_arguments = array(
  152. 'header' => $header,
  153. 'rows' => $rows,
  154. 'attributes' => array(
  155. 'id' => 'login-destination-overview',
  156. ),
  157. );
  158. $output .= theme('table', $table_arguments);
  159. $output .= drupal_render_children($form);
  160. return $output;
  161. }
  162. /**
  163. * Submit handler for the login destination overview form.
  164. *
  165. * This function update the login destination rule attribute
  166. * like rules are enabled/disabled or its weight.
  167. *
  168. * @see login_destination_overview_form()
  169. */
  170. function login_destination_overview_form_submit($form, &$form_state) {
  171. $element = &$form_state['values'];
  172. foreach (element_children($element) as $ldid) {
  173. if (isset($form[$ldid]['enabled'])) {
  174. $login_destination_rules[$ldid] = $element[$ldid];
  175. $login_destination_rules[$ldid]['ldid'] = $ldid;
  176. }
  177. }
  178. foreach ($login_destination_rules as $ldid => $login_destination_rule) {
  179. _login_destination_update_rules($login_destination_rule);
  180. }
  181. drupal_set_message(t('Your configuration has been saved.'), 'status');
  182. }
  183. /**
  184. * Save all our changed items to the database.
  185. *
  186. * @param array $login_destination_rule
  187. * An associative array representing a login destination item:
  188. * - enabled: (required) can contain 0 or 1, if rule is enabled then
  189. * it should be 1 else 0.
  190. * - weight: (required) can contain any integer value.
  191. *
  192. * @return bool
  193. * The ldid of the saved login destination rule, or FALSE
  194. * if the login destination rule could not be saved.
  195. */
  196. function _login_destination_update_rules($login_destination_rule) {
  197. if (!(isset($login_destination_rule['enabled']) &&
  198. isset($login_destination_rule['weight']) &&
  199. isset($login_destination_rule['ldid']))
  200. ) {
  201. return FALSE;
  202. }
  203. if ($login_destination_rule['enabled'] != 0 &&
  204. $login_destination_rule['enabled'] != 1
  205. ) {
  206. return FALSE;
  207. }
  208. $login_destination_rule['weight'] = (int) $login_destination_rule['weight'];
  209. if (!is_int($login_destination_rule['weight'])) {
  210. return FALSE;
  211. }
  212. db_update('login_destination')
  213. ->fields(array(
  214. 'enabled' => $login_destination_rule['enabled'],
  215. 'weight' => $login_destination_rule['weight'],
  216. ))
  217. ->condition('id', $login_destination_rule['ldid'])
  218. ->execute();
  219. return $login_destination_rule['ldid'];
  220. }
  221. /**
  222. * Render a destination of login destination rule.
  223. */
  224. function theme_login_destination_destination($variables) {
  225. $output = nl2br(check_plain($variables['destination']));
  226. if (empty($output)) {
  227. $output = '<i>' . t('Empty') . '</i>';
  228. }
  229. return $output;
  230. }
  231. /**
  232. * Render a trigger of login destination rule.
  233. */
  234. function theme_login_destination_triggers($variables) {
  235. $items = array_map('check_plain', $variables['items']);
  236. if (empty($items)) {
  237. return '<i>' . t('All triggers') . '</i>';
  238. }
  239. $output = '';
  240. foreach ($items as &$item) {
  241. switch ($item) {
  242. case 'login':
  243. $item = t('Login');
  244. break;
  245. case 'logout':
  246. $item = t('Logout');
  247. break;
  248. }
  249. $output .= $item . "<br/>";
  250. }
  251. return $output;
  252. }
  253. /**
  254. * Render a page type of login destination rule.
  255. */
  256. function theme_login_destination_pages($variables) {
  257. $type = $variables['pages_type'];
  258. if ($type == LOGIN_DESTINATION_REDIRECT_PHP) {
  259. return nl2br(check_plain($variables['pages']));
  260. }
  261. $pages = trim($variables['pages']);
  262. if (empty($pages)) {
  263. if ($type == LOGIN_DESTINATION_REDIRECT_NOTLISTED) {
  264. return '<i>' . t('All pages') . '</i>';
  265. }
  266. else {
  267. return '<i>' . t('No pages') . '</i>';
  268. }
  269. }
  270. $pages = explode("\n", preg_replace('/\r/', '', check_plain($variables['pages'])));
  271. $output = '';
  272. foreach ($pages as &$page) {
  273. if ($type == LOGIN_DESTINATION_REDIRECT_NOTLISTED) {
  274. $output .= "~ ";
  275. }
  276. $output .= $page . "<br/>";
  277. }
  278. return $output;
  279. }
  280. /**
  281. * Render a roles of login destination rule.
  282. */
  283. function theme_login_destination_roles($variables) {
  284. $items = array_values(array_intersect_key(_login_destination_role_options(), $variables['items']));
  285. if (empty($items)) {
  286. return '<i>' . t('All roles') . '</i>';
  287. }
  288. return theme('item_list', array('items' => $items));
  289. }
  290. /**
  291. * Category edit page.
  292. */
  293. function login_destination_edit_form($form, &$form_state, array $rule = array()) {
  294. // Default values.
  295. $rule += array(
  296. 'triggers' => array(),
  297. 'roles' => array(),
  298. 'pages_type' => LOGIN_DESTINATION_REDIRECT_NOTLISTED,
  299. 'pages' => '',
  300. 'destination_type' => LOGIN_DESTINATION_STATIC,
  301. 'destination' => '<front>',
  302. 'id' => NULL,
  303. 'weight' => 0,
  304. );
  305. $access = user_access('use PHP for settings');
  306. $type = $rule['destination_type'];
  307. if ($type == LOGIN_DESTINATION_SNIPPET && !$access) {
  308. $form['destination_type'] = array(
  309. '#type' => 'value',
  310. '#value' => LOGIN_DESTINATION_SNIPPET,
  311. );
  312. $form['destination'] = array(
  313. '#type' => 'value',
  314. '#value' => $rule['destination'],
  315. );
  316. }
  317. else {
  318. $options = array(
  319. LOGIN_DESTINATION_STATIC => t('Internal page or external URL'),
  320. );
  321. $description = t("Specify page by using its path. Example path is %blog for the blog page. %front is the front page. %current is the current page. Precede with http:// for an external URL. Leave empty to redirect to a default page.", array(
  322. '%blog' => 'blog',
  323. '%front' => '<front>',
  324. '%current' => '<current>',
  325. ));
  326. if ($access && module_exists('php')) {
  327. $options += array(LOGIN_DESTINATION_SNIPPET => t('Page returned by this PHP code (experts only)'));
  328. $description .= ' ' .
  329. t('If the PHP option is chosen, enter PHP code between %php. It should return either a string value or an array of params that the %function function will understand, for example. %example. For more information, see the online API entry for <a href="@url">url function</a>. Note that executing incorrect PHP code can break your Drupal site.', array(
  330. '%php' => '<?php ?>',
  331. '%function' => 'url($path = \'\', array $options = array())',
  332. '%example' => '<?php return array(\'blog\', array(\'fragment\' => \'overlay=admin/config\', ), ); ?>',
  333. '@url' => 'http://api.drupal.org/api/drupal/includes--common.inc/function/url/7',
  334. ));
  335. }
  336. $form['destination_type'] = array(
  337. '#type' => 'radios',
  338. '#title' => t('Redirect to page'),
  339. '#default_value' => $type,
  340. '#options' => $options,
  341. );
  342. $form['destination'] = array(
  343. '#type' => 'textarea',
  344. '#default_value' => $rule['destination'],
  345. '#description' => $description,
  346. );
  347. }
  348. $triggers = array_map('check_plain', $rule['triggers']);
  349. if (empty($triggers)) {
  350. $triggers = array();
  351. }
  352. $form['triggers'] = array(
  353. '#type' => 'checkboxes',
  354. '#title' => t('Redirect upon triggers'),
  355. '#options' => array(
  356. 'login' => t('Login, registration, one-time login link'),
  357. 'logout' => t('Logout'),
  358. ),
  359. '#default_value' => $triggers,
  360. '#description' => t('Redirect only upon selected trigger(s). If you select no triggers, all of them will be used.'),
  361. );
  362. $type = $rule['pages_type'];
  363. if ($type == LOGIN_DESTINATION_REDIRECT_PHP && !$access) {
  364. $form['pages_type'] = array(
  365. '#type' => 'value',
  366. '#value' => LOGIN_DESTINATION_REDIRECT_PHP,
  367. );
  368. $form['pages'] = array(
  369. '#type' => 'value',
  370. '#value' => $rule['destination'],
  371. );
  372. }
  373. else {
  374. $options = array(
  375. LOGIN_DESTINATION_REDIRECT_NOTLISTED => t('All pages except those listed'),
  376. LOGIN_DESTINATION_REDIRECT_LISTED => t('Only the listed pages'),
  377. );
  378. $description = t("Specify pages by using their paths. Enter one path per line. The '*' character is a wildcard. Example paths are %blog for the blog page and %blog-wildcard for every personal blog. %front is the front page. %login is the login form. %register is the registration form. %reset is the one-time login (e-mail validation).", array(
  379. '%blog' => 'blog',
  380. '%blog-wildcard' => 'blog/*',
  381. '%front' => '<front>',
  382. '%login' => 'user',
  383. '%register' => 'user/register',
  384. '%reset' => 'user/*/edit',
  385. ));
  386. if ($access && module_exists('php')) {
  387. $options += array(LOGIN_DESTINATION_REDIRECT_PHP => t('Pages on which this PHP code returns <code>TRUE</code> (experts only)'));
  388. $description .= ' ' .
  389. t('If the PHP option is chosen, enter PHP code between %php. Note that executing incorrect PHP code can break your Drupal site.', array('%php' => '<?php ?>'));
  390. }
  391. $form['pages_type'] = array(
  392. '#type' => 'radios',
  393. '#title' => t('Redirect from specific pages'),
  394. '#default_value' => $type,
  395. '#options' => $options,
  396. );
  397. $form['pages'] = array(
  398. '#type' => 'textarea',
  399. '#default_value' => $rule['pages'],
  400. '#description' => $description,
  401. );
  402. }
  403. $default_role_options = array_map('check_plain', $rule['roles']);
  404. if (empty($default_role_options)) {
  405. $default_role_options = array();
  406. }
  407. $form['roles'] = array(
  408. '#type' => 'checkboxes',
  409. '#title' => t('Redirect users with roles'),
  410. '#options' => _login_destination_role_options(),
  411. '#default_value' => $default_role_options,
  412. '#description' => t('Redirect only the selected role(s). If you select no roles, all users will be redirected.'),
  413. );
  414. $form['actions'] = array('#type' => 'actions');
  415. $form['actions']['submit'] = array(
  416. '#type' => 'submit',
  417. '#value' => t('Save'),
  418. );
  419. if ($rule['id']) {
  420. $form['id'] = array(
  421. '#type' => 'hidden',
  422. '#value' => $rule['id'],
  423. );
  424. }
  425. return $form;
  426. }
  427. /**
  428. * Validate the contact category edit page form submission.
  429. */
  430. function login_destination_edit_form_validate($form, &$form_state) {
  431. $destination = $form_state['values']['destination'];
  432. $destination_type = $form_state['values']['destination_type'];
  433. // Check user has enter any path.
  434. $available_urls = array('<current>', '<front>');
  435. if (empty($destination) || $destination_type != 0 || in_array($destination, $available_urls)) {
  436. return;
  437. }
  438. $destination = preg_replace("/\?.+/", "", $destination);
  439. if (url_is_external($destination)) {
  440. return;
  441. }
  442. // Get source path if an alias entered.
  443. $source_path = drupal_lookup_path('source', $destination);
  444. if (!empty($source_path)) {
  445. $destination = $source_path;
  446. }
  447. if (!drupal_valid_path($destination)) {
  448. form_set_error('destination', t('Incorrect path, please enter a valid path.'));
  449. }
  450. }
  451. /**
  452. * Process the contact category edit page form submission.
  453. */
  454. function login_destination_edit_form_submit($form, &$form_state) {
  455. $form_state['values']['triggers'] = serialize(array_filter($form_state['values']['triggers']));
  456. $form_state['values']['roles'] = serialize(array_filter($form_state['values']['roles']));
  457. if (empty($form_state['values']['id'])) {
  458. drupal_write_record('login_destination', $form_state['values']);
  459. }
  460. else {
  461. drupal_write_record('login_destination', $form_state['values'], array('id'));
  462. }
  463. drupal_set_message(t('Login destination to %destination has been saved.', array('%destination' => $form_state['values']['destination'])));
  464. $form_state['redirect'] = 'admin/config/people/login-destination';
  465. }
  466. /**
  467. * Form builder for deleting a login destination.
  468. */
  469. function login_destination_delete_form($form, &$form_state, array $rule) {
  470. $form['login_destination'] = array(
  471. '#type' => 'value',
  472. '#value' => $rule,
  473. );
  474. return confirm_form($form, t('Are you sure you want to delete the login destination %destination ?', array('%destination' => $rule['destination'])), 'admin/config/people/login-destination', t('This action cannot be undone.'), t('Delete'), t('Cancel'));
  475. }
  476. /**
  477. * Submit handler for the confirm delete login destination form.
  478. */
  479. function login_destination_delete_form_submit($form, &$form_state) {
  480. $rule = $form['login_destination']['#value'];
  481. db_delete('login_destination')
  482. ->condition('id', $rule['id'])
  483. ->execute();
  484. drupal_set_message(t('The login destination %destination has been deleted.', array('%destination' => $rule['destination'])));
  485. $form_state['redirect'] = 'admin/config/people/login-destination';
  486. }
  487. /**
  488. * Settings page.
  489. */
  490. function login_destination_settings() {
  491. $form = array();
  492. $form['settings']['login_destination_preserve_destination'] = array(
  493. '#type' => 'checkbox',
  494. '#default_value' => variable_get('login_destination_preserve_destination', FALSE),
  495. '#title' => t('Preserve the destination parameter'),
  496. '#description' => t("The 'destination' GET parameter will have priority over the settings of this module. With this setting enabled, redirect from the user login block will not work."),
  497. );
  498. $form['settings']['login_destination_immediate_redirect'] = array(
  499. '#type' => 'checkbox',
  500. '#default_value' => variable_get('login_destination_immediate_redirect', FALSE),
  501. '#title' => t('Redirect immediately after using one-time login link'),
  502. '#description' => t("User will be redirected before given the possibility to change their password."),
  503. );
  504. return system_settings_form($form);
  505. }