Contents: [hide]

Overview

Output Documents are files generated while running a case, which are meant to be printed out or stored digitally outside ProcessMaker. Output Documents are useful for creating external records of case data, as well as creating formatted documents such as letters, bills and receipts. Output Documents are generated from HTML templates and they can contain variables, which are auto-inserted when the Output Document is generated as a step when running a case. Output Documents are generated as PDF (Portable Document Format) and/or DOC (Word document) files, so they can be easily opened and printed using Adobe Acrobat and Microsoft Office (or alternatives such as Foxit Reader, Evince, Okular, WordPerfect, AbiWord and OpenOffice).

If the Output Document is generated as a PDF file, either the HTML2PDF (an old version of a PDF generator which is no longer recommended) or the TCPDF library can be used to generate the PDF file. "HTML2PDF" can be used if needing to insert some of the formatting options listed below such as page breaks and headers and footers, but "HTML2PDF" has compatibility problems with PHP 5.4.0 and later. In most cases, it is recommended to use the "TCPDF" library which is compatible with more recent versions of PHP. TCPDF is recommended if generated PDFs which contains images or trying to minimize the size of the file, because "HTML2PDF" generates compressed PDF documents, which omit extra parameters in the code, which means that the PDF file will be smaller in size.

Output Document Management

It is possible to see the list of Output Documents created in the project. Click on the "Output Documents" option inside the Main Toolbox:

All the Output Documents will be listed:

Where:

  1. Search Field: Enter the title of an output document in this field. As the text is entered all coincidences will be filtered in the list below.

  2. Create: This option opens the window to create a new Output Document. It is possible to use either this option to create an Output Document or this option.

  3. Show ID: Click on this button to obtain the Unique Identification code of the Output Document. For instance, use this ID to create an Output Document using the PMFGenerateOutputDocument function.

  4. Title: This column describes the title of the output documents created in the project. By default the list is sorted in ascending order, but it is possible to view the list of documents in descending order by clicking on the down triangle next to "Title".

  5. Type: It shows the type of document which always has an HTML format.

  6. Edit: Edit the information about the output document.

  7. Open Editor: It opens the WYSIWYG HTML editor in order to edit the document template:

    Read this documentation to learn how to use the HTML editor.

  8. Delete: Click this option to delete the Output Document. The following confirmation message will be shown:

    Select "Yes" to delete the Output Document and the flash message "Output document deleted successfully" is shown in the upper part of the designer.

  9. Pagination Control: When there are more than 10 documents created in the project, a new page is added to this window. To navigate through these pages use the > or < options. To view a specific page, click on the number of the page of this control.

Creating Output Documents

To create Output Documents, open a project and go to the right side of the screen where the Main Toolbox is located. Hover the pointer of the mouse over the + icon and the "Create" option will display to the left:

Click on the "Create" option and the following window will display:

Where:

  • Title: Adds a title to identify the Output Document.
  • Filename generated: The name of the file to be created when the Output Document is generated while running cases. Note that paths cannot be included in the filename, since Output Documents are stored in a standard location in the file system. To include a system or case variable in the filename, click on the [@@] button and select a variable.
  • Description: An small description about the document which should inform the user what is the general content or purpose of the document.
  • Report Generator: Choose the engine Output Documents will use to be generated. Use HTML2PDF if using versions earlier than 2.5 (either way remember that this option is not compatible with PHP 5.4), otherwise use "TCPDF" if using versions 3.0 or above
  • Media: Select the paper size:
    Paper TypeWidth (mm)Height (mm)
    Letter216279
    Legal216357
    Executive184267
    B5182257
    Folio216330
    A0Oversize8821247
    A08411189
    A1594841
    A2420594
    A3297420
    A4210297
    A5148210
    A6105148
    A774105
    A85274
    A93752
    A102637
    Screenshot640640480
    Screenshot800800600
    Screenshot10241024768
  • Left: Size of the paper's left margin in mm.
  • Right: Size of the paper's right margin in mm.
  • Top: Size of the paper's top margin in mm.
  • Bottom: Size of the paper's bottom margin in mm.
  • Output Document to Generate: Select whether the Output Document will be generated in DOC, PDF, or BOTH formats.
  • PDF Security: An option which allows passwords to be set for the generated PDF document and restricts how it may be used. Select one of the following options:
    • Disabled: Default. No security will be applied to the generated PDF document.
    • Enabled: If selected, the following security options are displayed:
      • Open Password: Define a password to open the PDF document.
      • Owner Password: Define a password to change the PDF document's permissions.
      • Allowed Permissions: Select how the PDF document may be used. To select more than one option, hold down on the CTRL key while clicking the following options:
        • Print: The document can be printed.
        • Modify: The document can be edited.
        • Copy: The document can be copied.
        • Forms: The fields in the document may be filled in.
  • Enable Versioning: Present a dropdown with two options which are "Yes" and "No". If "Yes" is chosen then the document will keep multiple versions of the Output Document. Versioning is useful if creating the same Output Document at multiple steps during a case. This option allows a record to be kept of how the document's data changes over the course of a case, which is useful for maintaining audit trails.
  • Destination Path: Enter the name of the folder where this Output Document should be displayed. Click on the [@@] button to select a variable which will be used in the folder name. To specify a subfolder inside other folders, enter a path to that folder, separating each folder with a / (forward slash). For example: Invoices/@#USR_USERNAME/@#subject_@#date
    To see a list of Input Documents, Output Documents and attached files found in each folder, go to HOME > Documents and click on the folder.
    Note: The Destination Path is a virtual path and it does not effect where output documents are stored in the file system. All files for cases will be stored inside the path where ProcessMaker has been installed.
  • Tags: Enter the name of the identifying tag(s), which will be associated with this Output Document. To specify more than one tag name, separate each tag name with commas. Click on the [@@] button to select a variable which will be used in the tag name. Tags result really useful when looking for Output Documents in the ProcessMaker database.
  • By clicking on the generated file link: Select whether the file will be downloaded or opened in the same browser.
    • Download the file: Download the file directly in the local computer. By choosing this option the browser will select automatically the option to download the file. This is the recommended option when creating Output Documents.
    • Open the file: Open the file in the same browser. By choosing this option the browser will select automatically the option to open the file.

      Note: If selecting this option when configuring an Output Document take into consideration that the browser must be configured differently to open the files downloaded. Therefore, install Adobe Acrobat Reader to be able to open the .pdf files. It is recommended to use the "Download the file" option to avoid the extra configuration that involves this option.

Creating Output Documents Using TCPDF Generator

Usually when PDF Documents are generated with more than 6 pages, they can't be created and downloaded producing an error in the HTML code. To improve the generation of PDF documents, the TCPDF generator was included inside ProcessMaker to allow users the creation and generation of PDF and DOC documents without having issues with the amount of pages created.

