From bf84e121ecfe12dff9c2cbbc98410d245fe639ce Mon Sep 17 00:00:00 2001
From: Jan-Hendrik Willms <tleilax+studip@gmail.com>
Date: Fri, 19 Aug 2022 18:17:33 +0000
Subject: [PATCH] fix errors in resource management, fixes #1331

Closes #1331

Merge request studip/studip!822
---
 app/controllers/resources/building.php        | 204 +++++-------------
 app/controllers/resources/export.php          |   3 +-
 app/views/resources/building/lock.php         |  21 --
 lib/models/resources/BrokenResource.class.php |  42 ++--
 lib/models/resources/Resource.class.php       |   5 +-
 lib/models/resources/ResourceLabel.class.php  |  62 +++---
 6 files changed, 110 insertions(+), 227 deletions(-)
 delete mode 100644 app/views/resources/building/lock.php

diff --git a/app/controllers/resources/building.php b/app/controllers/resources/building.php
index 895d1afab21..e77fed8a4ff 100644
--- a/app/controllers/resources/building.php
+++ b/app/controllers/resources/building.php
@@ -30,38 +30,38 @@ class Resources_BuildingController extends AuthenticatedController
             }
         }
     }
-    
+
     public function index_action($building_id)
     {
         $this->building = Building::find($building_id);
         $building_details = [];
-    
+
         if($this->building->number) {
             $building_details[_('Gebäudenummer')] = $this->building->number;
         }
         if($this->building->address) {
             $building_details[_('Adresse')] = $this->building->address;
         }
-        
+
         $this->building_details = $building_details;
         $this->geo_coordinates_object = $this->building->getPropertyObject(
             'geo_coordinates'
         );
-        
+
         PageLayout::setTitle(
             $this->building->getFullName() . ' - ' . _('Informationen')
         );
         if (Navigation::hasItem('/room_management/overview/index')) {
             Navigation::activateItem('/room_management/overview/index');
         }
-        
+
         $user = User::findCurrent();
-        
+
         $current_user_is_resource_admin = $this->building->userHasPermission(
             $user,
             'admin'
         );
-        
+
         $sidebar           = Sidebar::get();
         $actions           = new ActionsWidget();
         $actions_available = false;
@@ -96,30 +96,30 @@ class Resources_BuildingController extends AuthenticatedController
         if ($actions_available) {
             $sidebar->addWidget($actions);
         }
-        
+
         $tree_widget = new ResourceTreeWidget(Location::findAll(), null, null);
         $tree_widget->setCurrentResource($this->building);
-        
+
         $sidebar->addWidget($tree_widget);
     }
-    
+
     public function select_category_action()
     {
         PageLayout::setTitle(_('Gebäude hinzufügen'));
         if (!ResourceManager::userHasGlobalPermission(User::findCurrent(), 'admin')) {
             throw new AccessDeniedException();
         }
-        
+
         $this->next_action = Request::get('next_action');
         $this->categories  = ResourceCategory::findByClass_name('Building');
-        
+
         if (!$this->categories) {
             PageLayout::postError(
                 _('Es sind keine Gebäudekategorien eingerichtet!')
             );
         }
     }
-    
+
     protected function addEditHandler($mode = 'edit', $building_id = null)
     {
         $this->mode      = $mode;
@@ -133,7 +133,7 @@ class Resources_BuildingController extends AuthenticatedController
                 return;
             }
         }
-        
+
         //Get all properties of the building:
         $this->property_data              = [];
         $this->grouped_defined_properties = [];
@@ -152,7 +152,7 @@ class Resources_BuildingController extends AuthenticatedController
                 );
                 return;
             }
-            
+
             $this->grouped_defined_properties = $this->category->getGroupedPropertyDefinitions(
                 ['geo_coordinates', 'number', 'address']
             );
@@ -163,23 +163,23 @@ class Resources_BuildingController extends AuthenticatedController
                 );
             PageLayout::setTitle(sprintf(_('%s: Bearbeiten'), $this->building->getFullName()));
         }
