print.module 10.5 KB
Newer Older
1 2
<?php

3 4
/**
 * @file
jcnventura's avatar
jcnventura committed
5 6 7 8
 * Displays Printer-friendly versions of Drupal pages.
 *
 * This is the core module of the PF package, with the Drupal hooks
 * and other administrative functions.
9 10
 *
 * @ingroup print
11 12
 */

13
define('PRINT_LOGO_OPTIONS_DEFAULT', 1);
14
define('PRINT_LOGO_URL_DEFAULT', '');
15 16
define('PRINT_FOOTER_OPTIONS_DEFAULT', 1);
define('PRINT_FOOTER_USER_DEFAULT', '');
17
define('PRINT_CSS_DEFAULT', '');
18
define('PRINT_KEEP_THEME_CSS_DEFAULT', 0);
19
define('PRINT_URLS_DEFAULT', 1);
20
define('PRINT_URLS_ANCHORS_DEFAULT', 0);
21 22
define('PRINT_COMMENTS_DEFAULT', 0);
define('PRINT_NEWWINDOW_DEFAULT', 1);
jcnventura's avatar
jcnventura committed
23

24
define('PRINT_TYPE_URLLIST_DEFAULT', 1);
25
define('PRINT_TYPE_SYS_URLLIST_DEFAULT', 0);
jcnventura's avatar
jcnventura committed
26
define('PRINT_TYPE_LINK_TEXT_ENABLED_DEFAULT', 0);
27

28
define('PRINT_HTML_NEW_WINDOW_DEFAULT', 0);
29
define('PRINT_HTML_SENDTOPRINTER_DEFAULT', 0);
30
define('PRINT_HTML_WINDOWCLOSE_DEFAULT', 1);
31 32 33 34 35 36 37 38 39

define('PRINT_SOURCEURL_ENABLED_DEFAULT', 1);
define('PRINT_SOURCEURL_DATE_DEFAULT', 0);
define('PRINT_SOURCEURL_FORCENODE_DEFAULT', 0);

define('PRINT_ROBOTS_NOINDEX_DEFAULT', 1);
define('PRINT_ROBOTS_NOFOLLOW_DEFAULT', 1);
define('PRINT_ROBOTS_NOARCHIVE_DEFAULT', 0);

40 41
define('PRINT_LIB_PATH', 'sites/all/libraries');

42 43 44 45 46 47 48 49
/**
 * Implements hook_print_link().
 */
function print_print_link() {
  return array(
    'format' => 'html',
    'text' => t('Printer-friendly version'),
    'description' => t('Display a printer-friendly version of this page.'),
50
    'path' => 'print',
51 52 53 54 55
    'class' => 'print-page',
    'icon' => 'print_icon.gif',
    'module' => 'print',
  );
}
56

jcnventura's avatar
jcnventura committed
57 58 59 60 61 62 63
/**
 * Implements hook_print_new_window_alter().
 */
function print_print_new_window_alter(&$new_window, $format) {
  $new_window = variable_get('print_html_new_window', PRINT_HTML_NEW_WINDOW_DEFAULT);
}

64
/**
65
 * Implements hook_permission().
66
 */
67
function print_permission() {
68
  return array(
69 70 71 72
    'administer print' => array(
      'title' => t('Administer the module'),
      'description' => t('Perform maintenance tasks for the print module.'),
    ),
jcnventura's avatar
jcnventura committed
73 74 75 76
    'access print' => array(
      'title' => t('Access the printer-friendly page'),
      'description' => t('View the printer-friendly pages and the links to them in the original pages.'),
    ),
77
  );
78
}
79

jcnventura's avatar
jcnventura committed
80
/**
81
 * Implements hook_theme().
jcnventura's avatar
jcnventura committed
82 83 84
 */
