From d951db9752a26a9c968792ce1a0601d78615ebcf Mon Sep 17 00:00:00 2001
From: Jan-Hendrik Willms <tleilax+studip@gmail.com>
Date: Tue, 24 May 2022 15:58:53 +0000
Subject: [PATCH] correctly render clipboard widgets

Closes #1102

Merge request studip/studip!654
---
 lib/classes/sidebar/ClipboardWidget.class.php |  71 ++++--------
 .../sidebar/RoomClipboardWidget.class.php     |   5 +-
 lib/classes/sidebar/SidebarWidget.php         |  31 ++++-
 templates/sidebar/clipboard-widget.php        |  97 +++++++---------
 templates/sidebar/room-clipboard-widget.php   | 109 ++++++++----------
 templates/sidebar/widget-layout.php           |   5 +-
 6 files changed, 147 insertions(+), 171 deletions(-)

diff --git a/lib/classes/sidebar/ClipboardWidget.class.php b/lib/classes/sidebar/ClipboardWidget.class.php
index d5e7fa273db..f09615e33c6 100644
--- a/lib/classes/sidebar/ClipboardWidget.class.php
+++ b/lib/classes/sidebar/ClipboardWidget.class.php
@@ -65,7 +65,7 @@ class ClipboardWidget extends SidebarWidget
 
         $this->allowed_item_classes = $allowed_item_classes;
         $this->template = 'sidebar/clipboard-widget';
-        $this->title = _('Merkzettel');
+        $this->title = _('Eigene Merkzettel');
         $this->readonly = false;
         $this->apply_button_title = _('Hauptbereich aktualisieren');
 
@@ -78,6 +78,10 @@ class ClipboardWidget extends SidebarWidget
         if (!is_array($this->current_selected_items)) {
             $this->current_selected_items = [];
         }
+
+        $this->setId("ClipboardWidget_{$this->clipboard_widget_id}");
+        $this->setAdditionalAttribute('data-widget_id', $this->getId());
+        $this->addLayoutCSSClass('clipboard-widget');
     }
 
 
