Refactored resources directory to be an individual part and not dependant on a specific calendar backend driver
This commit is contained in:
parent
0b2e726857
commit
51fe7c26fb
9 changed files with 267 additions and 194 deletions
|
@ -38,6 +38,7 @@ class calendar extends rcube_plugin
|
|||
public $rc;
|
||||
public $lib;
|
||||
public $driver;
|
||||
public $resources_dir;
|
||||
public $home; // declare public to be used in other classes
|
||||
public $urlbase;
|
||||
public $timezone;
|
||||
|
@ -211,13 +212,7 @@ class calendar extends rcube_plugin
|
|||
require_once($this->home . '/drivers/calendar_driver.php');
|
||||
require_once($this->home . '/drivers/' . $driver_name . '/' . $driver_class . '.php');
|
||||
|
||||
switch ($driver_name) {
|
||||
case "kolab":
|
||||
$this->require_plugin('libkolab');
|
||||
default:
|
||||
$this->driver = new $driver_class($this);
|
||||
break;
|
||||
}
|
||||
|
||||
if ($this->driver->undelete)
|
||||
$this->driver->undelete = $this->rc->config->get('undo_timeout', 0) > 0;
|
||||
|
@ -297,7 +292,7 @@ class calendar extends rcube_plugin
|
|||
|
||||
$this->rc->output->set_env('timezone', $this->timezone->getName());
|
||||
$this->rc->output->set_env('calendar_driver', $this->rc->config->get('calendar_driver'), false);
|
||||
$this->rc->output->set_env('resources', (bool)$this->driver->resources);
|
||||
$this->rc->output->set_env('calendar_resources', (bool)$this->rc->config->get('calendar_resources_driver'));
|
||||
$this->rc->output->set_env('mscolors', $this->driver->get_color_values());
|
||||
$this->rc->output->set_env('identities-selector', $this->ui->identity_select(array('id' => 'edit-identities-list')));
|
||||
|
||||
|
@ -1936,6 +1931,30 @@ class calendar extends rcube_plugin
|
|||
|
||||
/**** Resource management functions ****/
|
||||
|
||||
/**
|
||||
* Getter for the configured implementation of the resource directory interface
|
||||
*/
|
||||
private function resources_directory()
|
||||
{
|
||||
if (is_object($this->resources_dir)) {
|
||||
return $this->resources_dir;
|
||||
}
|
||||
|
||||
if ($driver_name = $this->rc->config->get('calendar_resources_driver')) {
|
||||
$driver_class = 'resources_driver_' . $driver_name;
|
||||
|
||||
require_once($this->home . '/drivers/resources_driver.php');
|
||||
require_once($this->home . '/drivers/' . $driver_name . '/' . $driver_class . '.php');
|
||||
|
||||
$this->resources_dir = new $driver_class($this);
|
||||
}
|
||||
|
||||
return $this->resources_dir;
|
||||
}
|
||||
|
||||
/**
|
||||
* Handler for resoruce autocompletion requests
|
||||
*/
|
||||
public function resources_autocomplete()
|
||||
{
|
||||
$search = rcube_utils::get_input_value('_search', rcube_utils::INPUT_GPC, true);
|
||||
|
@ -1943,13 +1962,15 @@ class calendar extends rcube_plugin
|
|||
$maxnum = (int)$this->rc->config->get('autocomplete_max', 15);
|
||||
$results = array();
|
||||
|
||||
foreach ($this->driver->load_resources($search, $maxnum) as $rec) {
|
||||
if ($directory = $this->resources_directory()) {
|
||||
foreach ($directory->load_resources($search, $maxnum) as $rec) {
|
||||
$results[] = array(
|
||||
'name' => $rec['name'],
|
||||
'email' => $rec['email'],
|
||||
'type' => $rec['_type'],
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
$this->rc->output->command('ksearch_query_results', $results, $search, $sid);
|
||||
$this->rc->output->send();
|
||||
|
@ -1961,10 +1982,12 @@ class calendar extends rcube_plugin
|
|||
function resources_list()
|
||||
{
|
||||
$data = array();
|
||||
foreach ($this->driver->load_resources() as $rec) {
|
||||
$rec['dn'] = rcube_ldap::dn_decode($rec['ID']);
|
||||
|
||||
if ($directory = $this->resources_directory()) {
|
||||
foreach ($directory->load_resources() as $rec) {
|
||||
$data[] = $rec;
|
||||
}
|
||||
}
|
||||
|
||||
$this->rc->output->command('plugin.resource_data', $data);
|
||||
$this->rc->output->send();
|
||||
|
@ -1975,8 +1998,10 @@ class calendar extends rcube_plugin
|
|||
*/
|
||||
function resources_owner()
|
||||
{
|
||||
if ($directory = $this->resources_directory()) {
|
||||
$id = rcube_utils::get_input_value('_id', rcube_utils::INPUT_GPC);
|
||||
$data = $this->driver->get_resource_owner($id);
|
||||
$data = $directory->get_resource_owner($id);
|
||||
}
|
||||
|
||||
$this->rc->output->command('plugin.resource_owner', $data);
|
||||
$this->rc->output->send();
|
||||
|
|
|
@ -762,7 +762,7 @@ function rcube_calendar_ui(settings)
|
|||
|
||||
// show/hide tabs according to calendar's feature support
|
||||
$('#edit-tab-attendees')[(calendar.attendees?'show':'hide')]();
|
||||
$('#edit-tab-resources')[(calendar.resources?'show':'hide')]();
|
||||
$('#edit-tab-resources')[(rcmail.env.calendar_resources?'show':'hide')]();
|
||||
$('#edit-tab-attachments')[(calendar.attachments?'show':'hide')]();
|
||||
|
||||
// activate the first tab
|
||||
|
@ -1516,7 +1516,7 @@ function rcube_calendar_ui(settings)
|
|||
'<td class="confirmstate"><span class="' + String(data.status).toLowerCase() + '" title="' + Q(data.status || '') + '">' + Q(data.status || '') + '</span></td>' +
|
||||
'<td class="options">' + (organizer || readonly ? '' : dellink) + '</td>';
|
||||
|
||||
var table = calendar.resources && data.cutype == 'RESOURCE' ? resources_list : attendees_list;
|
||||
var table = rcmail.env.calendar_resources && data.cutype == 'RESOURCE' ? resources_list : attendees_list;
|
||||
var tr = $('<tr>')
|
||||
.addClass(String(data.role).toLowerCase())
|
||||
.html(html)
|
||||
|
@ -1706,12 +1706,12 @@ function rcube_calendar_ui(settings)
|
|||
|
||||
// assign parent-relations
|
||||
$.each(data, function(i, rec) {
|
||||
resources_data[rec.dn] = rec;
|
||||
resources_index.push(rec.dn);
|
||||
resources_data[rec.ID] = rec;
|
||||
resources_index.push(rec.ID);
|
||||
|
||||
if (rec.members) {
|
||||
$.each(rec.members, function(j, m){
|
||||
resources_data[m].parent_id = rec.dn;
|
||||
resources_data[m].parent_id = rec.ID;
|
||||
});
|
||||
}
|
||||
});
|
||||
|
@ -1730,10 +1730,10 @@ function rcube_calendar_ui(settings)
|
|||
$.each(index, function(i, dn) {
|
||||
if (rec = resources_data[dn]) {
|
||||
link = $('<a>').attr('href', '#')
|
||||
.attr('rel', rec.dn)
|
||||
.attr('rel', rec.ID)
|
||||
.html(Q(rec.name));
|
||||
|
||||
resources_treelist.insert({ id:rec.dn, html:link, classes:[rec._type], collapsed:true }, rec.parent_id, false);
|
||||
resources_treelist.insert({ id:rec.ID, html:link, classes:[rec._type], collapsed:true }, rec.parent_id, false);
|
||||
}
|
||||
});
|
||||
};
|
||||
|
@ -1772,7 +1772,7 @@ function rcube_calendar_ui(settings)
|
|||
for (var dn in resources_data) {
|
||||
rec = resources_data[dn];
|
||||
if (String(rec.name).toLowerCase().indexOf(q) >= 0) {
|
||||
dataset.push(rec.dn);
|
||||
dataset.push(rec.ID);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -135,4 +135,11 @@ $rcmail_config['calendar_itip_smtp_pass'] = '123456';
|
|||
// %i - Calendar UUID
|
||||
// $rcmail_config['calendar_caldav_url'] = 'http://%h/iRony/calendars/%u/%i';
|
||||
|
||||
// Driver to provide a resource directory ('ldap' is the only implementation yet).
|
||||
// Leave empty or commented to disable resources support.
|
||||
// $rcmail_config['calendar_resources_driver'] = 'ldap';
|
||||
|
||||
// LDAP directory configuration to find avilable resources for events
|
||||
// $rcmail_config['calendar_resources_directory'] = array(/* ldap_public-like address book configuration */)
|
||||
|
||||
?>
|
||||
|
|
|
@ -86,7 +86,6 @@ abstract class calendar_driver
|
|||
// features supported by backend
|
||||
public $alarms = false;
|
||||
public $attendees = false;
|
||||
public $resources = false;
|
||||
public $freebusy = false;
|
||||
public $attachments = false;
|
||||
public $undelete = false; // event undelete action
|
||||
|
@ -530,54 +529,4 @@ abstract class calendar_driver
|
|||
return $events;
|
||||
}
|
||||
|
||||
/**
|
||||
* Store alarm dismissal for birtual birthay events
|
||||
*
|
||||
* @param string Event identifier
|
||||
* @param integer Suspend the alarm for this number of seconds
|
||||
*/
|
||||
public function dismiss_birthday_alarm($event_id, $snooze = 0)
|
||||
{
|
||||
$rcmail = rcmail::get_instance();
|
||||
$cache = $rcmail->get_cache('calendar.birthdayalarms', 'db', 86400 * 30);
|
||||
$cache->remove($event_id);
|
||||
|
||||
// compute new notification time or disable if not snoozed
|
||||
$notifyat = $snooze > 0 ? time() + $snooze : null;
|
||||
$cache->set($event_id, array('snooze' => $snooze, 'notifyat' => $notifyat));
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Fetch resource objects to be displayed for booking
|
||||
*
|
||||
* @param string Search query (optional)
|
||||
* @return array List of resource records available for booking
|
||||
*/
|
||||
public function load_resources($query = null)
|
||||
{
|
||||
return array();
|
||||
}
|
||||
|
||||
/**
|
||||
* Return properties of a single resource
|
||||
*
|
||||
* @param mixed UID string
|
||||
* @return array Resource object as hash array
|
||||
*/
|
||||
public function get_resource($uid)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
public function get_resource_owner($id)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -47,6 +47,8 @@ class kolab_driver extends calendar_driver
|
|||
*/
|
||||
public function __construct($cal)
|
||||
{
|
||||
$cal->require_plugin('libkolab');
|
||||
|
||||
$this->cal = $cal;
|
||||
$this->rc = $cal->rc;
|
||||
$this->_read_calendars();
|
||||
|
@ -60,10 +62,6 @@ class kolab_driver extends calendar_driver
|
|||
$this->alarm_types = array('DISPLAY');
|
||||
$this->alarm_absolute = false;
|
||||
}
|
||||
|
||||
if ($this->rc->config->get('calendar_resources_directory')) {
|
||||
$this->resources = true;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
@ -1287,105 +1285,4 @@ class kolab_driver extends calendar_driver
|
|||
'FFDEAD');
|
||||
}
|
||||
|
||||
|
||||
private function resurces_ldap()
|
||||
{
|
||||
if (!isset($this->resources_dir)) {
|
||||
$this->resources_dir = new rcube_ldap($this->rc->config->get('calendar_resources_directory'), true);
|
||||
}
|
||||
|
||||
return $this->resources_dir->ready ? $this->resources_dir : null;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Fetch resource objects to be displayed for booking
|
||||
*
|
||||
* @param string Search query (optional)
|
||||
* @return array List of resource records available for booking
|
||||
*/
|
||||
public function load_resources($query = null, $num = 5000)
|
||||
{
|
||||
if (!($ldap = $this->resurces_ldap())) {
|
||||
return array();
|
||||
}
|
||||
|
||||
// TODO: apply paging
|
||||
$ldap->set_pagesize($num);
|
||||
|
||||
if (isset($query)) {
|
||||
$results = $ldap->search('*', $query, 0, true, true);
|
||||
}
|
||||
else {
|
||||
$results = $ldap->list_records();
|
||||
}
|
||||
|
||||
if ($results instanceof ArrayAccess) {
|
||||
foreach ($results as $i => $rec) {
|
||||
$results[$i] = $this->decode_resource($rec);
|
||||
}
|
||||
}
|
||||
|
||||
return $results;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return properties of a single resource
|
||||
*
|
||||
* @param mixed UID string
|
||||
* @return array Resource object as hash array
|
||||
*/
|
||||
public function get_resource($uid)
|
||||
{
|
||||
$rec = null;
|
||||
|
||||
if ($ldap = $this->resurces_ldap()) {
|
||||
$rec = $ldap->get_record($uid);
|
||||
|
||||
if (!empty($rec)) {
|
||||
$rec = $this->decode_resource($rec);
|
||||
}
|
||||
}
|
||||
|
||||
return $rec;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
public function get_resource_owner($dn)
|
||||
{
|
||||
$owner = null;
|
||||
|
||||
if ($ldap = $this->resurces_ldap()) {
|
||||
$owner = $ldap->get_record(rcube_ldap::dn_encode($dn), true);
|
||||
$owner['ID'] = rcube_ldap::dn_decode($owner['ID']);
|
||||
unset($owner['_raw_attrib'], $owner['_type']);
|
||||
}
|
||||
|
||||
return $owner;
|
||||
}
|
||||
|
||||
/**
|
||||
* Extract JSON-serialized attributes
|
||||
*/
|
||||
private function decode_resource($rec)
|
||||
{
|
||||
if (is_array($rec['attributes']) && $rec['attributes'][0]) {
|
||||
$attributes = array();
|
||||
|
||||
foreach ($rec['attributes'] as $sattr) {
|
||||
$attr = @json_decode($sattr, true);
|
||||
$attributes += $attr;
|
||||
}
|
||||
|
||||
$rec['attributes'] = $attributes;
|
||||
}
|
||||
|
||||
// remove unused cruft
|
||||
unset($rec['_raw_attrib']);
|
||||
|
||||
return $rec;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
146
plugins/calendar/drivers/ldap/resources_driver_ldap.php
Normal file
146
plugins/calendar/drivers/ldap/resources_driver_ldap.php
Normal file
|
@ -0,0 +1,146 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
* LDAP-based resource directory class using rcube_ldap functionality
|
||||
*
|
||||
* @author Thomas Bruederli <bruederli@kolabsys.com>
|
||||
*
|
||||
* Copyright (C) 2014, Kolab Systems AG <contact@kolabsys.com>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as
|
||||
* published by the Free Software Foundation, either version 3 of the
|
||||
* License, or (at your option) any later version.
|
||||
*
|
||||
* This program 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 Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
/**
|
||||
* LDAP-based resource directory implementation
|
||||
*/
|
||||
class resources_driver_ldap extends resources_driver
|
||||
{
|
||||
private $rc;
|
||||
private $cal;
|
||||
private $ldap;
|
||||
|
||||
/**
|
||||
* Default constructor
|
||||
*/
|
||||
function __construct($cal)
|
||||
{
|
||||
$this->cal = $cal;
|
||||
$this->rc = $cal->rc;
|
||||
}
|
||||
|
||||
/**
|
||||
* Fetch resource objects to be displayed for booking
|
||||
*
|
||||
* @param string Search query (optional)
|
||||
* @return array List of resource records available for booking
|
||||
*/
|
||||
public function load_resources($query = null, $num = 5000)
|
||||
{
|
||||
if (!($ldap = $this->connect())) {
|
||||
return array();
|
||||
}
|
||||
|
||||
// TODO: apply paging
|
||||
$ldap->set_pagesize($num);
|
||||
|
||||
if (isset($query)) {
|
||||
$results = $ldap->search('*', $query, 0, true, true);
|
||||
}
|
||||
else {
|
||||
$results = $ldap->list_records();
|
||||
}
|
||||
|
||||
if ($results instanceof ArrayAccess) {
|
||||
foreach ($results as $i => $rec) {
|
||||
$results[$i] = $this->decode_resource($rec);
|
||||
}
|
||||
}
|
||||
|
||||
return $results;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return properties of a single resource
|
||||
*
|
||||
* @param string Unique resource identifier
|
||||
* @return array Resource object as hash array
|
||||
*/
|
||||
public function get_resource($dn)
|
||||
{
|
||||
$rec = null;
|
||||
|
||||
if ($ldap = $this->connect()) {
|
||||
$rec = $ldap->get_record(rcube_ldap::dn_encode($dn));
|
||||
|
||||
if (!empty($rec)) {
|
||||
$rec = $this->decode_resource($rec);
|
||||
}
|
||||
}
|
||||
|
||||
return $rec;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return properties of a resource owner
|
||||
*
|
||||
* @param string Owner identifier
|
||||
* @return array Resource object as hash array
|
||||
*/
|
||||
public function get_resource_owner($dn)
|
||||
{
|
||||
$owner = null;
|
||||
|
||||
if ($ldap = $this->connect()) {
|
||||
$owner = $ldap->get_record(rcube_ldap::dn_encode($dn), true);
|
||||
$owner['ID'] = rcube_ldap::dn_decode($owner['ID']);
|
||||
unset($owner['_raw_attrib'], $owner['_type']);
|
||||
}
|
||||
|
||||
return $owner;
|
||||
}
|
||||
|
||||
/**
|
||||
* Extract JSON-serialized attributes
|
||||
*/
|
||||
private function decode_resource($rec)
|
||||
{
|
||||
$rec['ID'] = rcube_ldap::dn_decode($rec['ID']);
|
||||
|
||||
if (is_array($rec['attributes']) && $rec['attributes'][0]) {
|
||||
$attributes = array();
|
||||
|
||||
foreach ($rec['attributes'] as $sattr) {
|
||||
$attr = @json_decode($sattr, true);
|
||||
$attributes += $attr;
|
||||
}
|
||||
|
||||
$rec['attributes'] = $attributes;
|
||||
}
|
||||
|
||||
// remove unused cruft
|
||||
unset($rec['_raw_attrib']);
|
||||
|
||||
return $rec;
|
||||
}
|
||||
|
||||
private function connect()
|
||||
{
|
||||
if (!isset($this->ldap)) {
|
||||
$this->ldap = new rcube_ldap($this->rc->config->get('calendar_resources_directory'), true);
|
||||
}
|
||||
|
||||
return $this->ldap->ready ? $this->ldap : null;
|
||||
}
|
||||
|
||||
}
|
58
plugins/calendar/drivers/resources_driver.php
Normal file
58
plugins/calendar/drivers/resources_driver.php
Normal file
|
@ -0,0 +1,58 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
* Resources directory interface definition
|
||||
*
|
||||
* @author Thomas Bruederli <bruederli@kolabsys.com>
|
||||
*
|
||||
* Copyright (C) 2014, Kolab Systems AG <contact@kolabsys.com>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as
|
||||
* published by the Free Software Foundation, either version 3 of the
|
||||
* License, or (at your option) any later version.
|
||||
*
|
||||
* This program 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 Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
|
||||
/**
|
||||
* Interface definition for a resources directory driver classe
|
||||
*/
|
||||
abstract class resources_driver
|
||||
{
|
||||
|
||||
/**
|
||||
* Fetch resource objects to be displayed for booking
|
||||
*
|
||||
* @param string Search query (optional)
|
||||
* @return array List of resource records available for booking
|
||||
*/
|
||||
abstract public function load_resources($query = null);
|
||||
|
||||
/**
|
||||
* Return properties of a single resource
|
||||
*
|
||||
* @param string Unique resource identifier
|
||||
* @return array Resource object as hash array
|
||||
*/
|
||||
abstract public function get_resource($id);
|
||||
|
||||
/**
|
||||
* Return properties of a resource owner
|
||||
*
|
||||
* @param string Owner identifier
|
||||
* @return array Resource object as hash array
|
||||
*/
|
||||
public function get_resource_owner($id)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
}
|
|
@ -196,7 +196,6 @@ class calendar_ui
|
|||
unset($prop['user_id']);
|
||||
$prop['alarms'] = $this->cal->driver->alarms;
|
||||
$prop['attendees'] = $this->cal->driver->attendees;
|
||||
$prop['resources'] = $this->cal->driver->resources;
|
||||
$prop['freebusy'] = $this->cal->driver->freebusy;
|
||||
$prop['attachments'] = $this->cal->driver->attachments;
|
||||
$prop['undelete'] = $this->cal->driver->undelete;
|
||||
|
|
|
@ -126,14 +126,6 @@
|
|||
<div class="scroller">
|
||||
<roundcube:object name="plugin.resources_list" id="resources-list" class="listing treelist" />
|
||||
</div>
|
||||
<!--
|
||||
<div class="boxpagenav">
|
||||
<roundcube:button command="firstpage" type="link" class="icon firstpage disabled" classAct="icon firstpage" title="firstpage" content="|&lt;" />
|
||||
<roundcube:button command="previouspage" type="link" class="icon prevpage disabled" classAct="icon prevpage" title="previouspage" content="&lt;" />
|
||||
<roundcube:button command="nextpage" type="link" class="icon nextpage disabled" classAct="icon nextpage" title="nextpage" content="&gt;" />
|
||||
<roundcube:button command="lastpage" type="link" class="icon lastpage disabled" classAct="icon lastpage" title="lastpage" content="&gt;|" />
|
||||
</div>
|
||||
-->
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue