Start fleshing out the K_Resource_Group stuff.
authorMichael J. Rubinsky <mrubinsk@horde.org>
Fri, 18 Sep 2009 04:38:48 +0000 (00:38 -0400)
committerMichael J. Rubinsky <mrubinsk@horde.org>
Tue, 29 Sep 2009 20:53:56 +0000 (16:53 -0400)
kronolith/lib/Resource/Group.php [new file with mode: 0644]
kronolith/scripts/upgrades/2009-08-17_add_resources.sql

diff --git a/kronolith/lib/Resource/Group.php b/kronolith/lib/Resource/Group.php
new file mode 100644 (file)
index 0000000..0a72b60
--- /dev/null
@@ -0,0 +1,202 @@
+<?php
+/**
+ * Kronolith_Resource implementation to represent a group of similar resources.
+ *
+ * Copyright 2009 The Horde Project (http://www.horde.org/)
+ *
+ * See the enclosed file COPYING for license information (GPL). If you
+ * did not receive this file, see http://www.fsf.org/copyleft/gpl.html.
+ *
+ * @author Michael J. Rubinsky <mrubinsk@horde.org>
+ * @package Kronolith
+ */
+class Kronolith_Resource_Group extends Kronolith_Resource_Base
+{
+
+    /**
+     *
+     * @var Kronolith_Driver_Resource
+     */
+    private $_driver;
+
+    /**
+     * Local cache for event that accepts the invitation.
+     * @TODO: probably want to cache this in the session since we will typically
+     *        need to do this twice: once when adding the resource to the
+     *        attendees form, and once when actually saving the event.
+     *
+     * @var Kronolith_Resource_Single
+     */
+    private $_selectedResource;
+
+    /**
+     * Const'r
+     *
+     * @param $params
+     *
+     * @return Kronolith_Resource
+     */
+    public function __construct($params)
+    {
+        parent::__construct($params);
+        $this->_driver = $this->getDriver();
+    }
+
+    /**
+     * Override the get method to see if we have a selected resource. If so,
+     * return the resource's property value, otherwise, return the group's
+     * property value.
+     *
+     * @param string $property  The property to get.
+     *
+     * @return mixed  The requested property's value.
+     */
+    public function get($property)
+    {
+        if (empty($this->_selectedResource)) {
+            return parent::get($property);
+        } else {
+            return $this->_selectedResoruce->get($property);
+        }
+    }
+
+    /**
+     * Determine if the resource is free during the time period for the
+     * supplied event.
+     *
+     * @param mixed $event  Either a Kronolith_Event object or an array
+     *                      containing start and end times.
+     *
+     *
+     * @return boolean
+     */
+    public function isFree($event)
+    {
+        if (is_array($event)) {
+            $start = $event['start'];
+            $end = $event['end'];
+        } else {
+            $start = $event->start;
+            $end = $event->end;
+        }
+
+        /* Get all resources that are included in this category */
+        $resources = unserialize($this->get('members'));
+
+        /* Iterate over all resources until one with no conflicts is found */
+        $conflict = false;
+        foreach ($resources as $resource_id) {
+            $resource = $this->_driver->getResource($resource_id);
+            $busy = Kronolith::listEvents($start, $end, array($resource->get('calendar')));
+            if ($busy instanceof PEAR_Error) {
+                throw new Horde_Exception($busy->getMessage());
+            }
+
+            /* No events at all during time period for requested event */
+            if (!count($busy)) {
+                $this->_selectedResource = $resource;
+                return true;
+            }
+
+            /* Check for conflicts, ignoring the conflict if it's for the
+             * same event that is passed. */
+            if (!is_array($event)) {
+                $uid = $event->getUID();
+            } else {
+                $uid = 0;
+            }
+
+            foreach ($busy as $events) {
+                foreach ($events as $e) {
+                    if (!($e->hasStatus(Kronolith::STATUS_CANCELLED) ||
+                          $e->hasStatus(Kronolith::STATUS_FREE)) &&
+                         $e->getUID() !== $uid) {
+
+                         if (!($e->start->compareDateTime($end) >= 1 ||
+                             $e->end->compareDateTime($start) <= -1)) {
+
+                            // Not free, continue to the next resource
+                            $conflict = true;
+                            break;
+                         }
+                    }
+                }
+            }
+
+            if (!$conflict) {
+                /* No conflict detected for this resource */
+                $this->_selectedResource = $resource;
+                return true;
+            }
+        }
+
+        /* No resource found without conflicts */
+        return false;
+    }
+
+    /**
+     * Adds $event to an available member resource's calendar.
+     *
+     * @param $event
+     *
+     * @return void
+     */
+    public function addEvent($event)
+    {
+        if (empty($this->_selectedResource)) {
+            $this->isFree($event);
+        }
+//        /* Make sure it's not already attached. */
+//        $uid = $event->getUID();
+//        $existing = $driver->getByUID($uid, array($this->get('calendar')));
+//        if (!($existing instanceof PEAR_Error)) {
+//            /* Already attached, just update */
+//            $existing->fromiCalendar($event->toiCalendar(new Horde_iCalendar('2.0')));
+//            $existing->status = $event->status;
+//            $existing->save();
+//        } else {
+//            /* Create a new event */
+//            $e = $driver->getEvent();
+//            $e->setCalendar($this->get('calendar'));
+//            $e->fromiCalendar($event->toiCalendar(new Horde_iCalendar('2.0')));
+//            $e->save();
+//        }
+    }
+
+    /**
+     * Remove this event from resource's calendar
+     *
+     * @param $event
+     * @return unknown_type
+     */
+    public function removeEvent($event)
+    {
+        throw new Horde_Exception('Unsupported');
+    }
+
+    /**
+     * Obtain the freebusy information for this resource.
+     *
+     * @return unknown_type
+     */
+    public function getFreeBusy($startstamp = null, $endstamp = null, $asObject = false)
+    {
+        throw new Horde_Exception('Unsupported');
+    }
+
+    public function setId($id)
+    {
+        throw new Horde_Exception('Unsupported');
+    }
+
+    /**
+     * Group resources only make sense for RESPONSETYPE_AUTO
+     *
+     * @see lib/Resource/Kronolith_Resource_Base#getResponseType()
+     */
+    public function getResponseType()
+    {
+        return Kronolith_Resource::RESPONSETYPE_AUTO;
+    }
+
+}
\ No newline at end of file
index c9a7070..a83cfcb 100644 (file)
@@ -7,6 +7,8 @@ CREATE TABLE kronolith_resources (
     resource_description TEXT,
     resource_category VARCHAR(255) DEFAULT '',
     resource_response_type INT DEFAULT 0,
+    resource_type VARCHAR(255) NOT NULL,
+    resource_members BLOB,
     
     PRIMARY KEY (resource_id)
 );