You are here

entity_print.module in Entity Print 7

Same filename and directory in other branches
  1. 8.2 entity_print.module
  2. 8 entity_print.module

Print any entity.

File

entity_print.module
View source
<?php

/**
 * @file
 * Print any entity.
 */
define('ENTITY_PRINT_CSS_GROUP', CSS_THEME);

/**
 * Implements hook_entity_print().
 */
function entity_print_menu() {
  $items['entityprint/%/%'] = array(
    'title' => 'Print PDF',
    'page callback' => 'entity_print_entity_to_pdf',
    'page arguments' => array(
      1,
      2,
    ),
    'type' => MENU_CALLBACK,
    'access callback' => 'entity_print_access',
    'access arguments' => array(
      1,
      2,
    ),
  );
  $items['entityprint/%/%/debug'] = array(
    'title' => 'Print PDF Debug',
    'page callback' => 'entity_print_entity_debug',
    'page arguments' => array(
      1,
      2,
    ),
    'type' => MENU_CALLBACK,
    'access callback' => 'entity_print_access',
    'access arguments' => array(
      1,
      2,
    ),
  );
  $items['admin/config/content/entityprint'] = array(
    'title' => 'Entity Print',
    'description' => 'Configure the settings for Entity Print.',
    'page callback' => 'drupal_get_form',
    'page arguments' => array(
      'entity_print_settings_form',
    ),
    'type' => MENU_NORMAL_ITEM,
    'access arguments' => array(
      'administer entity print',
    ),
    'file' => 'entity_print.admin.inc',
  );
  return $items;
}

/**
 * Validate that the current user has access.
 *
 * We need to validate that the user is allowed to access this entity also the
 * print version.
 *
 * @param string $entity_type
 *   The entity type.
 * @param int $entity_id
 *   The entity id.
 *
 * @return bool
 *   TRUE if they have access otherwise FALSE.
 */
function entity_print_access($entity_type, $entity_id) {

  // Check for overall entity access permission.
  if (user_access('bypass entity print access')) {
    return entity_print_view_access($entity_type, $entity_id);
  }

  // Check for entity type access permission.
  if (user_access('entity print access type ' . $entity_type)) {
    return entity_print_view_access($entity_type, $entity_id);
  }

  // Check for entity bundle access permission.
  $entity = entity_load_single($entity_type, $entity_id);
  list($id, $vid, $bundle) = entity_extract_ids($entity_type, $entity);
  if (user_access('entity print access bundle ' . $bundle)) {
    return entity_print_view_access($entity_type, $entity_id);
  }
  return FALSE;
}

/**
 * Function to check for entity view permission.
 */
function entity_print_view_access($entity_type, $entity_id) {
  if ($entities = entity_load($entity_type, array(
    $entity_id,
  ))) {
    $entity = array_pop($entities);
    return entity_access('view', $entity_type, $entity);
  }
  return FALSE;
}

/**
 * Output an entity as a PDF.
 *
 * @param string $entity_type
 *   The entity type.
 * @param int $entity_id
 *   The entity id.
 */
function entity_print_entity_to_pdf($entity_type, $entity_id) {
  if ($entities = entity_load($entity_type, array(
    $entity_id,
  ))) {
    $library = libraries_load('phpwkhtmltopdf');
    if (!empty($library['loaded'])) {
      $pdf = new WkHtmlToPdf(array(
        'binary' => variable_get('entity_print_wkhtmltopdf', '/usr/local/bin/wkhtmltopdf'),
      ));
      $entity = reset($entities);
      $html = _entity_print_get_generated_html($entity_type, $entity);

      // Add a HTML file, a HTML string or a page from a URL.
      $pdf
        ->addPage($html);

      // Allow other modules to alter the generated PDF object.
      drupal_alter('entity_print_pdf', $pdf, $entity_type, $entity);
      if (!$pdf
        ->send()) {
        print $pdf
          ->getError();
      }
    }
    else {
      print $library['error message'];
    }
  }
}

/**
 * A debug callback for styling up the PDF.
 *
 * @param string $entity_type
 *   The entity type.
 * @param int $entity_id
 *   The entity id.
 */
function entity_print_entity_debug($entity_type, $entity_id) {
  if ($entities = entity_load($entity_type, array(
    $entity_id,
  ))) {
    $entity = reset($entities);
    print _entity_print_get_generated_html($entity_type, $entity);
  }
}

/**
 * Generate the HTML for our entity.
 *
 * @param string $entity_type
 *   The entity type.
 * @param object $entity
 *   The entity we're rendering.
 *
 * @return string
 *   The generate HTML.
 *
 * @throws \Exception
 */
function _entity_print_get_generated_html($entity_type, $entity) {
  $info = entity_get_info($entity_type);
  $entity_id = $entity->{$info['entity keys']['id']};
  $html_array = entity_view($entity_type, array(
    $entity,
  ), 'pdf');

  // Inject some generic CSS across all templates.
  if (variable_get('entity_print_default_css', TRUE)) {
    entity_print_add_css(drupal_get_path('module', 'entity_print') . '/css/entity-print.css');
  }

  // Inject CSS from the theme info files.
  $entity_print_css = _entity_print_get_css($entity_type, $entity, $info);
  return theme('entity_print__' . $entity_type . '__' . $entity_id, array(
    'entity_array' => $html_array,
    'entity' => $entity,
    'entity_print_css' => $entity_print_css,
  ));
}