This generator supports UTF-8 Unicode and right-to-left languages. Also it has a backward compatibility with documents created on previous versions of ProcessMaker. If documents less than 6 pages needs to be created also is possible to use the HTML2PDF generator. Moreover, this generates compressed documents, without configuring some extra parameters into the code, this means that the PDF document generated will be smaller in size, this is a great enhancement specially if you generate documents with images in them.

When an Output Document is being created, the new generator can be chosen as the image below:

Editing Templates

To edit the template of an Output Document, go to the Main Toolbox and click on "Output Documents". A list of all the templates created for the process will appear there. Select the one that needs to have it's content edited and click on the "Open Editor" button. A new window will open where the document can be changed and corrected in any way that the user wants. There is also an small "HTML" button where the user can click to access HTML code and save it for the document. Once the document is corrected, click on the "Save" button and a quick message will appear ensuring that the document will save all changes made.

Enter the desired text in the Output Document Template. Entering a hard return generates a new paragraph code in the HTML, which inserts a blank line in the text. To enter a line break which doesn't insert a blank line in the text, press SHIFT + ENTER to insert a tag. The editor supports the standard key combinations of CTL + c to copy, CTL + x to cut, and CTL + v to paste. Changes can be undone by pressing CTL + z. Multiple levels of undo are supported. After undoing changes with CTL + z, press CTL + y to redo the changes. When done editing the Output Document template, click Save to store the changes and then click on the close icon to close the editing window.

Inserting Variables

Case variables and system variables can be inserted into the text of an Output Document:

  • @#VARIABLE-NAME inserts the value of the variable without any changes.
  • @@VARIABLE-NAME inserts the value of the variable enclosed in "" (double quotation marks). Any quotation marks inside the value will be escaped with backslashes, such as "Don\'t say \"hello\"".

If a variable is associated with a dropdown box, checkbox, checkgroup, radio group, suggest box, datetime or file control in a DynaForm, then there will be an additional variable named @#VARIABLE-NAME_label which is created when the DynaForm is submitted. This variable holds the label of the selected option, which is displayed to the user, whereas @#VARIABLE-NAME holds the key of the selected option. For example, a variable named "selectService" which is associated with a dropdown box might have a value of "accounting" in its @#selectService variable, but "Accounting and Tax Filing Service" in its @#selectService_label variable. For more information, see Inserting Variables.

Variables can be inserted in the "Output Documents" editing window.

Now for the variables, next to the property Bold there is a variable picker, click on it to chose variables for the empty fields created. Select the variables with the @# signs to add the variables with no changes to the document. For example, Name will have the @#USR_USERNAME variable. Continue to add variable to the other fields and then click on save to store all changes made in the document.

Line Breaks in Textareas

A textarea control allows more than one line of text to be input into a field. But the information of this control is stored in one single line with \n as the representation for each line break, therefore, whenever using the Textarea's variable, the information will be displayed all together on the same line.

To preserve line breaks to show the textarea information in messages, emails, etc. it is recommended to use the nl2br php function within a trigger.

For example, create the following trigger and place it after the Dynaform.

@@textareaVar = nl2br(@@textareaVar);

Remember that to insert the value of a variable without any changes, the prefix @# must be used before the name of the variable, in this case the textarea variable will be @#textareaVar, as explained in the Inserting Variables section.

The function will insert HTML line breaks before all newlines. Therefore, the e-mail will display the variable preserving the line breaks typed in the textarea.

Formatting Output Documents

ProcessMaker includes a new advanced editor for documentation as seen in the image below:

This toolbar provides several options to make the documentation clean. To add formatting to Output Documents the toolbar includes the following buttons:

  • Upload File: Click on this button to upload a file with .html or .htm extension.
  • Variable Picker: Upload a variable by chosing the type and the prefix, to call said variable and open in the document.
  • Bold: Set the selected text to bold (a heavier weight). Shortcut: ctl + b
  • Italics: Set the selected text to italics (inclined text). Shortcut: ctl + i
  • Underline: Underline the selected text. Shortcut: ctl + u
  • Left align: Align the selected text along the left-hand border.
  • Center: Align the selected text in the center.
  • Right align: Align the selected text along the right-hand border.
  • Text Align: Justify the entire selected text.
  • Font: Allows the choosing of many different fonts to change the customize the document.
  • Font Size: Increases or decreases the font size of the selected text.
  • Cut, Copy and Paste: Cut will remove the selected text from its position, while Copy creates a duplicate. Paste copies text and inserts it in the document.
  • Ordered List: Insert an ordered list, which begins counting from 1.
  • Un-ordered List: Insert an unordered list, which uses bullet points instead of numbers.
  • Oudent, Indent, Quote: Outdent and Indent will addition an space of a selected text, outdent will align outside the text and indent will align inside the text. Quote works by selecting a text and aligning the text inside for quotation
  • Table Configuration: Create and edit a table of as many rows and columns as needed, can also insert more rows and columns or delete them. Order the columns of the table split or merged them depending of what is needed.
  • Undo and Redo: Recover or erase different actions made in the document.
  • Links Configuration: A link can either be insert it or edited but also can be unlinked to have only text. An image can also be inserted or edited.

    Note: Take into account that the source of the images inserted must be from a url with the http or a https protocol. This happens because of the editor in which it is not possible to upload a local image, for example. If needing to upload an image from a local resource, first upload it as a Public File and access it using this information.

  • Font Color: Change the color of the selected text.
  • Text Highlight Color: Change the highlight (background) color behind the selected text.
  • Edit CSS Style: A detailed editor for a particular text, where it can be configured manually and specify what does the text need to look like.
  • Format: Use this buttons to add format to the document. Add lines to separate important messages or erase them as well.
  • Subscript and Supscript: With a subscript or superscript a number, figure, symbol, or indicator can be added and it is set slightly below or above it.
  • Direction: The direction can make the text align Right to Left or either Left to Right.
  • HTML: Edit the HTML code for the template.

Be careful to not insert HTML formatting tags inside a variable name, because it will cause the variable to not be recognized by ProcessMaker. For example, if bold tags are inserted inside the variable @#USR_USERNAME, it becomes @#US<b>R_USER</b>NAME. Since, ProcessMaker can't find find the variable @#US, it will print the variable name in the generated Output Document.

Editing the HTML Code

For more control over the formatting of a template and the use of more advanced types of HTML elements such as images or tables, the HTML code can be directly edited by clicking on the "HTML" button on the toolbar. When done editing the HTML code, click on the "Update" button to save it and see the result in the document.

Inserting Images

To insert an image in an Output Document, first upload the image file to the "public" directory in the ProcessMaker server with the Process Files Manager (or another publicly accessible location). Take the ProcessMaker Logo of the wiki page as an example. The URL would be the following "http://wiki.processmaker.com/sites/default/files/full-logo.png"

Now create an Output Document by hovering your mouser over the plus sign next to the option "Output Documents" in the Main Toolbox of the Process Map. The image below shows how the output document should be configured, take into consideration that the field "Report Generator" needs to be on the option "TCPDF" to be able to see images. Click on the "Save" button to create the Output Document and add it to the "Output Documents" window.

