From cede27e88662ff32895e2eacca25a6a8ed0ddb5b Mon Sep 17 00:00:00 2001
From: Jan-Hendrik Willms <tleilax+studip@gmail.com>
Date: Tue, 7 Jan 2025 07:33:17 +0000
Subject: [PATCH] fix oer tags editting, fixes #5094

Closes #5094

Merge request studip/studip!3812
---
 app/views/oer/mymaterial/edit.php             | 20 +++++++---
 lib/models/OERMaterial.php                    | 15 +++----
 resources/assets/javascripts/bootstrap/oer.js | 40 ++++++++++---------
 resources/vue/components/Quicksearch.vue      |  2 +-
 4 files changed, 42 insertions(+), 35 deletions(-)

diff --git a/app/views/oer/mymaterial/edit.php b/app/views/oer/mymaterial/edit.php
index 71e010175e0..188ea3b0725 100644
--- a/app/views/oer/mymaterial/edit.php
+++ b/app/views/oer/mymaterial/edit.php
@@ -1,3 +1,11 @@
+<?php
+/**
+ * @var Oer_MymaterialController $controller
+ * @var OERMaterial $material
+ * @var string $usersearch
+ * @var string $tagsearch
+ */
+?>
 <form action="<?= $controller->edit($material->isNew() ? '' : $material) ?>"
       method="post"
       class="default"
@@ -178,7 +186,6 @@
                 </div>
             <? endif ?>
 
-
             <div class="oer_tags_container">
                 <?= _('Themen (am besten mindestens 5)') ?>
                 <?
@@ -194,19 +201,20 @@
                 ?>
 
                 <ul class="clean oer_tags" data-defaulttags="<?= htmlReady(json_encode($tags)) ?>">
-                    <li v-for="(tag, index) in displayTags" :key="index">
+                    <li v-for="(tag, index) in displayTags" :key="`tag-${index}`">
                         #
                         <quicksearch name="tags[]"
                                      searchtype="<?= htmlReady($tagsearch) ?>"
-                                     v-model="tags[index]"
+                                     v-model="tag"
                                      :autocomplete="true"
                                      :keep-value="true"
                         ></quicksearch>
-                        <a href="#"
+                        <button class="as-link"
                            @click.prevent="removeTag(index)"
-                           title="<?= _('Thema aus der Liste streichen') ?>">
+                           title="<?= _('Thema aus der Liste streichen') ?>"
+                        >
                             <studip-icon shape="trash" class="text-bottom"></studip-icon>
-                        </a>
+                        </button>
 
                     </li>
                 </ul>