function print_theme() {
  return array(
85
    'print' => array(
86
      'variables' => array('node' => NULL, 'format' => '', 'expand_css' => FALSE, 'message' => ''),
87
      'template' => 'print',
88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108
      'file' => 'print.pages.inc',
    ),
    'print_published' => array(
      'variables' => array(),
      'file' => 'print.pages.inc',
    ),
    'print_breadcrumb' => array(
      'variables' => array('node' => NULL),
      'file' => 'print.pages.inc',
    ),
    'print_footer' => array(
      'variables' => array(),
      'file' => 'print.pages.inc',
    ),
    'print_sourceurl' => array(
      'variables' => array('url' => '', 'node' => NULL, 'cid' => NULL),
      'file' => 'print.pages.inc',
    ),
    'print_url_list' => array(
      'variables' => array(),
      'file' => 'print.pages.inc',
109
    ),
jcnventura's avatar
jcnventura committed
110 111 112
  );
}

113
/**
114
 * Implements hook_preprocess_HOOK().
115
 */
116 117 118 119 120 121 122 123 124 125
function print_preprocess_node(&$variables) {
  if ($variables['elements']['#view_mode'] == 'print') {
    $type = $variables['elements']['#node']->type;
    $format = $variables['elements']['#print_format'];
    $nid = $variables['elements']['#node']->nid;

    $variables['theme_hook_suggestions'][] = "node__print";
    $variables['theme_hook_suggestions'][] = "node__print__{$format}";
    $variables['theme_hook_suggestions'][] = "node__print__{$format}__node__{$type}";
    $variables['theme_hook_suggestions'][] = "node__print__{$format}__node__{$nid}";
126
  }
127
}
128

129
/**
130
 * Implements hook_menu().
131
 */
132
function print_menu() {
jcnventura's avatar
jcnventura committed
133
  $link = print_print_link();
134 135
  $items = array();

jcnventura's avatar
jcnventura committed
136
  $items[$link['path']] = array(
137
    'title' => 'Printer-friendly',
jcnventura's avatar
jcnventura committed
138
    'page callback' => 'print_controller_html',
139
    'access arguments' => array('access print'),
jcnventura's avatar
jcnventura committed
140
    'type' => MENU_CALLBACK,
141
    'file' => 'print.pages.inc',
142
  );
jcnventura's avatar
jcnventura committed
143
  $items[$link['path'] . '/' . $link['path']] = array(
144
    'access callback' => FALSE,
145
  );
146
  $items['admin/config/user-interface/print'] = array(
147
    'title' => 'Printer, email and PDF versions',
148
    'description' => 'Adds a printer-friendly version link to content and administrative pages.',
149
    'page callback' => 'drupal_get_form',
jcnventura's avatar
jcnventura committed
150 151
    'page arguments' => array('print_html_settings'),
    'access arguments'  => array('administer print'),
152
    'file' => 'print.admin.inc',
jcnventura's avatar
jcnventura committed
153
  );
154
  $items['admin/config/user-interface/print/html'] = array(
jcnventura's avatar
jcnventura committed
155
    'title' => 'Web page',
156
    'weight' => 1,
jcnventura's avatar
jcnventura committed
157 158
    'type' => MENU_DEFAULT_LOCAL_TASK,
  );
159
  $items['admin/config/user-interface/print/common'] = array(
jcnventura's avatar
jcnventura committed
160
    'title' => 'Settings',
jcnventura's avatar
jcnventura committed
161
    'description' => 'Settings for the common functionalities for all the print sub-modules.',
jcnventura's avatar
jcnventura committed
162
    'page callback' => 'drupal_get_form',
163 164
    'page arguments' => array('print_main_settings'),
    'access arguments'  => array('administer print'),
jcnventura's avatar
jcnventura committed
165 166
    'weight' => 10,
    'type' => MENU_LOCAL_TASK,
167
    'file' => 'print.admin.inc',
168
  );
169 170 171 172

  return $items;
}

173
/**
174
 * Implements hook_block_info().
175
 */
