Let the platform do the work

SugarPDF

Overview

An overview of SugarPDF and how it relates to TCPDF. As of version 6.7.x, Sugar includes a Smarty template engine called PDF Manager that is accessible by navigating to Admin > PDF Manager. The PDF Manager allows administrators to create and manage templates for deployed modules without having to write custom code.  The following sections are only specific to developers looking to create their own custom TCPDF templates using PHP.

PDF Classes

The various classes used in generating PDFs within Sugar.

TCPDF

Sugar uses the TCPDF 4.6.013 library, located in ./vendor/tcpdf/, as the core engine to generate PDFs. This library is extended by Sugarpdf which is used by the core application to generate PDFs. 

Sugarpdf

The Sugarpdf class, located in ./include/Sugarpdf/Sugarpdf.php, extends the TCPDF class. Within this class, we have overridden certain functions to integrate sugar features. Some key methods that were overridden are listed below: 

Method Description
Header Overridden to enable custom logos.
SetFont Overridden to allow for the loading of custom fonts. The custom fonts direction is defined by the K_PATH_CUSTOM_FONTS var. By default, this value is set to ./custom/vendor/tcpdf/fonts/
Cell Overridden to apply the prepare_string() function. This allows for the ability to clean the string before sending to PDF.  

Some key additional methods that were added are listed below:

Method Description
predisplay Preprocessing before the display method is called. Is intended to setup general PDF document properties like margin, footer, header, etc.
display Performs the actual PDF content generation. This is where the logic to display output to the PDF should be placed.
process Calls predisplay and display.
writeCellTable Method to print a table using the cell print method of TCPDF
writeHTMLTable Method to print a table using the writeHTML print method of TCPDF

Custom PDF classes that extend Sugarpdf can be located in the following directories:

  • ./include/Sugarpdf/sugarpdf/sugarpdf.<pdf view>.php
  • ./modules/<module>/sugarpdf/sugarpdf.<pdf view>.php
  • ./custom/modules/<module>/sugarpdf/sugarpdf.<pdf view>.php

PDF Manager classes that extend Sugarpdf are located in the following directories:

  • ./include/Sugarpdf/sugarpdf/sugarpdf.smarty.php
  • ./include/Sugarpdf/sugarpdf/sugarpdf.pdfmanager.php
  • ./custom/include/Sugarpdf/sugarpdf/sugarpdf.pdfmanager.php

Each extended class will define a specific PDF view that is accessible with the following URL parameters:

  • module=<module>
  • action=sugarpdf
  • sugarpdf=<pdf view>

Within each custom PDF class, the display method will need to be redefined. If you would like, It is also possible to override other methods like Header. The process method of this class will be called from ViewSugarpdf. When a PDF is being generated, the most relevant sugarpdf.<pdf action>.pdf class is determined by the SugarpdfFactory.

ViewSugarpdf

The ViewSugarpdf class, located in ./include/MVC/View/views/view.sugarpdf.php, is used to create the SugarViews that generate PDFs. These views can be found and/or created in one of the following directory paths:

  • ./modules/<module>/views/view.sugarpdf.php
  • ./custom/modules/<module>/views/view.sugarpdf.php

SugarViews can be called by navigating to a URL in the format of:

http://<url>/index.php?module=<module>&action=sugarpdf&sugarpdf=<pdf action>

As of 6.7, PDFs are mainly generated using the PDF Manager templating system. To generate the PDF stored in the PDF Manager, you would call a URL in the format of:

http://<url>/index.php?module<module>&record=<record id>&action=sugarpdf&sugarpdf=pdfmanager&pdf_template_id=<template id>  

SugarpdfFactory

The ViewSugarpdf class uses the SugarpdfFactory class, located in ./include/Sugarpdf/SugarpdfFactory.php, to find the most relevant sugarpdf.<pdf action>.pdf class which generates the PDF document for a given PDF view and module. If one is not found, then the core Sugarpdf class is used.

