print_ui.module 27 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807
  1. <?php
  2. /**
  3. * @file
  4. * Printer-friendly pages User Interface module.
  5. *
  6. * This module handles the display of the printer-friendly sub-module links.
  7. *
  8. * @ingroup print
  9. */
  10. define('PRINT_UI_LINK_POS_DEFAULT', '{ "link": "link", "block": "block", "help": "help" }');
  11. define('PRINT_UI_LINK_TEASER_DEFAULT', 0);
  12. define('PRINT_UI_SHOW_LINK_DEFAULT', 1);
  13. define('PRINT_UI_SYS_LINK_VISIBILITY_DEFAULT', 1);
  14. define('PRINT_UI_SYS_LINK_PAGES_DEFAULT', '');
  15. define('PRINT_UI_LINK_USE_ALIAS_DEFAULT', 0);
  16. define('PRINT_UI_BOOK_LINK_DEFAULT', 1);
  17. define('PRINT_UI_ALLOW_NORMAL_LINK', 1);
  18. define('PRINT_UI_ALLOW_BOOK_LINK', 2);
  19. define('PRINT_UI_TYPE_FIELDS_WEIGHT', 30);
  20. define('PRINT_UI_TYPE_SHOW_LINK_DEFAULT', 1);
  21. define('PRINT_UI_TYPE_COMMENT_LINK_DEFAULT', 0);
  22. /**
  23. * Implements hook_permission().
  24. */
  25. function print_ui_permission() {
  26. return array(
  27. 'node-specific print configuration' => array(
  28. 'title' => t('Node-specific configuration'),
  29. 'description' => t('Enable access to the per-node settings.'),
  30. ),
  31. );
  32. }
  33. /**
  34. * Implements hook_theme().
  35. */
  36. function print_ui_theme() {
  37. return array(
  38. 'print_ui_format_link' => array(
  39. 'variables' => array('format' => '', 'location' => ''),
  40. ),
  41. 'print_ui_settings' => array(
  42. 'render element' => 'form',
  43. 'file' => 'print_ui.admin.inc',
  44. ),
  45. );
  46. }
  47. /**
  48. * Implements hook_menu().
  49. */
  50. function print_ui_menu() {
  51. $items = array();
  52. $items['admin/config/user-interface/print/ui'] = array(
  53. 'title' => 'Links',
  54. 'description' => 'Configure the print module links.',
  55. 'page callback' => 'drupal_get_form',
  56. 'page arguments' => array('print_ui_settings'),
  57. 'access arguments' => array('administer print'),
  58. 'weight' => 9,
  59. 'type' => MENU_LOCAL_TASK,
  60. 'file' => 'print_ui.admin.inc',
  61. );
  62. return $items;
  63. }
  64. /**
  65. * Implements hook_block_info().
  66. */
  67. function print_ui_block_info() {
  68. $block['print-links']['info'] = t('Printer, email and PDF versions');
  69. $block['print-links']['cache'] = DRUPAL_CACHE_PER_PAGE;
  70. return $block;
  71. }
  72. /**
  73. * Implements hook_block_view().
  74. */
  75. function print_ui_block_view($delta = '') {
  76. $block = array();
  77. switch ($delta) {
  78. case 'print-links':
  79. $nid = preg_replace('!^node/!', '', $_GET['q']);
  80. if (ctype_digit($nid)) {
  81. $node = node_load($nid);
  82. if (!node_access('view', $node)) {
  83. // If the user doesn't have access to the node, don't show any links.
  84. $block['content'] = '';
  85. return array();
  86. }
  87. }
  88. else {
  89. $node = NULL;
  90. }
  91. $block['content'] = '';
  92. foreach (module_implements('print_link') as $module) {
  93. $function = $module . '_print_link';
  94. if (function_exists($function)) {
  95. $link = call_user_func_array($function, array());
  96. $link_pos = variable_get('print_' . $link['format'] . '_link_pos', drupal_json_decode(PRINT_UI_LINK_POS_DEFAULT));
  97. if (!(empty($link_pos['block']))) {
  98. $links = print_ui_insert_link($link, array('node' => $node, 'location' => 'block'));
  99. if (!empty($links)) {
  100. $block['content'] .= $links;
  101. }
  102. }
  103. }
  104. }
  105. break;
  106. }
  107. return $block;
  108. }
  109. /**
  110. * Implements hook_help().
  111. */
  112. function print_ui_help($path, $arg) {
  113. $links = '';
  114. if (($path !== 'node/%') && ($path !== 'node/%/revisions/%/view')) {
  115. static $output = FALSE;
  116. if ($output === FALSE) {
  117. $output = TRUE;
  118. foreach (module_implements('print_link') as $module) {
  119. $function = $module . '_print_link';
  120. if (function_exists($function)) {
  121. $link = call_user_func_array($function, array());
  122. $link_pos = variable_get('print_' . $link['format'] . '_link_pos', drupal_json_decode(PRINT_UI_LINK_POS_DEFAULT));
  123. if (!empty($link_pos['help'])) {
  124. $links .= print_ui_insert_link($link, array('location' => 'help'));
  125. }
  126. }
  127. }
  128. if ($links) {
  129. return "<span class='print-syslink'>$links</span>";
  130. }
  131. }
  132. }
  133. return '';
  134. }
  135. /**
  136. * Implements hook_node_view_alter().
  137. */
  138. function print_ui_node_view_alter(&$build) {
  139. if (isset($build['links']['book']['#links']['book_printer'])) {
  140. $book_link = variable_get('print_html_book_link', PRINT_UI_BOOK_LINK_DEFAULT);
  141. if ($book_link) {
  142. $link = print_print_link();
  143. $link_pos = variable_get('print_html_link_pos', drupal_json_decode(PRINT_UI_LINK_POS_DEFAULT));
  144. if (!empty($link_pos['link'])) {
  145. $format = theme('print_ui_format_link', array('format' => 'html', 'location' => 'link'));
  146. $path = '';
  147. switch ($book_link) {
  148. case 1:
  149. $path = $build['links']['book']['#links']['book_printer']['href'];
  150. break;
  151. case 2:
  152. $link_use_alias = variable_get('print_html_link_use_alias', PRINT_UI_LINK_USE_ALIAS_DEFAULT);
  153. $path = ($link_use_alias && ($alias = drupal_lookup_path('alias', 'node/' . $build['#node']->nid))) ? $alias : $build['#node']->nid;
  154. break;
  155. }
  156. $build['links']['book']['#links']['book_printer'] = array(
  157. 'href' => $link['path'] . '/' . $path,
  158. 'title' => $format['text'],
  159. 'attributes' => $format['attributes'],
  160. 'html' => $format['html'],
  161. );
  162. }
  163. else {
  164. unset($build['links']['book']['#links']['book_printer']);
  165. }
  166. }
  167. }
  168. }
  169. /**
  170. * Implements hook_node_view().
  171. */
  172. function print_ui_node_view($node, $view_mode) {
  173. $corner_markup = '';
  174. foreach (module_implements('print_link') as $module) {
  175. $function = $module . '_print_link';
  176. if (function_exists($function)) {
  177. $link = call_user_func_array($function, array());
  178. $link_pos = variable_get('print_' . $link['format'] . '_link_pos', drupal_json_decode(PRINT_UI_LINK_POS_DEFAULT));
  179. $link_use_alias = variable_get('print_' . $link['format'] . '_link_use_alias', PRINT_UI_LINK_USE_ALIAS_DEFAULT);
  180. if (!preg_match('!^node/[\d]*/revisions/[\d]*/view$!', $_GET['q'])) {
  181. // Not a revision, use node->nid to build the path.
  182. $path = (($link_use_alias) && ($alias = drupal_lookup_path('alias', 'node/' . $node->nid))) ? $alias : $node->nid;
  183. }
  184. else {
  185. // This is a node revision, replace only the node component.
  186. $path = preg_replace('!^node/!', '', $_GET['q']);
  187. }
  188. $path = $link['path'] . '/' . $path;
  189. foreach (array('node', 'comment') as $type) {
  190. $allowed_type = print_ui_link_allowed($link, array(
  191. 'type' => $type,
  192. 'node' => $node,
  193. 'view_mode' => $view_mode,
  194. ));
  195. if ($allowed_type) {
  196. drupal_add_css(drupal_get_path('module', 'print_ui') . '/css/print_ui.theme.css');
  197. $links = array();
  198. $format = theme('print_ui_format_link', array('format' => $link['format'], 'location' => 'link'));
  199. // Show book link.
  200. if ($allowed_type === PRINT_UI_ALLOW_BOOK_LINK) {
  201. $path = $link['path'] . '/book/export/html/' . $node->nid;
  202. $links['book_' . $link['format']] = array(
  203. 'href' => $path,
  204. 'title' => $format['text'],
  205. 'attributes' => $format['attributes'],
  206. 'html' => $format['html'],
  207. );
  208. }
  209. elseif ($allowed_type === PRINT_UI_ALLOW_NORMAL_LINK) {
  210. $links['print_' . $link['format']] = array(
  211. 'href' => $path,
  212. 'title' => $format['text'],
  213. 'attributes' => $format['attributes'],
  214. 'html' => $format['html'],
  215. 'query' => _print_ui_query_string_encode($_GET, array('q')),
  216. );
  217. }
  218. $link_content = array(
  219. '#theme' => 'links',
  220. '#links' => $links,
  221. '#attributes' => array('class' => array('links', 'inline')),
  222. );
  223. // If it's a node, and configured to show the link, but it's not the
  224. // html version of a book then show it.
  225. if (($type == 'node') && !empty($link_pos['link']) && !(isset($node->book) && ($link['format'] == 'html'))) {
  226. $node->content['links']['print_' . $link['format']] = $link_content;
  227. }
  228. elseif (($type == 'comment') && isset($node->content['comments']['comments'])) {
  229. foreach ($node->content['comments']['comments'] as $cid => $comment) {
  230. if (is_numeric($cid)) {
  231. $link_content['#links']['print_' . $link['format']]['query']['comment'] = $cid;
  232. $node->content['comments']['comments'][$cid]['links']['print_' . $link['format']] = $link_content;
  233. }
  234. }
  235. }
  236. }
  237. }
  238. if (!empty($link_pos['corner'])) {
  239. $corner_markup .= print_ui_insert_link($link, array(
  240. 'node' => $node,
  241. 'path' => $path,
  242. 'location' => 'corner',
  243. ));
  244. }
  245. }
  246. }
  247. if (($view_mode == 'full') && (!empty($corner_markup))) {
  248. // Insert content corner links.
  249. $node->content['print_links'] = array(
  250. '#prefix' => '<span class="print-link">',
  251. '#markup' => $corner_markup,
  252. '#suffix' => '</span>',
  253. '#weight' => -101,
  254. );
  255. }
  256. }
  257. /**
  258. * Implements hook_node_load().
  259. */
  260. function print_ui_node_load($nodes, $types) {
  261. $ids = array();
  262. foreach ($nodes as $node) {
  263. $ids[] = $node->nid;
  264. }
  265. foreach (module_implements('print_link') as $module) {
  266. $function = $module . '_print_link';
  267. if (function_exists($function)) {
  268. $link = call_user_func_array($function, array());
  269. $display = 'print_' . $link['format'] . '_display';
  270. $display_comment = 'print_' . $link['format'] . '_display_comment';
  271. $display_urllist = 'print_' . $link['format'] . '_display_urllist';
  272. $result = db_query('SELECT nid, link, comments, url_list FROM {' . $module . '_node_conf} WHERE nid IN (:nids)', array(':nids' => $ids))->fetchAllAssoc('nid');
  273. foreach ($nodes as $node) {
  274. $node->{$display} = isset($result[$node->nid]) ? intval($result[$node->nid]->link) : variable_get($display . '_' . $node->type, PRINT_UI_TYPE_SHOW_LINK_DEFAULT);
  275. $node->{$display_comment} = isset($result[$node->nid]) ? intval($result[$node->nid]->comments) : variable_get($display_comment . '_' . $node->type, PRINT_UI_TYPE_COMMENT_LINK_DEFAULT);
  276. $node->{$display_urllist} = isset($result[$node->nid]) ? intval($result[$node->nid]->url_list) : variable_get($display_urllist . '_' . $node->type, PRINT_TYPE_URLLIST_DEFAULT);
  277. }
  278. }
  279. }
  280. }
  281. /**
  282. * Implements hook_node_insert().
  283. */
  284. function print_ui_node_insert($node) {
  285. print_ui_node_update($node);
  286. }
  287. /**
  288. * Implements hook_node_update().
  289. */
  290. function print_ui_node_update($node) {
  291. if (user_access('administer print') || user_access('node-specific print configuration')) {
  292. foreach (module_implements('print_link') as $module) {
  293. $function = $module . '_print_link';
  294. if (function_exists($function)) {
  295. $link = call_user_func_array($function, array());
  296. $display = 'print_' . $link['format'] . '_display';
  297. $display_comment = 'print_' . $link['format'] . '_display_comment';
  298. $display_urllist = 'print_' . $link['format'] . '_display_urllist';
  299. if (!isset($node->{$display}) || $node->{$display} === NULL) {
  300. $node->{$display} = variable_get($display . '_' . $node->type, PRINT_UI_TYPE_SHOW_LINK_DEFAULT);
  301. }
  302. if (!isset($node->{$display_comment}) || $node->{$display_comment} === NULL) {
  303. $node->{$display_comment} = variable_get($display_comment . '_' . $node->type, PRINT_UI_TYPE_COMMENT_LINK_DEFAULT);
  304. }
  305. if (!isset($node->{$display_urllist}) || $node->{$display_urllist} === NULL) {
  306. $node->{$display_urllist} = variable_get($display_urllist . '_' . $node->type, PRINT_TYPE_URLLIST_DEFAULT);
  307. }
  308. db_merge($module . '_node_conf')
  309. ->key(array('nid' => $node->nid))
  310. ->fields(array(
  311. 'link' => $node->{$display},
  312. 'comments' => $node->{$display_comment},
  313. 'url_list' => $node->{$display_urllist},
  314. ))
  315. ->execute();
  316. }
  317. }
  318. }
  319. }
  320. /**
  321. * Implements hook_node_delete().
  322. */
  323. function print_ui_node_delete($node) {
  324. foreach (module_implements('print_link') as $module) {
  325. $function = $module . '_print_link';
  326. if (function_exists($function)) {
  327. call_user_func_array($function, array());
  328. db_delete($module . '_node_conf')
  329. ->condition('nid', $node->nid)
  330. ->execute();
  331. }
  332. }
  333. }
  334. /**
  335. * Implements hook_form_alter().
  336. */
  337. function print_ui_form_alter(&$form, &$form_state, $form_id) {
  338. // Add the node-type settings option to activate the printer-friendly
  339. // version link.
  340. if ((user_access('administer print') || user_access('node-specific print configuration')) &&
  341. (($form_id == 'node_type_form') || !empty($form['#node_edit_form']))) {
  342. $form['print'] = array(
  343. '#type' => 'fieldset',
  344. '#title' => t('Printer, email and PDF versions'),
  345. '#collapsible' => TRUE,
  346. '#collapsed' => TRUE,
  347. '#weight' => PRINT_UI_TYPE_FIELDS_WEIGHT,
  348. '#group' => 'additional_settings',
  349. );
  350. foreach (module_implements('print_link') as $module) {
  351. $function = $module . '_print_link';
  352. if (function_exists($function)) {
  353. $link = call_user_func_array($function, array());
  354. $form['print']['print_' . $link['format']] = array(
  355. '#type' => 'fieldset',
  356. '#title' => check_plain($link['text']),
  357. '#collapsible' => TRUE,
  358. );
  359. $display = 'print_' . $link['format'] . '_display';
  360. $display_comment = 'print_' . $link['format'] . '_display_comment';
  361. $display_urllist = 'print_' . $link['format'] . '_display_urllist';
  362. $form['print']['print_' . $link['format']][$display] = array(
  363. '#type' => 'checkbox',
  364. '#title' => t('Show link'),
  365. );
  366. $form['print']['print_' . $link['format']][$display_comment] = array(
  367. '#type' => 'checkbox',
  368. '#title' => t('Show link in individual comments'),
  369. );
  370. $form['print']['print_' . $link['format']][$display_urllist] = array(
  371. '#type' => 'checkbox',
  372. '#title' => t('Show Printer-friendly URLs list'),
  373. );
  374. if ($form_id == 'node_type_form') {
  375. $form['print']['print_' . $link['format']][$display]['#default_value'] = variable_get($display . '_' . $form['#node_type']->type, PRINT_UI_TYPE_SHOW_LINK_DEFAULT);
  376. $form['print']['print_' . $link['format']][$display_comment]['#default_value'] = variable_get($display_comment . '_' . $form['#node_type']->type, PRINT_UI_TYPE_COMMENT_LINK_DEFAULT);
  377. $form['print']['print_' . $link['format']][$display_urllist]['#default_value'] = variable_get($display_urllist . '_' . $form['#node_type']->type, PRINT_TYPE_URLLIST_DEFAULT);
  378. }
  379. else {
  380. $node = $form['#node'];
  381. $form['print']['print_' . $link['format']][$display]['#default_value'] = isset($node->{$display}) ? $node->{$display} : variable_get($display . '_' . $node->type, PRINT_UI_TYPE_SHOW_LINK_DEFAULT);
  382. $form['print']['print_' . $link['format']][$display_comment]['#default_value'] = isset($node->{$display_comment}) ? $node->{$display_comment} : variable_get($display_comment . '_' . $node->type, PRINT_UI_TYPE_COMMENT_LINK_DEFAULT);
  383. $form['print']['print_' . $link['format']][$display_urllist]['#default_value'] = isset($node->{$display_urllist}) ? $node->{$display_urllist} : variable_get($display_urllist . '_' . $node->type, PRINT_TYPE_URLLIST_DEFAULT);
  384. }
  385. }
  386. }
  387. }
  388. }
  389. /**
  390. * Auxiliary function to fill the Printer-friendly link attributes.
  391. *
  392. * @param string $title
  393. * Text to displayed by the link when hovering over it with the mouse.
  394. * @param string $class
  395. * Class attribute to be used in the link.
  396. * @param bool $new_window
  397. * If TRUE opens the target page in a new window.
  398. *
  399. * @return array
  400. * An associative array containing:
  401. * - title: text to be used when hovering over the link.
  402. * - class: CSS class of the link tag.
  403. * - target: used for opening a new window with the non-javascript method
  404. * - onclick: open a new window, with the javascript method
  405. * - rel: SEO-related attribute indicating that the printer-friendly version
  406. * should not be indexed by search engine robots.
  407. */
  408. function _print_ui_fill_attributes($title = '', $class = '', $new_window = FALSE) {
  409. $print_newwindow = variable_get('print_newwindow', PRINT_NEWWINDOW_DEFAULT);
  410. $print_robots_noindex = variable_get('print_robots_noindex', PRINT_ROBOTS_NOINDEX_DEFAULT);
  411. $attributes = array();
  412. $attributes['title'] = $title;
  413. if (!empty($class)) {
  414. $attributes['class'] = array($class);
  415. }
  416. if ($new_window) {
  417. switch ($print_newwindow) {
  418. case 0:
  419. $attributes['target'] = '_blank';
  420. break;
  421. case 1:
  422. $attributes['onclick'] = 'window.open(this.href); return false';
  423. break;
  424. }
  425. }
  426. if (!empty($print_robots_noindex)) {
  427. $attributes['rel'] = 'nofollow';
  428. }
  429. return $attributes;
  430. }
  431. /**
  432. * Format the Printer-friendly link.
  433. *
  434. * @return array
  435. * An associative array containing:
  436. * - text: The content of the link
  437. * - html: TRUE if the text contains HTML tags, FALSE if it's plain text
  438. * - attributes: several attributes of the link tag (title, class, target,
  439. * onclick, rel)
  440. *
  441. * @see _print_ui_fill_attributes()
  442. * @ingroup themeable
  443. * @ingroup print_themeable
  444. */
  445. function theme_print_ui_format_link($vars) {
  446. $format = $vars['format'];
  447. foreach (module_implements('print_link') as $module) {
  448. $function = $module . '_print_link';
  449. if (function_exists($function)) {
  450. $link = call_user_func_array($function, array());
  451. if ($link['format'] == $format) {
  452. $link_class = variable_get('print_' . $link['format'] . '_link_class', $link['class']);
  453. $new_window = FALSE;
  454. $func = $module . '_print_new_window_alter';
  455. if (function_exists($func)) {
  456. $func($new_window, $link['format']);
  457. }
  458. $show_link = variable_get('print_' . $link['format'] . '_show_link', PRINT_UI_SHOW_LINK_DEFAULT);
  459. $link_text = filter_xss(variable_get('print_' . $link['format'] . '_link_text', $link['text']));
  460. $text = '';
  461. if ($show_link >= 2) {
  462. $img = drupal_get_path('module', $module) . '/icons/' . $link['icon'];
  463. switch ($show_link) {
  464. case 2:
  465. $text = theme('image', array(
  466. 'path' => $img,
  467. 'width' => '16px',
  468. 'height' => '16px',
  469. 'alt' => $link_text,
  470. 'title' => $link_text,
  471. 'attributes' => array('class' => array('print-icon')),
  472. ));
  473. break;
  474. case 3:
  475. $text = theme('image', array(
  476. 'path' => $img,
  477. 'width' => '16px',
  478. 'height' => '16px',
  479. 'alt' => $link_text,
  480. 'title' => $link_text,
  481. 'attributes' => array('class' => array('print-icon', 'print-icon-margin')),
  482. )) . $link_text;
  483. break;
  484. }
  485. $html = TRUE;
  486. }
  487. else {
  488. $text = $link_text;
  489. $html = FALSE;
  490. }
  491. return array(
  492. 'text' => $text,
  493. 'html' => $html,
  494. 'attributes' => _print_ui_fill_attributes($link['description'], strip_tags($link_class), $new_window),
  495. );
  496. }
  497. }
  498. }
  499. return array();
  500. }
  501. /**
  502. * Auxiliary function to display a formatted Printer-friendly link.
  503. *
  504. * Function made available so that developers may call this function from
  505. * their defined pages/blocks.
  506. *
  507. * @param array $link
  508. * Array returned by the hook_print_link() call.
  509. * @param array $args
  510. * Array of optional arguments:
  511. * - node: node object, to be used in checking node access. If the path
  512. * argument is not provided, the path used will be node/nid.
  513. * - path: path to be used in the link. If not specified, the current URL
  514. * is used.
  515. * - location: the location in the page where the link is being inserted
  516. * ('link', 'corner', 'block', 'help').
  517. *
  518. * @return string
  519. * string with the HTML link to the printer-friendly page
  520. */
  521. function print_ui_insert_link($link, $args = array()) {
  522. $node = isset($args['node']) ? $args['node'] : NULL;
  523. $path = isset($args['path']) ? $args['path'] : NULL;
  524. $location = isset($args['location']) ? $args['location'] : '';
  525. if ($node !== NULL) {
  526. $nid = $node->nid;
  527. if ($path === NULL) {
  528. $path = 'node/' . $nid;
  529. }
  530. $allowed_type = print_ui_link_allowed($link, array('node' => $node));
  531. }
  532. else {
  533. if ($path === NULL) {
  534. $nid = preg_replace('!^node/([\d]+)!', '$1', $_GET['q']);
  535. $path = $_GET['q'];
  536. }
  537. else {
  538. $nid = NULL;
  539. }
  540. $allowed_type = print_ui_link_allowed($link, array('path' => $path));
  541. }
  542. if ($allowed_type) {
  543. if ($nid !== NULL) {
  544. if ($allowed_type === PRINT_UI_ALLOW_BOOK_LINK) {
  545. $path = 'book/export/html/' . $nid;
  546. }
  547. else {
  548. if (variable_get('print_' . $link['format'] . '_link_use_alias', PRINT_UI_LINK_USE_ALIAS_DEFAULT) && ($alias = drupal_lookup_path('alias', $path))) {
  549. $path = $alias;
  550. }
  551. else {
  552. $path = $nid;
  553. }
  554. }
  555. $path = $link['path'] . '/' . $path;
  556. $query = _print_ui_query_string_encode($_GET, array('q'));
  557. }
  558. else {
  559. $query = NULL;
  560. }
  561. drupal_add_css(drupal_get_path('module', 'print_ui') . '/css/print_ui.theme.css');
  562. $format = theme('print_ui_format_link', array('format' => $link['format'], 'location' => $location));
  563. return '<span class="print_' . $link['format'] . '">' . l($format['text'], $path, array(
  564. 'attributes' => $format['attributes'],
  565. 'query' => $query,
  566. 'absolute' => TRUE,
  567. 'html' => $format['html'],
  568. )) . '</span>';
  569. }
  570. else {
  571. return FALSE;
  572. }
  573. }
  574. /**
  575. * Check if the link to the PF version is allowed depending on the settings.
  576. *
  577. * @param array $link
  578. * Array returned by the hook_print_link() call.
  579. * @param array $args
  580. * Array containing the possible parameters:
  581. * view_mode, node, type, path.
  582. *
  583. * @return int
  584. * FALSE if not allowed
  585. * PRINT_UI_ALLOW_NORMAL_LINK if a normal link is allowed
  586. * PRINT_UI_ALLOW_BOOK_LINK if a link is allowed in a book node
  587. */
  588. function print_ui_link_allowed($link, $args) {
  589. if (isset($args['view_mode'])) {
  590. $view_mode = $args['view_mode'];
  591. if ((($view_mode == 'teaser') && !variable_get('print_' . $link['format'] . '_link_teaser', PRINT_UI_LINK_TEASER_DEFAULT))
  592. || !in_array($view_mode, array('full', 'teaser'))) {
  593. // If the teaser link is disabled.
  594. return FALSE;
  595. }
  596. }
  597. $link_allowed_func = $link['module'] . '_link_allowed';
  598. if (function_exists($link_allowed_func)) {
  599. if (!$link_allowed_func($args)) {
  600. // If the format-specific function disallows the link.
  601. return FALSE;
  602. }
  603. }
  604. if (!empty($args['path'])) {
  605. $nid = preg_replace('!^node/!', '', drupal_get_normal_path($args['path']));
  606. if (ctype_digit($nid)) {
  607. $args['node'] = node_load($nid);
  608. }
  609. }
  610. if (!empty($args['node'])) {
  611. static $node_type = '';
  612. $node = $args['node'];
  613. if (isset($node->type)) {
  614. $node_type = $node->type;
  615. }
  616. // Node.
  617. if (isset($args['type']) && ($args['type'] == 'comment') && isset($node_type)) {
  618. // Link is for a comment, return the configured setting
  619. // Cache this statically to avoid duplicate queries for every comment.
  620. static $res = array();
  621. if (!isset($res[$link['format']][$node->nid])) {
  622. $res[$link['format']][$node->nid] = db_query("SELECT comments FROM {" . $link['module'] . "_node_conf} WHERE nid = :nid", array(':nid' => $node->nid))->fetchField();
  623. }
  624. $display_comment = ($res && ($res[$link['format']][$node->nid] !== FALSE)) ? $res[$link['format']][$node->nid] : variable_get('print_' . $link['format'] . '_display_comment_' . $node_type, PRINT_UI_TYPE_COMMENT_LINK_DEFAULT);
  625. if ($display_comment) {
  626. return PRINT_UI_ALLOW_NORMAL_LINK;
  627. }
  628. }
  629. else {
  630. // Node link.
  631. $display = 'print_' . $link['format'] . '_display';
  632. if (isset($node->{$display}) && !$node->{$display}) {
  633. // Link for this node is disabled.
  634. return FALSE;
  635. }
  636. elseif (isset($node->book)) {
  637. // Node is a book.
  638. $book_link = variable_get('print_' . $link['format'] . '_book_link', PRINT_UI_BOOK_LINK_DEFAULT);
  639. switch ($book_link) {
  640. case 1:
  641. if (user_access('access printer-friendly version')) {
  642. return PRINT_UI_ALLOW_BOOK_LINK;
  643. }
  644. break;
  645. case 2:
  646. return PRINT_UI_ALLOW_NORMAL_LINK;
  647. }
  648. }
  649. else {
  650. return PRINT_UI_ALLOW_NORMAL_LINK;
  651. }
  652. }
  653. }
  654. else {
  655. // 'System' page.
  656. $sys_link_visibility = variable_get('print_' . $link['format'] . '_sys_link_visibility', PRINT_UI_SYS_LINK_VISIBILITY_DEFAULT);
  657. $sys_link_pages = variable_get('print_' . $link['format'] . '_sys_link_pages', PRINT_UI_SYS_LINK_PAGES_DEFAULT);
  658. return _print_ui_page_match($sys_link_visibility, $_GET['q'], $sys_link_pages);
  659. }
  660. return FALSE;
  661. }
  662. /**
  663. * Check if the provided page is enabled according to the visibility settings.
  664. *
  665. * @param int $visibility
  666. * Current visibility settings:
  667. * 0 for show on every page except the listed pages
  668. * 1 for show on only the listed pages.
  669. * @param string $path
  670. * Current path.
  671. * @param string $pages
  672. * List of pages.
  673. *
  674. * @return bool
  675. * TRUE if it is enabled, FALSE otherwise
  676. */
  677. function _print_ui_page_match($visibility, $path, $pages) {
  678. if ($pages) {
  679. if ($visibility == 2) {
  680. if (module_exists('php')) {
  681. return php_eval($pages);
  682. }
  683. else {
  684. return FALSE;
  685. }
  686. }
  687. $alias = drupal_get_path_alias($path);
  688. $page_match = drupal_match_path($path, $pages);
  689. if ($alias != $path) {
  690. $page_match = $page_match || drupal_match_path($alias, $pages);
  691. }
  692. return !($visibility xor $page_match);
  693. }
  694. else {
  695. return !$visibility;
  696. }
  697. }
  698. /**
  699. * Parse an array into a valid urlencoded query string.
  700. *
  701. * Modified from drupal_query_string_encode to prevent re-encoding of
  702. * encoded original. (see #301192)
  703. *
  704. * @param array $query
  705. * The array to be processed e.g. $_GET.
  706. * @param array $exclude
  707. * The array filled with keys to be excluded.
  708. * @param string $parent
  709. * The be used in recursive calls.
  710. *
  711. * @return array
  712. * urlencoded string which can be appended to/as the URL query string
  713. */
  714. function _print_ui_query_string_encode($query, $exclude = array(), $parent = '') {
  715. $params = array();
  716. foreach ($query as $key => $value) {
  717. if (in_array($key, $exclude, TRUE)) {
  718. continue;
  719. }
  720. if (is_array($value)) {
  721. $params[$key] = _print_ui_query_string_encode($value, $exclude, $key);
  722. }
  723. else {
  724. $params[$key] = $value;
  725. }
  726. }
  727. return empty($params) ? NULL : $params;
  728. }