Skip to content

Commit

Permalink
MDL-28666 Extends repository to support references
Browse files Browse the repository at this point in the history
1. Allow repository to create references to external contents
2. Extends files API to handle file references
3. Generic file caching
4. Backup/restore file references
5. Download external contents if repository uninstalled
6. Allow filepicker to display iframe
7. PHPUnit test suits
  • Loading branch information
Dongsheng Cai authored and marinaglancy committed May 21, 2012
1 parent 4f7f2a8 commit 6723372
Show file tree
Hide file tree
Showing 61 changed files with 3,107 additions and 692 deletions.
73 changes: 63 additions & 10 deletions admin/repository.php
Original file line number Diff line number Diff line change
@@ -1,12 +1,27 @@
<?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/>.

require_once(dirname(dirname(__FILE__)) . '/config.php');
require_once($CFG->dirroot . '/repository/lib.php');
require_once($CFG->libdir . '/adminlib.php');

$repository = optional_param('repos', '', PARAM_FORMAT);
$action = optional_param('action', '', PARAM_ALPHA);
$sure = optional_param('sure', '', PARAM_ALPHA);
$repository = optional_param('repos', '', PARAM_ALPHANUMEXT);
$action = optional_param('action', '', PARAM_ACTION);
$sure = optional_param('sure', '', PARAM_ALPHA);
$downloadcontents = optional_param('downloadcontents', '', PARAM_ALPHA);

$display = true; // fall through to normal display

Expand Down Expand Up @@ -42,6 +57,10 @@

$return = true;

if (!empty($action)) {
require_sesskey();
}