The SugarpdfFactory class loads the first class found for the specified PDF action as determined by the following order:

  • ./custom/modules/<module>/sugarpdf/sugarpdf.<pdf view>.php
  • ./modules/<module>/sugarpdf/sugarpdf.<pdf view>.php
  • ./custom/include/Sugarpdf/sugarpdf/sugarpdf.<pdf view>.php
  • ./include/Sugarpdf/sugarpdf/sugarpdf.<pdf view>.php
  • ./include/Sugarpdf/sugarpdf.php

SugarpdfHelper

The SugarpdfHelper, located in ./include/Sugarpdf/SugarpdfHelper.php, is included by Sugarpdf. This is a utility file that contains many of the functions we use to generate PDFs.
Available functions are:

  • wrapTag, wrapTD, wrapTable, etc. : These functions help to create an HTML code.
  • prepare_string : This function prepare a string to be ready for the PDF printing.
  • format_number_sugarpdf : This function is a copy of format_number() from currency with a fix for sugarpdf.

PdfManagerHelper

The PdfManagerHelper, located in ./modules/PdfManager/PdfManagerHelper.php, is primarily utilized by the pdfmanager Sugarpdf view. This class file contains methods useful for accessing PDF Manager templates. Some of the primary methods are:

  • getAvailableModules : Returns an array of available modules for use with PdfManager.
  • getFields : Takes an module name and returns a list of fields and links available for this module in PdfManager.
  • getPublishedTemplatesForModule : Returns an array of the available templates for a specific module.

FontManager

The FontManagerclass, located in ./include/Sugarpdf/FontManager.php, is a stand-alone class that manages all the fonts for TCPDF. More information can be found in the PDF Fonts section below.

Functionality:

  • List all the available fonts from the OOB font directory and the custom font directory (it can create a well-formatted list for select tag).
  • Get the details of each listed font (Type, size, encoding,...) by reading the font php file.
  • Add a new font to the custom font directory from a font file and a metric file.
  • Delete a font from the custom font directory.

Generating a PDF

To generate a custom PDF in Sugar, you will need to create a PDF view that extends the Sugarpdf class. To accomplish this, create the file:

 ./custom/modules/<module>/sugarpdf/sugarpdf.<pdf view>.php

  <?php

if(!defined('sugarEntry') || !sugarEntry) die('Not A Valid Entry Point');

require_once('include/Sugarpdf/Sugarpdf.php');

class <module>Sugarpdf<pdf view> extends Sugarpdf
{
    /**
     * Override
     */
    function process(){
        $this->preDisplay();
        $this->display();
        $this->buildFileName();
    }

    /**
     * Custom header
     */
    public function Header()
    {
        $this->SetFont(PDF_FONT_NAME_MAIN, 'B', 16);
        $this->MultiCell(0, 0, 'TCPDF Header',0,'C');
        $this->drawLine();
    }

    /**
     * Custom header
     */
    public function Footer()
    {
        $this->SetFont(PDF_FONT_NAME_MAIN, '', 8);
        $this->MultiCell(0,0,'TCPDF Footer', 0, 'C');
    }

    /**
     * Predisplay content
     */
    function preDisplay()
    {
        //Adds a predisplay page
        $this->AddPage();
        $this->SetFont(PDF_FONT_NAME_MAIN,'',PDF_FONT_SIZE_MAIN);
        $this->Ln();
        $this->MultiCell(0,0,'Predisplay Content',0,'C');
    }

    /**
     * Main content
     */
    function display()
    {
        //add a display page
        $this->AddPage();
        $this->SetFont(PDF_FONT_NAME_MAIN,'',PDF_FONT_SIZE_MAIN);
        $this->Ln();
        $this->MultiCell(0,0,'Display Content',0,'C');
    }

    /**
     * Build filename
     */
    function buildFileName()
    {
        $this->fileName = 'example.pdf';
    }