176
function print_block_info() {
177 178 179
  $block['print-top']['info'] = t('Most printed');
  $block['print-top']['cache'] = DRUPAL_CACHE_GLOBAL;
  return $block;
180
}
jcnventura's avatar
jcnventura committed
181 182

/**
183
 * Implements hook_block_view().
jcnventura's avatar
jcnventura committed
184
 */
185
function print_block_view($delta = '') {
186 187
  $block = array();

188 189 190
  switch ($delta) {
    case 'print-top':
      $block['subject'] = t('Most printed');
jcnventura's avatar
jcnventura committed
191
      $result = db_query_range("SELECT path FROM {print_page_counter} LEFT JOIN {node} ON path = CONCAT('node/', node.nid) WHERE status <> 0 OR status IS NULL ORDER BY totalcount DESC", 0, 3)
192 193
                  ->fetchAll();
      if (count($result)) {
194
        $items = array();
195
        foreach ($result as $obj) {
196
          $items[] = l(_print_get_title($obj->path), $obj->path);
197
        }
198
        $block['content'] = theme('item_list', array('items' => $items, 'type' => 'ul'));
199
      }
200 201 202
      break;
  }
  return $block;
203
}
204

jcnventura's avatar
jcnventura committed
205 206 207 208 209 210 211 212 213 214 215
/**
 * Implements hook_help().
 */
function print_help($path, $arg) {
  switch ($path) {
    case 'admin/help#print':
      // Return a line-break version of the module README
      return _filter_autop(file_get_contents(drupal_get_path('module', 'print') . '/README.txt'));
  }
}

216
/**
217
 * Implements hook_node_delete().
218
 */
219
function print_node_delete($node) {
220
  db_delete('print_page_counter')
221
    ->condition('path', 'node/' . $node->nid)
222
    ->execute();
223
}
224

225
/**
226
 * Implements hook_entity_info_alter().
227
 */
228 229 230
function print_entity_info_alter(&$info) {
  // Add the 'Print' view mode for nodes.
  $info['node']['view modes'] += array(
231
    'print' => array(
232 233
      'label' => t('Print'),
      'custom settings' => FALSE,
234 235
    ),
  );
236
}
237

238 239 240
/**
 * Auxiliary function to discover a given page's title
 *
jcnventura's avatar
jcnventura committed
241
 * @param string $path
242
 *   path of the page being identified
jcnventura's avatar
jcnventura committed
243 244
 *
 * @return string
245 246 247 248 249
 *   string with the page's title
 */
function _print_get_title($path) {
  $path = drupal_get_normal_path($path);
  $nid = preg_replace('!^node/!', '', $path);
250
  if (ctype_digit($nid)) {
251
    $res = db_query("SELECT title FROM {node} WHERE nid = :nid", array(':nid' => $nid))
jcnventura's avatar
jcnventura committed
252
              ->fetchField();
253 254 255
  }
  else {
    $res = db_query("SELECT link_title FROM {menu_links} WHERE link_path = :link_path", array(':link_path' => $path))
jcnventura's avatar
jcnventura committed
256
              ->fetchField();
257 258 259 260
  }
  return $res;
}

261
/**
jcnventura's avatar
jcnventura committed
262 263
 * Auxiliary function to display a formatted Printer-friendly link
 *
jcnventura's avatar
jcnventura committed
264 265 266
 * Function made available so that developers may call this function from
 * their defined pages/blocks.
 *
jcnventura's avatar
jcnventura committed
267
 * @param string $path
jcnventura's avatar
jcnventura committed
268
 *   path of the original page (optional). If not specified, the current URL
jcnventura's avatar
jcnventura committed
269
 *   is used
jcnventura's avatar
jcnventura committed
270
 * @param object $node
271 272
 *   an optional node object, to be used in defining the path, if used, the
 *   path argument is irrelevant
jcnventura's avatar
jcnventura committed
273 274 275
 *
 * @return string
 *   HTML link to the printer-friendly page
276 277
 *
 * @ingroup print_api
278
 */
