Here's my code. It's a bit hacky, especially the image bit because of the way image files are stored (pathname hashes and all that), but it's a start. It's definitely not good enough for core: somebody will have to work on it!
Basically it reads the book chapters and then concatenates them into one long string of xml, which is what prince requires. This MUST be perfectlly formed though; any errors and prince will fail.
<?php
// This file is part of Moodle - http://moodle.org/
//
// Moodle is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// Moodle is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
/**
* Book printing
*
* @package booktool_print
* @copyright 2004-2011 Petr Skoda {@link http://skodak.org}
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
require(dirname(__FILE__).'/../../../../config.php');
require_once(dirname(__FILE__).'/locallib.php');
require_once('cja_image_function.php');
$id = required_param('id', PARAM_INT); // Course Module ID
$chapterid = optional_param('chapterid', 0, PARAM_INT); // Chapter ID
// =========================================================================
// security checks START - teachers and students view
// =========================================================================
$cm = get_coursemodule_from_id('book', $id, 0, false, MUST_EXIST);
$course = $DB->get_record('course', array('id'=>$cm->course), '*', MUST_EXIST);
$book = $DB->get_record('book', array('id'=>$cm->instance), '*', MUST_EXIST);
require_course_login($course, true, $cm);
$context = context_module::instance($cm->id);
require_capability('mod/book:read', $context);
require_capability('booktool/print:print', $context);
// Security checks END.
$PAGE->set_url('/mod/book/quickguide.php', array('id'=>$id, 'chapterid'=>$chapterid));
unset($id);
unset($chapterid);
// Setup Prince
include 'prince.php'; #The prince wrapper
$prince = new Prince("/home/chcja/bin/prince"); #This is where your prince installation is
$prince->setLog('/home/chcja/bin/prince_log.txt'); #Log for debugging
$prince->addStyleSheet('manual.css'); #This is your print stylesheet
// End prince setup
//Create pdfcontent, the xml string that will get given to prince.
$book_title = $COURSE->fullname;
$pdfcontent= '<html><body>';
$pdfcontent .= "<p class='book_title'>$book_title</p>";
// read book chapters
$chapters = book_preload_chapters($book);
$strbooks = get_string('modulenameplural', 'mod_book');
$strbook = get_string('modulename', 'mod_book');
$strtop = get_string('top', 'mod_book');
add_to_log($course->id, 'quickguide', 'view', 'tool/print/quickguide.php?id='.$cm->id, $book->id, $cm->id);
$allchapters = $DB->get_records('book_chapters', array('bookid'=>$book->id), 'pagenum');
list($toc, $titles) = booktool_print_get_toc($chapters, $book, $cm);
// chapters
$link1 = $CFG->wwwroot.'/mod/book/view.php?id='.$course->id.'&chapterid=';
$link2 = $CFG->wwwroot.'/mod/book/view.php?id='.$course->id;
foreach ($chapters as $ch) // This takes each individual chapter and joins them into one long one
{
$chapter = $allchapters[$ch->id];
if ($chapter->noprint) { // Noprint is a customisation I made to allow individual chapters of a book not to be printed
continue;
}
if ($chapter->hidden) {
continue;
}
$pdfcontent .= '<div class="book_chapter">';
if (!$book->customtitles) {
$pdfcontent .= '<p class="book_chapter_title">'.$titles[$ch->id].'</p>';
}
$content = str_replace($link1, '#ch', $chapter->content);
$content = str_replace($link2, '#top', $content);
$content = file_rewrite_pluginfile_urls($content, 'pluginfile.php', $context->id, 'mod_book', 'chapter', $ch->id);
$content = format_text($content, $chapter->contentformat, array('noclean'=>true, 'context'=>$context));
$content = get_images($content); #function for getting images
$pdfcontent .= "$content</div>";
}
$pdfcontent .= '</body></html>'; #Closing tags for the xml that makes the pdf
// Pass it to prince to print
#echo ($pdfcontent); #For debugging, dump to screen instead
header('Content-Type: application/pdf');
header("Content-Disposition: inline; filename=".urlencode($book_title)."pdf");
$prince->convert_string_to_passthru($pdfcontent);
?>