    /**
     * This method draw an horizontal line with a specific style.
     */
    protected function drawLine()
    {
        $this->SetLineStyle(array('width' => 0.85 / $this->getScaleFactor(), 'cap' => 'butt', 'join' => 'miter', 'dash' => 0, 'color' => array(220, 220, 220)));
        $this->MultiCell(0, 0, '', 'T', 0, 'C');
    }
}

This file will contain the markup for the PDF. The main things to note are the Header(), Footer() and display() methods as they contain most of the styling and display logic. The method buildFileName() will generate the document's name when downloaded by the user.

Once in place, navigate to Admin > Repair > Quick Repair and Rebuild. The PDF will now be accessible by navigating to the following url in your browser:

http://{sugar url}/index.php?module=<module>&action=sugarpdf&sugarpdf=<pdf action>

PDF Settings

This section will outline how to configure the PDF settings. These settings determine the widths, heights, images, pdf metadata, and the UI configurations found in:

Admin > PDF Manager > Edit Report PDF Template 

Settings

The default PDF settings for TCPDF can be found in ./include/Sugarpdf/sugarpdf_default.php. You can add additional custom settings by creating the following file:

./custom/include/Sugarpdf/sugarpdf_default.php

  <?php

$sugarpdf_default["PDF_NEW_SETTING"] = "Value";

You should note that values specified here will be the default values. Once edited, the updated values are stored in the database config table under the category "sugarpdf" and a name matching the setting name.

category: sugarpdf
name: pdf_new_setting
value: Value

Displaying and Editing Settings

A select set of settings can be edited within the Sugar UI by navigating to:

  Admin > PDF Manager > Edit Report PDF Template

The settings here are managed in the file ./modules/Configurator/metadata/SugarpdfSettingsdefs.php. A brief description of the settings parameters are listed below:

  • label : This is the display label for the setting.
  • info_label : Hover info text for the display label.
  • value : The PDF Setting.
  • class : Determines which panel the setting resides in. Possible values are 'basic' and 'logo'. 'advanced' is not currently an available value.
  • type : Determines the settings display widget. Possible values are: 'image', 'text', 'percent', 'multiselect', 'bool', 'password', and 'file'.

Custom settings can be added to this page by creating ./custom/modules/Configurator/metadata/SugarpdfSettingsdefs.php and specifying a new setting index. An example is below:

./custom/modules/Configurator/metadata/SugarpdfSettingsdefs.php

  <?php

    //Retrieve setting info from db
    defineFromConfig("PDF_NEW_SETTING", $sugarpdf_default["PDF_NEW_SETTING"]);

    //Add setting display
    $SugarpdfSettings['sugarpdf_pdf_new_setting'] = array(
        "label" => $mod_strings["LBL_PDF_NEW_SETTING_TITLE"],
        "info_label" => $mod_strings["LBL_PDF_NEW_SETTING_INFO"],
        "value" => PDF_NEW_SETTING,
        "class" => "basic",
        "type" => "text",
    );

You should note that the $SugarpdfSettings index should following the format sugarpdf_pdf_<setting name>. If your setting does not follow this format, it will not be saved or retrieved from the database correctly.

Once the setting is defined, you will need to define the display text for the UI setting.

./custom/modules/Configurator/language/en_us.lang.php

Once finished, navigate to Admin > Repair > Quick Repair and Rebuild. This will rebuild the language files for your display text.

PDF Fonts

The stock fonts for TCPDF are stored in the directory ./vendor/tcpdf/fonts/. If you would like to add additional fonts to the system, they should be added to the ./custom/vendor/tcpdf/fonts/ directory.

Font Cache

The font list is built by the font manager with the listFontFiles() or getSelectFontList() methods. The list is then saved in the cache as ./cache/Sugarpdf/cachedFontList.php. This caching process prevents unnecessary parsing of the fonts folder. The font cache is automatically cleared when the delete() or add() methods are used. When you create a module loader package to install fonts you will have to call the clearCachedFile() method in a post_execute and post_uninstall action in the manifest.php to clear the font cache.