Merge branch 'wip-MDL-55327-master' of git://github.com/abgreeve/moodle
This commit is contained in:
@@ -155,6 +155,7 @@ $string['displayscorewithessays'] = '<p>You earned {$a->score} out of {$a->tempm
|
||||
<p>Your {$a->essayquestions} essay question(s) will be graded and added into your final score at a later date.</p>
|
||||
<p>Your current grade without the essay question(s) is {$a->score} out of {$a->grade}.</p>';
|
||||
$string['displayscorewithoutessays'] = 'Your score is {$a->score} (out of {$a->grade}).';
|
||||
$string['duplicatepagenamed'] = 'Duplicate page: {$a}';
|
||||
$string['edit'] = 'Edit';
|
||||
$string['editingquestionpage'] = 'Editing {$a} question page';
|
||||
$string['editlessonsettings'] = 'Edit lesson settings';
|
||||
|
||||
@@ -23,6 +23,7 @@
|
||||
* delete
|
||||
* move
|
||||
* moveit
|
||||
* duplicate
|
||||
* @package mod_lesson
|
||||
* @copyright 1999 onwards Martin Dougiamas {@link http://moodle.com}
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
@@ -129,6 +130,10 @@ switch ($action) {
|
||||
$lesson->resort_pages($pageid, $after);
|
||||
redirect("$CFG->wwwroot/mod/lesson/edit.php?id=$cm->id");
|
||||
break;
|
||||
case 'duplicate':
|
||||
$lesson->duplicate_page($pageid);
|
||||
redirect(new moodle_url('/mod/lesson/edit.php', array('id' => $cm->id)));
|
||||
break;
|
||||
default:
|
||||
print_error('unknowaction');
|
||||
break;
|
||||
|
||||
@@ -1662,6 +1662,93 @@ class lesson extends lesson_base {
|
||||
return $this->pages;
|
||||
}
|
||||
|
||||
/**
|
||||
* Duplicate the lesson page.
|
||||
*
|
||||
* @param int $pageid Page ID of the page to duplicate.
|
||||
* @return void.
|
||||
*/
|
||||
public function duplicate_page($pageid) {
|
||||
global $PAGE;
|
||||
$cm = get_coursemodule_from_instance('lesson', $this->properties->id, $this->properties->course);
|
||||
$context = context_module::instance($cm->id);
|
||||
// Load the page.
|
||||
$page = $this->load_page($pageid);
|
||||
$properties = $page->properties();
|
||||
// The create method checks to see if these properties are set and if not sets them to zero, hence the unsetting here.
|
||||
if (!$properties->qoption) {
|
||||
unset($properties->qoption);
|
||||
}
|
||||
if (!$properties->layout) {
|
||||
unset($properties->layout);
|
||||
}
|
||||
if (!$properties->display) {
|
||||
unset($properties->display);
|
||||
}
|
||||
|
||||
$properties->pageid = $pageid;
|
||||
// Add text and format into the format required to create a new page.
|
||||
$properties->contents_editor = array(
|
||||
'text' => $properties->contents,
|
||||
'format' => $properties->contentsformat
|
||||
);
|
||||
$answers = $page->get_answers();
|
||||
// Answers need to be added to $properties.
|
||||
$i = 0;
|
||||
$answerids = array();
|
||||
foreach ($answers as $answer) {
|
||||
// Needs to be rearranged to work with the create function.
|
||||
$properties->answer_editor[$i] = array(
|
||||
'text' => $answer->answer,
|
||||
'format' => $answer->answerformat
|
||||
);
|
||||
|
||||
$properties->response_editor[$i] = array(
|
||||
'text' => $answer->response,
|
||||
'format' => $answer->responseformat
|
||||
);
|
||||
$answerids[] = $answer->id;
|
||||
|
||||
$properties->jumpto[$i] = $answer->jumpto;
|
||||
$properties->score[$i] = $answer->score;
|
||||
|
||||
$i++;
|
||||
}
|
||||
// Create the duplicate page.
|
||||
$newlessonpage = lesson_page::create($properties, $this, $context, $PAGE->course->maxbytes);
|
||||
$newanswers = $newlessonpage->get_answers();
|
||||
// Copy over the file areas as well.
|
||||
$this->copy_page_files('page_contents', $pageid, $newlessonpage->id, $context->id);
|
||||
$j = 0;
|
||||
foreach ($newanswers as $answer) {
|
||||
if (strpos($answer->answer, '@@PLUGINFILE@@') !== false) {
|
||||
$this->copy_page_files('page_answers', $answerids[$j], $answer->id, $context->id);
|
||||
}
|
||||
if (strpos($answer->response, '@@PLUGINFILE@@') !== false) {
|
||||
$this->copy_page_files('page_responses', $answerids[$j], $answer->id, $context->id);
|
||||
}
|
||||
$j++;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Copy the files from one page to another.
|
||||
*
|
||||
* @param string $filearea Area that the files are stored.
|
||||
* @param int $itemid Item ID.
|
||||
* @param int $newitemid The item ID for the new page.
|
||||
* @param int $contextid Context ID for this page.
|
||||
* @return void.
|
||||
*/
|
||||
protected function copy_page_files($filearea, $itemid, $newitemid, $contextid) {
|
||||
$fs = get_file_storage();
|
||||
$files = $fs->get_area_files($contextid, 'mod_lesson', $filearea, $itemid);
|
||||
foreach ($files as $file) {
|
||||
$fieldupdates = array('itemid' => $newitemid);
|
||||
$fs->create_file_from_storedfile($fieldupdates, $file);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Determines if a jumpto value is correct or not.
|
||||
*
|
||||
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 176 B |
@@ -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="M16 7v9H6v-4H0V0h7l3 3v1h3l3 3zM1 11h8V4H6V1H1v10zm6-8h1.6L7 1.4V3zm8 5h-3V5h-2v7H7v3h8V8zm-2-1h1.6L13 5.4V7z" fill="#999"/></svg>
|
||||
|
After Width: | Height: | Size: 434 B |
@@ -414,6 +414,13 @@ class mod_lesson_renderer extends plugin_renderer_base {
|
||||
$img = html_writer::img($this->output->pix_url('t/edit'), $label, array('class' => 'iconsmall'));
|
||||
$actions[] = html_writer::link($url, $img, array('title' => $label));
|
||||
|
||||
// Duplicate action.
|
||||
$url = new moodle_url('/mod/lesson/lesson.php', array('id' => $this->page->cm->id, 'pageid' => $page->id,
|
||||
'action' => 'duplicate', 'sesskey' => sesskey()));
|
||||
$label = get_string('duplicatepagenamed', 'lesson', format_string($page->title));
|
||||
$img = html_writer::img($this->output->pix_url('e/copy', 'mod_lesson'), $label, array('class' => 'iconsmall'));
|
||||
$actions[] = html_writer::link($url, $img, array('title' => $label));
|
||||
|
||||
$url = new moodle_url('/mod/lesson/view.php', array('id' => $this->page->cm->id, 'pageid' => $page->id));
|
||||
$label = get_string('previewpagenamed', 'lesson', format_string($page->title));
|
||||
$img = html_writer::img($this->output->pix_url('t/preview'), $label, array('class' => 'iconsmall'));
|
||||
|
||||
@@ -0,0 +1,132 @@
|
||||
@mod @mod_lesson
|
||||
Feature: In a lesson activity, a teacher can duplicate a lesson page
|
||||
In order to duplicate a lesson page
|
||||
As a teacher
|
||||
I need to add content to a lesson
|
||||
|
||||
Background:
|
||||
Given the following "users" exist:
|
||||
| username | firstname | lastname | email |
|
||||
| teacher1 | Teacher | 1 | teacher1@example.com |
|
||||
| student1 | Student | 1 | student1@example.com |
|
||||
And the following "courses" exist:
|
||||
| fullname | shortname | category |
|
||||
| Course 1 | C1 | 0 |
|
||||
And the following "course enrolments" exist:
|
||||
| user | course | role |
|
||||
| teacher1 | C1 | editingteacher |
|
||||
| student1 | C1 | student |
|
||||
And I log in as "teacher1"
|
||||
And I follow "Manage private files"
|
||||
And I upload "mod/lesson/tests/fixtures/moodle_logo.jpg" file to "Files" filemanager
|
||||
And I click on "Save changes" "button"
|
||||
When I am on homepage
|
||||
And I follow "Course 1"
|
||||
And I turn editing mode on
|
||||
And I add a "Lesson" to section "1" and I fill the form with:
|
||||
| Name | Test lesson name |
|
||||
| Description | Test lesson description |
|
||||
|
||||
@javascript
|
||||
Scenario: Duplicate content page with an image.
|
||||
Given I follow "Test lesson name"
|
||||
And I follow "Add a content page"
|
||||
And I set the following fields to these values:
|
||||
| Page title | First page name |
|
||||
| Page contents | First page contents |
|
||||
| id_answer_editor_0 | Next page |
|
||||
| id_jumpto_0 | Next page |
|
||||
| id_answer_editor_1 | Previous page |
|
||||
| id_jumpto_1 | Previous page |
|
||||
# Atto needs focus to add image, select empty p tag to do so.
|
||||
And I select the text in the "id_contents_editor" Atto editor
|
||||
And I click on "Image" "button" in the "#fitem_id_contents_editor" "css_element"
|
||||
And I click on "Browse repositories..." "button"
|
||||
And I click on "Private files" "link"
|
||||
And I click on "moodle_logo.jpg" "link"
|
||||
And I click on "Select this file" "button"
|
||||
And I set the field "Describe this image for someone who cannot see it" to "It's the logo"
|
||||
And I click on "Save image" "button"
|
||||
And I press "Save page"
|
||||
And I follow "Duplicate page: First page name"
|
||||
And I should see "Inserted page: First page name"
|
||||
And I follow "Update page: First page name"
|
||||
And I set the field "Page title" to "Introduction page"
|
||||
And I press "Save page"
|
||||
When I follow "Update page: First page name"
|
||||
And I should see "First page name"
|
||||
Then "//*[contains(@id, 'id_contents_editor')]//img[contains(@src, 'moodle_logo.jpg')]" "xpath_element" should exist
|
||||
|
||||
@javascript
|
||||
Scenario: Duplicate question page with image in answer.
|
||||
Given I follow "Test lesson name"
|
||||
And I follow "Add a question page"
|
||||
And I set the field "Select a question type" to "True/false"
|
||||
And I press "Add a question page"
|
||||
And I set the following fields to these values:
|
||||
| Page title | True false with an image in the answer |
|
||||
| Page contents | Select the picture |
|
||||
| id_answer_editor_0 | To be replaced |
|
||||
| id_response_editor_0 | Correct answer |
|
||||
| id_jumpto_0 | End of lesson |
|
||||
| id_score_0 | 1 |
|
||||
| id_answer_editor_1 | 1 |
|
||||
| id_response_editor_1 | Incorrect answer |
|
||||
| id_jumpto_1 | This page |
|
||||
| id_score_1 | 0 |
|
||||
# Atto needs focus to add image, select empty p tag to do so.
|
||||
And I select the text in the "id_answer_editor_0" Atto editor
|
||||
And I click on "Image" "button" in the "#fitem_id_answer_editor_0" "css_element"
|
||||
And I click on "Browse repositories..." "button"
|
||||
And I click on "Private files" "link"
|
||||
And I click on "moodle_logo.jpg" "link"
|
||||
And I click on "Select this file" "button"
|
||||
And I set the field "Describe this image for someone who cannot see it" to "It's the logo"
|
||||
And I click on "Save image" "button"
|
||||
And I press "Save page"
|
||||
And I follow "Duplicate page: True false with an image in the answer"
|
||||
And I should see "Inserted page: True false with an image in the answer"
|
||||
And I follow "Update page: True false with an image in the answer"
|
||||
And I set the field "Page title" to "First true false"
|
||||
And I press "Save page"
|
||||
When I follow "Update page: True false with an image in the answer"
|
||||
And I should see "True false with an image in the answer"
|
||||
And I should see "Select the picture"
|
||||
Then "//*[contains(@id, 'id_answer_editor_0')]//img[contains(@src, 'moodle_logo.jpg')]" "xpath_element" should exist
|
||||
|
||||
@javascript
|
||||
Scenario: Duplicate question page with image in feedback.
|
||||
Given I follow "Test lesson name"
|
||||
And I follow "Add a question page"
|
||||
And I set the field "Select a question type" to "True/false"
|
||||
And I press "Add a question page"
|
||||
And I set the following fields to these values:
|
||||
| Page title | True false with an image in the feedback |
|
||||
| Page contents | Select the picture |
|
||||
| id_answer_editor_0 | To be replaced |
|
||||
| id_response_editor_0 | Correct answer |
|
||||
| id_jumpto_0 | End of lesson |
|
||||
| id_score_0 | 1 |
|
||||
| id_answer_editor_1 | 1 |
|
||||
| id_response_editor_1 | Incorrect answer |
|
||||
| id_jumpto_1 | This page |
|
||||
| id_score_1 | 0 |
|
||||
# Atto needs focus to add image, select empty p tag to do so.
|
||||
And I select the text in the "id_response_editor_0" Atto editor
|
||||
And I click on "Image" "button" in the "#fitem_id_response_editor_0" "css_element"
|
||||
And I click on "Browse repositories..." "button"
|
||||
And I click on "Private files" "link"
|
||||
And I click on "moodle_logo.jpg" "link"
|
||||
And I click on "Select this file" "button"
|
||||
And I set the field "Describe this image for someone who cannot see it" to "It's the logo"
|
||||
And I click on "Save image" "button"
|
||||
And I press "Save page"
|
||||
And I follow "Duplicate page: True false with an image in the feedback"
|
||||
And I should see "Inserted page: True false with an image in the feedback"
|
||||
And I follow "Update page: True false with an image in the feedback"
|
||||
And I set the field "Page title" to "First true false"
|
||||
And I press "Save page"
|
||||
When I follow "Update page: True false with an image in the feedback"
|
||||
And I should see "True false with an image in the feedback"
|
||||
And I should see "Select the picture"
|
||||
Then "//*[contains(@id, 'id_response_editor_0')]//img[contains(@src, 'moodle_logo.jpg')]" "xpath_element" should exist
|
||||
@@ -0,0 +1,79 @@
|
||||
<?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/>.
|
||||
|
||||
/**
|
||||
* locallib tests.
|
||||
*
|
||||
* @package mod_lesson
|
||||
* @category test
|
||||
* @copyright 2016 Adrian Greeve <[email protected]>
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
|
||||
defined('MOODLE_INTERNAL') || die();
|
||||
|
||||
global $CFG;
|
||||
|
||||
require_once($CFG->dirroot.'/mod/lesson/locallib.php');
|
||||
|
||||
/**
|
||||
* locallib testcase.
|
||||
*
|
||||
* @package mod_lesson
|
||||
* @category test
|
||||
* @copyright 2016 Adrian Greeve <[email protected]>
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
class mod_lesson_locallib_testcase extends advanced_testcase {
|
||||
|
||||
/**
|
||||
* Test duplicating a lesson page element.
|
||||
*/
|
||||
public function test_duplicate_page() {
|
||||
global $DB;
|
||||
|
||||
$this->resetAfterTest();
|
||||
$this->setAdminUser();
|
||||
$course = $this->getDataGenerator()->create_course();
|
||||
$lessonmodule = $this->getDataGenerator()->create_module('lesson', array('course' => $course->id));
|
||||
// Convert to a lesson object.
|
||||
$lesson = new lesson($lessonmodule);
|
||||
|
||||
// Set up a generator to create content.
|
||||
$generator = $this->getDataGenerator()->get_plugin_generator('mod_lesson');
|
||||
$tfrecord = $generator->create_question_truefalse($lesson);
|
||||
$lesson->duplicate_page($tfrecord->id);
|
||||
|
||||
// Lesson pages.
|
||||
$records = $DB->get_records('lesson_pages', array('qtype' => 2));
|
||||
$sameelements = array('lessonid', 'qtype', 'qoption', 'layout', 'display', 'title', 'contents', 'contentsformat');
|
||||
$baserecord = array_shift($records);
|
||||
$secondrecord = array_shift($records);
|
||||
foreach ($sameelements as $element) {
|
||||
$this->assertEquals($baserecord->$element, $secondrecord->$element);
|
||||
}
|
||||
// Need lesson answers as well.
|
||||
$baserecordanswers = array_values($DB->get_records('lesson_answers', array('pageid' => $baserecord->id)));
|
||||
$secondrecordanswers = array_values($DB->get_records('lesson_answers', array('pageid' => $secondrecord->id)));
|
||||
$sameanswerelements = array('lessonid', 'jumpto', 'grade', 'score', 'flags', 'answer', 'answerformat', 'response',
|
||||
'responseformat');
|
||||
foreach ($baserecordanswers as $key => $baseanswer) {
|
||||
foreach ($sameanswerelements as $element) {
|
||||
$this->assertEquals($baseanswer->$element, $secondrecordanswers[$key]->$element);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user