Once in the "Output Documents" click on the "Open Editor" button to open a Word-like editor.

Then click on the "HTML" button to open the "HTML Source Editor".

Now add the following code to insert and image:

 
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html>
<head>
</head>
<body>
<p>This is a test for images</p>
<p><img src="http://wiki.processmaker.com/sites/default/files/full-logo.png" /></p>
</body>
</html>

Notice that the "src" or source of the image is the URL of the logo. After adding the code, click on the "Update" button to check is the image was properly uploaded. If the image is seen in the "Edit Output Document" window then it will be seen when running a case.

If there is an error then the following broken image will be shown in the editor. Check the code or image to be able to see it when running a case.

Inserting form fields

To insert form fields inside of an Output Document, edit the HTML code and create an HTML <form>. In that <form>, add <input>, <select>, and/or <submit> fields.

For example, this template code:

<form name="MyFormName">
First Name: <input type="text" name="firstName" size="20" value="Jo Anne"><br>
Last Name: <input type="text" name="lastName" size="20" value="Summers"><br>
<input type="checkbox" name="contactClient" value="contact" checked>Contact Client<br>
<select name="howContact">
    <option value="telephone">Telephone</option>
    <option value="fax" selected>Fax</option>
    <option value="email">Email</option>
 </select><br>
</form>

When Updated the code will look like the image below, allowing the document to run with the user name and the name of the case started.:

Note that these form fields are not interactive, so the content of the fields can not be edited.

Inserting Variables inside Form Fields

System variables and case variables can be inserted inside form fields. For example, to insert the @#USR_USERNAME system variable in a field named "username" and the @#CaseStarted in a field named "timeStarted":

<form name="MyForm">
Current user:<br>
<input type="text" name="username" value="@#USR_USERNAME"><br>
When case started:<br>
<input type="text" name="timeStarted" value="@#CaseStarted"><br>
</form>

Warning: If inserting inside an <input> field, only reference variables as @#variable-name. Do NOT use @@variable-name, because it will insert a set of double quotation marks inside a set of double quotations marks, which will mess up the HTML tag.

For example, this bad template code:

<input type="text" name="username" value="@@USR_USERNAME">

will generate erroneous HTML code like:

<input type="text" name="username" value=""admin"">

Checkboxes in Output Documents

In an Output Document, a checkbox is marked if it has the checked property defined in its HTML code.

This checkbox is marked:

<form name="MyForm">
<input type="checkbox" name="contactClient" value="contact" checked>Contact Client<br>
</form>

This one is not marked because there is no checked property:

<form name="MyForm">
<input type="checkbox" name="contactClient" value="contact">Contact Client<br>
</form>

In order to use a case variable to mark a checkbox in an Output Document, place the case variable in the HTML code like this:

<form name="MyForm">
<input type="checkbox" name="contactClient" value="contact" @#markContactClient >Contact Client<br>
</form>

If the value of @#markContactClient is "checked" then the checkbox will be marked. If it is "" (empty string), then it won't be marked in the Output Document.

Create a trigger which will set the value of @@markContactClient to "checked" or "", depending upon the value of a checkbox in a DynaForm. Set this trigger to fire before the step which generates the Output Document.

For example, if the variable associated with the checkbox control in the DynaForm is "contactClient", then use this PHP code to check whether the checkbox is marked in order to set the value of @@markContactClient.

@@markContactClient = '';
if (isset(@=contactClient) and !empty(@=contactClient) and @=contactClient[0] == 1) {
   @@markContactClient = 'checked';
}

Note: Checkboxes have a value of array(1) if marked or array(0) if unmarked. Checkboxes inside grids are not placed inside arrays, so they have a value of 1 if marked or 0 if unmarked.

Inserting Page Breaks

To insert a page break in both PDF and DOC files, first create the following trigger to define a HTML element that uses its style to force a page break:

@@pageBreak = '<p style="page-break-before: always;">';

This HTML code cannot be placed directly in the Output Document template, because the HTML Editor automatically strips out any style information, so this HTML code needs to be inserted with a case variable in the template. Then, insert the @#pageBreak variable in the template file. For example:

<p>This is page 1.</p>
@#pageBreak
<p>This is page 2.</p>

Make sure to set the trigger that defines @#pageBreak to execute at some point before the Output Document step.

To insert a page break which will only appear in PDF files which are generated using the HTML2PDF library, edit the HTML code of the Output Document and add the HTML comment: <!--NewPage-->

For example, use the following code:

<p>This is page 1.</p>
<!--NewPage-->
<p>This is page 2.</p>

Formatting documents to display content in RTL

The RTL skin is available in version 2.0.44 and later, which allows ProcessMaker to display correctly right-to-left languages such as Arabic and Hebrew. It is also possible to display the contents of Output Documents in right-to-left.

For content inside paragraphs, add dir="RTL" to the <p> tags:

<p dir="RTL">Testing RTL skin and language
  ...
</p>

For content inside tables, add dir="RTL" to the <table> tags:

<table dir="RTL">
  ...
</table>

For example the following Output Document template displays a table in right-to-left:

<p dir="RTL">Invoice Details</p>
<table class="mceItemTable" dir="RTL" border="0" align="right">
<tr>
<td>Reference</td>
<td>Number</td>
</tr>
<tr>
<td>Invoice approval</td>
<td>1</td>
</tr>
</table>

The resulting Output Document will be generated as:.doc document

Grids in Output Documents

The fields from a grid can also be inserted into Output Documents by editing the HTML code. They need to be enclosed inside open and closing tags for the grid. Use the tag @>GRID-NAME to open the grid and @<GRID-NAME to close the grid, where GRID-NAME is the name of a grid object in a master DynaForm. (Do NOT use the name of the separate grid form, only use the field name of the grid object found inside of a master form.) The GRID-NAME can also be an associative array of associative arrays. This array can be a case variable manually defined in a trigger or the value returned by querying a database with executeQuery(). Between these tags, include the variables for the fields in that grid:

A new HTML editor has been introduced, which makes it difficult to insert < and >, so the opening and closing tags for the grid have to be enclosed inside HTML comment tags <!-- ... -->, like this:

<!--@>GRID-NAME--> @#FIELD-1 @#FIELD-2 @#FIELD-3 <!--@<GRID-NAME-->

The fields enclosed in the opening and closing grid tags will be repeated as many times as there are rows in the grid.

For example, if designing a travel expenses report, the following Output Document would list each of the expenses in a grid named "EXPENSE_GRID" which has fields named "DATE", "TYPE", "DESCRIPTION", and "AMOUNT".