279
function print_insert_link($path = NULL, $node = NULL) {
280
  if (function_exists('print_ui_insert_link')) {
jcnventura's avatar
jcnventura committed
281
    return print_ui_insert_link(print_print_link(), $path, $node);
282 283
  }
  else {
284 285
    return FALSE;
  }
286
}
287

jcnventura's avatar
jcnventura committed
288 289 290
/**
 * Check if the link to the PF version is allowed depending on the settings
 *
jcnventura's avatar
jcnventura committed
291
 * @param array $args
jcnventura's avatar
jcnventura committed
292
 *   array containing the possible parameters:
jcnventura's avatar
jcnventura committed
293 294 295
 *    view_mode, node, type, path
 *
 * @return bool
jcnventura's avatar
jcnventura committed
296 297 298 299 300 301
 *   FALSE if not allowed, TRUE otherwise
 */
function print_link_allowed($args) {
  return (user_access('access print'));
}

302 303 304 305
/**
 * Implements hook_contextual_links_view_alter().
 */
function print_contextual_links_view_alter(&$element, $items) {
306 307 308 309
  // Hide all contextual links
  if (preg_match('!^print!', $_GET['q'])) {
    unset($element['#links']);
  }
310
}
311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331

/**
 * Auxiliary function to scan all module directories for a given library.
 *
 * @param string $lib
 *   The machine name of a library to return the path for.
 * @param string $mask
 *   The preg_match() regular expression of the files to find.
 *
 * @return array
 *   An array corresponding of the matching files.
 */
function _print_scan_libs($lib, $mask) {
  $tools = array_keys(file_scan_directory(drupal_get_path('module', 'print'), $mask));
  $tools = array_merge($tools, array_keys(file_scan_directory(PRINT_LIB_PATH, $mask)));
  if (module_exists('libraries')) {
    $tools = array_merge($tools, array_keys(file_scan_directory(libraries_get_path($lib), $mask)));
  }

  return array_unique($tools);
}
332

333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369
/**
 * Callback function for the preg_replace_callback replacing spaces with %20
 *
 * Replace spaces in URLs with %20
 *
 * @param array $matches
 *   array with the matched tag patterns, usually <a...>+text+</a>
 *
 * @return string
 *   tag with re-written URL
 */
function _print_replace_spaces($matches) {
  // first, split the html into the different tag attributes
  $pattern = '!\s*(\w+\s*=\s*"(?:\\\"|[^"])*")\s*|\s*(\w+\s*=\s*\'(?:\\\\\'|[^\'])*\')\s*|\s*(\w+\s*=\s*\w+)\s*|\s+!';
  $attribs = preg_split($pattern, $matches[1], -1, PREG_SPLIT_NO_EMPTY | PREG_SPLIT_DELIM_CAPTURE);
  foreach ($attribs as $key => $value) {
    $attribs[$key] = preg_replace('!(\w)\s*=\s*(.*)!', '$1=$2', $value);
  }

  $size = count($attribs);
  for ($i=1; $i < $size; $i++) {
    // If the attribute is href or src, we may need to rewrite the URL in the value
    if (preg_match('!^(?:href|src)\s*?=(.*)!i', $attribs[$i], $urls) > 0) {
      $url = trim($urls[1], " \t\n\r\0\x0B\"'");
      $new_url = str_replace(' ', '%20', $url);
      $matches[1] = str_replace($url, $new_url, $matches[1]);
    }
  }

  $ret = '<' . $matches[1] . '>';
  if (count($matches) == 4) {
    $ret .= $matches[2] . $matches[3];
  }

  return $ret;
}

370 371 372 373 374 375 376 377 378
/**
 * Implements hook_views_api().
 */
function print_views_api() {
  return array(
    'api' => 2.0,
    'path' => drupal_get_path('module', 'print'),
  );
}