From 59e38c2919836e5d4d8fcd080015a6a28690e0c6 Mon Sep 17 00:00:00 2001 From: Ben Klang Date: Wed, 23 Dec 2009 20:36:58 +0000 Subject: [PATCH] Add initial support for adding/listing/editing devices. Various fixes within the Sql and Ldap drivers. git-svn-id: https://svn.alkaloid.net/gpl/shout/trunk@504 06cd67b6-e706-0410-b29e-9de616bca6e9 --- devices.php | 77 +++++++++++++++++++++++++++++++++++++++++++++ extensions.php | 57 +++++++++++---------------------- lib/Driver.php | 4 +-- lib/Driver/Ldap.php | 67 +++++++++++++++++++-------------------- lib/Driver/Sql.php | 37 ++++++++++++++-------- lib/Forms/DeviceForm.php | 39 +++++++++++++++++++++++ lib/Forms/ExtensionForm.php | 3 +- lib/Shout.php | 1 + templates/devices/edit.inc | 6 ++++ templates/devices/list.inc | 40 +++++++++++++++++++++++ 10 files changed, 241 insertions(+), 90 deletions(-) create mode 100644 devices.php create mode 100644 lib/Forms/DeviceForm.php create mode 100644 templates/devices/edit.inc create mode 100644 templates/devices/list.inc diff --git a/devices.php b/devices.php new file mode 100644 index 000000000..a34aa620a --- /dev/null +++ b/devices.php @@ -0,0 +1,77 @@ + + * + * See the enclosed file COPYING for license information (GPL). If you + * did not receive this file, see http://www.fsf.org/copyleft/gpl.html. + */ +@define('SHOUT_BASE', dirname(__FILE__)); +require_once SHOUT_BASE . '/lib/base.php'; +require_once SHOUT_BASE . '/lib/Forms/DeviceForm.php'; + +$action = Horde_Util::getFormData('action'); +$devices = $shout_devices->getDevices($context); +$devid = Horde_Util::getFormData('devid'); +$vars = Horde_Variables::getDefaultVariables(); + +//$tabs = Shout::getTabs($context, $vars); + +$RENDERER = new Horde_Form_Renderer(); + +$section = 'devices'; +$title = _("Devices: "); + +switch ($action) { + case 'save': + print_r($vars); + $Form = new DeviceDetailsForm($vars); + print_r($Form); + // Show the list if the save was successful, otherwise back to edit. + $success = ($Form->isSubmitted() && $Form->isValid()); + if ($success) { + $notification->push(_("Device settings saved.")); + $action = 'list'; + break; + } else { + $action = 'edit'; + } + case 'add': + case 'edit': + if ($action == 'add') { + $title .= _("New Device"); + // Treat adds just like an empty edit + $action = 'edit'; + } else { + $title .= sprintf(_("Edit Device %s"), $extension); + + } + + $FormName = 'DeviceDetailsForm'; + $vars = new Horde_Variables($devices[$devid]); + $Form = new DeviceDetailsForm($vars); + + $Form->open($RENDERER, $vars, Horde::applicationUrl('devices.php'), 'post'); + + break; + + + case 'delete': + $notification->push("Not supported."); + break; + + case 'list': + default: + $action = 'list'; + $title .= _("List Users"); +} + +require SHOUT_TEMPLATES . '/common-header.inc'; +require SHOUT_TEMPLATES . '/menu.inc'; + +$notification->notify(); + +//echo $tabs->render($section); + +require SHOUT_TEMPLATES . '/devices/' . $action . '.inc'; + +require $registry->get('templates', 'horde') . '/common-footer.inc'; \ No newline at end of file diff --git a/extensions.php b/extensions.php index b1dd05de0..29f3a8247 100644 --- a/extensions.php +++ b/extensions.php @@ -27,22 +27,21 @@ $title = _("Extensions: "); switch ($action) { case 'add': - $title .= _("Add Extension"); - - # Treat adds just like an empty edit - $action = 'edit'; - case 'edit': - $title .= sprintf(_("Edit Extension %s"), $extension); + if ($action == 'add') { + $title .= _("New Extension"); + // Treat adds just like an empty edit + $action = 'edit'; + } else { + $title .= sprintf(_("Edit Extension %s"), $extension); + + } $FormName = 'UserDetailsForm'; $vars = new Horde_Variables($extensions[$extension]); $Form = &Horde_Form::singleton($FormName, $vars); - $Form->open($RENDERER, $vars, 'index.php', 'post'); - $Form->preserveVarByPost($vars, 'extension'); - $Form->preserveVarByPost($vars, 'context'); - $Form->preserveVarByPost($vars, 'section'); + $Form->open($RENDERER, $vars, Horde::applicationUrl('extensions.php'), 'post'); break; case 'save': @@ -54,46 +53,28 @@ switch ($action) { $FormValid = $Form->validate($vars, true); if (!$FormValid || !$Form->isSubmitted()) { - require SHOUT_BASE . '/usermgr/edit.php'; + $notification->push("FIXME: Redirect to re-edit"); } else { - # Form is Valid and Submitted + // Form is Valid and Submitted $extension = $vars->get('extension'); - $limits = $shout->getLimits($context, $extension); - # FIXME: Input Validation (Text::??) - $userdetails = array( + $details = array( "newextension" => $vars->get('newextension'), "name" => $vars->get('name'), "mailboxpin" => $vars->get('mailboxpin'), "email" => $vars->get('email'), - "uid" => $vars->get('uid'), ); - $userdetails['telephonenumber'] = array(); - $telephonenumber = $vars->get("telephonenumber"); - if (!empty($telephonenumber) && is_array($telephonenumber)) { - $i = 1; - while ($i <= $limits['telephonenumbersmax']) { - if (!empty($telephonenumber[$i])) { - $userdetails['telephonenumber'][] = $telephonenumber[$i++]; - } else { - $i++; - } - } + try { + $res = $shout_extensions->saveUser($context, + $extension, $details); + } catch (Exception $e) { + $notification->push($e); } - - $userdetails['dialopts'] = array(); - - $res = $shout->saveUser($context, $extension, $userdetails); - if (is_a($res, 'PEAR_Error')) { - $notification->push($res); - } else { - $notification->push(_("User information updated."), + $notification->push(_("User information updated."), 'horde.success'); - } - - } + } break; case 'delete': diff --git a/lib/Driver.php b/lib/Driver.php index d5278e07c..421afd3e2 100644 --- a/lib/Driver.php +++ b/lib/Driver.php @@ -139,8 +139,8 @@ class Shout_Driver { if (is_null($params)) { if ($GLOBALS['conf'][$class]['params']['driverconfig'] == 'horde') { - $params = array_merge($GLOBALS['conf'][$class]['params'], - Horde::getDriverConfig('storage', $driver)); + $params = array_merge(Horde::getDriverConfig('storage', $driver), + $GLOBALS['conf'][$class]['params']); } else { $params = $GLOBALS['conf'][$class]['params']; } diff --git a/lib/Driver/Ldap.php b/lib/Driver/Ldap.php index c4324176e..36f6d87b3 100644 --- a/lib/Driver/Ldap.php +++ b/lib/Driver/Ldap.php @@ -148,52 +148,49 @@ class Shout_Driver_Ldap extends Shout_Driver } /** - * Get a context's properties + * Get a list of destinations valid for this extension. + * A destination is either a telephone number, a VoIP device or an + * Instant Messaging address (a special case of VoIP). * - * @param string $context Context to get properties for - * - * @return integer Bitfield of properties valid for this context + * @param string $context Context for the extension + * @param string $extension Extension for which to return destinations */ - public function getContextProperties($context) + function getDestinations($context, $extension) { + // FIXME: LDAP filter injection + $filter = '(&(AstContext=%s)(AstVoicemailMailbox=%s))'; + $filter = sprintf($filter, $context, $extension); - $res = @ldap_search($this->_LDAP, - SHOUT_ASTERISK_BRANCH.','.$this->_params['basedn'], - "(&(objectClass=asteriskObject)(context=$context))", - array('objectClass')); - if(!$res) { - return PEAR::raiseError(_("Unable to get properties for $context")); - } + $attrs = array('telephoneNumber', 'AstExtensions'); - $res = ldap_get_entries($this->_LDAP, $res); + $res = ldap_search($this->_LDAP, $this->_params['basedn'], + $filter, $attrs); - $properties = 0; - if ($res['count'] != 1) { - return PEAR::raiseError(_("Incorrect number of properties found -for $context")); + if ($res === false) { + $msg = sprintf('Error while searching LDAP. Code %s; Message "%s"', + ldap_errno($this->_LDAP), ldap_error($this->_LDAP)); + Horde::logMessage($msg, __FILE__, __LINE__, PEAR_LOG_ERR); + throw new Shout_Exception(_("Internal error searching the directory.")); } - foreach ($res[0]['objectclass'] as $objectClass) { - switch ($objectClass) { - case "vofficeCustomer": - # FIXME What does this objectClass really do for us? - $properties = $properties | SHOUT_CONTEXT_CUSTOMERS; - break; - - case "asteriskExtensions": - $properties = $properties | SHOUT_CONTEXT_EXTENSIONS; - break; + $res = ldap_get_entries($this->_LDAP, $res); - case "asteriskMusicOnHold": - $properties = $properties | SHOUT_CONTEXT_MOH; - break; + if ($res === false) { + $msg = sprintf('Error while searching LDAP. Code %s; Message "%s"', + ldap_errno($this->_LDAP), ldap_error($this->_LDAP)); + Horde::logMessage($msg, __FILE__, __LINE__, PEAR_LOG_ERR); + throw new Shout_Exception(_("Internal error searching the directory.")); + } - case "asteriskMeetMe": - $properties = $properties | SHOUT_CONTEXT_CONFERENCE; - break; - } + if ($res['count'] != 1) { + $msg = sprintf('Error while searching LDAP. Code %s; Message "%s"', + ldap_errno($this->_LDAP), ldap_error($this->_LDAP)); + Horde::logMessage($msg, __FILE__, __LINE__, PEAR_LOG_ERR); + throw new Shout_Exception(_("Wrong number of entries found for this search.")); } - return $properties; + + return array('numbers' => $res['telephonenumbers'], + 'devices' => $res['astextensions']); } /** diff --git a/lib/Driver/Sql.php b/lib/Driver/Sql.php index 12166ac18..3e3430836 100644 --- a/lib/Driver/Sql.php +++ b/lib/Driver/Sql.php @@ -61,41 +61,52 @@ class Shout_Driver_Sql extends Shout_Driver /** * Get a list of devices for a given context * - * @param string $context Context in which to search for devices - * @param string $extension Extension in which to search for devices + * @param string $context Context in which to search for devicess * * @return array Array of devices within this context with their information * * @access private */ - public function getDevices($context, $extension) + public function getDevices($context) { - $sql = 'SELECT id, name, callerid, context, host, permit, nat, ' . - 'secret, disallow, allow FROM %s WHERE mailbox = ?'; + $sql = 'SELECT id, name, alias, callerid, context, mailbox, host, permit, ' . + 'nat, secret, disallow, allow FROM %s WHERE accountcode = ?'; $sql = sprintf($sql, $this->_params['table']); - $args = array($extension . '@' . $context); - + $args = array($context); $result = $this->_db->query($sql, $args); - if (is_a($result instanceof PEAR_Error)) { - throw Shout_Exception($result); + if ($result instanceof PEAR_Error) { + throw new Shout_Exception($result); } $row = $result->fetchRow(DB_FETCHMODE_ASSOC); if ($row instanceof PEAR_Error) { - throw Shout_Exception($row); + throw new Shout_Exception($row); } $devices = array(); while ($row && !($row instanceof PEAR_Error)) { - /* Add this new foo to the $_foo list. */ - $devices[] = $row; + // Asterisk uses the "name" field to indicate the registration + // identifier. We use the field "alias" to put a friendly name on + // the device. Thus devid -> name and name => alias + $devid = $row['name']; + $row['devid'] = $devid; + $row['name'] = $row['alias']; + unset($row['alias']); + + // Trim off the context from the mailbox number + list($row['mailbox']) = explode('@', $row['mailbox']); + + // Hide the DB internal ID from the front-end + unset($row['id']); + + $devices[$devid] = $row; /* Advance to the new row in the result set. */ $row = $result->fetchRow(DB_FETCHMODE_ASSOC); } $result->free(); - + return $devices; } /** diff --git a/lib/Forms/DeviceForm.php b/lib/Forms/DeviceForm.php new file mode 100644 index 000000000..04a75b164 --- /dev/null +++ b/lib/Forms/DeviceForm.php @@ -0,0 +1,39 @@ + + * + * See the enclosed file LICENSE for license information (GPL). If you + * did not receive this file, see http://www.horde.org/licenses/gpl.php. + * + * @package Shout + */ + +class DeviceDetailsForm extends Horde_Form { + + function __construct(&$vars) + { + parent::__construct($vars); + global $shout_extensions; + $context = $vars->get('context'); + if ($vars->exists('devid')) { + $formtitle = "Edit Device"; + $devid = $vars->get('devid'); + } else { + $formtitle = "Add Device"; + } + + parent::__construct($vars, _("$formtitle - Context: $context")); + $this->addHidden('', 'action', 'text', true); + $vars->set('action', 'save'); + $this->addHidden('', 'devid', 'int', true); + $this->addVariable(_("Device Name"), 'name', 'text', true); + $this->addVariable(_("Mailbox"), 'mailbox', 'int', true); + $this->addVariable(_("CallerID"), 'callerid', 'text', false); + + + return true; + } + +} \ No newline at end of file diff --git a/lib/Forms/ExtensionForm.php b/lib/Forms/ExtensionForm.php index 1fdf8f7e3..00a9bc7f9 100644 --- a/lib/Forms/ExtensionForm.php +++ b/lib/Forms/ExtensionForm.php @@ -10,10 +10,9 @@ * @package Shout */ -// {{{ class UserDetailsForm extends Horde_Form { - function UserDetailsForm(&$vars) + function __construct(&$vars) { global $shout_extensions; $context = $vars->get('context'); diff --git a/lib/Shout.php b/lib/Shout.php index 1ceae103d..8eed4aa8a 100644 --- a/lib/Shout.php +++ b/lib/Shout.php @@ -35,6 +35,7 @@ class Shout $menu = new Horde_Menu(HORDE_MENU_MASK_ALL); $menu->add(Horde::applicationUrl('extensions.php'), _("Extensions"), "user.png"); + $menu->add(Horde::applicationUrl('devices.php'), _("Devices"), "shout.png"); $menu->add(Horde::applicationUrl('routes.php'), _("Call Paths")); diff --git a/templates/devices/edit.inc b/templates/devices/edit.inc new file mode 100644 index 000000000..a95682f37 --- /dev/null +++ b/templates/devices/edit.inc @@ -0,0 +1,6 @@ +beginActive($Form->getTitle()); +$RENDERER->renderFormActive($Form, $vars); +$RENDERER->submit(); +$RENDERER->end(); +$Form->close($RENDERER); \ No newline at end of file diff --git a/templates/devices/list.inc b/templates/devices/list.inc new file mode 100644 index 000000000..49516c003 --- /dev/null +++ b/templates/devices/list.inc @@ -0,0 +1,40 @@ +
+ Context: +
+ +
+ + + + + + + $info) { + + $url = Horde::applicationUrl("devices.php"); + $url = Horde_Util::addParameter($url, + array( + 'devid' => $devid, + ) + ); + $editurl = Horde_Util::addParameter($url, 'action', 'edit'); + $deleteurl = Horde_Util::addParameter($url, 'action', 'delete'); + ?> + + + + + + +
Device IDMailboxCallerID
+ + + + + +
+
-- 2.11.0