<p align="center">Travel Expense Report</p>
<p align="center"><span>@#FIRST_NAME @#LAST_NAME @#REPORT_MONTH </span></p>
<p align="left"></p>
<table border="1" cellspacing="0">
<tbody>
<tr><th>Date</th><th>Type</th><th>Description</th><th>Amount</th></tr>
<!--@>EXPENSE_GRID-->
<tr>
<td>@#DATE</td>
<td>@#TYPE</td>
<td>@#DESCRIPTION</td>
<td>@#AMOUNT</td>
</tr>
<!--@<EXPENSE_GRID--></tbody>
</table>

The HTML Editor will show the code for the grid like the image below:

The Grid will look like the image below when opened in a .pdf document.

Remember that grid names and field names are case sensitive, so they must be spelled exactly as they were defined.

The EXPENSE_GRID could come from a grid DynaForm which has fields named "DATE", "TYPE", "DESCRIPTION" and "AMOUNT". However, it could also be generated by using executeQuery() to query a PM Table, Report Table or an external database. If the database has different field names than those in the Output Document, use "AS" to rename the fields. For example, a trigger containing the following code could be fired before the above Output Document is generated:

 $db = 'XXXXXXXXXXXXXXXXXXXXXXXXXXX'; //Unique ID for an external database
 $query = 'SELECT EXP_DATE AS DATE, EXP_TYPE AS TYPE, EXP_DESC AS DESCRIPTION, EXP_AMT AS AMOUNT FROM EXPENSES';
 @@EXPENSE_GRID = executeQuery($query, $db);

Likewise, the trigger could manually create EXPENSE_GRID as an associative array of associative arrays:

@=EXPENSE_GRID = array(
   '1' => array('DATE'=>'2010-04-25', 'TYPE'=>'Airfare', 'DESCRIPTION'=>'Flight to Paris', 'AMOUNT'=>1295.35),
   '2' => array('DATE'=>'2010-04-26', 'TYPE'=>'Lodging', 'DESCRIPTION'=>'Sheraton Hotel',  'AMOUNT'=>300.00 ),
   '3' => array('DATE'=>'2010-04-27', 'TYPE'=>'Meals',   'DESCRIPTION'=>'Lunch w/ client', 'AMOUNT'=>104.95 )
 );

Grids with a Fixed-Width Font

The default font for Output Documents is Arial, which is a variable-width font. It is hard to create neat columns of data with a variable-width font. Therefore, it is recommended to edit the HTML code and set the grid fields inside <pre>...</pre> tags or <tt>...</tt> tags, so the columns of data will line up in a fixed-width font.

For example:

<center>
Travel Expense Report <br>
@#FIRST_NAME @#LAST_NAME <br>
@#REPORT_MONTH <br>                          
</center>    
<pre>
Date           Type of Expense     Description            Amount
<!--@>EXPENSE_GRID-->
@#DATE         @#TYPE              @#DESCRIPTION          @#AMOUNT
<!--@<EXPENSE_GRID-->
</pre>

Grids inside an HTML Table

For even better formatting of grid data, edit the HTML code and set the the grid inside an HTML table.

Here is an example of the same grid fields inside an HTML table:

In version 2.5.0 and later:

<center>
Travel Expense Report<br>
@#FIRST_NAME @#LAST_NAME<br>
@#REPORT_MONTH
</center>
<br>
<table><tbody>  
<tr>
  <th>Date</th><th>Type Of expense</th><th>Description</th><th>Amount</th>
</tr>
<!--@>EXPENSE_GRID-->
<tr>
  <td>@#DATE</td><td>@#TYPE</td><td>@#DESCRIPTION</td><td>@#AMOUNT</td>
</tr>
<!--@<EXPENSE_GRID-->
</tbody></table>

The result in an Output Document would be:

Editing the HTML in the database

The graphical editor in ProcessMaker strips away unrecognized HTML tags, which can cause changes to the formatting of Output Documents. The only way to get around this problem is to edit the HTML code of Output Document in the database. It can be edited by using PhpMyAdmin to enter the wf_WORKSPACE database in MySQL and then use the Output Document's UID to search for the Output Document's template in the CONTENT table. It can be found with the following query:

SELECT CON_VALUE FROM CONTENT WHERE CON_ID='OUTPUT-DOCUMENT-UID' AND CON_CATEGORY='OUT_DOC_TEMPLATE'

If using PhpMyAdmin, click on the record's Edit link to edit the Output Document's template:

Errors with Output Documents

Error while generating PDF Documents

PHP version 5.3.3 or less must be installed if using the HTML2PDF library to generate PDF documents. Otherwise, a blank page will be generated. If a later version of PHP is installed, use the TCPDF library to generate Output Documents.

Variables are not inserted

If variables are not inserted into an Output Document, then either:

  1. The variable name was not spelled correctly. Remember that system and case variable names are case sensitive. Recheck the spelling by looking at the field name in the DynaForm or the variable name in the Trigger where it was defined.
  2. The case variable doesn't exist when the Output Document was created. If an Output Document references fields from a DynaForm which is used later in the process, then the case variable doesn't yet exist. Also, remember that case variables for each field in a DynaForm are only created when the DynaForm is submitted. If the user clicks on the Next Step link in a DynaForm whose Next Step Link property is set to "No Save & Continue", then none of the data in the DynaForm will be saved.

In order to determine what is the problem, run a case with the Trigger Debugger turned on and check whether the variables exist and what values they contain.

Output Document is empty

If an Output Document is generated which is empty, then there probably wasn't enough session memory to properly generate the document. Large output documents may need more than 80MB of session memory. Try increasing PHP's memory_limit setting.

Error in html2pdf

ProcessMaker uses html2pdf to generate Output Documents in PDF format. If an error message appears about a class in html2pdf saying "out of memory", then the pcre.backtrack_limit setting probably needs to be increased to allow for bigger style definitions, larger template files and deeper levels of nested tables/divs. pcre.backtrack_limit is a new setting introduced in PHP 5.2.0. If using an older version of PHP, upgrade to a newer version which supports the setting.

Edit php.ini, which is the PHP configuration file on the server running ProcessMaker, and add/modify the following line to increase the backtrack_limit:

pcre.backtrack_limit=1000000

Then, restart Apache for the new setting to take effect.

Using Non US-ASCII Characters in Output Documents

If the use of characters inside an Output Document is needed and the generation of this documents needs to be done in HTML2PDF (Old Version) then follow the steps below to be able to open a document with Chinese, Arabic, Japanese and others characters succesfully.

  • 1. Download this file (it will download automatically depending on your browsers configuration) which allows the use of characters inside an Output Document. The file that has been downloaded must be added into the following route in the ProcessMaker installation: [installation path]/gulliver/thidparty/html2ps_pdf/fonts. Remember to give the folder all the corresponding permissions.
  • 2. Create an Output document with the specifications shown in the image below. Notice that the "Report Generator" field will be in "HTML2PDF". Click on the "Save" button to store the document.

  • 3. Once saved, open the editor of the Output Document recently created by clicking on the "Open Editor" button.

  • 4. Add text with chinese characters such as: "This is an example with chinese characters 這是一個用漢字的例子".

  • 5. When a case runs, both .doc and .pdf options will be available. Click on the link to start the download of the documents.

  • 6. Notice that when the documents are opened the characters will be displayed correctly in both .doc and .pdf as seen in the images below.

  • 7.Other characters can also be added to Output Documents.