@@ -158,62 +162,27 @@ class ClipboardWidget extends SidebarWidget
 
     public function render($variables = [])
     {
-        $template = $GLOBALS['template_factory']->open(
-            $this->template
-        );
-
-        $layout = $GLOBALS['template_factory']->open(
-            'widgets/widget-layout'
-        );
-        $template->set_layout('widgets/widget-layout');
-
         $clipboards = Clipboard::getClipboardsForUser(
             $GLOBALS['user']->id
         );
 
-        if (!$this->current_clipboard_id) {
-            if ($clipboards) {
-                $_SESSION['selected_clipboard_id'] = $clipboards[0]->id;
-                $_SESSION['selected_clipboard_items'] = [];
-                $this->current_clipboard_id = $clipboards[0]->id;
-            }
+        if (!$this->current_clipboard_id && $clipboards) {
+            $_SESSION['selected_clipboard_id'] = $clipboards[0]->id;
+            $_SESSION['selected_clipboard_items'] = [];
+            $this->current_clipboard_id = $clipboards[0]->id;
         }
 
-        $template->set_attribute(
-            'selected_clipboard_id',
-            $this->current_clipboard_id
-        );
-        $template->set_attribute(
-            'selected_clipboard_items',
-            $this->current_selected_items
-        );
-        $template->set_attribute('clipboards', $clipboards);
-        $template->set_attribute(
-            'allowed_item_classes',
-            $this->allowed_item_classes
-        );
-        $template->set_attribute(
-            'clipboard_widget_id',
-            $this->clipboard_widget_id
-        );
-        $template->set_attribute(
-            'draggable_items',
-            $this->draggable_items
-        );
-        $template->set_attribute(
-            'readonly',
-            $this->readonly
-        );
-        $template->set_attribute(
-            'apply_button_title',
-            $this->apply_button_title
-        );
-        $template->set_attribute(
-            'elements',
-            $this->elements
-        );
-
-        return $template->render();
+        return parent::render($variables + [
+            'clipboards'               => $clipboards,
+            'allowed_item_classes'     => $this->allowed_item_classes,
+            'clipboard_widget_id'      => $this->clipboard_widget_id,
+            'draggable_items'          => $this->draggable_items,
+            'readonly'                 => $this->readonly,
+            'apply_button_title'       => $this->apply_button_title,
+            'elements'                 => $this->elements,
+            'selected_clipboard_id'    => $this->current_clipboard_id,
+            'selected_clipboard_items' => $this->current_selected_items,
+        ]);
     }
 
     /**
diff --git a/lib/classes/sidebar/RoomClipboardWidget.class.php b/lib/classes/sidebar/RoomClipboardWidget.class.php
index 3973c4af415..cf6b9672272 100644
--- a/lib/classes/sidebar/RoomClipboardWidget.class.php
+++ b/lib/classes/sidebar/RoomClipboardWidget.class.php
@@ -18,6 +18,9 @@ class RoomClipboardWidget extends ClipboardWidget
 
         parent::__construct(['Room']);
 
+        $this->setTitle(_('Individuelle Raumgruppen'));
+        $this->template = 'sidebar/room-clipboard-widget';
+
         $current_user = User::findCurrent();
 
         $this->addLink(
@@ -49,7 +52,5 @@ class RoomClipboardWidget extends ClipboardWidget
                  'data-show_in_dialog' => '1']
             );
         }
-
-        $this->template = 'sidebar/room-clipboard-widget';
     }
 }
diff --git a/lib/classes/sidebar/SidebarWidget.php b/lib/classes/sidebar/SidebarWidget.php
index 1957eda7598..0e4cc5fa91e 100644
--- a/lib/classes/sidebar/SidebarWidget.php
+++ b/lib/classes/sidebar/SidebarWidget.php
@@ -9,6 +9,9 @@
  */
 class SidebarWidget extends Widget
 {
+    protected $additional_attributes = [];
+
+
     public function __construct()
     {
         $this->layout = 'sidebar/widget-layout.php';
@@ -46,7 +49,7 @@ class SidebarWidget extends Widget
     {
         $this->extra = $extra;
     }
-    
+
     public function getExtra()
     {
         return $this->extra;
@@ -57,6 +60,24 @@ class SidebarWidget extends Widget
         $this->extra = false;
     }
 
+    public function setAdditionalAttribute(string $key, $value)
+    {
+        $this->additional_attributes[$key] = $value;
+    }
+
+    public function setAdditionalAttributes(array $attributes)
+    {
+        foreach ($attributes as $key => $value) {
+            $this->setAdditionalAttribute($key, $value);
+        }
+    }
+
+    public function removeAdditionalAttribute(string $key)
+    {
+        unset($this->additional_attributes[$key]);
+    }
+
+
     /**
      * Renders the widget.
      * The widget will only be rendered if it contains at least one element.
@@ -65,6 +86,12 @@ class SidebarWidget extends Widget
      */
     public function render($variables = [])
     {
+        $attributes = $this->additional_attributes;
+        if (!empty($this->id)) {
+            $attributes['id'] = $this->id;
+        }
+        $variables['additional_attributes'] = $attributes;
+
         return parent::render($variables);
     }
-}
\ No newline at end of file
+}
diff --git a/templates/sidebar/clipboard-widget.php b/templates/sidebar/clipboard-widget.php
index f3716a6dc26..dc2b911e143 100644
--- a/templates/sidebar/clipboard-widget.php
+++ b/templates/sidebar/clipboard-widget.php
@@ -1,56 +1,47 @@
-<section class="sidebar-widget clipboard-widget"
-         id="ClipboardWidget_<?= htmlReady($clipboard_widget_id) ?>"
-         data-widget_id="<?= htmlReady($clipboard_widget_id) ?>">
-    <header class="sidebar-widget-header">
-        <?= _('Eigene Merkzettel') ?>
-    </header>
-    <section class="sidebar-widget-content">
-        <?= $this->render_partial(
-            'sidebar/clipboard-area.php',
-            [
-                'clipboards' => $clipboards,
-                'empty_clipboard_string' => _('Ziehen Sie Elemente in diesen Bereich um den Merkzettel zu füllen.'),
-                'selected_clipboard_id' => ($clipboards[0] instanceof Clipboard
-                                          ? $clipboards[0]->id
-                                          : ''),
-                'draggable_items' => $draggable_items,
-                'clipboard_widget_id' => $clipboard_widget_id
-            ]
-        ) ?>
+<?= $this->render_partial(
+    'sidebar/clipboard-area.php',
+    [
+        'clipboards' => $clipboards,
+        'empty_clipboard_string' => _('Ziehen Sie Elemente in diesen Bereich um den Merkzettel zu füllen.'),
+        'selected_clipboard_id' => ($clipboards[0] instanceof Clipboard
+                                  ? $clipboards[0]->id
+                                  : ''),
+        'draggable_items' => $draggable_items,
+        'clipboard_widget_id' => $clipboard_widget_id
+    ]
+) ?>
 
-        <ul class="widget-list widget-links invisible">
-        <? foreach ($elements as $index => $element): ?>
-            <li id="<?= htmlReady('link-' . md5($element->url)) ?>" <?= $element->icon ? 'style="' . $element->icon->asCSS() .'"' : '' ?>>
-                <?= $element->render() ?>
-            </li>
-        <? endforeach; ?>
-        </ul>
+<ul class="widget-list widget-links invisible">
+<? foreach ($elements as $index => $element): ?>
+    <li id="<?= htmlReady('link-' . md5($element->url)) ?>" <?= $element->icon ? 'style="' . $element->icon->asCSS() .'"' : '' ?>>
+        <?= $element->render() ?>
+    </li>
+<? endforeach; ?>
+</ul>
 
-        <? if (!$readonly): ?>
-            <form class="default new-clipboard-form"
-                  action="<?= URLHelper::getLink(
-                          'dispatch.php/clipboard/add'
-                          )?>"
-                  method="post">
-                <?= CSRFProtection::tokenTag() ?>
-                <input type="hidden" name="allowed_item_class"
-                       value="<?= htmlReady($allowed_item_class) ?>">
-                <input type="hidden" name="widget_id"
-                       value="<?= htmlReady($clipboard_widget_id) ?>">
-                <label>
-                    <?= _('Merkzettel hinzufügen') ?>
-                    <?= tooltipIcon(_('Geben Sie bitte einen Namen ein und klicken Sie auf das Plus-Symbol um einen neuen Merkzettel zu erstellen.')) ?>
-                    <input type="text" name="name" placeholder="<?= _('Name des neuen Merkzettels') ?>"
-                </label>
+<? if (!$readonly): ?>
+    <form class="default new-clipboard-form"
+          action="<?= URLHelper::getLink(
+                  'dispatch.php/clipboard/add'
+                  )?>"
+          method="post">
+        <?= CSRFProtection::tokenTag() ?>
+        <input type="hidden" name="allowed_item_class"
+               value="<?= htmlReady($allowed_item_class) ?>">
+        <input type="hidden" name="widget_id"
+               value="<?= htmlReady($clipboard_widget_id) ?>">
+        <label>
+            <?= _('Merkzettel hinzufügen') ?>
+            <?= tooltipIcon(_('Geben Sie bitte einen Namen ein und klicken Sie auf das Plus-Symbol um einen neuen Merkzettel zu erstellen.')) ?>
+            <input type="text" name="name" placeholder="<?= _('Name des neuen Merkzettels') ?>"
+        </label>
 