diff --git a/lib/models/OERMaterial.php b/lib/models/OERMaterial.php
index 604f845e391..83ca8e2973a 100644
--- a/lib/models/OERMaterial.php
+++ b/lib/models/OERMaterial.php
@@ -237,15 +237,12 @@ class OERMaterial extends SimpleORMap
 
     public function getTopics()
     {
-        $statement = DBManager::get()->prepare("
-            SELECT oer_tags.*
-            FROM oer_tags
-                INNER JOIN oer_tags_material ON (oer_tags_material.tag_hash = oer_tags.tag_hash)
-            WHERE oer_tags_material.material_id = :material_id
-            ORDER BY oer_tags.name ASC
-        ");
-        $statement->execute(['material_id' => $this->getId()]);
-        return $statement->fetchAll(PDO::FETCH_ASSOC);
+        $query = "SELECT oer_tags.*
+                  FROM oer_tags
+                  JOIN oer_tags_material USING (tag_hash)
+                  WHERE oer_tags_material.material_id = :material_id
+                  ORDER BY oer_tags.name ASC";
+        return DBManager::get()->fetchAll($query, [':material_id' => $this->id]);
     }
 
     public function setTopics($tags)
diff --git a/resources/assets/javascripts/bootstrap/oer.js b/resources/assets/javascripts/bootstrap/oer.js
index b47c55d4641..f2aeb5eafc5 100644
--- a/resources/assets/javascripts/bootstrap/oer.js
+++ b/resources/assets/javascripts/bootstrap/oer.js
@@ -48,19 +48,21 @@ STUDIP.ready(() => {
     if ($('.oercampus_editmaterial').length) {
 
         STUDIP.Vue.load().then(({createApp}) => {
+            const data = {
+                name: $('.oercampus_editmaterial input.oername').val(),
+                logo_url: $('.oercampus_editmaterial .logo_file').data("oldurl") ?? null,
+                customlogo: $('.oercampus_editmaterial .logo_file').data("customlogo") == '1',
+                filename: $('.oercampus_editmaterial .file.drag-and-drop').data("filename"),
+                filesize: $('.oercampus_editmaterial .file.drag-and-drop').data("filesize"),
+                tags: $('.oercampus_editmaterial .oer_tags').data("defaulttags") ?? [],
+                minimumTags: 5
+            };
+
             const app = createApp({
                 data() {
-                    return {
-                        name: $('.oercampus_editmaterial input.oername').val(),
-                        logo_url: $('.oercampus_editmaterial .logo_file').data("oldurl") ?? null,
-                        customlogo: $('.oercampus_editmaterial .logo_file').data("customlogo") == '1',
-                        filename: $('.oercampus_editmaterial .file.drag-and-drop').data("filename"),
-                        filesize: $('.oercampus_editmaterial .file.drag-and-drop').data("filesize"),
-                        tags: $('.oercampus_editmaterial .oer_tags').data("defaulttags") ?? [],
-                        minimumTags: 5
-                    };
+                    return data;
                 },
-                mounted: function () {
+                mounted() {
                     jQuery("#difficulty_slider_edit").slider({
                         range: true,
                         min: 1,
@@ -74,10 +76,10 @@ STUDIP.ready(() => {
                     jQuery('.oercampus_editmaterial').find(':focusable').first().focus();
                 },
                 methods: {
-                    editName: function () {
+                    editName() {
                         this.name = $('.oername').val();
                     },
-                    editImage: function (event) {
+                    editImage(event) {
                         let reader = new FileReader();
                         reader.addEventListener("load", () => {
                             this.logo_url = reader.result;
@@ -89,11 +91,11 @@ STUDIP.ready(() => {
                                 : event.dataTransfer.files[0]
                         );
                     },
-                    dropImage: function (event) {
+                    dropImage(event) {
                         window.document.getElementById("oer_logo_uploader").files = event.dataTransfer.files;
                         this.editImage(event);
                     },
-                    editFile: function (event) {
+                    editFile(event) {
                         this.filename = event.target.files[0].name;
                         this.filesize = event.target.files[0].size;
                         if (!this.name) {
@@ -101,20 +103,20 @@ STUDIP.ready(() => {
                             $('.oername').val(this.name);
                         }
                     },
-                    dropFile: function (event) {
+                    dropFile(event) {
                         window.document.getElementById("oer_file").files = event.dataTransfer.files;
                         this.editFile(event);
                     },
-                    addTag: function () {
+                    addTag() {
                         if (this.minimumTags < this.tags.length) {
                             this.minimumTags = this.tags.length + 1;
                         } else {
                             this.minimumTags++;
                         }
                     },
-                    removeTag: function (i) {
-                        this.tags.splice(i, 1);
-                        if ((this.minimumTags > this.tags.length) && (this.minimumTags > 5)) {
+                    removeTag(i) {
+                        this.tags = this.tags.filter((element, index) => index !== i);
+                        if (this.minimumTags > this.tags.length && this.minimumTags > 5) {
                             this.minimumTags--;
                         }
                     }
diff --git a/resources/vue/components/Quicksearch.vue b/resources/vue/components/Quicksearch.vue
index 94c1d518f48..dcdd31dfb73 100644
--- a/resources/vue/components/Quicksearch.vue
+++ b/resources/vue/components/Quicksearch.vue
@@ -177,7 +177,7 @@ export default {
         }
     },
     watch: {
-        value (val) {
+        modelValue(val) {
             this.reset(true);
             this.initialize(val);
         },
-- 
GitLab