Inserting Output Documents into a Process

After creating an output document, decide where in a process the Output Document can be submitted. Remember that a task is a group of steps, so an output document must be added in a task. Read this documentation which explains how to add an Output Document as a step

Output Documents Example

Simple Output Documents Example

To create simple Output Documents, go to Output Documents in the main toolbox and click on "Create". A new window will open in which the information about the document must be filled. After filling in all the information that is necessary, save the output document.

Once saved, the "Output Document Example" will appear in the Output Documents list, click on "Open Editor" to write a document in a Word-like environment. After it is saved, a quick message will appear saying the document has been edited succesfully.

After saving it, go to the first task and right click on it to select "Steps" and drag and drop the "Output Documents Example" to be called after the Dynaform.

Now, to see how an Output Document looks when a case is running, go to "Home" > "New Case" and double click on the process that contains the Output Document. In this case, the process "Copy of Purchase Request" is being used as an example. Once the initial information of the client is filled in, the next step is to see the document. As the image below shows, the document is generated in .doc and .pdf.

The image below shows how both documents look in both formats .doc and .pdf.

Output Documents Example with HTML

To create an example with HTML, first create four variables "name" type String, "email" type String, "address" type String and "currentDate" type Datetime. These variables will be stored in all the fields of the DynaForm that we will create next.

Now, create a Dynaform with fields named as the variables to have congruence between the variable, the Dynaform and the soon to be created Output Document. Don't forget to create a "Submit" button to go into the next task.

Save the Dynaform "Order request form" to add it as a step to the task will be working on.

It's time to create an Output Document with the name "Output Documents Example". Locate the button with the "HTML" sign and click on it. It will open an HTML Source Editor where code can be added. Try adding this code for this particular example:

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html>
<head>
</head>
<body>
<p></p>
<div style="font-family: 'Trebuchet MS', Arial, Helvetica, sans-serif; font-size: 13px;">
<p><img src="http://www.processmaker.com/uploads/processmaker_logo_nobg300.png" width="300" height="72" /></p>
<p style="color: #009; font-weight: bold;">NEW YORK<br />Brooklyn, NY, 11238, USA</p>
<p style="text-align: center; text-decoration: underline; font-size: 20px;">PROOF OF PAYMENT</p>
<p>Sent by: @#USR_USERNAME</p>
<p>Name: @#name</p>
<p>Email: @#email</p>
<p>Address: @#address</p>
<p>Current date: @#currentDate</p>
<p>Status: Approved</p>
<p></p>
</div>
</body>
</html>
</body>
</html>

When the code is ready to be executed click on update to save it.

The result of this HTML Code will be:

This example was designed to use variables that will show the saved field of a Dynaform and appear automatically in the output Document. For this, go to the variable picker in the edition window of Output Documents, choose the prefix "@#" because it will insert the value of the variable without any changes. Insert the variable that belongs with each field, as seen in the image below.

After adding all the variables to each field, the Output Document is ready to be assigned to a task. Then, save it, and it will appear in the list with the other documents.

Choose the first task and right click on it to show its properties, click on "Steps" and add the Output Document after completing the Dynaform, as seen in the image below.

To test if it works, go to "Home" > "New Case" and star the process "Copy of Purchase Request" by double clicking it. Fill the information in the form and click "Submit" to see the Output Document.

The next window will show that there is an Output Document before moving on to the next task, and that there are two files generated in .doc and .pdf.

Once "Open" is clicked for either document, an automatic download of the Output Documents will start and will be saved in the Download folder. Open them to see that the document has the information required in the HTML Code and is calling all the variables added in the Dynaform.

Output Document Storage

Output Document Definitions

The definitions of Output Documents are stored in the wf_<WORKSPACE>.OUTPUT_DOCUMENT table in the MySQL database. This table, however, doesn't contain the title, description, template and filename for Output Documents, because this information can be multilingual with a different version for each language. Instead, this information is stored in the wf_<WORKSPACE>.CONTENT table under different ISO 639-1 language codes, such as "en" for English or "es" for Spanish.

To find the title, description, template and filename for Output Documents, enter MySQL (either from the command line or with a graphical program such as phpMyAdmin) or access it through a function such as executeQuery() in a trigger. Search for a value of 'OUT_DOC_TITLE', 'OUT_DOC_DESCRIPTION', 'OUT_DOC_TEMPLATE', and 'OUT_DOC_FILENAME' in the wf_<WORKSPACE>.OUTPUT_DOCUMENT.CON_CATEGORY field. For example, to find all Output Document templates:

SELECT * FROM CONTENT WHERE CON_CATEGORY='OUT_DOC_TEMPLATE'

To find a specific Output Document template, specify its unique ID in the query:

SELECT * FROM CONTENT WHERE CON_CATEGORY='OUT_DOC_TEMPLATE' AND CON_ID='XXXXXXXXXXXXXXXXXXXXXXXXXX';

Use the following SQL query to see all the entries related to Output Documents:

SELECT CON_CATEGORY, CON_ID, CON_LANG FROM CONTENT WHERE CON_CATEGORY LIKE 'OUT_DOC_%'

To see the information about a particular Output Document definition, search for its unique ID, which can either be found in the field wf_<WORKSPACE>.OUTPUT_DOCUMENT.OUT_DOC_UID or by opening the list of Output Documents inside ProcessMaker and clicking the UID link for an Output Document. Once the unique ID is known, it can be used in a SQL query:

SELECT * FROM CONTENT WHERE CON_ID = 'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX'

For example, here is an Output Document defined in both English and Spanish:

mysql> select * from CONTENT where CON_ID = '2136030664a9bfeb8a775d7029704021'; +---------------------+----------------------------------+----------+------------------------------------------------------------+ | CON_CATEGORY | CON_ID | CON_LANG | CON_VALUE | +---------------------+----------------------------------+----------+------------------------------------------------------------+ | OUT_DOC_TEMPLATE | 2136030664a9bfeb8a775d7029704021 | en | Dear @#ClientName,<br>Please open case @#CaseNumber. | | OUT_DOC_TITLE | 2136030664a9bfeb8a775d7029704021 | en | Open Case Letter | | OUT_DOC_DESCRIPTION | 2136030664a9bfeb8a775d7029704021 | en | Letter asking client to open the case | | OUT_DOC_FILENAME | 2136030664a9bfeb8a775d7029704021 | en | OpenCaseLetter | | OUT_DOC_TEMPLATE | 2136030664a9bfeb8a775d7029704021 | es | Estimado @#ClientName,<br>Por favor abra caso @#CaseNumber.| | OUT_DOC_TITLE | 2136030664a9bfeb8a775d7029704021 | es | Carta - Abrir Caso | | OUT_DOC_DESCRIPTION | 2136030664a9bfeb8a775d7029704021 | es | Carta pidiendo que el cliente abra el caso | | OUT_DOC_FILENAME | 2136030664a9bfeb8a775d7029704021 | es | CartaAbrirCaso | +---------------------+----------------------------------+----------+------------------------------------------------------------+

