Commit f2a9bb6e authored by Amaia's avatar Amaia
Browse files

MDL-68526 core_contentbank: Delete content when a course is deleted

Or when a course category is moved/deleted
parent d8511836
......@@ -146,6 +146,39 @@ abstract class content {
return $this->content->name;
}
/**
* Set a new contextid to the content.
*
* @param int $contextid The new contextid of the content.
* @return bool True if the content has been succesfully updated. False otherwise.
*/
public function set_contextid(int $contextid): bool {
if ($this->content->contextid == $contextid) {
return true;
}
$oldcontextid = $this->content->contextid;
$this->content->contextid = $contextid;
$updated = $this->update_content();
if ($updated) {
// Move files to new context
$fs = get_file_storage();
$fs->move_area_files_to_new_context($oldcontextid, $contextid, 'contentbank', 'public', $this->content->id);
} else {
$this->content->contextid = $oldcontextid;
}
return $updated;
}
/**
* Returns the contextid of the content.
*
* @return int The id of the content context.
*/
public function get_contextid(): string {
return $this->content->contextid;
}
/**
* Returns the content ID.
*
......
......@@ -25,6 +25,7 @@
namespace core_contentbank;
use stored_file;
use context;
/**
* Content bank class
......@@ -88,10 +89,10 @@ class contentbank {
/**
* Obtains an array of supported extensions in the given context.
*
* @param \context $context Optional context to check (default null)
* @param context $context Optional context to check (default null)
* @return array The array with all the extensions supported and the supporting plugin names.
*/
public function load_context_supported_extensions(\context $context = null): array {
public function load_context_supported_extensions(context $context = null): array {
$extensionscache = \cache::make('core', 'contentbank_context_extensions');
$contextextensions = $extensionscache->get($context->id);
......@@ -117,10 +118,10 @@ class contentbank {
* Obtains a string with all supported extensions by active plugins.
* Mainly to use as filepicker options parameter.
*
* @param \context $context Optional context to check (default null)
* @param context $context Optional context to check (default null)
* @return string A string with all the extensions supported.
*/
public function get_supported_extensions_as_string(\context $context = null) {
public function get_supported_extensions_as_string(context $context = null) {
$supported = $this->load_context_supported_extensions($context);
$extensions = array_keys($supported);
return implode(',', $extensions);
......@@ -144,10 +145,10 @@ class contentbank {
* Get the first content bank plugin supports a file extension.
*
* @param string $extension Content file extension
* @param \context $context $context Optional context to check (default null)
* @param context $context $context Optional context to check (default null)
* @return string contenttype name supports the file extension or null if the extension is not supported by any allowed plugin.
*/
public function get_extension_supporter(string $extension, \context $context = null): ?string {
public function get_extension_supporter(string $extension, context $context = null): ?string {
$supporters = $this->load_context_supported_extensions($context);
if (array_key_exists($extension, $supporters)) {
return $supporters[$extension];
......@@ -240,4 +241,55 @@ class contentbank {
$event->trigger();
return $content;
}
/**
* Delete content bank content by context.
*
* @param context $context The context to delete content from.
* @return bool
*/
public function delete_contents(context $context): bool {
global $DB;
$result = true;
$records = $DB->get_records('contentbank_content', ['contextid' => $context->id]);
foreach ($records as $record) {
$contenttypeclass = "\\$record->contenttype\\contenttype";
if (class_exists($contenttypeclass)) {
$contenttype = new $contenttypeclass($context);
$contentclass = "\\$record->contenttype\\content";
$content = new $contentclass($record);
if (!$contenttype->delete_content($content)) {
$result = false;
}
}
}
return $result;
}
/**
* Move content bank content from a context to another.
*
* @param context $from The context to get content from.
* @param context $to The context to move content to.
* @return bool
*/
public function move_contents(context $from, context $to): bool {
global $DB;
$result = true;
$records = $DB->get_records('contentbank_content', ['contextid' => $from->id]);
foreach ($records as $record) {
$contenttypeclass = "\\$record->contenttype\\contenttype";
if (class_exists($contenttypeclass)) {
$contenttype = new $contenttypeclass($from);
$contentclass = "\\$record->contenttype\\content";
$content = new $contentclass($record);
if (!$contenttype->move_content($content, $to)) {
$result = false;
}
}
}
return $result;
}
}
......@@ -134,6 +134,18 @@ abstract class contenttype {
return $content->set_name($name);
}
/**
* Move content to another context.
* This method can be overwritten by the plugins if they need to change some other specific information.
*
* @param content $content The content to rename.
* @param context $context The new context.
* @return boolean true if the content has been renamed; false otherwise.
*/
public function move_content(content $content, \context $context): bool {
return $content->set_contextid($context->id);
}
/**
* Returns the contenttype name of this content.
*
......
......@@ -1993,6 +1993,10 @@ class core_course_category implements renderable, cacheable_object, IteratorAggr
// Now delete anything that may depend on course category context.
grade_course_category_delete($this->id, 0, $showfeedback);
$cb = new \core_contentbank\contentbank();
if (!$cb->delete_contents($this->get_context())) {
throw new moodle_exception('errordeletingcontentfromcategory', 'contentbank', '', $this->get_formatted_name());
}
if (!question_delete_course_category($this, 0, $showfeedback)) {
throw new moodle_exception('cannotdeletecategoryquestions', '', '', $this->get_formatted_name());
}
......@@ -2153,6 +2157,19 @@ class core_course_category implements renderable, cacheable_object, IteratorAggr
// Now delete anything that may depend on course category context.
grade_course_category_delete($this->id, $newparentid, $showfeedback);
$cb = new \core_contentbank\contentbank();
$newparentcontext = context_coursecat::instance($newparentid);
$result = $cb->move_contents($context, $newparentcontext);
if ($showfeedback) {
if ($result) {
echo $OUTPUT->notification(get_string('contentsmoved', 'contentbank', $catname), 'notifysuccess');
} else {
echo $OUTPUT->notification(
get_string('errordeletingcontentbankfromcategory', 'contentbank', $catname),
'notifysuccess'
);
}
}
if (!question_delete_course_category($this, $newparentcat, $showfeedback)) {
if ($showfeedback) {
echo $OUTPUT->notification(get_string('errordeletingquestionsfromcategory', 'question', $catname), 'notifysuccess');
......
......@@ -23,16 +23,19 @@
*/
$string['author'] = 'Author';
$string['contentbank'] = 'Content bank';
$string['contentdeleted'] = 'The content has been deleted.';
$string['contentname'] = 'Content name';
$string['contentnotdeleted'] = 'An error was encountered while trying to delete the content.';
$string['contentnotrenamed'] = 'An error was encountered while trying to rename the content.';
$string['contentrenamed'] = 'The content has been renamed.';
$string['contentsmoved'] = 'Content bank contents moved to {$a}.';
$string['eventcontentcreated'] = 'Content created';
$string['eventcontentdeleted'] = 'Content deleted';
$string['eventcontentupdated'] = 'Content updated';
$string['eventcontentuploaded'] = 'Content uploaded';
$string['eventcontentviewed'] = 'Content viewed';
$string['errordeletingcontentfromcategory'] = 'Error deleting content from category {$a}.';
$string['deletecontent'] = 'Delete content';
$string['deletecontentconfirm'] = 'Are you sure you want to delete the content <em>\'{$a->name}\'</em> and all associated files? This action cannot be undone.';
$string['file'] = 'Upload content';
......
......@@ -5335,6 +5335,13 @@ function remove_course_contents($courseid, $showfeedback = true, array $options
echo $OUTPUT->notification($strdeleted.get_string('questions', 'question'), 'notifysuccess');
}
// Delete content bank contents.
$cb = new \core_contentbank\contentbank();
$cbdeleted = $cb->delete_contents($coursecontext);
if ($showfeedback && $cbdeleted) {
echo $OUTPUT->notification($strdeleted.get_string('contentbank', 'contentbank'), 'notifysuccess');
}
// Make sure there are no subcontexts left - all valid blocks and modules should be already gone.
$childcontexts = $coursecontext->get_child_contexts(); // Returns all subcontexts since 2.2.
foreach ($childcontexts as $childcontext) {
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment