diff --git a/.github/workflows/moodle-ci.yml b/.github/workflows/moodle-ci.yml index 187d0b9..f131371 100644 --- a/.github/workflows/moodle-ci.yml +++ b/.github/workflows/moodle-ci.yml @@ -4,11 +4,11 @@ on: [push, pull_request] jobs: test: - runs-on: ubuntu-18.04 + runs-on: ubuntu-20.04 services: postgres: - image: postgres:10 + image: postgres:13.0 env: POSTGRES_USER: 'postgres' POSTGRES_HOST_AUTH_METHOD: 'trust' @@ -16,7 +16,7 @@ jobs: - 5432:5432 options: --health-cmd pg_isready --health-interval 10s --health-timeout 5s --health-retries 3 mariadb: - image: mariadb:10.5 + image: mariadb:10.6.7 env: MYSQL_USER: 'root' MYSQL_ALLOW_EMPTY_PASSWORD: "true" @@ -28,15 +28,30 @@ jobs: fail-fast: false matrix: include: + - php: '8.2' + moodle-branch: 'MOODLE_403_STABLE' + database: 'mariadb' + - php: '8.1' + moodle-branch: 'MOODLE_403_STABLE' + database: 'pgsql' + - php: '8.0' + moodle-branch: 'MOODLE_402_STABLE' + database: 'mariadb' + - php: '8.0' + moodle-branch: 'MOODLE_403_STABLE' + database: 'pgsql' + - php: '8.0' + moodle-branch: 'MOODLE_401_STABLE' + database: 'pgsql' - php: '7.4' - moodle-branch: 'MOODLE_311_STABLE' - database: pgsql + moodle-branch: 'MOODLE_401_STABLE' + database: 'mariadb' + - php: '8.0' + moodle-branch: 'MOODLE_400_STABLE' + database: 'pgsql' - php: '7.4' - moodle-branch: 'MOODLE_310_STABLE' - database: mariadb - - php: '7.3' - moodle-branch: 'MOODLE_39_STABLE' - database: pgsql + moodle-branch: 'MOODLE_400_STABLE' + database: 'pgsql' steps: - name: Check out repository code diff --git a/CHANGES.md b/CHANGES.md index 0b35de1..375eb97 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -1,3 +1,12 @@ +### 7.0.0 ### + +* New maintainer: bdecent gmbh. +* Behat and PHPUnit tests updated and tested on Moodle 4.1 - 4.3. +* Fixed minor coding style issues. +* Added monologo for Moodle 4.x. +* Fixed improper use of require_login method instead of require_course_login (resolves #10). +* New feature: Display block content on course page (based on work by Harald, David und Nicklas @devcamp19 — Thanks!). + ### 6.0.1 ### * Behat and PHPUnit tests updated and tested on Moodle 3.9 - 3.11. diff --git a/backup/moodle2/backup_poster_stepslib.php b/backup/moodle2/backup_poster_stepslib.php index 6f5b5bb..582bbb5 100644 --- a/backup/moodle2/backup_poster_stepslib.php +++ b/backup/moodle2/backup_poster_stepslib.php @@ -23,7 +23,6 @@ * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later */ -defined('MOODLE_INTERNAL') || die(); /** * Provides the definition of the backup structure @@ -44,11 +43,11 @@ class backup_poster_activity_structure_step extends backup_activity_structure_st protected function define_structure() { // Define the poster root element. - $poster = new backup_nested_element('poster', array('id'), array( - 'name', 'intro', 'introformat', 'timecreated', 'timemodified', 'shownameview', 'showdescriptionview')); + $poster = new backup_nested_element('poster', ['id'], ['name', 'intro', + 'introformat', 'timecreated', 'timemodified', 'shownameview', 'showdescriptionview', 'display', ]); // Define the data source. - $poster->set_source_table('poster', array('id' => backup::VAR_ACTIVITYID)); + $poster->set_source_table('poster', ['id' => backup::VAR_ACTIVITYID]); // Define file annotations. $poster->annotate_files('mod_poster', 'intro', null); diff --git a/backup/moodle2/restore_poster_activity_task.class.php b/backup/moodle2/restore_poster_activity_task.class.php index 90865f8..c0c68fe 100644 --- a/backup/moodle2/restore_poster_activity_task.class.php +++ b/backup/moodle2/restore_poster_activity_task.class.php @@ -54,16 +54,16 @@ protected function define_my_steps() { * @return array of restore_decode_content */ public static function define_decode_contents() { - return array(new restore_decode_content('poster', array('intro'), 'poster')); + return [new restore_decode_content('poster', ['intro'], 'poster')]; } /** * Defines the decoding rules for links belonging to the activity to be executed by the link decoder. */ public static function define_decode_rules() { - return array( + return [ new restore_decode_rule('POSTERINDEX', '/mod/poster/index.php?id=$1', 'course'), new restore_decode_rule('POSTERVIEWBYID', '/mod/poster/view.php?id=$1', 'course_module'), - ); + ]; } } diff --git a/backup/moodle2/restore_poster_stepslib.php b/backup/moodle2/restore_poster_stepslib.php index f244770..1978f96 100644 --- a/backup/moodle2/restore_poster_stepslib.php +++ b/backup/moodle2/restore_poster_stepslib.php @@ -23,8 +23,6 @@ * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later */ -defined('MOODLE_INTERNAL') || die(); - /** * Structure step to restore poster activity instance. * @@ -39,7 +37,7 @@ class restore_poster_activity_structure_step extends restore_activity_structure_ * @return array of restore_path_element */ protected function define_structure() { - return $this->prepare_activity_structure(array(new restore_path_element('poster', '/activity/poster'))); + return $this->prepare_activity_structure([new restore_path_element('poster', '/activity/poster')]); } /** diff --git a/classes/event/course_module_instance_list_viewed.php b/classes/event/course_module_instance_list_viewed.php index 83df464..39c5f2c 100644 --- a/classes/event/course_module_instance_list_viewed.php +++ b/classes/event/course_module_instance_list_viewed.php @@ -25,7 +25,6 @@ namespace mod_poster\event; -defined('MOODLE_INTERNAL') || die(); /** * Class of the mod_poster instances list viewed events. diff --git a/classes/event/course_module_viewed.php b/classes/event/course_module_viewed.php index 23887de..543b0ef 100644 --- a/classes/event/course_module_viewed.php +++ b/classes/event/course_module_viewed.php @@ -25,8 +25,6 @@ namespace mod_poster\event; -defined('MOODLE_INTERNAL') || die(); - /** * Class of the mod_poster course module viewed events. * diff --git a/classes/poster.php b/classes/poster.php new file mode 100644 index 0000000..2785c26 --- /dev/null +++ b/classes/poster.php @@ -0,0 +1,122 @@ +. + +/** + * Define poster class. + * @package mod_poster + * @copyright bdecent gmbh 2023 + * based on the work by + * 2015 David Mudrak and + * 2019 Harald, David und Nicklas @devcamp19 + * + * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later + */ + +namespace mod_poster; + +use mod_poster\event\course_module_viewed; +use completion_info; + +/** + * Class poster + * + * @package mod_poster + */ +class poster { + + /** + * @var mixed|object|false fetched from get_record. + */ + protected $settings; + + /** + * @var mixed course fetched from DB. + */ + protected $course; + + /** + * @var \cm_info + */ + protected $cm; + + /** + * poster constructor. + * + * @param \cm_info|\stdClass $cm + * @throws \dml_exception + */ + public function __construct($cm) { + global $DB; + $this->settings = $DB->get_record('poster', ['id' => $cm->instance], '*', MUST_EXIST); + $this->course = $DB->get_record('course', ['id' => $cm->course], '*', MUST_EXIST); + $this->cm = $cm; + } + + /** + * Get settings saved in DB for the poster module. + * + * @return false|mixed|object + */ + public function get_settings() { + return $this->settings; + } + + /** + * Get course settings. + * + * @return false|mixed|object + */ + public function get_course() { + return $this->course; + } + + /** + * Set up the page for displaying the content. + * + * @param \moodle_page $page + */ + public function setup_page(\moodle_page &$page) { + $page->set_url('/mod/poster/view.php', ['id' => $this->cm->id]); + $page->set_title($this->course->shortname.': '.$this->settings->name); + $page->set_heading($this->course->fullname); + $page->set_activity_record($this->settings); + // Define the custom block regions we want to use at the poster view page. + // Region names are limited to 16 characters. + $page->blocks->add_region('mod_poster-pre', true); + $page->blocks->add_region('mod_poster-post', true); + } + + /** + * Trigger module view. + * @param \context $context + */ + public function trigger_module_viewed(\context $context) { + // Trigger module viewed event. + $event = course_module_viewed::create([ + 'objectid' => $this->settings->id, + 'context' => $context, + ]); + $event->add_record_snapshot('course_modules', $this->cm); + $event->add_record_snapshot('course', $this->course); + $event->add_record_snapshot('poster', $this->settings); + $event->trigger(); + + // Mark the module instance as viewed by the current user. + $completion = new completion_info($this->course); + $completion->set_module_viewed($this->cm); + } + +} diff --git a/classes/privacy/provider.php b/classes/privacy/provider.php index 5be696c..3c41ed6 100644 --- a/classes/privacy/provider.php +++ b/classes/privacy/provider.php @@ -25,8 +25,6 @@ namespace mod_poster\privacy; -defined('MOODLE_INTERNAL') || die(); - /** * Privacy API implementation for the Poster plugin. * diff --git a/db/access.php b/db/access.php index cc580a7..b4ff644 100644 --- a/db/access.php +++ b/db/access.php @@ -25,30 +25,30 @@ defined('MOODLE_INTERNAL') || die(); -$capabilities = array( +$capabilities = [ // Ability to add instance of the module to the course. - 'mod/poster:addinstance' => array( + 'mod/poster:addinstance' => [ 'riskbitmask' => RISK_XSS, 'captype' => 'write', 'contextlevel' => CONTEXT_COURSE, - 'archetypes' => array( + 'archetypes' => [ 'editingteacher' => CAP_ALLOW, - 'manager' => CAP_ALLOW - ), - 'clonepermissionsfrom' => 'moodle/course:manageactivities' - ), + 'manager' => CAP_ALLOW, + ], + 'clonepermissionsfrom' => 'moodle/course:manageactivities', + ], // Ability to view the poster instance. - 'mod/poster:view' => array( + 'mod/poster:view' => [ 'captype' => 'read', 'contextlevel' => CONTEXT_MODULE, - 'archetypes' => array( + 'archetypes' => [ 'guest' => CAP_ALLOW, 'student' => CAP_ALLOW, 'teacher' => CAP_ALLOW, 'editingteacher' => CAP_ALLOW, - 'manager' => CAP_ALLOW - ) - ), -); + 'manager' => CAP_ALLOW, + ], + ], +]; diff --git a/db/install.xml b/db/install.xml index 4cc7879..be9b74c 100644 --- a/db/install.xml +++ b/db/install.xml @@ -15,6 +15,7 @@ + diff --git a/db/upgrade.php b/db/upgrade.php index c9b8837..a278cdf 100644 --- a/db/upgrade.php +++ b/db/upgrade.php @@ -23,8 +23,6 @@ * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later */ -defined('MOODLE_INTERNAL') || die(); - /** * Performs the poster upgrade steps. * @@ -36,5 +34,17 @@ function xmldb_poster_upgrade($oldversion) { $dbman = $DB->get_manager(); + if ($oldversion < 2023112701) { + // Add new fields to poster table. + $table = new xmldb_table('poster'); + $field = new xmldb_field('display'); + $field->set_attributes(XMLDB_TYPE_INTEGER, '4', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, '0', 'showdescriptionview'); + if (!$dbman->field_exists($table, $field)) { + $dbman->add_field($table, $field); + } + + // Poster savepoint reached. + upgrade_mod_savepoint(true, 2023112701, 'poster'); + } return true; } diff --git a/index.php b/index.php index 647e39f..1bdc456 100644 --- a/index.php +++ b/index.php @@ -26,20 +26,20 @@ $id = required_param('id', PARAM_INT); -$course = $DB->get_record('course', array('id' => $id), '*', MUST_EXIST); +$course = $DB->get_record('course', ['id' => $id], '*', MUST_EXIST); require_course_login($course, true); $PAGE->set_pagelayout('incourse'); -$PAGE->set_url('/mod/poster/index.php', array('id' => $course->id)); +$PAGE->set_url('/mod/poster/index.php', ['id' => $course->id]); $PAGE->set_title($course->shortname.': '.get_string('modulenameplural', 'mod_poster')); $PAGE->set_heading($course->fullname); $PAGE->navbar->add(get_string('modulenameplural', 'mod_poster')); // Trigger instances list viewed event. -$event = \mod_poster\event\course_module_instance_list_viewed::create(array( - 'context' => context_course::instance($course->id) -)); +$event = \mod_poster\event\course_module_instance_list_viewed::create([ + 'context' => context_course::instance($course->id), +]); $event->add_record_snapshot('course', $course); $event->trigger(); @@ -48,7 +48,7 @@ if (!$posters = get_all_instances_in_course('poster', $course)) { notice(get_string('thereareno', 'core', get_string('modulenameplural', 'mod_poster')), - new moodle_url('/course/view.php', array('id' => $course->id))); + new moodle_url('/course/view.php', ['id' => $course->id])); } $usesections = course_format_uses_sections($course->format); @@ -57,20 +57,20 @@ $table->attributes['class'] = 'generaltable mod_index'; if ($usesections) { - $table->head = array( + $table->head = [ get_string('sectionname', 'format_'.$course->format), get_string('postername', 'mod_poster'), - get_string('moduleintro', 'core') - ); - $table->align = array('center', 'left', 'left'); + get_string('moduleintro', 'core'), + ]; + $table->align = ['center', 'left', 'left']; } else { - $table->head = array( + $table->head = [ get_string('lastmodified', 'core'), get_string('postername', 'mod_poster'), - get_string('moduleintro', 'core') - ); - $table->align = array('left', 'left', 'left'); + get_string('moduleintro', 'core'), + ]; + $table->align = ['left', 'left', 'left']; } $modinfo = get_fast_modinfo($course); @@ -93,15 +93,15 @@ $printsection = html_writer::span(userdate($poster->timemodified), 'smallinfo'); } - $table->data[] = array( + $table->data[] = [ $printsection, html_writer::link( - new moodle_url('view.php', array('id' => $cm->id)), + new moodle_url('view.php', ['id' => $cm->id]), format_string($poster->name), - array('class' => $poster->visible ? '' : 'dimmed') + ['class' => $poster->visible ? '' : 'dimmed'] ), - format_module_intro('poster', $poster, $cm->id) - ); + format_module_intro('poster', $poster, $cm->id), + ]; } echo html_writer::table($table); diff --git a/lang/en/poster.php b/lang/en/poster.php index 43ff877..75fd4d2 100644 --- a/lang/en/poster.php +++ b/lang/en/poster.php @@ -44,3 +44,10 @@ $string['showdescriptionview_help'] = 'If enabled, the description above will be displayed on the poster page.'; $string['shownameview'] = 'Display name on view page'; $string['shownameview_help'] = 'If enabled, the poster name will be displayed as heading on the poster page.'; + +$string['displaypage'] = 'Display poster on separate page'; +$string['displayinline'] = 'Display poster on course page'; +$string['display'] = 'Choose where to display the poster contents'; +$string['display_help'] = 'This module allows you to display blocks directly on the course page or in a separate page.'; +$string['editlabelmessage'] = 'These blocks should be edited on Poster view page'; +$string['editlabelbutton'] = 'Go to view page'; diff --git a/lib.php b/lib.php index b96b600..916e82a 100644 --- a/lib.php +++ b/lib.php @@ -22,7 +22,11 @@ * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later */ -defined('MOODLE_INTERNAL') || die(); +use mod_poster\poster; + + +define('POSTER_DISPLAY_PAGE', 0); +define('POSTER_DISPLAY_INLINE', 1); /** * Returns the information if the module supports a feature @@ -102,49 +106,112 @@ function poster_update_instance(stdClass $poster) { function poster_delete_instance($id) { global $DB; - if (! $poster = $DB->get_record('poster', array('id' => $id))) { + if (! $poster = $DB->get_record('poster', ['id' => $id])) { return false; } - $DB->delete_records('poster', array('id' => $poster->id)); + $DB->delete_records('poster', ['id' => $poster->id]); return true; } /** - * Adds items into the poster administration block + * Return the page type patterns that can be used by blocks * - * @param settings_navigation $settingsnav The settings navigation object - * @param navigation_node $node The node to add module settings to + * @param string $pagetype Current page type + * @param stdClass $parentcontext Block's parent context + * @param stdClass $currentcontext Current context of block */ -function poster_extend_settings_navigation(settings_navigation $settingsnav, navigation_node $node) { - global $PAGE; +function poster_page_type_list($pagetype, $parentcontext, $currentcontext) { + return [ + 'mod-poster-view' => get_string('page-mod-poster-view', 'mod_poster'), + ]; +} - if ($PAGE->user_allowed_editing()) { - $url = $PAGE->url; - $url->param('sesskey', sesskey()); - if ($PAGE->user_is_editing()) { - $url->param('edit', 'off'); - $editstring = get_string('turneditingoff', 'core'); - } else { - $url->param('edit', 'on'); - $editstring = get_string('turneditingon', 'core'); +/** + * Given a coursemodule object, this function returns the extra + * information needed to print this activity in various places. + * + * If poster needs to be displayed inline we store additional information + * in customdata, so functions {See poster_cm_info_dynamic()} and + * {See poster_cm_info_view()} do not need to do DB queries + * + * @param cm_info $cm + * @return cached_cm_info info + */ +function poster_get_coursemodule_info($cm) { + global $DB; + if (!($poster = $DB->get_record('poster', ['id' => $cm->instance], + 'id, name, display, showdescriptionview, intro, introformat'))) { + return null; + } + $cminfo = new cached_cm_info(); + $cminfo->name = $poster->name; + if ($poster->display == POSTER_DISPLAY_INLINE) { + // Prepare poster object to store in customdata. + $fdata = new stdClass(); + $fdata->showdescriptionview = $poster->showdescriptionview; + if ($cm->showdescription && strlen(trim($poster->intro))) { + $fdata->intro = $poster->intro; + if ($poster->introformat != FORMAT_MOODLE) { + $fdata->introformat = $poster->introformat; + } } + $cminfo->customdata = $fdata; + } else { + if ($cm->showdescription) { + // Convert intro to html. Do not filter cached version, filters run at display time. + $cminfo->content = format_module_intro('poster', $poster, $cm->id, false); + } + } + return $cminfo; +} - $node->add($editstring, $url, navigation_node::TYPE_SETTING); +/** + * Sets dynamic information about a course module + * + * This function is called from cm_info when displaying the module + * mod_poster can be displayed inline on course page and therefore have no course link + * + * @param cm_info $cm + */ +function poster_cm_info_dynamic(cm_info $cm) { + if ($cm->customdata) { + // The field 'customdata' is not empty IF AND ONLY IF we display contens inline. + $cm->set_no_view_link(); } } /** - * Return the page type patterns that can be used by blocks + * Overwrites the content in the course-module object with the poster files list + * if poster.display == POSTER_DISPLAY_INLINE * - * @param string $pagetype Current page type - * @param stdClass $parentcontext Block's parent context - * @param stdClass $currentcontext Current context of block + * @param cm_info $cminfo */ -function poster_page_type_list($pagetype, $parentcontext, $currentcontext) { - return array( - 'mod-poster-view' => get_string('page-mod-poster-view', 'mod_poster'), - ); +function poster_cm_info_view(cm_info $cminfo) { + global $PAGE, $OUTPUT; + $poster = new poster($cminfo); + + if ($cminfo->uservisible && $cminfo->customdata && has_capability('mod/poster:view', $cminfo->context)) { + // Restore poster object from customdata. + // Note the field 'customdata' is not empty IF AND ONLY IF we display contens inline. + // Otherwise the content is default. + $context = context_module::instance($cminfo->id); + $page = new moodle_page(); + $page->set_context($context); + $page->set_cm($cminfo); + $poster->setup_page($page); + $output = $page->get_renderer('mod_poster'); + if (!$PAGE->user_is_editing()) { + $page->blocks->load_blocks(); + $content = $output->view_page_content($poster); + } else { + $url = new moodle_url('/mod/poster/view.php', ['id' => $cminfo->id]); + $content = $OUTPUT->render_from_template('mod_poster/edit_label', [ + 'url' => $url->out(), + ]); + } + $cminfo->set_content($content); + } } diff --git a/mod_form.php b/mod_form.php index e2e5827..54e4760 100644 --- a/mod_form.php +++ b/mod_form.php @@ -46,11 +46,21 @@ public function definition() { $mform->addElement('header', 'general', get_string('general', 'core_form')); // Add the poster name field. - $mform->addElement('text', 'name', get_string('postername', 'mod_poster'), array('size' => '64')); + $mform->addElement('text', 'name', get_string('postername', 'mod_poster'), ['size' => '64']); $mform->setType('name', PARAM_TEXT); $mform->addRule('name', null, 'required', null, 'client'); $mform->addRule('name', get_string('maximumchars', 'core', 255), 'maxlength', 255, 'client'); + // Add the option to display the content on the course page. + $mform->addElement('select', 'display', get_string('display', 'mod_poster'), + [POSTER_DISPLAY_PAGE => get_string('displaypage', 'mod_poster'), + POSTER_DISPLAY_INLINE => get_string('displayinline', 'mod_poster'), ]); + $mform->addHelpButton('display', 'display', 'mod_poster'); + if (!$this->courseformat->has_view_page()) { + $mform->setConstant('display', POSTER_DISPLAY_PAGE); + $mform->hardFreeze('display'); + } + // Add the show name at the view page field. $mform->addElement('advcheckbox', 'shownameview', get_string('shownameview', 'mod_poster')); $mform->addHelpButton('shownameview', 'shownameview', 'mod_poster'); diff --git a/pix/monologo.svg b/pix/monologo.svg new file mode 100644 index 0000000..a3492ef --- /dev/null +++ b/pix/monologo.svg @@ -0,0 +1,5 @@ + + + + + diff --git a/renderer.php b/renderer.php index 9df8c1b..b67dd02 100644 --- a/renderer.php +++ b/renderer.php @@ -23,7 +23,6 @@ * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later */ -defined('MOODLE_INTERNAL') || die(); /** * The renderer for poster module @@ -94,7 +93,7 @@ protected function view_page_description($poster) { * @param stdClass $poster The poster instance record * @return string */ - protected function view_page_content($poster) { + public function view_page_content($poster) { $out = ''; @@ -114,30 +113,30 @@ protected function view_page_content($poster) { $cssclassmain .= $haspre ? '' : ' empty-region-mod_poster-pre'; $cssclassmain .= $haspost ? '' : ' empty-region-mod_poster-post'; - $out .= html_writer::start_div($cssclassmain, array('id' => 'mod_poster-content')); - $out .= html_writer::start_div('row'); + $out .= \html_writer::start_div($cssclassmain, ['id' => 'mod_poster-content']); + $out .= \html_writer::start_div('row ml-0 mr-0'); $cssclassgrid = 'col-md-6'; $cssclasssingle = 'col-md-12'; if ($haspre) { - $out .= html_writer::start_div($haspost ? $cssclassgrid : $cssclasssingle); - $out .= html_writer::start_div('mod_poster-content-region', array('id' => 'mod_poster-content-region-pre')); + $out .= \html_writer::start_div(($haspost ? $cssclassgrid : $cssclasssingle) . ' pl-0 pr-0 '); + $out .= \html_writer::start_div('mod_poster-content-region', ['id' => 'mod_poster-content-region-pre']); $out .= $this->custom_block_region('mod_poster-pre'); - $out .= html_writer::end_div(); - $out .= html_writer::end_div(); + $out .= \html_writer::end_div(); + $out .= \html_writer::end_div(); } if ($haspost) { - $out .= html_writer::start_div($haspre ? $cssclassgrid : $cssclasssingle); - $out .= html_writer::start_div('mod_poster-content-region', array('id' => 'mod_poster-content-region-post')); + $out .= \html_writer::start_div($haspre ? $cssclassgrid : $cssclasssingle); + $out .= \html_writer::start_div('mod_poster-content-region', ['id' => 'mod_poster-content-region-post']); $out .= $this->custom_block_region('mod_poster-post'); - $out .= html_writer::end_div(); - $out .= html_writer::end_div(); + $out .= \html_writer::end_div(); + $out .= \html_writer::end_div(); } - $out .= html_writer::end_div(); - $out .= html_writer::end_div(); + $out .= \html_writer::end_div(); + $out .= \html_writer::end_div(); return $out; } diff --git a/styles.css b/styles.css index 2f076ce..4d9d26a 100644 --- a/styles.css +++ b/styles.css @@ -16,3 +16,14 @@ margin-bottom: 5px; min-height: 10em; } + +.section .poster .mod-indent-outer { + padding-left: 24px; + display: block; +} + +/* Make sure the poster blocks content width to available. */ +.course-content .modtype_poster.activity .description .description-inner { + width: 100%; + margin-top: 15px; +} diff --git a/templates/edit_label.mustache b/templates/edit_label.mustache new file mode 100644 index 0000000..8e65c5a --- /dev/null +++ b/templates/edit_label.mustache @@ -0,0 +1,42 @@ +{{! + 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 . +}} +{{! + @template mod_poster/edit_label + + This template for editing blocks on course page + + Variables required for this template: + + Variables optional for this template: + * url - link to module page + + Example context (json): + { + "url": "http://school.edu/mod/poster/view.php?id=30" + } + +}} +
+
+ {{# str }} editlabelmessage, mod_poster {{/ str }} +
+ +
diff --git a/tests/behat/add_blocks.feature b/tests/behat/add_blocks.feature index 1cfdad3..83c2eed 100644 --- a/tests/behat/add_blocks.feature +++ b/tests/behat/add_blocks.feature @@ -20,18 +20,17 @@ Feature: Adding blocks to the poster page | activity | name | intro | course | idnumber | | poster | Poster 003 | This is a test poster 003. | C1 | poster003 | And I log in as "teacher1" - And I am on "Course 001" course homepage - And I turn editing mode on - And I follow "Poster 003" - And I add the "HTML" poster block - And I configure the "(new HTML block)" block + And I am on "Course 001" course homepage with editing mode on + And I am on the "Poster 003" "poster activity" page + And I select "html" from the "bui_addblock" singleselect + And I configure the "(new text block)" block And I set the field "config_title" to "Created in poster context" And I set the field "Content" to "This is first HTML block displayed at a poster page" And I set the field "Region" to "mod_poster-pre" And I press "Save changes" - And I am on "Course 001" course homepage - And I add the "HTML" block - And I configure the "(new HTML block)" block + And I am on "Course 001" course homepage with editing mode on + And I add the "Text" block + And I configure the "(new text block)" block And I set the field "config_title" to "Created in course context" And I set the field "Content" to "This is second HTML block displayed at a poster page" And I set the field "Display on page types" to "Any page" @@ -41,7 +40,7 @@ Feature: Adding blocks to the poster page And I set the field "Display on page types" to "Poster module main page" And I set the field "Region" to "mod_poster-pre" And I press "Save changes" - And I add the "Logged in user" poster block + And I select "Logged in user" from the "bui_addblock" singleselect And I configure the "Logged in user" block And I set the field "Region" to "mod_poster-post" And I press "Save changes" diff --git a/tests/behat/add_poster.feature b/tests/behat/add_poster.feature index c10b68d..8860ee7 100644 --- a/tests/behat/add_poster.feature +++ b/tests/behat/add_poster.feature @@ -1,4 +1,4 @@ -@mod @mod_poster +@mod @mod_poster @add_poster Feature: Adding poster activity In order to display blocks not only on the course page side bars As a teacher @@ -23,7 +23,7 @@ Feature: Adding poster activity When I log in as "student1" And I am on "Course 001" course homepage And I follow "Poster 001" - Then I should see "This is a test poster 001." + Then I should see "This is a test poster 001." in the "#mod_poster-description" "css_element" And I am on "Course 001" course homepage And I follow "Poster 002" - And I should not see "This is a test poster 002." + And "#mod_poster-description" "css_element" should not exist diff --git a/tests/behat/behat_mod_poster.php b/tests/behat/behat_mod_poster.php deleted file mode 100644 index a15f484..0000000 --- a/tests/behat/behat_mod_poster.php +++ /dev/null @@ -1,64 +0,0 @@ -. - -/** - * Provide the {@see behat_mod_poster} class. - * - * @package mod_poster - * @category test - * @copyright 2017 David Mudrák - * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later - */ - -// NOTE: no MOODLE_INTERNAL test here, this file may be required by behat before including /config.php. - -require_once(__DIR__ . '/../../../../lib/behat/behat_base.php'); - -/** - * Define the Poster module's behat steps. - * - * The poster module changes the default look & behaviour of the "add-block" widget so that it looks like the drop down - * selector even in Boost based theme (where it would normally be displayed as a link in the flat navigation). As a - * consequence, we can't use the default step {@see i_add_the_block()} because it would fail in Boost (the expected - * link is not in the flat navigation). - * - * Instead, we define a custom step as a copy of the {@see behat_blocks::i_add_the_block()} that expects the default - * drop down selector. - * - * @copyright 2017 David Mudrak - * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later - */ -class behat_mod_poster extends behat_base { - - /** - * Adds the selected block. Editing mode must be previously enabled. - * - * @Given /^I add the "(?P(?:[^"]|\\")*)" poster block$/ - * @param string $blockname - */ - public function i_add_the_poster_block($blockname) { - $this->execute('behat_forms::i_set_the_field_to', - array("bui_addblock", $this->escape($blockname)) - ); - - // If we are running without javascript we need to submit the form. - if (!$this->running_javascript()) { - $this->execute('behat_general::i_click_on_in_the', - array(get_string('go'), "button", "#add_block", "css_element") - ); - } - } -} diff --git a/tests/generator_test.php b/tests/mod_poster_generator_test.php similarity index 79% rename from tests/generator_test.php rename to tests/mod_poster_generator_test.php index d94376c..5024427 100644 --- a/tests/generator_test.php +++ b/tests/mod_poster_generator_test.php @@ -14,18 +14,30 @@ // You should have received a copy of the GNU General Public License // along with Moodle. If not, see . + +/** + * Poster activity testcases. + * + * @package mod_poster + * @copyright 2021 bdecent gmbh + * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later + */ +namespace mod_poster; + + /** * Poster module generator tests. * * @package mod_poster * @category test - * @copyright 2021 David Mudrák + * @copyright 2021 bdecent gmbh * @license https://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later */ -class mod_poster_generator_test extends advanced_testcase { +class mod_poster_generator_test extends \advanced_testcase { /** * Test {@see mod_poster_generator::create_instance()}. + * @covers ::create_instance */ public function test_create_instance() { global $DB; diff --git a/version.php b/version.php index 880676b..676f4c9 100644 --- a/version.php +++ b/version.php @@ -18,14 +18,17 @@ * Provides meta-information about the plugin. * * @package mod_poster - * @copyright 2015 David Mudrak + * @copyright bdecent gmbh 2023 + * based on the work by David Mudrak + * * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later */ defined('MOODLE_INTERNAL') || die(); $plugin->component = 'mod_poster'; -$plugin->release = '6.0.1'; -$plugin->version = 2021022101; +$plugin->release = '7.0.0'; +$plugin->version = 2023120100; $plugin->requires = 2020061500; $plugin->maturity = MATURITY_STABLE; +$plugin->supported = [401, 403]; diff --git a/view.php b/view.php index 2d08d9e..2f9584d 100644 --- a/view.php +++ b/view.php @@ -22,6 +22,9 @@ * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later */ + +use mod_poster\poster; + require(__DIR__.'/../../config.php'); require_once($CFG->libdir.'/completionlib.php'); @@ -29,41 +32,21 @@ $edit = optional_param('edit', null, PARAM_BOOL); $cm = get_coursemodule_from_id('poster', $cmid, 0, false, MUST_EXIST); -$course = $DB->get_record('course', array('id' => $cm->course), '*', MUST_EXIST); -$poster = $DB->get_record('poster', array('id' => $cm->instance), '*', MUST_EXIST); +$poster = new poster($cm); +$course = $poster->get_course(); +$posterdata = $poster->get_settings(); -require_login($course, true, $cm); +require_course_login($course, true, $cm); require_capability('mod/poster:view', $PAGE->context); -$PAGE->set_url('/mod/poster/view.php', array('id' => $cm->id)); -$PAGE->set_title($course->shortname.': '.$poster->name); -$PAGE->set_heading($course->fullname); -$PAGE->set_activity_record($poster); +$poster->setup_page($PAGE); -if ($edit !== null and confirm_sesskey() and $PAGE->user_allowed_editing()) { +if ($edit !== null && confirm_sesskey() && $PAGE->user_allowed_editing()) { $USER->editing = $edit; redirect($PAGE->url); } -// Trigger module viewed event. -$event = \mod_poster\event\course_module_viewed::create(array( - 'objectid' => $poster->id, - 'context' => $PAGE->context, -)); -$event->add_record_snapshot('course_modules', $cm); -$event->add_record_snapshot('course', $course); -$event->add_record_snapshot('poster', $poster); -$event->trigger(); - -// Mark the module instance as viewed by the current user. -$completion = new completion_info($course); -$completion->set_module_viewed($cm); - -// Define the custom block regions we want to use at the poster view page. -// Region names are limited to 16 characters. -$PAGE->blocks->add_region('mod_poster-pre', true); -$PAGE->blocks->add_region('mod_poster-post', true); - +$poster->trigger_module_viewed($PAGE->context); $output = $PAGE->get_renderer('mod_poster'); -echo $output->view_page($poster); +echo $output->view_page($posterdata);