/**
* Helper function that generates a moodle_url object
* relevant to the repository
Expand Down Expand Up @@ -152,10 +171,10 @@ function repository_action_url($repository) {

// Display instances list and creation form
if ($action == 'edit') {
$instanceoptionnames = repository::static_function($repository, 'get_instance_option_names');
if (!empty($instanceoptionnames)) {
repository::display_instances_list(get_context_instance(CONTEXT_SYSTEM), $repository);
}
$instanceoptionnames = repository::static_function($repository, 'get_instance_option_names');
if (!empty($instanceoptionnames)) {
repository::display_instances_list(context_system::instance(), $repository);
}
}
}
} else if ($action == 'show') {
Expand Down Expand Up @@ -185,15 +204,49 @@ function repository_action_url($repository) {
if (!confirm_sesskey()) {
print_error('confirmsesskeybad', '', $baseurl);
}
if ($repositorytype->delete()) {

if (!empty($downloadcontents) and $downloadcontents == 'yes') {
$downloadcontents = true;
} else {
$downloadcontents = false;
}

if ($repositorytype->delete($downloadcontents)) {
redirect($baseurl);
} else {
print_error('instancenotdeleted', 'repository', $baseurl);
}
exit;
} else {
echo $OUTPUT->header();
echo $OUTPUT->confirm(get_string('confirmremove', 'repository', $repositorytype->get_readablename()), $sesskeyurl . '&action=delete&repos=' . $repository . '&sure=yes', $baseurl);

$message = get_string('confirmremove', 'repository', $repositorytype->get_readablename());

$output = $OUTPUT->box_start('generalbox', 'notice');
$output .= html_writer::tag('p', $message);

$removeurl = new moodle_url($sesskeyurl);
$removeurl->params(array(
'action' =>'delete',
'repos' => $repository,
'sure' => 'yes',
));

$removeanddownloadurl = new moodle_url($sesskeyurl);
$removeanddownloadurl->params(array(
'action' =>'delete',
'repos'=> $repository,
'sure' => 'yes',
'downloadcontents' => 'yes',
));

$output .= $OUTPUT->single_button($removeurl, get_string('continueuninstall', 'repository'));
$output .= $OUTPUT->single_button($removeanddownloadurl, get_string('continueuninstallanddownload', 'repository'));
$output .= $OUTPUT->single_button($baseurl, get_string('cancel'));
$output .= $OUTPUT->box_end();

echo $output;

$return = false;
}
} else if ($action == 'moveup') {
Expand Down Expand Up @@ -255,7 +308,7 @@ function repository_action_url($repository) {
// Calculate number of instances in order to display them for the Moodle administrator
if (!empty($instanceoptionnames)) {
$params = array();
$params['context'] = array(get_system_context());
$params['context'] = array(context_system::instance());
$params['onlyvisible'] = false;
$params['type'] = $typename;
$admininstancenumber = count(repository::static_function($typename, 'get_instances', $params));
Expand Down
89 changes: 61 additions & 28 deletions admin/repositoryinstance.php
Original file line number Diff line number Diff line change
@@ -1,18 +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/>.

require_once(dirname(dirname(__FILE__)) . '/config.php');
require_once($CFG->dirroot . '/repository/lib.php');
require_once($CFG->libdir . '/adminlib.php');

require_sesskey();

// id of repository
$edit = optional_param('edit', 0, PARAM_INT);
$new = optional_param('new', '', PARAM_FORMAT);
$new = optional_param('new', '', PARAM_PLUGIN);
$hide = optional_param('hide', 0, PARAM_INT);
$delete = optional_param('delete', 0, PARAM_INT);
$sure = optional_param('sure', '', PARAM_ALPHA);
$type = optional_param('type', '', PARAM_PLUGIN);
$downloadcontents = optional_param('downloadcontents', '', PARAM_ALPHA);

$context = get_context_instance(CONTEXT_SYSTEM);
$context = context_system::instance();

$pagename = 'repositorycontroller';

Expand All @@ -25,15 +42,19 @@
}

admin_externalpage_setup($pagename);
require_capability('moodle/site:config', get_context_instance(CONTEXT_SYSTEM));
require_capability('moodle/site:config', $context);

$baseurl = new moodle_url("/$CFG->admin/repositoryinstance.php", array('sesskey'=>sesskey()));

$parenturl = new moodle_url("/$CFG->admin/repository.php", array(
'sesskey'=>sesskey(),
'action'=>'edit',
));

$sesskeyurl = "$CFG->wwwroot/$CFG->admin/repositoryinstance.php?sesskey=" . sesskey();
$baseurl = "$CFG->wwwroot/$CFG->admin/repository.php?session=". sesskey() .'&action=edit&repos=';
if ($new) {
$baseurl .= $new;
}
else {
$baseurl .= $type;
$parenturl->param('repos', $new);
} else {
$parenturl->param('repos', $type);
}

$return = true;
Expand All @@ -48,7 +69,7 @@
$typeid = $instance->options['typeid'];
} else {
$plugin = $new;
$typeid = $new;
$typeid = null;
$instance = null;
}

Expand All @@ -57,12 +78,9 @@
// end setup, begin output

if ($mform->is_cancelled()){
redirect($baseurl);
redirect($parenturl);
exit;
} else if ($fromform = $mform->get_data()){
if (!confirm_sesskey()) {
print_error('confirmsesskeybad', '', $baseurl);
}
if ($edit) {
$settings = array();
$settings['name'] = $fromform->name;
Expand All @@ -77,13 +95,13 @@
}
$success = $instance->set_option($settings);
} else {
$success = repository::static_function($plugin, 'create', $plugin, 0, get_system_context(), $fromform);
$success = repository::static_function($plugin, 'create', $plugin, 0, $context, $fromform);
$data = data_submitted();
}
if ($success) {
redirect($baseurl);
redirect($parenturl);
} else {
print_error('instancenotsaved', 'repository', $baseurl);
print_error('instancenotsaved', 'repository', $parenturl);
}
exit;
} else {
Expand All @@ -95,9 +113,6 @@
$return = false;
}
} else if (!empty($hide)) {
if (!confirm_sesskey()) {
print_error('confirmsesskeybad', '', $baseurl);
}
$instance = repository::get_type_by_typename($hide);
$instance->hide();
$return = true;
Expand All @@ -108,25 +123,43 @@
throw new repository_exception('readonlyinstance', 'repository');
}
if ($sure) {
if (!confirm_sesskey()) {
print_error('confirmsesskeybad', '', $baseurl);
if (!empty($downloadcontents) and $downloadcontents == 'yes') {
$downloadcontents = true;
} else {
$downloadcontents = false;
}
if ($instance->delete()) {
if ($instance->delete($downloadcontents)) {
$deletedstr = get_string('instancedeleted', 'repository');
redirect($baseurl, $deletedstr, 3);
redirect($parenturl, $deletedstr, 3);
} else {
print_error('instancenotdeleted', 'repository', $baseurl);
print_error('instancenotdeleted', 'repository', $parenturl);
}
exit;
}

echo $OUTPUT->header();
echo $OUTPUT->confirm(get_string('confirmdelete', 'repository', $instance->name), "$sesskeyurl&type=$type'&delete=$delete'&sure=yes", "$CFG->wwwroot/$CFG->admin/repositoryinstance.php?session=". sesskey());
echo $OUTPUT->box_start('generalbox', 'notice');
$continueurl = new moodle_url($baseurl, array(
'type' => $type,
'delete' => $delete,
'sure' => 'yes',
));
$continueanddownloadurl = new moodle_url($continueurl, array(
'downloadcontents' => 'yes'
));
$message = get_string('confirmdelete', 'repository', $instance->name);
echo html_writer::tag('p', $message);

echo $OUTPUT->single_button($continueurl, get_string('continueuninstall', 'repository'));
echo $OUTPUT->single_button($continueanddownloadurl, get_string('continueuninstallanddownload', 'repository'));
echo $OUTPUT->single_button($parenturl, get_string('cancel'));

echo $OUTPUT->box_end();

$return = false;
}

if (!empty($return)) {

redirect($baseurl);
redirect($parenturl);
}
echo $OUTPUT->footer();
2 changes: 1 addition & 1 deletion backup/backupfilesedit_form.php
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ class backup_files_edit_form extends moodleform {
function definition() {
$mform =& $this->_form;
$contextid = $this->_customdata['contextid'];
$options = array('subdirs'=>0, 'maxfiles'=>-1, 'accepted_types'=>'*', 'return_types'=>FILE_INTERNAL);
$options = array('subdirs'=>0, 'maxfiles'=>-1, 'accepted_types'=>'*', 'return_types'=>FILE_INTERNAL | FILE_REFERENCE);
$mform->addElement('filemanager', 'files_filemanager', get_string('files'), null, $options);
$mform->addElement('hidden', 'contextid', $this->_customdata['contextid']);
$mform->addElement('hidden', 'currentcontext', $this->_customdata['currentcontext']);
Expand Down
19 changes: 14 additions & 5 deletions backup/moodle2/backup_stepslib.php
Original file line number Diff line number Diff line change
Expand Up @@ -1404,17 +1404,20 @@ protected function define_structure() {
'contenthash', 'contextid', 'component', 'filearea', 'itemid',
'filepath', 'filename', 'userid', 'filesize',
'mimetype', 'status', 'timecreated', 'timemodified',
'source', 'author', 'license', 'sortorder'));
'source', 'author', 'license', 'sortorder', 'reference', 'repositoryid'));

// Build the tree

$files->add_child($file);

// Define sources

$file->set_source_sql("SELECT f.*
$file->set_source_sql("SELECT f.*, r.repositoryid, r.reference
FROM {files} f
JOIN {backup_ids_temp} bi ON f.id = bi.itemid
JOIN {files_reference} r
ON r.id = f.referencefileid
JOIN {backup_ids_temp} bi
ON f.id = bi.itemid
WHERE bi.backupid = ?
AND bi.itemname = 'filefinal'", array(backup::VAR_BACKUPID));

Expand Down Expand Up @@ -1442,6 +1445,8 @@ protected function define_structure() {
$info['backup_date'] = time();
$info['backup_uniqueid']= $this->get_backupid();
$info['mnet_remoteusers']=backup_controller_dbops::backup_includes_mnet_remote_users($this->get_backupid());
$info['include_file_references_to_external_content'] =
backup_controller_dbops::backup_includes_file_references($this->get_backupid());
$info['original_wwwroot']=$CFG->wwwroot;
$info['original_site_identifier_hash'] = md5(get_site_identifier());
$info['original_course_id'] = $this->get_courseid();
Expand All @@ -1461,7 +1466,7 @@ protected function define_structure() {

$information = new backup_nested_element('information', null, array(
'name', 'moodle_version', 'moodle_release', 'backup_version',
'backup_release', 'backup_date', 'mnet_remoteusers', 'original_wwwroot',
'backup_release', 'backup_date', 'mnet_remoteusers', 'include_file_references_to_external_content', 'original_wwwroot',
'original_site_identifier_hash', 'original_course_id',
'original_course_fullname', 'original_course_shortname', 'original_course_startdate',
'original_course_contextid', 'original_system_contextid'));
Expand Down Expand Up @@ -1584,8 +1589,12 @@ protected function define_execution() {
// Calculate the zip fullpath (in OS temp area it's always backup.mbz)
$zipfile = $basepath . '/backup.mbz';

$has_file_references = backup_controller_dbops::backup_includes_file_references($this->get_backupid());
// Perform storage and return it (TODO: shouldn't be array but proper result object)
return array('backup_destination' => backup_helper::store_backup_file($this->get_backupid(), $zipfile));
return array(
'backup_destination' => backup_helper::store_backup_file($this->get_backupid(), $zipfile),
'include_file_references_to_external_content' => $has_file_references
);
}
}

Expand Down
15 changes: 14 additions & 1 deletion backup/moodle2/restore_stepslib.php
Original file line number Diff line number Diff line change
Expand Up @@ -586,11 +586,23 @@ protected function define_structure() {
return array($file);
}

// Processing functions go here
/**
* Processing functions go here
*
* @param array $data one file record including repositoryid and reference
*/
public function process_file($data) {

$data = (object)$data; // handy

$isreference = !empty($data->repositoryid);
$issamesite = $this->task->is_samesite();

// If it's not samesite, we skip file refernces
if (!$issamesite && $isreference) {
return;
}

// load it if needed:
// - it it is one of the annotated inforef files (course/section/activity/block)
// - it is one "user", "group", "grouping", "grade", "question" or "qtype_xxxx" component file (that aren't sent to inforef ever)
Expand All @@ -601,6 +613,7 @@ public function process_file($data) {
$data->component == 'grouping' || $data->component == 'grade' ||
$data->component == 'question' || substr($data->component, 0, 5) == 'qtype');
if ($isfileref || $iscomponent) {
// Process files
restore_dbops::set_backup_files_record($this->get_restoreid(), $data);
}
}
Expand Down
Loading

0 comments on commit 6723372

Please sign in to comment.