Commit f3a6a46e authored by jcnventura's avatar jcnventura

Move pdf library handling into specialized sub-modules.

parent 545f0a4e
......@@ -8,29 +8,48 @@
*/
/**
* @defgroup print Printer, email and PDF versions
* @defgroup print Files
*
* Files used by the print module, grouped by sub-module
*
* - Printer-friendly pages
* - @link print.module Module main file @endlink
* - @link print.admin.inc Settings form @endlink
* - @link print.pages.inc HTML generation @endlink
* - @link print.admin.inc Settings form @endlink
* - @link print.install (Un)Install routines @endlink
* - @link print.tpl.php Page generation template @endlink
* - Send by email
* - @link print_mail.module Module main file @endlink
* - @link print_mail.admin.inc Settings form @endlink
* - @link print_mail.inc Mail form and send mail routine @endlink
* - @link print_mail.admin.inc Settings form @endlink
* - @link print_mail.install (Un)Install routines @endlink
* - @link views_handler_sort_print_mail_sentcount.inc Views handler @endlink
* - PDF version
* - @link print_pdf.module Module main file @endlink
* - @link print_pdf.admin.inc Settings form @endlink
* - @link print_pdf.pages.inc PDF generation @endlink
* - @link print_pdf.class.inc Auxiliary PHP5 class @endlink
* - @link print_pdf.admin.inc Settings form @endlink
* - @link print_pdf.install (Un)Install routines @endlink
* - @link print_pdf.drush.inc Drush commands @endlink
* - PDF library handlers:
* - dompdf
* - @link print_pdf_dompdf.module Module main file @endlink
* - @link print_pdf_dompdf.pages.inc PDF generation @endlink
* - @link print_pdf_dompdf.admin.inc Settings form @endlink
* - @link print_pdf_dompdf.install (Un)Install routines @endlink
* - mPDF
* - @link print_pdf_mpdf.module Module main file @endlink
* - @link print_pdf_mpdf.pages.inc PDF generation @endlink
* - TCPDF
* - @link print_pdf_tcpdf.module Module main file @endlink
* - @link print_pdf_tcpdf.pages.inc PDF generation @endlink
* - @link print_pdf_tcpdf.admin.inc Settings form @endlink
* - @link print_pdf_tcpdf.install (Un)Install routines @endlink
* - @link print_pdf_tcpdf.class.inc Auxiliary PHP5 class @endlink
* - wkhtmltopdf
* - @link print_pdf_wkhtmltopdf.module Module main file @endlink
* - @link print_pdf_wkhtmltopdf.pages.inc PDF generation @endlink
* - @link print_pdf_wkhtmltopdf.admin.inc Settings form @endlink
* - @link print_pdf_wkhtmltopdf.install (Un)Install routines @endlink
* - User Interface (Links)
* - @link print_ui.module Module main file @endlink
* - @link print_ui.admin.inc Settings form @endlink
......@@ -47,3 +66,9 @@
*
* Default theme implementations of the print module
*/
/**
* @defgroup print_api API
*
* Functions that are provided for use by third-party code.
*/
......@@ -36,6 +36,8 @@ define('PRINT_ROBOTS_NOINDEX_DEFAULT', 1);
define('PRINT_ROBOTS_NOFOLLOW_DEFAULT', 1);
define('PRINT_ROBOTS_NOARCHIVE_DEFAULT', 0);
define('PRINT_LIB_PATH', 'sites/all/libraries');
/**
* Implements hook_print_link().
*/
......@@ -270,6 +272,8 @@ function _print_get_title($path) {
*
* @return string
* HTML link to the printer-friendly page
*
* @ingroup print_api
*/
function print_insert_link($path = NULL, $node = NULL) {
if (function_exists('print_ui_insert_link')) {
......@@ -303,3 +307,24 @@ function print_contextual_links_view_alter(&$element, $items) {
unset($element['#links']);
}
}
/**
* 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);
}
......@@ -10,8 +10,6 @@
* @ingroup print
*/
require_once(DRUPAL_ROOT . '/' . drupal_get_path('module', 'print') . '/print.pages.inc');
// Include MIME library
@include_once('Mail/mime.php');
......@@ -274,6 +272,8 @@ function print_mail_form_validate($form, &$form_state) {
*/
function print_mail_form_submit($form, &$form_state) {
if (!array_key_exists('cancel', $form_state['values'])) {
module_load_include('inc', 'print', 'print.pages');
$link = print_mail_print_link();
if (!empty($form_state['values']['fld_from_name'])) {
......
......@@ -291,6 +291,8 @@ function _print_mail_access($permission) {
*
* @return string
* string with the HTML link to the printer-friendly page
*
* @ingroup print_api
*/
function print_mail_insert_link($path = NULL, $node = NULL) {
if (function_exists('print_ui_insert_link')) {
......@@ -407,7 +409,7 @@ function print_mail_rules_action_info() {
* @ingroup rules
*/
function print_mail_action_submit($node, $settings) {
require_once(DRUPAL_ROOT . '/' . drupal_get_path('module', 'print_mail') . '/print_mail.inc');
module_load_include('inc', 'print_mail', 'print_mail');
$form_state['values'] = array(
'path' => 'node/' . $node['node']->nid,
......
<?php
/**
* @file
* Contains the administrative functions of the print_pdf_dompdf sub-module.
*
* This file is included by the print_pdf_dompdf module, and includes the
* settings form.
*
* @ingroup print
*/
/**
* Form constructor for the dompdf options settings form.
*
* @ingroup forms
*/
function print_pdf_dompdf_settings() {
$form['settings'] = array(
'#type' => 'fieldset',
'#title' => t('dompdf options'),
);
$form['settings']['print_pdf_dompdf_unicode'] = array(
'#type' => 'checkbox',
'#title' => t("Use dompdf's Unicode Mode"),
'#default_value' => variable_get('print_pdf_dompdf_unicode', PRINT_PDF_DOMPDF_UNICODE_DEFAULT),
'#description' => t("If enabled, dompdf's Unicode mode is used. If not, the module will attempt to convert some non-ASCII chars to ISO-8859-1."),
);
$form['settings']['print_pdf_dompdf_font_subsetting'] = array(
'#type' => 'checkbox',
'#title' => t('Enable font subsetting'),
'#default_value' => variable_get('print_pdf_dompdf_font_subsetting', PRINT_PDF_DOMPDF_FONT_SUBSETTING_DEFAULT),
'#description' => t('Only embed those font characters that are actually used. This can generates smaller PDF files but may significantly slow down processing.'),
);
return system_settings_form($form);
}
name = "dompdf library handler"
description = "PDF generation library using dompdf."
core=7.x
package = "Printer, email and PDF versions"
dependencies[] = print_pdf
files[] = print_pdf_dompdf.module
files[] = print_pdf_dompdf.admin.inc
files[] = print_pdf_dompdf.pages.inc
files[] = print_pdf_dompdf.install
configure = admin/config/user-interface/print/pdf/dompdf
<?php
/**
* @file
* Install, update and uninstall functions for the print_pdf_dompdf module.
*
* @ingroup print
*/
/**
* Implements hook_uninstall().
*/
function print_pdf_dompdf_uninstall() {
variable_del('print_pdf_dompdf_unicode');
variable_del('print_pdf_dompdf_font_subsetting');
}
<?php
/**
* @file
* Generate a PDF for the print_pdf module using the dompdf library.
*
* @ingroup print
*/
define('PRINT_PDF_DOMPDF_UNICODE_DEFAULT', 0);
define('PRINT_PDF_DOMPDF_FONT_SUBSETTING_DEFAULT', FALSE);
/**
* Implements hook_theme().
*/
function print_pdf_dompdf_theme() {
return array(
'print_pdf_dompdf_footer' => array(
'variables' => array('html' => ''),
'file' => 'print_pdf_dompdf.pages.inc',
),
);
}
/**
* Implements hook_menu().
*/
function print_pdf_dompdf_menu() {
$items = array();
$items['admin/config/user-interface/print/pdf/dompdf'] = array(
'title' => 'dompdf',
'description' => 'Configure the dompdf options.',
'page callback' => 'drupal_get_form',
'page arguments' => array('print_pdf_dompdf_settings'),
'access arguments' => array('administer print'),
'type' => MENU_LOCAL_TASK,
'file' => 'print_pdf_dompdf.admin.inc',
);
return $items;
}
/**
* Implements hook_requirements().
*/
function print_pdf_dompdf_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)) {
$tool = explode('|', $print_pdf_pdf_tool);
if (is_file($tool[1]) && is_readable($tool[1])) {
if (basename($tool[1]) == 'dompdf_config.inc.php') {
$version = _print_pdf_dompdf_version($tool[1]);
$requirements['print_pdf_tool_version'] = array(
'title' => $t('Printer, email and PDF versions - PDF generation library'),
'value' => $t('dompdf') . ' ' . $version,
);
if (variable_get('print_pdf_autoconfig', PRINT_PDF_AUTOCONFIG_DEFAULT)) {
$directory = dirname($tool[1]) . '/lib/fonts';
if (!is_dir($directory) || !is_writable($directory)) {
$requirements['print_pdf_tool'] = array(
'title' => $t('DOMPDF font cache directory'),
'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' => 'dompdf', '%libdir' => $directory)),
'severity' => REQUIREMENT_ERROR,
);
}
}
}
}
}
break;
}
return $requirements;
}
/**
* Find out the version of the dompdf library
*
* @param string $pdf_tool
* Filename of the tool to be analysed.
*
* @return string
* version number of the tcpdf library
*/
function _print_pdf_dompdf_version($pdf_tool) {
require_once(DRUPAL_ROOT . '/' . $pdf_tool);
// Poor man's way to find dompdf version
if (!defined('DOMPDF_DIR')) {
return 'unknown';
}
else if (!defined('DOMPDF_CHROOT')) {
return '0.5.1';
}
elseif (!defined('DOMPDF_FONT_CACHE')) {
return '0.5.2';
}
elseif (!defined('DOMPDF_LOG_OUTPUT_FILE')) {
return '0.6.0 beta1';
}
elseif (!defined('DOMPDF_ADMIN_USERNAME')) {
return '0.6.0 beta2';
}
else {
return '0.6.0 beta3';
}
}
/**
* Implements hook_print_pdf_available_libs_alter().
*/
function print_pdf_dompdf_print_pdf_available_libs_alter(&$pdf_tools) {
$tools = _print_scan_libs('dompdf', '!^dompdf_config.inc.php$!');
foreach ($tools as $tool) {
$pdf_tools['print_pdf_dompdf|' . $tool] = 'dompdf (' . dirname($tool) . ')';
}
}
<?php
/**
* @file
* Generates the PDF version using dompdf
*
* This file is included by the print_pdf_dompdf module and includes the
* functions that interface with the dompdf library
*
* @ingroup print
*/
/**
* Implements hook_print_pdf_generate().
*/
function print_pdf_dompdf_print_pdf_generate($html, $meta, $filename = NULL) {
$pdf_tool = explode('|', variable_get('print_pdf_pdf_tool', PRINT_PDF_PDF_TOOL_DEFAULT));
$paper_size = variable_get('print_pdf_paper_size', PRINT_PDF_PAPER_SIZE_DEFAULT);
$page_orientation = variable_get('print_pdf_page_orientation', PRINT_PDF_PAGE_ORIENTATION_DEFAULT);
$content_disposition = variable_get('print_pdf_content_disposition', PRINT_PDF_CONTENT_DISPOSITION_DEFAULT);
$unicode = TRUE;
if (variable_get('print_pdf_autoconfig', PRINT_PDF_AUTOCONFIG_DEFAULT)) {
$unicode = variable_get('print_pdf_dompdf_unicode', PRINT_PDF_DOMPDF_UNICODE_DEFAULT);
$font_subsetting = variable_get('print_pdf_dompdf_font_subsetting', PRINT_PDF_DOMPDF_FONT_SUBSETTING_DEFAULT);
define('DOMPDF_ENABLE_PHP', FALSE);
define('DOMPDF_ENABLE_REMOTE', TRUE);
define('DOMPDF_TEMP_DIR', file_directory_temp());
define('DOMPDF_UNICODE_ENABLED', $unicode);
define('DOMPDF_ENABLE_FONTSUBSETTING', $font_subsetting);
}
require_once(DRUPAL_ROOT . '/' . $pdf_tool[1]);
spl_autoload_register('DOMPDF_autoload');
// Try to use local file access for image files
$html = _print_pdf_file_access_images($html);
// dompdf seems to have problems with something in system.css so let's not use it
$html = preg_replace('!<link.*?modules/system/system.css.*?/>!', '', $html);
$url_array = parse_url($meta['url']);
$protocol = $url_array['scheme'] . '://';
$host = $url_array['host'];
$path = dirname($url_array['path']) . '/';
$dompdf = new DOMPDF();
$dompdf->set_base_path($path);
$dompdf->set_host($host);
$dompdf->set_paper(drupal_strtolower($paper_size), $page_orientation);
$dompdf->set_protocol($protocol);
// dompdf can't handle footers cleanly, so disable the following
// $html = theme('print_pdf_dompdf_footer', array('html' => $html));
// If dompdf Unicode support is disabled, try to convert to ISO-8859-1 and then to HTML entities
if (!$unicode) {
// Convert the euro sign to an HTML entity
$html = str_replace('€', '&#0128;', $html);
// Convert from UTF-8 to ISO 8859-1 and then to HTML entities
if (function_exists('utf8_decode')) {
$html = utf8_decode($html);
}
// iconv fails silently when it encounters something that it doesn't know, so don't use it
// else if (function_exists('iconv')) {
// $html = iconv('UTF-8', 'ISO-8859-1', $html);
// }
elseif (function_exists('mb_convert_encoding')) {
$html = mb_convert_encoding($html, 'ISO-8859-1', 'UTF-8');
}
elseif (function_exists('recode_string')) {
$html = recode_string('UTF-8..ISO_8859-1', $html);
}
$html = htmlspecialchars_decode(htmlentities($html, ENT_NOQUOTES, 'ISO-8859-1'), ENT_NOQUOTES);
}
// Must get rid of tbody (dompdf goes into recursion)
$html = preg_replace('!<tbody[^>]*?>|</tbody>!i', '', $html);
$dompdf->load_html($html);
$dompdf->render();
if ($filename) {
$dompdf->stream($filename, array('Attachment' => ($content_disposition == 2)));
return TRUE;
}
else {
return $dompdf->output();
}
}
/**
* Format the dompdf footer contents
*
* @param array $vars
* An associative array containing:
* - $html: contents of the body of the HTML from the original node
*
* @return string
* customized HTML text
*
* @ingroup themeable
* @ingroup print_themeable
*/
function theme_print_pdf_dompdf_footer($vars) {
preg_match('!<div class="print-footer">(.*?)</div>!si', $vars['html'], $tpl_footer);
$html = str_replace($tpl_footer[0], '', $vars['html']);
$text = '<script type="text/php">
if (isset($pdf)) {
$font = Font_Metrics::get_font("verdana");;
$size = 10;
$color = array(0,0,0);
$text_height = Font_Metrics::get_font_height($font, $size);
$w = $pdf->get_width();
$h = $pdf->get_height();
$footer = $pdf->open_object();
// Draw a line along the bottom
$y = $h - 25;
$pdf->line(15, $y, $w - 15, $y, $color, 1);
$y += $text_height / 2;
$pdf->page_text(15, $y, \'' . addslashes(strip_tags($tpl_footer[1])) . '\', $font, $size, $color);
$pdf->close_object();
$pdf->add_object($footer, "all");
// Center the text
$width = Font_Metrics::get_text_width("Page 1 of 2", $font, $size);
$pagenumtxt = t("Page !n of !total", array("!n" => "{PAGE_NUM}", "!total" => "{PAGE_COUNT}"));
$pdf->page_text($w - 15 - $width, $y, $pagenumtxt, $font, $size, $color);
}
</script>';
return str_replace("<body>", "<body>" . $text, $html);
}
<?php
/**
* @file
* Contains the administrative functions of the print_pdf_tcpdf sub-module.
*
* This file is included by the print_pdf_tcpdf module, and includes the
* settings form.
*
* @ingroup print
*/
/**
* Form constructor for the TCPDF options settings form.
*
* @ingroup forms
*/
function print_pdf_tcpdf_settings() {
$form['settings'] = array(
'#type' => 'fieldset',
'#title' => t('TCPDF options'),
);
$form['settings']['print_pdf_font_family'] = array(
'#type' => 'textfield',
'#title' => t('Font family'),
'#default_value' => variable_get('print_pdf_font_family', PRINT_PDF_TCPDF_FONT_FAMILY_DEFAULT),
'#size' => 60,
'#maxlength' => 250,
'#description' => t('Set the font family to be used. Examples: %examples.', array('%examples' => 'helvetica, times, courier, dejavusans, dejavuserif, freesans, freeserif, freemono')) . '<br />' .
t("CAUTION: TCPDF embeds the complete font in the generated PDF. If you're not using Unicode, then helvetica or times are safe choices that will keep the PDF small. Unicode fonts can increase the size of the PDF to the 1MB region."),
);
$form['settings']['print_pdf_font_size'] = array(
'#type' => 'textfield',
'#title' => t('Font size'),
'#default_value' => variable_get('print_pdf_font_size', PRINT_PDF_TCPDF_FONT_SIZE_DEFAULT),
'#size' => 2,
'#maxlength' => 3,
'#description' => t('Set the font size to be used for normal text. This is the base value for the scaling applied to other text styles.'),
);
$form['settings']['print_pdf_font_subsetting'] = array(
'#type' => 'checkbox',
'#title' => t('Enable font subsetting'),
'#default_value' => variable_get('print_pdf_font_subsetting', PRINT_PDF_TCPDF_FONT_SUBSETTING_DEFAULT),
'#description' => t('Only embed those font characters that are actually used. This can generates smaller PDF files but may significantly slow down processing.'),
);
$form['#validate'][] = '_print_pdf_tcpdf_settings_validate';
return system_settings_form($form);
}
/**
* Form validation handler for print_pdf_tcpdf_settings().
*
* @see print_pdf_tcpdf_settings()
* @ingroup forms
*/
function _print_pdf_tcpdf_settings_validate($form, &$form_state) {
if ($form_state['values']['print_pdf_font_size'] < 1) {
form_set_error('print_pdf_font_size', t("Font size must be at least 1."));
}
}
name = "TCPDF library handler"
description = "PDF generation library using TCPDF."
core=7.x
package = "Printer, email and PDF versions"
dependencies[] = print_pdf
files[] = print_pdf_tcpdf.module
files[] = print_pdf_tcpdf.admin.inc
files[] = print_pdf_tcpdf.pages.inc
files[] = print_pdf_tcpdf.install
configure = admin/config/user-interface/print/pdf/tcpdf
<?php
/**
* @file
* Install, update and uninstall functions for the print_pdf_tcpdf module.
*
* @ingroup print
*/
/**
* Implements hook_uninstall().
*/
function print_pdf_tcpdf_uninstall() {
variable_del('print_pdf_font_family');
variable_del('print_pdf_font_size');
variable_del('print_pdf_font_subsetting');
}
<?php
/**
* @file
* Generate a PDF for the print_pdf module using the TCPDF library.
*
* @ingroup print
*/
define('PRINT_PDF_TCPDF_FONT_FAMILY_DEFAULT', 'dejavusans');
define('PRINT_PDF_TCPDF_FONT_SIZE_DEFAULT', 10);
define('PRINT_PDF_TCPDF_FONT_SUBSETTING_DEFAULT', FALSE);
/**
* Implements hook_theme().
*/
function print_pdf_tcpdf_theme() {
return array(
'print_pdf_tcpdf_header' => array(
'variables' => array('pdf' => NULL, 'html' => '', 'font' => array()),
'file' => 'print_pdf_tcpdf.pages.inc',
),
'print_pdf_tcpdf_page' => array(
'variables' => array('pdf' => NULL),
'file' => 'print_pdf_tcpdf.pages.inc',
),
'print_pdf_tcpdf_content' => array(
'variables' => array('pdf' => NULL, 'html' => '', 'font' => array()),
'file' => 'print_pdf_tcpdf.pages.inc',
),
'print_pdf_tcpdf_footer' => array(
'variables' => array('pdf' => NULL, 'html' => '', 'font' => array()),
'file' => 'print_pdf_tcpdf.pages.inc',
),
'print_pdf_tcpdf_footer2' => array(
'variables' => array('pdf' => NULL),
'file' => 'print_pdf_tcpdf.pages.inc',
),
);
}
/**
* Implements hook_menu().
*/
function print_pdf_tcpdf_menu() {
$items = array();
$items['admin/config/user-interface/print/pdf/tcpdf'] = array(
'title' => 'TCPDF',
'description' => 'Configure the TCPDF options.',
'page callback' => 'drupal_get_form',
'page arguments' => array('print_pdf_tcpdf_settings'),
'access arguments' => array('administer print'),
'type' => MENU_LOCAL_TASK,
'file' => 'print_pdf_tcpdf.admin.inc',
);
return $items;
}
/**
* Implements hook_requirements().
*/
function print_pdf_tcpdf_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)) {
$tool = explode('|', $print_pdf_pdf_tool);
if (is_file($tool[1]) && is_readable($tool[1])) {
if (basename($tool[1]) == 'tcpdf.php') {
$version = _print_pdf_tcpdf_version($tool[1]);
if (version_compare($version, '5.9.001', '<')) {
$requirements['print_pdf_tool_version'] = array(
'title' => $t('Printer, email and PDF versions - PDF generation library'),
'value' => $t('Unsupported TCPDF version'),
'description' => $t('The currently selected version of TCPDF (@version) is not supported. Please update to a !url.', array('@version' => $version, '!url' => l($t('newer version'), 'http://sourceforge.net/projects/tcpdf/files/latest'))),
'severity' => REQUIREMENT_ERROR,
);
}
else {
$requirements['print_pdf_tool_version'] = array(
'title' => $t('Printer, email and PDF versions - PDF generation library'),
'value' => $t('TCPDF') . ' ' . $version,
);
}
if (variable_get('print_pdf_autoconfig', PRINT_PDF_AUTOCONFIG_DEFAULT)) {
foreach (array('cache', 'images') as $dir) {
$directory = dirname($tool[1]) . '/' . $dir;
if (!is_dir($directory) || !is_writable($directory)) {
$requirements['print_pdf_tool_' . $dir] = array(
'title' => $t('TCPDF directory'),
'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' => 'TCPDF', '%libdir' => $directory)),
'severity' => REQUIREMENT_ERROR,
);
}
}
}
}
}
}
break;
}
return $requirements;
}
/**
* Find out the version of the TCPDF library
*
* @param string $pdf_tool
* Filename of the tool to be analysed.
*
* @return string
* version number of the tcpdf library
*/
function _print_pdf_tcpdf_version($pdf_tool) {
if (variable_get('print_pdf_autoconfig', PRINT_PDF_AUTOCONFIG_DEFAULT)) {
// prevent TCPDF default configs
define('K_TCPDF_EXTERNAL_CONFIG', TRUE);
}
require_once(DRUPAL_ROOT . '/' . $pdf_tool);