-                <?= Icon::create('add', 'clickable',
-                    [   'title' => _('Hinzufügen')])->asInput([
-                        'name'   => 'save',
-                        'id' => 'add-clipboard-button',
-                        'class' => 'middle',
-                        'disabled' => 'disabled'
-                    ]) ?>
-            </form>
-        <? endif ?>
-    </section>
-</section>
+        <?= Icon::create('add', 'clickable',
+            [   'title' => _('Hinzufügen')])->asInput([
+                'name'   => 'save',
+                'id' => 'add-clipboard-button',
+                'class' => 'middle',
+                'disabled' => 'disabled'
+            ]) ?>
+    </form>
+<? endif ?>
diff --git a/templates/sidebar/room-clipboard-widget.php b/templates/sidebar/room-clipboard-widget.php
index ff00513fcf3..dfd2a015712 100644
--- a/templates/sidebar/room-clipboard-widget.php
+++ b/templates/sidebar/room-clipboard-widget.php
@@ -1,63 +1,52 @@
-<section class="sidebar-widget clipboard-widget"
-         id="ClipboardWidget_<?= htmlReady($clipboard_widget_id) ?>"
-         data-widget_id="<?= htmlReady($clipboard_widget_id) ?>">
-    <header class="sidebar-widget-header">
-        <?= _('Individuelle Raumgruppen') ?>
-    </header>
-    <section class="sidebar-widget-content">
-        <div id="clipboard-group-container" class="<?= $clipboards ? '' : 'invisible' ?>">
-            <?= $this->render_partial(
-                'sidebar/clipboard-area.php',
-                [
-                    'clipboards' => $clipboards,
-                    'allowed_item_class' => $allowed_item_class,
-                    'empty_clipboard_string' => _('Ziehen Sie Räume in diesen Bereich um die Raumgruppe zu füllen.'),
-                    'selected_clipboard_id' => $selected_clipboard_id,
-                    'draggable_items' => $draggable_items,
-                    'special_item_template' => 'sidebar/room-clipboard-item',
-                    'clipboard_widget_id' => $clipboard_widget_id
-                ]
-                ); ?>
+<div id="clipboard-group-container" class="<?= $clipboards ? '' : 'invisible' ?>">
+    <?= $this->render_partial(
+        'sidebar/clipboard-area.php',
+        [
+            'clipboards' => $clipboards,
+            'allowed_item_class' => $allowed_item_class,
+            'empty_clipboard_string' => _('Ziehen Sie Räume in diesen Bereich um die Raumgruppe zu füllen.'),
+            'selected_clipboard_id' => $selected_clipboard_id,
+            'draggable_items' => $draggable_items,
+            'special_item_template' => 'sidebar/room-clipboard-item',
+            'clipboard_widget_id' => $clipboard_widget_id
+        ]
+        ); ?>
 
