diff --git a/amd/build/block_delete_handler.min.js b/amd/build/block_delete_handler.min.js
new file mode 100644
index 00000000..dbb20359
--- /dev/null
+++ b/amd/build/block_delete_handler.min.js
@@ -0,0 +1,10 @@
+define("block_opencast/block_delete_handler",["exports","core/modal_factory","core/ajax","core/templates","core/prefetch","core/str","core/notification"],(function(_exports,_modal_factory,_ajax,_templates,_prefetch,_str,_notification){function _interopRequireDefault(obj){return obj&&obj.__esModule?obj:{default:obj}}
+/**
+ * Javascript to add a custom block_delete handler
+ *
+ * @module block_opencast/block_delete_handler
+ * @copyright 2024 Justus Dieckmann, University of Münster
+ * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
+ */Object.defineProperty(_exports,"__esModule",{value:!0}),_exports.init=void 0,_modal_factory=_interopRequireDefault(_modal_factory),_ajax=_interopRequireDefault(_ajax),_templates=_interopRequireDefault(_templates),_prefetch=_interopRequireDefault(_prefetch),_notification=_interopRequireDefault(_notification);_exports.init=(contextid,deleteurl)=>{_prefetch.default.prefetchTemplate("block_opencast/delete_block_modal"),_prefetch.default.prefetchString("block_opencast","deletecheck_title_modal");document.querySelector(".block_opencast a.dropdown-item.block_opencast_delete").onclick=async e=>{e.preventDefault();const html=await _templates.default.render("block_opencast/delete_block_modal",{deleteblockurl:deleteurl}),modal=await _modal_factory.default.create({type:_modal_factory.default.types.CANCEL,body:html,title:await(0,_str.getString)("deletecheck_title_modal","block_opencast"),large:!0});await modal.show(),modal.body[0].querySelector(".block_opencast-delete-mapping").onclick=async()=>{try{await _ajax.default.call([{methodname:"block_opencast_unlink_series",args:{contextid:contextid,ocinstanceid:-1,seriesid:"all"}}])[0],window.location=deleteurl}catch(e){_notification.default.exception(e)}}}}}));
+
+//# sourceMappingURL=block_delete_handler.min.js.map
\ No newline at end of file
diff --git a/amd/build/block_delete_handler.min.js.map b/amd/build/block_delete_handler.min.js.map
new file mode 100644
index 00000000..62b4ccd6
--- /dev/null
+++ b/amd/build/block_delete_handler.min.js.map
@@ -0,0 +1 @@
+{"version":3,"file":"block_delete_handler.min.js","sources":["../src/block_delete_handler.js"],"sourcesContent":["// This file is part of Moodle - http://moodle.org/\n//\n// Moodle is free software: you can redistribute it and/or modify\n// it under the terms of the GNU General Public License as published by\n// the Free Software Foundation, either version 3 of the License, or\n// (at your option) any later version.\n//\n// Moodle is distributed in the hope that it will be useful,\n// but WITHOUT ANY WARRANTY; without even the implied warranty of\n// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n// GNU General Public License for more details.\n//\n// You should have received a copy of the GNU General Public License\n// along with Moodle. If not, see .\n\n/**\n * Javascript to add a custom block_delete handler\n *\n * @module block_opencast/block_delete_handler\n * @copyright 2024 Justus Dieckmann, University of Münster\n * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later\n */\n\nimport ModalFactory from 'core/modal_factory';\nimport Ajax from 'core/ajax';\nimport Templates from 'core/templates';\nimport Prefetch from \"core/prefetch\";\nimport {getString} from 'core/str';\nimport Notification from \"core/notification\";\n\nexport const init = (contextid, deleteurl) => {\n Prefetch.prefetchTemplate('block_opencast/delete_block_modal');\n Prefetch.prefetchString('block_opencast', 'deletecheck_title_modal');\n const deleteButton = document.querySelector('.block_opencast a.dropdown-item.block_opencast_delete');\n deleteButton.onclick = async(e) => {\n e.preventDefault();\n\n const html = await Templates.render('block_opencast/delete_block_modal', {\n deleteblockurl: deleteurl\n });\n\n const modal = await ModalFactory.create({\n type: ModalFactory.types.CANCEL,\n body: html,\n title: await getString('deletecheck_title_modal', 'block_opencast'),\n large: true\n });\n await modal.show();\n modal.body[0].querySelector('.block_opencast-delete-mapping').onclick = async() => {\n try {\n await Ajax.call([{\n methodname: 'block_opencast_unlink_series',\n args: {contextid: contextid, ocinstanceid: -1, seriesid: 'all'}\n }])[0];\n window.location = deleteurl;\n } catch (e) {\n Notification.exception(e);\n }\n };\n };\n};\n"],"names":["contextid","deleteurl","prefetchTemplate","prefetchString","document","querySelector","onclick","async","e","preventDefault","html","Templates","render","deleteblockurl","modal","ModalFactory","create","type","types","CANCEL","body","title","large","show","Ajax","call","methodname","args","ocinstanceid","seriesid","window","location","exception"],"mappings":";;;;;;;wUA8BoB,CAACA,UAAWC,+BACnBC,iBAAiB,uDACjBC,eAAe,iBAAkB,2BACrBC,SAASC,cAAc,yDAC/BC,QAAUC,MAAAA,IACnBC,EAAEC,uBAEIC,WAAaC,mBAAUC,OAAO,oCAAqC,CACrEC,eAAgBZ,YAGda,YAAcC,uBAAaC,OAAO,CACpCC,KAAMF,uBAAaG,MAAMC,OACzBC,KAAMV,KACNW,YAAa,kBAAU,0BAA2B,kBAClDC,OAAO,UAELR,MAAMS,OACZT,MAAMM,KAAK,GAAGf,cAAc,kCAAkCC,QAAUC,oBAE1DiB,cAAKC,KAAK,CAAC,CACbC,WAAY,+BACZC,KAAM,CAAC3B,UAAWA,UAAW4B,cAAe,EAAGC,SAAU,UACzD,GACJC,OAAOC,SAAW9B,UACpB,MAAOO,yBACQwB,UAAUxB"}
\ No newline at end of file
diff --git a/amd/src/block_delete_handler.js b/amd/src/block_delete_handler.js
new file mode 100644
index 00000000..82f3c64c
--- /dev/null
+++ b/amd/src/block_delete_handler.js
@@ -0,0 +1,61 @@
+// 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 .
+
+/**
+ * Javascript to add a custom block_delete handler
+ *
+ * @module block_opencast/block_delete_handler
+ * @copyright 2024 Justus Dieckmann, University of Münster
+ * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
+ */
+
+import ModalFactory from 'core/modal_factory';
+import Ajax from 'core/ajax';
+import Templates from 'core/templates';
+import Prefetch from "core/prefetch";
+import {getString} from 'core/str';
+import Notification from "core/notification";
+
+export const init = (contextid, deleteurl) => {
+ Prefetch.prefetchTemplate('block_opencast/delete_block_modal');
+ Prefetch.prefetchString('block_opencast', 'deletecheck_title_modal');
+ const deleteButton = document.querySelector('.block_opencast a.dropdown-item.block_opencast_delete');
+ deleteButton.onclick = async(e) => {
+ e.preventDefault();
+
+ const html = await Templates.render('block_opencast/delete_block_modal', {
+ deleteblockurl: deleteurl
+ });
+
+ const modal = await ModalFactory.create({
+ type: ModalFactory.types.CANCEL,
+ body: html,
+ title: await getString('deletecheck_title_modal', 'block_opencast'),
+ large: true
+ });
+ await modal.show();
+ modal.body[0].querySelector('.block_opencast-delete-mapping').onclick = async() => {
+ try {
+ await Ajax.call([{
+ methodname: 'block_opencast_unlink_series',
+ args: {contextid: contextid, ocinstanceid: -1, seriesid: 'all'}
+ }])[0];
+ window.location = deleteurl;
+ } catch (e) {
+ Notification.exception(e);
+ }
+ };
+ };
+};
diff --git a/block_opencast.php b/block_opencast.php
index 17c7dedf..40969a43 100644
--- a/block_opencast.php
+++ b/block_opencast.php
@@ -199,49 +199,47 @@ public function instance_create() {
* @return block_contents a representation of the block, for rendering.
*/
public function get_content_for_output($output) {
+ global $COURSE, $PAGE;
// Get the block_contents object from parent class.
$bc = parent::get_content_for_output($output);
- // We prepare the data to use and replace the existing action link contents.
- $title = $this->title;
- $defaultdeletestr = get_string('deleteblock', 'block', $this->title);
+ // Check whether the user can manually delete series mapping.
+ if (!has_capability('block/opencast:manageseriesforcourse', $this->context)) {
+ return $bc;
+ }
// Check if the block_contents has controls.
if (!empty($bc->controls)) {
// We filter the controls to find the delete action link.
- $deleteactionfiltered = array_filter($bc->controls, function ($actionlink) use ($defaultdeletestr, $title) {
- // Get the text from action link.
- $actionlinktext = $actionlink->text;
- // Get the text if it is a type of lang_string via __toString.
- if ($actionlinktext instanceof \lang_string) {
- $actionlinktext = $actionlinktext->__toString();
- }
- return $actionlinktext === $defaultdeletestr;
+ $deleteactionfiltered = array_filter($bc->controls, function ($actionlink) {
+ return str_contains($actionlink->attributes['class'], 'editing_delete');
});
// In case the delete action link could be found, we try to replace its properties.
if (!empty($deleteactionfiltered)) {
$index = key($deleteactionfiltered);
$deleteaction = reset($deleteactionfiltered);
- // Replace the action link's text.
- if (isset($deleteaction->text)) {
- $deleteaction->text = get_string('delete_block_action_item_text', 'block_opencast');
- }
+
+ // Delete all modal-related attributes.
if (isset($deleteaction->attributes)) {
- if (isset($deleteaction->attributes['data-modal-title-str'])) {
- $deleteaction->attributes['data-modal-title-str'] = json_encode(
- ['deletecheck_title_modal', 'block_opencast']
- );
- }
- if (isset($deleteaction->attributes['data-modal-content-str'])) {
- $deleteaction->attributes['data-modal-content-str'] = json_encode(
- ['deletecheck_content_modal', 'block_opencast']
- );
+ foreach ($deleteaction->attributes as $k => $v) {
+ if (str_starts_with($k, 'data-modal')) {
+ unset($deleteaction->attributes[$k]);
+ }
}
+ $deleteaction->attributes['class'] .= ' block_opencast_delete';
}
$bc->controls[$index] = $deleteaction;
+ $deleteurl = new moodle_url('/course/view.php', [
+ 'id' => $COURSE->id,
+ 'bui_deleteid' => $this->instance->id,
+ 'bui_confirm' => 1,
+ 'sesskey' => sesskey()
+ ]);
+ $PAGE->requires->js_call_amd('block_opencast/block_delete_handler', 'init',
+ [$this->context->id, $deleteurl->out(false)]);
}
}
return $bc;
diff --git a/classes/external.php b/classes/external.php
index 1f45a7e5..a41052da 100644
--- a/classes/external.php
+++ b/classes/external.php
@@ -299,17 +299,21 @@ public static function unlink_series(int $contextid, int $ocinstanceid, string $
list($unused, $course, $cm) = get_context_info_array($context->id);
- $mapping = seriesmapping::get_record(['ocinstanceid' => $params['ocinstanceid'], 'courseid' => $course->id,
- 'series' => $params['seriesid'], ], true);
+ if ($params['seriesid'] === 'all') {
+ $mappings = seriesmapping::get_records(['courseid' => $course->id]);
+ } else {
+ $mappings = seriesmapping::get_records(['ocinstanceid' => $params['ocinstanceid'], 'courseid' => $course->id,
+ 'series' => $params['seriesid']]);
+ }
- if ($mapping) {
+ foreach ($mappings as $mapping) {
if (!$mapping->delete()) {
throw new moodle_exception('delete_series_failed', 'block_opencast');
}
// Unlinking series from course.
- $apibridge = apibridge::get_instance($params['ocinstanceid']);
- $seriesunlinked = $apibridge->unlink_series_from_course($course->id, $params['seriesid']);
+ $apibridge = apibridge::get_instance($mapping->get('ocinstanceid'));
+ $seriesunlinked = $apibridge->unlink_series_from_course($course->id, $mapping->get('series'));
if (!$seriesunlinked) {
throw new moodle_exception('delete_series_failed', 'block_opencast');
diff --git a/lang/en/block_opencast.php b/lang/en/block_opencast.php
index d2530afe..9209bf81 100644
--- a/lang/en/block_opencast.php
+++ b/lang/en/block_opencast.php
@@ -891,12 +891,13 @@
$string['directaccess_copy_success'] = 'The direct access link has been successfully copied to clipboard.';
$string['directaccess_copytoclipboard_unavialable'] = 'It seems that your browser does not support the copy to clipboard functionality, try to copy the link manually from the dropdown item.';
$string['opencast:autocompleteteacherroles'] = 'Teacher roles to be extracted and provided in the autocomplete list';
-$string['delete_block_action_item_text'] = 'Remove Opencast Block';
+// Strings for delete block modal.
$string['deletecheck_title_modal'] = 'Remove Opencast Block?';
-$string['deletecheck_content_modal'] = 'Are you sure you want to remove the Opencast block from the course?
You get to decide whether to remove the series mapping in the next step.';
-$string['confirm_delete_seriesmapping_title_page'] = 'Opencast Block: Delete series mapping';
-$string['confirm_delete_seriesmapping_title_confirm'] = 'Delete Opencast course series mapping';
-$string['confirm_delete_seriesmapping_content_confirm'] = 'Do you also want to delete the course series mapping of this block?
NOTE: If the course series mapping is deleted, it is not possible to retrieve the current series to this course anymore.';
$string['error_block_delete_seriesmapping'] = 'Unfortunately, there was an error during course series mapping deletion, please contact the system administrator.';
+
+$string['delete_mapping_explanation'] = 'The Opencast Block tracks which Opencast Series is mapped to the course.
You can choose whether to delete the mapping.
If you delete it, the series will no longer appear when you create the opencast block again.';
+$string['only_delete_block'] = 'Delete block, but keep series mapping';
+$string['delete_block_and_mapping'] = 'Delete block and series mapping';
+
// Deprecated since version 2021062300.
$string['video_already_uploaded'] = 'Video already uploaded';
diff --git a/lib.php b/lib.php
index 741ab5e1..43c7e421 100644
--- a/lib.php
+++ b/lib.php
@@ -105,88 +105,3 @@ function block_opencast_pre_course_delete(stdClass $course) {
$mapping->delete();
}
}
-
-
-/**
- * Pre-delete block hook to show a confirmation message or to perform cleaup the related series and videos.
- *
- * @param object $instance a row from the block_instances table
- *
- * @throws moodle_exception
- */
-function block_opencast_pre_block_delete($instance) {
-
- // We make sure if the deleting block is Opencast block, otherwise we do nothing!
- if ($instance->blockname !== 'opencast') {
- return;
- }
-
- // Get the course and context base don block instance parentcontextid.
- list($context, $course, $cm) = get_context_info_array($instance->parentcontextid);
-
- // We get the flag 'removeseriesmapping' to decide whether to delete the series mapping.
- $removeseriesmapping = optional_param('removeseriesmapping', null, PARAM_INT);
-
- // At first the flag is not set, therefore we have the chance to show a confirmation page.
- if (is_null($removeseriesmapping) && !empty($course) && !empty($context)) {
- $deletepage = new moodle_page();
- $deletepage->set_pagelayout('admin');
- $deletepage->blocks->show_only_fake_blocks(true);
- $deletepage->set_course($course);
- $deletepage->set_context($context);
- if ($cm) {
- $deletepage->set_cm($cm);
- }
- // The default delete url.
- $deleteurl = new moodle_url('/course/view.php',
- [
- 'id' => $course->id,
- 'sesskey' => sesskey(),
- 'bui_deleteid' => $instance->id,
- 'bui_confirm' => 1
- ]
- );
- $deletepage->set_url($deleteurl);
- $deletepage->set_block_actions_done();
- $PAGE = $deletepage;
- /** @var core_renderer $output */
- $output = $deletepage->get_renderer('core');
- $OUTPUT = $output;
-
- $deletepagetitle = get_string('confirm_delete_seriesmapping_title_page', 'block_opencast');
- $confirmtitle = get_string('confirm_delete_seriesmapping_title_confirm', 'block_opencast');
- $message = get_string('confirm_delete_seriesmapping_content_confirm', 'block_opencast');
-
- $PAGE->navbar->add($deletepagetitle);
- $PAGE->set_title($deletepagetitle);
- $PAGE->set_heading($course->fullname);
- echo $OUTPUT->header();
-
- // Creating a confirmation page with assigning a flag 'removeseriesmapping' to decide whether to delete series mapping.
- $confirmurl = new moodle_url($deletepage->url, array('removeseriesmapping' => 1));
- $cancelurl = new moodle_url($deletepage->url, array('removeseriesmapping' => 0));
-
- $yesbutton = new single_button($confirmurl, get_string('yes'));
- $nobutton = new single_button($cancelurl, get_string('no'));
-
- $displayoptions['confirmtitle'] = $confirmtitle;
-
- echo $OUTPUT->confirm($message, $yesbutton, $nobutton, $displayoptions);
- echo $OUTPUT->footer();
- // Make sure that nothing else happens after we have displayed this form.
- exit;
- } else if ($removeseriesmapping === 1) { // We only perform the series mapping deletion if the flag is set to 1.
- $success = true;
- $mappings = seriesmapping::get_records(['courseid' => $course->id]);
- foreach ($mappings as $mapping) {
- if (!$mapping->delete()) {
- $success = false;
- }
- }
- if (!$success) {
- throw new moodle_exception('error_block_delete_seriesmapping', 'block_opencast');
- }
- }
- // We let the process continue if the flag 'removeseriesmapping' is set to 0,
- // which means it is decided not to delete series mapping.
-}
diff --git a/templates/delete_block_modal.mustache b/templates/delete_block_modal.mustache
new file mode 100644
index 00000000..93406dc3
--- /dev/null
+++ b/templates/delete_block_modal.mustache
@@ -0,0 +1,35 @@
+{{!
+ 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 block_opencast/delete_block_modal
+
+ This template renders the delete modal
+
+ Example context (json):
+ {
+ "deleteblockurl": "https://moodle.local/blocks/opencast/managedefaults.php?courseid=3&ocinstanceid=1"
+ }
+}}
+{{#str}} delete_mapping_explanation, block_opencast {{/str}}
+
+
+ {{#str}} delete_block_and_mapping, block_opencast {{/str}}
+
+
+ {{#str}} only_delete_block, block_opencast {{/str}}
+
+