/**
 * Inject the relevant css for the template.
 *
 * You can specify CSS files to be included per entity type and bundle in your
 * themes css file. This code uses your current theme which is likely to be the
 * front end theme.
 *
 * Examples:
 *
 * entity_print[all] = 'css/all-pdfs.css'
 * entity_print[commerce_order][all] = 'css/orders.css'
 * entity_print[node][article] = 'css/article-pdf.css'
 *
 * @param string $entity_type
 *   The entity type to add the css for.
 * @param object $entity
 *   The entity object.
 * @param array $entity_info
 *   The entity info from entity_get_info().
 *
 * @return array
 *   An array of stylesheets to be used for this template.
 */
function _entity_print_get_css($entity_type, $entity, $entity_info) {

  // Allow other modules to add their own CSS.
  module_invoke_all('entity_print_css', $entity_type, $entity);
  global $theme;
  $theme_path = drupal_get_path('theme', $theme);
  $theme_info = drupal_parse_info_file($theme_path . "/{$theme}.info");

  // Parse out the CSS from the theme info.
  if (isset($theme_info['entity_print'])) {

    // See if we have the special "all" key which is added to every PDF.
    if (isset($theme_info['entity_print']['all'])) {
      entity_print_add_css("{$theme_path}/" . $theme_info['entity_print']['all']);
      unset($theme_info['entity_print']['all']);
    }
    foreach ($theme_info['entity_print'] as $key => $value) {

      // If the entity type doesn't match just skip.
      if ($key !== $entity_type) {
        continue;
      }

      // Parse our css files per entity type and bundle.
      foreach ($value as $css_bundle => $css) {

        // If it's magic key "all" add it otherwise check the bundle.
        if ($css_bundle === 'all' || $entity->{$entity_info['entity keys']['bundle']} === $css_bundle) {
          entity_print_add_css("{$theme_path}/{$css}");
        }
      }
    }
  }

  // Grab all the css files and filter by group so we only have css defined to
  // be used in entity print.
  $entity_print_css = array_filter(drupal_add_css(), function ($a) {
    return $a['group'] === ENTITY_PRINT_CSS_GROUP;
  });
  return $entity_print_css;
}

/**
 * Add a CSS file for entity print.
 *
 * @param string $css_file
 *   Path to the CSS file.
 */
function entity_print_add_css($css_file) {
  drupal_add_css($css_file, array(
    'group' => ENTITY_PRINT_CSS_GROUP,
  ));
}

/**
 * Implements hook_theme().
 */
function entity_print_theme($existing, $type, $theme, $path) {
  return array(
    'entity_print' => array(
      'path' => $path . '/templates',
      'template' => 'entity-print',
      'variables' => array(
        'entity_array' => NULL,
        'entity' => NULL,
        'entity_print_css' => NULL,
      ),
    ),
  );
}

/**
 * Implements hook_permission().
 */
function entity_print_permission() {

  // Administer entity print.
  $permissions['administer entity print'] = array(
    'title' => t('Administer Entity Print'),
    'description' => t('Allow users to administer the Entity Print settings.'),
    // We make this restricted because you can set the path to the wkhtmltopdf
    // binary from the settings page. It isn't vulnerable to injection but
    // it's probably not a setting you want everyone configuring anyway.
    'restrict access' => TRUE,
  );

  // Bypass access.
  $permissions['bypass entity print access'] = array(
    'title' => t('Bypass entity print access'),
    'description' => t('Allow a user to bypass the entity print access rights.'),
  );

  // Create a permission for every entity type and bundle.
  $entities = entity_get_info();
  foreach ($entities as $entity_key => $entity_info) {
    $permissions['entity print access type ' . $entity_key] = array(
      'title' => t('%entity_label: Use entity print for all bundles', array(
        '%entity_label' => $entity_info['label'],
      )),
      'description' => t('Allow a user to use entity print to view the generated PDF for all %entity_label bundles.', array(
        '%entity_label' => $entity_info['label'],
      )),
    );
    foreach ($entity_info['bundles'] as $bundle_key => $entity_bundle) {
      $permissions['entity print access bundle ' . $bundle_key] = array(
        'title' => t('%entity_label (%entity_bundle_label): Use entity print', array(
          '%entity_label' => $entity_info['label'],
          '%entity_bundle_label' => $entity_bundle['label'],
        )),
        'description' => t('Allow a user to use entity print to view the generated PDF for entity type %entity_label and bundle %entity_bundle_label', array(
          '%entity_label' => $entity_info['label'],
          '%entity_bundle_label' => $entity_bundle['label'],
        )),
      );
    }
  }
  return $permissions;
}

/**
 * Implements hook_entity_info_alter().
 */
function entity_print_entity_info_alter(&$entity_info) {
  foreach ($entity_info as $type => $info) {
    $entity_info[$type]['view modes']['pdf'] = array(
      'label' => 'PDF',
      'custom settings' => FALSE,
    );
  }
}

Functions

Namesort descending Description
entity_print_access Validate that the current user has access.
entity_print_add_css Add a CSS file for entity print.
entity_print_entity_debug A debug callback for styling up the PDF.
entity_print_entity_info_alter Implements hook_entity_info_alter().
entity_print_entity_to_pdf Output an entity as a PDF.
entity_print_menu Implements hook_entity_print().
entity_print_permission Implements hook_permission().
entity_print_theme Implements hook_theme().
entity_print_view_access Function to check for entity view permission.
_entity_print_get_css Inject the relevant css for the template.
_entity_print_get_generated_html Generate the HTML for our entity.

Constants

Namesort descending Description
ENTITY_PRINT_CSS_GROUP @file Print any entity.