first commit

This commit is contained in:
CHIEFSOFT\ameye
2024-09-30 18:11:26 -04:00
commit e592ca6823
27270 changed files with 5002257 additions and 0 deletions
@@ -0,0 +1,98 @@
<?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/>.
/**
* booktool_exportimscp book exported event.
*
* @package booktool_exportimscp
* @copyright 2013 Frédéric Massart
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
namespace booktool_exportimscp\event;
defined('MOODLE_INTERNAL') || die();
/**
* booktool_exportimscp book exported event class.
*
* @package booktool_exportimscp
* @since Moodle 2.6
* @copyright 2013 Frédéric Massart
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
class book_exported extends \core\event\base {
/**
* Create instance of event.
*
* @since Moodle 2.7
*
* @param \stdClass $book
* @param \context_module $context
* @return book_exported
*/
public static function create_from_book(\stdClass $book, \context_module $context) {
$data = array(
'context' => $context,
'objectid' => $book->id
);
/** @var book_exported $event */
$event = self::create($data);
$event->add_record_snapshot('book', $book);
return $event;
}
/**
* Returns description of what happened.
*
* @return string
*/
public function get_description() {
return "The user with id '$this->userid' has exported the book with course module id '$this->contextinstanceid'.";
}
/**
* Return localised event name.
*
* @return string
*/
public static function get_name() {
return get_string('eventbookexported', 'booktool_exportimscp');
}
/**
* Get URL related to the action.
*
* @return \moodle_url
*/
public function get_url() {
return new \moodle_url('/mod/book/tool/exportimscp/index.php', array('id' => $this->contextinstanceid));
}
/**
* Init method.
*
* @return void
*/
protected function init() {
$this->data['crud'] = 'r';
$this->data['edulevel'] = self::LEVEL_OTHER;
$this->data['objecttable'] = 'book';
}
public static function get_objectid_mapping() {
return array('db' => 'book', 'restore' => 'book');
}
}
@@ -0,0 +1,46 @@
<?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/>.
/**
* Privacy provider implementation for booktool_exportimscp.
*
* @package booktool_exportimscp
* @copyright 2018 Mihail Geshoski <mihail@moodle.com>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
namespace booktool_exportimscp\privacy;
defined('MOODLE_INTERNAL') || die();
/**
* Privacy provider implementation for booktool_exportimscp.
*
* @copyright 2018 Mihail Geshoski <mihail@moodle.com>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
class provider implements \core_privacy\local\metadata\null_provider {
/**
* Get the language string identifier with the component's language
* file to explain why this plugin stores no data.
*
* @return string
*/
public static function get_reason(): string {
return 'privacy:metadata';
}
}
+32
View File
@@ -0,0 +1,32 @@
<?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 module capability definition
*
* @package booktool_exportimscp
* @copyright 2011 Petr Skoda {@link http://skodak.org}
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
defined('MOODLE_INTERNAL') || die;
$capabilities = array(
'booktool/exportimscp:export' => array(
'captype' => 'read',
'contextlevel' => CONTEXT_MODULE
),
);
+29
View File
@@ -0,0 +1,29 @@
<?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/>.
/**
* Export to IMSCP booktool log events definition
*
* @package booktool_exportimscp
* @copyright 2012 onwards Eloy Lafuente (stronk7) {@link http://stronk7.com}
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
defined('MOODLE_INTERNAL') || die();
$logs = array(
array('module'=>'book', 'action'=>'exportimscp', 'mtable'=>'book', 'field'=>'name')
);
+40
View File
@@ -0,0 +1,40 @@
body,
table,
td,
th,
li,
p {
font-family: Arial, Verdana, Helvetica, sans-serif;
font-size: 1em;
line-height: 150%;
letter-spacing: 0.02em;
}
th {
font-weight: bold;
}
a:link,
a:visited {
text-decoration: none;
}
a:hover {
text-decoration: underline;
}
h1.main,
h2.main,
h3.main,
h4.main,
h5.main,
h6.main {
font-weight: bold;
}
h1#header {
color: #666;
text-align: right;
padding-bottom: 0.2em;
border-bottom: solid 1px #666;
}
+50
View File
@@ -0,0 +1,50 @@
<?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 IMSCP export plugin
*
* @package booktool_exportimscp
* @copyright 2001-3001 Antonio Vicent {@link http://ludens.es}
* @copyright 2001-3001 Eloy Lafuente (stronk7) {@link http://stronk7.com}
* @copyright 2011 Petr Skoda {@link http://skodak.org}
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
require(__DIR__.'/../../../../config.php');
require_once(__DIR__.'/locallib.php');
require_once($CFG->dirroot.'/mod/book/locallib.php');
require_once($CFG->libdir.'/filelib.php');
$id = required_param('id', PARAM_INT); // Course Module ID
$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);
$PAGE->set_url('/mod/book/tool/exportimscp/index.php', array('id'=>$id));
require_login($course, false, $cm);
$context = context_module::instance($cm->id);
require_capability('mod/book:read', $context);
require_capability('booktool/exportimscp:export', $context);
\booktool_exportimscp\event\book_exported::create_from_book($book, $context)->trigger();
$file = booktool_exportimscp_build_package($book, $context);
send_stored_file($file, 10, 0, true, array('filename' => clean_filename($book->name).'.zip'));
@@ -0,0 +1,32 @@
<?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/>.
/**
* exportimscp booktool language strings
*
* @package booktool_exportimscp
* @copyright 2011 Petr Skoda {@link http://skodak.org}
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
defined('MOODLE_INTERNAL') || die;
$string['eventbookexported'] = 'Book exported';
$string['exportimscp:export'] = 'Export book as IMS content package';
$string['generateimscp'] = 'Download IMS CP';
$string['nochapters'] = 'No book chapters found, so unable to export to IMS CP.';
$string['pluginname'] = 'Book IMS CP export';
$string['privacy:metadata'] = 'The Book IMS CP export plugin does not store any personal data.';
+41
View File
@@ -0,0 +1,41 @@
<?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/>.
/**
* IMSCP export lib
*
* @package booktool_exportimscp
* @copyright 2011 Petr Skoda {@link http://skodak.org}
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
defined('MOODLE_INTERNAL') || die;
/**
* Adds module specific settings to the settings block
*
* @param settings_navigation $settings The settings navigation object
* @param navigation_node $node The node to add module settings to
*/
function booktool_exportimscp_extend_settings_navigation(settings_navigation $settings, navigation_node $node) {
if (has_capability('booktool/exportimscp:export', $settings->get_page()->cm->context)) {
$url = new moodle_url('/mod/book/tool/exportimscp/index.php', array('id' => $settings->get_page()->cm->id));
$icon = new pix_icon('generate', '', 'booktool_exportimscp', array('class'=>'icon'));
$umscpnode = $node->add(get_string('generateimscp', 'booktool_exportimscp'), $url,
navigation_node::TYPE_SETTING, null, null, $icon);
$umscpnode->set_force_into_more_menu(true);
}
}
+262
View File
@@ -0,0 +1,262 @@
<?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 imscp export lib
*
* @package booktool_exportimscp
* @copyright 2001-3001 Antonio Vicent {@link http://ludens.es}
* @copyright 2001-3001 Eloy Lafuente (stronk7) {@link http://stronk7.com}
* @copyright 2011 Petr Skoda {@link http://skodak.org}
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
defined('MOODLE_INTERNAL') || die;
require_once(__DIR__.'/lib.php');
require_once($CFG->dirroot.'/mod/book/locallib.php');
/**
* Export one book as IMSCP package
*
* @param stdClass $book book instance
* @param context_module $context
* @return bool|stored_file
*/
function booktool_exportimscp_build_package($book, $context) {
global $DB;
$fs = get_file_storage();
if ($packagefile = $fs->get_file($context->id, 'booktool_exportimscp', 'package', $book->revision, '/', 'imscp.zip')) {
return $packagefile;
}
// fix structure and test if chapters present
if (!book_preload_chapters($book)) {
throw new \moodle_exception('nochapters', 'booktool_exportimscp');
}
// prepare temp area with package contents
booktool_exportimscp_prepare_files($book, $context);
$packer = get_file_packer('application/zip');
$areafiles = $fs->get_area_files($context->id, 'booktool_exportimscp', 'temp', $book->revision, "sortorder, itemid, filepath, filename", false);
$files = array();
foreach ($areafiles as $file) {
$path = $file->get_filepath().$file->get_filename();
$path = ltrim($path, '/');
$files[$path] = $file;
}
unset($areafiles);
$packagefile = $packer->archive_to_storage($files, $context->id, 'booktool_exportimscp', 'package', $book->revision, '/', 'imscp.zip');
// drop temp area
$fs->delete_area_files($context->id, 'booktool_exportimscp', 'temp', $book->revision);
// delete older versions
$sql = "SELECT DISTINCT itemid
FROM {files}
WHERE contextid = :contextid AND component = 'booktool_exportimscp' AND itemid < :revision";
$params = array('contextid'=>$context->id, 'revision'=>$book->revision);
$revisions = $DB->get_records_sql($sql, $params);
foreach ($revisions as $rev => $unused) {
$fs->delete_area_files($context->id, 'booktool_exportimscp', 'temp', $rev);
$fs->delete_area_files($context->id, 'booktool_exportimscp', 'package', $rev);
}
return $packagefile;
}
/**
* Prepare temp area with the files used by book html contents
*
* @param stdClass $book book instance
* @param context_module $context
*/
function booktool_exportimscp_prepare_files($book, $context) {
global $CFG, $DB;
$fs = get_file_storage();
$temp_file_record = array('contextid'=>$context->id, 'component'=>'booktool_exportimscp', 'filearea'=>'temp', 'itemid'=>$book->revision);
$chapters = $DB->get_records('book_chapters', array('bookid'=>$book->id), 'pagenum');
$chapterresources = array();
foreach ($chapters as $chapter) {
$chapterresources[$chapter->id] = array();
$files = $fs->get_area_files($context->id, 'mod_book', 'chapter', $chapter->id, "sortorder, itemid, filepath, filename", false);
foreach ($files as $file) {
$temp_file_record['filepath'] = '/'.$chapter->pagenum.$file->get_filepath();
$fs->create_file_from_storedfile($temp_file_record, $file);
$chapterresources[$chapter->id][] = $chapter->pagenum.$file->get_filepath().$file->get_filename();
}
if ($file = $fs->get_file($context->id, 'booktool_exportimscp', 'temp', $book->revision, "/$chapter->pagenum/", 'index.html')) {
// this should not exist
$file->delete();
}
$content = booktool_exportimscp_chapter_content($chapter, $context);
$index_file_record = array('contextid'=>$context->id, 'component'=>'booktool_exportimscp', 'filearea'=>'temp',
'itemid'=>$book->revision, 'filepath'=>"/$chapter->pagenum/", 'filename'=>'index.html');
$fs->create_file_from_string($index_file_record, $content);
}
$css_file_record = array('contextid'=>$context->id, 'component'=>'booktool_exportimscp', 'filearea'=>'temp',
'itemid'=>$book->revision, 'filepath'=>"/css/", 'filename'=>'styles.css');
$fs->create_file_from_pathname($css_file_record, __DIR__.'/imscp.css');
// Init imsmanifest and others
$imsmanifest = '';
$imsitems = '';
$imsresources = '';
// Moodle and Book version
$moodle_release = $CFG->release;
$moodle_version = $CFG->version;
$book_version = get_config('mod_book', 'version');
$bookname = format_string($book->name, true, array('context'=>$context));
// Load manifest header
$imsmanifest .= '<?xml version="1.0" encoding="UTF-8"?>
<!-- This package has been created with Moodle ' . $moodle_release . ' (' . $moodle_version . ') http://moodle.org/, Book module version ' . $book_version . ' - https://github.com/skodak/moodle-mod_book -->
<!-- One idea and implementation by Eloy Lafuente (stronk7) and Antonio Vicent (C) 2001-3001 -->
<manifest xmlns="http://www.imsglobal.org/xsd/imscp_v1p1" xmlns:imsmd="http://www.imsglobal.org/xsd/imsmd_v1p2" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" identifier="MANIFEST-' . md5($CFG->wwwroot . '-' . $book->course . '-' . $book->id) . '" xsi:schemaLocation="http://www.imsglobal.org/xsd/imscp_v1p1 imscp_v1p1.xsd http://www.imsglobal.org/xsd/imsmd_v1p2 imsmd_v1p2p2.xsd">
<organizations default="MOODLE-' . $book->course . '-' . $book->id . '">
<organization identifier="MOODLE-' . $book->course . '-' . $book->id . '" structure="hierarchical">
<title>' . htmlspecialchars($bookname, ENT_COMPAT) . '</title>';
// To store the prev level (book only have 0 and 1)
$prevlevel = null;
$currlevel = 0;
foreach ($chapters as $chapter) {
// Calculate current level ((book only have 0 and 1)
$currlevel = empty($chapter->subchapter) ? 0 : 1;
// Based upon prevlevel and current one, decide what to close
if ($prevlevel !== null) {
// Calculate the number of spaces (for visual xml-text formating)
$prevspaces = substr(' ', 0, $currlevel * 2);
// Same level, simply close the item
if ($prevlevel == $currlevel) {
$imsitems .= $prevspaces . ' </item>' . "\n";
}
// Bigger currlevel, nothing to close
// Smaller currlevel, close both the current item and the parent one
if ($prevlevel > $currlevel) {
$imsitems .= ' </item>' . "\n";
$imsitems .= ' </item>' . "\n";
}
}
// Update prevlevel
$prevlevel = $currlevel;
// Calculate the number of spaces (for visual xml-text formatting)
$currspaces = substr(' ', 0, $currlevel * 2);
$chaptertitle = format_string($chapter->title, true, array('context'=>$context));
// Add the imsitems
$imsitems .= $currspaces .' <item identifier="ITEM-' . $book->course . '-' . $book->id . '-' . $chapter->pagenum .'" isvisible="true" identifierref="RES-' .
$book->course . '-' . $book->id . '-' . $chapter->pagenum . "\">\n" .
$currspaces . ' <title>' . htmlspecialchars($chaptertitle, ENT_COMPAT) . '</title>' . "\n";
// Add the imsresources
// First, check if we have localfiles
$localfiles = array();
foreach ($chapterresources[$chapter->id] as $localfile) {
$localfiles[] = "\n" . ' <file href="' . $localfile . '" />';
}
// Now add the dependency to css
$cssdependency = "\n" . ' <dependency identifierref="RES-' . $book->course . '-' . $book->id . '-css" />';
// Now build the resources section
$imsresources .= ' <resource identifier="RES-' . $book->course . '-' . $book->id . '-' . $chapter->pagenum . '" type="webcontent" xml:base="' .
$chapter->pagenum . '/" href="index.html">' . "\n" .
' <file href="' . $chapter->pagenum . '/index.html" />' . implode($localfiles) . $cssdependency . "\n".
' </resource>' . "\n";
}
// Close items (the latest chapter)
// Level 1, close 1
if ($currlevel == 0) {
$imsitems .= ' </item>' . "\n";
}
// Level 2, close 2
if ($currlevel == 1) {
$imsitems .= ' </item>' . "\n";
$imsitems .= ' </item>' . "\n";
}
// Define the css common resource
$cssresource = ' <resource identifier="RES-' . $book->course . '-' . $book->id . '-css" type="webcontent" xml:base="css/" href="styles.css">
<file href="css/styles.css" />
</resource>' . "\n";
// Add imsitems to manifest
$imsmanifest .= "\n" . $imsitems;
// Close the organization
$imsmanifest .= " </organization>
</organizations>";
// Add resources to manifest
$imsmanifest .= "\n <resources>\n" . $imsresources . $cssresource . " </resources>";
// Close manifest
$imsmanifest .= "\n</manifest>\n";
$manifest_file_record = array('contextid'=>$context->id, 'component'=>'booktool_exportimscp', 'filearea'=>'temp',
'itemid'=>$book->revision, 'filepath'=>"/", 'filename'=>'imsmanifest.xml');
$fs->create_file_from_string($manifest_file_record, $imsmanifest);
}
/**
* Returns the html contents of one book's chapter to be exported as IMSCP
*
* @param stdClass $chapter the chapter to be exported
* @param context_module $context context the chapter belongs to
* @return string the contents of the chapter
*/
function booktool_exportimscp_chapter_content($chapter, $context) {
$options = new stdClass();
$options->noclean = true;
$options->context = $context;
// We need to rewrite the pluginfile URLs so the media filters can work.
$chaptercontent = file_rewrite_pluginfile_urls($chapter->content, 'pluginfile.php', $context->id, 'mod_book', 'chapter',
$chapter->id);
$chaptercontent = format_text($chaptercontent, $chapter->contentformat, $options);
// Now remove again the full pluginfile URLs.
$options = array('reverse' => true);
$chaptercontent = file_rewrite_pluginfile_urls($chaptercontent, 'pluginfile.php', $context->id, 'mod_book', 'chapter',
$chapter->id, $options);
$chaptercontent = str_replace('@@PLUGINFILE@@/', '', $chaptercontent);
$chaptertitle = format_string($chapter->title, true, array('context'=>$context));
$content = '';
$content .= '<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">' . "\n";
$content .= '<html>' . "\n";
$content .= '<head>' . "\n";
$content .= '<meta http-equiv="content-type" content="text/html; charset=utf-8" />' . "\n";
$content .= '<link rel="stylesheet" type="text/css" href="../css/styles.css" />' . "\n";
$content .= '<title>' . $chaptertitle . '</title>' . "\n";
$content .= '</head>' . "\n";
$content .= '<body>' . "\n";
$content .= '<h1 id="header">' . $chaptertitle . '</h1>' ."\n";
$content .= $chaptercontent . "\n";
$content .= '</body>' . "\n";
$content .= '</html>' . "\n";
return $content;
}
Binary file not shown.

After

Width:  |  Height:  |  Size: 816 B

@@ -0,0 +1,65 @@
<?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/>.
/**
* Events tests.
*
* @package booktool_exportimscp
* @category phpunit
* @copyright 2013 Frédéric Massart
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
namespace booktool_exportimscp\event;
/**
* Events tests class.
*
* @package booktool_exportimscp
* @category phpunit
* @copyright 2013 Frédéric Massart
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
class events_test extends \advanced_testcase {
public function setUp(): void {
$this->resetAfterTest();
}
public function test_book_exported(): void {
// There is no proper API to call to test the event, so what we are
// doing here is simply making sure that the events returns the right information.
$course = $this->getDataGenerator()->create_course();
$book = $this->getDataGenerator()->create_module('book', array('course' => $course->id));
$context = \context_module::instance($book->cmid);
$event = \booktool_exportimscp\event\book_exported::create_from_book($book, $context);
// Triggering and capturing the event.
$sink = $this->redirectEvents();
$event->trigger();
$events = $sink->get_events();
$this->assertCount(1, $events);
$event = reset($events);
// Checking that the event contains the expected values.
$this->assertInstanceOf('\booktool_exportimscp\event\book_exported', $event);
$this->assertEquals(\context_module::instance($book->cmid), $event->get_context());
$this->assertEquals($book->id, $event->objectid);
}
}
+29
View File
@@ -0,0 +1,29 @@
<?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 IMSCP export plugin version info
*
* @package booktool_exportimscp
* @copyright 2011 Petr Skoda {@link http://skodak.org}
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
defined('MOODLE_INTERNAL') || die;
$plugin->component = 'booktool_exportimscp'; // Full name of the plugin (used for diagnostics)
$plugin->version = 2024042200; // The current plugin version (Date: YYYYMMDDXX).
$plugin->requires = 2024041600; // Requires this Moodle version.
@@ -0,0 +1,46 @@
<?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/>.
/**
* Privacy provider implementation for booktool_importhtml.
*
* @package booktool_importhtml
* @copyright 2018 Mihail Geshoski <mihail@moodle.com>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
namespace booktool_importhtml\privacy;
defined('MOODLE_INTERNAL') || die();
/**
* Privacy provider implementation for booktool_importhtml.
*
* @copyright 2018 Mihail Geshoski <mihail@moodle.com>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
class provider implements \core_privacy\local\metadata\null_provider {
/**
* Get the language string identifier with the component's language
* file to explain why this plugin stores no data.
*
* @return string
*/
public static function get_reason(): string {
return 'privacy:metadata';
}
}
+37
View File
@@ -0,0 +1,37 @@
<?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 import capability definition
*
* @package booktool_importhtml
* @copyright 2011 Petr Skoda {@link http://skodak.org}
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
defined('MOODLE_INTERNAL') || die;
$capabilities = array(
'booktool/importhtml:import' => array(
'riskbitmask' => RISK_XSS,
'captype' => 'write',
'contextlevel' => CONTEXT_MODULE,
'archetypes' => array(
'editingteacher' => CAP_ALLOW,
'manager' => CAP_ALLOW,
)
),
);
+88
View File
@@ -0,0 +1,88 @@
<?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 import form
*
* @package booktool_importhtml
* @copyright 2004-2011 Petr Skoda {@link http://skodak.org}
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
defined('MOODLE_INTERNAL') || die;
require_once($CFG->libdir.'/formslib.php');
class booktool_importhtml_form extends moodleform {
function definition() {
$mform = $this->_form;
$data = $this->_customdata;
$mform->addElement('header', 'general', get_string('import', 'booktool_importhtml'));
$options = array(
// '0'=>get_string('typeonefile', 'booktool_importhtml'),
'1'=>get_string('typezipdirs', 'booktool_importhtml'),
'2'=>get_string('typezipfiles', 'booktool_importhtml'),
);
$mform->addElement('select', 'type', get_string('type', 'booktool_importhtml'), $options);
$mform->setDefault('type', 2);
$mform->addElement('filepicker', 'importfile', get_string('ziparchive', 'booktool_importhtml'));
$mform->addHelpButton('importfile', 'ziparchive', 'booktool_importhtml');
$mform->addRule('importfile', null, 'required');
$mform->addElement('hidden', 'id');
$mform->setType('id', PARAM_INT);
$mform->addElement('hidden', 'chapterid');
$mform->setType('chapterid', PARAM_INT);
$this->add_action_buttons(true, get_string('doimport', 'booktool_importhtml'));
$this->set_data($data);
}
function validation($data, $files) {
global $USER;
if ($errors = parent::validation($data, $files)) {
return $errors;
}
$usercontext = context_user::instance($USER->id);
$fs = get_file_storage();
if (!$files = $fs->get_area_files($usercontext->id, 'user', 'draft', $data['importfile'], 'id', false)) {
$errors['importfile'] = get_string('required');
return $errors;
} else {
$file = reset($files);
if ($file->get_mimetype() != 'application/zip') {
$errors['importfile'] = get_string('invalidfiletype', 'error', $file->get_filename());
// better delete current file, it is not usable anyway
$fs->delete_area_files($usercontext->id, 'user', 'draft', $data['importfile']);
} else {
if (!$chpterfiles = toolbook_importhtml_get_chapter_files($file, $data['type'])) {
$errors['importfile'] = get_string('errornochapters', 'booktool_importhtml');
}
}
}
return $errors;
}
}
+93
View File
@@ -0,0 +1,93 @@
<?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 import
*
* @package booktool_importhtml
* @copyright 2004-2011 Petr Skoda {@link http://skodak.org}
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
require(__DIR__.'/../../../../config.php');
require_once(__DIR__.'/locallib.php');
require_once(__DIR__.'/import_form.php');
$id = required_param('id', PARAM_INT); // Course Module ID
$chapterid = optional_param('chapterid', 0, PARAM_INT); // Chapter ID
$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_login($course, false, $cm);
$context = context_module::instance($cm->id);
require_capability('booktool/importhtml:import', $context);
$PAGE->set_url('/mod/book/tool/importhtml/index.php', array('id' => $id));
if ($chapterid) {
if (!$chapter = $DB->get_record('book_chapters', array('id'=>$chapterid, 'bookid'=>$book->id))) {
$chapterid = 0;
}
} else {
$chapter = false;
}
$PAGE->set_title($book->name);
$PAGE->set_heading($course->fullname);
$PAGE->activityheader->set_attrs([
'hidecompletion' => true,
'description' => ''
]);
// Prepare the page header.
$strbook = get_string('modulename', 'mod_book');
$strbooks = get_string('modulenameplural', 'mod_book');
$mform = new booktool_importhtml_form(null, array('id'=>$id, 'chapterid'=>$chapterid));
// If data submitted, then process and store.
if ($mform->is_cancelled()) {
if (empty($chapter->id)) {
redirect($CFG->wwwroot."/mod/book/view.php?id=$cm->id");
} else {
redirect($CFG->wwwroot."/mod/book/view.php?id=$cm->id&chapterid=$chapter->id");
}
} else if ($data = $mform->get_data()) {
echo $OUTPUT->header();
echo $OUTPUT->heading(get_string('importingchapters', 'booktool_importhtml'), 3);
// this is a bloody hack - children do not try this at home!
$fs = get_file_storage();
$draftid = file_get_submitted_draft_itemid('importfile');
if (!$files = $fs->get_area_files(context_user::instance($USER->id)->id, 'user', 'draft', $draftid, 'id DESC', false)) {
redirect($PAGE->url);
}
$file = reset($files);
toolbook_importhtml_import_chapters($file, $data->type, $book, $context);
echo $OUTPUT->continue_button(new moodle_url('/mod/book/view.php', array('id'=>$id)));
echo $OUTPUT->footer();
die;
}
echo $OUTPUT->header();
$mform->display();
echo $OUTPUT->footer();
@@ -0,0 +1,41 @@
<?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 import language strings
*
* @package booktool_importhtml
* @copyright 2011 Petr Skoda {@link http://skodak.org}
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
defined('MOODLE_INTERNAL') || die;
$string['doimport'] = 'Import';
$string['errornochapters'] = 'Cannot find chapters in selected file';
$string['import'] = 'Import chapter';
$string['importhtml:import'] = 'Import chapters';
$string['importing'] = 'Importing';
$string['importingchapters'] = 'Importing chapters into book';
$string['pluginname'] = 'Book chapter import';
$string['privacy:metadata'] = 'The Book chapter import plugin does not store any personal data.';
$string['relinking'] = 'Relinking';
$string['type'] = 'Type';
$string['typeonefile'] = 'One HTML file with headings as chapters';
$string['typezipfiles'] = 'Each HTML file represents one chapter';
$string['typezipdirs'] = 'Each folder represents one chapter';
$string['ziparchive'] = 'Zip file';
$string['ziparchive_help'] = 'Select a zip file containing HTML files and optional multimedia files and folders. To upload subchapters, add "_sub" to the end of HTML file or folder names.';
+38
View File
@@ -0,0 +1,38 @@
<?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/>.
/**
* HTML import lib
*
* @package booktool_importhtml
* @copyright 2011 Petr Skoda {@link http://skodak.org}
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
defined('MOODLE_INTERNAL') || die;
/**
* Adds module specific settings to the settings block
*
* @param settings_navigation $settings The settings navigation object
* @param navigation_node $node The node to add module settings to
*/
function booktool_importhtml_extend_settings_navigation(settings_navigation $settings, navigation_node $node) {
if (has_capability('booktool/importhtml:import', $settings->get_page()->cm->context)) {
$url = new moodle_url('/mod/book/tool/importhtml/index.php', array('id' => $settings->get_page()->cm->id));
$node->add(get_string('import', 'booktool_importhtml'), $url, navigation_node::TYPE_SETTING, null, 'importchapter', null);
}
}
+346
View File
@@ -0,0 +1,346 @@
<?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/>.
/**
* HTML import lib
*
* @package booktool_importhtml
* @copyright 2011 Petr Skoda {@link http://skodak.org}
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
defined('MOODLE_INTERNAL') || die;
require_once(__DIR__.'/lib.php');
require_once($CFG->dirroot.'/mod/book/locallib.php');
/**
* Import HTML pages packaged into one zip archive
*
* @param stored_file $package
* @param string $type type of the package ('typezipdirs' or 'typezipfiles')
* @param stdClass $book
* @param context_module $context
* @param bool $verbose
*/
function toolbook_importhtml_import_chapters($package, $type, $book, $context, $verbose = true) {
global $DB, $OUTPUT;
$fs = get_file_storage();
$chapterfiles = toolbook_importhtml_get_chapter_files($package, $type);
$packer = get_file_packer('application/zip');
$fs->delete_area_files($context->id, 'mod_book', 'importhtmltemp', 0);
$package->extract_to_storage($packer, $context->id, 'mod_book', 'importhtmltemp', 0, '/');
// $datafiles = $fs->get_area_files($context->id, 'mod_book', 'importhtmltemp', 0, 'id', false);
// echo "<pre>";p(var_export($datafiles, true));
$chapters = array();
if ($verbose) {
echo $OUTPUT->notification(get_string('importing', 'booktool_importhtml'), 'notifysuccess');
}
if ($type == 0) {
$chapterfile = reset($chapterfiles);
if ($file = $fs->get_file_by_hash(sha1("$context->id/mod_book/importhtmltemp/0/$chapterfile->pathname"))) {
$htmlcontent = toolbook_importhtml_fix_encoding($file->get_content());
$htmlchapters = toolbook_importhtml_parse_headings(toolbook_importhtml_parse_body($htmlcontent));
// TODO: process h1 as main chapter and h2 as subchapters
}
} else {
foreach ($chapterfiles as $chapterfile) {
if ($file = $fs->get_file_by_hash(sha1("/$context->id/mod_book/importhtmltemp/0/$chapterfile->pathname"))) {
$chapter = new stdClass();
$htmlcontent = toolbook_importhtml_fix_encoding($file->get_content());
$chapter->bookid = $book->id;
$chapter->pagenum = $DB->get_field_sql('SELECT MAX(pagenum) FROM {book_chapters} WHERE bookid = ?', array($book->id)) + 1;
$chapter->importsrc = '/'.$chapterfile->pathname;
$chapter->content = toolbook_importhtml_parse_styles($htmlcontent);
$chapter->content .= toolbook_importhtml_parse_body($htmlcontent);
$chapter->title = toolbook_importhtml_parse_title($htmlcontent, $chapterfile->pathname);
$chapter->contentformat = FORMAT_HTML;
$chapter->hidden = 0;
$chapter->timecreated = time();
$chapter->timemodified = time();
if (preg_match('/_sub(\/|\.htm)/i', $chapter->importsrc)) { // If filename or directory ends with *_sub treat as subchapters
$chapter->subchapter = 1;
} else {
$chapter->subchapter = 0;
}
$chapter->id = $DB->insert_record('book_chapters', $chapter);
$chapter = $DB->get_record('book_chapters', array('id' => $chapter->id));
$chapters[$chapter->id] = $chapter;
\mod_book\event\chapter_created::create_from_chapter($book, $context, $chapter)->trigger();
}
}
}
if ($verbose) {
echo $OUTPUT->notification(get_string('relinking', 'booktool_importhtml'), 'notifysuccess');
}
$allchapters = $DB->get_records('book_chapters', array('bookid'=>$book->id), 'pagenum');
foreach ($chapters as $chapter) {
// find references to all files and copy them + relink them
$matches = null;
if (preg_match_all('/(src|codebase|name|href)\s*=\s*"([^"]+)"/i', $chapter->content, $matches)) {
$file_record = array('contextid'=>$context->id, 'component'=>'mod_book', 'filearea'=>'chapter', 'itemid'=>$chapter->id);
foreach ($matches[0] as $i => $match) {
$filepath = dirname($chapter->importsrc).'/'.$matches[2][$i];
$filepath = toolbook_importhtml_fix_path($filepath);
if (strtolower($matches[1][$i]) === 'href') {
// skip linked html files, we will try chapter relinking later
foreach ($allchapters as $target) {
if ($target->importsrc === $filepath) {
continue 2;
}
}
}
if ($file = $fs->get_file_by_hash(sha1("/$context->id/mod_book/importhtmltemp/0$filepath"))) {
if (!$oldfile = $fs->get_file_by_hash(sha1("/$context->id/mod_book/chapter/$chapter->id$filepath"))) {
$fs->create_file_from_storedfile($file_record, $file);
}
$chapter->content = str_replace($match, $matches[1][$i].'="@@PLUGINFILE@@'.$filepath.'"', $chapter->content);
}
}
$DB->set_field('book_chapters', 'content', $chapter->content, array('id'=>$chapter->id));
}
}
unset($chapters);
$allchapters = $DB->get_records('book_chapters', array('bookid'=>$book->id), 'pagenum');
foreach ($allchapters as $chapter) {
$newcontent = $chapter->content;
$matches = null;
if (preg_match_all('/(href)\s*=\s*"([^"]+)"/i', $chapter->content, $matches)) {
foreach ($matches[0] as $i => $match) {
if (strpos($matches[2][$i], ':') !== false or strpos($matches[2][$i], '@') !== false) {
// it is either absolute or pluginfile link
continue;
}
$chapterpath = dirname($chapter->importsrc).'/'.$matches[2][$i];
$chapterpath = toolbook_importhtml_fix_path($chapterpath);
foreach ($allchapters as $target) {
if ($target->importsrc === $chapterpath) {
$newcontent = str_replace($match, 'href="'.new moodle_url('/mod/book/view.php',
array('id'=>$context->instanceid, 'chapterid'=>$target->id)).'"', $newcontent);
}
}
}
}
if ($newcontent !== $chapter->content) {
$DB->set_field('book_chapters', 'content', $newcontent, array('id'=>$chapter->id));
}
}
$fs->delete_area_files($context->id, 'mod_book', 'importhtmltemp', 0);
// update the revision flag - this takes a long time, better to refetch the current value
$book = $DB->get_record('book', array('id'=>$book->id));
$DB->set_field('book', 'revision', $book->revision+1, array('id'=>$book->id));
}
/**
* Parse the headings of the imported package of type 'typeonefile'
* (currently unsupported)
*
* @param string $html html content to parse
* @todo implement this once the type 'typeonefile' is enabled
*/
function toolbook_importhtml_parse_headings($html) {
}
/**
* Parse the links to external css sheets of the imported html content
*
* @param string $html html content to parse
* @return string all the links to external css sheets
*/
function toolbook_importhtml_parse_styles($html) {
$styles = '';
if (preg_match('/<head[^>]*>(.+)<\/head>/is', $html, $matches)) {
$head = $matches[1];
if (preg_match_all('/<link[^>]+rel="stylesheet"[^>]*>/i', $head, $matches)) { // Extract links to css.
for ($i=0; $i<count($matches[0]); $i++) {
$styles .= $matches[0][$i]."\n";
}
}
}
return $styles;
}
/**
* Normalize paths to be absolute
*
* @param string $path original path with MS/relative separators
* @return string the normalized and cleaned absolute path
*/
function toolbook_importhtml_fix_path($path) {
$path = str_replace('\\', '/', $path); // anti MS hack
$path = '/'.ltrim($path, './'); // dirname() produces . for top level files + our paths start with /
$cnt = substr_count($path, '..');
for ($i=0; $i<$cnt; $i++) {
$path = preg_replace('|[^/]+/\.\./|', '', $path, 1);
}
$path = clean_param($path, PARAM_PATH);
return $path;
}
/**
* Convert some html content to utf8, getting original encoding from html headers
*
* @param string $html html content to convert
* @return string html content converted to utf8
*/
function toolbook_importhtml_fix_encoding($html) {
if (preg_match('/<head[^>]*>(.+)<\/head>/is', $html, $matches)) {
$head = $matches[1];
if (preg_match('/charset=([^"]+)/is', $head, $matches)) {
$enc = $matches[1];
return core_text::convert($html, $enc, 'utf-8');
}
}
return iconv('UTF-8', 'UTF-8//IGNORE', $html);
}
/**
* Extract the body from any html contents
*
* @param string $html the html to parse
* @return string the contents of the body
*/
function toolbook_importhtml_parse_body($html) {
$matches = null;
if (preg_match('/<body[^>]*>(.+)<\/body>/is', $html, $matches)) {
return $matches[1];
} else {
return '';
}
}
/**
* Extract the title of any html content, getting it from the title tag
*
* @param string $html the html to parse
* @param string $default default title to apply if no title is found
* @return string the resulting title
*/
function toolbook_importhtml_parse_title($html, $default) {
$matches = null;
if (preg_match('/<title>([^<]+)<\/title>/i', $html, $matches)) {
return $matches[1];
} else {
return $default;
}
}
/**
* Returns all the html files (chapters) from a file package
*
* @param stored_file $package file to be processed
* @param string $type type of the package ('typezipdirs' or 'typezipfiles')
*
* @return array the html files found in the package
*/
function toolbook_importhtml_get_chapter_files($package, $type) {
$packer = get_file_packer('application/zip');
$files = $package->list_files($packer);
$tophtmlfiles = array();
$subhtmlfiles = array();
$topdirs = array();
foreach ($files as $file) {
if (empty($file->pathname)) {
continue;
}
if (substr($file->pathname, -1) === '/') {
if (substr_count($file->pathname, '/') !== 1) {
// skip subdirs
continue;
}
if (!isset($topdirs[$file->pathname])) {
$topdirs[$file->pathname] = array();
}
} else {
$mime = mimeinfo('icon', $file->pathname);
if ($mime !== 'markup') {
continue;
}
$level = substr_count($file->pathname, '/');
if ($level === 0) {
$tophtmlfiles[$file->pathname] = $file;
} else if ($level === 1) {
$subhtmlfiles[$file->pathname] = $file;
$dir = preg_replace('|/.*$|', '', $file->pathname);
$topdirs[$dir][$file->pathname] = $file;
} else {
// lower levels are not interesting
continue;
}
}
}
core_collator::ksort($tophtmlfiles, core_collator::SORT_NATURAL);
core_collator::ksort($subhtmlfiles, core_collator::SORT_NATURAL);
core_collator::ksort($topdirs, core_collator::SORT_NATURAL);
$chapterfiles = array();
if ($type == 2) {
$chapterfiles = $tophtmlfiles;
} else if ($type == 1) {
foreach ($topdirs as $dir => $htmlfiles) {
if (empty($htmlfiles)) {
continue;
}
core_collator::ksort($htmlfiles, core_collator::SORT_NATURAL);
if (isset($htmlfiles[$dir.'/index.html'])) {
$htmlfile = $htmlfiles[$dir.'/index.html'];
} else if (isset($htmlfiles[$dir.'/index.htm'])) {
$htmlfile = $htmlfiles[$dir.'/index.htm'];
} else if (isset($htmlfiles[$dir.'/Default.htm'])) {
$htmlfile = $htmlfiles[$dir.'/Default.htm'];
} else {
$htmlfile = reset($htmlfiles);
}
$chapterfiles[$htmlfile->pathname] = $htmlfile;
}
} else if ($type == 0) {
if ($tophtmlfiles) {
if (isset($tophtmlfiles['index.html'])) {
$htmlfile = $tophtmlfiles['index.html'];
} else if (isset($tophtmlfiles['index.htm'])) {
$htmlfile = $tophtmlfiles['index.htm'];
} else if (isset($tophtmlfiles['Default.htm'])) {
$htmlfile = $tophtmlfiles['Default.htm'];
} else {
$htmlfile = reset($tophtmlfiles);
}
} else {
$htmlfile = reset($subhtmlfiles);
}
$chapterfiles[$htmlfile->pathname] = $htmlfile;
}
return $chapterfiles;
}
Binary file not shown.
@@ -0,0 +1,78 @@
<?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/>.
/**
* booktool_importhtml tests.
*
* @package booktool_importhtml
* @category phpunit
* @copyright 2013 Frédéric Massart
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
namespace booktool_importhtml;
defined('MOODLE_INTERNAL') || die();
global $CFG;
require_once($CFG->dirroot.'/mod/book/tool/importhtml/locallib.php');
/**
* booktool_importhtml tests class.
*
* @package booktool_importhtml
* @category phpunit
* @copyright 2013 Frédéric Massart
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
class locallib_test extends \advanced_testcase {
public function setUp(): void {
$this->resetAfterTest();
}
public function test_import_chapters_events(): void {
$course = $this->getDataGenerator()->create_course();
$book = $this->getDataGenerator()->create_module('book', array('course' => $course->id));
$context = \context_module::instance($book->cmid);
$record = new \stdClass();
$record->contextid = $context->id;
$record->component = 'phpunit';
$record->filearea = 'test';
$record->itemid = 0;
$record->filepath = '/';
$record->filename = 'chapters.zip';
$fs = get_file_storage();
$file = $fs->create_file_from_pathname($record, __DIR__ . '/fixtures/chapters.zip');
// Importing the chapters.
$sink = $this->redirectEvents();
toolbook_importhtml_import_chapters($file, 2, $book, $context, false);
$events = $sink->get_events();
// Checking the results.
$this->assertCount(5, $events);
foreach ($events as $event) {
$this->assertInstanceOf('\mod_book\event\chapter_created', $event);
$this->assertEquals($context, $event->get_context());
$chapter = $event->get_record_snapshot('book_chapters', $event->objectid);
$this->assertNotEmpty($chapter);
$this->assertEventContextNotUsed($event);
}
}
}
+29
View File
@@ -0,0 +1,29 @@
<?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 import plugin version info
*
* @package booktool_importhtml
* @copyright 2011 Petr Skoda {@link http://skodak.org}
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
defined('MOODLE_INTERNAL') || die;
$plugin->component = 'booktool_importhtml'; // Full name of the plugin (used for diagnostics)
$plugin->version = 2024042200; // The current plugin version (Date: YYYYMMDDXX).
$plugin->requires = 2024041600; // Requires this Moodle version.
@@ -0,0 +1,98 @@
<?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/>.
/**
* booktool_print book printed event.
*
* @package booktool_print
* @copyright 2013 Frédéric Massart
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
namespace booktool_print\event;
defined('MOODLE_INTERNAL') || die();
/**
* booktool_print book printed event class.
*
* @package booktool_print
* @since Moodle 2.6
* @copyright 2013 Frédéric Massart
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
class book_printed extends \core\event\base {
/**
* Create instance of event.
*
* @since Moodle 2.7
*
* @param \stdClass $book
* @param \context_module $context
* @return book_printed
*/
public static function create_from_book(\stdClass $book, \context_module $context) {
$data = array(
'context' => $context,
'objectid' => $book->id
);
/** @var book_printed $event */
$event = self::create($data);
$event->add_record_snapshot('book', $book);
return $event;
}
/**
* Returns description of what happened.
*
* @return string
*/
public function get_description() {
return "The user with id '$this->userid' has printed the book with course module id '$this->contextinstanceid'.";
}
/**
* Return localised event name.
*
* @return string
*/
public static function get_name() {
return get_string('eventbookprinted', 'booktool_print');
}
/**
* Get URL related to the action.
*
* @return \moodle_url
*/
public function get_url() {
return new \moodle_url('/mod/book/tool/print/index.php', array('id' => $this->contextinstanceid));
}
/**
* Init method.
*
* @return void
*/
protected function init() {
$this->data['crud'] = 'r';
$this->data['edulevel'] = self::LEVEL_PARTICIPATING;
$this->data['objecttable'] = 'book';
}
public static function get_objectid_mapping() {
return array('db' => 'book', 'restore' => 'book');
}
}
@@ -0,0 +1,101 @@
<?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/>.
/**
* booktool_print chapter printed event.
*
* @package booktool_print
* @copyright 2013 Frédéric Massart
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
namespace booktool_print\event;
defined('MOODLE_INTERNAL') || die();
/**
* booktool_print chapter printed event class.
*
* @package booktool_print
* @since Moodle 2.6
* @copyright 2013 Frédéric Massart
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
class chapter_printed extends \core\event\base {
/**
* Create instance of event.
*
* @since Moodle 2.7
*
* @param \stdClass $book
* @param \context_module $context
* @param \stdClass $chapter
* @return chapter_printed
*/
public static function create_from_chapter(\stdClass $book, \context_module $context, \stdClass $chapter) {
$data = array(
'context' => $context,
'objectid' => $chapter->id,
);
/** @var chapter_printed $event */
$event = self::create($data);
$event->add_record_snapshot('book', $book);
$event->add_record_snapshot('book_chapters', $chapter);
return $event;
}
/**
* Returns description of what happened.
*
* @return string
*/
public function get_description() {
return "The user with id '$this->userid' has printed the chapter with id '$this->objectid' of the book with " .
"course module id '$this->contextinstanceid'.";
}
/**
* Return localised event name.
*
* @return string
*/
public static function get_name() {
return get_string('eventchapterprinted', 'booktool_print');
}
/**
* Get URL related to the action.
*
* @return \moodle_url
*/
public function get_url() {
return new \moodle_url('/mod/book/tool/print/index.php', array('id' => $this->contextinstanceid));
}
/**
* Init method.
*
* @return void
*/
protected function init() {
$this->data['crud'] = 'r';
$this->data['edulevel'] = self::LEVEL_PARTICIPATING;
$this->data['objecttable'] = 'book_chapters';
}
public static function get_objectid_mapping() {
return array('db' => 'book_chapters', 'restore' => 'book_chapter');
}
}
@@ -0,0 +1,106 @@
<?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/>.
/**
* Class containing data for the view book page.
*
* @package booktool_print
* @copyright 2019 Mihail Geshoski
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
namespace booktool_print\output;
defined('MOODLE_INTERNAL') || die();
use renderable;
use renderer_base;
use stdClass;
use templatable;
use context_module;
/**
* Class containing data for the print book page.
*
* @copyright 2019 Mihail Geshoski
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
class print_book_chapter_page implements renderable, templatable {
/**
* @var object $book The book object.
*/
protected $book;
/**
* @var object $cm The course module object.
*/
protected $cm;
/**
* @var object $chapter The book chapter object.
*/
protected $chapter;
/**
* Construct this renderable.
*
* @param object $book The book
* @param object $cm The course module
* @param object $chapter The book chapter
*/
public function __construct($book, $cm, $chapter) {
$this->book = $book;
$this->cm = $cm;
$this->chapter = $chapter;
}
/**
* Export this data so it can be used as the context for a mustache template.
*
* @param renderer_base $output
* @return stdClass
*/
public function export_for_template(renderer_base $output) {
global $OUTPUT;
$context = context_module::instance($this->cm->id);
$chapters = book_preload_chapters($this->book);
$data = new stdClass();
// Print dialog link.
$data->printdialoglink = $output->render_print_book_chapter_dialog_link();
$data->booktitle = $OUTPUT->heading(format_string($this->book->name, true,
array('context' => $context)), 1);
if (!$this->book->customtitles) {
// If the current chapter is a subchapter, get the title of the parent chapter.
if ($this->chapter->subchapter) {
$parentchaptertitle = book_get_chapter_title($chapters[$this->chapter->id]->parent, $chapters,
$this->book, $context);
$data->parentchaptertitle = $OUTPUT->heading(format_string($parentchaptertitle, true,
array('context' => $context)), 2);
}
}
list($chaptercontent, $chaptervisible) = $output->render_print_book_chapter($this->chapter, $chapters,
$this->book, $this->cm);
$chapter = new stdClass();
$chapter->content = $chaptercontent;
$chapter->visible = $chaptervisible;
$data->chapter = $chapter;
return $data;
}
}
@@ -0,0 +1,103 @@
<?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/>.
/**
* Class containing data for the view book page.
*
* @package booktool_print
* @copyright 2019 Mihail Geshoski
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
namespace booktool_print\output;
defined('MOODLE_INTERNAL') || die();
use moodle_url;
use renderable;
use renderer_base;
use stdClass;
use templatable;
use context_module;
/**
* Class containing data for the print book page.
*
* @copyright 2019 Mihail Geshoski
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
class print_book_page implements renderable, templatable {
/**
* @var object $book The book object.
*/
protected $book;
/**
* @var object $cm The course module object.
*/
protected $cm;
/**
* Construct this renderable.
*
* @param object $book The book
* @param object $cm The course module
*/
public function __construct($book, $cm) {
$this->book = $book;
$this->cm = $cm;
}
/**
* Export this data so it can be used as the context for a mustache template.
*
* @param renderer_base $output
* @return stdClass
*/
public function export_for_template(renderer_base $output) {
global $OUTPUT, $CFG, $SITE, $USER;
$context = context_module::instance($this->cm->id);
$chapters = book_preload_chapters($this->book);
$course = get_course($this->book->course);
$data = new stdClass();
// Print dialog link.
$data->printdialoglink = $output->render_print_book_dialog_link();
$data->booktitle = $OUTPUT->heading(format_string($this->book->name, true,
array('context' => $context)), 1);
$introtext = file_rewrite_pluginfile_urls($this->book->intro, 'pluginfile.php', $context->id, 'mod_book', 'intro', null);
$data->bookintro = format_text($introtext, $this->book->introformat,
array('noclean' => true, 'context' => $context));
$data->sitelink = \html_writer::link(new moodle_url($CFG->wwwroot),
format_string($SITE->fullname, true, array('context' => $context)));
$data->coursename = format_string($course->fullname, true, array('context' => $context));
$data->modulename = format_string($this->book->name, true, array('context' => $context));
$data->username = fullname($USER, true);
$data->printdate = userdate(time());
$data->toc = $output->render_print_book_toc($chapters, $this->book, $this->cm);
foreach ($chapters as $ch) {
list($chaptercontent, $chaptervisible) = $output->render_print_book_chapter($ch, $chapters, $this->book,
$this->cm);
$chapter = new stdClass();
$chapter->content = $chaptercontent;
$chapter->visible = $chaptervisible;
$data->chapters[] = $chapter;
}
return $data;
}
}
@@ -0,0 +1,208 @@
<?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/>.
/**
* Defines the renderer for the book print tool.
*
* @package booktool_print
* @copyright 2019 Mihail Geshoski
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
namespace booktool_print\output;
defined('MOODLE_INTERNAL') || die();
use plugin_renderer_base;
use html_writer;
use context_module;
use moodle_url;
use moodle_exception;
/**
* The renderer for the book print tool.
*
* @copyright 2019 Mihail Geshoski
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
class renderer extends plugin_renderer_base {
/**
* Render the print book page.
*
* @param print_book_page $page
* @return string html for the page
* @throws moodle_exception
*/
public function render_print_book_page(print_book_page $page) {
$data = $page->export_for_template($this);
return parent::render_from_template('booktool_print/print_book', $data);
}
/**
* Render the print book chapter page.
*
* @param print_book_chapter_page $page
* @return string html for the page
* @throws moodle_exception
*/
public function render_print_book_chapter_page(print_book_chapter_page $page) {
$data = $page->export_for_template($this);
return parent::render_from_template('booktool_print/print_book_chapter', $data);
}
/**
* Render the print book chapter link.
*
* @return string html for the link
*/
public function render_print_book_chapter_dialog_link() {
$printtext = get_string('printchapter', 'booktool_print');
$printicon = $this->output->pix_icon('chapter', $printtext, 'booktool_print',
array('class' => 'icon'));
$printlinkatt = array('onclick' => 'window.print();return false;', 'class' => 'hidden-print');
return html_writer::link('#', $printicon . $printtext, $printlinkatt);
}
/**
* Render the print book link.
*
* @return string html for the link
*/
public function render_print_book_dialog_link() {
$printtext = get_string('printbook', 'booktool_print');
$printicon = $this->output->pix_icon('book', $printtext, 'booktool_print',
array('class' => 'icon'));
$printlinkatt = array('onclick' => 'window.print();return false;', 'class' => 'hidden-print');
return html_writer::link('#', $printicon . $printtext, $printlinkatt);
}
/**
* Render the print book table of contents.
*
* @param array $chapters Array of book chapters
* @param object $book The book object
* @param object $cm The curse module object
* @return string html for the TOC
*/
public function render_print_book_toc($chapters, $book, $cm) {
$first = true;
$context = context_module::instance($cm->id);
$toc = ''; // Representation of toc (HTML).
switch ($book->numbering) {
case BOOK_NUM_NONE:
$toc .= html_writer::start_tag('div', array('class' => 'book_toc_none'));
break;
case BOOK_NUM_NUMBERS:
$toc .= html_writer::start_tag('div', array('class' => 'book_toc_numbered'));
break;
case BOOK_NUM_BULLETS:
$toc .= html_writer::start_tag('div', array('class' => 'book_toc_bullets'));
break;
case BOOK_NUM_INDENTED:
$toc .= html_writer::start_tag('div', array('class' => 'book_toc_indented'));
break;
}
$toc .= html_writer::tag('a', '', array('name' => 'toc')); // Representation of toc (HTML).
$toc .= html_writer::tag('h2', get_string('toc', 'mod_book'), ['class' => 'text-center pb-5']);
$toc .= html_writer::start_tag('ul');
foreach ($chapters as $ch) {
if (!$ch->hidden) {
$title = book_get_chapter_title($ch->id, $chapters, $book, $context);
if (!$ch->subchapter) {
if ($first) {
$toc .= html_writer::start_tag('li');
} else {
$toc .= html_writer::end_tag('ul');
$toc .= html_writer::end_tag('li');
$toc .= html_writer::start_tag('li');
}
} else {
if ($first) {
$toc .= html_writer::start_tag('li');
$toc .= html_writer::start_tag('ul');
$toc .= html_writer::start_tag('li');
} else {
$toc .= html_writer::start_tag('li');
}
}
if (!$ch->subchapter) {
$toc .= html_writer::link(new moodle_url('#ch' . $ch->id), $title,
array('title' => s($title), 'class' => 'font-weight-bold text-decoration-none'));
$toc .= html_writer::start_tag('ul');
} else {
$toc .= html_writer::link(new moodle_url('#ch' . $ch->id), $title,
array('title' => s($title), 'class' => 'text-decoration-none'));
$toc .= html_writer::end_tag('li');
}
$first = false;
}
}
$toc .= html_writer::end_tag('ul');
$toc .= html_writer::end_tag('li');
$toc .= html_writer::end_tag('ul');
$toc .= html_writer::end_tag('div');
$toc = str_replace('<ul></ul>', '', $toc); // Cleanup of invalid structures.
return $toc;
}
/**
* Render the print book chapter.
*
* @param object $chapter The book chapter object
* @param array $chapters The array of book chapters
* @param object $book The book object
* @param object $cm The course module object
* @return array The array containing the content of the book chapter and visibility information
*/
public function render_print_book_chapter($chapter, $chapters, $book, $cm) {
$context = context_module::instance($cm->id);
$title = book_get_chapter_title($chapter->id, $chapters, $book, $context);
$chaptervisible = $chapter->hidden ? false : true;
$bookchapter = '';
$bookchapter .= html_writer::start_div('book_chapter pt-3', ['id' => 'ch' . $chapter->id]);
if (!$book->customtitles) {
if (!$chapter->subchapter) {
$bookchapter .= $this->output->heading($title, 2, 'text-center pb-5');
} else {
$bookchapter .= $this->output->heading($title, 3, 'text-center pb-5');
}
}
$chaptertext = file_rewrite_pluginfile_urls($chapter->content, 'pluginfile.php', $context->id,
'mod_book', 'chapter', $chapter->id);
$bookchapter .= format_text($chaptertext, $chapter->contentformat, array('noclean' => true, 'context' => $context));
$bookchapter .= html_writer::end_div();
return array($bookchapter, $chaptervisible);
}
}
@@ -0,0 +1,46 @@
<?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/>.
/**
* Privacy provider implementation for booktool_print.
*
* @package booktool_print
* @copyright 2018 Mihail Geshoski <mihail@moodle.com>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
namespace booktool_print\privacy;
defined('MOODLE_INTERNAL') || die();
/**
* Privacy provider implementation for booktool_print.
*
* @copyright 2018 Mihail Geshoski <mihail@moodle.com>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
class provider implements \core_privacy\local\metadata\null_provider {
/**
* Get the language string identifier with the component's language
* file to explain why this plugin stores no data.
*
* @return string
*/
public static function get_reason(): string {
return 'privacy:metadata';
}
}
+40
View File
@@ -0,0 +1,40 @@
<?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 module capability definition
*
* @package booktool_print
* @copyright 2011 Petr Skoda {@link http://skodak.org}
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
defined('MOODLE_INTERNAL') || die;
$capabilities = array(
'booktool/print:print' => array(
'captype' => 'read',
'contextlevel' => CONTEXT_MODULE,
'archetypes' => array(
'guest' => CAP_ALLOW,
'frontpage' => CAP_ALLOW,
'student' => CAP_ALLOW,
'teacher' => CAP_ALLOW,
'editingteacher' => CAP_ALLOW,
'manager' => CAP_ALLOW,
)
),
);
+30
View File
@@ -0,0 +1,30 @@
<?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/>.
/**
* Print booktool log events definition
*
* @package booktool_print
* @copyright 2012 onwards Eloy Lafuente (stronk7) {@link http://stronk7.com}
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
defined('MOODLE_INTERNAL') || die();
$logs = array(
array('module' => 'book', 'action' => 'print', 'mtable' => 'book', 'field' => 'name'),
array('module' => 'book', 'action' => 'print chapter', 'mtable' => 'book_chapters', 'field' => 'title')
);
+97
View File
@@ -0,0 +1,97 @@
<?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(__DIR__.'/../../../../config.php');
require_once(__DIR__.'/locallib.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);
// Check all variables.
if ($chapterid) {
// Single chapter printing - only visible!
$chapter = $DB->get_record('book_chapters', array('id' => $chapterid, 'bookid' => $book->id), '*',
MUST_EXIST);
} else {
// Complete book.
$chapter = false;
}
$PAGE->set_url('/mod/book/print.php', array('id' => $id, 'chapterid' => $chapterid));
$PAGE->activityheader->disable();
$PAGE->set_pagelayout("embedded");
unset($id);
unset($chapterid);
// Security checks END.
// read chapters
$chapters = book_preload_chapters($book);
$strbooks = get_string('modulenameplural', 'mod_book');
$strbook = get_string('modulename', 'mod_book');
$strtop = get_string('top', 'mod_book');
// Page header.
$strtitle = format_string($book->name, true, array('context' => $context));
$PAGE->set_title($strtitle);
$PAGE->set_heading($strtitle);
$PAGE->requires->css('/mod/book/tool/print/print.css');
$renderer = $PAGE->get_renderer('booktool_print');
// Begin page output.
echo $OUTPUT->header();
if ($chapter) {
if ($chapter->hidden) {
require_capability('mod/book:viewhiddenchapters', $context);
}
\booktool_print\event\chapter_printed::create_from_chapter($book, $context, $chapter)->trigger();
$page = new booktool_print\output\print_book_chapter_page($book, $cm, $chapter);
} else {
\booktool_print\event\book_printed::create_from_book($book, $context)->trigger();
$page = new booktool_print\output\print_book_page($book, $cm);
}
echo $renderer->render($page);
// Finish page output.
echo $OUTPUT->footer();
@@ -0,0 +1,35 @@
<?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 module language strings
*
* @package booktool_print
* @copyright 2011 Petr Skoda {@link http://skodak.org}
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
defined('MOODLE_INTERNAL') || die;
$string['eventbookprinted'] = 'Book printed';
$string['eventchapterprinted'] = 'Chapter printed';
$string['pluginname'] = 'Book printing';
$string['printbook'] = 'Print book';
$string['printchapter'] = 'Print this chapter';
$string['printdate'] = 'Date';
$string['printedby'] = 'Printed by';
$string['print:print'] = 'Print book';
$string['privacy:metadata'] = 'The Book printing plugin does not store any personal data.';
+64
View File
@@ -0,0 +1,64 @@
<?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/>.
/**
* Print lib
*
* @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
*/
defined('MOODLE_INTERNAL') || die;
/**
* Adds module specific settings to the settings block
*
* @param settings_navigation $settings The settings navigation object
* @param navigation_node $node The node to add module settings to
*/
function booktool_print_extend_settings_navigation(settings_navigation $settings, navigation_node $node) {
$params = $settings->get_page()->url->params();
if (empty($params['id']) or empty($params['chapterid'])) {
return;
}
if (has_capability('booktool/print:print', $settings->get_page()->cm->context)) {
$url1 = new moodle_url('/mod/book/tool/print/index.php', array('id'=>$params['id']));
$url2 = new moodle_url('/mod/book/tool/print/index.php', array('id'=>$params['id'], 'chapterid'=>$params['chapterid']));
$action = new action_link($url1, get_string('printbook', 'booktool_print'), new popup_action('click', $url1));
$booknode = $node->add(get_string('printbook', 'booktool_print'), $action, navigation_node::TYPE_SETTING, null, 'printbook',
new pix_icon('book', '', 'booktool_print', array('class' => 'icon')));
$booknode->set_force_into_more_menu(true);
$action = new action_link($url2, get_string('printchapter', 'booktool_print'), new popup_action('click', $url2));
$chapternode = $node->add(get_string('printchapter', 'booktool_print'), $action, navigation_node::TYPE_SETTING, null,
'printchapter', new pix_icon('chapter', '', 'booktool_print', array('class' => 'icon')));
$chapternode->set_force_into_more_menu(true);
}
}
/**
* Return read actions.
*
* Note: This is not used by new logging system. Event with
* crud = 'r' and edulevel = LEVEL_PARTICIPATING will
* be considered as view action.
*
* @return array
*/
function booktool_print_get_view_actions() {
return array('print');
}
+36
View File
@@ -0,0 +1,36 @@
<?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 print lib
*
* @package booktool_print
* @copyright 2011 Petr Skoda {@link http://skodak.org}
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
defined('MOODLE_INTERNAL') || die;
require_once(__DIR__.'/lib.php');
require_once($CFG->dirroot.'/mod/book/locallib.php');
/**
* @deprecated since Moodle 3.7
*/
function booktool_print_get_toc() {
throw new coding_exception(__FUNCTION__ . ' can not be used any more. Please use booktool_print renderer
function render_print_book_toc().');
}
Binary file not shown.

After

Width:  |  Height:  |  Size: 307 B

+3
View File
@@ -0,0 +1,3 @@
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd" [
<!ENTITY ns_flows "http://ns.adobe.com/Flows/1.0/">
]><svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 16 16" preserveAspectRatio="xMinYMid meet" overflow="visible"><path d="M4 16H0V2l2-2h8.5c.8 0 1.5.7 1.5 1.5V4h-1V2.5c0-.8-.7-1.5-1.5-1.5H3.1l-1 1h6.4c.8 0 1.5.7 1.5 1.5V4H8.6L6 6.6v3.6c-1.2.4-2 1.5-2 2.8v3zm12 0v-3c0-1.1-.9-2-2-2H7c-1.1 0-2 .9-2 2v3h11zm-2-1H7v-1h7v1zM9 5L7 7v3h7V5H9zm4 4H8V8h2V6h3v3z" fill="#888"/></svg>

After

Width:  |  Height:  |  Size: 554 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 446 B

+3
View File
@@ -0,0 +1,3 @@
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd" [
<!ENTITY ns_flows "http://ns.adobe.com/Flows/1.0/">
]><svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 16 16" preserveAspectRatio="xMinYMid meet" overflow="visible"><path d="M4 12c-2 0-4 1.2-4 1.2V1.1S2 0 4 0s3.1.5 4 1c.9-.5 2-1 4-1s4 1.1 4 1.1v9.6c-.3-.3-.6-.5-1-.6V1.8S12.9 1 11.4 1c-1.3 0-2.6.7-3.4 1.1C7.2 1.7 5.9 1 4.6 1 3.1 1 1 1.8 1 1.8v9.9s2-.8 3.6-.8h.1c-.3.3-.5.6-.6 1 0 .1 0 .1-.1.1zm1.9-1.8s.1 0 0 0L6 6.6 8.6 4H14V2.5S12.8 2 11.4 2C9.8 2 8 3.3 8 3.3S6.2 2 4.6 2C3.2 2 2 2.5 2 2.5v7.9s1.2-.4 2.6-.4c.5 0 .9.1 1.3.2zM16 16v-3c0-1.1-.9-2-2-2H7c-1.1 0-2 .9-2 2v3h11zm-2-1H7v-1h7v1zM9 5L7 7v3h7V5H9zm4 4H8V8h2V6h3v3z" fill="#888"/></svg>

After

Width:  |  Height:  |  Size: 773 B

+111
View File
@@ -0,0 +1,111 @@
/* ===== TOC numbering styles ===== */
/* numbering == NONE */
#page-mod-book-print .book_toc_none {
page-break-before: always;
}
#page-mod-book-print .book_toc_none ul,
#page-mod-book-print .book_toc_none ul ul {
margin-left: 0;
padding-left: 0;
}
#page-mod-book-print .book_toc_none li {
margin-top: 10px;
list-style: none;
}
#page-mod-book-print .book_toc_none li li {
margin-top: 0;
list-style: none;
}
/* numbering == NUMBERED */
#page-mod-book-print .book_toc_numbered {
page-break-before: always;
}
#page-mod-book-print .book_toc_numbered li {
margin-top: 10px;
list-style: none;
}
#page-mod-book-print .book_toc_numbered li li {
margin-top: 0;
list-style: none;
}
#page-mod-book-print .book_toc_numbered ul,
#page-mod-book-print .book_toc_numbered ul ul {
margin-left: 0;
padding-left: 0;
}
/* numbering == BULLETS */
#page-mod-book-print .book_toc_bullets {
page-break-before: always;
}
#page-mod-book-print .book_toc_bullets li {
margin-top: 10px;
list-style: none;
}
#page-mod-book-print .book_toc_bullets li li {
margin-top: 0;
list-style: circle;
}
#page-mod-book-print .book_toc_bullets ul {
margin-left: 0;
padding-left: 0;
}
#page-mod-book-print .book_toc_bullets ul ul {
margin-left: 20px;
padding-left: 0;
}
/* numbering == INDENTED */
#page-mod-book-print .book_toc_indented {
page-break-before: always;
}
#page-mod-book-print .book_toc_indented li {
margin-top: 10px;
list-style: none;
}
#page-mod-book-print .book_toc_indented li li {
margin-top: 0;
list-style: none;
}
#page-mod-book-print .book_toc_indented ul {
margin-left: 0;
padding-left: 0;
}
#page-mod-book-print .book_toc_indented ul ul {
margin-left: 20px;
padding-left: 0;
}
#page-mod-book-print .book .book_chapter,
#page-mod-book-print .book .book_description {
page-break-before: always;
}
#page-mod-book-print {
padding-top: 0;
}
/* Exclude elements from printing. */
@media print {
.hidden-print {
display: none !important; /* stylelint-disable-line declaration-no-important */
}
.book .book_title {
margin-top: 45%;
}
}
@@ -0,0 +1,137 @@
{{!
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 comments.
You should have received a copy of the GNU General Public License
along with Moodle. If not, see <http://www.gnu.org/licenses/>.
}}
{{!
@template booktool_print/print_book
Print book page.
Classes required for JS:
* none
Data attributes required for JS:
* none
* printdialoglink string The URL pointing to the print book chapter popup window.
* booktitle string The HTML of the book title.
* bookintro string The book description.
* sitelink string The HTML link pointing to the site's dashboard.
* coursename string The name of the course.
* modulename string The name of the module.
* username string The user name.
* printdate string The print date.
* chaptertitle string The title of the chapter.
* toc object The HTML of the table of contents.
* chapters array The array of book chapters, their content and visibility information.
Example context (json):
{
"printdialoglink": "<a>Print book</a>",
"booktitle": "<h2>Book title</h2>",
"bookintro": "Book description",
"sitelink" : "<a>Site title</a>",
"coursename" : "Course name",
"modulename" : "Module name",
"username" : "User name",
"printdate" : "Tuesday, 22 January 2019, 10:17 AM",
"chaptertitle": "Chapter title",
"toc" : "<div>Table of contents</div>",
"chapters": [
{
"content": "<div>Chapter1 content</div>",
"visible": "true"
},
{
"content": "<div>Chapter2 content</div>",
"visible": "false"
}
]
}
}}
<div class="book p-4">
<div class="text-right">{{{ printdialoglink }}}</div>
<div class="text-center pb-3 book_title">{{{ booktitle }}}</div>
<div class="book_info w-100 pt-6 d-inline-block">
<div class="w-50 float-left">
<table>
<tr>
<td>
{{# str }} site {{/ str }}:
</td>
<td class="pl-3">
{{{ sitelink }}}
</td>
</tr>
<tr>
<td>
{{# str }} course {{/ str }}:
</td>
<td class="pl-3">
{{{ coursename }}}
</td>
</tr>
<tr>
<td>
{{# str }} modulename, mod_book {{/ str }}:
</td>
<td class="pl-3">
{{{ modulename }}}
</td>
</tr>
</table>
</div>
<div class="w-50 float-left">
<table class="float-right">
<tr>
<td>
{{# str }} printedby, booktool_print {{/ str }}:
</td>
<td class="pl-3">
{{{ username }}}
</td>
</tr>
<tr>
<td>
{{# str }} printdate, booktool_print {{/ str }}:
</td>
<td class="pl-3">
{{{ printdate }}}
</td>
</tr>
</table>
</div>
</div>
{{#bookintro}}
<div class="w-100 book_description">
<div class="py-5">
<h2 class="text-center pb-5">{{#str}} description {{/str}}</h2>
<p class="book_summary">{{{ bookintro }}}</p>
</div>
</div>
{{/bookintro}}
<div class="w-100">
<div class="py-5">{{{ toc }}}</div>
</div>
<div class="w-100">
{{#chapters}}
{{#visible }}
<div class="pb-5">
{{{ content }}}
</div>
{{/visible}}
{{/chapters}}
</div>
</div>
@@ -0,0 +1,56 @@
{{!
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 comments.
You should have received a copy of the GNU General Public License
along with Moodle. If not, see <http://www.gnu.org/licenses/>.
}}
{{!
@template booktool_print/print_book_chapter
Print book chapter page.
Classes required for JS:
* none
Data attributes required for JS:
* none
Context variables required for this template:
* printdialoglink string The URL pointing to the print book chapter popup window.
* booktitle string The HTML of the book title.
* parentchaptertitle string The HTML of the parent chapter title (if exists).
* chapter object The object containing the HTML of the chapter content and chapter's visibility.
Example context (json):
{
"printdialoglink": "<a>Print book</a>",
"booktitle": "<h2>Book title</h2>",
"parentchaptertitle": "<h2>Parent chapter title</h2>",
"chapter": {
"content": "<div>Chapter content</div>",
"visible": "true"
}
}
}}
<div class="chapter col-12 p-4">
<div class="text-right">{{{ printdialoglink }}}</div>
<div class="text-center pb-5">{{{ booktitle }}}</div>
<div class="chapter">
{{#parentchaptertitle}}
<div class="text-center">
{{{parentchaptertitle}}}
</div>
{{/parentchaptertitle}}
{{{chapter.content}}}
</div>
</div>
@@ -0,0 +1,91 @@
<?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/>.
/**
* Events tests.
*
* @package booktool_print
* @category phpunit
* @copyright 2013 Frédéric Massart
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
namespace booktool_print\event;
/**
* Events tests class.
*
* @package booktool_print
* @category phpunit
* @copyright 2013 Frédéric Massart
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
class events_test extends \advanced_testcase {
public function setUp(): void {
$this->resetAfterTest();
}
public function test_book_printed(): void {
// There is no proper API to call to test the event, so what we are
// doing here is simply making sure that the events returns the right information.
$course = $this->getDataGenerator()->create_course();
$book = $this->getDataGenerator()->create_module('book', array('course' => $course->id));
$context = \context_module::instance($book->cmid);
$event = \booktool_print\event\book_printed::create_from_book($book, $context);
// Triggering and capturing the event.
$sink = $this->redirectEvents();
$event->trigger();
$events = $sink->get_events();
$this->assertCount(1, $events);
$event = reset($events);
// Checking that the event contains the expected values.
$this->assertInstanceOf('\booktool_print\event\book_printed', $event);
$this->assertEquals(\context_module::instance($book->cmid), $event->get_context());
$this->assertEquals($book->id, $event->objectid);
}
public function test_chapter_printed(): void {
// There is no proper API to call to test the event, so what we are
// doing here is simply making sure that the events returns the right information.
$course = $this->getDataGenerator()->create_course();
$book = $this->getDataGenerator()->create_module('book', array('course' => $course->id));
$bookgenerator = $this->getDataGenerator()->get_plugin_generator('mod_book');
$chapter = $bookgenerator->create_chapter(array('bookid' => $book->id));
$context = \context_module::instance($book->cmid);
$event = \booktool_print\event\chapter_printed::create_from_chapter($book, $context, $chapter);
// Triggering and capturing the event.
$sink = $this->redirectEvents();
$event->trigger();
$events = $sink->get_events();
$this->assertCount(1, $events);
$event = reset($events);
// Checking that the event contains the expected values.
$this->assertInstanceOf('\booktool_print\event\chapter_printed', $event);
$this->assertEquals(\context_module::instance($book->cmid), $event->get_context());
$this->assertEquals($chapter->id, $event->objectid);
}
}
+29
View File
@@ -0,0 +1,29 @@
<?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 print plugin version info
*
* @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
*/
defined('MOODLE_INTERNAL') || die;
$plugin->component = 'booktool_print'; // Full name of the plugin (used for diagnostics)
$plugin->version = 2024042200; // The current plugin version (Date: YYYYMMDDXX).
$plugin->requires = 2024041600; // Requires this Moodle version.