-        
+
         if (($mode == 'add') || ($mode == 'edit')) {
             $this->possible_parents = [];
             $locations              = Location::findAll();
             foreach ($locations as $location) {
                 $this->possible_parents[] = $location;
-                
+
                 //Get all ResourceLabel resources from the location
                 //and add them as possible parents:
                 $labels = $location->findChildrenByClassName('ResourceLabel', 3);
-                
+
                 foreach ($labels as $label) {
                     $this->possible_parents[] = $label;
                 }
             }
         }
-        
+
         foreach ($this->grouped_defined_properties as $properties) {
             foreach ($properties as $property) {
                 if ($mode == 'add') {
@@ -190,7 +190,7 @@ class Resources_BuildingController extends AuthenticatedController
                 }
             }
         }
-        
+
         $this->show_form = true;
         if (Request::submitted('confirmed')) {
             CSRFProtection::verifyUnsafeRequest();
@@ -205,9 +205,9 @@ class Resources_BuildingController extends AuthenticatedController
             $this->altitude      = Request::float('geo_coordinates_altitude');
             $this->osm_link      = Request::get('geo_coordinates_osm_link');
             $this->sort_position = Request::get('sort_position');
-            
+
             $this->property_data = Request::getArray('properties');
-            
+
             //validation:
             if (!$this->name) {
                 PageLayout::postError(
@@ -227,73 +227,73 @@ class Resources_BuildingController extends AuthenticatedController
                 );
                 return;
             }
-            
+
             //data conversion:
-            
+
             $position_string = '';
             if ($this->latitude >= 0.0) {
                 $position_string .= '+';
             }
             $position_string .= number_format($this->latitude, 7);
-            
+
             if ($this->longitude >= 0.0) {
                 $position_string .= '+';
             }
             $position_string .= number_format($this->longitude, 7);
-            
+
             if ($this->altitude >= 0.0) {
                 $position_string .= '+';
             }
             $position_string .= number_format($this->altitude, 7) . 'CRSWGS_84/';
-            
+
             //store data:
-            
+
             if ($mode == 'add') {
                 $this->building              = new Building();
                 $this->building->category_id = $this->category_id;
             }
-            
+
             $this->building->name        = $this->name;
             $this->building->description = $this->description;
             $this->building->parent_id   = $this->parent_id;
-            
+
             if ($this->building->isDirty()) {
                 $successfully_stored = $this->building->store();
             } else {
                 $successfully_stored = true;
             }
-            
+
             if ($GLOBALS['perm']->have_perm('root')) {
                 $this->building->sort_position = $this->sort_position;
             }
-            
+
             //Store properties:
-            
+
             //Special treatment for the geo_coordinates property:
-            
+
             $failed_properties = 0;
             try {
                 $this->building->geo_coordinates = $position_string;
             } catch (Exception $e) {
                 $failed_properties++;
             }
-            
+
             //Special treatment for the number property:
             try {
                 $this->building->number = $this->number;
             } catch (Exception $e) {
                 $failed_properties++;
             }
-            
+
             //Special treatment for the address property:
             try {
                 $this->building->address = $this->address;
             } catch (Exception $e) {
                 $failed_properties++;
             }
-            
+
             //Store all non-special properties:
-            
+
             $user              = User::findCurrent();
             $failed_properties += count(
                 $this->building->setPropertiesById(
@@ -301,9 +301,9 @@ class Resources_BuildingController extends AuthenticatedController
                     $user
                 )
             );
-            
+
             //Display result messages:
-            
+
             if ($successfully_stored && !$failed_properties) {
                 $this->show_form = false;
                 PageLayout::postSuccess(
@@ -347,16 +347,16 @@ class Resources_BuildingController extends AuthenticatedController
             }
         }
     }