Note that a multilingual Output Document like this can be created by first logging into ProcessMaker in English and creating the Output Document, then logging into ProcessMaker in Spanish and editing the same output document in Spanish.

Output Document Files

When Output Document files are generated while running a case, an HTML file is created based upon the Output Document's template. From that HTML file, a PDF and/or DOC file are created. (Actually the DOC file is really just HTML code inside a DOC container.)

Output Documents files are stored at:

<INSTALL-DIRECTORY>/shared/sites/<WORKSPACE>/files/<CASE-UID>/outdocs/<CASE-FILE-UID>_<VERSION>.<EXTENSION>

The filename of output documents files includes the unique ID for the case file (which is stored in the wf_<WORKFLOW>.APP_DOCUMENT.APP_DOC_UID field) and the version number, which starts counting from 1. Even if versioning isn't enabled, the filename will include "_1".

Linux/UNIX:

<INSTALL-DIRECTORY>/shared/sites/<WORKSPACE>/files/<CASE-UID>/outdocs/<CASE-FILE-UID>_<VERSION>.html /<CASE-FILE-UID>_<VERSION>.pdf /<CASE-FILE-UID>_<VERSION>.doc

Note: The TCPDF library doesn't generate a separate HTML file.

For example:

/opt/processmaker/shared/sites/workflow/files/a03459e1cb9824dac456780eca7b5cf6/outdocs/6663790024dd29d8bcb8212038377266_2.doc

Windows:

<INSTALL-DIRECTORY>\processmaker\shared\<WORKSPACE>\files\<CASE-UID>\outdocs\<CASE-FILE-UID>_<VERSION>.html \<CASE-FILE-UID>_<VERSION>.pdf \<CASE-FILE-UID>_<VERSION>.doc

For example in Windows Vista and later:

C:\Users\Bob\AppData\Roaming\ProcessMaker-2_5_3\processmaker\shared\workflow\files\a03459e1cb9824dac456780eca7b5cf6\outdocs\6663790024dd29d8bcb8212038377266_2.doc

In version 2.5.1 and later, an option was added to allow case files to be stored in a series of 3 subdirectories created from the case's unique ID to avoid the 32K file limits of Linux's ext3 file system. In version 3.0 and later, this option is activated by default. This means that a directory using the case's unique ID, such as /a03459e1cb9824dac456780eca7b5cf6/ in the above example, becomes 3 subdirectories whose names are three characters in the case's unique ID, with the rest of the unique ID placed in the name of another subdirectory:

/opt/processmaker/shared/sites/workflow/files/a03/459/e1c/b9824dac456780eca7b5cf6/outdocs/6663790024dd29d8bcb8212038377266_2.doc

If accessing an Output Document file from a ProcessMaker trigger or plugin, it is recommended to use the defined constant PATH_DOCUMENT, to set the location of the case files, such as "/opt/processmaker/shared/sites/workflow/files/" on a Linux/UNIX system, and PATH_SEP, which is "/" on Linux/UNIX systems and "\" on Windows systems to separate directories in the file system. The G::getPathFromUID() method may be used in version 2.5.1 or later to break a unique ID number into subdirectories in this way if the system requires it. For example to get an Output Document file with the case-file ID of 6960198894e6927e0a40b14004833875 and the version number 2 in the current case:

$OutDocPath = PATH_DOCUMENT . G::getPathFromUID(@@APPLICATION) . PATH_SEP . "outdocs" . PATH_SEP . "6960198894e6927e0a40b14004833875_2.pdf";
If unsure if in version 2.5.1 or later, then use method_exists() to check whether G::getPathFromUID() exists before calling it.
$caseId = 'a03459e1cb9824dac456780eca7b5cf6';
$caseIdPath = method_exists(G, "getPathFromUID") ? G::getPathFromUID($caseId) : $caseId;
$OutDocPath = PATH_DOCUMENT . $caseIdPath . PATH_SEP . "outdocs" . PATH_SEP . "6960198894e6927e0a40b14004833875_2.pdf";

Changing the File Location

If needing to store Input and Output Document files in a different location, such as a NAS, then copy the contents of the files directory to the new location and then edit the source code in workflow/public_html/sysGeneric.php and change the location of PATH_DOCUMENT, which is defined at line 332:

 define( 'PATH_DOCUMENT', PATH_DATA_SITE . 'files/' );

For example, to store files on an NAS mounted drive at /media/nas/processmaker:

define( 'PATH_DOCUMENT', '/media/nas/processmaker/' );

Make sure to include the forward slash in Linux/UNIX or the backward slash in Windows at the end of the path.

Generated Output Documents in the Database

When an Output Document is generated when running a case, a new entry is added to the wf_<WORKSPACE>.APP_DOCUMENT table and a new unique ID is assigned to the generated Output Document. In addition, 3 new entries are added to the wf_<WORKSPACE>.CONTENT table whose CON_ID field is set to that unique ID and the CON_CATEGORY fields are set to 'APP_DOC_TITLE','APP_DOC_FILENAME' and 'APP_DOC_COMMENT', respectively.

If inside a trigger or using an external application or script, the unique ID for an Output Document file can be found with the outputDocumentList() web service. Inside a trigger or a DynaForm, the unique IDs for all generated Output Documents can be looked up with the following SQL query:

SELECT APP_DOC_UID FROM APP_DOCUMENT WHERE APP_DOC_TYPE='OUTPUT' AND APP_DOC_STATUS='ACTIVE'

To find the generated Output Documents for a specified case:

SELECT APP_DOC_UID FROM APP_DOCUMENT WHERE APP_UID='<CASE-UID>' AND
  APP_DOC_TYPE='OUTPUT' AND APP_DOC_STATUS='ACTIVE'

To find a specified Output Document for a specified case, which was uploaded by a specified user:

SELECT APP_DOC_UID FROM APP_DOCUMENT WHERE APP_UID='<CASE-UID>' AND
  DOC_UID='<INPUT_DOC_UID>' AND USR_UID='<USER_UID>' AND
  APP_DOC_TYPE='INPUT' AND APP_DOC_STATUS='ACTIVE'

Output Documents can be marked by tags, which provide an easy way to find related Output Documents under HOME > Documents. The tags are stored in the wf_<WORKSPACE>.APP_DOCUMENT.APP_DOC_TAGS field for each generated Output Document file and multiple tags are separated by commas. To find all generated Output Document files for a case with a specified tag:

SELECT APP_DOC_UID FROM APP_DOCUMENT WHERE APP_DOC_TYPE='OUTPUT' AND
   APP_DOC_STATUS='ACTIVE' AND APP_DOC_TAGS LIKE '%<TAG>%'

