function fillpdf_execute_merge in FillPDF 7
Same name and namespace in other branches
- 6 fillpdf.module \fillpdf_execute_merge()
- 7.2 fillpdf.module \fillpdf_execute_merge()
Utility to allow other functions to merge PDFs.
Utility function to allow other functions to merge PDFs with the various methods in a consistent way.
Parameters
string $method: The service or program being used. Possible values: local, remote, pdftk.
array $fields: The fields to merge into the PDF. Should be retrieved from the {fillpdf_fields} table.
mixed $fillpdf: When in URL mode, this is the record from {fillpdf_forms}. When in Stream mode, this is the PDF data.
string $mode: A special flag to control the behavior of this function. URL mode merges using a PDF on the file system and Stream mode merges using the value of $fillpdf directly. Possible values: url, stream.
Return value
bool|null|string The output of the fill method or FALSE on failure.
1 call to fillpdf_execute_merge()
- fillpdf_merge_pdf in ./
fillpdf.module - Constructs a page and sends it to the browser or saves it.
File
- ./
fillpdf.module, line 1396
Code
function fillpdf_execute_merge($method, array $fields, $fillpdf, $mode = 'url', $flatten = TRUE, $image_data = array()) {
$data = NULL;
// Try to prepare the data so that the $method part can process it without
// caring too much about merge tool.
switch ($mode) {
case 'url':
$filename = $fillpdf->url;
break;
case 'stream':
$filename = file_unmanaged_save_data($fillpdf, file_directory_temp() . '/pdf_data.pdf', FILE_EXISTS_RENAME);
break;
default:
// Ensure variable is always set to something.
$filename = $fillpdf->url;
}
$contents = _fillpdf_get_file_contents($filename, '<front>');
switch ($method) {
// FillPDF Service.
case 'remote':
// Anonymize image data from the fields array; we should not send the real
// filename to FillPDF Service. We do this in the specific fill method
// because others (e.g. local) may need the filename on the local system.
foreach ($fields as $field_name => &$field) {
if (!empty($image_data[$field_name])) {
$field_path_info = pathinfo($field);
$field = '{image}' . md5($field_path_info['filename']) . '.' . $field_path_info['extension'];
}
}
unset($field);
$api_key = variable_get('fillpdf_api_key', '0');
$result = _fillpdf_xmlrpc_request(FILLPDF_DEFAULT_SERVLET_URL, 'merge_pdf_v3', base64_encode($contents), $fields, $api_key, $flatten, $image_data);
if ($result->error == TRUE) {
if ($mode === 'stream') {
file_unmanaged_delete($filename);
}
// After error message set in _fillpdf_xmlrpc_request().
return FALSE;
}
$data = base64_decode($result->data);
break;
// FillPDF LocalService.
case 'local_service':
// Translate passed fields into the format the API expects.
$field_mappings = array();
foreach ($fields as $key => $field) {
if (strpos($field, '{image}') === 0) {
// If this is an image, then we should check the $image_data array for
// the actual information. We can get the extension from the
// filenamehash parameter.
if (!empty($image_data[$key]) && !empty($image_data[$key]['data']) && !empty($image_data[$key]['filenamehash'])) {
$field_mappings[$key] = array(
'type' => 'image',
'data' => $image_data[$key]['data'],
'extension' => pathinfo($image_data[$key]['filenamehash'], PATHINFO_EXTENSION),
);
continue;
}
}
$field_mappings[$key] = array(
'type' => 'text',
'data' => $field,
);
}
// Build an API request and get the REST API to handle the request.
$request = array(
'pdf' => base64_encode($contents),
'flatten' => $flatten,
'fields' => $field_mappings,
);
$json = drupal_json_encode($request);
$merge_endpoint = variable_get('fillpdf_local_service_endpoint') . '/api/v1/merge';
$result = drupal_http_request($merge_endpoint, array(
'method' => 'POST',
'data' => $json,
'headers' => array(
'Content-Type' => 'application/json',
),
));
if ((int) $result->code !== 200) {
if ($result->code) {
drupal_set_message('Error ' . $result->code . '. Reason: ' . $result->error, 'error');
}
else {
drupal_set_message('Error occurred merging PDF: ' . $result->error, 'error');
}
$fields = array();
break;
}
$data = base64_decode(drupal_json_decode($result->data)['pdf']);
if ($mode === 'stream') {
file_unmanaged_delete($filename);
}
break;
// Local JavaBridge servlet.
case 'local':
$require = drupal_get_path('module', 'fillpdf') . '/lib/JavaBridge/java/Java.inc';
require_once DRUPAL_ROOT . '/' . $require;
try {
$fillpdf = new java('com.ocdevel.FillpdfService', base64_encode($contents), 'bytes');
foreach ($fields as $key => $field) {
if (substr($field, 0, 7) == '{image}') {
// Remove {image} marker.
$image_filepath = substr($field, 7);
$fillpdf
->image($key, $image_filepath, "file");
}
else {
$fillpdf
->text($key, $field);
}
}
} catch (JavaException $e) {
if ($mode == 'stream') {
file_unmanaged_delete($filename);
}
$error = check_plain(java_truncate((string) $e));
drupal_set_message($error, 'error');
watchdog('fillpdf', $error, array(), WATCHDOG_ERROR);
// After setting error message.
return FALSE;
}
try {
if ($flatten) {
$data = java_values(base64_decode($fillpdf
->toByteArray()));
}
else {
$data = java_values(base64_decode($fillpdf
->toByteArrayUnflattened()));
}
} catch (JavaException $e) {
if ($mode == 'stream') {
file_unmanaged_delete($filename);
}
$error = check_plain(java_truncate((string) $e));
drupal_set_message($error, 'error');
watchdog('fillpdf', $error, array(), WATCHDOG_ERROR);
// After setting error message.
return FALSE;
}
break;
case 'pdftk':
// Looks like I'm the first actually to use this! (wizonesolutions).
module_load_include('inc', 'fillpdf', 'xfdf');
$xfdfname = $filename . '.xfdf';
$xfdf = create_xfdf(basename($xfdfname), $fields);
// Generate the file.
$xfdffile = file_unmanaged_save_data($xfdf, $xfdfname, FILE_EXISTS_RENAME);
// Now feed this to pdftk and save the result to a variable.
$pdftk_command = array();
$pdftk_command[] = fillpdf_pdftk_path();
$pdftk_command[] = escapeshellarg(drupal_realpath($filename));
$pdftk_command[] = 'fill_form';
$pdftk_command[] = escapeshellarg(drupal_realpath($xfdffile));
$pdftk_command[] = 'output -';
if ($flatten) {
$pdftk_command[] = 'flatten';
}
$pdftk_command[] = 'drop_xfa';
$pdftk_command = implode(' ', $pdftk_command);
// Run the pdftk command and read stdout, stderr, and exit status.
$descriptorspec = array(
1 => array(
'pipe',
'w',
),
2 => array(
'pipe',
'w',
),
);
$proc = proc_open($pdftk_command, $descriptorspec, $pipes);
// Read stdout.
$data = stream_get_contents($pipes[1]);
fclose($pipes[1]);
// Read stderr.
$stderr = stream_get_contents($pipes[2]);
fclose($pipes[2]);
// Read exit status.
$exit_status = proc_close($proc);
// Public error message if no data returned by pdftk.
if (!$data) {
drupal_set_message(t('Error with pdftk. No PDF generated.'), 'error');
}
// Log errors when no PDF or non-zero exit status.
if (!$data || $exit_status !== 0) {
$message = 'Error with pdftk: Exit status: !exit_status; data length: !data_length; stderr: @stderr';
$variables = array(
'!exit_status' => $exit_status,
'!data_length' => strlen($data),
'@stderr' => $stderr,
);
watchdog('fillpdf', $message, $variables, WATCHDOG_ERROR);
}
file_unmanaged_delete($xfdffile);
break;
case 'test':
$data = file_get_contents(drupal_get_path('module', 'fillpdf') . '/tests/fillpdf_test_v4.pdf');
variable_set('fillpdf_test_last_merge_metadata', array(
'fields' => $fields,
'images' => $image_data,
'flatten' => $flatten,
));
}
if ($data) {
return $data;
}
else {
return FALSE;
}
}