123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593 |
- <?php
- /**
- * @file
- * Displays Printer-friendly versions of Drupal pages.
- *
- * @ingroup print
- */
- define('PRINT_PDF_PDF_TOOL_DEFAULT', 0);
- define('PRINT_PDF_CONTENT_DISPOSITION_DEFAULT', 2);
- define('PRINT_PDF_PAPER_SIZE_DEFAULT', 'A4');
- define('PRINT_PDF_PAGE_ORIENTATION_DEFAULT', 'portrait');
- define('PRINT_PDF_IMAGES_VIA_FILE_DEFAULT', 0);
- define('PRINT_PDF_AUTOCONFIG_DEFAULT', 1);
- define('PRINT_PDF_FILENAME_DEFAULT', '[site:name] - [node:title] - [node:changed:custom:Y-m-d]');
- define('PRINT_PDF_CACHE_ENABLED_DEFAULT', 0);
- define('PRINT_PDF_CACHE_LIFETIME_DEFAULT', 86400); // 1 day
- /**
- * Implements hook_print_link().
- */
- function print_pdf_print_link() {
- return array(
- 'format' => 'pdf',
- 'text' => t('PDF version'),
- 'description' => t('Display a PDF version of this page.'),
- 'path' => 'printpdf',
- 'class' => 'print-pdf',
- 'icon' => 'pdf_icon.png',
- 'module' => 'print_pdf',
- );
- }
- /**
- * Implements hook_print_new_window_alter().
- */
- function print_pdf_print_new_window_alter(&$new_window, $format) {
- $new_window = (variable_get('print_pdf_content_disposition', PRINT_PDF_CONTENT_DISPOSITION_DEFAULT) == 1);
- }
- /**
- * Implements hook_permission().
- */
- function print_pdf_permission() {
- return array(
- 'access PDF version' => array(
- 'title' => t('Access the PDF version'),
- 'description' => t('View the PDF versions and the links to them in the original pages.'),
- ),
- );
- }
- /**
- * Implements hook_init().
- */
- function print_pdf_init() {
- if (variable_get('print_pdf_autoconfig', PRINT_PDF_AUTOCONFIG_DEFAULT)) {
- $print_pdf_pdf_tool = variable_get('print_pdf_pdf_tool', PRINT_PDF_PDF_TOOL_DEFAULT);
- $tool = explode('|', $print_pdf_pdf_tool);
- $function = $tool[0] . '_pdf_tool_info';
- if (function_exists($function)) {
- $info = $function();
- }
- if (isset($info['public_dirs'])) {
- foreach ($info['public_dirs'] as $dir) {
- $directory = 'public://print_pdf/' . $tool[0] . '/' . $dir;
- $wrapper = file_stream_wrapper_get_instance_by_uri($directory);
- $real_directory_path = $wrapper->getDirectoryPath() . "/" . file_uri_target($directory);
- $result = file_prepare_directory($real_directory_path, FILE_CREATE_DIRECTORY);
- if (!$result) {
- watchdog('print_pdf', 'Failed to create directory "%dir" for %tool.', array('%dir' => $directory, '%tool' => $tool[0]), WATCHDOG_CRITICAL);
- }
- }
- }
- }
- if (variable_get('print_pdf_cache_enabled', PRINT_PDF_CACHE_ENABLED_DEFAULT)) {
- $directory = print_pdf_cache_dir();
- $wrapper = file_stream_wrapper_get_instance_by_uri($directory);
- $real_directory_path = $wrapper->getDirectoryPath() . "/" . file_uri_target($directory);
- $result = file_prepare_directory($real_directory_path, FILE_MODIFY_PERMISSIONS | FILE_CREATE_DIRECTORY);
- if (!$result) {
- watchdog('print_pdf', 'Failed to create directory "%dir" for print_pdf cache.', array('%dir' => $directory), WATCHDOG_CRITICAL);
- }
- }
- }
- /**
- * Implements hook_flush_caches().
- */
- function print_pdf_flush_caches() {
- print_pdf_cache_delete();
- return array();
- }
- /**
- * Implements hook_menu().
- */
- function print_pdf_menu() {
- $link = print_pdf_print_link();
- $items = array();
- $items[$link['path']] = array(
- 'title' => 'Printer-friendly PDF',
- 'page callback' => 'print_pdf_controller',
- 'access arguments' => array('access PDF version'),
- 'type' => MENU_CALLBACK,
- 'file' => 'print_pdf.pages.inc',
- );
- $items[$link['path'] . '/' . $link['path']] = array(
- 'access callback' => FALSE,
- );
- $items['admin/config/user-interface/print/pdf'] = array(
- 'title' => 'PDF',
- 'description' => 'Configure the settings of the PDF generation functionality.',
- 'page callback' => 'drupal_get_form',
- 'page arguments' => array('print_pdf_settings'),
- 'access arguments' => array('administer print'),
- 'weight' => 3,
- 'type' => MENU_LOCAL_TASK,
- 'file' => 'print_pdf.admin.inc',
- );
- $items['admin/config/user-interface/print/pdf/options'] = array(
- 'title' => 'Options',
- 'weight' => -1,
- 'type' => MENU_DEFAULT_LOCAL_TASK,
- );
- return $items;
- }
- /**
- * Implements hook_variable_info().
- */
- function print_pdf_variable_info($options) {
- $link = print_pdf_print_link();
- $variable['print_pdf_link_text'] = array(
- 'title' => t('PDF version'),
- 'description' => t('Text used in the link to the PDF version.'),
- 'type' => 'string',
- 'default' => t($link['text']),
- );
- return $variable;
- }
- /**
- * Implements hook_block_info().
- */
- function print_pdf_block_info() {
- $block['print_pdf-top']['info'] = t('Most PDFd');
- $block['print_pdf-top']['cache'] = DRUPAL_CACHE_GLOBAL;
- return $block;
- }
- /**
- * Implements hook_block_view().
- */
- function print_pdf_block_view($delta = 0) {
- switch ($delta) {
- case 'print_pdf-top':
- $block['subject'] = t('Most PDFd');
- $result = db_query_range("SELECT path FROM {print_pdf_page_counter} LEFT JOIN {node} n ON path = CONCAT('node/', n.nid) WHERE status <> 0 OR status IS NULL ORDER BY totalcount DESC", 0, 3)
- ->fetchAll();
- if (count($result)) {
- $items = array();
- foreach ($result as $obj) {
- $items[] = l(_print_get_title($obj->path), $obj->path);
- }
- $block['content'] = theme('item_list', array('items' => $items, 'type' => 'ul'));
- }
- break;
- }
- return $block;
- }
- /**
- * Implements hook_requirements().
- */
- function print_pdf_requirements($phase) {
- $requirements = array();
- $t = get_t();
- switch ($phase) {
- // At runtime, make sure that a PDF generation tool is selected
- case 'runtime':
- $print_pdf_pdf_tool = variable_get('print_pdf_pdf_tool', PRINT_PDF_PDF_TOOL_DEFAULT);
- if (empty($print_pdf_pdf_tool)) {
- $requirements['print_pdf_tool'] = array(
- 'title' => $t('Printer, email and PDF versions - PDF generation library'),
- 'value' => $t('No PDF tool selected'),
- 'description' => $t('Please configure it in the !url.', array('!url' => l($t('PDF settings page'), 'admin/config/user-interface/print/pdf'))),
- 'severity' => REQUIREMENT_ERROR,
- );
- }
- else {
- // Tool is defined, get some data from it's handler module
- $tool = explode('|', $print_pdf_pdf_tool);
- $function = $tool[0] . '_pdf_tool_info';
- if (function_exists($function)) {
- $info = $function();
- }
- // Is the file there?
- if (!is_file($tool[1]) || !is_readable($tool[1])) {
- $requirements['print_pdf_tool'] = array(
- 'title' => $t('Printer, email and PDF versions - PDF generation library'),
- 'value' => $t('File not found'),
- 'description' => $t('The currently selected PDF generation library (%file) is no longer accessible.', array('%file' => $tool[1])),
- 'severity' => REQUIREMENT_ERROR,
- );
- }
- else {
- // Get the version number
- $function = $tool[0] . '_pdf_tool_version';
- if (function_exists($function)) {
- $version = $function($tool[1]);
- if (isset($info['min_version']) && version_compare($version, $info['min_version'], '<')) {
- $requirements['print_pdf_tool_version'] = array(
- 'title' => $t('Printer, email and PDF versions - PDF generation library'),
- 'value' => $t('Unsupported %lib version', array('%lib' => $info['name'])),
- 'description' => $t('The currently selected version of %lib (@version) is not supported. Please update to a !url.',
- array('%lib' => $info['name'], '@version' => $version, '!url' => l($t('newer version'), $info['url']))),
- 'severity' => REQUIREMENT_ERROR,
- );
- }
- else {
- $requirements['print_pdf_tool_version'] = array(
- 'title' => $t('Printer, email and PDF versions - PDF generation library'),
- 'value' => $info['name'] . ' ' . $version,
- );
- }
- }
- }
- // If auto-config is on, check for write access to the appropriate dirs
- if (variable_get('print_pdf_autoconfig', PRINT_PDF_AUTOCONFIG_DEFAULT)) {
- $directories = array();
- if (isset($info['public_dirs'])) {
- foreach ($info['public_dirs'] as $dir) {
- $directories[] = 'public://print_pdf/' . $tool[0] . '/' . $dir;
- }
- }
- if (isset($info['tool_dirs'])) {
- foreach ($info['tool_dirs'] as $dir) {
- $directories[] = dirname($tool[1]) . '/' . $dir;
- }
- }
- foreach ($directories as $dir) {
- if (!is_dir($dir) || !is_writable($dir)) {
- $requirements['print_pdf_tool_' . $dir] = array(
- 'title' => $t('%lib directory', array('%lib' => $info['name'])),
- 'value' => $t('Non-writable permissions'),
- 'description' => $t('You must change the %libdir permissions to be writable, as %lib requires write-access to that directory.', array('%lib' => $info['name'], '%libdir' => $dir)),
- 'severity' => REQUIREMENT_ERROR,
- );
- }
- }
- }
- }
- break;
- }
- return $requirements;
- }
- /**
- * Implements hook_node_load().
- */
- function print_pdf_node_load($nodes, $types) {
- $ids = array();
- foreach ($nodes as $node) {
- $ids[] = $node->nid;
- }
- $link = print_pdf_print_link();
- $size = 'print_' . $link['format'] . '_size';
- $orientation = 'print_' . $link['format'] . '_orientation';
- $result = db_query('SELECT nid, size, orientation FROM {print_pdf_node_conf} WHERE nid IN (:nids)', array(':nids' => $ids))->fetchAllAssoc('nid');
- foreach ($nodes as $node) {
- $node->{$size} = (isset($result[$node->nid]) && !empty($result[$node->nid]->size)) ? $result[$node->nid]->size : variable_get($size . '_' . $node->type);
- $node->{$orientation} = (isset($result[$node->nid]) && !empty($result[$node->nid]->orientation)) ? $result[$node->nid]->orientation : variable_get($orientation . '_' . $node->type);
- }
- }
- /**
- * Implements hook_node_insert().
- */
- function print_pdf_node_insert($node) {
- return print_pdf_node_update($node);
- }
- /**
- * Implements hook_node_update().
- */
- function print_pdf_node_update($node) {
- if (user_access('administer print') || user_access('node-specific print configuration')) {
- $link = print_pdf_print_link();
- $size = 'print_' . $link['format'] . '_size';
- $orientation = 'print_' . $link['format'] . '_orientation';
- if (!isset($node->{$size})) $node->{$size} = variable_get($size . '_' . $node->type);
- if (!isset($node->{$orientation})) $node->{$orientation} = variable_get($orientation . '_' . $node->type);
- db_merge('print_pdf_node_conf')
- ->key(array('nid' => $node->nid))
- ->fields(array(
- 'size' => $node->{$size},
- 'orientation' => $node->{$orientation},
- ))
- ->execute();
- }
- print_pdf_cache_delete($node->nid);
- }
- /**
- * Implements hook_node_delete().
- */
- function print_pdf_node_delete($node) {
- db_delete('print_pdf_page_counter')
- ->condition('path', 'node/' . $node->nid)
- ->execute();
- print_pdf_cache_delete($node->nid);
- }
- /**
- * Implements hook_form_alter().
- */
- function print_pdf_form_alter(&$form, &$form_state, $form_id) {
- // Add the node-type settings option to activate the printer-friendly version link
- if ((user_access('administer print') || user_access('node-specific print configuration')) &&
- (($form_id == 'node_type_form') || !empty($form['#node_edit_form']))) {
- $link = print_pdf_print_link();
- $size = 'print_' . $link['format'] . '_size';
- $orientation = 'print_' . $link['format'] . '_orientation';
- $form['print']['print_' . $link['format']][$size] = array(
- '#type' => 'select',
- '#title' => t('Paper size'),
- '#options' => _print_pdf_paper_sizes(TRUE),
- '#description' => t('Choose the paper size of the generated PDF.'),
- );
- $form['print']['print_' . $link['format']][$orientation] = array(
- '#type' => 'select',
- '#title' => t('Page orientation'),
- '#options' => array('' => 'Unchanged', 'portrait' => t('Portrait'), 'landscape' => t('Landscape')),
- '#description' => t('Choose the page orientation of the generated PDF.'),
- );
- if ($form_id == 'node_type_form') {
- $form['print']['print_' . $link['format']][$size]['#default_value'] = variable_get($size . '_' . $form['#node_type']->type);
- $form['print']['print_' . $link['format']][$orientation]['#default_value'] = variable_get($orientation . '_' . $form['#node_type']->type);
- }
- else {
- $node = $form['#node'];
- $form['print']['print_' . $link['format']][$size]['#default_value'] = isset($node->{$size}) ? $node->{$size} : variable_get($size . '_' . $node->type);
- $form['print']['print_' . $link['format']][$orientation]['#default_value'] = isset($node->{$orientation}) ? $node->{$orientation} : variable_get($orientation . '_' . $node->type);
- }
- }
- }
- /**
- * Auxiliary function to display a formatted PDF version link
- *
- * Function made available so that developers may call this function from
- * their defined pages/blocks.
- *
- * @param string $path
- * path to be used in the link. If not specified, the current URL is used.
- * @param object $node
- * node object, to be used in checking node access. If the path argument is
- * not provided, the path used will be node/nid.
- * @param string $location
- * where in the page where the link is being inserted ('link', 'corner',
- * 'block', 'help').
- *
- * @return bool
- * string with the HTML link to the printer-friendly page
- *
- * @ingroup print_api
- */
- function print_pdf_insert_link($path = NULL, $node = NULL, $location = '') {
- if (function_exists('print_ui_insert_link')) {
- return print_ui_insert_link(print_pdf_print_link(), array('path' => $path, 'node' => $node, 'location' => $location));
- }
- else {
- return FALSE;
- }
- }
- /**
- * Check if the link to the PDF version is allowed depending on the settings
- *
- * @param array $args
- * array containing the possible parameters:
- * view_mode, node, type, path
- *
- * @return bool
- * FALSE if not allowed, TRUE otherwise
- */
- function print_pdf_link_allowed($args) {
- $print_pdf_pdf_tool = variable_get('print_pdf_pdf_tool', PRINT_PDF_PDF_TOOL_DEFAULT);
- return (user_access('access PDF version') && (!empty($print_pdf_pdf_tool)));
- }
- /**
- * Implements hook_cron().
- */
- function print_pdf_cron() {
- print_pdf_cache_clean();
- }
- /**
- * Removes pdf files for nodes/paths if they are older than the lifetime.
- */
- function print_pdf_cache_clean() {
- $lifetime = variable_get('print_pdf_cache_lifetime', PRINT_PDF_CACHE_LIFETIME_DEFAULT);
- if ($lifetime > 0) {
- $files = file_scan_directory(print_pdf_cache_dir(), '!\d+\.pdf$!');
- foreach ($files as $file) {
- // For all files in the cache directory, see when they were last accessed
- $result = db_query("SELECT timestamp FROM {print_pdf_page_counter} WHERE path = :path", array(':path' => 'node/' . $file->name))
- ->fetchField();
- // Keep the file only if the last access was within the cache max life value
- if (($result === FALSE) || ($result + $lifetime < REQUEST_TIME)) {
- print_pdf_cache_delete($file->name);
- }
- }
- }
- }
- /**
- * Returns the cache directory.
- *
- * @return string
- * The scheme://path of the cache directory
- */
- function print_pdf_cache_dir() {
- $scheme = 'private';
- if (!file_stream_wrapper_valid_scheme($scheme)) {
- $scheme = 'temporary';
- }
- return $scheme . '://print_pdf/cache';
- }
- /**
- * Deletes one or more files from the PDF cache directory.
- *
- * @param int nid
- * The node ID of the page for which the cached PDF should be deleted.
- * If not provided, the entire cache directory will be deleted.
- */
- function print_pdf_cache_delete($nid = NULL) {
- $directory = print_pdf_cache_dir();
- if ($nid) {
- $filename = $directory . '/' . $nid . '.pdf';
- if (is_file($filename)) {
- file_unmanaged_delete($filename);
- }
- }
- else {
- // If no nid is provided, flush the entire cache.
- if (is_dir($directory)) {
- file_unmanaged_delete_recursive($directory);
- }
- }
- }
- /**
- * Displays the PDF as inline or a downloadable file.
- *
- * @param string $pdf
- * PDF content string
- * @param string $filename
- * Filename of the generated PDF
- *
- * @return string
- * The disposed PDF file
- */
- function print_pdf_dispose_content($pdf, $filename) {
- if (headers_sent()) {
- exit('Unable to stream pdf: headers already sent');
- }
- header('Cache-Control: private');
- header('Content-Type: application/pdf');
- $content_disposition = variable_get('print_pdf_content_disposition', PRINT_PDF_CONTENT_DISPOSITION_DEFAULT);
- $attachment = ($content_disposition == 2) ? 'attachment' : 'inline';
- header("Content-Disposition: $attachment; filename=\"$filename\"");
- echo $pdf;
- flush();
- return TRUE;
- }
- /**
- * Generate a PDF version of the provided HTML.
- *
- * @param string $html
- * HTML content of the PDF
- * @param array $meta
- * Meta information to be used in the PDF
- * - url: original URL
- * - name: author's name
- * - title: Page title
- * - node: node object
- * @param string $filename
- * (optional) Filename of the generated PDF
- * @param string $paper_size
- * (optional) Paper size of the generated PDF
- * @param string $page_orientation
- * (optional) Page orientation of the generated PDF
- *
- * @return
- * generated PDF page, or NULL in case of error
- *
- * @see print_pdf_controller()
- *
- * @ingroup print_api
- */
- function print_pdf_generate_html($html, $meta, $filename = NULL, $paper_size = NULL, $page_orientation = NULL) {
- $pdf_tool = explode('|', variable_get('print_pdf_pdf_tool', PRINT_PDF_PDF_TOOL_DEFAULT));
- module_load_include('inc', $pdf_tool[0], $pdf_tool[0] . '.pages');
- $function = $pdf_tool[0] . '_print_pdf_generate';
- if (function_exists($function)) {
- $pdf = $function($html, $meta, $paper_size, $page_orientation);
- }
- if ($filename) {
- return print_pdf_dispose_content($pdf, $filename);
- }
- return $pdf;
- }
- /**
- * Implements hook_views_api().
- */
- function print_pdf_views_api() {
- return array(
- 'api' => 2.0,
- 'path' => drupal_get_path('module', 'print_pdf'),
- );
- }
- /**
- * Lists all possible paper sizes
- *
- * @return
- * array of strings with the available paper sizes
- */
- function _print_pdf_paper_sizes($include_default = FALSE) {
- $ret = array();
- $ret = ($include_default) ? array('' => 'Unchanged') : array();
- $ret += array(
- '4A0' => '4A0', '2A0' => '2A0', 'A0' => 'A0',
- 'A1' => 'A1', 'A2' => 'A2', 'A3' => 'A3', 'A4' => 'A4',
- 'A5' => 'A5', 'A6' => 'A6', 'A7' => 'A7', 'A8' => 'A8',
- 'A9' => 'A9', 'A10' => 'A10', 'B0' => 'B0', 'B1' => 'B1',
- 'B2' => 'B2', 'B3' => 'B3', 'B4' => 'B4', 'B5' => 'B5',
- 'B6' => 'B6', 'B7' => 'B7', 'B8' => 'B8', 'B9' => 'B9',
- 'B10' => 'B10', 'C0' => 'C0', 'C1' => 'C1', 'C2' => 'C2',
- 'C3' => 'C3', 'C4' => 'C4', 'C5' => 'C5', 'C6' => 'C6',
- 'C7' => 'C7', 'C8' => 'C8', 'C9' => 'C9', 'C10' => 'C10',
- 'RA0' => 'RA0', 'RA1' => 'RA1', 'RA2' => 'RA2',
- 'RA3' => 'RA3', 'RA4' => 'RA4', 'SRA0' => 'SRA0',
- 'SRA1' => 'SRA1', 'SRA2' => 'SRA2', 'SRA3' => 'SRA3',
- 'SRA4' => 'SRA4', 'LETTER' => 'Letter', 'LEGAL' => 'Legal',
- 'EXECUTIVE' => 'Executive', 'FOLIO' => 'Folio',
- );
- return $ret;
- }
|