0) {
$packet_id = $packet_gen_info['form_ref'];
$packet_options = unserialize($packet_gen_info['options']);
$packet_source = 'F';
} else {
continue;
}
/**
* Connect to the database and pull to packet metadata.
**/
$mysql_query = "";
$mysql_result = @mysql_query($mysql_query);
$mysql_row = mysql_fetch_assoc($mysql_result);
$packet_gen_info['packet_code'] = 'fid' . $packet_id;
/**
* If the export format has already been generated let's get rid of it.
**/
if (file_exists(PACKET_FILESTORE_DIR . '/' . $packet_gen_info['packet_code'] . $packet_options['format'])) {
unlink(PACKET_FILESTORE_DIR . '/' . $packet_gen_info['packet_code'] . $packet_options['format']);
}
/**
* Connect to the database and pull the items contained within the packet.
**/
$mysql_query = "";
$mysql_result = @mysql_query($mysql_query);
/**
* First pull in the stylesheet
**/
$pages[$page] = file_get_contents(PACKET_TEMPLATES_DIR . "/form_stylesheet.css");
/**
* Now pull in each page and the associated questionnaire.
* Replace variables specific to each page (item code, item content, etc).
**/
while ($mysql_row=mysql_fetch_assoc($mysql_result)) {
$page++;
$pages[$page] = file_get_contents(PACKET_TEMPLATES_DIR . "/form_item_template.htm");
$pages[$page] = str_replace("%ITEM_CODE%", $mysql_row['code'], $pages[$page]);
$pages[$page] = str_replace("%ITEM_CONTENT%", $mysql_row['text'], $pages[$page]);
/**
* Set the filename
**/
$filenames[$page] = strtoupper(substr($mysql_row['code'], 0, 2)) . sprintf('%03u', substr($mysql_row['code'], 2, strpos($mysql_row['code'], '-')-2)) . '-' . sprintf('%02u', substr($mysql_row['code'], strpos($mysql_row['code'], '-')+1));
/**
* Some HTML modifications need to be made in order to accommodate certain
* requirements and/or limitations of DOMPDF.
*
* First, since DOMPDF doesn't supported ordered lists we'll change them into tables.
*
* We'll automate the ordered list creation by using an auto-incrementing ascii code.
* To enable the auto-increment we'll use the preg-replace function with the "e" modifier.
* This tells PHP to treat the replacement string similar to a PHP echo statment.
* Because of this (and I guess to avoid syntax problems) the string is escaped prior to
* being executed. I've found that using single quotes around the replacement string makes it
* easier to compensate for the auto-escaping. For example, using double quotes causes problems
* if you use a back reference (i.e. $1). See the PHP docs on preg_replace for more information.
*
* Doing this here instead of in the global replacement section makes it more difficult to write
* the matching string since we haven't yet run the HTML through tidy. Unfortunately, I haven't had
* time to figure out how to get the auto-increment working on a per-page basis.
**/
$ascii_code = 65;
$pages[$page] = preg_replace('/\
(.*?)\<\/li\>/ise', '"".chr(\$ascii_code++).". | | $1 |
"', $pages[$page]);
$pages[$page] = preg_replace('/\(.*?)\<\/ol\>/is', '', $pages[$page]);
}
if (count($pages) == 0) {
continue;
}
/**
* Now that the pages have been collected and formatted, assemble the document.
* We're either creating a single big document or many individual documents.
* The only situation where we're creating a single document is when we're
* placing multiple items on a page (pagesaver == TRUE)
**/
if ($packet_options['format'] == 'pdf' && $packet_options['pagesaver'] && !$packet_options['splitpdfs']) {
$html = file_get_contents(PACKET_TEMPLATES_DIR . "/form_shell.htm");
$html = str_replace("%DOCUMENT_STYLESHEET%", $pages[0], $html);
$html = str_replace("%DOCUMENT_CONTENT%", implode("\r\n\r\n", array_slice($pages, 1)), $html);
$html_docs[1] = $html;
$filenames[1] = $packet_gen_info['packet_code'];
} else {
for ($page = 1; $page < count($pages); $page++) {
$html = file_get_contents(PACKET_TEMPLATES_DIR . "/form_shell.htm");
$html = str_replace("%DOCUMENT_STYLESHEET%", $pages[0], $html);
$html = str_replace("%DOCUMENT_CONTENT%", $pages[$page], $html);
$html_docs[$page] = $html;
}
}
/**
* Now render the compiled HTML documents to PDF
**/
foreach ($html_docs as $html_doc_index => $html_doc) {
if (create_export($html_doc, $filenames[$html_doc_index], $packet_options['format']) === FALSE) {
continue(2);
}
}
/**
* If this is a single PDF form export we'll combine the
* resulting page PDFs into a single document. Otherwise we'll collect the export
* files into a ZIP archive.
**/
$return_code = 0;
if (isset($packet_options) && $packet_options['format'] == 'pdf' && $packet_options['splitpdfs'] == FALSE) {
$exec_cmd = 'pdftk';
for ($html_doc = 1; $html_doc <= count($html_docs); $html_doc++) {
$exec_cmd .= ' ' . PACKET_TEMP_DIR . '/' . $filenames[$html_doc] . '.pdf';
}
$exec_cmd .= ' cat output ' . PACKET_FILESTORE_DIR . '/' . $packet_gen_info['packet_code'] . '.pdf';
exec($exec_cmd, $pdftk_output, $pdftk_return_code);
$return_code = $pdftk_return_code;
} else {
$zip = new ZipArchive();
$zip_return_code = $zip->open(PACKET_FILESTORE_DIR . '/' . $packet_gen_info['packet_code'] . '.' . $packet_options['format'] . '.zip', ZIPARCHIVE::CREATE);
if ($zip_return_code === TRUE) {
for ($html_doc = 1; $html_doc <= count($html_docs); $html_doc++) {
if (!$zip->addFile(PACKET_TEMP_DIR . '/' . $filenames[$html_doc] . '.' . $packet_options['format'])) {
$zip_return_code = 600;
continue;
}
}
$zip->close();
}
$return_code = ($zip_return_code === TRUE ? 0 : $zip_return_code);
}
/**
* If we've successfully created the export format let's delete all the support documents.
**/
if ($return_code == 0) {
for ($html_doc = 1; $html_doc <= count($html_docs); $html_doc++) {
unlink(PACKET_TEMP_DIR . '/' . $filenames[$html_doc] . '.pdf');
unlink(PACKET_TEMP_DIR . '/' . $filenames[$html_doc] . '.htm');
if ($packet_options['format'] == 'eps') { unlink(PACKET_TEMP_DIR . '/' . $filenames[$html_doc] . '.eps'); }
if ($packet_options['format'] == 'tif') { unlink(PACKET_TEMP_DIR . '/' . $filenames[$html_doc] . '.tif'); }
}
} else {
continue;
}
}
cleanup();
function get_packet_id () {
$mysql_stmt = "";
$mysql_result = mysql_query($mysql_stmt);
if ($mysql_result && mysql_num_rows($mysql_result) > 0) {
$mysql_row = mysql_fetch_assoc($mysql_result);
return $mysql_row;
} else {
return FALSE;
}
}
function cleanup () {
unlink(PACKET_TEMP_DIR . '/packet_gen.pid');
exit();
}
function create_export ($html, $filename, $format = 'pdf') {
/**
* For some reason you can't reuse the DOMPDF class once you have rendered
* a PDF. Rather than debug this we'll go ahead and set up the object each
* time this function is called rather than set it up once at the beginning
* of the script. This uses a lot of memory, however, so once TIDY and DOMPDF
* have done their work we'll go ahead and destroy the objects to free up space.
**/
/**
* Declare any variables used in the function.
* - $tidy_config : tidy configuration options (see http://tidy.sourceforge.net/docs/quickref.html)
**/
$tidy_config = array(
'ascii-chars' => TRUE,
'clean' => TRUE,
'drop-proprietary-attributes' => TRUE,
'enclose-block-text' => TRUE,
'indent' => TRUE,
'indent-attributes' => TRUE,
'input-encoding' => 'utf8',
'join-classes' => FALSE,
'join-styles' => FALSE,
'merge-divs' => FALSE,
'numeric-entities' => TRUE,
'output-encoding' => 'ascii',
'output-html' => TRUE,
'output-xhtml' => FALSE,
'word-2000' => TRUE,
'wrap' => 167,
'wrap-attributes' => FALSE
);
/**
* Instantiate loadable modules
* - tidy for cleaning and formatting the HTML document
* (this will help minimize errors in the PDF creation process)
* - DOMPDF
**/
$tidy = new tidy();
$dompdf = new DOMPDF();
/**
* Before we go any further we need to strip out some tags that tidy is having trouble
* dealing with:
* - : Word tag. tidy is removing the contents.
**/
$html = preg_replace("/<(\/?)o:p>/", "<$1span>", $html);
/**
* Run tidy on the document to clean up the HTML formatting. This is necessary to
* ensure that the HTML is friendly to DOMPDF.
**/
$tidy->parseString($html, $tidy_config, 'utf8');
$tidy->cleanRepair();
$html = tidy_get_output($tidy);
/**
* Some global HTML modifications need to be made in order to accommodate certain
* requirements and/or limitations of DOMPDF.
*
* First we need to make sure image references include the domain and absolute path.
* DOMPDF treats each image reference as a file system reference unless an external-style
* reference is used.
*
* Previously we used $_SERVER['HTTP_HOST'] to find the host, but that was when this script
* was run interactively. Leaving this out for now as we need to think about the best way
* to perform this replacement. Also, we'll need to update it to take into account
* template variables at the beginning of the URL.
**/
//$html = preg_replace('/src=([^>]*?)\"\//is','src="http://' . $_SERVER['HTTP_HOST'] . '/', $html);
//$html = preg_replace('/url\(\//is','url(http://' . $_SERVER['HTTP_HOST'] . '/', $html);
$patterns = array(
'/src=([^>]*?)\"\/(?!' . str_replace('/', '\/', ltrim(PACKET_TEMPLATES_DIR, '/')) . ')/is',
'/url\(\/(?!' . str_replace('/', '\/', ltrim(PACKET_TEMPLATES_DIR, '/')) . ')/is'
);
$replacements = array(
'src="http://www.eclecticgeek.com/',
'url(http://www.eclecticgeek.com/'
);
$html = preg_replace($patterns, $replacements, $html);
/**
* Next, DOMPDF likes to work in inches, and it doesn't really like the width attribute of tags.
* This is particularly important for images, but we've also run into some table troubles as well.
* Since pretty much everything is specified in pixels (pt in some cases ... but we'll ignore those for now)
* let's try to rewrite all width attributes as inches specified in a style attribute. Current DPI seems to
* be 120; divide pixel width by 120 to get number of inches.
**/
$html = preg_replace('/<([^>]*?width=\"(\d*?)\"[^>]*?)>/ise', '"<$1 style=\"width: " . round(($2/120), 3) . "in;\">"', $html);
/**
* The width styler for images is causing some apostrphes to be escaped. Currently unaware of
* the cause as it is inconsistent. This will unescape any escaped apostrophes.
**/
$html = str_replace("\'", "'", $html);
/**
* Run tidy again to make sure that any code replacement is nicely formatted.
**/
$tidy->parseString($html, $tidy_config, 'utf8');
$tidy->cleanRepair();
$html = tidy_get_output($tidy);
/**
* The preserve-entities option for tidy doesn't appear to be supported. In order to avoid
* problems with "smart" punctuation with DOMPDF (which doesn't appear to handle it well) we'll
* go ahead and manually convert any known characters to HTML entity. The standard string
* replacement functions don't work since these characters are multi-byte.
* Currently these lines aren't doing anything since I have the ascii-chars option for tiday set
* because DOMPDF is having trouble with multi-byte characters (such as smart punctuation).
**/
$html = preg_replace("/\x{2018}/isu", "‘", $html);
$html = preg_replace("/\x{2019}/isu", "’", $html);
$html = preg_replace("/\x{201C}/isu", "“", $html);
$html = preg_replace("/\x{201D}/isu", "”", $html);
$html = preg_replace("/\x{2013}/isu", "–", $html);
$html = preg_replace("/\x{2014}/isu", "—", $html);
/**
* Output the HTML so we can check for errors.
**/
file_put_contents(PACKET_TEMP_DIR . '/' . $filename . '.htm', $html);
/**
* Output the PDF if the PDF variable is set to true. Otherwise output the final HTML.
**/
$dompdf->load_html($html);
$dompdf->render();
$pdf = $dompdf->output();
file_put_contents(PACKET_TEMP_DIR . '/' . $filename . '.pdf', $pdf);
/**
* Unless we deallocate the memory used by tidy and DOMPDF we will run out of memory.
**/
unset($tidy);
unset($dompdf);
if ($format == 'eps') {
// $exec_cmd = 'pdftops -f 1 -l 1 -nocrop -noshrink -eps ' . $tmpfile . ' ' . $tmpfile . '.eps';
// GhostScript needs a high resolution (-r4800, or higher), otherwise it will convert small fonts to bitmap
$exec_cmd = 'gs -dSAFER -dBATCH -dNOPAUSE -sDEVICE=epswrite -dLanguageLevel=2 -dEPSCrop -r4800 -sOutputFile=' . PACKET_TEMP_DIR . '/' . $filename . '.eps ' . PACKET_TEMP_DIR . '/' . $filename . '.pdf';
exec($exec_cmd, $pdfconv_output, $pdfconv_return_code);
$exec_cmd = 'epstool --add-tiff6p-preview --device bmpgray ' . PACKET_TEMP_DIR . '/' . $filename . '.eps ' . PACKET_TEMP_DIR . '/' . $filename . '.eps';
exec($exec_cmd, $epstool_output, $epstool_return_code);
}
if ($format == 'tif') {
$exec_cmd = 'gs -dSAFER -dBATCH -dNOPAUSE -sDEVICE=tiff24nc -r150 -sOutputFile=' . PACKET_TEMP_DIR . '/' . $filename . '.tif ' . PACKET_TEMP_DIR . '/' . $filename . '.pdf';
exec($exec_cmd, $pdfconv_output, $pdfconv_return_code);
}
return (file_exists(PACKET_TEMP_DIR . '/' . $filename . '.' . $format) ? TRUE : FALSE);
}
?>