// Need to load Horde_Util:: to give us access to Horde_Util::getPathInfo().
require_once dirname(__FILE__) . '/lib/Application.php';
-$action = basename(Horde_Util::getPathInfo());
+$action = Horde_Util::getFormData('action');
+
if (empty($action)) {
// This is the only case where we really don't return anything, since
// the frontend can be presumed not to make this request on purpose.
}
try {
- new Shout_Application();
+ $shout = new Shout_Application(array('init' => true));
} catch (Horde_Exception $e) {
/* Handle session timeouts when they come from an AJAX request. */
if (($e->getCode() == Horde_Registry::AUTH_FAILURE) &&
Horde_Auth::authenticateFailure('shout', $e);
}
+$context = $_SESSION['shout']['context'];
+
+switch($action) {
+case 'addDestination':
+ try {
+ // FIXME: Use Form?
+ $exten = Horde_Util::getFormData('extension');
+ $type = Horde_Util::getFormData('type');
+ $dest = Horde_Util::getFormData('destination');
+ $shout->extensions->addDestination($context, $exten, $type, $dest);
+
+ $extensions = $shout->extensions->getExtensions($context);
+ Horde::sendHTTPResponse(Horde::prepareResponse($extensions), 'json');
+ } catch (Exception $e) {
+ Horde::logMessage($e->getMessage(), __FILE__, __LINE__, PEAR_LOG_ERR);
+ //FIXME: Create a way to notify the user of the failure.
+ }
+
+ break;
+
+case 'deleteDestination':
+ try {
+ // FIXME: Use Form?
+ $exten = Horde_Util::getFormData('extension');
+ $type = Horde_Util::getFormData('type');
+ $dest = Horde_Util::getFormData('destination');
+ $shout->extensions->deleteDestination($context, $exten, $type, $dest);
+
+ $extensions = $shout->extensions->getExtensions($context);
+ Horde::sendHTTPResponse(Horde::prepareResponse($extensions), 'json');
+ } catch (Exception $e) {
+ Horde::logMessage($e->getMessage(), __FILE__, __LINE__, PEAR_LOG_ERR);
+ //FIXME: Create a way to notify the user of the failure.
+ }
+ break;
+
+case 'getDestinations':
+ try {
+ $extensions = $shout->extensions->getExtensions($context);
+ Horde::sendHTTPResponse(Horde::prepareResponse($extensions), 'json');
+ } catch (Exception $e) {
+ Horde::logMessage($e->getMessage(), __FILE__, __LINE__, PEAR_LOG_ERR);
+ //FIXME: Create a way to notify the user of the failure.
+ }
+ break;
+}
}
/**
+ * Add a new destination valid for this extension.
+ * A destination is either a telephone number or a VoIP device.
+ *
+ * @param string $context Context for the extension
+ * @param string $extension Extension for which to return destinations
+ * @param string $type Destination type ("device" or "number")
+ * @param string $destination The destination itself
+ *
+ * @return boolean True on success.
+ */
+ function addDestination($context, $extension, $type, $destination)
+ {
+ // FIXME: Permissions check
+ $dn = $this->_getExtensionDn($context, $extension);
+ $attr = $this->_getDestAttr($type, $destination);
+
+ $res = ldap_mod_add($this->_LDAP, $dn, $attr);
+ if ($res === false) {
+ $msg = sprintf('Error while modifying the LDAP entry. 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 modifing the directory. Details have been logged for the administrator."));
+ }
+
+ return true;
+ }
+
+ /**
* 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).
+ * A destination is either a telephone number or a VoIP device.
*
* @param string $context Context for the extension
* @param string $extension Extension for which to return destinations
'devices' => $res['astextensions']);
}
+ function deleteDestination($context, $extension, $type, $destination)
+ {
+ $dn = $this->_getExtensionDn($context, $extension);
+ $attr = $this->_getDestAttr($type, $destination);
+
+ $res = ldap_mod_del($this->_LDAP, $dn, $attr);
+ if ($res === false) {
+ $msg = sprintf('Error while modifying the LDAP entry. 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 modifing the directory. Details have been logged for the administrator."));
+ }
+
+ return true;
+ }
+
+ protected function _getDestAttr($type, $destination)
+ {
+ switch ($type) {
+ case 'number':
+ // FIXME: Strip this number down to just digits
+ // FIXME: Add check for non-international numbers?
+ $attr = array('telephoneNumber' => $destination);
+ break;
+
+ case 'device':
+ // FIXME: Check that the device is valid and associated with this
+ // context.
+ $attr = array('AstExtension' => $destination);
+ break;
+
+ default:
+ throw new Shout_Exception(_("Invalid destination type specified."));
+ break;
+ }
+
+ return $attr;
+ }
+
/**
* Save an extension to the LDAP tree
*
var destinations = new Array();
-function resetDestInfo(exten)
+function resetDestInfo(collapse)
{
+ destinations.each(function(item) {
+ exten = item.key;
+ _resetExtenDest(exten);
+ if (collapse) {
+ contract(exten);
+ }
+ });
+}
+
+function _resetExtenDest(exten)
+{
+
while ((e = $('destX'+exten+'info').childNodes[0]) != null) {
$('destX'+exten+'info').removeChild(e);
}
}
dest['devices'].each(function(s) {
- e = document.createElement('img');
- e.src = "<?php echo $registry->getImageDir() . '/shout.png'; ?>";
- t = document.createTextNode(" "+s);
- b = document.createElement('br');
- $('destX'+exten+'info').appendChild(e);
- $('destX'+exten+'info').appendChild(t);
- $('destX'+exten+'info').appendChild(b);
+ img = document.createElement('img');
+ img.src = "<?php echo $registry->getImageDir() . '/shout.png'; ?>";
+ text = document.createTextNode(" "+s+" ");
+ del = document.createElement('img');
+ del.src = "<?php echo $registry->getImageDir('horde') . '/delete-small.png'; ?>"
+ del.style.cursor = 'pointer';
+ del.setAttribute('onclick', 'delDest("'+exten+'", "device", "'+s+'")');
+ br = document.createElement('br');
+ $('destX'+exten+'info').appendChild(img);
+ $('destX'+exten+'info').appendChild(text);
+ $('destX'+exten+'info').appendChild(del);
+ $('destX'+exten+'info').appendChild(br);
});
dest['numbers'].each(function(s) {
- e = document.createElement('img');
- e.src = "<?php echo $registry->getImageDir() . '/telephone-pole.png'; ?>";
- t = document.createTextNode(" "+s);
- b = document.createElement('br');
- $('destX'+exten+'info').appendChild(e);
- $('destX'+exten+'info').appendChild(t);
- $('destX'+exten+'info').appendChild(b);
+ img = document.createElement('img');
+ img.src = "<?php echo $registry->getImageDir() . '/telephone-pole.png'; ?>";
+ text = document.createTextNode(" "+s+" ");
+ del = document.createElement('img');
+ del.src = "<?php echo $registry->getImageDir('horde') . '/delete-small.png'; ?>"
+ del.style.cursor = 'pointer';
+ del.setAttribute('onclick', 'delDest("'+exten+'", "number", "'+s+'")');
+ br = document.createElement('br');
+ $('destX'+exten+'info').appendChild(img);
+ $('destX'+exten+'info').appendChild(text);
+ $('destX'+exten+'info').appendChild(del);
+ $('destX'+exten+'info').appendChild(br);
});
form = document.createElement('form');
function processForm(event)
{
Event.stop(event);
- spinner = document.createElement('img');
- spinner.src = "<?php echo $registry->getImageDir('horde') . '/loading.gif'; ?>"
form = event.target;
Element.extend(form);
exten = form.getInputs('hidden', 'extension').first().value;
- resetDestInfo(exten);
+ spinner = document.createElement('img');
+ spinner.src = "<?php echo $registry->getImageDir('horde') . '/loading.gif'; ?>"
- $('destX'+exten+'addDest').show();
+ $('destX'+exten+'submit').hide();
+ form.insertBefore(spinner, $('destX'+exten+'submit'))
+ // FIXME: Better error handling
+ new Ajax.Request('<?php echo Horde::applicationUrl('ajax.php'); ?>',
+ {
+ method: 'post',
+ parameters: form.serialize(true),
+ onSuccess: function(r) {
+ //alert(json ? Object.inspect(json) : "no JSON object")
+ destinations = $H(r.responseJSON.response);
+ resetDestInfo();
+ },
+ onFailure: function(){ alert('Something went wrong...') }
+ });
}
function addDest(exten)
{
+ // Hide the link to create the form below.
+ // We only want one active at a time.
$('destX'+exten+'addDest').hide();
+
+ hidden = document.createElement('input');
+ hidden.type = 'hidden';
+ hidden.name = 'action';
+ hidden.value = 'addDestination';
+
select = document.createElement('select');
select.name = 'type';
option = document.createElement('option');
- option.name = 'number';
+ option.value = 'number';
text = document.createTextNode("<?php echo _("Number"); ?>");
option.appendChild(text);
select.appendChild(option);
option = document.createElement('option');
- option.name = 'device';
+ option.value = 'device';
text = document.createTextNode("<?php echo _("Device"); ?>");
option.appendChild(text);
select.appendChild(option);
input = document.createElement('input');
input.name = 'destination';
- input.id = 'destination';
input.type = "text";
input.size = 12;
input.maxlength = 15;
save = document.createElement("input");
- save.name = "action";
+ save.name = "submit";
save.value = "Save";
save.type = "submit";
+ save.id = 'destX'+exten+'submit';
br = document.createElement('br');
+ $('destX'+exten+'form').appendChild(hidden);
$('destX'+exten+'form').appendChild(select);
$('destX'+exten+'form').appendChild(input);
$('destX'+exten+'form').appendChild(save);
Event.observe($('destX'+exten+'form'), 'submit', function(event) {processForm(event);});
}
-destinations = $H({
-<?php
-foreach ($extensions as $extension => $info)
+function delDest(exten, type, dest)
{
- echo "'${extension}': {\n";
- if (count($info['devices'])) {
- echo ' \'devices\': ["' . implode('","', $info['devices']) . '"],';
- }
- if (count($info['numbers'])) {
- echo ' \'numbers\': ["' . implode('","', $info['numbers']) . '"],';
- }
- echo "},\n";
+ params = $H({
+ 'extension': exten,
+ 'type': type,
+ 'destination': dest,
+ 'action': 'deleteDestination'
+ });
+
+ // FIXME: Better error handling
+ new Ajax.Request('<?php echo Horde::applicationUrl('ajax.php'); ?>',
+ {
+ method: 'post',
+ parameters: params,
+ onSuccess: function(r) {
+ //alert(json ? Object.inspect(json) : "no JSON object")
+ destinations = $H(r.responseJSON.response);
+ resetDestInfo();
+ },
+ onFailure: function(){ alert('Something went wrong...') }
+ });
}
-?>
-});
-// Initialize the data.
-destinations.each(function(item) {
- exten = item.key;
- resetDestInfo(exten);
- contract(exten);
-})
+destinations = $H();
+
+new Ajax.Request('<?php echo Horde::applicationUrl('ajax.php'); ?>',
+{
+ method: 'post',
+ parameters: $H({'action': 'getDestinations'}),
+ onSuccess: function(r) {
+ destinations = $H(r.responseJSON.response);
+ resetDestInfo(true);
+ }
+});
// -->
</script>