function recipe_pdf35_export_single in Recipe 6
1 string reference to 'recipe_pdf35_export_single'
- recipe_pdf35_recipeio in plugins/
recipe_pdf35.module - Implementation of hook_recipeio($type).
File
- plugins/
recipe_pdf35.module, line 31 - recipe_pdf35.module - Enables exporting of 3x5" cards in pdf format. This is incredibly rudimentary at this point. 1 and only 1 card and if you go over, the text is lost.
Code
function recipe_pdf35_export_single($nid = NULL) {
if ($nid === NULL) {
drupal_set_message(t('Recipe not found.'));
drupal_not_found();
}
$node = node_load(array(
'nid' => $nid,
'type' => 'recipe',
));
// you should not be able to export unpublished recipes
if ($node->status == 0) {
drupal_access_denied();
return;
}
$recipe_data = prepare_receipe_data($node);
$pdf_pages = get_pdf_pages($recipe_data);
// This is a non-indented section for ease of making byte-accurate pdf strings.
// The newlines and spacing is pretty critical for this to work.
$pdf_index = array();
$objects = array(
'first item in the objects array is thrown out.',
);
// Resource Object, required by page objects.
$obj = <<<EOS
[/PDF /Text]
EOS;
array_push($objects, $obj);
$pdf_index['resource'] = count($objects) - 1;
// Font 1 Object, required by page objects.
$obj = <<<EOS
<< /Type /Font
/Subtype /Type1
/Name /F1
/BaseFont /Arial
/Encoding /WinAnsiEncoding
>>
EOS;
array_push($objects, $obj);
$pdf_index['font1'] = count($objects) - 1;
// Font 2 Object, required by page objects.
$obj = <<<EOS
<< /Type /Font
/Subtype /Type1
/Name /F2
/BaseFont /Courier
/Encoding /WinAnsiEncoding
>>
EOS;
array_push($objects, $obj);
$pdf_index['font2'] = count($objects) - 1;
$current_pos = count($objects) + 1;
$page_refs = array();
for ($i = 0; $i < count($pdf_pages); $i++) {
if (count($pdf_pages) > 1) {
$page_item_count = get_page_item_count($pdf_pages[$i]) + 1;
}
else {
$page_item_count = get_page_item_count($pdf_pages[$i]);
}
$page_refs[] = $current_pos + $page_item_count . ' 0 R';
$current_pos = $current_pos + $page_item_count + 1;
}
$kid_refs = implode(" ", $page_refs);
$kid_count = count($page_refs);
// Pages Object, required by root.
$obj = <<<EOS
<< /Type /Pages
/Kids [{<span class="php-variable">$kid_refs</span>}]
/Count {<span class="php-variable">$kid_count</span>}
>>
EOS;
array_push($objects, $obj);
$pdf_index['pages'] = count($objects) - 1;
// Render the objects for each page, then the page item.
for ($i = 0; $i < count($pdf_pages); $i++) {
foreach ($pdf_pages[$i]['header'] as $obj) {
array_push($objects, $obj);
$pdf_pages[$i]['items'][] = "" . count($objects) - 1 . ' 0 R';
}
foreach ($pdf_pages[$i]['column_0'] as $obj) {
array_push($objects, $obj);
$pdf_pages[$i]['items'][] = "" . count($objects) - 1 . ' 0 R';
}
foreach ($pdf_pages[$i]['column_1'] as $obj) {
array_push($objects, $obj);
$pdf_pages[$i]['items'][] = "" . count($objects) - 1 . ' 0 R';
}
foreach ($pdf_pages[$i]['column_2'] as $obj) {
array_push($objects, $obj);
$pdf_pages[$i]['items'][] = "" . count($objects) - 1 . ' 0 R';
}
foreach ($pdf_pages[$i]['footer'] as $obj) {
array_push($objects, $obj);
$pdf_pages[$i]['items'][] = "" . count($objects) - 1 . ' 0 R';
}
// Page Numbers
if (count($pdf_pages) > 1) {
$page_nbr = t('Page ' . ($i + 1));
$obj = "BT /F1 6 Tf 12 TL 325 17 Td ({$page_nbr})' ET";
$len = strlen($obj);
$obj = "<< /Length {$len} >>\nstream\n{$obj}\nendstream";
array_push($objects, $obj);
$pdf_pages[$i]['items'][] = "" . count($objects) - 1 . ' 0 R';
}
// Page Object
$content_refs = implode(' ', $pdf_pages[$i]['items']);
$obj = "<< /Type /Page\n/Parent {$pdf_index['pages']} 0 R\n/MediaBox [0 0 360 216]\n/Contents [{$content_refs}]\n/Resources << /ProcSet 4 0 R\n/Font << /F1 {$pdf_index['font1']} 0 R /F2 {$pdf_index['font2']} 0 R >>\n>>\n>>";
array_push($objects, $obj);
}
// Root Object, required by trailer.
$obj = <<<EOS
<< /Type /Catalog
/Pages {<span class="php-variable">$pdf_index</span>[<span class="php-string">'pages'</span>]} 0 R
>>
EOS;
array_push($objects, $obj);
$pdf_index['root'] = count($objects) - 1;
/* Loop the objects array for the actual pdf with object refs.
*
*/
$xref = array();
$pdf = "%PDF-1.4\n";
$pdf .= '%' . pack("c*", 128, 200, 225, 255) . "\n";
foreach ($objects as $obj_num => $o) {
// We skip array index 0.
if ($obj_num != 0) {
// Save the xref byte offset.
$xref[$obj_num] = strlen($pdf);
$pdf .= "{$obj_num} 0 obj\n";
$pdf .= "{$o}\n";
$pdf .= "endobj\n";
}
}
$xref_start_pos = strlen($pdf);
$xref_entry_count = count($xref) + 1;
$pdf .= "xref\n";
$pdf .= "0 {$xref_entry_count}\n";
$pdf .= "0000000000 65535 f \n";
foreach ($xref as $obj_num => $offset) {
$pdf .= sprintf("%010u 00000 n \n", $offset);
}
// Start of trailer section.
$pdf .= "trailer\n";
$pdf .= "<< /Size {$xref_entry_count}\n";
// Hard coded warning, /Root is the 1 0 object in this module.
$pdf .= "/Root {$pdf_index['root']} 0 R\n";
$pdf .= ">>\n";
$pdf .= "startxref\n";
$pdf .= "{$xref_start_pos}\n";
$pdf .= '%%EOF';
$file_name = strtolower($node->title) . '.pdf';
$file_name = str_replace(' ', '_', $file_name);
drupal_set_header('Content-type: application/pdf');
drupal_set_header($header = "Content-Disposition: attachment; filename={$file_name}");
return $pdf;
}