To find all generated Output Documents created between a certain date range:

SELECT APP_DOC_UID FROM APP_DOCUMENT WHERE APP_DOC_TYPE='OUTPUT' AND APP_DOC_STATUS='ACTIVE' AND
   APP_DOC_CREATE_DATE>='<YYYY-MM-DD HH:MM:SS>' AND APP_DOC_CREATE_DATE<='<YYYY-MM-DD HH:MM:SS>'

To find the unique IDs for all the generated files for a specified Output Document Definition and their filenames used under HOME > Documents (not its real filename in the file system), query the wf_<WORKSPACE>.CONTENT table:

SELECT C.CON_ID, C.CON_VALUE FROM APP_DOCUMENT AD, CONTENT C
  WHERE AD.DOC_UID='<OUT-DOC-DEFINITION-UID>' AND AD.APP_DOC_STATUS='ACTIVE' AND
  AD.APP_DOC_UID=C.CON_ID AND C.CON_CATEGORY='APP_DOC_FILENAME' AND C.CON_VALUE<>''

To find the unique IDs for all the generated Output Documents for a specified user and their filenames used under HOME > Documents:

SELECT C.CON_ID, C.CON_VALUE FROM APP_DOCUMENT AD, CONTENT C
  WHERE AD.USR_UID='<USER-UID>' AND AD.APP_DOC_TYPE='OUTPUT' AND AD.APP_DOC_STATUS='ACTIVE' AND
  AD.APP_DOC_UID=C.CON_ID AND C.CON_CATEGORY='APP_DOC_FILENAME' AND C.CON_VALUE=''

To find the unique IDs for all the generated Output Documents for a specified case and their filenames used under HOME > Documents:

SELECT C.CON_ID, C.CON_VALUE FROM APP_DOCUMENT AD, CONTENT C
  WHERE AD.APP_UID='<CASE-UID>' AND AD.APP_DOC_TYPE='OUTPUT' AND AD.APP_DOC_STATUS='ACTIVE' AND
  AD.APP_DOC_UID=C.CON_ID AND C.CON_CATEGORY='APP_DOC_FILENAME' AND C.CON_VALUE<>''

If multi-lingual processes have been designed and the filename depends upon the system language, then add ADD C.CON_LANG='<LANG-CODE>' to the 3 queries above.

If the Output Document is configured to allow multiple versions of the same Input Document file, then also look for the record with the highest positive integer in the wf_<WORKSPACE>.APP_DOCUMENT.DOC_VERSION field. (The counting starts from the number 1.)

To find the most recent version of a generated Output Document for a specified case:

SELECT APP_DOC_UID FROM APP_DOCUMENT WHERE APP_UID='<CASE-UID>' AND
  DOC_UID='<OUT-DOC-DEFINITION-UID>' AND APP_DOC_STATUS='ACTIVE' AND
  DOC_VERSION = (SELECT MAX(DOC_VERSION) FROM APP_DOCUMENT WHERE APP_UID='<CASE-UID>' AND
  DOC_UID='<OUT-DOC-DEFINITION-UID>' AND APP_DOC_STATUS='ACTIVE')

Accessing Output Document with Triggers

Links to Output Documents in DynaForms

Trigger code can be used to look up information about an Output Document file in the database and construct the address to download the file.

First, add two link controls to a DynaForm for the PDF and DOC of an Output Document file:

In the properties of the link to the PDF file, set its display text property to the @@filenamePdf variable and set its href property to the @@filePdfUrl variable. Likewise, in the properties of the DOC file, set its display text property to the @@filenameDoc variable and set its href property to the @@fileDocUrl variable.

Then, create the following trigger which looks up information about the latest version of the Output Document file in the APP_DOCUMENT table and its filename in the CONTENT table in the database:

//set to the ID of the Output Document:
$docId = '30671206456bbc811c7dd13078044406';
$caseId = @@APPLICATION;
$query = "SELECT AD.APP_DOC_UID AS FILE_ID, C.CON_VALUE AS FILENAME, AD.DOC_VERSION AS VERSION
   FROM APP_DOCUMENT AD, CONTENT C
   WHERE AD.APP_UID='$caseId' AND AD.DOC_UID='$docId' AND AD.APP_DOC_UID=C.CON_ID AND
   C.CON_CATEGORY='APP_DOC_FILENAME' AND AD.DOC_VERSION=C.CON_PARENT
   ORDER BY AD.DOC_VERSION DESC"
;
$result = executeQuery($query);

if (!is_array($result) or count($result) == 0) {
   die("Error: Unable to find Output Document file for case $caseId.");
}

$fileId = $result[1]['FILE_ID'];
$filename = $result[1]['FILENAME'];
$version = $result[1]['VERSION'];
@@filePdfUrl = "http://{$_SERVER['SERVER_NAME']}:{$_SERVER['SERVER_PORT']}/sys" . @@SYS_SYS .
   "/neoclassic/en/cases/cases_ShowOutputDocument?a=$fileId&v=$version&ext=pdf";
@@fileDocUrl = "http://{$_SERVER['SERVER_NAME']}:{$_SERVER['SERVER_PORT']}/sys" . @@SYS_SYS .
   "/neoclassic/en/cases/cases_ShowOutputDocument?a=$fileId&v=$version&ext=doc";
@@filenamePdf = "{$filename}_{$version}.pdf";
@@filenameDoc = "{$filename}_{$version}.doc";

This trigger code sets the values of the variables which are inserted into the properties of the link controls when the DynaForm is generated. Make sure to change the $docId to the unique ID of the Output Document. Then, set this trigger to fire before the DynaForm.

When a case is run, the filenames and the URLs of the PDF and DOC files should be automatically inserted in the links in the DynaForm.

Generating Output Documents

The PMFGenerateOutputDocument() function can be called in a trigger to generate an Output Document in the current case. The PMFGenerateOutputDocument() function doesn't return any information about the generated file, but afterwards the executeQuery() function can be used to lookup this information in the wf_WORKSPACE.APP_DOCUMENT table. Information such as the filename, file version, the user who generated the file, and datetime when generated can be obtained with a complex database query as shown in the previous example, but it is much simpler to use the AppDocument::Load() method to obtain this information.

Example:

This example (which can be downloaded here) shows how to generate an Output Document and display a link to the generated file in a subsequent DynaForm, so that it is not necessary to have a separate Output Document step.

First, create two string variables named outDocUrl and outDocFilename, which will be used to pass the web address and filename of the generated file to the DynaForm. Then create a DynaForm which has a link control. In the properties of that link control, set the display text property to @@outDocFilename and the href property to @@outDocUrl.

Then, create an Output Document and get its Unique ID number by clicking on its Show ID button:

Then, create a trigger with the following code which generates the Output Document and looks up information about the generated PDF file:

//set to the Unique ID of the Output Document:
$outDocId = '84581368556d0b69010a355067195050';
$caseId = @@APPLICATION;