-            <? if (!$readonly): ?>
-                <ul class="widget-list widget-links invisible">
-                <? foreach ($elements as $index => $element): ?>
-                    <li id="<?= htmlReady('link-' . md5($element->url)) ?>" <?= $element->icon ? 'style="' . $element->icon->asCSS() .'"' : '' ?>>
-                    <a <?= arrayToHtmlAttributes($element->attributes) ?>
-                        data-url_path = "<?= htmlReady($element->url) ?>">
-                        <?= htmlReady($element->label) ?>
-                    </a>
-                    </li>
-                <? endforeach; ?>
-                </ul>
+<? if (!$readonly): ?>
+    <ul class="widget-list widget-links invisible">
+    <? foreach ($elements as $index => $element): ?>
+        <li id="<?= htmlReady('link-' . md5($element->url)) ?>" <?= $element->icon ? 'style="' . $element->icon->asCSS() .'"' : '' ?>>
+        <a <?= arrayToHtmlAttributes($element->attributes) ?>
+            data-url_path = "<?= htmlReady($element->url) ?>">
+            <?= htmlReady($element->label) ?>
+        </a>
+        </li>
+    <? endforeach; ?>
+    </ul>
+    <form class="default new-clipboard-form"
+          action="<?= URLHelper::getLink(
+                  'dispatch.php/clipboard/add'
+                  )?>"
+          method="post">
+        <?= CSRFProtection::tokenTag() ?>
+        <input type="hidden" name="allowed_item_class"
+               value="<?= htmlReady($allowed_item_class) ?>">
+        <input type="hidden" name="widget_id"
+               value="<?= htmlReady($clipboard_widget_id) ?>">
+        <label>
+            <?= _('Raumgruppe hinzufügen') ?>
+            <?= tooltipIcon(_('Geben Sie bitte einen Namen ein und klicken Sie auf das Plus-Symbol um eine neue Raumgruppe zu erstellen.')) ?>
+            <input type="text" name="name" placeholder="<?= _('Name der neuen Raumgruppe') ?>">
 
-            </div>
+            <?= Icon::create('add', 'clickable',
+                [   'title' => _('Hinzufügen')])->asInput([
+                    'name'   => 'save',
+                    'id' => 'add-clipboard-button',
+                    'class' => 'middle',
+                    'disabled' => 'disabled'
+                ]) ?>
+        </label>
 
-            <form class="default new-clipboard-form"
-                  action="<?= URLHelper::getLink(
-                          'dispatch.php/clipboard/add'
-                          )?>"
-                  method="post">
-                <?= CSRFProtection::tokenTag() ?>
-                <input type="hidden" name="allowed_item_class"
-                       value="<?= htmlReady($allowed_item_class) ?>">
-                <input type="hidden" name="widget_id"
-                       value="<?= htmlReady($clipboard_widget_id) ?>">
-                <label>
-                    <?= _('Raumgruppe hinzufügen') ?>
-                    <?= tooltipIcon(_('Geben Sie bitte einen Namen ein und klicken Sie auf das Plus-Symbol um eine neue Raumgruppe zu erstellen.')) ?>
-                    <input type="text" name="name" placeholder="<?= _('Name der neuen Raumgruppe') ?>">
-
-                    <?= Icon::create('add', 'clickable',
-                        [   'title' => _('Hinzufügen')])->asInput([
-                            'name'   => 'save',
-                            'id' => 'add-clipboard-button',
-                            'class' => 'middle',
-                            'disabled' => 'disabled'
-                        ]) ?>
-                </label>
-
-            </form>
-        <? endif ?>
-    </section>
-</section>
+    </form>
+<? endif ?>
+</div>
diff --git a/templates/sidebar/widget-layout.php b/templates/sidebar/widget-layout.php
index de3f82fb74e..779511c04c4 100644
--- a/templates/sidebar/widget-layout.php
+++ b/templates/sidebar/widget-layout.php
@@ -1,6 +1,5 @@
-<div class="<?= $base_class ?>-widget <? if ($layout_css_classes && is_array($layout_css_classes)) echo htmlReady(implode(' ', $layout_css_classes)); ?>"
-    <? if ($id) printf('id="%s"', htmlReady($id)) ?>
-    <? if ($style) printf('style="%s"', $style) ?>>
+<div class="<?= $base_class ?>-widget <?= is_array($layout_css_classes) ? htmlReady(implode(' ', $layout_css_classes)) : '' ?>"
+    <?= arrayToHtmlAttributes($additional_attributes) ?>>
 <? if ($title): ?>
     <div class="<?= $base_class ?>-widget-header">
     <? if ($extra): ?>
-- 
GitLab