From: Michael M Slusarz Date: Thu, 16 Jul 2009 19:22:28 +0000 (-0600) Subject: Move imple handling to Horde_Ajax_Imple::. X-Git-Url: https://git.internetallee.de/?a=commitdiff_plain;h=4f74564881be2e063e6ab0d5bac4a0c5cdd15f63;p=horde.git Move imple handling to Horde_Ajax_Imple::. --- diff --git a/imp/imple.php b/imp/imple.php deleted file mode 100644 index b1c37d7c0..000000000 --- a/imp/imple.php +++ /dev/null @@ -1,58 +0,0 @@ - - * @package IMP - */ - -// As of right now, imples don't need read/write session access. -$session_control = 'readonly'; -$session_timeout = 'none'; - -$authentication = 'horde'; -require_once dirname(__FILE__) . '/lib/base.php'; - -$viewmode = $_SESSION['imp']['view']; - -if (!($path = Horde_Util::getFormData('imple'))) { - if ($viewmode == 'dimp') { - Horde::sendHTTPResponse(new stdClass(), 'json'); - } - exit; -} - -if ($path[0] == '/') { - $path = substr($path, 1); -} - -$path = explode('/', $path); -$impleName = reset($path); - -if (!($imple = IMP_Imple::factory($impleName))) { - if ($viewmode == 'dimp') { - Horde::sendHTTPResponse(new stdClass(), 'json'); - } - exit; -} - -$args = array(); -foreach ($path as $pair) { - if (strpos($pair, '=') === false) { - $args[$pair] = true; - } else { - list($name, $val) = explode('=', $pair); - $args[$name] = $val; - } -} - -$result = $imple->handle($args); - -$ct = empty($_SERVER['Content-Type']) - ? (is_string($result) ? 'plain' : 'json') - : $_SERVER['Content-Type']; - -Horde::sendHTTPResponse($result, $ct); diff --git a/imp/lib/Ajax/Imple/ContactAutoCompleter.php b/imp/lib/Ajax/Imple/ContactAutoCompleter.php new file mode 100644 index 000000000..edadd241c --- /dev/null +++ b/imp/lib/Ajax/Imple/ContactAutoCompleter.php @@ -0,0 +1,133 @@ + + * @package IMP + */ +class IMP_Ajax_Imple_ContactAutoCompleter extends Horde_Ajax_Imple_Base +{ + /** + * The URL to use in attach(). + * + * @var string + */ + protected $_url; + + /** + * Has the address book been output to the browser? + * + * @var boolean + */ + static protected $_listOutput = false; + + /** + * Constructor. + * + * @param array $params Configuration parameters. + *
+     * 'triggerId' => TODO (optional)
+     * 'resultsId' => TODO (optional)
+     * 
+ */ + public function __construct($params) + { + if (empty($params['triggerId'])) { + $params['triggerId'] = $this->_randomid(); + } + if (empty($params['resultsId'])) { + $params['resultsId'] = $params['triggerId'] . '_results'; + } + + parent::__construct($params); + } + + /** + * Attach the object to a javascript event. + */ + public function attach() + { + Horde::addScriptFile('prototype.js', 'horde', true); + Horde::addScriptFile('effects.js', 'horde', true); + Horde::addScriptFile('autocomplete.js', 'horde', true); + + $params = array( + '"' . $this->_params['triggerId'] . '"', + '"' . $this->_params['resultsId'] . '"' + ); + + $js_params = array( + 'tokens: [",", ";"]', + 'indicator: "' . $this->_params['triggerId'] . '_loading_img"', + 'afterUpdateElement: function(f, t) { if (!f.value.endsWith(";")) { f.value += ","; } f.value += " "; }' + ); + $ac_browser = empty($GLOBALS['conf']['compose']['ac_browser']) ? 0 : $GLOBALS['conf']['compose']['ac_browser']; + + if ($ac_browser && !isset($_SESSION['imp']['cache']['ac_ajax'])) { + $success = $use_ajax = true; + $sparams = IMP_Compose::getAddressSearchParams(); + foreach ($sparams['fields'] as $val) { + array_map('strtolower', $val); + sort($val); + if ($val != array('email', 'name')) { + $success = false; + break; + } + } + if ($success) { + $addrlist = IMP_Compose::getAddressList(); + $use_ajax = count($addrlist) > $ac_browser; + } + $_SESSION['imp']['cache']['ac_ajax'] = $use_ajax; + } + + if (!$ac_browser || $_SESSION['imp']['cache']['ac_ajax']) { + $func = 'Ajax.Autocompleter'; + if (empty($this->_url)) { + $this->_url = $this->_getUrl('ContactAutoCompleter', 'imp', array('input' => $this->_params['triggerId'])); + } + $params[] = '"' . $this->_url . '"'; + + $js_params[] = 'minChars: ' . intval($GLOBALS['conf']['compose']['ac_threshold'] ? $GLOBALS['conf']['compose']['ac_threshold'] : 1); + } else { + if (!self::$_listOutput) { + if (!isset($addrlist)) { + $addrlist = IMP_Compose::getAddressList(); + } + IMP::addInlineScript('if (!IMP) { var IMP = {}; } IMP.ac_list = '. Horde_Serialize::serialize(array_map('htmlspecialchars', $addrlist), Horde_Serialize::JSON, Horde_Nls::getCharset())); + self::$_listOutput = true; + } + $func = 'Autocompleter.Local'; + $params[] = 'IMP.ac_list'; + $js_params[] = 'partialSearch: true'; + $js_params[] = 'fullSearch: true'; + } + + $params[] = '{' . implode(',', $js_params) . '}'; + IMP::addInlineScript('new ' . $func . '(' . implode(',', $params) . ')', 'dom'); + } + + /** + * Perform the address search. + * + * @param array $args Array with 1 key: 'input'. + * + * @return array The data to send to the autocompleter JS code. + */ + public function handle($args) + { + // Avoid errors if 'input' isn't set and short-circuit empty searches. + if (empty($args['input']) || + !($input = Horde_Util::getPost($args['input']))) { + return array(); + } + + return array_map('htmlspecialchars', IMP_Compose::expandAddresses($input)); + } + +} diff --git a/imp/lib/Ajax/Imple/SpellChecker.php b/imp/lib/Ajax/Imple/SpellChecker.php new file mode 100644 index 000000000..d0b1494c8 --- /dev/null +++ b/imp/lib/Ajax/Imple/SpellChecker.php @@ -0,0 +1,110 @@ + + * @package IMP + */ +class IMP_Ajax_Imple_SpellChecker extends Horde_Ajax_Imple_Base +{ + /** + * Constructor. + * + * @param array $params Configuration parameters. + *
+     * 'id' => TODO (optional)
+     * 'locales' => TODO (optional)
+     * 'states' => TODO (optional)
+     * 'targetId' => TODO (optional)
+     * 'triggerId' => TODO (optional)
+     * 
+ */ + public function __construct($params = array()) + { + if (empty($params['id'])) { + $params['id'] = $this->_randomid(); + } + if (empty($params['targetId'])) { + $params['targetId'] = $this->_randomid(); + } + if (empty($params['triggerId'])) { + $params['triggerId'] = $params['targetId'] . '_trigger'; + } + if (empty($params['states'])) { + $params['states'] = '""'; + } else { + $params['states'] = Horde_Serialize::serialize($params['states'], Horde_Serialize::JSON, Horde_Nls::getCharset()); + } + if (empty($params['locales'])) { + $params['locales'] = array(); + foreach (array_keys(Horde_Nls::$config['spelling']) as $lcode) { + $params['locales'][$lcode] = Horde_Nls::$config['languages'][$lcode]; + } + } + asort($params['locales'], SORT_LOCALE_STRING); + $params['locales'] = Horde_Serialize::serialize($params['locales'], Horde_Serialize::JSON, Horde_Nls::getCharset()); + + parent::__construct($params); + } + + /** + */ + public function attach() + { + Horde::addScriptFile('prototype.js', 'horde', true); + Horde::addScriptFile('effects.js', 'horde', true); + Horde::addScriptFile('KeyNavList.js', 'imp', true); + Horde::addScriptFile('SpellChecker.js', 'imp', true); + + $url = $this->_getUrl('SpellChecker', 'imp', array('input' => $this->_params['targetId'])); + + IMP::addInlineScript($this->_params['id'] . ' = new SpellChecker("' . $url . '", "' . $this->_params['targetId'] . '", "' . $this->_params['triggerId'] . '", ' . $this->_params['states'] . ', ' . $this->_params['locales'] . ', \'widget\');', 'dom'); + } + + /** + */ + public function handle($args) + { + $spellArgs = array(); + + if (!empty($GLOBALS['conf']['spell']['params'])) { + $spellArgs = $GLOBALS['conf']['spell']['params']; + } + + if (isset($args['locale'])) { + $spellArgs['locale'] = $args['locale']; + } elseif (isset($GLOBALS['language'])) { + $spellArgs['locale'] = $GLOBALS['language']; + } + + /* Add local dictionary words. */ + try { + $result = Horde::loadConfiguration('spelling.php', 'ignore_list', 'horde'); + $spellArgs['localDict'] = $result; + } catch (Horde_Exception $e) {} + + if (!empty($args['html'])) { + $spellArgs['html'] = true; + } + + try { + $speller = Horde_SpellChecker::getInstance($GLOBALS['conf']['spell']['driver'], $spellArgs); + } catch (Horde_Exception $e) { + Horde::logMessage($e, __FILE__, __LINE__, PEAR_LOG_ERR); + return array(); + } + + try { + return $speller->spellCheck(Horde_Util::getPost($args['input'])); + } catch (Horde_Exception $e) { + Horde::logMessage($e, __FILE__, __LINE__, PEAR_LOG_ERR); + return array('bad' => array(), 'suggestions' => array()); + } + } + +} diff --git a/imp/lib/Imple.php b/imp/lib/Imple.php deleted file mode 100644 index a2ce17ee4..000000000 --- a/imp/lib/Imple.php +++ /dev/null @@ -1,98 +0,0 @@ - - * @package IMP - */ -class IMP_Imple -{ - /** - * Parameters needed by the subclasses. - * - * @var array - */ - protected $_params = array(); - - /** - * Attempts to return a concrete IMP_Imple instance based on $imple. - * - * @param string $imple The type of concrete subclass to return based - * on the imple type indicated. The code is - * dynamically included. - * @param array $params The configuration parameter array. - * - * @return mixed The newly created concrete instance, or false on error. - */ - static public function factory($imple, $params = array()) - { - $imple = basename($imple); - if (!$imple) { - return false; - } - - $class = 'IMP_Imple_' . $imple; - if (!class_exists($class)) { - include_once dirname(__FILE__) . '/Imple/' . $imple . '.php'; - if (!class_exists($class)) { - return false; - } - } - - return new $class($params); - } - - /** - * Constructor. - * - * @param array $params Any parameters needed by the class. - */ - function __construct($params) - { - $this->_params = $params; - $this->attach(); - } - - /** - * Attach the object to a javascript event. - */ - public function attach() - { - Horde::addScriptFile('prototype.js', 'horde', true); - Horde::addScriptFile('effects.js', 'horde', true); - } - - /** - * TODO - * - * @param TODO - */ - public function handle($args) - { - } - - /** - * Return the rendered HTML code. - * - * @return string The HTML code. - */ - public function html() - { - } - - /** - * Generate a random ID string. - * - * @return string The random ID string. - */ - protected function _randomid() - { - return 'imple_' . uniqid(mt_rand()); - } - -} diff --git a/imp/lib/Imple/ContactAutoCompleter.php b/imp/lib/Imple/ContactAutoCompleter.php deleted file mode 100644 index 3960b3c9b..000000000 --- a/imp/lib/Imple/ContactAutoCompleter.php +++ /dev/null @@ -1,130 +0,0 @@ - - * @package IMP - */ -class IMP_Imple_ContactAutoCompleter extends IMP_Imple -{ - /** - * The URL to use in attach(). - * - * @var string - */ - protected $_url; - - /** - * Has the address book been output to the browser? - * - * @var boolean - */ - static protected $_listOutput = false; - - /** - * Constructor. - * - * @param array $params Configuration parameters. - *
-     * 'triggerId' => TODO (optional)
-     * 'resultsId' => TODO (optional)
-     * 
- */ - function __construct($params) - { - if (empty($params['triggerId'])) { - $params['triggerId'] = $this->_randomid(); - } - if (empty($params['resultsId'])) { - $params['resultsId'] = $params['triggerId'] . '_results'; - } - - parent::__construct($params); - } - - /** - * Attach the object to a javascript event. - */ - public function attach() - { - parent::attach(); - Horde::addScriptFile('autocomplete.js', 'horde', true); - - $params = array( - '"' . $this->_params['triggerId'] . '"', - '"' . $this->_params['resultsId'] . '"' - ); - - $js_params = array( - 'tokens: [",", ";"]', - 'indicator: "' . $this->_params['triggerId'] . '_loading_img"', - 'afterUpdateElement: function(f, t) { if (!f.value.endsWith(";")) { f.value += ","; } f.value += " "; }' - ); - $ac_browser = empty($GLOBALS['conf']['compose']['ac_browser']) ? 0 : $GLOBALS['conf']['compose']['ac_browser']; - - if ($ac_browser && !isset($_SESSION['imp']['cache']['ac_ajax'])) { - $success = $use_ajax = true; - $sparams = IMP_Compose::getAddressSearchParams(); - foreach ($sparams['fields'] as $val) { - array_map('strtolower', $val); - sort($val); - if ($val != array('email', 'name')) { - $success = false; - break; - } - } - if ($success) { - $addrlist = IMP_Compose::getAddressList(); - $use_ajax = count($addrlist) > $ac_browser; - } - $_SESSION['imp']['cache']['ac_ajax'] = $use_ajax; - } - - if (!$ac_browser || $_SESSION['imp']['cache']['ac_ajax']) { - $func = 'Ajax.Autocompleter'; - if (empty($this->_url)) { - $this->_url = Horde::url($GLOBALS['registry']->get('webroot', 'imp') . '/imple.php?imple=ContactAutoCompleter/input=' . rawurlencode($this->_params['triggerId']), true); - } - $params[] = '"' . $this->_url . '"'; - - $js_params[] = 'minChars: ' . intval($GLOBALS['conf']['compose']['ac_threshold'] ? $GLOBALS['conf']['compose']['ac_threshold'] : 1); - } else { - if (!self::$_listOutput) { - if (!isset($addrlist)) { - $addrlist = IMP_Compose::getAddressList(); - } - IMP::addInlineScript('if (!IMP) { var IMP = {}; } IMP.ac_list = '. Horde_Serialize::serialize(array_map('htmlspecialchars', $addrlist), Horde_Serialize::JSON, Horde_Nls::getCharset())); - self::$_listOutput = true; - } - $func = 'Autocompleter.Local'; - $params[] = 'IMP.ac_list'; - $js_params[] = 'partialSearch: true'; - $js_params[] = 'fullSearch: true'; - } - - $params[] = '{' . implode(',', $js_params) . '}'; - IMP::addInlineScript('new ' . $func . '(' . implode(',', $params) . ')', 'dom'); - } - - /** - * Perform the address search. - * - * @param array $args Array with 1 key: 'input'. - * - * @return array The data to send to the autocompleter JS code. - */ - public function handle($args) - { - // Avoid errors if 'input' isn't set and short-circuit empty searches. - if (empty($args['input']) || - !($input = Horde_Util::getPost($args['input']))) { - return array(); - } - - return array_map('htmlspecialchars', IMP_Compose::expandAddresses($input)); - } - -} diff --git a/imp/lib/Imple/SpellChecker.php b/imp/lib/Imple/SpellChecker.php deleted file mode 100644 index 9dc421103..000000000 --- a/imp/lib/Imple/SpellChecker.php +++ /dev/null @@ -1,105 +0,0 @@ - - * @package IMP - */ -class IMP_Imple_SpellChecker extends IMP_Imple -{ - /** - * Constructor. - * - * @param array $params Configuration parameters. - *
-     * 'id' => TODO (optional)
-     * 'locales' => TODO (optional)
-     * 'states' => TODO (optional)
-     * 'targetId' => TODO (optional)
-     * 'triggerId' => TODO (optional)
-     * 
- */ - function __construct($params = array()) - { - if (empty($params['id'])) { - $params['id'] = $this->_randomid(); - } - if (empty($params['targetId'])) { - $params['targetId'] = $this->_randomid(); - } - if (empty($params['triggerId'])) { - $params['triggerId'] = $params['targetId'] . '_trigger'; - } - if (empty($params['states'])) { - $params['states'] = '""'; - } else { - $params['states'] = Horde_Serialize::serialize($params['states'], Horde_Serialize::JSON, Horde_Nls::getCharset()); - } - if (empty($params['locales'])) { - $params['locales'] = array(); - foreach (array_keys(Horde_Nls::$config['spelling']) as $lcode) { - $params['locales'][$lcode] = Horde_Nls::$config['languages'][$lcode]; - } - } - asort($params['locales'], SORT_LOCALE_STRING); - $params['locales'] = Horde_Serialize::serialize($params['locales'], Horde_Serialize::JSON, Horde_Nls::getCharset()); - - parent::__construct($params); - } - - /** - */ - public function attach() - { - parent::attach(); - Horde::addScriptFile('KeyNavList.js', 'imp', true); - Horde::addScriptFile('SpellChecker.js', 'imp', true); - $url = Horde::url($GLOBALS['registry']->get('webroot', 'imp') . '/imple.php?imple=SpellChecker/input=' . rawurlencode($this->_params['targetId']), true); - IMP::addInlineScript($this->_params['id'] . ' = new SpellChecker("' . $url . '", "' . $this->_params['targetId'] . '", "' . $this->_params['triggerId'] . '", ' . $this->_params['states'] . ', ' . $this->_params['locales'] . ', \'widget\');', 'dom'); - } - - /** - */ - public function handle($args) - { - $spellArgs = array(); - - if (!empty($GLOBALS['conf']['spell']['params'])) { - $spellArgs = $GLOBALS['conf']['spell']['params']; - } - - if (isset($args['locale'])) { - $spellArgs['locale'] = $args['locale']; - } elseif (isset($GLOBALS['language'])) { - $spellArgs['locale'] = $GLOBALS['language']; - } - - /* Add local dictionary words. */ - try { - $result = Horde::loadConfiguration('spelling.php', 'ignore_list', 'horde'); - $spellArgs['localDict'] = $result; - } catch (Horde_Exception $e) {} - - if (!empty($args['html'])) { - $spellArgs['html'] = true; - } - - try { - $speller = Horde_SpellChecker::getInstance($GLOBALS['conf']['spell']['driver'], $spellArgs); - } catch (Horde_Exception $e) { - Horde::logMessage($e, __FILE__, __LINE__, PEAR_LOG_ERR); - return array(); - } - - try { - return $speller->spellCheck(Horde_Util::getPost($args['input'])); - } catch (Horde_Exception $e) { - Horde::logMessage($e, __FILE__, __LINE__, PEAR_LOG_ERR); - return array('bad' => array(), 'suggestions' => array()); - } - } - -} diff --git a/imp/lib/UI/Compose.php b/imp/lib/UI/Compose.php index 793525cfe..6f2cd6cb0 100644 --- a/imp/lib/UI/Compose.php +++ b/imp/lib/UI/Compose.php @@ -99,7 +99,8 @@ class IMP_UI_Compose { /* Attach autocompleters to the compose form elements. */ foreach ($fields as $val) { - call_user_func_array(array('IMP_Imple', 'factory'), array('ContactAutoCompleter', array('triggerId' => $val))); + $imple = Horde_Ajax_Imple::getInstance(array('imp', 'ContactAutoCompleter'), array('triggerId' => $val)); + $imple->attach(); } } @@ -122,7 +123,9 @@ class IMP_UI_Compose 'Error' => $spell_img . $br . _("Spell Check Failed") ) ); - call_user_func_array(array('IMP_Imple', 'factory'), array('SpellChecker', $args)); + + $imple = Horde_Ajax_Imple::getInstance(array('imp', 'SpellChecker'), $args); + $imple->attach(); } /** diff --git a/kronolith/attendees.php b/kronolith/attendees.php index 12c9054f4..e4c0c6a96 100644 --- a/kronolith/attendees.php +++ b/kronolith/attendees.php @@ -248,7 +248,7 @@ $date = new Horde_Date($date); $vfb_html = $attendee_view->render($date); // Add the ContactAutoCompleter -Kronolith_Imple::factory('ContactAutoCompleter', array('triggerId' => 'newAttendees')); +Horde_Ajax_Imple::getInstance(array('kronolith', 'ContactAutoCompleter'), array('triggerId' => 'newAttendees')); $title = _("Edit attendees"); require KRONOLITH_TEMPLATES . '/common-header.inc'; diff --git a/kronolith/calendars/edit.php b/kronolith/calendars/edit.php index a88023aba..f87c51b39 100644 --- a/kronolith/calendars/edit.php +++ b/kronolith/calendars/edit.php @@ -58,4 +58,4 @@ require KRONOLITH_TEMPLATES . '/common-header.inc'; require KRONOLITH_TEMPLATES . '/menu.inc'; echo $form->renderActive($form->getRenderer(), $vars, 'edit.php', 'post'); require $registry->get('templates', 'horde') . '/common-footer.inc'; -Kronolith_Imple::factory('TagAutoCompleter', array('triggerId' => 'tags', 'id')); +Horde_Ajax_Imple::getInstance(array('kronolith', 'TagAutoCompleter'), array('triggerId' => 'tags', 'id')); diff --git a/kronolith/imple.php b/kronolith/imple.php deleted file mode 100644 index 10a059315..000000000 --- a/kronolith/imple.php +++ /dev/null @@ -1,63 +0,0 @@ - - */ - -require_once dirname(__FILE__) . '/lib/base.php'; - -$path = Horde_Util::getFormData('imple'); -if (!$path) { - exit; -} -if ($path[0] == '/') { - $path = substr($path, 1); -} -$path = explode('/', $path); -$impleName = array_shift($path); - -$imple = Kronolith_Imple::factory($impleName); -if (!$imple) { - exit; -} -$args = array(); -foreach ($path as $pair) { - if (strpos($pair, '=') === false) { - $args[$pair] = true; - } else { - list($name, $val) = explode('=', $pair); - $args[$name] = $val; - } -} - -$result = $imple->handle($args); - -if (!empty($_SERVER['Content-Type'])) { - $ct = $_SERVER['Content-Type']; -} else { - $ct = is_string($result) ? 'plain' : 'json'; -} - -switch ($ct) { -case 'json': - header('Content-Type: application/json'); - echo Horde_Serialize::serialize($result, Horde_Serialize::JSON, Horde_Nls::getCharset()); - break; - -case 'plain': - header('Content-Type: text/plain'); - echo $result; - break; - -case 'html': - header('Content-Type: text/html'); - echo $result; - break; - -default: - echo $result; -} diff --git a/kronolith/index.php b/kronolith/index.php index 284582fcb..89976e1c3 100644 --- a/kronolith/index.php +++ b/kronolith/index.php @@ -65,5 +65,5 @@ require KRONOLITH_TEMPLATES . '/index/index.inc'; Kronolith::includeScriptFiles(); Kronolith::outputInlineScript(); $notification->notify(array('listeners' => array('javascript'))); -Kronolith_Imple::factory('TagAutoCompleter', array('triggerId' => 'kronolithEventTags', 'pretty' => true)); +Horde_Ajax_Imple::getInstance(array('kronolith', 'TagAutoCompleter'), array('triggerId' => 'kronolithEventTags', 'pretty' => true)); echo "\n"; diff --git a/kronolith/js/src/tagactions.js b/kronolith/js/src/tagactions.js index ed66515d8..237597ca9 100644 --- a/kronolith/js/src/tagactions.js +++ b/kronolith/js/src/tagactions.js @@ -2,7 +2,7 @@ function addTag(resource, type, endpoint) { if (!$('newtags-input_' + resource).value.blank()) { var params = new Object(); - params.imple="TagActions/action=add/resource=" + resource + "/type=" + type + "/tags=" + $('newtags-input_' + resource).value; + params.imple="/action=add/resource=" + resource + "/type=" + type + "/tags=" + $('newtags-input_' + resource).value; new Ajax.Updater({success:'tags_' + resource}, endpoint, { @@ -19,7 +19,7 @@ function addTag(resource, type, endpoint) function removeTag(resource, type, tagid, endpoint) { var params = new Object(); - params.imple = "TagActions/action=remove/resource=" + resource + "/type=" + type + "/tags=" + tagid; + params.imple = "/action=remove/resource=" + resource + "/type=" + type + "/tags=" + tagid; new Ajax.Updater({success:'tags_' + resource}, endpoint, { @@ -29,4 +29,4 @@ function removeTag(resource, type, tagid, endpoint) ); return true; -} \ No newline at end of file +} diff --git a/kronolith/lib/Ajax/Imple/ContactAutoCompleter.php b/kronolith/lib/Ajax/Imple/ContactAutoCompleter.php new file mode 100644 index 000000000..2f58934c6 --- /dev/null +++ b/kronolith/lib/Ajax/Imple/ContactAutoCompleter.php @@ -0,0 +1,156 @@ + + * @package Kronolith + */ +class Kronolith_Ajax_Imple_ContactAutoCompleter extends Horde_Ajax_Imple_Base +{ + /** + * Constructor. + * + * @param array $params Configuration parameters. + *
+     * 'triggerId' => TODO (optional)
+     * 'resultsId' => TODO (optional)
+     * 
+ */ + public function __construct($params) + { + if (empty($params['triggerId'])) { + $params['triggerId'] = $this->_randomid(); + } + if (empty($params['resultsId'])) { + $params['resultsId'] = $params['triggerId'] . '_results'; + } + + parent::__construct($params); + } + + /** + * Attach the Imple object to a javascript event. + */ + public function attach() + { + Horde::addScriptFile('prototype.js', 'horde', true); + Horde::addScriptFile('effects.js', 'horde', true); + Horde::addScriptFile('autocomplete.js', 'horde', true); + + $params = array( + '"' . $this->_params['triggerId'] . '"', + '"' . $this->_params['resultsId'] . '"', + '"' . $this->_getUrl('ContactAutoCompleter', 'kronolith', array('input' => $this->_params['triggerId'])) . '"' + ); + + $js_params = array( + 'tokens: [",", ";"]', + 'indicator: "' . $this->_params['triggerId'] . '_loading_img"', + 'afterUpdateElement: function(f, t) { if (!f.value.endsWith(";")) { f.value += ","; } f.value += " "; }' + ); + + $params[] = '{' . implode(',', $js_params) . '}'; + + Kronolith::addInlineScript('new Ajax.Autocompleter(' . implode(',', $params) . ')', 'dom'); + } + + /** + * TODO + * + * @param array $args TODO + * + * @return string TODO + */ + public function handle($args) + { + // Avoid errors if 'input' isn't set and short-circuit empty searches. + if (empty($args['input']) || + !($input = Horde_Util::getFormData($args['input']))) { + return array(); + } + + return array_map('htmlspecialchars', $this->_expandAddresses($input)); + } + + /** + * Uses the Registry to expand names and return error information for + * any address that is either not valid or fails to expand. This function + * will not search if the address string is empty. + * + * @param string $addrString The name(s) or address(es) to expand. + * + * @return array All matching addresses. + */ + protected function _expandAddresses($addrString) + { + return preg_match('|[^\s]|', $addrString) + ? $this->getAddressList(reset(array_filter(array_map('trim', Horde_Mime_Address::explode($addrString, ',;'))))) + : ''; + } + + /** + * Uses the Registry to expand names and return error information for + * any address that is either not valid or fails to expand. + * + * @param string $search The term to search by. + * + * @return array All matching addresses. + */ + static public function getAddressList($search = '') + { + $src = explode("\t", $GLOBALS['prefs']->getValue('search_sources')); + if ((count($src) == 1) && empty($src[0])) { + $src = array(); + } + + $fields = array(); + if (($val = $GLOBALS['prefs']->getValue('search_fields'))) { + $field_arr = explode("\n", $val); + foreach ($field_arr as $field) { + $field = trim($field); + if (!empty($field)) { + $tmp = explode("\t", $field); + if (count($tmp) > 1) { + $source = array_splice($tmp, 0, 1); + $fields[$source[0]] = $tmp; + } + } + } + } + + try { + $res = $GLOBALS['registry']->call('contacts/search', array($search, $src, $fields, true)); + } catch (Horde_Exception $e) { + Horde::logMessage($e, __FILE__, __LINE__, PEAR_LOG_ERR); + return array(); + } + + if (!count($res)) { + return array(); + } + + /* The first key of the result will be the search term. The matching + * entries are stored underneath this key. */ + $search = array(); + foreach (reset($res) as $val) { + if (!empty($val['email'])) { + if (strpos($val['email'], ',') !== false) { + $search[] = Horde_Mime_Address::encode($val['name'], 'personal') . ': ' . $val['email'] . ';'; + } else { + $mbox_host = explode('@', $val['email']); + if (isset($mbox_host[1])) { + $search[] = Horde_Mime_Address::writeAddress($mbox_host[0], $mbox_host[1], $val['name']); + } + } + } + } + + return $search; + } + +} diff --git a/kronolith/lib/Ajax/Imple/Embed.php b/kronolith/lib/Ajax/Imple/Embed.php new file mode 100644 index 000000000..b8301679d --- /dev/null +++ b/kronolith/lib/Ajax/Imple/Embed.php @@ -0,0 +1,122 @@ + + * @package Kronolith + */ +class Kronolith_Ajax_Imple_Embed extends Horde_Ajax_Imple_Base +{ + /** + */ + public function attach() + { + } + + /** + * Handles the output of the embedded widget. This must always be valid + * javascript. + *
+     * The following arguments are required:
+     *   view      => the view (block) we want
+     *   container => the DOM node to populate with the widget
+     *   calendar  => the share_name for the requested calendar
+     *
+     * The following are optional (and are not used for all views)
+     *   months     => the number of months to include
+     *   maxevents     => the maximum number of events to show
+     *
+     * @param array $args  Arguments for this view.
+     */
+    public function handle($args)
+    {
+        /* First, determine the type of view we are asking for */
+        $view = $args['view'];
+
+        /* The DOM container to put the HTML in on the remote site */
+        $container = $args['container'];
+
+        /* The share_name of the calendar to display */
+        $calendar = $args['calendar'];
+
+        /* Deault to showing only 1 month when we have a choice */
+        $count_month = (!empty($args['months']) ? $args['months'] : 1);
+
+        /* Default to no limit for the number of events */
+        $max_events = (!empty($args['maxevents']) ? $args['maxevents'] : 0);
+
+        /* Default to one week */
+        $count_days = (!empty($args['days']) ? $args['days'] : 7);
+
+        if (!empty($args['css']) && $args['css'] == 'none') {
+            $nocss = true;
+        }
+
+        /* Load the registry with no session control */
+        $registry = Horde_Registry::singleton(Horde_Registry::SESSION_NONE);
+
+
+        /* Build the block parameters */
+        $params = array(
+            'calendar' => $calendar,
+            'maxevents' => $max_events,
+            'months' => $count_month,
+            'days' => $count_days
+        );
+
+        /* Call the Horde_Block api to get the calendar HTML */
+        $title = $registry->call('horde/blockTitle', array('kronolith', $view, $params));
+        $results = $registry->call('horde/blockContent', array('kronolith', $view, $params));
+
+        /* Some needed paths */
+        $js_path = $registry->get('jsuri', 'kronolith');
+
+        /* Local js */
+        $jsurl = Horde::url($js_path . '/embed.js', true);
+
+        /* Horde's js */
+        $hjs_path = $registry->get('jsuri', 'horde');
+        $hjsurl = Horde::url($hjs_path . '/horde-embed.js', true);
+        $pturl = Horde::url($hjs_path . '/prototype.js', true);
+
+        /* CSS */
+        if (empty($nocss)) {
+            $cssurl = Horde::url($registry->get('themesuri', 'kronolith') . '/embed.css', true);
+            $hcssurl = Horde::url($registry->get('themesuri', 'horde') . '/embed.css', true);
+        } else {
+            $cssurl= '';
+        }
+
+        /* Escape the text and put together the javascript to send back */
+        $results = addslashes('
' . $title . '
' . $results . '
'); + $html = <<'); + document.write(''); + } + if (typeof Prototype == 'undefined') { + document.write(''); + } + kronolith = new Object(); + kronolithNodes = new Array(); + document.write(''); + document.write(''); + } + kronolithNodes[kronolithNodes.length] = '$container'; + kronolith['$container'] = "$results"; + //]]> +EOT; + + /* Send it */ + header('Content-Type: text/javascript'); + echo $html; + exit; + } + +} diff --git a/kronolith/lib/Ajax/Imple/TagActions.php b/kronolith/lib/Ajax/Imple/TagActions.php new file mode 100644 index 000000000..b4bb3e838 --- /dev/null +++ b/kronolith/lib/Ajax/Imple/TagActions.php @@ -0,0 +1,106 @@ + + * @package Kronolith + */ +class Kronolith_Ajax_Imple_TagActions extends Horde_Ajax_Imple_Base +{ + /** + */ + public function attach() + { + Horde::addScriptFile('tagactions.js'); + $dom_id = $this->_params['triggerId']; + $action = $this->_params['action']; + $content_id = $this->_params['resource']; + $content_type = $this->_params['type']; + $tag_id = !empty($this->_params['tagId']) ? $this->_params['tagId'] : null; + $endpoint = $this->_getUrl('TagActions', 'kronolith'); + + if ($action == 'add') { + $js = "Event.observe('" . $dom_id . "_" . $content_id . "', 'click', function(event) {addTag('" . $content_id . "', '" . $content_type . "', '" . $endpoint . "'); Event.stop(event)});"; + } elseif ($action == 'delete') { + $js = "Event.observe('" . $dom_id . "', 'click', function(event) {removeTag('" . $content_id . "', '" . $content_type . "', " . $tag_id . ", '" . $endpoint . "'); Event.stop(event)});"; + } + Kronolith::addInlineScript($js, 'window'); + } + + /** + * Handle the tag related action. + * + * If removing a tag, needs a 'resource' which is the local identifier of + * the kronolith object, a 'type' which should be the string reprentation of + * the type of object (event/calendar) and 'tags' should be the integer + * tag_id of the tag to remove. + */ + public function handle($args) + { + global $ansel_storage; + + $request = $args['action']; + $content = array('id' => $args['resource'], 'type' => $args['type']); + $tags = $args['tags']; + + // Check perms + if ($args['type'] == 'calendar') { + $cal = $GLOBALS['kronolith_shares']->getShare($args['resource']); + $perm = $cal->hasPermission(Horde_Auth::getAuth(), PERMS_EDIT); + } elseif($args['type'] == 'event') { + $event = Kronolith::getDriver()->getByUID($args['resource']); + $perm = $event->hasPermission(PERMS_EDIT, Horde_Auth::getAuth()); + } + + if ($perm) { + /* Get the resource owner */ + $tagger = Kronolith::getTagger(); + switch ($request) { + case 'add': + $tagger->tag($args['resource'], $tags, $args['type']); + break; + case 'remove': + $tagger->untag($args['resource'], (int)$tags, $args['type']); + break; + } + } + return $this->_getTagHtml($tagger, $args['resource'], $args['type']); + + } + + /** + * Generate the HTML for the tag lists to send back to the browser. + * + * TODO: This should be made a view helper when we move to using Horde_View + * + * @param Kronolith_Tagger $tagger The tagger object + * @param string $id The identifier (share name or event uid) + * @param string $type The type of resource (calendar/event) + * + * @return string The HTML + */ + private function _getTagHtml($tagger, $id, $type) + { + $tags = $tagger->getTags($id, 'calendar'); + $js = ''; + $html = ''; + + if ($type == 'calendar') { + $cal = $GLOBALS['kronolith_shares']->getShare($id); + $hasEdit = $cal->hasPermission(Horde_Auth::getAuth(), PERMS_EDIT); + } elseif ($type == 'event') { + $event = Kronolith::getDriver()->getByUID($id); + $hasEdit = $event->hasPermission(PERMS_EDIT, Horde_Auth::getAuth()); + } + + foreach ($tags as $tag_id => $tag) { + $html .= '
  • ' . $tag . ($hasEdit ? '' . Horde::img('delete-small.png', _("Remove Tag"), '', $GLOBALS['registry']->getImageDir('horde')) . '' : '') . '
  • '; + } + + return $html; + } + +} diff --git a/kronolith/lib/Ajax/Imple/TagAutoCompleter.php b/kronolith/lib/Ajax/Imple/TagAutoCompleter.php new file mode 100644 index 000000000..d17fd9b0b --- /dev/null +++ b/kronolith/lib/Ajax/Imple/TagAutoCompleter.php @@ -0,0 +1,126 @@ + + * @package Kronolith + */ +class Kronolith_Ajax_Imple_TagAutoCompleter extends Horde_Ajax_Imple_Base +{ + /** + * Constructor. + * + * @param array $params Configuration parameters. + *
    +     * 'triggerId' => TODO (optional)
    +     * 'resultsId' => TODO (optional)
    +     * 
    + */ + public function __construct($params) + { + if (!count($params)) { + return; + } + if (empty($params['resultsId'])) { + $params['resultsId'] = $params['triggerId'] . '_results'; + } + + parent::__construct($params); + } + + /** + * Attach the Imple object to a javascript event. + * If the 'pretty' parameter is empty then we want a + * traditional autocompleter, otherwise we get a spiffy pretty one. + * + */ + public function attach() + { + Horde::addScriptFile('prototype.js', 'horde', true); + Horde::addScriptFile('effects.js', 'horde', true); + Horde::addScriptFile('autocomplete.js', 'horde', true); + + $registry = Horde_Registry::singleton(); + + if ($pretty = !empty($this->_params['pretty'])) { + Horde::addScriptFile('prettyautocomplete.js', 'horde', true); + $this->_params['uri'] = $this->_getUrl('TagAutoCompleter', 'kronolith'); + } else { + $this->_params['uri'] = $this->_getUrl('TagAutoCompleter', 'kronolith', array('input' => $this->_params['triggerId'])); + } + + if (!$pretty) { + $params = array( + '"' . $this->_params['triggerId'] . '"', + '"' . $this->_params['resultsId'] . '"', + '"' . $this->_params['uri'] . '"' + ); + } + + $js_params = array( + 'tokens: [","]', + 'indicator: "' . $this->_params['triggerId'] . '_loading_img"' + ); + + // The pretty version needs to set this callback itself... + if (!$pretty && !empty($this->_params['updateElement'])) { + $js_params[] = 'updateElement: ' . $this->_params['updateElement']; + } + + $params[] = '{' . implode(',', $js_params) . '}'; + + if ($pretty) { + $js_vars = array('boxClass' => 'hordeACBox kronolithLongField', + 'uri' => $this->_params['uri'], + 'trigger' => $this->_params['triggerId'], + 'URI_IMG_HORDE' => $registry->getImageDir('horde'), + 'params' => $params); + + if (!empty($this->_params['existing'])) { + $js_vars['existing'] = $this->_params['existing']; + } + + $script = array('new PrettyAutocompleter(' . Horde_Serialize::serialize($js_vars, Horde_Serialize::JSON, Horde_Nls::getCharset()) . ')'); + } else { + $script = array('new Ajax.Autocompleter(' . implode(',', $params) . ')'); + } + + Kronolith::addInlineScript($script, 'dom'); + } + + /** + * TODO + * + * @param array $args TODO + * + * @return string TODO + */ + public function handle($args) + { + // Avoid errors if 'input' isn't set and short-circuit empty searches. + if (empty($args['input']) || + !($input = Horde_Util::getFormData($args['input']))) { + return array(); + } + return array_map('htmlspecialchars', $this->getTagList($input)); + } + + /** + * Get a list of existing, used tags that match the search term. + * + * @param string $search The term to search by. + * + * @return array All matching tags. + */ + public function getTagList($search = '') + { + $tagger = Kronolith::getTagger(); + $tags = $tagger->listTags($search); + + return array_values($tags); + } + +} diff --git a/kronolith/lib/Imple.php b/kronolith/lib/Imple.php deleted file mode 100644 index 50062f8e6..000000000 --- a/kronolith/lib/Imple.php +++ /dev/null @@ -1,100 +0,0 @@ - - * @package Kronolith - */ -class Kronolith_Imple -{ - - /** - * Parameters needed by the subclasses. - * - * @var array - */ - protected $_params = array(); - - /** - * Attempts to return a concrete Imple instance based on $imple. - * - * @param string $imple The type of concrete Imple subclass to return - * return, based on the imple type indicated. The - * code is dynamically included. - * @param array $params The configuration parameter array. - * - * @return mixed The newly created concrete Imple instance, or false on - * error. - */ - public static function factory($imple, $params = array()) - { - $imple = basename($imple); - if (!$imple) { - return false; - } - - $class = 'Kronolith_Imple_' . $imple; - if (!class_exists($class)) { - include_once dirname(__FILE__) . '/Imple/' . $imple . '.php'; - if (!class_exists($class)) { - return false; - } - } - - return new $class($params); - } - - /** - * Constructor. - * - * @param array $params Any parameters needed by the class. - */ - public function __construct($params) - { - $this->_params = $params; - $this->attach(); - } - - /** - * Attach the Imple object to a javascript event. - */ - public function attach() - { - Horde::addScriptFile('prototype.js', 'horde', true); - Horde::addScriptFile('effects.js', 'horde', true); - } - - /** - * TODO - * - * @param TODO - */ - public function handle($args) - { - } - - /** - * Return the rendered HTML code. - * - * @return string The HTML code. - */ - public function html() - { - } - - /** - * Generate a random ID string. - * - * @access private - * - * @return string The random ID string. - */ - public function _randomid() - { - return 'imple_' . uniqid(mt_rand()); - } - -} diff --git a/kronolith/lib/Imple/ContactAutoCompleter.php b/kronolith/lib/Imple/ContactAutoCompleter.php deleted file mode 100644 index 598a0b6aa..000000000 --- a/kronolith/lib/Imple/ContactAutoCompleter.php +++ /dev/null @@ -1,153 +0,0 @@ - - * @package Kronolith - */ -class Kronolith_Imple_ContactAutoCompleter extends Kronolith_Imple -{ - /** - * Constructor. - * - * @param array $params Configuration parameters. - *
    -     * 'triggerId' => TODO (optional)
    -     * 'resultsId' => TODO (optional)
    -     * 
    - */ - public function __construct($params) - { - if (empty($params['triggerId'])) { - $params['triggerId'] = $this->_randomid(); - } - if (empty($params['resultsId'])) { - $params['resultsId'] = $params['triggerId'] . '_results'; - } - - parent::__construct($params); - } - - /** - * Attach the Imple object to a javascript event. - */ - public function attach() - { - parent::attach(); - Horde::addScriptFile('autocomplete.js', 'horde', true); - - $params = array( - '"' . $this->_params['triggerId'] . '"', - '"' . $this->_params['resultsId'] . '"', - '"' . Horde::url($GLOBALS['registry']->get('webroot', 'kronolith') . '/imple.php?imple=ContactAutoCompleter/input=' . rawurlencode($this->_params['triggerId']), true) . '"' - ); - - $js_params = array( - 'tokens: [",", ";"]', - 'indicator: "' . $this->_params['triggerId'] . '_loading_img"', - 'afterUpdateElement: function(f, t) { if (!f.value.endsWith(";")) { f.value += ","; } f.value += " "; }' - ); - - $params[] = '{' . implode(',', $js_params) . '}'; - - Kronolith::addInlineScript('new Ajax.Autocompleter(' . implode(',', $params) . ')', 'dom'); - } - - /** - * TODO - * - * @param array $args TODO - * - * @return string TODO - */ - public function handle($args) - { - // Avoid errors if 'input' isn't set and short-circuit empty searches. - if (empty($args['input']) || - !($input = Horde_Util::getFormData($args['input']))) { - return array(); - } - - return array_map('htmlspecialchars', $this->_expandAddresses($input)); - } - - /** - * Uses the Registry to expand names and return error information for - * any address that is either not valid or fails to expand. This function - * will not search if the address string is empty. - * - * @param string $addrString The name(s) or address(es) to expand. - * - * @return array All matching addresses. - */ - protected function _expandAddresses($addrString) - { - return preg_match('|[^\s]|', $addrString) - ? $this->getAddressList(reset(array_filter(array_map('trim', Horde_Mime_Address::explode($addrString, ',;'))))) - : ''; - } - - /** - * Uses the Registry to expand names and return error information for - * any address that is either not valid or fails to expand. - * - * @param string $search The term to search by. - * - * @return array All matching addresses. - */ - static public function getAddressList($search = '') - { - $src = explode("\t", $GLOBALS['prefs']->getValue('search_sources')); - if ((count($src) == 1) && empty($src[0])) { - $src = array(); - } - - $fields = array(); - if (($val = $GLOBALS['prefs']->getValue('search_fields'))) { - $field_arr = explode("\n", $val); - foreach ($field_arr as $field) { - $field = trim($field); - if (!empty($field)) { - $tmp = explode("\t", $field); - if (count($tmp) > 1) { - $source = array_splice($tmp, 0, 1); - $fields[$source[0]] = $tmp; - } - } - } - } - - try { - $res = $GLOBALS['registry']->call('contacts/search', array($search, $src, $fields, true)); - } catch (Horde_Exception $e) { - Horde::logMessage($e, __FILE__, __LINE__, PEAR_LOG_ERR); - return array(); - } - - if (!count($res)) { - return array(); - } - - /* The first key of the result will be the search term. The matching - * entries are stored underneath this key. */ - $search = array(); - foreach (reset($res) as $val) { - if (!empty($val['email'])) { - if (strpos($val['email'], ',') !== false) { - $search[] = Horde_Mime_Address::encode($val['name'], 'personal') . ': ' . $val['email'] . ';'; - } else { - $mbox_host = explode('@', $val['email']); - if (isset($mbox_host[1])) { - $search[] = Horde_Mime_Address::writeAddress($mbox_host[0], $mbox_host[1], $val['name']); - } - } - } - } - - return $search; - } - -} diff --git a/kronolith/lib/Imple/Embed.php b/kronolith/lib/Imple/Embed.php deleted file mode 100644 index d284a6bb0..000000000 --- a/kronolith/lib/Imple/Embed.php +++ /dev/null @@ -1,125 +0,0 @@ - - * - * @package Kronolith - */ -class Kronolith_Imple_Embed extends Kronolith_Imple { - - /** - * Override the parent method since it uses Horde::addScriptFile() - * - */ - function attach() - { - //noop - } - - - /** - * Handles the output of the embedded widget. This must always be valid - * javascript. - *
    -     * The following arguments are required:
    -     *   view      => the view (block) we want
    -     *   container => the DOM node to populate with the widget
    -     *   calendar  => the share_name for the requested calendar
    -     *
    -     * The following are optional (and are not used for all views)
    -     *   months     => the number of months to include
    -     *   maxevents     => the maximum number of events to show
    -     *
    -     * @param array $args  Arguments for this view.
    -     */
    -    function handle($args)
    -    {
    -        /* First, determine the type of view we are asking for */
    -        $view = $args['view'];
    -
    -        /* The DOM container to put the HTML in on the remote site */
    -        $container = $args['container'];
    -
    -        /* The share_name of the calendar to display */
    -        $calendar = $args['calendar'];
    -
    -        /* Deault to showing only 1 month when we have a choice */
    -        $count_month = (!empty($args['months']) ? $args['months'] : 1);
    -
    -        /* Default to no limit for the number of events */
    -        $max_events = (!empty($args['maxevents']) ? $args['maxevents'] : 0);
    -
    -        /* Default to one week */
    -        $count_days = (!empty($args['days']) ? $args['days'] : 7);
    -
    -        if (!empty($args['css']) && $args['css'] == 'none') {
    -            $nocss = true;
    -        }
    -
    -        /* Load the registry with no session control */
    -        $registry = Horde_Registry::singleton(Horde_Registry::SESSION_NONE);
    -
    -
    -        /* Build the block parameters */
    -        $params = array('calendar' => $calendar,
    -                        'maxevents' => $max_events,
    -                        'months' => $count_month,
    -                        'days' => $count_days);
    -
    -        /* Call the Horde_Block api to get the calendar HTML */
    -        $title = $registry->call('horde/blockTitle', array('kronolith', $view, $params));
    -        $results = $registry->call('horde/blockContent', array('kronolith', $view, $params));
    -
    -        /* Some needed paths */
    -        $js_path = $registry->get('jsuri', 'kronolith');
    -
    -        /* Local js */
    -        $jsurl = Horde::url($js_path . '/embed.js', true);
    -
    -        /* Horde's js */
    -        $hjs_path = $registry->get('jsuri', 'horde');
    -        $hjsurl = Horde::url($hjs_path . '/horde-embed.js', true);
    -        $pturl = Horde::url($hjs_path . '/prototype.js', true);
    -
    -        /* CSS */
    -        if (empty($nocss)) {
    -            $cssurl = Horde::url($registry->get('themesuri', 'kronolith') . '/embed.css', true);
    -            $hcssurl = Horde::url($registry->get('themesuri', 'horde') . '/embed.css', true);
    -        } else {
    -            $cssurl= '';
    -        }
    -
    -        /* Escape the text and put together the javascript to send back */
    -        $results = addslashes('
    ' . $title . '
    ' . $results . '
    '); - $html = <<'); - document.write(''); - } - if (typeof Prototype == 'undefined') { - document.write(''); - } - kronolith = new Object(); - kronolithNodes = new Array(); - document.write(''); - document.write(''); - } - kronolithNodes[kronolithNodes.length] = '$container'; - kronolith['$container'] = "$results"; - //]]> -EOT; - - /* Send it */ - header('Content-Type: text/javascript'); - echo $html; - exit; - } - -} diff --git a/kronolith/lib/Imple/TagActions.php b/kronolith/lib/Imple/TagActions.php deleted file mode 100644 index baa82fa45..000000000 --- a/kronolith/lib/Imple/TagActions.php +++ /dev/null @@ -1,110 +0,0 @@ - - * - * @package Kronolith - */ -class Kronolith_Imple_TagActions extends Kronolith_Imple -{ - public function attach() - { - // TODO: HACK! attach is called in the contructor which means that even - // if we are only handling the request, we try to attach(). - if (count($this->_params) == 0) { - return; - } - Horde::addScriptFile('tagactions.js'); - $dom_id = $this->_params['triggerId']; - $action = $this->_params['action']; - $content_id = $this->_params['resource']; - $content_type = $this->_params['type']; - $tag_id = !empty($this->_params['tagId']) ? $this->_params['tagId'] : null; - $endpoint = Horde::url('imple.php', true); - - if ($action == 'add') { - $js = "Event.observe('" . $dom_id . "_" . $content_id . "', 'click', function(event) {addTag('" . $content_id . "', '" . $content_type . "', '" . $endpoint . "'); Event.stop(event)});"; - } elseif ($action == 'delete') { - $js = "Event.observe('" . $dom_id . "', 'click', function(event) {removeTag('" . $content_id . "', '" . $content_type . "', " . $tag_id . ", '" . $endpoint . "'); Event.stop(event)});"; - } - Kronolith::addInlineScript($js, 'window'); - } - - /** - * Handle the tag related action. - * - * If removing a tag, needs a 'resource' which is the local identifier of - * the kronolith object, a 'type' which should be the string reprentation of - * the type of object (event/calendar) and 'tags' should be the integer - * tag_id of the tag to remove. - */ - public function handle($args) - { - global $ansel_storage; - - $request = $args['action']; - $content = array('id' => $args['resource'], 'type' => $args['type']); - $tags = $args['tags']; - - // Check perms - if ($args['type'] == 'calendar') { - $cal = $GLOBALS['kronolith_shares']->getShare($args['resource']); - $perm = $cal->hasPermission(Horde_Auth::getAuth(), PERMS_EDIT); - } elseif($args['type'] == 'event') { - $event = Kronolith::getDriver()->getByUID($args['resource']); - $perm = $event->hasPermission(PERMS_EDIT, Horde_Auth::getAuth()); - } - - if ($perm) { - /* Get the resource owner */ - $tagger = Kronolith::getTagger(); - switch ($request) { - case 'add': - $tagger->tag($args['resource'], $tags, $args['type']); - break; - case 'remove': - $tagger->untag($args['resource'], (int)$tags, $args['type']); - break; - } - } - return $this->_getTagHtml($tagger, $args['resource'], $args['type']); - - } - - /** - * Generate the HTML for the tag lists to send back to the browser. - * - * TODO: This should be made a view helper when we move to using Horde_View - * - * @param Kronolith_Tagger $tagger The tagger object - * @param string $id The identifier (share name or event uid) - * @param string $type The type of resource (calendar/event) - * - * @return string The HTML - */ - private function _getTagHtml($tagger, $id, $type) - { - $tags = $tagger->getTags($id, 'calendar'); - $js = ''; - $html = ''; - - if ($type == 'calendar') { - $cal = $GLOBALS['kronolith_shares']->getShare($id); - $hasEdit = $cal->hasPermission(Horde_Auth::getAuth(), PERMS_EDIT); - } elseif ($type == 'event') { - $event = Kronolith::getDriver()->getByUID($id); - $hasEdit = $event->hasPermission(PERMS_EDIT, Horde_Auth::getAuth()); - } - - foreach ($tags as $tag_id => $tag) { - $html .= '
  • ' . $tag . ($hasEdit ? '' . Horde::img('delete-small.png', _("Remove Tag"), '', $GLOBALS['registry']->getImageDir('horde')) . '' : '') . '
  • '; - } - - return $html; - } - -} diff --git a/kronolith/lib/Imple/TagAutoCompleter.php b/kronolith/lib/Imple/TagAutoCompleter.php deleted file mode 100644 index e10bfd5ef..000000000 --- a/kronolith/lib/Imple/TagAutoCompleter.php +++ /dev/null @@ -1,124 +0,0 @@ - - * @package Kronolith - */ -class Kronolith_Imple_TagAutoCompleter extends Kronolith_Imple -{ - /** - * Constructor. - * - * @param array $params Configuration parameters. - *
    -     * 'triggerId' => TODO (optional)
    -     * 'resultsId' => TODO (optional)
    -     * 
    - */ - public function __construct($params) - { - if (!count($params)) { - return; - } - if (empty($params['resultsId'])) { - $params['resultsId'] = $params['triggerId'] . '_results'; - } - - parent::__construct($params); - } - - /** - * Attach the Imple object to a javascript event. - * If the 'pretty' parameter is empty then we want a - * traditional autocompleter, otherwise we get a spiffy pretty one. - * - */ - public function attach() - { - global $registry; - parent::attach(); - Horde::addScriptFile('autocomplete.js', 'horde', true); - - if ($pretty = !empty($this->_params['pretty'])) { - Horde::addScriptFile('prettyautocomplete.js', 'horde', true); - $this->_params['uri'] = Horde::url($GLOBALS['registry']->get('webroot', 'kronolith') . '/imple.php?imple=TagAutoCompleter', true); - } else { - $this->_params['uri'] = Horde::url($GLOBALS['registry']->get('webroot', 'kronolith') . '/imple.php?imple=TagAutoCompleter/input=' . rawurlencode($this->_params['triggerId']), true); - } - - if (!$pretty) { - $params = array( - '"' . $this->_params['triggerId'] . '"', - '"' . $this->_params['resultsId'] . '"', - '"' . $this->_params['uri'] . '"' - ); - } - - $js_params = array( - 'tokens: [","]', - 'indicator: "' . $this->_params['triggerId'] . '_loading_img"' - ); - - // The pretty version needs to set this callback itself... - if (!$pretty && !empty($this->_params['updateElement'])) { - $js_params[] = 'updateElement: ' . $this->_params['updateElement']; - } - - $params[] = '{' . implode(',', $js_params) . '}'; - - if ($pretty) { - $js_vars = array('boxClass' => 'hordeACBox kronolithLongField', - 'uri' => $this->_params['uri'], - 'trigger' => $this->_params['triggerId'], - 'URI_IMG_HORDE' => $registry->getImageDir('horde'), - 'params' => $params); - - if (!empty($this->_params['existing'])) { - $js_vars['existing'] = $this->_params['existing']; - } - - $script = array('new PrettyAutocompleter(' . Horde_Serialize::serialize($js_vars, Horde_Serialize::JSON, Horde_Nls::getCharset()) . ')'); - } else { - $script = array('new Ajax.Autocompleter(' . implode(',', $params) . ')'); - } - - Kronolith::addInlineScript($script, 'dom'); - } - - /** - * TODO - * - * @param array $args TODO - * - * @return string TODO - */ - public function handle($args) - { - // Avoid errors if 'input' isn't set and short-circuit empty searches. - if (empty($args['input']) || - !($input = Horde_Util::getFormData($args['input']))) { - return array(); - } - return array_map('htmlspecialchars', $this->getTagList($input)); - } - - /** - * Get a list of existing, used tags that match the search term. - * - * @param string $search The term to search by. - * - * @return array All matching tags. - */ - static public function getTagList($search = '') - { - $tagger = Kronolith::getTagger(); - $tags = $tagger->listTags($search); - - return array_values($tags); - } - -} diff --git a/kronolith/templates/edit/edit.inc b/kronolith/templates/edit/edit.inc index 3992470ab..4e6c891ae 100644 --- a/kronolith/templates/edit/edit.inc +++ b/kronolith/templates/edit/edit.inc @@ -379,7 +379,7 @@ endif;
    - 'tags', 'id' => $event->getUID())); ?> + 'tags', 'id' => $event->getUID())); ?> diff --git a/kronolith/templates/panel.inc b/kronolith/templates/panel.inc index 4b60cfb82..f9c0de5d2 100644 --- a/kronolith/templates/panel.inc +++ b/kronolith/templates/panel.inc @@ -66,7 +66,7 @@ if ($cal->hasPermission(Horde_Auth::getAuth(), PERMS_EDIT)) { . Horde::img('delete-small.png', _("Remove Tag"), '', $registry->getImageDir('horde')) . ''; } -Kronolith_Imple::factory('TagActions', array('triggerId' => 'remove' . md5($id . $tag_id), +Horde_Ajax_Imple::getInstance(array('kronolith', 'TagActions'), array('triggerId' => 'remove' . md5($id . $tag_id), 'action' => 'delete', 'resource' => $id, 'type' => 'calendar', @@ -80,8 +80,8 @@ Kronolith_Imple::factory('TagActions', array('triggerId' => 'remove' . md5($id .
    'newtags-input_' . $id, 'id' => $id)); - Kronolith_Imple::factory('TagActions', array('triggerId' => 'newtags-button', + Horde_Ajax_Imple::getInstance(array('kronolith', 'TagAutoCompleter'), array('triggerId' => 'newtags-input_' . $id, 'id' => $id)); + Horde_Ajax_Imple::getInstance(array('kronolith', 'TagActions'), array('triggerId' => 'newtags-button', 'resource' => $id, 'type' => 'calendar', 'action' => 'add'));