PMFGenerateOutputDocument($outDocId);

//retrieve info from the database about the generated output document file
$query = "SELECT APP_DOC_UID FROM APP_DOCUMENT WHERE APP_UID='$caseId' AND
   DOC_UID='$outDocId' AND APP_DOC_STATUS='ACTIVE'"
;
$result = executeQuery($query);
 
if (!is_array($result) or count($result) == 0) {
   die("Error: Unable to find generated Output Document in database.");
}
 
$d = new AppDocument();
$aFile = $d->Load( $result[1]['APP_DOC_UID'] );

//change from 'http://' to 'https://' if using SSL
//change 'pdf' to 'doc' for MS Word file
@@outDocUrl = 'http://' . $_SERVER['SERVER_NAME'] .
   // ':' . $_SERVER['SERVER_PORT'] . //uncomment if needing a port number
   '/sys'. @@SYS_SYS . '/en/neoclassic/cases/cases_ShowOutputDocument?a=' .
   $aFile['APP_DOC_UID'] . '&v='. $aFile['DOC_VERSION'] . '&ext=pdf';
@@outDocFilename = $aFile['APP_DOC_FILENAME'] .'_'. $aFile['DOC_VERSION'] .'.pdf';

Change the $outDocId variable to the Output Document's unique ID. The address in @@outDocUrl also may need to be adjusted if using https or if using a port number. In this example, the link is for a PDF file, but change from 'pdf' to 'doc' if linking to an MS Word file. Set the above trigger to fire before the DynaForm.

When a case is run, the filename for the generated Output Document file should be displayed in the link field.

Convert Output Documents to Text Files

The following example shows how to convert an Output Document file into a text file and display it in a Link control in a subsequent DynaForm so the user can download the text file.

In this example, the pdftotext command from Poppler is used to convert an Output Document's PDF file into a text file. Poppler has to be installed separately on the ProcessMaker server. On most Linux/UNIX servers, it is available to be installed in the poppler-utils package. For Windows machines, Poppler can be downloaded here. If not wishing to install a separate program, it is also possible to convert the Output Document's HTML file into text with the strip_tags() function, so this example can be modified to work without Poppler.

First, create an Output Document in the process and get its ID number, which in this example is "233815488585c62af61e2a6077136729".

Then, create a DynaForm with a Link control. In the properties of the Link, set the display text to @@textDocFilename and the href to @@textDocUrl.

Finally, create the following trigger:

//set to the Unique ID of the Output Document:
$outDocId = '233815488585c62af61e2a6077136729';
PMFGenerateOutputDocument($outDocId);

//retrieve info from the database about the generated output document file
$caseId = @@APPLICATION;
$query = "SELECT APP_DOC_UID, DOC_VERSION FROM APP_DOCUMENT
   WHERE APP_UID='$caseId' AND DOC_UID='$outDocId' AND
   APP_DOC_STATUS='ACTIVE' ORDER BY APP_DOC_CREATE_DATE DESC"
;
$result = executeQuery($query);
if (!is_array($result) or count($result) == 0) {
   die("Error: Unable to find generated Output Document in database.");
}
//get the filename of the uploaded document:
$d = new AppDocument();
$aFile = $d->Load($result[1]['APP_DOC_UID'], $result[1]['DOC_VERSION']);
$originalFilename = $aFile['APP_DOC_FILENAME'].'_'.$aFile['DOC_VERSION'];
$filename = $result[1]['APP_DOC_UID'].'_'.$result[1]['DOC_VERSION'];

$g = new G();
$path = PATH_DOCUMENT. $g->getPathFromUID($caseId) .PATH_SEP. "outdocs" .PATH_SEP. $filename .'.pdf';

$tempFile = tempnam(sys_get_temp_dir(), $originalFilename.'_');
//convert PDF to text file:
exec("pdftotext $path $tempFile.txt", @=aOutput);

//upload temporary text file to current case
$params = array (
   'ATTACH_FILE'  => new CurlFile($tempFile.'.txt'),
   'APPLICATION'  => @@APPLICATION,
   'INDEX'        => @%INDEX,
   'USR_UID'      => @@USER_LOGGED,
   'DOC_UID'      => '-1',
   'APP_DOC_TYPE' => 'ATTACHED',
   'TITLE'        => '',
   'COMMENT'      => ''
);

$domain = ($g->is_https() ? 'https://' : 'http://') . $_SERVER['SERVER_NAME'];
//add if needing a port number: .':'. $_SERVER['SERVER_PORT']
$uploadUrl = $domain.'/sys'.SYS_SYS.'/'.SYS_LANG.'/'.SYS_SKIN.'/services/upload';

//upload text file created from output document
ob_flush();
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $uploadUrl);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, $params);
// curl_setopt ($ch, CURLOPT_SSL_VERIFYHOST, 1); //Uncomment for SSL
// curl_setopt ($ch, CURLOPT_SSL_VERIFYPEER, 1); //Uncomment for SSL
$response = curl_exec($ch);
curl_close($ch);
//delete temporary text files:
unlink($tempFile);
unlink($tempFile.'.txt');

if (strpos($response, 'uploaded successfully') === false) {
   die($response);
}      

//lookup uploaded text file in the database:
$query = "SELECT APP_DOC_UID, DOC_VERSION FROM APP_DOCUMENT
   WHERE APP_UID='$caseId' AND DOC_UID='-1' AND APP_DOC_STATUS='ACTIVE'
   ORDER BY APP_DOC_CREATE_DATE DESC"
;
$result = executeQuery($query);

@@textDocUrl = $domain.'/sys'.SYS_SYS.'/'.SYS_LANG.'/'.SYS_SKIN.
        '/cases/cases_ShowDocument?a='. $result[1]['APP_DOC_UID'] .
        '&v='. $result[1]['DOC_VERSION'];
@@textDocFilename = basename($tempFile.'.txt');

Change the ID number of the Output Document to match your process. Set this trigger to execute before the DynaForm.

This trigger first uses PMFGenerateOutputDocument() to create the Output Document files. Then, it searches in the APP_DOCUMENT table in the database for the newly generated file in order to get its unique ID and version number. With that information, it calls the AppDocument::Load() method in order to get the filename of the generated file and construct the path where the file is stored on the ProcessMaker server.

The trigger then uses the tempnam() function to create a temporary file on the ProcessMaker server which will hold the text file. Then, it uses the exec() function to make a system call for the pdftotext program to convert the Output Document's PDF file into a text file.

The temporary text file is then uploaded to /services/upload as a new document in the case. The APP_DOCUMENT table is queried again to find the ID number and version number of this new document file. The URL to download the text file is placed in the @@textDocUrl variable and the filename of the text file is placed in the @@textDocFilename variable.

When a case is run and the DynaForm with the Link field is displayed, the user can click on the link to download the text file.

For a sample process containing this code, download and install output_document_to_text_file-3.pmx (right click and select "Save Link As").