-    
-    
+
+
     public function add_action()
     {
         if (!ResourceManager::userHasGlobalPermission(User::findCurrent(), 'admin')) {
             throw new AccessDeniedException();
         }
-        
+
         PageLayout::setTitle(_('Gebäude hinzufügen'));
-        
+
         $this->category_id = Request::get('category_id');
         $this->category    = ResourceCategory::find($this->category_id);
         if (!$this->category) {
@@ -378,26 +378,26 @@ class Resources_BuildingController extends AuthenticatedController
             $this->addEditHandler('add');
         }
     }
-    
-    
+
+
     public function edit_action($building_id = null)
     {
         if (!ResourceManager::userHasGlobalPermission(User::findCurrent(), 'admin')) {
             throw new AccessDeniedException();
         }
-        
+
         $this->addEditHandler('edit', $building_id);
     }
-    
-    
+
+
     public function delete_action($building_id = null)
     {
         if (!ResourceManager::userHasGlobalPermission(User::findCurrent(), 'admin')) {
             throw new AccessDeniedException();
         }
-        
+
         $this->show_form = false;
-        
+
         $this->building = Building::find($building_id);
         if (!$this->building) {
             PageLayout::postError(
@@ -406,7 +406,7 @@ class Resources_BuildingController extends AuthenticatedController
             return;
         }
         PageLayout::setTitle(sprintf(_('%s: Löschen'), $this->building->getFullName()));
-        
+
         //geo_coordinates_object is needed in the index view that is loaded
         //from the view for this action.
         $this->geo_coordinates_object = $this->building->getPropertyObject(
@@ -415,7 +415,7 @@ class Resources_BuildingController extends AuthenticatedController
         $this->required_properties    = Building::getRequiredProperties(
             ['geo_coordinates']
         );
-        
+
         $this->show_form = true;
         if (Request::submitted('save')) {
             CSRFProtection::verifyUnsafeRequest();
@@ -427,100 +427,4 @@ class Resources_BuildingController extends AuthenticatedController
             }
         }
     }
-    
-    
-    public function lock_action($building_id = null)
-    {
-        if (!ResourceManager::userHasGlobalPermission(User::findCurrent(), 'admin')) {
-            throw new AccessDeniedException();
-        }
-        
-        $this->show_form = false;
-        $this->building  = Room::find($building_id);
-        if (!$this->building) {
-            PageLayout::postError(
-                _('Das angegebene Gebäude wurde nicht gefunden!')
-            );
-            return;
-        }
-        
-        PageLayout::setTitle(
-            sprintf(
-                _('Gebäude %s sperren'),
-                $this->building->name
-            )
-        );
-        
-        if (Request::submitted('confirmed')) {
-            $begin_date = Request::get('begin_date');
-            $begin_time = Request::get('begin_time');
-            $end_date   = Request::get('end_date');
-            $end_time   = Request::get('end_time');
-            
-            //$begin and $end are in the format Y-m-d H:i
-            $begin_date  = explode('.', $begin_date);
-            $begin_time  = explode(':', $begin_time);
-            $this->begin = new DateTime();
-            $this->begin->setDate(
-                intval($begin_date[2]),
-                intval($begin_date[1]),
-                intval($begin_date[0])
-            );
-            $this->begin->setTime(
-                intval($begin_time[0]),
-                intval($begin_time[1]),
-                0
-            );
-            
-            $end_date  = explode('.', $end_date);
-            $end_time  = explode(':', $end_time);
-            $this->end = new DateTime();
-            $this->end->setDate(
-                intval($end_date[2]),
-                intval($end_date[1]),
-                intval($end_date[0])
-            );
-            $this->end->setTime(
-                intval($end_time[0]),
-                intval($end_time[1]),
-                0
-            );
-            
-            try {
-                $lock = ResourceManager::lockResource(
-                    $this->building,
-                    $this->begin,
-                    $this->end
-                );
-            } catch (ResourceUnlockableException $e) {
-                PageLayout::postError(
-                    _('Das Gebäude konnte nicht gesperrt werden!'),
-                    [$e->getMessage()]
-                );
-                $this->show_form = true;
-                return;
-            } catch (ResourceUnavailableException $e) {
-                PageLayout::postError(
-                    _('Das Gebäude konnte nicht gesperrt werden!'),
-                    [$e->getMessage()]
-                );
-                $this->show_form = true;
-                return;
-            }
-            $this->show_form = false;
-            PageLayout::postSuccess(
-                sprintf(
-                    _('Das Gebäude wurde im Zeitraum von %1$s bis %2$s gesperrt!'),
-                    $this->begin->format('d.m.Y H:i'),
-                    $this->end->format('d.m.Y H:i')
-                )
-            );
-        } else {
-            //Set default form data:
-            $this->begin = new DateTime();
-            $this->end   = new DateTime();
-            $this->end->add(new DateInterval('P1D'));
-            $this->show_form = true;
-        }
-    }
-}
\ No newline at end of file
+}
diff --git a/app/controllers/resources/export.php b/app/controllers/resources/export.php
index a329b9d5971..c838f9fa3bf 100644
--- a/app/controllers/resources/export.php
+++ b/app/controllers/resources/export.php
@@ -454,8 +454,7 @@ class Resources_ExportController extends AuthenticatedController
                     [0, 2]
                 );
             } else {
-                $intervals = ResourceManager::getBookingIntervalsForResource(
-                    $this->resource,
+                $intervals = $this->resource->getResourceBookings(
                     $week_begin,
                     $week_end,
                     [0, 2]
diff --git a/app/views/resources/building/lock.php b/app/views/resources/building/lock.php
deleted file mode 100644
index d80f04b0512..00000000000
--- a/app/views/resources/building/lock.php
+++ /dev/null
@@ -1,21 +0,0 @@
-<? if ($show_form): ?>
-<form class="default" method="post" data-dialog="reload-on-close"
-    action="<?= $controller->link_for('resources/building/lock/' . $building->id) ?>">
-    <fieldset>
-        <legend><?= _('Bitte Sperrzeiten auswählen') ?></legend>
-        <label>
-            <?= _('Startzeitpunkt') ?>
-            <input type="text" class="has-date-picker" name="begin_date" value="<?= htmlReady($begin->format('d.m.Y')) ?>">
-            <input type="text" class="has-time-picker" name="begin_time" value="<?= htmlReady($begin->format('H:i')) ?>">
-        </label>
-        <label>
-            <?= _('Endzeitpunkt') ?>
-            <input type="text" class="has-date-picker" name="end_date" value="<?= htmlReady($end->format('d.m.Y')) ?>">
-            <input type="text" class="has-time-picker"  name="end_time" value="<?= htmlReady($end->format('H:i')) ?>">
-        </label>
-    </fieldset>
-    <div data-dialog-button>
-        <?= \Studip\Button::create(_('Sperren'), 'confirmed') ?>
-    </div>
-</form>
-<? endif ?>
diff --git a/lib/models/resources/BrokenResource.class.php b/lib/models/resources/BrokenResource.class.php
index 10897e702a8..d1014ef3932 100644
--- a/lib/models/resources/BrokenResource.class.php
+++ b/lib/models/resources/BrokenResource.class.php
@@ -38,17 +38,17 @@ class BrokenResource extends Resource
     {
         return null;
     }
-    
+
     public function setFolder(ResourceFolder $folder)
     {
         return false;
     }
-    
+
     public function createFolder()
     {
         return null;
     }
-    
+
     public function createSimpleBooking(
         User $user,
         DateTime $begin,
@@ -75,7 +75,7 @@ class BrokenResource extends Resource
     {
         return null;
     }
-    
+
     public function createBooking(
         User $user,
         $range_id = null,
@@ -91,7 +91,7 @@ class BrokenResource extends Resource
     ) {
         return null;
     }
-    
+
     public function createSimpleRequest(
         User $user,
         DateTime $begin,
@@ -114,7 +114,7 @@ class BrokenResource extends Resource
     {
         return null;
     }
-    
+
     public function createLock(
         User $user,
         DateTime $begin,
@@ -124,28 +124,28 @@ class BrokenResource extends Resource
     {
         return null;
     }
-    
+
     public function propertyExists($name = '')
     {
         //Resource labels don't have properties:
         return false;
     }
-    
+
     public function getPropertyObject(string $name = '')
     {
         return null;
     }
-    
+
     public function getProperty(string $name = '')
     {
         return null;
     }
-    
+
     public function getPropertyRelatedObject(string $name = '')
     {
         return null;
     }
-    
+
     public function setProperty(string $name = '', $state = '', $user_id = null)
     {
         return false;
@@ -155,7 +155,7 @@ class BrokenResource extends Resource
     {
         return false;
     }
-    
+
     public function setPropertyByDefinitionId(
         $property_definition_id = null,
         $state = null
@@ -163,22 +163,22 @@ class BrokenResource extends Resource
     {
         return false;
     }
-    
+
     public function setPropertyRelatedObject(string $name, SimpleORMap $object)
     {
         return false;
     }
-    
+
     public function getIcon($role = Icon::ROLE_INFO)
     {
         return Icon::create('resources-broken', $role);
     }
-    
+
     public function getPropertyArray($only_requestable_properties = false)
     {
         return [];
     }
-    
+
     public function isAssigned(
         DateTime $begin,
         DateTime $end,
@@ -196,7 +196,7 @@ class BrokenResource extends Resource
     {
         return false;
     }
-    
+
     public function isLocked(
         DateTime $begin,
         DateTime $end,
@@ -205,7 +205,7 @@ class BrokenResource extends Resource
     {
         return true;
     }
-    
+
     public function isAvailable(
         DateTime $begin,
         DateTime $end,
@@ -214,12 +214,12 @@ class BrokenResource extends Resource
     {
         return false;
     }
-    
+
     public function isAvailableForRequest(ResourceRequest $request)
     {
         return false;
     }
-    
+
     public function getFullName()
     {
         return sprintf('%1$s (%2$s)', $this->name, _('defekt'));
@@ -230,7 +230,7 @@ class BrokenResource extends Resource
         return [];
     }
 
-    public function getResourceBookings(DateTime $begin, DateTime $end)
+    public function getResourceBookings(DateTime $begin, DateTime $end, array $booking_types = [0])
     {
         return [];
     }
diff --git a/lib/models/resources/Resource.class.php b/lib/models/resources/Resource.class.php
index 89fc3875e51..9e2bf997a61 100644
--- a/lib/models/resources/Resource.class.php
+++ b/lib/models/resources/Resource.class.php
@@ -2739,10 +2739,11 @@ class Resource extends SimpleORMap implements StudipItem
      *
      * @param DateTime $begin Begin of timeframe.
      * @param DateTime $end End of timeframe.
+     * @param array $booking_types
      *
      * @return ResourceBooking[] An array of ResourceBooking objects.
      */
-    public function getResourceBookings(DateTime $begin, DateTime $end)
+    public function getResourceBookings(DateTime $begin, DateTime $end, array $booking_types = [0])
     {
         return ResourceBooking::findByResourceAndTimeRanges(
             $this,
@@ -2752,7 +2753,7 @@ class Resource extends SimpleORMap implements StudipItem
                     'end' => $end->getTimestamp()
                 ]
             ],
-            [0]
+            $booking_types
         );
     }
 
diff --git a/lib/models/resources/ResourceLabel.class.php b/lib/models/resources/ResourceLabel.class.php
index c0d92e046e7..b75d0475ab6 100644
--- a/lib/models/resources/ResourceLabel.class.php
+++ b/lib/models/resources/ResourceLabel.class.php
@@ -31,17 +31,17 @@ class ResourceLabel extends Resource
     {
         return null;
     }
-    
+
     public function setFolder(ResourceFolder $folder)
     {
         return false;
     }
-    
+
     public function createFolder()
     {
         return null;
     }
-    
+
     public function createSimpleBooking(
         User $user,
         DateTime $begin,
@@ -54,7 +54,7 @@ class ResourceLabel extends Resource
     {
         return null;
     }
-    
+
     public function createBookingFromRequest(
         User $user,
         ResourceRequest $request,
@@ -68,7 +68,7 @@ class ResourceLabel extends Resource
     {
         return null;
     }
-    
+
     public function createBooking(
         User $user,
         $range_id = null,
@@ -85,7 +85,7 @@ class ResourceLabel extends Resource
     {
         return null;
     }
-    
+
     public function createSimpleRequest(
         User $user,
         DateTime $begin,
@@ -96,7 +96,7 @@ class ResourceLabel extends Resource
     {
         return null;
     }
-    
+
     public function createRequest(
         User $user,
         $date_range_ids = null,
@@ -107,7 +107,7 @@ class ResourceLabel extends Resource
     {
         return null;
     }
-    
+
     public function createLock(
         User $user,
         DateTime $begin,
@@ -117,38 +117,38 @@ class ResourceLabel extends Resource
     {
         return null;
     }
-    
+
     public function propertyExists($name = '')
     {
         //Resource labels don't have properties:
         return false;
     }
-    
+
     public function getPropertyObject(string $name)
     {
         return null;
     }
-    
+
     public function getProperty(string $name)
     {
         return null;
     }
-    
+
     public function getPropertyRelatedObject(string $name)
     {
         return null;
     }
-    
+
     public function setProperty(string $name, $state = '', $user_id = null)
     {
         return false;
     }
-    
+
     public function isPropertyEditable(string $name, User $user)
     {
         return false;
     }
-    
+
     public function setPropertyByDefinitionId(
         $property_definition_id = null,
         $state = null
@@ -156,22 +156,22 @@ class ResourceLabel extends Resource
     {
         return false;
     }
-    
+
     public function setPropertyRelatedObject(string $name, SimpleORMap $object)
     {
         return false;
     }
-    
+
     public function getIcon($role = Icon::ROLE_INFO)
     {
         return Icon::create('resource-label', $role);
     }
-    
+
     public function getPropertyArray($only_requestable_properties = false)
     {
         return [];
     }
-    
+
     public function isAssigned(
         DateTime $begin,
         DateTime $end,
@@ -180,7 +180,7 @@ class ResourceLabel extends Resource
     {
         return false;
     }
-    
+
     public function isReserved(
         DateTime $begin,
         DateTime $end,
@@ -189,7 +189,7 @@ class ResourceLabel extends Resource
     {
         return false;
     }
-    
+
     public function isLocked(
         DateTime $begin,
         DateTime $end,
@@ -198,7 +198,7 @@ class ResourceLabel extends Resource
     {
         return true;
     }
-    
+
     public function isAvailable(
         DateTime $begin,
         DateTime $end,
@@ -207,42 +207,42 @@ class ResourceLabel extends Resource
     {
         return false;
     }
-    
+
     public function isAvailableForRequest(ResourceRequest $request)
     {
         return false;
     }
-    
+
     public function getFullName()
     {
         return $this->name;
     }
-    
+
     public function getOpenResourceRequests(DateTime $begin, DateTime $end)
     {
         return [];
     }
-    
-    public function getResourceBookings(DateTime $begin, DateTime $end)
+
+    public function getResourceBookings(DateTime $begin, DateTime $end, array $booking_types = [0])
     {
         return [];
     }
-    
+
     public function getResourceLocks(DateTime $begin, DateTime $end)
     {
         return [];
     }
-    
+
     public function hasFiles()
     {
         return false;
     }
-    
+
     public function checkHierarchy()
     {
         return true;
     }
-    
+
     public function getItemAvatarURL()
     {
         return Icon::create('info',  Icon::ROLE_INFO)->asImagePath();
-- 
GitLab