+++ /dev/null
-<?php
-/**
- * @package Horde_Alarm
- *
- * Copyright 2007-2010 The Horde Project (http://www.horde.org/)
- *
- * See the enclosed file COPYING for license information (LGPL). If you
- * did not receive this file, see http://www.fsf.org/copyleft/lgpl.html.
- */
-
-/**
- * The Horde_Alarm:: class provides an interface to deal with reminders,
- * alarms and notifications through a standardized API.
- *
- * Alarm hashes have the following fields:
- * - id: Unique alarm id.
- * - user: The alarm's user. Empty if a global alarm.
- * - start: The alarm start as a Horde_Date.
- * - end: The alarm end as a Horde_Date.
- * - methods: The notification methods for this alarm.
- * - params: The paramters for the notification methods.
- * - title: The alarm title.
- * - text: An optional alarm description.
- * - snooze: The snooze time (next time) of the alarm as a Horde_Date.
- * - internal: Holds internally used data.
- *
- * @author Jan Schneider <jan@horde.org>
- * @package Horde_Alarm
- */
-class Horde_Alarm {
-
- /**
- * Hash containing connection parameters.
- *
- * @var array
- */
- var $_params = array('ttl' => 300);
-
- /**
- * An error message to throw when something is wrong.
- *
- * @var string
- */
- var $_errormsg;
-
- /**
- * Constructor - just store the $params in our newly-created object. All
- * other work is done by initialize().
- *
- * @param array $params Any parameters needed for this driver.
- */
- function Horde_Alarm($params = array(), $errormsg = null)
- {
- $this->_params = array_merge($this->_params, $params);
- if ($errormsg === null) {
- $this->_errormsg = _("The alarm backend is not currently available.");
- } else {
- $this->_errormsg = $errormsg;
- }
- }
-
- /**
- * Returns an alarm hash from the backend.
- *
- * @param string $id The alarm's unique id.
- * @param string $user The alarm's user
- *
- * @return array An alarm hash.
- */
- function get($id, $user)
- {
- $alarm = $this->_get($id, $user);
- if (is_a($alarm, 'PEAR_Error')) {
- return $alarm;
- }
- if (isset($alarm['mail']['body'])) {
- $alarm['mail']['body'] = $this->_fromDriver($alarm['mail']['body']);
- }
- return $alarm;
- }
-
- /**
- * Stores an alarm hash in the backend.
- *
- * The alarm will be added if it doesn't exist, and updated otherwise.
- *
- * @param array $alarm An alarm hash.
- */
- function set($alarm)
- {
- if (isset($alarm['mail']['body'])) {
- $alarm['mail']['body'] = $this->_toDriver($alarm['mail']['body']);
- }
- if ($this->exists($alarm['id'], isset($alarm['user']) ? $alarm['user'] : '')) {
- return $this->_update($alarm);
- } else {
- return $this->_add($alarm);
- }
- }
-
- /**
- * Returns whether an alarm with the given id exists already.
- *
- * @param string $id The alarm's unique id.
- * @param string $user The alarm's user
- *
- * @return boolean True if the specified alarm exists.
- */
- function exists($id, $user)
- {
- $exists = $this->_exists($id, $user);
- return $exists && !is_a($exists, 'PEAR_Error');
- }
-
- /**
- * Delays (snoozes) an alarm for a certain period.
- *
- * @param string $id The alarm's unique id.
- * @param string $user The notified user.
- * @param integer $minutes The delay in minutes. A negative value
- * dismisses the alarm completely.
- */
- function snooze($id, $user, $minutes)
- {
- $alarm = $this->get($id, $user);
- if (is_a($alarm, 'PEAR_Error')) {
- return $alarm;
- }
- if (empty($user)) {
- return PEAR::raiseError(_("This alarm cannot be snoozed."));
- }
- if ($alarm) {
- if ($minutes > 0) {
- $alarm['snooze'] = new Horde_Date(time());
- $alarm['snooze']->min += $minutes;
- return $this->_snooze($id, $user, $alarm['snooze']);
- } else {
- return $this->_dismiss($id, $user);
- }
- }
- }
-
- /**
- * Returns whether an alarm is snoozed.
- *
- * @param string $id The alarm's unique id.
- * @param string $user The alarm's user
- * @param Horde_Date $time The time when the alarm may be snoozed.
- * Defaults to now.
- *
- * @return boolean True if the alarm is snoozed.
- */
- function isSnoozed($id, $user, $time = null)
- {
- if (is_null($time)) {
- $time = new Horde_Date(time());
- }
- return (bool)$this->_isSnoozed($id, $user, $time);
- }
-
- /**
- * Deletes an alarm from the backend.
- *
- * @param string $id The alarm's unique id.
- * @param string $user The alarm's user. All users' alarms if null.
- */
- function delete($id, $user = null)
- {
- return $this->_delete($id, $user);
- }
-
- /**
- * Retrieves active alarms from all applications and stores them in the
- * backend.
- *
- * The applications will only be called once in the configured time span,
- * by default 5 minutes.
- *
- * @param string $user Retrieve alarms for this user, or for all users
- * if null.
- * @param boolean $preload Preload alarms that go off within the next
- * ttl time span?
- */
- function load($user = null, $preload = true)
- {
- if (isset($_SESSION['horde']['alarm']['loaded']) &&
- time() - $_SESSION['horde']['alarm']['loaded'] < $this->_params['ttl']) {
- return;
- }
-
- foreach ($GLOBALS['registry']->listApps(null, false, Horde_Perms::READ) as $app) {
- if (!$GLOBALS['registry']->hasMethod('listAlarms', $app)) {
- continue;
- }
-
- /* Preload alarms that happen in the next ttl seconds. */
- if ($preload) {
- try {
- $alarms = $GLOBALS['registry']->callByPackage($app, 'listAlarms', array(time() + $this->_params['ttl'], $user), array('noperms' => true));
- } catch (Horde_Exception $e) {
- continue;
- }
- } else {
- $alarms = array();
- }
-
- /* Load current alarms if no preloading requested or if this
- * is the first call in this session. */
- if (!$preload ||
- !isset($_SESSION['horde']['alarm']['loaded'])) {
- try {
- $app_alarms = $GLOBALS['registry']->callByPackage($app, 'listAlarms', array(time(), $user), array('noperms' => true));
- } catch (Horde_Exception $e) {
- Horde::logMessage($e, __FILE__, __LINE__, PEAR_LOG_ERR);
- $app_alarms = array();
- }
- $alarms = array_merge($alarms, $app_alarms);
- }
-
- foreach ($alarms as $alarm) {
- $this->set($alarm);
- }
- }
-
- $_SESSION['horde']['alarm']['loaded'] = time();
- }
-
- /**
- * Returns a list of alarms from the backend.
- *
- * @param string $user Return alarms for this user, all users if
- * null, or global alarms if empty.
- * @param Horde_Date $time The time when the alarms should be active.
- * Defaults to now.
- * @param boolean $load Update active alarms from all applications?
- * @param boolean $preload Preload alarms that go off within the next
- * ttl time span?
- *
- * @return array A list of alarm hashes.
- */
- function listAlarms($user = null, $time = null, $load = false,
- $preload = true)
- {
- if (empty($time)) {
- $time = new Horde_Date(time());
- }
- if ($load) {
- $this->load($user, $preload);
- }
-
- $alarms = $this->_list($user, $time);
- if (is_a($alarms, 'PEAR_Error')) {
- return $alarms;
- }
-
- foreach (array_keys($alarms) as $alarm) {
- if (isset($alarms[$alarm]['mail']['body'])) {
- $alarms[$alarm]['mail']['body'] = $this->_fromDriver($alarms[$alarm]['mail']['body']);
- }
- }
- return $alarms;
- }
-
- /**
- * Notifies the user about any active alarms.
- *
- * @param string $user Notify this user, all users if null, or guest
- * users if empty.
- * @param boolean $load Update active alarms from all applications?
- * @param boolean $preload Preload alarms that go off within the next
- * ttl time span?
- * @param array $exclude Don't notify with these methods.
- */
- function notify($user = null, $load = true, $preload = true,
- $exclude = array())
- {
- $alarms = $this->listAlarms($user, null, $load, $preload);
- if (is_a($alarms, 'PEAR_Error')) {
- Horde::logMessage($alarms, __FILE__, __LINE__, PEAR_LOG_ERR);
- return $alarms;
- }
- if (empty($alarms)) {
- return;
- }
-
- $methods = array_keys($this->notificationMethods());
- foreach ($alarms as $alarm) {
- foreach ($alarm['methods'] as $alarm_method) {
- if (in_array($alarm_method, $methods) &&
- !in_array($alarm_method, $exclude)) {
- $result = $this->{'_' . $alarm_method}($alarm);
- if (is_a($result, 'PEAR_Error')) {
- Horde::logMessage($result, __FILE__, __LINE__, PEAR_LOG_ERR);
- }
- }
- }
- }
- }
-
- /**
- * Notifies about an alarm through Horde_Notification.
- *
- * @param array $alarm An alarm hash.
- */
- function _notify($alarm)
- {
- static $sound_played;
-
- $GLOBALS['notification']->push($alarm['title'], 'horde.alarm', array('alarm' => $alarm));
- if (!empty($alarm['params']['notify']['sound']) &&
- !isset($sound_played[$alarm['params']['notify']['sound']])) {
- require_once 'Horde/Notification/Listener/Audio.php';
- $GLOBALS['notification']->attach('audio');
- $GLOBALS['notification']->push($alarm['params']['notify']['sound'], 'audio');
- $sound_played[$alarm['params']['notify']['sound']] = true;
- }
- }
-
- /**
- * Notifies about an alarm by email.
- *
- * @param array $alarm An alarm hash.
- */
- function _mail($alarm)
- {
- if (!empty($alarm['internal']['mail']['sent'])) {
- return;
- }
-
- if (empty($alarm['params']['mail']['email'])) {
- if (empty($alarm['user'])) {
- return;
- }
- $identity = Horde_Prefs_Identity::singleton('none', $alarm['user']);
- $email = $identity->getDefaultFromAddress(true);
- } else {
- $email = $alarm['params']['mail']['email'];
- }
-
- $mail = new Horde_Mime_Mail(array(
- 'subject' => $alarm['title'],
- 'body' => empty($alarm['params']['mail']['body']) ? $alarm['text'] : $alarm['params']['mail']['body'],
- 'to' => $email,
- 'from' => $email,
- 'charset' => Horde_Nls::getCharset()));
- $mail->addHeader('Auto-Submitted', 'auto-generated');
- $mail->addHeader('X-Horde-Alarm', $alarm['title'], Horde_Nls::getCharset());
- $sent = $mail->send(Horde::getMailerConfig());
- if (is_a($sent, 'PEAR_Error')) {
- return $sent;
- }
-
- $alarm['internal']['mail']['sent'] = true;
- $this->_internal($alarm['id'], $alarm['user'], $alarm['internal']);
- }
-
- /**
- * Notifies about an alarm with an SMS through the sms/send API method.
- *
- * @param array $alarm An alarm hash.
- */
- function _sms($alarm)
- {
- }
-
- /**
- * Returns a list of available notification methods and method parameters.
- *
- * The returned list is a hash with method names as the keys and
- * optionally associated parameters as values. The parameters are hashes
- * again with parameter names as keys and parameter information as
- * values. The parameter information is hash with the following keys:
- * 'desc' contains a parameter description; 'required' specifies whether
- * this parameter is required.
- *
- * @return array List of methods and parameters.
- */
- function notificationMethods()
- {
- static $methods;
-
- if (!isset($methods)) {
- $methods = array('notify' => array(
- '__desc' => _("Inline Notification"),
- 'sound' => array('type' => 'sound',
- 'desc' => _("Play a sound?"),
- 'required' => false)),
- 'mail' => array(
- '__desc' => _("Email Notification"),
- 'email' => array('type' => 'text',
- 'desc' => _("Email address (optional)"),
- 'required' => false)));
- /*
- if ($GLOBALS['registry']->hasMethod('sms/send')) {
- $methods['sms'] = array(
- 'phone' => array('type' => 'text',
- 'desc' => _("Cell phone number"),
- 'required' => true));
- }
- */
- }
-
- return $methods;
- }
-
- /**
- * Garbage collects old alarms in the backend.
- */
- function gc()
- {
- /* A 1% chance we will run garbage collection during a call. */
- if (rand(0, 99) != 0) {
- return;
- }
-
- return $this->_gc();
- }
-
- /**
- * Attempts to return a concrete Horde_Alarm instance based on $driver.
- *
- * @param string $driver The type of concrete Horde_Alarm subclass to
- * return. The class name is based on the storage
- * driver ($driver). The code is dynamically
- * included.
- * @param array $params A hash containing any additional configuration
- * or connection parameters a subclass might need.
- *
- * @return mixed The newly created concrete Horde_Alarm instance, or false
- * on an error.
- */
- static function factory($driver = null, $params = null)
- {
- if (is_null($driver)) {
- $driver = empty($GLOBALS['conf']['alarms']['driver']) ? 'sql' : $GLOBALS['conf']['alarms']['driver'];
- }
-
- $driver = basename($driver);
-
- if (is_null($params)) {
- $params = Horde::getDriverConfig('alarms', $driver);
- }
-
- $class = 'Horde_Alarm_' . $driver;
- if (class_exists($class)) {
- $alarm = new $class($params);
- $result = $alarm->initialize();
- if (is_a($result, 'PEAR_Error')) {
- $alarm = new Horde_Alarm($params, sprintf(_("The alarm backend is not currently available: %s"), $result->getMessage()));
- } else {
- $alarm->gc();
- }
- } else {
- $alarm = new Horde_Alarm($params, sprintf(_("Unable to load the definition of %s."), $class));
- }
-
- return $alarm;
- }
-
- /**
- * Converts a value from the driver's charset.
- *
- * @param mixed $value Value to convert.
- *
- * @return mixed Converted value.
- */
- function _fromDriver($value)
- {
- return $value;
- }
-
- /**
- * Converts a value to the driver's charset.
- *
- * @param mixed $value Value to convert.
- *
- * @return mixed Converted value.
- */
- function _toDriver($value)
- {
- return $value;
- }
-
- /**
- * @abstract
- */
- function _get()
- {
- return PEAR::raiseError($this->_errormsg);
- }
-
- /**
- * @abstract
- */
- function _list()
- {
- return PEAR::raiseError($this->_errormsg);
- }
-
- /**
- * @abstract
- */
- function _add()
- {
- return PEAR::raiseError($this->_errormsg);
- }
-
- /**
- * @abstract
- */
- function _update()
- {
- return PEAR::raiseError($this->_errormsg);
- }
-
- /**
- * @abstract
- */
- function _internal()
- {
- return PEAR::raiseError($this->_errormsg);
- }
-
- /**
- * @abstract
- */
- function _exists()
- {
- return PEAR::raiseError($this->_errormsg);
- }
-
- /**
- * @abstract
- */
- function _snooze()
- {
- return PEAR::raiseError($this->_errormsg);
- }
-
- /**
- * @abstract
- */
- function _isSnoozed()
- {
- return PEAR::raiseError($this->_errormsg);
- }
-
- /**
- * @abstract
- */
- function _delete()
- {
- return PEAR::raiseError($this->_errormsg);
- }
-
-}
+++ /dev/null
-<?php
-/**
- * @package Horde_Alarm
- *
- * Copyright 2007-2010 The Horde Project (http://www.horde.org/)
- *
- * See the enclosed file COPYING for license information (LGPL). If you
- * did not receive this file, see http://www.fsf.org/copyleft/lgpl.html.
- */
-
-/**
- * The Horde_Alarm_sql:: class is a Horde_Alarm storage implementation using
- * the PEAR DB package.
- *
- * Required values for $params:<pre>
- * 'phptype' The database type (e.g. 'pgsql', 'mysql', etc.).
- * 'charset' The database's internal charset.</pre>
- *
- * Optional values for $params:<pre>
- * 'table' The name of the foo table in 'database'.
- *
- * Required by some database implementations:<pre>
- * 'database' The name of the database.
- * 'hostspec' The hostname of the database server.
- * 'protocol' The communication protocol ('tcp', 'unix', etc.).
- * 'username' The username with which to connect to the database.
- * 'password' The password associated with 'username'.
- * 'options' Additional options to pass to the database.
- * 'tty' The TTY on which to connect to the database.
- * 'port' The port on which to connect to the database.</pre>
- *
- * The table structure can be created by the scripts/sql/horde_alarm.sql
- * script.
- *
- * @author Jan Schneider <jan@horde.org>
- * @package Horde_Alarm
- */
-class Horde_Alarm_sql extends Horde_Alarm {
-
- /**
- * Handle for the current database connection.
- *
- * @var DB
- */
- var $_db;
-
- /**
- * Handle for the current database connection, used for writing. Defaults
- * to the same handle as $_db if a separate write database is not required.
- *
- * @var DB
- */
- var $_write_db;
-
- /**
- * Constructs a new SQL storage object.
- *
- * @param array $params A hash containing connection parameters.
- */
- function Horde_Alarm_sql($params = array())
- {
- $this->_params = array_merge($this->_params, $params);
- }
-
- /**
- * Converts a value from the driver's charset.
- *
- * @param mixed $value Value to convert.
- *
- * @return mixed Converted value.
- */
- function _fromDriver($value)
- {
- return Horde_String::convertCharset($value, $this->_params['charset']);
- }
-
- /**
- * Converts a value to the driver's charset.
- *
- * @param mixed $value Value to convert.
- *
- * @return mixed Converted value.
- */
- function _toDriver($value)
- {
- return Horde_String::convertCharset($value, Horde_Nls::getCharset(), $this->_params['charset']);
- }
-
- /**
- * Returns an alarm hash from the backend.
- *
- * @param string $id The alarm's unique id.
- * @param string $user The alarm's user
- *
- * @return array An alarm hash.
- */
- function _get($id, $user)
- {
- $query = sprintf('SELECT alarm_id, alarm_uid, alarm_start, alarm_end, alarm_methods, alarm_params, alarm_title, alarm_text, alarm_snooze, alarm_internal FROM %s WHERE alarm_id = ? AND %s',
- $this->_params['table'],
- !empty($user) ? 'alarm_uid = ?' : '(alarm_uid = ? OR alarm_uid IS NULL)');
- Horde::logMessage('SQL query by Horde_Alarm_sql::_get(): ' . $query,
- __FILE__, __LINE__, PEAR_LOG_DEBUG);
- $alarm = $this->_db->getRow($query, array($id, $user), DB_FETCHMODE_ASSOC);
- if (is_a($alarm, 'PEAR_Error')) {
- Horde::logMessage($alarm, __FILE__, __LINE__);
- return $alarm;
- }
- if (empty($alarm)) {
- return PEAR::raiseError(_("Alarm not found"));
- }
- $alarm = array(
- 'id' => $alarm['alarm_id'],
- 'user' => $alarm['alarm_uid'],
- 'start' => new Horde_Date($alarm['alarm_start'], 'UTC'),
- 'end' => empty($alarm['alarm_end']) ? null : new Horde_Date($alarm['alarm_end'], 'UTC'),
- 'methods' => @unserialize($alarm['alarm_methods']),
- 'params' => @unserialize($alarm['alarm_params']),
- 'title' => $this->_fromDriver($alarm['alarm_title']),
- 'text' => $this->_fromDriver($alarm['alarm_text']),
- 'snooze' => empty($alarm['alarm_snooze']) ? null : new Horde_Date($alarm['alarm_snooze'], 'UTC'),
- 'internal' => empty($alarm['alarm_internal']) ? null : @unserialize($alarm['alarm_internal']));
- return $alarm;
- }
-
- /**
- * Returns a list of alarms from the backend.
- *
- * @param Horde_Date $time The time when the alarms should be active.
- * @param string $user Return alarms for this user, all users if
- * null, or global alarms if empty.
- *
- * @return array A list of alarm hashes.
- */
- function _list($user, $time)
- {
- $query = sprintf('SELECT alarm_id, alarm_uid, alarm_start, alarm_end, alarm_methods, alarm_params, alarm_title, alarm_text, alarm_snooze, alarm_internal FROM %s WHERE alarm_dismissed = 0 AND ((alarm_snooze IS NULL AND alarm_start <= ?) OR alarm_snooze <= ?) AND (alarm_end IS NULL OR alarm_end >= ?)%s ORDER BY alarm_start, alarm_end',
- $this->_params['table'],
- is_null($user) ? '' : ' AND (alarm_uid IS NULL OR alarm_uid = ? OR alarm_uid = ?)');
- $dt = $time->setTimezone('UTC')->format('Y-m-d\TH:i:s');
- $values = array($dt, $dt, $dt);
- if (!is_null($user)) {
- $values[] = '';
- $values[] = (string)$user;
- }
- Horde::logMessage('SQL query by Horde_Alarm_sql::_list(): ' . $query,
- __FILE__, __LINE__, PEAR_LOG_DEBUG);
-
- $alarms = array();
- $result = $this->_db->query($query, $values);
- if (is_a($result, 'PEAR_Error')) {
- Horde::logMessage($result, __FILE__, __LINE__);
- return $result;
- }
- while ($alarm = $result->fetchRow(DB_FETCHMODE_ASSOC)) {
- if (is_a($alarm, 'PEAR_Error')) {
- Horde::logMessage($alarm, __FILE__, __LINE__);
- return $alarm;
- }
- $alarms[] = array(
- 'id' => $alarm['alarm_id'],
- 'user' => $alarm['alarm_uid'],
- 'start' => new Horde_Date($alarm['alarm_start'], 'UTC'),
- 'end' => empty($alarm['alarm_end']) ? null : new Horde_Date($alarm['alarm_end'], 'UTC'),
- 'methods' => @unserialize($alarm['alarm_methods']),
- 'params' => @unserialize($alarm['alarm_params']),
- 'title' => $this->_fromDriver($alarm['alarm_title']),
- 'text' => $this->_fromDriver($alarm['alarm_text']),
- 'snooze' => empty($alarm['alarm_snooze']) ? null : new Horde_Date($alarm['alarm_snooze'], 'UTC'),
- 'internal' => empty($alarm['alarm_internal']) ? null : @unserialize($alarm['alarm_internal']));
- }
-
- return $alarms;
- }
-
- /**
- * Adds an alarm hash to the backend.
- *
- * @param array $alarm An alarm hash.
- */
- function _add($alarm)
- {
- $query = sprintf('INSERT INTO %s (alarm_id, alarm_uid, alarm_start, alarm_end, alarm_methods, alarm_params, alarm_title, alarm_text, alarm_snooze) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)', $this->_params['table']);
- $values = array($alarm['id'],
- isset($alarm['user']) ? $alarm['user'] : '',
- (string)$alarm['start']->setTimezone('UTC'),
- empty($alarm['end']) ? null : (string)$alarm['end']->setTimezone('UTC'),
- serialize($alarm['methods']),
- serialize($alarm['params']),
- $this->_toDriver($alarm['title']),
- empty($alarm['text']) ? null : $this->_toDriver($alarm['text']),
- null);
- Horde::logMessage('SQL query by Horde_Alarm_sql::_add(): ' . $query,
- __FILE__, __LINE__, PEAR_LOG_DEBUG);
- $result = $this->_write_db->query($query, $values);
- if (is_a($result, 'PEAR_Error')) {
- Horde::logMessage($result, __FILE__, __LINE__);
- }
- return $result;
- }
-
- /**
- * Updates an alarm hash in the backend.
- *
- * @param array $alarm An alarm hash.
- */
- function _update($alarm)
- {
- $query = sprintf('UPDATE %s set alarm_start = ?, alarm_end = ?, alarm_methods = ?, alarm_params = ?, alarm_title = ?, alarm_text = ? WHERE alarm_id = ? AND %s',
- $this->_params['table'],
- isset($alarm['user']) ? 'alarm_uid = ?' : '(alarm_uid = ? OR alarm_uid IS NULL)');
- $values = array((string)$alarm['start']->setTimezone('UTC'),
- empty($alarm['end']) ? null : (string)$alarm['end']->setTimezone('UTC'),
- serialize($alarm['methods']),
- serialize($alarm['params']),
- $this->_toDriver($alarm['title']),
- empty($alarm['text'])
- ? null
- : $this->_toDriver($alarm['text']),
- $alarm['id'],
- isset($alarm['user']) ? $alarm['user'] : '');
- Horde::logMessage('SQL query by Horde_Alarm_sql::_update(): ' . $query,
- __FILE__, __LINE__, PEAR_LOG_DEBUG);
- $result = $this->_write_db->query($query, $values);
- if (is_a($result, 'PEAR_Error')) {
- Horde::logMessage($result, __FILE__, __LINE__);
- }
- return $result;
- }
-
- /**
- * Updates internal alarm properties, i.e. properties not determined by
- * the application setting the alarm.
- *
- * @param string $id The alarm's unique id.
- * @param string $user The alarm's user
- * @param array $internal A hash with the internal data.
- */
- function _internal($id, $user, $internal)
- {
- $query = sprintf('UPDATE %s set alarm_internal = ? WHERE alarm_id = ? AND %s',
- $this->_params['table'],
- !empty($user) ? 'alarm_uid = ?' : '(alarm_uid = ? OR alarm_uid IS NULL)');
- $values = array(serialize($internal), $id, $user);
- Horde::logMessage('SQL query by Horde_Alarm_sql::_internal(): ' . $query,
- __FILE__, __LINE__, PEAR_LOG_DEBUG);
- $result = $this->_write_db->query($query, $values);
- if (is_a($result, 'PEAR_Error')) {
- Horde::logMessage($result, __FILE__, __LINE__);
- }
- return $result;
- }
-
- /**
- * Returns whether an alarm with the given id exists already.
- *
- * @param string $id The alarm's unique id.
- * @param string $user The alarm's user
- *
- * @return boolean True if the specified alarm exists.
- */
- function _exists($id, $user)
- {
- $query = sprintf('SELECT 1 FROM %s WHERE alarm_id = ? AND %s',
- $this->_params['table'],
- !empty($user) ? 'alarm_uid = ?' : '(alarm_uid = ? OR alarm_uid IS NULL)');
- Horde::logMessage('SQL query by Horde_Alarm_sql::_exists(): ' . $query,
- __FILE__, __LINE__, PEAR_LOG_DEBUG);
- $result = $this->_db->getOne($query, array($id, $user));
- if (is_a($result, 'PEAR_Error')) {
- Horde::logMessage($result, __FILE__, __LINE__);
- }
- return $result;
- }
-
- /**
- * Delays (snoozes) an alarm for a certain period.
- *
- * @param string $id The alarm's unique id.
- * @param string $user The alarm's user
- * @param Horde_Date $snooze The snooze time.
- */
- function _snooze($id, $user, $snooze)
- {
- $query = sprintf('UPDATE %s set alarm_snooze = ? WHERE alarm_id = ? AND %s',
- $this->_params['table'],
- !empty($user) ? 'alarm_uid = ?' : '(alarm_uid = ? OR alarm_uid IS NULL)');
- $values = array((string)$snooze->setTimezone('UTC'), $id, $user);
- Horde::logMessage('SQL query by Horde_Alarm_sql::_snooze(): ' . $query,
- __FILE__, __LINE__, PEAR_LOG_DEBUG);
- $result = $this->_write_db->query($query, $values);
- if (is_a($result, 'PEAR_Error')) {
- Horde::logMessage($result, __FILE__, __LINE__);
- }
- return $result;
- }
-
- /**
- * Dismisses an alarm.
- *
- * @param string $id The alarm's unique id.
- * @param string $user The alarm's user
- */
- function _dismiss($id, $user)
- {
- $query = sprintf('UPDATE %s set alarm_dismissed = 1 WHERE alarm_id = ? AND %s',
- $this->_params['table'],
- !empty($user) ? 'alarm_uid = ?' : '(alarm_uid = ? OR alarm_uid IS NULL)');
- $values = array($id, $user);
- Horde::logMessage('SQL query by Horde_Alarm_sql::_dismiss(): ' . $query,
- __FILE__, __LINE__, PEAR_LOG_DEBUG);
- $result = $this->_write_db->query($query, $values);
- if (is_a($result, 'PEAR_Error')) {
- Horde::logMessage($result, __FILE__, __LINE__);
- }
- return $result;
- }
-
- /**
- * Returns whether an alarm is snoozed.
- *
- * @param string $id The alarm's unique id.
- * @param string $user The alarm's user
- * @param Horde_Date $time The time when the alarm may be snoozed.
- *
- * @return boolean True if the alarm is snoozed.
- */
- function _isSnoozed($id, $user, $time)
- {
- $query = sprintf('SELECT 1 FROM %s WHERE alarm_id = ? AND %s AND (alarm_dismissed = 1 OR (alarm_snooze IS NOT NULL AND alarm_snooze >= ?))',
- $this->_params['table'],
- !empty($user) ? 'alarm_uid = ?' : '(alarm_uid = ? OR alarm_uid IS NULL)');
- Horde::logMessage('SQL query by Horde_Alarm_sql::_isSnoozed(): ' . $query,
- __FILE__, __LINE__, PEAR_LOG_DEBUG);
- $result = $this->_db->getOne($query, array($id, $user, (string)$time->setTimezone('UTC')));
- if (is_a($result, 'PEAR_Error')) {
- Horde::logMessage($result, __FILE__, __LINE__);
- }
- return $result;
- }
-
- /**
- * Deletes an alarm from the backend.
- *
- * @param string $id The alarm's unique id.
- * @param string $user The alarm's user. All users' alarms if null.
- */
- function _delete($id, $user = null)
- {
- $query = sprintf('DELETE FROM %s WHERE alarm_id = ?', $this->_params['table']);
- $values = array($id);
- if (!is_null($user)) {
- $query .= empty($user)
- ? ' AND (alarm_uid IS NULL OR alarm_uid = ?)'
- : ' AND alarm_uid = ?';
- $values[] = $user;
- }
- Horde::logMessage('SQL query by Horde_Alarm_sql::_delete(): ' . $query,
- __FILE__, __LINE__, PEAR_LOG_DEBUG);
- $result = $this->_write_db->query($query, $values);
- if (is_a($result, 'PEAR_Error')) {
- Horde::logMessage($result, __FILE__, __LINE__);
- }
- return $result;
- }
-
- /**
- * Garbage collects old alarms in the backend.
- */
- function _gc()
- {
- $query = sprintf('DELETE FROM %s WHERE alarm_end IS NOT NULL AND alarm_end < ?', $this->_params['table']);
- Horde::logMessage('SQL query by Horde_Alarm_sql::_gc(): ' . $query,
- __FILE__, __LINE__, PEAR_LOG_DEBUG);
- $end = new Horde_Date(time());
- $result = $this->_write_db->query($query, (string)$end->setTimezone('UTC'));
- if (is_a($result, 'PEAR_Error')) {
- Horde::logMessage($result, __FILE__, __LINE__);
- }
- return $result;
- }
-
- /**
- * Attempts to open a connection to the SQL server.
- *
- * @return boolean True on success, PEAR_Error on failure.
- */
- function initialize()
- {
- Horde::assertDriverConfig($this->_params, 'sql',
- array('phptype', 'charset'));
-
- if (!isset($this->_params['database'])) {
- $this->_params['database'] = '';
- }
- if (!isset($this->_params['username'])) {
- $this->_params['username'] = '';
- }
- if (!isset($this->_params['hostspec'])) {
- $this->_params['hostspec'] = '';
- }
- if (!isset($this->_params['table'])) {
- $this->_params['table'] = 'horde_alarms';
- }
-
- /* Connect to the SQL server using the supplied parameters. */
- require_once 'DB.php';
- $this->_write_db = &DB::connect($this->_params,
- array('persistent' => !empty($this->_params['persistent']),
- 'ssl' => !empty($this->_params['ssl'])));
- if (is_a($this->_write_db, 'PEAR_Error')) {
- Horde::logMessage($this->_write_db, __FILE__, __LINE__);
- return $this->_write_db;
- }
- $this->_initConn($this->_write_db);
-
- /* Check if we need to set up the read DB connection seperately. */
- if (!empty($this->_params['splitread'])) {
- $params = array_merge($this->_params, $this->_params['read']);
- $this->_db = &DB::connect($params,
- array('persistent' => !empty($params['persistent']),
- 'ssl' => !empty($params['ssl'])));
- if (is_a($this->_db, 'PEAR_Error')) {
- Horde::logMessage($this->_db, __FILE__, __LINE__);
- return $this->_db;
- }
- $this->_initConn($this->_db);
- } else {
- /* Default to the same DB handle for the writer too. */
- $this->_db = &$this->_write_db;
- }
-
- return true;
- }
-
- /**
- */
- function _initConn(&$db)
- {
- // Set DB portability options.
- switch ($db->phptype) {
- case 'mssql':
- $db->setOption('portability', DB_PORTABILITY_LOWERCASE | DB_PORTABILITY_ERRORS | DB_PORTABILITY_RTRIM);
- break;
-
- default:
- $db->setOption('portability', DB_PORTABILITY_LOWERCASE | DB_PORTABILITY_ERRORS);
- }
-
- /* Handle any database specific initialization code to run. */
- switch ($db->dbsyntax) {
- case 'oci8':
- $query = "ALTER SESSION SET NLS_DATE_FORMAT = 'YYYY-MM-DD HH24:MI:SS'";
-
- /* Log the query at a DEBUG log level. */
- Horde::logMessage(sprintf('SQL connection setup for Alarms, query = "%s"', $query),
- __FILE__, __LINE__, PEAR_LOG_DEBUG);
-
- $db->query($query);
- break;
-
- case 'pgsql':
- $query = "SET datestyle TO 'iso'";
-
- /* Log the query at a DEBUG log level. */
- Horde::logMessage(sprintf('SQL connection setup for Alarms, query = "%s"', $query),
- __FILE__, __LINE__, PEAR_LOG_DEBUG);
-
- $db->query($query);
- break;
- }
- }
-
-}
--- /dev/null
+<?php
+/**
+ * @package Horde_Alarm
+ *
+ * Copyright 2007-2010 The Horde Project (http://www.horde.org/)
+ *
+ * See the enclosed file COPYING for license information (LGPL). If you
+ * did not receive this file, see http://www.fsf.org/copyleft/lgpl.html.
+ */
+
+/**
+ * The Horde_Alarm:: class provides an interface to deal with reminders,
+ * alarms and notifications through a standardized API.
+ *
+ * @author Jan Schneider <jan@horde.org>
+ * @package Horde_Alarm
+ */
+class Horde_Alarm
+{
+ /**
+ * Hash containing connection parameters.
+ *
+ * @var array
+ */
+ protected $_params = array('ttl' => 300);
+
+ /**
+ * Attempts to return a concrete instance based on $driver.
+ *
+ * @param string $driver The type of concrete subclass to
+ * return. The class name is based on the storage
+ * driver ($driver). The code is dynamically
+ * included.
+ * @param array $params A hash containing any additional configuration
+ * or connection parameters a subclass might need.
+ *
+ * @return Horde_Alarm The newly created concrete instance.
+ * @throws Horde_Alarm_Exception
+ */
+ static public function factory($driver = null, $params = null)
+ {
+ if (is_null($driver)) {
+ $driver = empty($GLOBALS['conf']['alarms']['driver'])
+ ? 'sql'
+ : $GLOBALS['conf']['alarms']['driver'];
+ }
+
+ $driver = ucfirst(basename($driver));
+
+ if (is_null($params)) {
+ $params = Horde::getDriverConfig('alarms', $driver);
+ }
+
+ $class = __CLASS__ . '_' . $driver;
+
+ if (class_exists($class)) {
+ $alarm = new $class($params);
+ $alarm->initialize();
+ $alarm->gc();
+ return $alarm;
+ }
+
+ throw new Horde_Alarm_Exception('Could not find driver.');
+ }
+
+ /**
+ * Constructor.
+ *
+ * @param array $params Any parameters needed for this driver.
+ */
+ public function __construct($params = array())
+ {
+ $this->_params = array_merge($this->_params, $params);
+ }
+
+ /**
+ * Returns an alarm hash from the backend.
+ *
+ * @param string $id The alarm's unique id.
+ * @param string $user The alarm's user
+ *
+ * @return array An alarm hash. Contains the following:
+ * <pre>
+ * id: Unique alarm id.
+ * user: The alarm's user. Empty if a global alarm.
+ * start: The alarm start as a Horde_Date.
+ * end: The alarm end as a Horde_Date.
+ * methods: The notification methods for this alarm.
+ * params: The paramters for the notification methods.
+ * title: The alarm title.
+ * text: An optional alarm description.
+ * snooze: The snooze time (next time) of the alarm as a Horde_Date.
+ * internal: Holds internally used data.
+ * </pre>
+ * @throws Horde_Alarm_Exception
+ */
+ public function get($id, $user)
+ {
+ $alarm = $this->_get($id, $user);
+
+ if (isset($alarm['mail']['body'])) {
+ $alarm['mail']['body'] = $this->_fromDriver($alarm['mail']['body']);
+ }
+
+ return $alarm;
+ }
+
+ /**
+ * @throws new Horde_Alarm_Exception
+ */
+ protected function _get()
+ {
+ }
+
+ /**
+ * Stores an alarm hash in the backend.
+ *
+ * The alarm will be added if it doesn't exist, and updated otherwise.
+ *
+ * @param array $alarm An alarm hash. See self::get() for format.
+ *
+ * @return TODO
+ */
+ public function set($alarm)
+ {
+ if (isset($alarm['mail']['body'])) {
+ $alarm['mail']['body'] = $this->_toDriver($alarm['mail']['body']);
+ }
+
+ return $this->exists($alarm['id'], isset($alarm['user']) ? $alarm['user'] : '')
+ ? $this->_update($alarm)
+ : $this->_add($alarm);
+ }
+
+ /**
+ * @throws new Horde_Alarm_Exception
+ */
+ protected function _update()
+ {
+ }
+
+ /**
+ * @throws new Horde_Alarm_Exception
+ */
+ protected function _add()
+ {
+ }
+
+ /**
+ * Returns whether an alarm with the given id exists already.
+ *
+ * @param string $id The alarm's unique id.
+ * @param string $user The alarm's user
+ *
+ * @return boolean True if the specified alarm exists.
+ */
+ public function exists($id, $user)
+ {
+ try {
+ return $this->_exists($id, $user);
+ } catch (Horde_Alarm_Exception $e) {
+ return false;
+ }
+ }
+
+ /**
+ * @throws Horde_Alarm_Exception
+ */
+ protected function _exists()
+ {
+ }
+
+ /**
+ * Delays (snoozes) an alarm for a certain period.
+ *
+ * @param string $id The alarm's unique id.
+ * @param string $user The notified user.
+ * @param integer $minutes The delay in minutes. A negative value
+ * dismisses the alarm completely.
+ *
+ * @return TODO
+ * @throws Horde_Alarm_Exception
+ */
+ public function snooze($id, $user, $minutes)
+ {
+ if (empty($user)) {
+ throw new Horde_Alarm_Exception('This alarm cannot be snoozed.');
+ }
+
+ $alarm = $this->get($id, $user);
+
+ if ($alarm) {
+ if ($minutes > 0) {
+ $alarm['snooze'] = new Horde_Date(time());
+ $alarm['snooze']->min += $minutes;
+ return $this->_snooze($id, $user, $alarm['snooze']);
+ }
+
+ return $this->_dismiss($id, $user);
+ }
+ }
+
+ /**
+ * @throws new Horde_Alarm_Exception
+ */
+ protected function _snooze()
+ {
+ }
+
+ /**
+ * @throws new Horde_Alarm_Exception
+ */
+ protected function _dismiss()
+ {
+ }
+
+ /**
+ * Returns whether an alarm is snoozed.
+ *
+ * @param string $id The alarm's unique id.
+ * @param string $user The alarm's user
+ * @param Horde_Date $time The time when the alarm may be snoozed.
+ * Defaults to now.
+ *
+ * @return boolean True if the alarm is snoozed.
+ */
+ public function isSnoozed($id, $user, $time = null)
+ {
+ if (is_null($time)) {
+ $time = new Horde_Date(time());
+ }
+ return (bool)$this->_isSnoozed($id, $user, $time);
+ }
+
+ /**
+ * @throws new Horde_Alarm_Exception
+ */
+ protected function _isSnoozed()
+ {
+ }
+
+ /**
+ * Deletes an alarm from the backend.
+ *
+ * @param string $id The alarm's unique id.
+ * @param string $user The alarm's user. All users' alarms if null.
+ */
+ function delete($id, $user = null)
+ {
+ return $this->_delete($id, $user);
+ }
+
+ /**
+ * @throws new Horde_Alarm_Exception
+ */
+ protected function _delete()
+ {
+ }
+
+ /**
+ * Retrieves active alarms from all applications and stores them in the
+ * backend.
+ *
+ * The applications will only be called once in the configured time span,
+ * by default 5 minutes.
+ *
+ * @param string $user Retrieve alarms for this user, or for all users
+ * if null.
+ * @param boolean $preload Preload alarms that go off within the next
+ * ttl time span?
+ */
+ public function load($user = null, $preload = true)
+ {
+ if (isset($_SESSION['horde']['alarm']['loaded']) &&
+ (time() - $_SESSION['horde']['alarm']['loaded']) < $this->_params['ttl']) {
+ return;
+ }
+
+ foreach ($GLOBALS['registry']->listApps(null, false, Horde_Perms::READ) as $app) {
+ if (!$GLOBALS['registry']->hasMethod('listAlarms', $app)) {
+ continue;
+ }
+
+ /* Preload alarms that happen in the next ttl seconds. */
+ if ($preload) {
+ try {
+ $alarms = $GLOBALS['registry']->callByPackage($app, 'listAlarms', array(time() + $this->_params['ttl'], $user), array('noperms' => true));
+ } catch (Horde_Exception $e) {
+ continue;
+ }
+ } else {
+ $alarms = array();
+ }
+
+ /* Load current alarms if no preloading requested or if this
+ * is the first call in this session. */
+ if (!$preload ||
+ !isset($_SESSION['horde']['alarm']['loaded'])) {
+ try {
+ $app_alarms = $GLOBALS['registry']->callByPackage($app, 'listAlarms', array(time(), $user), array('noperms' => true));
+ } catch (Horde_Exception $e) {
+ Horde::logMessage($e, __FILE__, __LINE__, PEAR_LOG_ERR);
+ $app_alarms = array();
+ }
+ $alarms = array_merge($alarms, $app_alarms);
+ }
+
+ foreach ($alarms as $alarm) {
+ $this->set($alarm);
+ }
+ }
+
+ $_SESSION['horde']['alarm']['loaded'] = time();
+ }
+
+ /**
+ * Returns a list of alarms from the backend.
+ *
+ * @param string $user Return alarms for this user, all users if
+ * null, or global alarms if empty.
+ * @param Horde_Date $time The time when the alarms should be active.
+ * Defaults to now.
+ * @param boolean $load Update active alarms from all applications?
+ * @param boolean $preload Preload alarms that go off within the next
+ * ttl time span?
+ *
+ * @return array A list of alarm hashes.
+ * @throws Horde_Alarm_Exception
+ */
+ public function listAlarms($user = null, $time = null, $load = false,
+ $preload = true)
+ {
+ if (empty($time)) {
+ $time = new Horde_Date(time());
+ }
+ if ($load) {
+ $this->load($user, $preload);
+ }
+
+ $alarms = $this->_list($user, $time);
+
+ foreach (array_keys($alarms) as $alarm) {
+ if (isset($alarms[$alarm]['mail']['body'])) {
+ $alarms[$alarm]['mail']['body'] = $this->_fromDriver($alarms[$alarm]['mail']['body']);
+ }
+ }
+ return $alarms;
+ }
+
+ /**
+ * @throws new Horde_Alarm_Exception
+ */
+ protected function _list()
+ {
+ }
+
+ /**
+ * Notifies the user about any active alarms.
+ *
+ * @param string $user Notify this user, all users if null, or guest
+ * users if empty.
+ * @param boolean $load Update active alarms from all applications?
+ * @param boolean $preload Preload alarms that go off within the next
+ * ttl time span?
+ * @param array $exclude Don't notify with these methods.
+ *
+ * @throws Horde_Alarm_Exception
+ */
+ public function notify($user = null, $load = true, $preload = true,
+ $exclude = array())
+ {
+ try {
+ $alarms = $this->listAlarms($user, null, $load, $preload);
+ } catch (Horde_Alarm_Exception $e) {
+ Horde::logMessage($e, __FILE__, __LINE__, PEAR_LOG_ERR);
+ throw $e;
+ }
+
+ if (empty($alarms)) {
+ return;
+ }
+
+ $methods = array_keys($this->notificationMethods());
+ foreach ($alarms as $alarm) {
+ foreach ($alarm['methods'] as $alarm_method) {
+ if (in_array($alarm_method, $methods) &&
+ !in_array($alarm_method, $exclude)) {
+ try {
+ $result = $this->{'_' . $alarm_method}($alarm);
+ } catch (Horde_Alarm_Exception $e) {
+ Horde::logMessage($e, __FILE__, __LINE__, PEAR_LOG_ERR);
+ }
+ }
+ }
+ }
+ }
+
+ /**
+ * Notifies about an alarm through Horde_Notification.
+ *
+ * @param array $alarm An alarm hash.
+ */
+ protected function _notify($alarm)
+ {
+ static $sound_played;
+
+ $GLOBALS['notification']->push($alarm['title'], 'horde.alarm', array('alarm' => $alarm));
+ if (!empty($alarm['params']['notify']['sound']) &&
+ !isset($sound_played[$alarm['params']['notify']['sound']])) {
+ $GLOBALS['notification']->attach('audio');
+ $GLOBALS['notification']->push($alarm['params']['notify']['sound'], 'audio');
+ $sound_played[$alarm['params']['notify']['sound']] = true;
+ }
+ }
+
+ /**
+ * Notifies about an alarm by email.
+ *
+ * @param array $alarm An alarm hash.
+ *
+ * @throws Horde_Mime_Exception
+ */
+ protected function _mail($alarm)
+ {
+ if (!empty($alarm['internal']['mail']['sent'])) {
+ return;
+ }
+
+ if (empty($alarm['params']['mail']['email'])) {
+ if (empty($alarm['user'])) {
+ return;
+ }
+ $identity = Horde_Prefs_Identity::singleton('none', $alarm['user']);
+ $email = $identity->getDefaultFromAddress(true);
+ } else {
+ $email = $alarm['params']['mail']['email'];
+ }
+
+ $mail = new Horde_Mime_Mail(array(
+ 'subject' => $alarm['title'],
+ 'body' => empty($alarm['params']['mail']['body']) ? $alarm['text'] : $alarm['params']['mail']['body'],
+ 'to' => $email,
+ 'from' => $email,
+ 'charset' => Horde_Nls::getCharset()
+ ));
+ $mail->addHeader('Auto-Submitted', 'auto-generated');
+ $mail->addHeader('X-Horde-Alarm', $alarm['title'], Horde_Nls::getCharset());
+ $sent = $mail->send(Horde::getMailerConfig());
+
+ $alarm['internal']['mail']['sent'] = true;
+ $this->_internal($alarm['id'], $alarm['user'], $alarm['internal']);
+ }
+
+ /**
+ * @throws new Horde_Alarm_Exception
+ */
+ protected function _internal()
+ {
+ }
+
+ /**
+ * Notifies about an alarm with an SMS through the sms/send API method.
+ *
+ * @param array $alarm An alarm hash.
+ */
+ protected function _sms($alarm)
+ {
+ }
+
+ /**
+ * Returns a list of available notification methods and method parameters.
+ *
+ * The returned list is a hash with method names as the keys and
+ * optionally associated parameters as values. The parameters are hashes
+ * again with parameter names as keys and parameter information as
+ * values. The parameter information is hash with the following keys:
+ * 'desc' contains a parameter description; 'required' specifies whether
+ * this parameter is required.
+ *
+ * @return array List of methods and parameters.
+ */
+ public function notificationMethods()
+ {
+ static $methods;
+
+ if (!isset($methods)) {
+ $methods = array(
+ 'notify' => array(
+ '__desc' => _("Inline Notification"),
+ 'sound' => array(
+ 'type' => 'sound',
+ 'desc' => _("Play a sound?"),
+ 'required' => false
+ )
+ ),
+ 'mail' => array(
+ '__desc' => _("Email Notification"),
+ 'email' => array(
+ 'type' => 'text',
+ 'desc' => _("Email address (optional)"),
+ 'required' => false
+ )
+ )
+ );
+ /*
+ if ($GLOBALS['registry']->hasMethod('sms/send')) {
+ $methods['sms'] = array(
+ 'phone' => array('type' => 'text',
+ 'desc' => _("Cell phone number"),
+ 'required' => true));
+ }
+ */
+ }
+
+ return $methods;
+ }
+
+ /**
+ * Garbage collects old alarms in the backend.
+ */
+ public function gc()
+ {
+ /* A 1% chance we will run garbage collection during a call. */
+ if (rand(0, 99) == 0) {
+ return $this->_gc();
+ }
+ }
+
+ /**
+ * Converts a value from the driver's charset.
+ *
+ * @param mixed $value Value to convert.
+ *
+ * @return mixed Converted value.
+ */
+ protected function _fromDriver($value)
+ {
+ return $value;
+ }
+
+ /**
+ * Converts a value to the driver's charset.
+ *
+ * @param mixed $value Value to convert.
+ *
+ * @return mixed Converted value.
+ */
+ protected function _toDriver($value)
+ {
+ return $value;
+ }
+
+}
--- /dev/null
+<?php
+/**
+ * Exception handler for the Horde_Alarm class.
+ *
+ * Copyright 2010 The Horde Project (http://www.horde.org/)
+ *
+ * See the enclosed file COPYING for license information (LGPL). If you
+ * did not receive this file, see http://www.fsf.org/copyleft/lgpl.html.
+ *
+ * @author Michael Slusarz <slusarz@horde.org>
+ * @category Horde
+ * @package Horde_Alarm
+ */
+class Horde_Alarm_Exception extends Horde_Exception_Prior
+{
+}
--- /dev/null
+<?php
+/**
+ * @package Horde_Alarm
+ *
+ * Copyright 2007-2010 The Horde Project (http://www.horde.org/)
+ *
+ * See the enclosed file COPYING for license information (LGPL). If you
+ * did not receive this file, see http://www.fsf.org/copyleft/lgpl.html.
+ */
+
+/**
+ * The Horde_Alarm_sql:: class is a Horde_Alarm storage implementation using
+ * the PEAR DB package.
+ *
+ * Required values for $params:<pre>
+ * 'phptype' - (string) The database type (e.g. 'pgsql', 'mysql', etc.).
+ * 'charset' - (string) The database's internal charset.</pre>
+ *
+ * Optional values for $params:<pre>
+ * 'table' - (string) The name of the foo table in 'database'.
+ *
+ * Required by some database implementations:<pre>
+ * 'database' - The name of the database.
+ * 'hostspec' - The hostname of the database server.
+ * 'protocol' - The communication protocol ('tcp', 'unix', etc.).
+ * 'username' - The username with which to connect to the database.
+ * 'password' - The password associated with 'username'.
+ * 'options' - Additional options to pass to the database.
+ * 'tty' - The TTY on which to connect to the database.
+ * 'port' - The port on which to connect to the database.</pre>
+ *
+ * The table structure can be created by the
+ * horde/scripts/sql/horde_alarm.sql script.
+ *
+ * @author Jan Schneider <jan@horde.org>
+ * @package Horde_Alarm
+ */
+class Horde_Alarm_Sql extends Horde_Alarm
+{
+ /**
+ * Handle for the current database connection.
+ *
+ * @var DB
+ */
+ protected $_db;
+
+ /**
+ * Handle for the current database connection, used for writing. Defaults
+ * to the same handle as $_db if a separate write database is not required.
+ *
+ * @var DB
+ */
+ protected $_write_db;
+
+ /**
+ * Converts a value from the driver's charset.
+ *
+ * @param mixed $value Value to convert.
+ *
+ * @return mixed Converted value.
+ */
+ protected function _fromDriver($value)
+ {
+ return Horde_String::convertCharset($value, $this->_params['charset']);
+ }
+
+ /**
+ * Converts a value to the driver's charset.
+ *
+ * @param mixed $value Value to convert.
+ *
+ * @return mixed Converted value.
+ */
+ protected function _toDriver($value)
+ {
+ return Horde_String::convertCharset($value, Horde_Nls::getCharset(), $this->_params['charset']);
+ }
+
+ /**
+ * Returns an alarm hash from the backend.
+ *
+ * @param string $id The alarm's unique id.
+ * @param string $user The alarm's user
+ *
+ * @return array An alarm hash.
+ */
+ protected function _get($id, $user)
+ {
+ $query = sprintf('SELECT alarm_id, alarm_uid, alarm_start, alarm_end, alarm_methods, alarm_params, alarm_title, alarm_text, alarm_snooze, alarm_internal FROM %s WHERE alarm_id = ? AND %s',
+ $this->_params['table'],
+ !empty($user) ? 'alarm_uid = ?' : '(alarm_uid = ? OR alarm_uid IS NULL)');
+ Horde::logMessage('SQL query by Horde_Alarm_sql::_get(): ' . $query,
+ __FILE__, __LINE__, PEAR_LOG_DEBUG);
+ $alarm = $this->_db->getRow($query, array($id, $user), DB_FETCHMODE_ASSOC);
+ if ($alarm instanceof PEAR_Error) {
+ Horde::logMessage($alarm, __FILE__, __LINE__);
+ throw new Horde_Alarm_Exception($alarm);
+ }
+
+ if (empty($alarm)) {
+ throw new Horde_Alarm_Exception('Alarm not found');
+ }
+
+ return $this->_getHash($alarm);
+ }
+
+ /**
+ * Returns a list of alarms from the backend.
+ *
+ * @param Horde_Date $time The time when the alarms should be active.
+ * @param string $user Return alarms for this user, all users if
+ * null, or global alarms if empty.
+ *
+ * @return array A list of alarm hashes.
+ */
+ protected function _list($user, $time)
+ {
+ $query = sprintf('SELECT alarm_id, alarm_uid, alarm_start, alarm_end, alarm_methods, alarm_params, alarm_title, alarm_text, alarm_snooze, alarm_internal FROM %s WHERE alarm_dismissed = 0 AND ((alarm_snooze IS NULL AND alarm_start <= ?) OR alarm_snooze <= ?) AND (alarm_end IS NULL OR alarm_end >= ?)%s ORDER BY alarm_start, alarm_end',
+ $this->_params['table'],
+ is_null($user) ? '' : ' AND (alarm_uid IS NULL OR alarm_uid = ? OR alarm_uid = ?)');
+ $dt = $time->setTimezone('UTC')->format('Y-m-d\TH:i:s');
+ $values = array($dt, $dt, $dt);
+ if (!is_null($user)) {
+ $values[] = '';
+ $values[] = (string)$user;
+ }
+ Horde::logMessage('SQL query by Horde_Alarm_sql::_list(): ' . $query,
+ __FILE__, __LINE__, PEAR_LOG_DEBUG);
+
+ $alarms = array();
+ $result = $this->_db->query($query, $values);
+ if ($result instanceof PEAR_Error) {
+ Horde::logMessage($result, __FILE__, __LINE__);
+ throw new Horde_Alarm_Exception($result);
+ }
+
+ while ($alarm = $result->fetchRow(DB_FETCHMODE_ASSOC)) {
+ if ($alarm instanceof PEAR_Error) {
+ Horde::logMessage($alarm, __FILE__, __LINE__);
+ throw new Horde_Alarm_Exception($alarm);
+ }
+
+ $alarms[] = $this->_getHash($alarm);
+ }
+
+ return $alarms;
+ }
+
+ /**
+ */
+ protected function _getHash($alarm)
+ {
+ return array(
+ 'id' => $alarm['alarm_id'],
+ 'user' => $alarm['alarm_uid'],
+ 'start' => new Horde_Date($alarm['alarm_start'], 'UTC'),
+ 'end' => empty($alarm['alarm_end']) ? null : new Horde_Date($alarm['alarm_end'], 'UTC'),
+ 'methods' => @unserialize($alarm['alarm_methods']),
+ 'params' => @unserialize($alarm['alarm_params']),
+ 'title' => $this->_fromDriver($alarm['alarm_title']),
+ 'text' => $this->_fromDriver($alarm['alarm_text']),
+ 'snooze' => empty($alarm['alarm_snooze']) ? null : new Horde_Date($alarm['alarm_snooze'], 'UTC'),
+ 'internal' => empty($alarm['alarm_internal']) ? null : @unserialize($alarm['alarm_internal'])
+ );
+ }
+
+ /**
+ * Adds an alarm hash to the backend.
+ *
+ * @param array $alarm An alarm hash.
+ */
+ protected function _add($alarm)
+ {
+ $query = sprintf('INSERT INTO %s (alarm_id, alarm_uid, alarm_start, alarm_end, alarm_methods, alarm_params, alarm_title, alarm_text, alarm_snooze) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)', $this->_params['table']);
+ $values = array(
+ $alarm['id'],
+ isset($alarm['user']) ? $alarm['user'] : '',
+ (string)$alarm['start']->setTimezone('UTC'),
+ empty($alarm['end']) ? null : (string)$alarm['end']->setTimezone('UTC'),
+ serialize($alarm['methods']),
+ serialize($alarm['params']),
+ $this->_toDriver($alarm['title']),
+ empty($alarm['text']) ? null : $this->_toDriver($alarm['text']),
+ null
+ );
+ Horde::logMessage('SQL query by Horde_Alarm_sql::_add(): ' . $query,
+ __FILE__, __LINE__, PEAR_LOG_DEBUG);
+
+ $result = $this->_write_db->query($query, $values);
+ if ($result instanceof PEAR_Error) {
+ Horde::logMessage($result, __FILE__, __LINE__);
+ throw new Horde_Alarm_Exception($result);
+ }
+
+ return $result;
+ }
+
+ /**
+ * Updates an alarm hash in the backend.
+ *
+ * @param array $alarm An alarm hash.
+ */
+ protected function _update($alarm)
+ {
+ $query = sprintf('UPDATE %s set alarm_start = ?, alarm_end = ?, alarm_methods = ?, alarm_params = ?, alarm_title = ?, alarm_text = ? WHERE alarm_id = ? AND %s',
+ $this->_params['table'],
+ isset($alarm['user']) ? 'alarm_uid = ?' : '(alarm_uid = ? OR alarm_uid IS NULL)');
+ $values = array((string)$alarm['start']->setTimezone('UTC'),
+ empty($alarm['end']) ? null : (string)$alarm['end']->setTimezone('UTC'),
+ serialize($alarm['methods']),
+ serialize($alarm['params']),
+ $this->_toDriver($alarm['title']),
+ empty($alarm['text'])
+ ? null
+ : $this->_toDriver($alarm['text']),
+ $alarm['id'],
+ isset($alarm['user']) ? $alarm['user'] : '');
+ Horde::logMessage('SQL query by Horde_Alarm_sql::_update(): ' . $query,
+ __FILE__, __LINE__, PEAR_LOG_DEBUG);
+
+ $result = $this->_write_db->query($query, $values);
+ if ($result instanceof PEAR_Error) {
+ Horde::logMessage($result, __FILE__, __LINE__);
+ throw new Horde_Alarm_Exception($result);
+ }
+
+ return $result;
+ }
+
+ /**
+ * Updates internal alarm properties, i.e. properties not determined by
+ * the application setting the alarm.
+ *
+ * @param string $id The alarm's unique id.
+ * @param string $user The alarm's user
+ * @param array $internal A hash with the internal data.
+ */
+ protected function _internal($id, $user, $internal)
+ {
+ $query = sprintf('UPDATE %s set alarm_internal = ? WHERE alarm_id = ? AND %s',
+ $this->_params['table'],
+ !empty($user) ? 'alarm_uid = ?' : '(alarm_uid = ? OR alarm_uid IS NULL)');
+ $values = array(serialize($internal), $id, $user);
+ Horde::logMessage('SQL query by Horde_Alarm_sql::_internal(): ' . $query,
+ __FILE__, __LINE__, PEAR_LOG_DEBUG);
+
+ $result = $this->_write_db->query($query, $values);
+ if ($result instanceof PEAR_Error) {
+ Horde::logMessage($result, __FILE__, __LINE__);
+ throw new Horde_Alarm_Exception($result);
+ }
+
+ return $result;
+ }
+
+ /**
+ * Returns whether an alarm with the given id exists already.
+ *
+ * @param string $id The alarm's unique id.
+ * @param string $user The alarm's user
+ *
+ * @return boolean True if the specified alarm exists.
+ */
+ protected function _exists($id, $user)
+ {
+ $query = sprintf('SELECT 1 FROM %s WHERE alarm_id = ? AND %s',
+ $this->_params['table'],
+ !empty($user) ? 'alarm_uid = ?' : '(alarm_uid = ? OR alarm_uid IS NULL)');
+ Horde::logMessage('SQL query by Horde_Alarm_sql::_exists(): ' . $query,
+ __FILE__, __LINE__, PEAR_LOG_DEBUG);
+
+ $result = $this->_db->getOne($query, array($id, $user));
+ if ($result instanceof PEAR_Error) {
+ Horde::logMessage($result, __FILE__, __LINE__);
+ throw new Horde_Alarm_Exception($result);
+ }
+
+ return $result;
+ }
+
+ /**
+ * Delays (snoozes) an alarm for a certain period.
+ *
+ * @param string $id The alarm's unique id.
+ * @param string $user The alarm's user
+ * @param Horde_Date $snooze The snooze time.
+ */
+ protected function _snooze($id, $user, $snooze)
+ {
+ $query = sprintf('UPDATE %s set alarm_snooze = ? WHERE alarm_id = ? AND %s',
+ $this->_params['table'],
+ !empty($user) ? 'alarm_uid = ?' : '(alarm_uid = ? OR alarm_uid IS NULL)');
+ $values = array((string)$snooze->setTimezone('UTC'), $id, $user);
+ Horde::logMessage('SQL query by Horde_Alarm_sql::_snooze(): ' . $query,
+ __FILE__, __LINE__, PEAR_LOG_DEBUG);
+
+ $result = $this->_write_db->query($query, $values);
+ if ($result instanceof PEAR_Error) {
+ Horde::logMessage($result, __FILE__, __LINE__);
+ throw new Horde_Alarm_Exception($result);
+ }
+
+ return $result;
+ }
+
+ /**
+ * Dismisses an alarm.
+ *
+ * @param string $id The alarm's unique id.
+ * @param string $user The alarm's user
+ */
+ protected function _dismiss($id, $user)
+ {
+ $query = sprintf('UPDATE %s set alarm_dismissed = 1 WHERE alarm_id = ? AND %s',
+ $this->_params['table'],
+ !empty($user) ? 'alarm_uid = ?' : '(alarm_uid = ? OR alarm_uid IS NULL)');
+ $values = array($id, $user);
+ Horde::logMessage('SQL query by Horde_Alarm_sql::_dismiss(): ' . $query,
+ __FILE__, __LINE__, PEAR_LOG_DEBUG);
+
+ $result = $this->_write_db->query($query, $values);
+ if ($result instanceof PEAR_Error) {
+ Horde::logMessage($result, __FILE__, __LINE__);
+ throw new Horde_Alarm_Exception($result);
+ }
+
+ return $result;
+ }
+
+ /**
+ * Returns whether an alarm is snoozed.
+ *
+ * @param string $id The alarm's unique id.
+ * @param string $user The alarm's user
+ * @param Horde_Date $time The time when the alarm may be snoozed.
+ *
+ * @return boolean True if the alarm is snoozed.
+ */
+ protected function _isSnoozed($id, $user, $time)
+ {
+ $query = sprintf('SELECT 1 FROM %s WHERE alarm_id = ? AND %s AND (alarm_dismissed = 1 OR (alarm_snooze IS NOT NULL AND alarm_snooze >= ?))',
+ $this->_params['table'],
+ !empty($user) ? 'alarm_uid = ?' : '(alarm_uid = ? OR alarm_uid IS NULL)');
+ Horde::logMessage('SQL query by Horde_Alarm_sql::_isSnoozed(): ' . $query,
+ __FILE__, __LINE__, PEAR_LOG_DEBUG);
+
+ $result = $this->_db->getOne($query, array($id, $user, (string)$time->setTimezone('UTC')));
+ if ($result instanceof PEAR_Error) {
+ Horde::logMessage($result, __FILE__, __LINE__);
+ throw new Horde_Alarm_Exception($result);
+ }
+
+ return $result;
+ }
+
+ /**
+ * Deletes an alarm from the backend.
+ *
+ * @param string $id The alarm's unique id.
+ * @param string $user The alarm's user. All users' alarms if null.
+ */
+ protected function _delete($id, $user = null)
+ {
+ $query = sprintf('DELETE FROM %s WHERE alarm_id = ?', $this->_params['table']);
+ $values = array($id);
+ if (!is_null($user)) {
+ $query .= empty($user)
+ ? ' AND (alarm_uid IS NULL OR alarm_uid = ?)'
+ : ' AND alarm_uid = ?';
+ $values[] = $user;
+ }
+ Horde::logMessage('SQL query by Horde_Alarm_sql::_delete(): ' . $query,
+ __FILE__, __LINE__, PEAR_LOG_DEBUG);
+
+ $result = $this->_write_db->query($query, $values);
+ if ($result instanceof PEAR_Error) {
+ Horde::logMessage($result, __FILE__, __LINE__);
+ throw new Horde_Alarm_Exception($result);
+ }
+
+ return $result;
+ }
+
+ /**
+ * Garbage collects old alarms in the backend.
+ */
+ protected function _gc()
+ {
+ $query = sprintf('DELETE FROM %s WHERE alarm_end IS NOT NULL AND alarm_end < ?', $this->_params['table']);
+ Horde::logMessage('SQL query by Horde_Alarm_sql::_gc(): ' . $query,
+ __FILE__, __LINE__, PEAR_LOG_DEBUG);
+ $end = new Horde_Date(time());
+
+ $result = $this->_write_db->query($query, (string)$end->setTimezone('UTC'));
+ if ($result instanceof PEAR_Error) {
+ Horde::logMessage($result, __FILE__, __LINE__);
+ throw new Horde_Alarm_Exception($result);
+ }
+
+ return $result;
+ }
+
+ /**
+ * Attempts to open a connection to the SQL server.
+ */
+ public function initialize()
+ {
+ Horde::assertDriverConfig($this->_params, 'sql',
+ array('phptype', 'charset'));
+
+ $this->_params = array_merge(array(
+ 'database' => '',
+ 'username' => '',
+ 'hostspec' => '',
+ 'table' => 'horde_alarms'
+ ), $this->_params);
+
+ /* Connect to the SQL server using the supplied parameters. */
+ $this->_write_db = DB::connect($this->_params,
+ array('persistent' => !empty($this->_params['persistent']),
+ 'ssl' => !empty($this->_params['ssl'])));
+ if ($this->_write_db instanceof PEAR_Error) {
+ Horde::logMessage($this->_write_db, __FILE__, __LINE__);
+ throw new Horde_Alarm_Exception($this->_write_db);
+ }
+ $this->_initConn($this->_write_db);
+
+ /* Check if we need to set up the read DB connection seperately. */
+ if (!empty($this->_params['splitread'])) {
+ $params = array_merge($this->_params, $this->_params['read']);
+ $this->_db = DB::connect($params,
+ array('persistent' => !empty($params['persistent']),
+ 'ssl' => !empty($params['ssl'])));
+ if ($this->_db instanceof PEAR_Error) {
+ Horde::logMessage($this->_db, __FILE__, __LINE__);
+ throw new Horde_Alarm_Exception($this->_db);
+ }
+ $this->_initConn($this->_db);
+ } else {
+ /* Default to the same DB handle for the writer too. */
+ $this->_db = $this->_write_db;
+ }
+ }
+
+ /**
+ */
+ protected function _initConn($db)
+ {
+ // Set DB portability options.
+ switch ($db->phptype) {
+ case 'mssql':
+ $db->setOption('portability', DB_PORTABILITY_LOWERCASE | DB_PORTABILITY_ERRORS | DB_PORTABILITY_RTRIM);
+ break;
+
+ default:
+ $db->setOption('portability', DB_PORTABILITY_LOWERCASE | DB_PORTABILITY_ERRORS);
+ break;
+ }
+
+ /* Handle any database specific initialization code to run. */
+ switch ($db->dbsyntax) {
+ case 'oci8':
+ $query = "ALTER SESSION SET NLS_DATE_FORMAT = 'YYYY-MM-DD HH24:MI:SS'";
+
+ /* Log the query at a DEBUG log level. */
+ Horde::logMessage(sprintf('SQL connection setup for Alarms, query = "%s"', $query),
+ __FILE__, __LINE__, PEAR_LOG_DEBUG);
+
+ $db->query($query);
+ break;
+
+ case 'pgsql':
+ $query = "SET datestyle TO 'iso'";
+
+ /* Log the query at a DEBUG log level. */
+ Horde::logMessage(sprintf('SQL connection setup for Alarms, query = "%s"', $query),
+ __FILE__, __LINE__, PEAR_LOG_DEBUG);
+
+ $db->query($query);
+ break;
+ }
+ }
+
+}
http://pear.php.net/dtd/tasks-1.0.xsd
http://pear.php.net/dtd/package-2.0
http://pear.php.net/dtd/package-2.0.xsd">
- <name>Horde_Alarm</name>
+ <name>Alarm</name>
<channel>pear.horde.org</channel>
<summary>Horde alarm libraries</summary>
<description>This package provides an interface to deal with reminders,
<email>jan@horde.org</email>
<active>yes</active>
</lead>
- <date>2007-02-01</date>
+ <date>2009-02-11</date>
<version>
- <release>0.1.0</release>
- <api>0.1.0</api>
+ <release>0.2.0</release>
+ <api>0.2.0</api>
</version>
<stability>
<release>beta</release>
<api>beta</api>
</stability>
<license uri="http://www.gnu.org/copyleft/lesser.html">LGPL</license>
- <notes>* Initial release.</notes>
+ <notes>* Initial Horde 4 package.</notes>
<contents>
- <dir name="/" baseinstalldir="/Horde">
- <dir name="Alarm">
- <file name="sql.php" role="php" />
- </dir> <!-- /Alarm -->
- <dir name="tests">
- <file name="001.phpt" role="test" />
- </dir> <!-- /tests -->
- <file name="Alarm.php" role="php" />
+ <dir name="/">
+ <dir name="lib">
+ <dir name="Horde">
+ <dir name="Alarm">
+ <file name="Exception.php" role="php" />
+ <file name="Sql.php" role="php" />
+ </dir> <!-- /lib/Horde/Alarm -->
+ <file name="Alarm.php" role="php" />
+ </dir> <!-- /lib/Horde -->
+ </dir> <!-- /lib -->
+ <dir name="test">
+ <dir name="Horde">
+ <dir name="Alarm">
+ <file name="001.phpt" role="test" />
+ <file name="setup.inc.dist" role="test" />
+ </dir> <!-- /test/Horde/Alarm -->
+ </dir> <!-- /test/Horde -->
+ </dir> <!-- /test -->
</dir> <!-- / -->
</contents>
<dependencies>
<required>
<php>
- <min>4.3.0</min>
+ <min>5.2.0</min>
</php>
<pearinstaller>
- <min>1.4.0b1</min>
+ <min>1.5.0</min>
</pearinstaller>
<package>
<name>Date</name>
</package>
</required>
</dependencies>
- <phprelease />
+ <phprelease>
+ <filelist>
+ <install name="lib/Horde/Alarm/Exception.php" as="Horde/Alarm/Exception.php" />
+ <install name="lib/Horde/Alarm/Sql.php" as="Horde/Alarm/Sql.php" />
+ <install name="lib/Horde/Alarm.php" as="Horde/Alarm.php" />
+ </filelist>
+ </phprelease>
+ <changelog>
+ <release>
+ <date>2007-02-01</date>
+ <version>
+ <release>0.1.0</release>
+ <api>0.1.0</api>
+ </version>
+ <stability>
+ <release>beta</release>
+ <api>beta</api>
+ </stability>
+ <license uri="http://www.gnu.org/copyleft/lesser.html">LGPL</license>
+ <notes>* Initial release.</notes>
+ </release>
+ </changelog>
</package>
--- /dev/null
+--TEST--
+Horde_Alarm tests.
+--SKIPIF--
+<?php
+$setup = @include dirname(__FILE__) . '/setup.inc';
+if (!$setup || empty($params)) {
+ echo 'skip No SQL configuration provided.';
+}
+?>
+--FILE--
+<?php
+
+include dirname(__FILE__) . '/setup.inc';
+require dirname(__FILE__) . '/../../../lib/Horde/Alarm.php';
+require 'Horde.php';
+require 'Horde/Nls.php';
+
+$alarm = Horde_Alarm::factory('sql', $params);
+
+$now = time();
+$date = new Horde_Date($now);
+$end = new Horde_Date($now + 3600);
+$hash = array('id' => 'personalalarm',
+ 'user' => 'john',
+ 'start' => $date,
+ 'end' => $end,
+ 'methods' => array(),
+ 'params' => array(),
+ 'title' => 'This is a personal alarm.');
+
+var_dump($alarm->set($hash));
+var_dump($alarm->exists('personalalarm', 'john'));
+$saved = $alarm->get('personalalarm', 'john');
+var_dump($saved);
+var_dump($saved['start']->compareDateTime($date));
+$hash['title'] = 'Changed alarm text';
+var_dump($alarm->set($hash));
+$date->min--;
+$alarm->set(array('id' => 'publicalarm',
+ 'start' => $date,
+ 'end' => $end,
+ 'methods' => array(),
+ 'params' => array(),
+ 'title' => 'This is a public alarm.'));
+var_dump($alarm->listAlarms('john'));
+var_dump($alarm->delete('publicalarm', ''));
+var_dump($alarm->listAlarms('john'));
+$error = $alarm->snooze('personalalarm', 'jane', 30);
+var_dump($error->getMessage());
+var_dump($alarm->snooze('personalalarm', 'john', 30));
+var_dump($alarm->isSnoozed('personalalarm', 'john'));
+var_dump($alarm->listAlarms('john'));
+var_dump($alarm->listAlarms('john', $end));
+var_dump($alarm->set(array('id' => 'noend',
+ 'user' => 'john',
+ 'start' => $date,
+ 'methods' => array('notify'),
+ 'params' => array(),
+ 'title' => 'This is an alarm without end.')));
+var_dump($alarm->listAlarms('john', $end));
+var_dump($alarm->delete('noend', 'john'));
+var_dump($alarm->delete('personalalarm', 'john'));
+
+?>
+--EXPECTF--
+int(1)
+bool(true)
+array(10) {
+ ["id"]=>
+ string(13) "personalalarm"
+ ["user"]=>
+ string(4) "john"
+ ["start"]=>
+ object(horde_date)(7) {
+ ["year"]=>
+ int(%d%d%d%d)
+ ["month"]=>
+ int(%d)
+ ["mday"]=>
+ int(%d)
+ ["hour"]=>
+ int(%d)
+ ["min"]=>
+ int(%d)
+ ["sec"]=>
+ int(%d)
+ ["_supportedSpecs"]=>
+ string(21) "%CdDeHImMnRStTyYbBpxX"
+ }
+ ["end"]=>
+ object(horde_date)(7) {
+ ["year"]=>
+ int(%d%d%d%d)
+ ["month"]=>
+ int(%d)
+ ["mday"]=>
+ int(%d)
+ ["hour"]=>
+ int(%d)
+ ["min"]=>
+ int(%d)
+ ["sec"]=>
+ int(%d)
+ ["_supportedSpecs"]=>
+ string(21) "%CdDeHImMnRStTyYbBpxX"
+ }
+ ["methods"]=>
+ array(0) {
+ }
+ ["params"]=>
+ array(0) {
+ }
+ ["title"]=>
+ string(25) "This is a personal alarm."
+ ["text"]=>
+ NULL
+ ["snooze"]=>
+ NULL
+ ["internal"]=>
+ NULL
+}
+int(0)
+int(1)
+array(2) {
+ [0]=>
+ array(10) {
+ ["id"]=>
+ string(11) "publicalarm"
+ ["user"]=>
+ string(0) ""
+ ["start"]=>
+ object(horde_date)(7) {
+ ["year"]=>
+ int(%d%d%d%d)
+ ["month"]=>
+ int(%d)
+ ["mday"]=>
+ int(%d)
+ ["hour"]=>
+ int(%d)
+ ["min"]=>
+ int(%d)
+ ["sec"]=>
+ int(%d)
+ ["_supportedSpecs"]=>
+ string(21) "%CdDeHImMnRStTyYbBpxX"
+ }
+ ["end"]=>
+ object(horde_date)(7) {
+ ["year"]=>
+ int(%d%d%d%d)
+ ["month"]=>
+ int(%d)
+ ["mday"]=>
+ int(%d)
+ ["hour"]=>
+ int(%d)
+ ["min"]=>
+ int(%d)
+ ["sec"]=>
+ int(%d)
+ ["_supportedSpecs"]=>
+ string(21) "%CdDeHImMnRStTyYbBpxX"
+ }
+ ["methods"]=>
+ array(0) {
+ }
+ ["params"]=>
+ array(0) {
+ }
+ ["title"]=>
+ string(23) "This is a public alarm."
+ ["text"]=>
+ NULL
+ ["snooze"]=>
+ NULL
+ ["internal"]=>
+ NULL
+ }
+ [1]=>
+ array(10) {
+ ["id"]=>
+ string(13) "personalalarm"
+ ["user"]=>
+ string(4) "john"
+ ["start"]=>
+ object(horde_date)(7) {
+ ["year"]=>
+ int(%d%d%d%d)
+ ["month"]=>
+ int(%d)
+ ["mday"]=>
+ int(%d)
+ ["hour"]=>
+ int(%d)
+ ["min"]=>
+ int(%d)
+ ["sec"]=>
+ int(%d)
+ ["_supportedSpecs"]=>
+ string(21) "%CdDeHImMnRStTyYbBpxX"
+ }
+ ["end"]=>
+ object(horde_date)(7) {
+ ["year"]=>
+ int(%d%d%d%d)
+ ["month"]=>
+ int(%d)
+ ["mday"]=>
+ int(%d)
+ ["hour"]=>
+ int(%d)
+ ["min"]=>
+ int(%d)
+ ["sec"]=>
+ int(%d)
+ ["_supportedSpecs"]=>
+ string(21) "%CdDeHImMnRStTyYbBpxX"
+ }
+ ["methods"]=>
+ array(0) {
+ }
+ ["params"]=>
+ array(0) {
+ }
+ ["title"]=>
+ string(18) "Changed alarm text"
+ ["text"]=>
+ NULL
+ ["snooze"]=>
+ NULL
+ ["internal"]=>
+ NULL
+ }
+}
+int(1)
+array(1) {
+ [0]=>
+ array(10) {
+ ["id"]=>
+ string(13) "personalalarm"
+ ["user"]=>
+ string(4) "john"
+ ["start"]=>
+ object(horde_date)(7) {
+ ["year"]=>
+ int(%d%d%d%d)
+ ["month"]=>
+ int(%d)
+ ["mday"]=>
+ int(%d)
+ ["hour"]=>
+ int(%d)
+ ["min"]=>
+ int(%d)
+ ["sec"]=>
+ int(%d)
+ ["_supportedSpecs"]=>
+ string(21) "%CdDeHImMnRStTyYbBpxX"
+ }
+ ["end"]=>
+ object(horde_date)(7) {
+ ["year"]=>
+ int(%d%d%d%d)
+ ["month"]=>
+ int(%d)
+ ["mday"]=>
+ int(%d)
+ ["hour"]=>
+ int(%d)
+ ["min"]=>
+ int(%d)
+ ["sec"]=>
+ int(%d)
+ ["_supportedSpecs"]=>
+ string(21) "%CdDeHImMnRStTyYbBpxX"
+ }
+ ["methods"]=>
+ array(0) {
+ }
+ ["params"]=>
+ array(0) {
+ }
+ ["title"]=>
+ string(18) "Changed alarm text"
+ ["text"]=>
+ NULL
+ ["snooze"]=>
+ NULL
+ ["internal"]=>
+ NULL
+ }
+}
+string(15) "Alarm not found"
+int(1)
+bool(true)
+array(0) {
+}
+array(1) {
+ [0]=>
+ array(10) {
+ ["id"]=>
+ string(13) "personalalarm"
+ ["user"]=>
+ string(4) "john"
+ ["start"]=>
+ object(horde_date)(7) {
+ ["year"]=>
+ int(%d%d%d%d)
+ ["month"]=>
+ int(%d)
+ ["mday"]=>
+ int(%d)
+ ["hour"]=>
+ int(%d)
+ ["min"]=>
+ int(%d)
+ ["sec"]=>
+ int(%d)
+ ["_supportedSpecs"]=>
+ string(21) "%CdDeHImMnRStTyYbBpxX"
+ }
+ ["end"]=>
+ object(horde_date)(7) {
+ ["year"]=>
+ int(%d%d%d%d)
+ ["month"]=>
+ int(%d)
+ ["mday"]=>
+ int(%d)
+ ["hour"]=>
+ int(%d)
+ ["min"]=>
+ int(%d)
+ ["sec"]=>
+ int(%d)
+ ["_supportedSpecs"]=>
+ string(21) "%CdDeHImMnRStTyYbBpxX"
+ }
+ ["methods"]=>
+ array(0) {
+ }
+ ["params"]=>
+ array(0) {
+ }
+ ["title"]=>
+ string(18) "Changed alarm text"
+ ["text"]=>
+ NULL
+ ["snooze"]=>
+ object(horde_date)(7) {
+ ["year"]=>
+ int(%d%d%d%d)
+ ["month"]=>
+ int(%d)
+ ["mday"]=>
+ int(%d)
+ ["hour"]=>
+ int(%d)
+ ["min"]=>
+ int(%d)
+ ["sec"]=>
+ int(%d)
+ ["_supportedSpecs"]=>
+ string(21) "%CdDeHImMnRStTyYbBpxX"
+ }
+ ["internal"]=>
+ NULL
+ }
+}
+int(1)
+array(2) {
+ [0]=>
+ array(10) {
+ ["id"]=>
+ string(5) "noend"
+ ["user"]=>
+ string(4) "john"
+ ["start"]=>
+ object(horde_date)(7) {
+ ["year"]=>
+ int(%d%d%d%d)
+ ["month"]=>
+ int(%d)
+ ["mday"]=>
+ int(%d)
+ ["hour"]=>
+ int(%d)
+ ["min"]=>
+ int(%d)
+ ["sec"]=>
+ int(%d)
+ ["_supportedSpecs"]=>
+ string(21) "%CdDeHImMnRStTyYbBpxX"
+ }
+ ["end"]=>
+ NULL
+ ["methods"]=>
+ array(1) {
+ [0]=>
+ string(6) "notify"
+ }
+ ["params"]=>
+ array(0) {
+ }
+ ["title"]=>
+ string(29) "This is an alarm without end."
+ ["text"]=>
+ NULL
+ ["snooze"]=>
+ NULL
+ ["internal"]=>
+ NULL
+ }
+ [1]=>
+ array(10) {
+ ["id"]=>
+ string(13) "personalalarm"
+ ["user"]=>
+ string(4) "john"
+ ["start"]=>
+ object(horde_date)(7) {
+ ["year"]=>
+ int(%d%d%d%d)
+ ["month"]=>
+ int(%d)
+ ["mday"]=>
+ int(%d)
+ ["hour"]=>
+ int(%d)
+ ["min"]=>
+ int(%d)
+ ["sec"]=>
+ int(%d)
+ ["_supportedSpecs"]=>
+ string(21) "%CdDeHImMnRStTyYbBpxX"
+ }
+ ["end"]=>
+ object(horde_date)(7) {
+ ["year"]=>
+ int(%d%d%d%d)
+ ["month"]=>
+ int(%d)
+ ["mday"]=>
+ int(%d)
+ ["hour"]=>
+ int(%d)
+ ["min"]=>
+ int(%d)
+ ["sec"]=>
+ int(%d)
+ ["_supportedSpecs"]=>
+ string(21) "%CdDeHImMnRStTyYbBpxX"
+ }
+ ["methods"]=>
+ array(0) {
+ }
+ ["params"]=>
+ array(0) {
+ }
+ ["title"]=>
+ string(18) "Changed alarm text"
+ ["text"]=>
+ NULL
+ ["snooze"]=>
+ object(horde_date)(7) {
+ ["year"]=>
+ int(%d%d%d%d)
+ ["month"]=>
+ int(%d)
+ ["mday"]=>
+ int(%d)
+ ["hour"]=>
+ int(%d)
+ ["min"]=>
+ int(%d)
+ ["sec"]=>
+ int(%d)
+ ["_supportedSpecs"]=>
+ string(21) "%CdDeHImMnRStTyYbBpxX"
+ }
+ ["internal"]=>
+ NULL
+ }
+}
+int(1)
+int(1)
--- /dev/null
+<?php
+$params = array('phptype' => 'mysql',
+ 'database' => 'horde',
+ 'username' => 'horde',
+ 'password' => 'horde',
+ 'charset' => 'iso-8859-1');
+
+require_once 'Log.php';
+$conf['log'] = array('priority' => PEAR_LOG_DEBUG,
+ 'ident' => 'HORDE',
+ 'params' => array('append' => true),
+ 'name' => '/tmp/horde.log',
+ 'type' => 'file',
+ 'enabled' => true);
+++ /dev/null
---TEST--
-Horde_Alarm tests.
---SKIPIF--
-<?php
-$setup = @include dirname(__FILE__) . '/setup.inc';
-if (!$setup || empty($params)) {
- echo 'skip No SQL configuration provided.';
-}
-?>
---FILE--
-<?php
-
-include dirname(__FILE__) . '/setup.inc';
-require dirname(__FILE__) . '/../Alarm.php';
-require 'Horde.php';
-require 'Horde/Nls.php';
-
-$alarm = Horde_Alarm::factory('sql', $params);
-
-$now = time();
-$date = new Horde_Date($now);
-$end = new Horde_Date($now + 3600);
-$hash = array('id' => 'personalalarm',
- 'user' => 'john',
- 'start' => $date,
- 'end' => $end,
- 'methods' => array(),
- 'params' => array(),
- 'title' => 'This is a personal alarm.');
-
-var_dump($alarm->set($hash));
-var_dump($alarm->exists('personalalarm', 'john'));
-$saved = $alarm->get('personalalarm', 'john');
-var_dump($saved);
-var_dump($saved['start']->compareDateTime($date));
-$hash['title'] = 'Changed alarm text';
-var_dump($alarm->set($hash));
-$date->min--;
-$alarm->set(array('id' => 'publicalarm',
- 'start' => $date,
- 'end' => $end,
- 'methods' => array(),
- 'params' => array(),
- 'title' => 'This is a public alarm.'));
-var_dump($alarm->listAlarms('john'));
-var_dump($alarm->delete('publicalarm', ''));
-var_dump($alarm->listAlarms('john'));
-$error = $alarm->snooze('personalalarm', 'jane', 30);
-var_dump($error->getMessage());
-var_dump($alarm->snooze('personalalarm', 'john', 30));
-var_dump($alarm->isSnoozed('personalalarm', 'john'));
-var_dump($alarm->listAlarms('john'));
-var_dump($alarm->listAlarms('john', $end));
-var_dump($alarm->set(array('id' => 'noend',
- 'user' => 'john',
- 'start' => $date,
- 'methods' => array('notify'),
- 'params' => array(),
- 'title' => 'This is an alarm without end.')));
-var_dump($alarm->listAlarms('john', $end));
-var_dump($alarm->delete('noend', 'john'));
-var_dump($alarm->delete('personalalarm', 'john'));
-
-?>
---EXPECTF--
-int(1)
-bool(true)
-array(10) {
- ["id"]=>
- string(13) "personalalarm"
- ["user"]=>
- string(4) "john"
- ["start"]=>
- object(horde_date)(7) {
- ["year"]=>
- int(%d%d%d%d)
- ["month"]=>
- int(%d)
- ["mday"]=>
- int(%d)
- ["hour"]=>
- int(%d)
- ["min"]=>
- int(%d)
- ["sec"]=>
- int(%d)
- ["_supportedSpecs"]=>
- string(21) "%CdDeHImMnRStTyYbBpxX"
- }
- ["end"]=>
- object(horde_date)(7) {
- ["year"]=>
- int(%d%d%d%d)
- ["month"]=>
- int(%d)
- ["mday"]=>
- int(%d)
- ["hour"]=>
- int(%d)
- ["min"]=>
- int(%d)
- ["sec"]=>
- int(%d)
- ["_supportedSpecs"]=>
- string(21) "%CdDeHImMnRStTyYbBpxX"
- }
- ["methods"]=>
- array(0) {
- }
- ["params"]=>
- array(0) {
- }
- ["title"]=>
- string(25) "This is a personal alarm."
- ["text"]=>
- NULL
- ["snooze"]=>
- NULL
- ["internal"]=>
- NULL
-}
-int(0)
-int(1)
-array(2) {
- [0]=>
- array(10) {
- ["id"]=>
- string(11) "publicalarm"
- ["user"]=>
- string(0) ""
- ["start"]=>
- object(horde_date)(7) {
- ["year"]=>
- int(%d%d%d%d)
- ["month"]=>
- int(%d)
- ["mday"]=>
- int(%d)
- ["hour"]=>
- int(%d)
- ["min"]=>
- int(%d)
- ["sec"]=>
- int(%d)
- ["_supportedSpecs"]=>
- string(21) "%CdDeHImMnRStTyYbBpxX"
- }
- ["end"]=>
- object(horde_date)(7) {
- ["year"]=>
- int(%d%d%d%d)
- ["month"]=>
- int(%d)
- ["mday"]=>
- int(%d)
- ["hour"]=>
- int(%d)
- ["min"]=>
- int(%d)
- ["sec"]=>
- int(%d)
- ["_supportedSpecs"]=>
- string(21) "%CdDeHImMnRStTyYbBpxX"
- }
- ["methods"]=>
- array(0) {
- }
- ["params"]=>
- array(0) {
- }
- ["title"]=>
- string(23) "This is a public alarm."
- ["text"]=>
- NULL
- ["snooze"]=>
- NULL
- ["internal"]=>
- NULL
- }
- [1]=>
- array(10) {
- ["id"]=>
- string(13) "personalalarm"
- ["user"]=>
- string(4) "john"
- ["start"]=>
- object(horde_date)(7) {
- ["year"]=>
- int(%d%d%d%d)
- ["month"]=>
- int(%d)
- ["mday"]=>
- int(%d)
- ["hour"]=>
- int(%d)
- ["min"]=>
- int(%d)
- ["sec"]=>
- int(%d)
- ["_supportedSpecs"]=>
- string(21) "%CdDeHImMnRStTyYbBpxX"
- }
- ["end"]=>
- object(horde_date)(7) {
- ["year"]=>
- int(%d%d%d%d)
- ["month"]=>
- int(%d)
- ["mday"]=>
- int(%d)
- ["hour"]=>
- int(%d)
- ["min"]=>
- int(%d)
- ["sec"]=>
- int(%d)
- ["_supportedSpecs"]=>
- string(21) "%CdDeHImMnRStTyYbBpxX"
- }
- ["methods"]=>
- array(0) {
- }
- ["params"]=>
- array(0) {
- }
- ["title"]=>
- string(18) "Changed alarm text"
- ["text"]=>
- NULL
- ["snooze"]=>
- NULL
- ["internal"]=>
- NULL
- }
-}
-int(1)
-array(1) {
- [0]=>
- array(10) {
- ["id"]=>
- string(13) "personalalarm"
- ["user"]=>
- string(4) "john"
- ["start"]=>
- object(horde_date)(7) {
- ["year"]=>
- int(%d%d%d%d)
- ["month"]=>
- int(%d)
- ["mday"]=>
- int(%d)
- ["hour"]=>
- int(%d)
- ["min"]=>
- int(%d)
- ["sec"]=>
- int(%d)
- ["_supportedSpecs"]=>
- string(21) "%CdDeHImMnRStTyYbBpxX"
- }
- ["end"]=>
- object(horde_date)(7) {
- ["year"]=>
- int(%d%d%d%d)
- ["month"]=>
- int(%d)
- ["mday"]=>
- int(%d)
- ["hour"]=>
- int(%d)
- ["min"]=>
- int(%d)
- ["sec"]=>
- int(%d)
- ["_supportedSpecs"]=>
- string(21) "%CdDeHImMnRStTyYbBpxX"
- }
- ["methods"]=>
- array(0) {
- }
- ["params"]=>
- array(0) {
- }
- ["title"]=>
- string(18) "Changed alarm text"
- ["text"]=>
- NULL
- ["snooze"]=>
- NULL
- ["internal"]=>
- NULL
- }
-}
-string(15) "Alarm not found"
-int(1)
-bool(true)
-array(0) {
-}
-array(1) {
- [0]=>
- array(10) {
- ["id"]=>
- string(13) "personalalarm"
- ["user"]=>
- string(4) "john"
- ["start"]=>
- object(horde_date)(7) {
- ["year"]=>
- int(%d%d%d%d)
- ["month"]=>
- int(%d)
- ["mday"]=>
- int(%d)
- ["hour"]=>
- int(%d)
- ["min"]=>
- int(%d)
- ["sec"]=>
- int(%d)
- ["_supportedSpecs"]=>
- string(21) "%CdDeHImMnRStTyYbBpxX"
- }
- ["end"]=>
- object(horde_date)(7) {
- ["year"]=>
- int(%d%d%d%d)
- ["month"]=>
- int(%d)
- ["mday"]=>
- int(%d)
- ["hour"]=>
- int(%d)
- ["min"]=>
- int(%d)
- ["sec"]=>
- int(%d)
- ["_supportedSpecs"]=>
- string(21) "%CdDeHImMnRStTyYbBpxX"
- }
- ["methods"]=>
- array(0) {
- }
- ["params"]=>
- array(0) {
- }
- ["title"]=>
- string(18) "Changed alarm text"
- ["text"]=>
- NULL
- ["snooze"]=>
- object(horde_date)(7) {
- ["year"]=>
- int(%d%d%d%d)
- ["month"]=>
- int(%d)
- ["mday"]=>
- int(%d)
- ["hour"]=>
- int(%d)
- ["min"]=>
- int(%d)
- ["sec"]=>
- int(%d)
- ["_supportedSpecs"]=>
- string(21) "%CdDeHImMnRStTyYbBpxX"
- }
- ["internal"]=>
- NULL
- }
-}
-int(1)
-array(2) {
- [0]=>
- array(10) {
- ["id"]=>
- string(5) "noend"
- ["user"]=>
- string(4) "john"
- ["start"]=>
- object(horde_date)(7) {
- ["year"]=>
- int(%d%d%d%d)
- ["month"]=>
- int(%d)
- ["mday"]=>
- int(%d)
- ["hour"]=>
- int(%d)
- ["min"]=>
- int(%d)
- ["sec"]=>
- int(%d)
- ["_supportedSpecs"]=>
- string(21) "%CdDeHImMnRStTyYbBpxX"
- }
- ["end"]=>
- NULL
- ["methods"]=>
- array(1) {
- [0]=>
- string(6) "notify"
- }
- ["params"]=>
- array(0) {
- }
- ["title"]=>
- string(29) "This is an alarm without end."
- ["text"]=>
- NULL
- ["snooze"]=>
- NULL
- ["internal"]=>
- NULL
- }
- [1]=>
- array(10) {
- ["id"]=>
- string(13) "personalalarm"
- ["user"]=>
- string(4) "john"
- ["start"]=>
- object(horde_date)(7) {
- ["year"]=>
- int(%d%d%d%d)
- ["month"]=>
- int(%d)
- ["mday"]=>
- int(%d)
- ["hour"]=>
- int(%d)
- ["min"]=>
- int(%d)
- ["sec"]=>
- int(%d)
- ["_supportedSpecs"]=>
- string(21) "%CdDeHImMnRStTyYbBpxX"
- }
- ["end"]=>
- object(horde_date)(7) {
- ["year"]=>
- int(%d%d%d%d)
- ["month"]=>
- int(%d)
- ["mday"]=>
- int(%d)
- ["hour"]=>
- int(%d)
- ["min"]=>
- int(%d)
- ["sec"]=>
- int(%d)
- ["_supportedSpecs"]=>
- string(21) "%CdDeHImMnRStTyYbBpxX"
- }
- ["methods"]=>
- array(0) {
- }
- ["params"]=>
- array(0) {
- }
- ["title"]=>
- string(18) "Changed alarm text"
- ["text"]=>
- NULL
- ["snooze"]=>
- object(horde_date)(7) {
- ["year"]=>
- int(%d%d%d%d)
- ["month"]=>
- int(%d)
- ["mday"]=>
- int(%d)
- ["hour"]=>
- int(%d)
- ["min"]=>
- int(%d)
- ["sec"]=>
- int(%d)
- ["_supportedSpecs"]=>
- string(21) "%CdDeHImMnRStTyYbBpxX"
- }
- ["internal"]=>
- NULL
- }
-}
-int(1)
-int(1)
+++ /dev/null
-<?php
-$params = array('phptype' => 'mysql',
- 'database' => 'horde',
- 'username' => 'horde',
- 'password' => 'horde',
- 'charset' => 'iso-8859-1');
-
-require_once 'Log.php';
-$conf['log'] = array('priority' => PEAR_LOG_DEBUG,
- 'ident' => 'HORDE',
- 'params' => array('append' => true),
- 'name' => '/tmp/horde.log',
- 'type' => 'file',
- 'enabled' => true);
<configswitch name="driver" desc="What alarm storage driver should we
use?">sql
<case name="false" desc="None"/>
- <case name="sql" desc="SQL Database">
+ <case name="Sql" desc="SQL Database">
<configsection name="params">
<configsql switchname="driverconfig">
<configstring name="table" required="false" desc="The name of the