Horde 4 changes:
authorMichael J. Rubinsky <mrubinsk@horde.org>
Mon, 20 Dec 2010 22:21:50 +0000 (17:21 -0500)
committerMichael J. Rubinsky <mrubinsk@horde.org>
Tue, 21 Dec 2010 01:02:57 +0000 (20:02 -0500)
php5-ify, move to Horde_Db, add migrations

18 files changed:
hermes/admin.php
hermes/deliverables.php
hermes/entry.php
hermes/invoicing.php
hermes/lib/Admin.php
hermes/lib/Api.php
hermes/lib/Application.php
hermes/lib/Driver.php
hermes/lib/Driver/sql.php
hermes/lib/Forms/Search.php
hermes/lib/Forms/Time.php
hermes/lib/Hermes.php
hermes/lib/Injector/Factory/Driver.php [new file with mode: 0644]
hermes/migration/1_hermes_base_tables.php [new file with mode: 0644]
hermes/migration/2_hermes_autoincrement.php [new file with mode: 0644]
hermes/scripts/purge.php
hermes/search.php
hermes/time.php

index 6bd036c..b9cca08 100644 (file)
@@ -9,12 +9,10 @@
  */
 
 require_once dirname(__FILE__) . '/lib/Application.php';
-$hermes = Horde_Registry::appInit('hermes');
-require_once HERMES_BASE . '/lib/Admin.php';
+Horde_Registry::appInit('hermes', array('admin' => true));
 
-if (!$registry->isAdmin()) {
-    exit('forbidden.');
-}
+// @TODO
+require_once HERMES_BASE . '/lib/Admin.php';
 
 $r = new Horde_Form_Renderer();
 $vars = Horde_Variables::getDefaultVariables();
@@ -35,6 +33,8 @@ function _open()
     }
 }
 
+$driver = $GLOBALS['injector']->getInstance('Hermes_Driver');
+
 // This is a dirty work around to a Horde_Form behavior.
 // Horde_Variables#exists() only checks on expected variables, while
 // Horde_Variables#get() returns the value if one was passed.  Since the form
@@ -49,11 +49,11 @@ if (!empty($formname)) {
 
         if ($form->isValid()) {
             $form->getInfo($vars, $info);
-            $result = $hermes->driver->updateJobType($info);
-            if (!is_a($result, 'PEAR_Error')) {
+            try {
+                $result = $driver->updateJobType($info);
                 $notification->push(sprintf(_("The job type \"%s\" has been added."), $vars->get('name')), 'horde.success');
-            } else {
-                $notification->push(sprintf(_("There was an error adding the job type: %s."), $result->getMessage()), 'horde.error');
+            } catch (Exception $e) {
+                $notification->push(sprintf(_("There was an error adding the job type: %s."), $e->getMessage()), 'horde.error');
             }
         } else {
             _open();
@@ -146,11 +146,11 @@ if (!empty($formname)) {
             // update everything.
             $form1->getInfo($vars, $info);
             $info['id'] = $info['jobtype'];
-            $result = $hermes->driver->updateJobType($info);
-            if (!PEAR::isError($result)) {
+            try {
+                $result = $driver->updateJobType($info);
                 $notification->push(_("The job type has been modified."), 'horde.success');
-            } else {
-                $notification->push(sprintf(_("There was an error editing the job type: %s."), $result->getMessage()), 'horde.error');
+            } catch (Exception $e) {
+                $notification->push(sprintf(_("There was an error editing the job type: %s."), $e->getMessage()), 'horde.error');
             }
         } else {
             _open();
@@ -169,13 +169,13 @@ if (!empty($formname)) {
         $form->validate($vars);
 
         if ($form->isValid()) {
-            $result = $hermes->driver->updateClientSettings($vars->get('client'),
-                                                    $vars->get('enterdescription') ? 1 : 0,
-                                                    $vars->get('exportid'));
-            if (PEAR::isError($result)) {
-                $notification->push(sprintf(_("There was an error editing the client settings: %s."), $result->getMessage()), 'horde.error');
-            } else {
-                $notification->push(_("The client settings have been modified."), 'horde.success');
+            try {
+                $result = $driver->updateClientSettings($vars->get('client'),
+                                                        $vars->get('enterdescription') ? 1 : 0,
+                                                        $vars->get('exportid'));
+                 $notification->push(_("The client settings have been modified."), 'horde.success');
+            } catch (Exception $e) {
+                $notification->push(sprintf(_("There was an error editing the client settings: %s."), $e->getMessage()), 'horde.error');
             }
         } else {
             _open();
@@ -195,11 +195,11 @@ if (!empty($formname)) {
 
         if ($form->isValid()) {
             if ($vars->get('yesno') == 1) {
-                $result = $hermes->driver->deleteJobType($vars->get('jobtype'));
-                if (!PEAR::isError($result)) {
+                try {
+                    $result = $driver->deleteJobType($vars->get('jobtype'));
                     $notification->push(_("The job type has been deleted."), 'horde.success');
-                } else {
-                    $notification->push(sprintf(_("There was an error deleting the job type: %s."), $result->getMessage()), 'horde.error');
+                } catch (Exception $e) {
+                    $notification->push(sprintf(_("There was an error deleting the job type: %s."), $e->getMessage()), 'horde.error');
                 }
             } else {
                 $notification->push(_("The job type was not deleted."), 'horde.message');
index 17552d4..4ed1e39 100644 (file)
@@ -7,9 +7,11 @@
  *
  * @author Jason M. Felice <jason.m.felice@gmail.com>
  */
-
 require_once dirname(__FILE__) . '/lib/Application.php';
-$hermes = Horde_Registry::appInit('hermes');
+
+Horde_Registry::appInit('hermes');
+
+// @TODO
 require_once HERMES_BASE . '/lib/Forms/Deliverable.php';
 
 $vars = Horde_Variables::getDefaultVariables();
@@ -19,37 +21,30 @@ case 'deliverableform':
     $form = new DeliverableForm($vars);
     $form->validate($vars);
     if ($form->isValid()) {
-        $form->getInfo($vars, $info);
-        if (!empty($info['deliverable_id'])) {
-            $info['id'] = $info['deliverable_id'];
-            if (empty($info['parent'])) {
-                $origdeliv = $hermes->driver->getDeliverableByID($info['id']);
-                if (!is_a($origdeliv, 'PEAR_Error')) {
+        try {
+            $form->getInfo($vars, $info);
+            if (!empty($info['deliverable_id'])) {
+                $info['id'] = $info['deliverable_id'];
+                if (empty($info['parent'])) {
+                    $origdeliv = $GLOBALS['injector']->getInstance('Hermes_Driver')->getDeliverableByID($info['id']);
                     $info['parent'] = $origdeliv['parent'];
                 }
             }
-        }
-        $res = $hermes->driver->updateDeliverable($info);
-        if (is_a($res, 'PEAR_Error')) {
-            $notification->push(sprintf(_("Error saving deliverable: %s"),
-                                        $res->getMessage()),
-                                'horde.error');
-        } else {
-            $notification->push(_("Deliverable saved successfully."),
-                                'horde.success');
+            $res = $GLOBALS['injector']->getInstance('Hermes_Driver')->updateDeliverable($info);
+            $notification->push(_("Deliverable saved successfully."), 'horde.success');
             $vars = new Horde_Variables(array('client_id' => $vars->get('client_id')));
+        } catch (Exception $e) {
+            $notification->push(sprintf(_("Error saving deliverable: %s"), $res->getMessage()), 'horde.error');
         }
     }
     break;
 
 case 'deletedeliverable':
-    $res = $hermes->driver->deleteDeliverable($vars->get('delete'));
-    if (is_a($res, 'PEAR_Error')) {
-        $notification->push(sprintf(_("Error deleting deliverable: %s"),
-                                    $res->getMessage()), 'horde.error');
-    } else {
-        $notification->push(_("Deliverable successfully deleted."),
-                            'horde.success');
+    try {
+        $res = $GLOBALS['injector']->getInstance('Hermes_Driver')->deleteDeliverable($vars->get('delete'));
+        $notification->push(_("Deliverable successfully deleted."), 'horde.success');
+    } catch (Exception $e) {
+        $notification->push(sprintf(_("Error deleting deliverable: %s"), $res->getMessage()), 'horde.error');
     }
     break;
 }
@@ -67,27 +62,18 @@ if (!$vars->exists('deliverable_id') && !$vars->exists('new')) {
 
 if ($vars->exists('deliverable_id') || $vars->exists('new')) {
     if ($vars->exists('deliverable_id')) {
-        $deliverable = $hermes->driver->getDeliverableByID($vars->get('deliverable_id'));
-        if (is_a($deliverable, 'PEAR_Error')) {
-            throw new Hermes_Exception($deliverable);
-        }
-
+        $deliverable = $GLOBALS['injector']->getInstance('Hermes_Driver')->getDeliverableByID($vars->get('deliverable_id'));
         foreach ($deliverable as $name => $value) {
             $vars->set($name, $value);
         }
     }
-
     $form = new DeliverableForm($vars);
     $form->renderActive($renderer, $vars, 'deliverables.php', 'post');
 } elseif ($vars->exists('client_id')) {
     $clients = Hermes::listClients();
     $clientname = $clients[$vars->get('client_id')];
 
-    $deliverables = $hermes->driver->listDeliverables(array('client_id' => $vars->get('client_id')));
-    if (is_a($deliverables, 'PEAR_Error')) {
-        throw new Hermes_Exception($deliverables);
-    }
-
+    $deliverables = $GLOBALS['injector']->getInstance('Hermes_Driver')->listDeliverables(array('client_id' => $vars->get('client_id')));
     $tree = $GLOBALS['injector']->getInstance('Horde_Core_Factory_Tree')->create('deliverables', 'Javascript');
     $tree->setOption(array('class'       => 'item',
                            'alternate'   => true));
index f2b0349..9763be5 100644 (file)
@@ -10,7 +10,9 @@
  */
 
 require_once dirname(__FILE__) . '/lib/Application.php';
-$hermes = Horde_Registry::appInit('hermes');
+Horde_Registry::appInit('hermes');
+
+// @TODO
 require_once HERMES_BASE . '/lib/Forms/Time.php';
 
 $vars = Horde_Variables::getDefaultVariables();
@@ -36,22 +38,23 @@ case 'timeentryform':
     $form = new TimeEntryForm($vars);
     if ($form->validate($vars)) {
         $form->getInfo($vars, $info);
-        if ($vars->exists('id')) {
-            $msg = _("Your time was successfully updated.");
-            $result = $hermes->driver->updateTime(array($info));
-            $do_redirect = true;
-        } else {
-            $msg = _("Your time was successfully entered.");
-            $result = $hermes->driver->enterTime($GLOBALS['registry']->getAuth(), $info);
-            $do_redirect = false;
-        }
-        if (is_a($result, 'PEAR_Error')) {
-            Horde::logMessage($result, __FILE__, __LINE__, PEAR_LOG_ERR);
-            $notification->push(sprintf(_("There was an error storing your timesheet: %s"), $result->getMessage()), 'horde.error');
+        try {
+            if ($vars->exists('id')) {
+                $msg = _("Your time was successfully updated.");
+                $GLOBALS['injector']->getInstance('Hermes_Driver')->updateTime(array($info));
+                $do_redirect = true;
+            } else {
+                $msg = _("Your time was successfully entered.");
+                $GLOBALS['injector']->getInstance('Hermes_Driver')->enterTime($GLOBALS['registry']->getAuth(), $info);
+                $do_redirect = false;
+            }
+        } catch (Exception $e) {
+            Horde::logMessage($e, 'err');
+            $notification->push(sprintf(_("There was an error storing your timesheet: %s"), $e->getMessage()), 'horde.error');
             $do_redirect = false;
-        } else {
-            $notification->push($msg, 'horde.success');
         }
+
+        $notification->push($msg, 'horde.success');
         if ($do_redirect) {
             $url = $vars->get('url');
             if (empty($url)) {
@@ -71,7 +74,7 @@ default:
             $notification->push(_("Access denied; user cannot modify this timeslice."), 'horde.error');
             Horde::url('time.php')->redirect();
         }
-        $myhours = $hermes->driver->getHours(array('id' => $id));
+        $myhours = $GLOBALS['injector']->getInstance('Hermes_Driver')->getHours(array('id' => $id));
         if (is_array($myhours)) {
             foreach ($myhours as $item) {
                 if (isset($item['id']) && $item['id'] == $id) {
index 41567a8..b424675 100644 (file)
@@ -15,10 +15,10 @@ require_once 'Horde/Form.php';
 require_once 'Horde/Form/Renderer.php';
 require_once 'Horde/Form/Type/tableset.php';
 
-$hours = $hermes->driver->getHours(array('billable' => true,
-                                 'submitted' => true));
-if (is_a($hours, 'PEAR_Error')) {
-    $notification->push($hours->getMessage(), 'horde.error');
+try {
+    $hours = $GLOBALS['injector']->getInstance('Hermes_Driver')->getHours(array('billable' => true, 'submitted' => true));
+} catch (Exception $e) {
+    $notification->push($e->getMessage(), 'horde.error');
     Horde::url('time.php')->redirect();
 }
 if (empty($hours)) {
@@ -111,12 +111,12 @@ if ($form->validate()) {
                                            'discount' => 0);
         }
 
-        $invoice_id = $registry->call('invoices/save', array($invoice));
-        if (is_a($invoice_id, 'PEAR_Error')) {
-            $notification->push($invoice_id->getMessage(), 'horde.error');
-        } else {
+        try {
+            $invoice_id = $registry->call('invoices/save', array($invoice));
             $msg = sprintf(_("Invoice for client %s successfuly created."), $clients[$group['client']]);
             $notification->push($msg, 'horde.success');
+        } catch (Exception $e) {
+            $notification->push($invoice_id->getMessage(), 'horde.error');
         }
     }
 
@@ -129,4 +129,4 @@ require HERMES_TEMPLATES . '/menu.inc';
 $renderer = new Horde_Form_Renderer(array('varrenderer_driver' => 'tableset_html'));
 $form->renderActive($renderer, null, Horde::url('invoicing.php'), 'post');
 
-require $registry->get('templates', 'horde') . '/common-footer.inc';
+require $registry->get('templates', 'horde') . '/common-footer.inc';
\ No newline at end of file
index 4774329..16f4a81 100644 (file)
@@ -39,20 +39,18 @@ class EditJobTypeStep1Form extends Horde_Form {
 
     function EditJobTypeStep1Form(&$vars)
     {
-        global $hermes;
-
         parent::Horde_Form($vars, 'editjobtypestep1form');
 
         $values = array();
-        $jobtypes = $hermes->driver->listJobTypes();
-        if (!is_a($jobtypes, 'PEAR_Error')) {
+        try {
+            $jobtypes = $GLOBALS['injector']->getInstance('Hermes_Driver')->listJobTypes();
             foreach ($jobtypes as $id => $jobtype) {
                 $values[$id] = $jobtype['name'];
                 if (empty($jobtype['enabled'])) {
                     $values[$id] .= _(" (DISABLED)");
                 }
             }
-        }
+        } catch (Hermes_Exception $e) {}
 
         if ($values) {
             $subtype = 'enum';
@@ -74,13 +72,14 @@ class EditJobTypeStep2Form extends Horde_Form {
 
     function EditJobTypeStep2Form(&$vars)
     {
-        global $hermes;
-
         parent::Horde_Form($vars, 'editjobtypestep2form');
 
         $jobtype = $vars->get('jobtype');
-        $info = $hermes->driver->getJobTypeByID($jobtype);
-        if (!$info || is_a($info, 'PEAR_Error')) {
+        try {
+            $info = $GLOBALS['injector']->getInstance('Hermes_Driver')->getJobTypeByID($jobtype);
+        } catch (Exception $e) {}
+
+        if (!$info) {
             $stype = 'invalid';
             $type_params = array(_("This is not a valid job type."));
         } else {
@@ -112,13 +111,13 @@ class DeleteJobTypeForm extends Horde_Form {
 
     function DeleteJobTypeForm(&$vars)
     {
-        global $hermes;
-
         parent::Horde_Form($vars, 'deletejobtypeform');
 
         $jobtype = $vars->get('jobtype');
-        $info = $hermes->driver->getJobTypeByID($jobtype);
 
+        try {
+            $info = $GLOBALS['injector']->getInstance('Hermes_Driver')->getJobTypeByID($jobtype);
+        } catch (Exception $e) {}
         $yesnotype = 'enum';
         $type_params = array(array(0 => _("No"), 1 => _("Yes")));
 
@@ -165,13 +164,13 @@ class EditClientStep2Form extends Horde_Form {
 
     function EditClientStep2Form(&$vars)
     {
-        global $hermes;
-
         parent::Horde_Form($vars, 'editclientstep2form');
 
         $client = $vars->get('client');
-        $info = $hermes->driver->getClientSettings($client);
-        if (!$info || is_a($info, 'PEAR_Error')) {
+        try {
+            $info = $GLOBALS['injector']->getInstance('Hermes_Driver')->getClientSettings($client);
+        } catch (Hermes_Exception $e) {}
+        if (!$info) {
             $stype = 'invalid';
             $type_params = array(_("This is not a valid client."));
         } else {
index d311150..ba13f11 100644 (file)
@@ -5,19 +5,28 @@
  * This file defines Hermes's external API interface. Other applications
  * can interact with Hermes through this API.
  *
+ * See the enclosed file LICENSE for license information (BSD). If you
+ * did not receive this file, see http://www.horde.org/licenses/bsdl.php.
+ *
  * @package Hermes
  */
-
 class Hermes_Api extends Horde_Registry_Api
 {
-
+    /**
+     * @TODO
+     *
+     * @param <type> $name
+     * @param <type> $params
+     *
+     * @return <type>
+     */
     public static function getTableMetaData($name, $params)
     {
         switch ($name) {
         case 'hours':
             $emptype = Hermes::getEmployeesType('enum');
             $clients = Hermes::listClients();
-            $hours = $GLOBALS['hermes']->driver->getHours($params);
+            $hours = $GLOBALS['injector']->getInstance('Hermes_Driver')->getHours($params);
             $yesno = array(1 => _("Yes"),
                            0 => _("No"));
 
@@ -97,20 +106,22 @@ class Hermes_Api extends Horde_Registry_Api
                                  'columns' => $fColumns)));
 
         default:
-            return PEAR::raiseError(sprintf(_("\"%s\" is not a defined table."),
-                                            $name));
+            throw new Hermes_Exception(sprintf(_("\"%s\" is not a defined table."), $name));
         }
     }
 
+    /**
+     * @TODO
+     *
+     * @param <type> $name
+     * @param <type> $params
+     * @return string
+     */
     public static function getTableData($name, $params)
     {
         switch ($name) {
         case 'hours':
-            $time_data = $GLOBALS['hermes']->driver->getHours($params);
-            if (is_a($time_data, 'PEAR_Error')) {
-                return $time_data;
-            }
-
+            $time_data = $GLOBALS['injector']->getInstance('Hermes_Driver')->getHours($params);
             $subtotal_column = null;
             if ($search_mode = $GLOBALS['session']->get('hermes', 'search_mode')) {
                 switch ($search_mode) {
@@ -246,6 +257,15 @@ class Hermes_Api extends Horde_Registry_Api
         return $result;
     }
 
+    /**
+     * @TODO
+     *
+     * @param <type> $table_data
+     * @param <type> $hours
+     * @param <type> $billable_hours
+     * @param <type> $value
+     * @return <type>
+     */
     public static function renderSubtotals(&$table_data, $hours, $billable_hours, $value)
     {
         $billable_pct = ($hours == 0.0) ? 0.0 :
@@ -273,17 +293,19 @@ class Hermes_Api extends Horde_Registry_Api
         return;
     }
 
+    /**
+     * @TODO
+     *
+     * @param <type> $criteria
+     * @return <type>
+     */
     function listCostObjects($criteria)
     {
         if (!$GLOBALS['conf']['time']['deliverables']) {
             return array();
         }
 
-        $deliverables = $GLOBALS['hermes']->driver->listDeliverables($criteria);
-        if (is_a($deliverables, 'PEAR_Error')) {
-            return PEAR::raiseError(sprintf(_("An error occurred retrieving deliverables: %s"), $deliverables->getMessage()));
-        }
-
+        $deliverables = $GLOBALS['injector']->getInstance('Hermes_Driver')->listDeliverables($criteria);
         if (empty($criteria['id'])) {
             /* Build heirarchical tree. */
             $levels = array();
@@ -340,25 +362,40 @@ class Hermes_Api extends Horde_Registry_Api
     /**
      * Retrieve list of job types.
      *
-     * @abstract
-     *
      * @param array $criteria  Hash of filter criteria:
      *
      *                      'enabled' => If present, only retrieve enabled
      *                                   or disabled job types.
      *
-     * @return mixed Associative array of job types, or PEAR_Error on failure.
+     * @return array Associative array of job types
      */
     function listJobTypes($criteria = array())
     {
-        return $GLOBALS['hermes']->driver->listJobTypes($criteria);
+        return $GLOBALS['injector']->getInstance('Hermes_Driver')->listJobTypes($criteria);
     }
 
+    /**
+     *
+     * @see Hermes::listClients
+     */
     function listClients()
     {
         return Hermes::listClients();
     }
 
+    /**
+     * @TODO
+     *
+     * @param <type> $date
+     * @param <type> $client
+     * @param <type> $jobType
+     * @param <type> $costObject
+     * @param <type> $hours
+     * @param <type> $billable
+     * @param <type> $description
+     * @param <type> $notes
+     * @return <type>
+     */
     function recordTime($date, $client, $jobType,
                                 $costObject, $hours, $billable = true,
                                 $description = '', $notes = '')
@@ -388,14 +425,10 @@ class Hermes_Api extends Horde_Registry_Api
         $form->useToken(false);
         if ($form->validate($vars)) {
             $form->getInfo($vars, $info);
-            $result = $GLOBALS['hermes']->driver->enterTime($GLOBALS['registry']->getAuth(), $info);
-            if (is_a($result, 'PEAR_Error')) {
-                return $result;
-            } else {
-                return true;
-            }
+            return $GLOBALS['injector']->getInstance('Hermes_Driver')->enterTime($GLOBALS['registry']->getAuth(), $info);
         } else {
-            return PEAR::raiseError(_("Invalid entry: check data and retry."));
+            throw new Hermes_Exception(_("Invalid entry: check data and retry."));
         }
     }
+
 }
index 3a09611..f3df91c 100644 (file)
@@ -6,12 +6,14 @@
  *
  * Copyright 2001-2007 Robert E. Coyle <robertecoyle@hotmail.com>
  * Copyright 2010 Alkaloid Networks (http://projects.alkaloid.net/)
+ * Copyright 2010 The Horde Project (http://www.horde.org)
  *
  * See the enclosed file LICENSE for license information (BSD). If you
  * did not receive this file, see http://www.horde.org/licenses/bsdl.php.
  *
  * @author Robert E. Coyle <robertecoyle@hotmail.com>
  * @author  Ben Klang <ben@alkaloid.net>
+ * @author Michael J. Rubinsky <mrubinsk@horde.org>
  * @package Hermes
  */
 
@@ -43,23 +45,13 @@ class Hermes_Application extends Horde_Registry_Application
     public $version = 'H4 (2.0-git)';
 
     /**
-     * Driver object for reading/writing time entries
-     */
-    static public $driver = null;
-
-    /**
      * Initialization function.
      *
      * Global variables defined:
      */
     protected function _init()
     {
-        try {
-            $this->driver = Hermes::getDriver();
-        } catch (Hermes_Exception $e) {
-            $GLOBALS['notification']->push($e);
-            return false;
-        }
+        $GLOBALS['injector']->bindFactory('Hermes_Driver', 'Hermes_Injector_Factory_Driver', 'create');
     }
 
     /**
index 5f033c6..5ba8f2e 100644 (file)
@@ -3,36 +3,70 @@
  * Hermes_Driver:: defines an API for implementing storage backends
  * for Hermes.
  *
+ * See the enclosed file LICENSE for license information (BSD). If you
+ * did not receive this file, see http://www.horde.org/licenses/bsdl.php.
+ *
  * @author  Chuck Hagenbuch <chuck@horde.org>
- * @since   Hermes 0.1
+ * @author  Michael J. Rubinsky <mrubinsk@horde.org>
  * @package Hermes
  */
-class Hermes_Driver {
+abstract class Hermes_Driver
+{
+    /**
+     * Parameters
+     *
+     * @var array
+     */
+    protected $_params;
+
+    /**
+     * Constructor
+     *
+     */
+    public function __construct($params = array())
+    {
+        $this->_params = $params;
+    }
 
     /**
      * Retrieve a specific job type record.
      *
-     * @param integer $jobTypeID            The ID of the job type.
+     * @param integer $jobTypeID  The ID of the job type.
      *
-     * @return mixed Hash of job type properties, or PEAR_Error on failure.
+     * @return array Hash of job type properties.
+     * @throws Horde_Exception_NotFound
      */
-    function getJobTypeByID($jobTypeID)
+    public function getJobTypeByID($jobTypeID)
     {
         $jobtypes = $this->listJobTypes(array('id' => $jobTypeID));
-        if (is_a($jobtypes, 'PEAR_Error')) {
-            return $jobtypes;
-        }
         if (!isset($jobtypes[$jobTypeID])) {
-            return PEAR::raiseError(sprintf(_("No job type with ID \"%s\"."),
-                                            $jobTypeID));
+            throw new Horde_Exception_NotFound(sprintf(_("No job type with ID \"%s\"."), $jobTypeID));
         }
+
         return $jobtypes[$jobTypeID];
     }
 
     /**
+     * Retrieve a deliverable by ID.
+     *
+     * @param integer $deliverableID  The ID of the deliverable to retrieve.
+     *
+     * @return array Hash of deliverable's properties.
+     * @throws Horde_Exception_NotFound
+     */
+    function getDeliverableByID($deliverableID)
+    {
+        $deliverables = $this->listDeliverables(array('id' => $deliverableID));
+        if (!isset($deliverables[$deliverableID])) {
+            throw new Horde_Exception_NotFound(sprintf(_("Deliverable %d not found."), $deliverableID));
+        }
+
+        return $deliverables[$deliverableID];
+    }
+
+    /**
      * Add or update a job type record.
      *
-     * @abstract
      * @param array $jobtype        A hash of job type properties:
      *                  'id'        => The ID of the job, if updating.  If not
      *                                 present, a new job type is created.
@@ -40,57 +74,32 @@ class Hermes_Driver {
      *                  'enabled'   => Whether the job type is enabled for new
      *                                 time entry.
      *
-     * @return mixed The job's ID, or PEAR_Error on failure.
+     * @return The job's ID.
      */
-    function updateJobType($jobtype)
-    {
-        return PEAR::raiseError(_("Not implemented."));
-    }
+    abstract public function updateJobType($jobtype);
 
     /**
-     * Retrieve list of job types.
+     * @TODO
      *
-     * @abstract
+     */
+    abstract public function deleteJobType($jobTypeID);
+
+    /**
+     * Retrieve list of job types.
      *
      * @param array $criteria  Hash of filter criteria:
      *
      *                      'enabled' => If present, only retrieve enabled
      *                                   or disabled job types.
      *
-     * @return mixed Associative array of job types, or PEAR_Error on failure.
+     * @return array Hash of job type.
      */
-    function listJobTypes($criteria = array())
-    {
-        return PEAR::raiseError(_("Not implemented."));
-    }
+    abstract public function listJobTypes(array $criteria = array());
 
-    /**
-     * Retrieve a deliverable by ID.
-     *
-     * @param integer $deliverableID        The ID of the deliverable to
-     *                                      retrieve.
-     * @return mixed Hash of deliverable's properties, or PEAR_Error on
-     *               failure.
-     */
-    function getDeliverableByID($deliverableID)
-    {
-        $deliverables = $this->listDeliverables(array('id' => $deliverableID));
-        if (is_a($deliverables, 'PEAR_Error')) {
-            return $deliverables;
-        }
-
-        if (!isset($deliverables[$deliverableID])) {
-            return PEAR::raiseError(sprintf(_("Deliverable %d not found."),
-                                            $deliverableID));
-        }
-
-        return $deliverables[$deliverableID];
-    }
 
     /**
      * Add or update a deliverable.
      *
-     * @abstract
      * @param array $deliverable    A hash of deliverable properties:
      *                  'id'            => The ID of the deliverable, if
      *                                     updating.  If not present, a new
@@ -105,44 +114,52 @@ class Hermes_Driver {
      *                  'description'   => Text description (notes) for this
      *                                     deliverable.
      *
-     * @return mixed Integer ID of new or saved deliverable, or PEAR_Error on
-     *               failure.
+     * @return integer  ID of new or saved deliverable.
      */
-    function updateDeliverable($deliverable)
-    {
-        return PEAR::raiseError(_("Not implemented."));
-    }
+    abstract public function updateDeliverable($deliverable);
 
     /**
      * Retrieve list of deliverables.
      *
-     * @abstract
-     *
      * @param array $criteria  A hash of search criteria:
      *              'id'        => If present, only deliverable with
      *                             specified ID is searched for.
      *              'client_id' => If present, list is filtered by
      *                             client ID.
      *
-     * @return mixed Associative array of job types, or PEAR_Error on failure.
+     * @return array Hash of job types.
      */
-    function listDeliverables($criteria = array())
-    {
-        return PEAR::raiseError(_("Not implemented."));
-    }
+    abstract public function listDeliverables($criteria = array());
 
     /**
      * Delete a deliverable.
      *
-     * @abstract
-     * @param integer $deliverableID        The ID of the deliverable.
+     * @param integer $deliverableID  The ID of the deliverable.
      *
-     * @return mixed Null, or PEAR_Error on failure.
+     * @return void
      */
-    function deleteDeliverable($deliverableID)
-    {
-        return PEAR::raiseError(_("Not implemented."));
-    }
+    abstract public function deleteDeliverable($deliverableID);
+
+    /**
+     * @TODO:
+     *
+     */
+    abstract public function markAs($field, $hours);
+
+    /**
+     * @TODO
+     */
+    abstract public function getClientSettings($clientID);
+
+    /**
+     * @TODO
+     */
+    abstract public function updateClientSettings($clientID, $description, $exportId);
+
+    /**
+     * @TODO
+     */
+    abstract public function purge();
 
     /**
      * Attempts to return a concrete Hermes_Driver instance based on $driver.
index c34b93b..08d5924 100644 (file)
@@ -1,58 +1,41 @@
 <?php
 /**
- * Hermes storage implementation for PHP's PEAR database abstraction layer.
+ * Hermes SQL storage driver.
  *
- * Required values for $params:<pre>
- *      'phptype'       The database type (e.g. 'pgsql', 'mysql', etc.).</pre>
  *
- * Required by some database implementations:<pre>
- *      'hostspec'      The hostname of the database server.
- *      'protocol'      The communication protocol ('tcp', 'unix', etc.).
- *      'database'      The name of the database.
- *      '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>
+ * See the enclosed file LICENSE for license information (BSD). If you
+ * did not receive this file, see http://www.horde.org/licenses/bsdl.php.
  *
- * The table structure can be created by the
- * scripts/drivers/hermes.sql script.
- *
- * @author  Chuck Hagenbuch <chuck@horde.org
+ * @author  Chuck Hagenbuch <chuck@horde.org>
+ * @author  Michael J. Rubinsky <mrubinsk@horde.org>
  * @package Hermes
  */
-class Hermes_Driver_sql extends Hermes_Driver {
-
-    /**
-     * Hash containing connection parameters.
-     *
-     * @var array
-     */
-    var $_params = array();
-
+class Hermes_Driver_Sql extends Hermes_Driver
+{
     /**
      * Handle for the current database connection.
      *
-     * @var DB
+     * @var Horde_Db_Adapter
      */
-    var $_db;
+    protected $_db;
 
     /**
-     * Boolean indicating whether or not we're connected to the SQL server.
+     * Constructor
      *
-     * @var boolean
-     */
-    var $_connected = false;
-
-    /**
-     * Constructs a new SQL storage object.
+     * @param array $params  A hash containing connection parameters.
+     * <pre>
+     *   db_adapter => The Horde_Db_Adapter object
+     * </pre>
      *
-     * @param string $user      The user who owns these billing.
-     * @param array  $params    A hash containing connection parameters.
+     * @return Hermes_Driver_Sql  The driver object.
      */
-    function Hermes_Driver_sql($params = array())
+    public function __construct($params = array())
     {
-        $this->_params = $params;
+        parent::__construct($params);
+        if (empty($params['db_adapter'])) {
+            throw new InvalidArgumentException('Missing Horde_Db_Adapter parameter.');
+        }
+        $this->_db = $params['db_adapter'];
     }
 
     /**
@@ -71,29 +54,27 @@ class Hermes_Driver_sql extends Hermes_Driver {
      *                            billable hours.
      *             'description'  A short description of the work.
      *
-     * @return mixed  True on success, PEAR_Error on failure.
+     * @return integer  The new timeslice_id of the newly entered slice
+     * @throws Hermes_Exception
      */
-    function enterTime($employee, $info)
+    public function enterTime($employee, array $info)
     {
-        require_once 'Date.php';
-
-        /* Make sure we have a valid database connection. */
-        $this->_connect();
-
         /* Get job rate */
         $sql = 'SELECT jobtype_rate FROM hermes_jobtypes WHERE jobtype_id = ?';
-        $job_rate = $this->_db->getOne($sql, array($info['type']));
-
+        try {
+            $job_rate = $this->_db->selectValue($sql, array($info['type']));
+        } catch (Horde_Db_Exception $e) {
+            throw new Hermes_Exception($e);
+        }
         $dt = new Date($info['date']);
-        $timeslice_id = $this->_db->nextId('hermes_timeslices');
-        $sql = 'INSERT INTO hermes_timeslices (timeslice_id, ' .
+        $sql = 'INSERT INTO hermes_timeslices (' .
                'clientjob_id, employee_id, jobtype_id, ' .
                'timeslice_hours, timeslice_isbillable, ' .
                'timeslice_date, timeslice_description, ' .
                'timeslice_note, timeslice_rate, costobject_id) ' .
-               'VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)';
-        $values = array((int)$timeslice_id,
-                        $info['client'],
+               'VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?)';
+        
+        $values = array($info['client'],
                         $employee,
                         $info['type'],
                         $info['hours'],
@@ -105,8 +86,11 @@ class Hermes_Driver_sql extends Hermes_Driver {
                         (empty($info['costobject']) ? null :
                          $info['costobject']));
 
-        Horde::logMessage($sql, 'DEBUG');
-        return $this->_db->query($sql, $values);
+        try {
+            return $this->_db->insert($sql, $values);
+        } catch (Horde_Db_Exception $e) {
+            throw new Hermes_Exception($e);
+        }
     }
 
     /**
@@ -126,22 +110,22 @@ class Hermes_Driver_sql extends Hermes_Driver {
      *                        If any rows contain a 'delete' entry, those rows
      *                        will be deleted instead of updated.
      *
-     * @return mixed  True on success, PEAR_Error on failure.
+     * @return mixed  boolean
+     * @throws Horde_Exception_PermissionDenied
+     * @throws Hermes_Exception
      */
-    function updateTime($entries)
+    public function updateTime($entries)
     {
-        require_once 'Date.php';
-
-        /* Make sure we have a valid database connection. */
-        $this->_connect();
-
         foreach ($entries as $info) {
             if (!Hermes::canEditTimeslice($info['id'])) {
-                return PEAR::raiseError(_("Access denied; user cannot modify this timeslice."));
+                throw new Horde_Exception_PermissionDenied(_("Access denied; user cannot modify this timeslice."));
             }
             if (!empty($info['delete'])) {
-                $sql = 'DELETE FROM hermes_timeslices WHERE timeslice_id = ?';
-                $values = array((int)$info['id']);
+                try {
+                    return $this->_db->delete('DELETE FROM hermes_timeslices WHERE timeslice_id = ?', array((int)$info['id']));
+                } catch (Horde_Db_Exception $e) {
+                    throw new Hermes_Exception($e);
+                }
             } else {
                 if (isset($info['employee'])) {
                     $employee_cl = ' employee_id = ?,';
@@ -166,26 +150,27 @@ class Hermes_Driver_sql extends Hermes_Driver {
                                 $info['note'],
                                 (empty($info['costobject']) ? null : $info['costobject']),
                                 (int)$info['id']);
-            }
-
-            Horde::logMessage($sql, 'DEBUG');
-
-            $result = $this->_db->query($sql, $values);
-            if (is_a($result, 'PEAR_Error')) {
-                return $result;
+                try {
+                    return $this->_db->update($sql, $values);
+                } catch (Horde_Db_Exception $e) {
+                    throw new Hermes_Exception($e);
+                }
             }
         }
-
-        return true;
     }
 
-    function getHours($filters = array(), $fields = array())
+    /**
+     * @TODO
+     *
+     * @global <type> $conf
+     * @param <type> $filters
+     * @param <type> $fields
+     * @return <type> 
+     */
+    function getHours(array $filters = array(), array $fields = array())
     {
         global $conf;
 
-        /* Make sure we have a valid database connection. */
-        $this->_connect();
-
         $fieldlist = array(
             'id' => 'b.timeslice_id as id',
             'client' => ' b.clientjob_id as client',
@@ -272,17 +257,17 @@ class Hermes_Driver_sql extends Hermes_Driver {
                     break;
                 }
             }
+        }
+
         if (!empty($where)) {
             $sql .= ' WHERE ' . $where;
         }
-        }
-
         $sql .= ' ORDER BY timeslice_date DESC, clientjob_id';
-
-        Horde::logMessage($sql, 'DEBUG');
-        $hours = $this->_db->getAll($sql, DB_FETCHMODE_ASSOC);
-        if (is_a($hours, 'PEAR_Error')) {
-            return $hours;
+        
+        try {
+            $hours = $this->_db->selectAll($sql);
+        } catch (Horde_Db_Exception $e) {
+            throw new Hermes_Exception($e);
         }
 
         // Do per-record processing
@@ -292,16 +277,15 @@ class Hermes_Driver_sql extends Hermes_Driver {
 
             // Add cost object names to the results.
             if (empty($fields) || in_array('costobject', $fields)) {
-            
                 if (empty($hours[$hkey]['costobject'])) {
                     $hours[$hkey]['_costobject_name'] = '';
                 } else {
-                    $costobject = Hermes::getCostObjectByID($hours[$hkey]['costobject']);
-                    if (is_a($costobject, 'PEAR_Error')) {
-                        $hours[$hkey]['_costobject_name'] = sprintf(_("Error: %s"), $costobject->getMessage());
-                    } else {
-                        $hours[$hkey]['_costobject_name'] = $costobject['name'];
+                    try {
+                        $costobject = Hermes::getCostObjectByID($hours[$hkey]['costobject']);
+                    } catch (Horde_Exception $e) {
+                        $hours[$hkey]['_costobject_name'] = sprintf(_("Error: %s"), $e->getMessage());
                     }
+                    $hours[$hkey]['_costobject_name'] = $costobject['name'];
                 }
             }
         }
@@ -310,9 +294,9 @@ class Hermes_Driver_sql extends Hermes_Driver {
     }
 
     /**
-     * @access private
+     * @TODO
      */
-    function _equalClause($lhs, $rhs, $quote = true)
+    private function _equalClause($lhs, $rhs, $quote = true)
     {
         require_once 'Horde/SQL.php';
 
@@ -336,14 +320,19 @@ class Hermes_Driver_sql extends Hermes_Driver {
         return $ret . ' )';
     }
 
-    function markAs($field, $hours)
+    /**
+     * @TODO
+     *
+     * @param <type> $field
+     * @param <type> $hours
+     * @return <type>
+     */
+    public function markAs($field, $hours)
     {
         if (!count($hours)) {
             return false;
         }
 
-        $this->_connect();
-
         switch ($field) {
         case 'submitted':
             $h_field = 'timeslice_submitted';
@@ -365,16 +354,17 @@ class Hermes_Driver_sql extends Hermes_Driver {
         $sql = 'UPDATE hermes_timeslices SET ' . $h_field . ' = 1' .
                ' WHERE timeslice_id IN (' . implode(',', $ids) . ')';
 
-        Horde::logMessage($sql, 'DEBUG');
-
-        return $this->_db->query($sql);
+        return $this->_db->update($sql);
     }
 
-    function listJobTypes($criteria = array())
+    /**
+     * @TODO
+     *
+     * @param <type> $criteria
+     * @return <type>
+     */
+    public function listJobTypes(array $criteria = array())
     {
-        /* Make sure we have a valid database connection. */
-        $this->_connect();
-
         $where = array();
         $values = array();
         if (isset($criteria['id'])) {
@@ -391,35 +381,27 @@ class Hermes_Driver_sql extends Hermes_Driver {
                (empty($where) ? '' : (' WHERE ' . join(' AND ', $where))) .
                ' ORDER BY jobtype_name';
 
-        Horde::logMessage($sql, 'DEBUG');
-
-        $result = $this->_db->query($sql, $values);
-        if (is_a($result, 'PEAR_Error')) {
-            return $result;
+        try {
+            $rows = $this->_db->selectAll($sql, $values);
+        } catch (Horde_Db_Exception $e) {
+            throw new Hermes_Exception($e);
         }
 
         $results = array();
-        $row = $result->fetchRow(DB_FETCHMODE_ASSOC);
-        while (!empty($row) && !is_a($row, 'PEAR_Error')) {
+        foreach ($rows as $row) {
             $id = $row['jobtype_id'];
             $results[$id] = array('id'       => $id,
                                   'name'     => $row['jobtype_name'],
                                   'rate'     => (float)$row['jobtype_rate'],
                                   'billable' => (int)$row['jobtype_billable'],
                                   'enabled'  => !empty($row['jobtype_enabled']));
-            $row = $result->fetchRow(DB_FETCHMODE_ASSOC);
-        }
-        if (is_a($row, 'PEAR_Error')) {
-            return $row;
         }
 
         return $results;
     }
 
-    function updateJobType($jobtype)
+    public function updateJobType($jobtype)
     {
-        $this->_connect();
-
         if (!isset($jobtype['enabled'])) {
             $jobtype['enabled'] = 1;
         }
@@ -427,54 +409,58 @@ class Hermes_Driver_sql extends Hermes_Driver {
             $jobtype['billable'] = 1;
         }
         if (empty($jobtype['id'])) {
-            $jobtype['id'] = $this->_db->nextId('hermes_jobtypes');
-            $sql = 'INSERT INTO hermes_jobtypes (jobtype_id, jobtype_name, ' .
-                   ' jobtype_enabled, jobtype_rate, jobtype_billable) VALUES (?, ?, ?, ?, ?)';
-            $values = array($jobtype['id'], $jobtype['name'],
-                            (int)$jobtype['enabled'], (float)$jobtype['rate'], (int)$jobtype['billable']);
+            $sql = 'INSERT INTO hermes_jobtypes (jobtype_name, jobtype_enabled, '
+                . 'jobtype_rate, jobtype_billable) VALUES (?, ?, ?, ?)';
+            $values = array($jobtype['name'],
+                            (int)$jobtype['enabled'],
+                            (float)$jobtype['rate'],
+                            (int)$jobtype['billable']);
+
+            try {
+                return $this->_db->insert($sql, $values);
+            } catch (Horde_Db_Exception $e) {
+                throw new Hermes_Exception($e);
+            }
         } else {
             $sql = 'UPDATE hermes_jobtypes' .
                    ' SET jobtype_name = ?, jobtype_enabled = ?, jobtype_rate = ?,' .
                    ' jobtype_billable = ?  WHERE jobtype_id = ?';
-            $values = array($jobtype['name'], (int)$jobtype['enabled'],(float)$jobtype['rate'],
-                            (int)$jobtype['billable'], $jobtype['id']);
-        }
-
-        Horde::logMessage($sql, 'DEBUG');
+            $values = array($jobtype['name'],
+                            (int)$jobtype['enabled'],
+                            (float)$jobtype['rate'],
+                            (int)$jobtype['billable'],
+                            $jobtype['id']);
+
+            try {
+                $this->_db->update($sql, $values);
+            } catch (Horde_Db_Exception $e) {
+                throw new Hermes_Exception($e);
+            }
 
-        $result = $this->_db->query($sql, $values);
-        if (is_a($result, 'PEAR_Error')) {
-            return $result;
+            return $jobtype['id'];
         }
-
-        return $jobtype['id'];
     }
 
-    function deleteJobType($jobTypeID)
+    public function deleteJobType($jobTypeID)
     {
-        /* Make sure we have a valid database connection. */
-        $this->_connect();
-
-        $sql = 'DELETE FROM hermes_jobtypes WHERE jobtype_id = ?';
-        $values = array($jobTypeID);
-
-        Horde::logMessage($sql, 'DEBUG');
-
-        return $this->_db->query($sql, $values);
+        try {
+            return $this->_db->delete('DELETE FROM hermes_jobtypes WHERE jobtype_id = ?', array($jobTypeID));
+        } catch (Horde_Db_Exception $e) {
+            throw Hermes_Exception($e);
+        }
     }
 
-    function updateDeliverable($deliverable)
+    /**
+     * @see Hermes_Driver::updateDeliverable
+     */
+    public function updateDeliverable($deliverable)
     {
-        $this->_connect();
-
         if (empty($deliverable['id'])) {
-            $deliverable['id'] = $this->_db->nextId('hermes_deliverables');
-            $sql = 'INSERT INTO hermes_deliverables (deliverable_id,' .
+            $sql = 'INSERT INTO hermes_deliverables (' .
                    ' client_id, deliverable_name, deliverable_parent,' .
                    ' deliverable_estimate, deliverable_active,' .
-                   ' deliverable_description) VALUES (?, ?, ?, ?, ?, ?, ?)';
-            $values = array((int)$deliverable['id'],
-                            $deliverable['client_id'],
+                   ' deliverable_description) VALUES (?, ?, ?, ?, ?, ?)';
+            $values = array($deliverable['client_id'],
                             $deliverable['name'],
                             (empty($deliverable['parent']) ? null :
                              (int)$deliverable['parent']),
@@ -483,6 +469,12 @@ class Hermes_Driver_sql extends Hermes_Driver {
                             ($deliverable['active'] ? 1 : 0),
                             (empty($deliverable['description']) ? null :
                              $deliverable['description']));
+
+            try {
+                return $this->_db->insert($sql, $values);
+            } catch (Horde_Db_Exception $e) {
+                throw new Hermes_Exception($e);
+            }
         } else {
             $sql = 'UPDATE hermes_deliverables SET client_id = ?,' .
                    ' deliverable_name = ?, deliverable_parent = ?,' .
@@ -498,22 +490,20 @@ class Hermes_Driver_sql extends Hermes_Driver {
                             (empty($deliverable['description']) ? null :
                              $deliverable['description']),
                             $deliverable['id']);
+            try {
+                $this->_db->update($sql, $values);
+                return $deliverable['id'];
+            } catch (Horde_Db_Exception $e) {
+                throw new Hermes_Exception($e);
+            }
         }
-
-        Horde::logMessage($sql, 'DEBUG');
-
-        $result = $this->_db->query($sql, $values);
-        if (is_a($result, 'PEAR_Error')) {
-            return $result;
-        }
-
-        return $deliverable['id'];
     }
 
-    function listDeliverables($criteria = array())
+    /**
+     * @see Hermes_Driver::listDeliverables()
+     */
+    public function listDeliverables($criteria = array())
     {
-        $this->_connect();
-
         $where = array();
         $values = array();
         if (isset($criteria['id'])) {
@@ -536,17 +526,16 @@ class Hermes_Driver_sql extends Hermes_Driver {
         $sql = 'SELECT * FROM hermes_deliverables' .
                (count($where) ? ' WHERE ' . join(' AND ', $where) : '');
 
-        Horde::logMessage($sql, 'DEBUG');
-
-        $result = $this->_db->query($sql, $values);
-        if (is_a($result, 'PEAR_Error')) {
-            return $result;
+        try {
+            $rows = $this->_db->selectAll($sql, $values);
+        } catch (Horde_Db_Exception $e) {
+            throw new Hermes_Exception($e);
         }
 
         $deliverables = array();
-        $row = $result->fetchRow(DB_FETCHMODE_ASSOC);
-        while (!empty($row) && !is_a($row, 'PEAR_Error')) {
-
+        //$row = $result->fetchRow(DB_FETCHMODE_ASSOC);
+        //while (!empty($row) && !is_a($row, 'PEAR_Error')) {
+        foreach ($rows as $row) {
             $deliverable = array('id'          => $row['deliverable_id'],
                                  'client_id'   => $row['client_id'],
                                  'name'        => $row['deliverable_name'],
@@ -555,66 +544,55 @@ class Hermes_Driver_sql extends Hermes_Driver {
                                  'active'      => !empty($row['deliverable_active']),
                                  'description' => $row['deliverable_description']);
             $deliverables[$row['deliverable_id']] = $deliverable;
-            $row = $result->fetchRow(DB_FETCHMODE_ASSOC);
-        }
-
-        if (is_a($row, 'PEAR_Error')) {
-            return $row;
         }
 
         return $deliverables;
     }
 
-    function deleteDeliverable($deliverableID)
+    /**
+     * @see Hermes_Driver::updateDeliverable
+     * @throws Hermes_Exception
+     */
+    public function deleteDeliverable($deliverableID)
     {
-        $this->_connect();
-
-        $sql = 'SELECT COUNT(*) AS c FROM hermes_deliverables' .
-               ' WHERE deliverable_parent = ?';
+        $sql = 'SELECT COUNT(*) AS c FROM hermes_deliverables WHERE deliverable_parent = ?';
         $values = array($deliverableID);
 
-        Horde::logMessage($sql, 'DEBUG');
-
-        $result = $this->_db->query($sql, $values);
-        if (is_a($result, 'PEAR_Error')) {
-            return $result;
+        try {
+            $result = $this->_db->selectValue($sql, $values);
+        } catch (Horde_Db_Exception $e) {
+            throw new Hermes_Exception($e);
         }
-        $row = $result->fetchRow(DB_FETCHMODE_ASSOC);
-        if (!empty($row['c'])) {
-            return PEAR::raiseError(_("Cannot delete deliverable; it has children."));
+        if (!empty($result)) {
+            throw new Hermes_Exception(_("Cannot delete deliverable; it has children."));
         }
 
-        $sql = 'SELECT COUNT(*) AS c FROM hermes_timeslices' .
-               ' WHERE costobject_id = ?';
+        $sql = 'SELECT COUNT(*) AS c FROM hermes_timeslices WHERE costobject_id = ?';
         $values = array($deliverableID);
-
-        Horde::logMessage($sql, 'DEBUG');
-
-        $result = $this->_db->query($sql, $values);
-        if (is_a($result, 'PEAR_Error')) {
-            return $result;
+        try {
+            $result = $this->_db->selectValue($sql, $values);
+        } catch (Horde_Db_Exception $e) {
+            throw new Hermes_Exception($e);
         }
-        $row = $result->fetchRow(DB_FETCHMODE_ASSOC);
-        if (!empty($row['c'])) {
-            return PEAR::raiseError(_("Cannot delete deliverable; there is time entered on it."));
+        if (!empty($result)) {
+            throw Hermes_Exception(_("Cannot delete deliverable; there is time entered on it."));
         }
 
         $sql = 'DELETE FROM hermes_deliverables WHERE deliverable_id = ?';
         $values = array($deliverableID);
 
-        Horde::logMessage($sql, 'DEBUG');
-
-        return $this->_db->query($sql, $values);
+        try {
+            return $this->_db->delete($sql, $values);
+        } catch (Horde_Db_Exception $e) {
+            throw new Hermes_Exception($e);
+        }
     }
 
-    function getClientSettings($clientID)
+    public function getClientSettings($clientID)
     {
-        /* Make sure we have a valid database connection. */
-        $this->_connect();
-
         $clients = Hermes::listClients();
         if (empty($clientID) || !isset($clients[$clientID])) {
-            return PEAR::raiseError('Does not exist');
+            throw new Hermes_Exception('Does not exist');
         }
 
         $sql = 'SELECT clientjob_id, clientjob_enterdescription,' .
@@ -622,13 +600,16 @@ class Hermes_Driver_sql extends Hermes_Driver {
                ' WHERE clientjob_id = ?';
         $values = array($clientID);
 
-        Horde::logMessage($sql, 'DEBUG');
-
-        $clientJob = $this->_db->getAssoc($sql, false, $values);
-        if (is_a($clientJob, 'PEAR_Error')) {
-            return $clientJob;
+        try {
+            $rows = $this->_db->selectAll($sql, $values);
+        } catch (Horde_Db_Exception $e) {
+            throw new Hermes_Exception($e);
         }
-
+        $clientJob = array();
+        foreach ($rows as $row) {
+            $clientJob[$row['clientjob_id']] = array($row['clientjob_enterdescription'], $row['clientjob_exportid']);
+        }
+        
         if (isset($clientJob[$clientID])) {
             $settings = array('id' => $clientID,
                               'enterdescription' => $clientJob[$clientID][0],
@@ -643,82 +624,62 @@ class Hermes_Driver_sql extends Hermes_Driver {
         return $settings;
     }
 
-    function updateClientSettings($clientID, $enterdescription = 1, $exportid = null)
+    /**
+     * @TODO
+     *
+     * @param <type> $clientID
+     * @param <type> $enterdescription
+     * @param string $exportid
+     * @return <type>
+     */
+    public function updateClientSettings($clientID, $enterdescription = 1, $exportid = null)
     {
-        /* Make sure we have a valid database connection. */
-        $this->_connect();
-
         if (empty($exportid)) {
             $exportid = null;
         }
 
-        $sql = 'SELECT clientjob_id FROM hermes_clientjobs' .
-               ' WHERE clientjob_id = ?';
+        $sql = 'SELECT clientjob_id FROM hermes_clientjobs WHERE clientjob_id = ?';
         $values = array($clientID);
 
-        Horde::logMessage($sql, 'DEBUG');
-
-        if ($this->_db->getOne($sql, $values) !== $clientID) {
+        if ($this->_db->selectValue($sql, $values) !== $clientID) {
             $sql = 'INSERT INTO hermes_clientjobs (clientjob_id,' .
                    ' clientjob_enterdescription, clientjob_exportid)' .
                    ' VALUES (?, ?, ?)';
             $values = array($clientID, (int)$enterdescription, $exportid);
+
+            try {
+                return $this->_db->insert($sql, $values);
+            } catch (Horde_Db_Exception $e) {
+                throw new Hermes_Exception($e);
+            }
         } else {
             $sql = 'UPDATE hermes_clientjobs SET' .
                    ' clientjob_exportid = ?, clientjob_enterdescription = ?' .
                    ' WHERE clientjob_id = ?';
             $values = array($exportid, (int)$enterdescription, $clientID);
+            
+            try {
+                return $this->_db->update($sql, $values);
+            } catch (Horde_Db_Exception $e) {
+                throw new Hermes_Exception($e);
+            }
         }
-
-        Horde::logMessage($sql, 'DEBUG');
-
-        return $this->_db->query($sql, $values);
     }
 
-    function purge()
+    /**
+     * @TODO
+     * @global  $conf
+     * @return <type>
+     */
+    public function purge()
     {
         global $conf;
 
-        /* Make sure we have a valid database connection. */
-        $this->_connect();
-
         $query = 'DELETE FROM hermes_timeslices' .
                  ' WHERE timeslice_exported = ? AND timeslice_date < ?';
         $values = array(1, mktime(0, 0, 0, date('n'),
                                   date('j') - $conf['time']['days_to_keep']));
-        return $this->_db->query($query, $values);
+        return $this->_db->delete($query, $values);
     }
-
-    /**
-     * Attempts to open a persistent connection to the SQL server.
-     *
-     * @return boolean  True on success.
-     * @throws Horde_Exception
-     */
-    function _connect()
-    {
-        if ($this->_connected) {
-            return true;
-        }
-
-        $this->_db = $GLOBALS['injector']->getInstance('Horde_Core_Factory_DbPear')->create('rw', 'hermes', 'storage');
-
-        return true;
-    }
-
-    /**
-     * Disconnect from the SQL server and clean up the connection.
-     *
-     * @return boolean  True on success, false on failure.
-     */
-    function _disconnect()
-    {
-        if ($this->_connected) {
-            $this->_connected = false;
-            return $this->_db->disconnect();
-        }
-
-        return true;
-    }
-
+    
 }
index 53441a1..bc1c6f0 100644 (file)
@@ -69,39 +69,38 @@ class SearchForm extends Horde_Form {
 
     function getClientsType()
     {
-        $clients = Hermes::listClients();
-        if (is_a($clients, 'PEAR_Error')) {
-            return array('invalid', array(sprintf(_("An error occurred listing clients: %s"),
-                                           $clients->getMessage())));
-        } else {
-            $clients = array('' => _("- - None - -")) + $clients;
-            return array('multienum', array($clients));
+        try {
+            $clients = Hermes::listClients();
+        } catch (Exception $e) {
+            return array('invalid', array(sprintf(_("An error occurred listing clients: %s"), $e->getMessage())));
         }
+        $clients = array('' => _("- - None - -")) + $clients;
+
+        return array('multienum', array($clients));
     }
 
     function getJobTypesType()
     {
-        global $hermes;
-
-        $types = $hermes->driver->listJobTypes();
-        if (is_a($types, 'PEAR_Error')) {
+        try {
+            $types = $GLOBALS['injector']->getInstance('Hermes_Driver')->listJobTypes();
+        } catch (Horde_Exception $e) {
             return array('invalid', array(sprintf(_("An error occurred listing job types: %s"),
-                                           $types->getMessage())));
-        } else {
-            $values = array();
-            foreach ($types as $id => $type) {
-                $values[$id] = $type['name'];
-                if (empty($type['enabled'])) {
-                    $values[$id] .= _(" (DISABLED)");
-                }
+                                           $e->getMessage())));
+        }
+        $values = array();
+        foreach ($types as $id => $type) {
+            $values[$id] = $type['name'];
+            if (empty($type['enabled'])) {
+                $values[$id] .= _(" (DISABLED)");
             }
-            return array('multienum', array($values));
         }
+
+        return array('multienum', array($values));
     }
 
     function getCostObjectType($vars)
     {
-        global $hermes, $registry;
+        global $registry;
 
         $clients = $vars->get('clients');
         if (count($clients) == 0){
@@ -116,11 +115,10 @@ class SearchForm extends Horde_Form {
 
             foreach ($registry->listApps() as $app) {
                 if ($registry->hasMethod('listCostObjects', $app)) {
-                    $res = $registry->callByPackage($app, 'listCostObjects',
-                                                    array($criteria));
-                    if (is_a($res, 'PEAR_Error')) {
-                        global $notification;
-                        $notification->push(sprintf(_("Error retrieving cost objects from \"%s\": %s"), $registry->get('name', $app), $res->getMessage()), 'horde.error');
+                    try {
+                        $res = $registry->callByPackage($app, 'listCostObjects', array($criteria));
+                    } catch (Horde_Exception $e) {
+                        $GLOBALS['notification']->push(sprintf(_("Error retrieving cost objects from \"%s\": %s"), $registry->get('name', $app), $res->getMessage()), 'horde.error');
                         continue;
                     }
                     foreach (array_keys($res) as $catkey) {
@@ -153,8 +151,6 @@ class SearchForm extends Horde_Form {
 
     function getSearchCriteria(&$vars)
     {
-        require_once 'Date.php';
-
         if (!$this->isValid() || !$this->isSubmitted()) {
             return null;
         }
index 3d6453f..4974121 100644 (file)
@@ -16,8 +16,8 @@
  * @author  Chuck Hagenbuch <chuck@horde.org>
  * @package Hermes
  */
-class TimeForm extends Horde_Form {
-
+class TimeForm extends Horde_Form
+{
     function TimeForm(&$vars, $name = null)
     {
         parent::Horde_Form($vars, $name);
@@ -25,30 +25,30 @@ class TimeForm extends Horde_Form {
 
     function getJobTypeType()
     {
-        global $hermes;
-
-        $types = $hermes->driver->listJobTypes(array('enabled' => true));
-        if (is_a($types, 'PEAR_Error')) {
-            return array('invalid', array(sprintf(_("An error occurred listing job types: %s"),
-                                                  $types->getMessage())));
-        } elseif (count($types)) {
+        try {
+            $types = $GLOBALS['injector']->getInstance('Hermes_Driver')->listJobTypes(array('enabled' => true));
+        } catch (Horde_Exception $e) {
+            return array('invalid', array(sprintf(_("An error occurred listing job types: %s"), $e->getMessage())));
+        }
+        if (count($types)) {
             $values = array();
             foreach ($types as $id => $type) {
                 $values[$id] = $type['name'];
             }
             return array('enum', array($values));
-        } else {
-            return array('invalid', array(_("There are no job types configured.")));
         }
+
+        return array('invalid', array(_("There are no job types configured.")));
     }
 
     function getClientType()
     {
-        $clients = Hermes::listClients();
-        if (is_a($clients, 'PEAR_Error')) {
-            return array('invalid', array(sprintf(_("An error occurred listing clients: %s"),
-                                                  $clients->getMessage())));
-        } elseif ($clients) {
+        try {
+            $clients = Hermes::listClients();
+        } catch (Horde_Exception $e) {
+            return array('invalid', array(sprintf(_("An error occurred listing clients: %s"), $e->getMessage())));
+        }
+        if ($clients) {
             if (count($clients) > 1) {
                 $clients = array('' => _("--- Select A Client ---")) + $clients;
             }
@@ -62,7 +62,7 @@ class TimeForm extends Horde_Form {
      */
     function getCostObjectType($clientID = null)
     {
-        global $hermes, $registry;
+        global $registry;
 
         /* Check to see if any other active applications are exporting cost
          * objects to which we might want to bill our time. */
@@ -78,11 +78,10 @@ class TimeForm extends Horde_Form {
                 continue;
             }
 
-            $result = $registry->callByPackage($app, 'listCostObjects',
-                                               array($criteria));
-            if (is_a($result, 'PEAR_Error')) {
-                global $notification;
-                $notification->push(sprintf(_("Error retrieving cost objects from \"%s\": %s"), $registry->get('name', $app), $result->getMessage()), 'horde.error');
+            try {
+                $result = $registry->callByPackage($app, 'listCostObjects', array($criteria));
+            } catch (Horde_Exception $e) {
+                $GLOBALS['notification']->push(sprintf(_("Error retrieving cost objects from \"%s\": %s"), $registry->get('name', $app), $e->getMessage()), 'horde.error');
                 continue;
             }
 
@@ -116,12 +115,10 @@ class TimeForm extends Horde_Form {
                 if (!empty($GLOBALS['conf']['time']['sum_billable_only'])) {
                     $filter['billable'] = true;
                 }
-                $result = $hermes->driver->getHours($filter, array('hours'));
-                if (!is_a($result, 'PEAR_Error')) {
-                    foreach ($result as $entry) {
-                        if (!empty($entry['hours'])) {
-                            $hours += $entry['hours'];
-                        }
+                $result = $GLOBALS['injector']->getInstance('Hermes_Driver')->getHours($filter, array('hours'));
+                foreach ($result as $entry) {
+                    if (!empty($entry['hours'])) {
+                        $hours += $entry['hours'];
                     }
                 }
 
@@ -157,8 +154,8 @@ class TimeForm extends Horde_Form {
  * @author  Chuck Hagenbuch <chuck@horde.org>
  * @package Hermes
  */
-class TimeEntryForm extends TimeForm {
-
+class TimeEntryForm extends TimeForm
+{
     /**
      * Reference to the form field storing the cost objects.
      *
@@ -219,13 +216,14 @@ class TimeEntryForm extends TimeForm {
         }
 
         if ($vars->exists('client')) {
-            $info = $hermes->driver->getClientSettings($vars->get('client'));
-            if (!is_a($info, 'PEAR_Error') && !$info['enterdescription']) {
+            try {
+                $info = $GLOBALS['injector']->getInstance('Hermes_Driver')->getClientSettings($vars->get('client'));
+            } catch (Horde_Exception $e) {}
+            if (!$info['enterdescription']) {
                 $vars->set('description', _("See Attached Timesheet"));
             }
         }
         $descvar = &$this->addVariable(_("Description"), 'description', 'longtext', true, false, null, array(4, 60));
-
         $this->addVariable(_("Additional Notes"), 'note', 'longtext', false, false, null, array(4, 60));
     }
 
@@ -264,14 +262,13 @@ class TimeReviewForm extends TimeForm {
             $map = array();
             $clients = Hermes::listClients();
             foreach ($clients as $id => $name) {
-                $info = $hermes->driver->getClientSettings($id);
-                if (!is_a($info, 'PEAR_Error')) {
+                try {
+                    $info = $GLOBALS['injector']->getInstance('Hermes_Driver')->getClientSettings($id);
                     $map[$id] = $info['enterdescription'] ? '' : _("See Attached Timesheet");
-                } else {
+                } catch (Horde_Exception $e) {
                     $map[$id] = '';
                 }
             }
-
             require_once 'Horde/Form/Action.php';
             $action = &Horde_Form_Action::factory('conditional_setvalue',
                                                   array('map' => $map,
@@ -286,13 +283,13 @@ class TimeReviewForm extends TimeForm {
 
         require_once 'Horde/Identity.php';
         $auth = $GLOBALS['injector']->getInstance('Horde_Core_Factory_Auth')->create();
-        $users = $auth->listUsers();
-        if (!is_a($users, 'PEAR_Error')) {
+        try {
+            $users = $auth->listUsers();
             foreach ($users as $user) {
                 $identity = &Identity::singleton('none', $user);
                 $employees[$user] = $identity->getValue('fullname');
             }
-        }
+        } catch (Horde_Exception $e) {}
 
         $this->addVariable(_("Employee"), 'employee', 'enum', true, false, null, array($employees));
 
index 66c428f..04d733e 100644 (file)
@@ -2,29 +2,21 @@
 /**
  * Hermes Base Class.
  *
+ *
+ * See the enclosed file LICENSE for license information (BSD). If you
+ * did not receive this file, see http://www.horde.org/licenses/bsdl.php.
+ *
  * @author  Chuck Hagenbuch <chuck@horde.org>
  * @package Hermes
  */
-class Hermes {
-
-    public static function &getDriver()
-    {
-        global $conf;
-
-        require_once HERMES_BASE . '/lib/Driver.php';
-        return Hermes_Driver::singleton();
-    }
-
-    public static function listClients()
+class Hermes
+{
+    static public function listClients()
     {
         static $clients;
 
         if (is_null($clients)) {
             $result = $GLOBALS['registry']->call('clients/searchClients', array(array('')));
-            if (is_a($result, 'PEAR_Error')) {
-                return $result;
-            }
-
             $client_name_field = $GLOBALS['conf']['client']['field'];
             $clients = array();
             if (!empty($result)) {
@@ -40,7 +32,7 @@ class Hermes {
         return $clients;
     }
 
-    public static function getDayOfWeek($timestamp)
+    static public function getDayOfWeek($timestamp)
     {
         // Return 0-6, indicating the position of $timestamp in the
         // period.
@@ -51,7 +43,7 @@ class Hermes {
     /**
      * Build Hermes' list of menu items.
      */
-    public static function getMenu($returnType = 'object')
+    static public function getMenu($returnType = 'object')
     {
         global $registry, $conf, $print_link;
 
@@ -62,11 +54,11 @@ class Hermes {
         $menu->add(Horde::url('entry.php'), _("_New Time"), 'hermes.png', null, null, null, Horde_Util::getFormData('id') ? '__noselection' : null);
         $menu->add(Horde::url('search.php'), _("_Search"), 'search.png');
 
-        if ($conf['time']['deliverables'] && $registry->isAdmin('hermes:deliverables')) {
+        if ($conf['time']['deliverables'] && $registry->isAdmin(array('permission' => 'hermes:deliverables'))) {
             $menu->add(Horde::url('deliverables.php'), _("_Deliverables"), 'hermes.png');
         }
 
-        if ($conf['invoices']['driver'] && $registry->isAdmin('hermes:invoicing')) {
+        if ($conf['invoices']['driver'] && $registry->isAdmin(array('permission' => 'hermes:invoicing'))) {
             $menu->add(Horde::url('invoicing.php'), _("_Invoicing"), 'invoices.png');
         }
 
@@ -87,16 +79,15 @@ class Hermes {
         }
     }
 
-    public static function canEditTimeslice($id)
+    static public function canEditTimeslice($id)
     {
-        $hermes = $GLOBALS['registry']->getApiInstance('hermes', 'application');
         $perms = $GLOBALS['injector']->getInstance('Horde_Perms');
 
         if ($perms->hasPermission('hermes:review', $GLOBALS['registry']->getAuth(), Horde_Perms::EDIT)) {
             return true;
         }
 
-        $hours = $hermes->driver->getHours(array('id' => $id));
+        $hours = $GLOBALS['injector']->getInstance('Hermes_Driver')->getHours(array('id' => $id));
         if (!is_array($hours) || count($hours) != 1) {
             return false;
         }
@@ -114,10 +105,10 @@ class Hermes {
      * Rewrite an hours array into a format useable by Horde_Data::
      *
      * @param array $hours          This is an array of the results from
-     *                              $hermes->driver->getHours().
+     *                              $driver->getHours().
      * @return array an array suitable for Horde_Data::
      */
-    public static function makeExportHours($hours)
+    static public function makeExportHours($hours)
     {
         if (is_null($hours)) {
             return null;
@@ -161,17 +152,17 @@ class Hermes {
      *
      * @return array A two-element array of the type and the type's parameters.
      */
-    public static function getEmployeesType($enumtype = 'multienum')
+    static public function getEmployeesType($enumtype = 'multienum')
     {
         $auth = $GLOBALS['injector']->getInstance('Horde_Core_Factory_Auth')->create();
         if (!$auth->hasCapability('list')) {
             return array('text', array());
         }
-        $users = $auth->listUsers();
-        if (is_a($users, 'PEAR_Error')) {
+        try {
+            $users = $auth->listUsers();
+        } catch (Exception $e) {
             return array('invalid',
-                         array(sprintf(_("An error occurred listing users: %s"),
-                                       $users->getMessage())));
+                         array(sprintf(_("An error occurred listing users: %s"), $e->getMessage())));
         }
 
         $employees = array();
@@ -187,7 +178,7 @@ class Hermes {
         return array($enumtype, array($employees));
     }
 
-    public static function getCostObjectByID($id)
+    static public function getCostObjectByID($id)
     {
         static $cost_objects;
 
@@ -196,9 +187,6 @@ class Hermes {
 
             if (!isset($cost_objects[$app])) {
                 $results = $GLOBALS['registry']->callByPackage($app, 'listCostObjects', array(array()));
-                if (is_a($results, 'PEAR_Error')) {
-                    return $results;
-                }
                 $cost_objects[$app] = $results;
             }
 
@@ -211,10 +199,10 @@ class Hermes {
             }
         }
 
-        return PEAR::raiseError(_("Not found."));
+        throw new Horde_Exception_NotFound();
     }
 
-    public static function tabs()
+    static public function tabs()
     {
         /* Build search mode tabs. */
         $sUrl = Horde::selfUrl();
diff --git a/hermes/lib/Injector/Factory/Driver.php b/hermes/lib/Injector/Factory/Driver.php
new file mode 100644 (file)
index 0000000..da9c448
--- /dev/null
@@ -0,0 +1,51 @@
+<?php
+/**
+ * Hermes_Driver:: factory
+ *
+ * @author   Michael J. Rubinsky <mrubinsk@horde.org>
+ * @category Horde
+ * @license  http://www.fsf.org/copyleft/gpl.html GPL
+ * @package  Hermes
+ */
+class Hermes_Injector_Factory_Driver
+{
+    /**
+     *
+     * @var array
+     */
+    private $_instances = array();
+
+    /**
+     *
+     * @var Horde_Injector
+     */
+    private $_injector;
+
+    public function __construct(Horde_Injector $injector)
+    {
+        $this->_injector = $injector;
+    }
+
+    /**
+     * Return an Hermes_Storage instance.
+     *
+     * @return Ansel_Storage
+     */
+    public function create()
+    {
+        $driver = $GLOBALS['conf']['storage']['driver'];
+        $signature = serialize(array($driver, $GLOBALS['conf']['storage']['params']['driverconfig']));
+        if (empty($this->_instances[$signature])) {
+            if ($driver == 'sql' && $GLOBALS['conf']['storage']['params']['driverconfig'] == 'horde') {
+                $params = array('db_adapter' => $this->_injector->getInstance('Horde_Db_Adapter'));
+            } else {
+                throw new Horde_Exception('Using non-global db connection not yet supported.');
+            }
+            $class = 'Hermes_Driver_' . $driver;
+            $this->_instances[$signature] = new $class($params);
+        }
+
+        return $this->_instances[$signature];
+    }
+
+}
diff --git a/hermes/migration/1_hermes_base_tables.php b/hermes/migration/1_hermes_base_tables.php
new file mode 100644 (file)
index 0000000..7a2d949
--- /dev/null
@@ -0,0 +1,98 @@
+<?php
+/**
+ * Create Hermes base tables
+ *
+ * Copyright 2010 The Horde Project (http://www.horde.org/)
+ *
+ * See the enclosed file COPYING for license information (GPL). If you
+ * did not receive this file, see http://www.fsf.org/copyleft/gpl.html.
+ *
+ * @author   Michael J. Rubinsky <mrubinsk@horde.org>
+ * @category Horde
+ * @license  http://www.fsf.org/copyleft/gpl.html GPL
+ * @package  Hermes
+ */
+class HermesBaseTables extends Horde_Db_Migration_Base
+{
+    /**
+     * Upgrade.
+     */
+    public function up()
+    {
+        $tableList = $this->tables();
+
+        if (!in_array('hermes_timeslices', $tableList)) {
+            // Create: hermes_timeslice
+            $t = $this->createTable('hermes_timeslices', array('primaryKey' => false));
+            $t->column('timeslice_id', 'integer', array('null' => false));
+            $t->column('clientjob_id', 'string', array('limit' => 255, 'null' => false));
+            $t->column('employee_id', 'string', array('limit' => 255, 'null' => false));
+            $t->column('jobtype_id', 'integer', array('null' => false));
+            $t->column('timeslice_hours', 'decimal', array('precision' => 10, 'scale' => 2, 'null' => false));
+            $t->column('timeslice_rate', 'decimal', array('precision' => 10, 'scale' => 2));
+            $t->column('timeslice_isbillable', 'integer', array('default' => 0, 'null' => false));
+            $t->column('timeslice_date', 'integer', array('null' => false));
+            $t->column('timeslice_description', 'text', array('null' => false));
+            $t->column('timeslice_note', 'text');
+            $t->column('timeslice_submitted', 'integer', array('default' => 0, 'null' => false));
+            $t->column('timeslice_exported', 'integer', array('default' => 0, 'null' => false));
+            $t->column('costobject_id', 'string', array('limit' => 255));
+            $t->primaryKey(array('timeslice_id'));
+            $t->end();
+        }
+
+        if (!in_array('hermes_jobtypes', $tableList)) {
+            // Create: hermes_jobtypes
+            $t = $this->createTable('hermes_jobtypes', array('primaryKey' => false));
+            $t->column('jobtype_id', 'integer', array('null' => false));
+            $t->column('jobtype_name', 'string', array('limit' => 255));
+            $t->column('jobtype_enabled', 'integer', array('default' => 1, 'null' => false));
+            $t->column('jobtype_rate', 'decimal', array('precision' => 10, 'scale' => 2));
+            $t->column('jobtype_billable', 'integer', array('default' => 0, 'null' => false));
+            $t->primaryKey(array('jobtype_id'));
+            $t->end();
+        }
+
+        if (!in_array('hermes_clientjobs', $tableList)) {
+            // Create: hermes_clientjobs
+            $t = $this->createTable('hermes_clientjobs', array('primaryKey' => false));
+            $t->column('clientjob_id', 'string', array('limit' => 255, 'null' => false));
+            $t->column('clientjob_enterdescription', 'integer', array('null' => false, 'default' => 1));
+            $t->column('clientjob_exportid', 'string', array('limit' => 255));
+            $t->primaryKey(array('clientjob_id'));
+            $t->end();
+        }
+
+        if (!in_array('hermes_deliverables', $tableList)) {
+            // Create: hermes_deliverables
+            $t = $this->createTable('hermes_deliverables', array('primaryKey' => false));
+            $t->column('deliverable_id', 'integer', array('null' => false));
+            $t->column('client_id', 'string', array('limit' => 255, 'null' => false));
+            $t->column('deliverable_name', 'string', array('limit' => 255, 'null' => false));
+            $t->column('deliverable_parent', 'integer');
+            $t->column('deliverable_estimate', 'decimal', array('precision' => 10, 'scale' => 2));
+            $t->column('deliverable_active', 'integer', array('default' => 1, 'null' => false));
+            $t->column('deliverable_description', 'text');
+            $t->primaryKey(array('deliverable_id'));
+            $t->end();
+
+            $this->addIndex('hermes_deliverables', array('client_id'));
+            $this->addIndex('hermes_deliverables', array('deliverable_active'));
+        }
+    }
+
+    /**
+     * Downgrade
+     *
+     */
+    public function down()
+    {
+        $tableList = $this->tables();
+
+        $this->dropTable('hermes_timeslices');
+        $this->dropTable('hermes_jobtypes');
+        $this->dropTable('hermes_clientjobs');
+        $this->dropTable('hermes_deliverables');
+    }
+
+}
diff --git a/hermes/migration/2_hermes_autoincrement.php b/hermes/migration/2_hermes_autoincrement.php
new file mode 100644 (file)
index 0000000..6888de9
--- /dev/null
@@ -0,0 +1,40 @@
+<?php
+/**
+ * Create Hermes base tables
+ *
+ * Copyright 2010 The Horde Project (http://www.horde.org/)
+ *
+ * See the enclosed file COPYING for license information (GPL). If you
+ * did not receive this file, see http://www.fsf.org/copyleft/gpl.html.
+ *
+ * @author   Michael J. Rubinsky <mrubinsk@horde.org>
+ * @category Horde
+ * @license  http://www.fsf.org/copyleft/gpl.html GPL
+ * @package  Hermes
+ */
+class HermesAutoincrement extends Horde_Db_Migration_Base
+{
+    /**
+     * Upgrade.
+     */
+    public function up()
+    {
+        $this->changeColumn('hermes_timeslices', 'timeslice_id', 'integer', array('autoincrement' => true, 'null' => false, 'default' => null));
+        $this->changeColumn('hermes_jobtypes', 'jobtype_id', 'integer', array('autoincrement' => true, 'null' => false, 'default' => null));
+        $this->changeColumn('hermes_deliverables', 'deliverable_id', 'integer', array('autoincrement' => true, 'null' => false, 'default' => null));
+
+    }
+
+    /**
+     * Downgrade
+     *
+     */
+    public function down()
+    {
+        $this->changeColumn('hermes_timeslices', 'timeslice_id', 'integer', array('autoincrement' => false, 'null' => false, 'default' => null));
+        $this->changeColumn('hermes_jobtypes', 'jobtype_id', 'integer', array('autoincrement' => false, 'null' => false, 'default' => null));
+        $this->changeColumn('hermes_deliverables', 'deliverable_id', 'integer', array('autoincrement' => false, 'null' => false, 'default' => null));
+
+    }
+
+}
index 378e889..4fd4628 100755 (executable)
@@ -13,4 +13,4 @@ require_once dirname(__FILE__) . '/lib/Application.php';
 $hermes = Horde_Registry::appInit('hermes');
 
 printf(_("Deleting data that was exported/billed more than %s days ago.\n"), $conf['time']['days_to_keep']);
-$hermes->driver->purge();
+$GLOBALS['injector']->getInstance('Hermes_Driver')->purge();
index 09b671b..affeb29 100644 (file)
@@ -9,7 +9,9 @@
  */
 
 require_once dirname(__FILE__) . '/lib/Application.php';
-$hermes = Horde_Registry::appInit('hermes');
+Horde_Registry::appInit('hermes');
+
+// @TODO
 require_once HERMES_BASE . '/lib/Forms/Export.php';
 require_once HERMES_BASE . '/lib/Forms/Search.php';
 require_once HERMES_BASE . '/lib/Forms/Time.php';
@@ -19,14 +21,13 @@ $vars = Horde_Variables::getDefaultVariables();
 
 $delete = $vars->get('delete');
 if (!empty($delete)) {
-    $result = $hermes->driver->updateTime(array(array('id' => $delete, 'delete' => true)));
-    if (is_a($result, 'PEAR_Error')) {
-        Horde::logMessage($result, __FILE__, __LINE__, PEAR_LOG_ERR);
-        $notification->push(sprintf(_("There was an error deleting the time: %s"), $result->getMessage()), 'horde.error');
-    } else {
-        $notification->push(_("The time entry was successfully deleted."), 'horde.success');
-        $vars->remove('delete');
+    try {
+        $GLOBALS['injector']->getInstance('Hermes_Driver')->updateTime(array(array('id' => $delete, 'delete' => true)));
+    } catch (Horde_Exception $e) {
+        $notification->push(sprintf(_("There was an error deleting the time: %s"), $e->getMessage()), 'horde.error');
     }
+    $notification->push(_("The time entry was successfully deleted."), 'horde.success');
+    $vars->remove('delete');
 }
 
 $criteria = null;
@@ -57,32 +58,32 @@ case 'exportform':
             $form->validate($vars);
             if ($form->isValid()) {
                 $form->getInfo($vars, $info);
-                $hours = $hermes->driver->getHours($criteria);
-                if (is_a($hours, 'PEAR_Error')) {
-                    $notification->push($hours, 'horde.error');
-                } elseif (is_null($hours) || count($hours) == 0) {
-                    $notification->push(_("No time to export!"), 'horde.error');
-                } else {
-                    $exportHours = Hermes::makeExportHours($hours);
-                    $data = Horde_Data::factory(array('hermes', $info['format']));
-                    $filedata = $data->exportData($exportHours);
-                    $browser->downloadHeaders($data->getFilename('export'), $data->getContentType(), false, strlen($filedata));
-
-                    echo $filedata;
-                    if (!empty($info['mark_exported']) &&
-                        $info['mark_exported'] == 'yes' &&
-                        $perms->hasPermission('hermes:review', $GLOBALS['registry']->getAuth(),
-                                              Horde_Perms::EDIT)) {
-                        $hermes->driver->markAs('exported', $hours);
+                try {
+                    $hours = $GLOBALS['injector']->getInstance('Hermes_Driver')->getHours($criteria);
+                    if (is_null($hours) || count($hours) == 0) {
+                        $notification->push(_("No time to export!"), 'horde.error');
+                    } else {
+                        $exportHours = Hermes::makeExportHours($hours);
+                        $data = Horde_Data::factory(array('hermes', $info['format']));
+                        $filedata = $data->exportData($exportHours);
+                        $browser->downloadHeaders($data->getFilename('export'), $data->getContentType(), false, strlen($filedata));
+                        echo $filedata;
+                        if (!empty($info['mark_exported']) &&
+                            $info['mark_exported'] == 'yes' &&
+                            $perms->hasPermission('hermes:review', $GLOBALS['registry']->getAuth(),
+                                                  Horde_Perms::EDIT)) {
+                            $GLOBALS['injector']->getInstance('Hermes_Driver')->markAs('exported', $hours);
+                        }
+                        exit;
                     }
-                    exit;
+                } catch (Horde_Exception $e) {
+                    $notification->push($hours, 'horde.error');
                 }
             }
         }
     }
 }
 
-
 $title = _("Search for Time");
 $print_view = (bool)$vars->get('print');
 if (!$print_view) {
index 2663045..7e4ccec 100644 (file)
@@ -10,7 +10,7 @@
  */
 
 require_once dirname(__FILE__) . '/lib/Application.php';
-$hermes = Horde_Registry::appInit('hermes');
+Horde_Registry::appInit('hermes');
 
 require_once HERMES_BASE . '/lib/Forms/Time.php';
 require_once HERMES_BASE . '/lib/Table.php';
@@ -19,14 +19,13 @@ $vars = Horde_Variables::getDefaultVariables();
 
 $delete = $vars->get('delete');
 if (!empty($delete)) {
-    $result = $hermes->driver->updateTime(array(array('id' => $delete, 'delete' => true)));
-    if (is_a($result, 'PEAR_Error')) {
-        Horde::logMessage($result, __FILE__, __LINE__, PEAR_LOG_ERR);
-        $notification->push(sprintf(_("There was an error deleting the time: %s"), $result->getMessage()), 'horde.error');
-    } else {
-        $notification->push(_("The time entry was successfully deleted."), 'horde.success');
-        $vars->remove('delete');
+    try {
+        $GLOBALS['injector']->getInstance('Hermes_Driver')->updateTime(array(array('id' => $delete, 'delete' => true)));
+    } catch (Horde_Exception $e) {
+        $notification->push(sprintf(_("There was an error deleting the time: %s"), $e->getMessage()), 'horde.error');
     }
+    $notification->push(_("The time entry was successfully deleted."), 'horde.success');
+    $vars->remove('delete');
 }
 
 switch ($vars->get('formname')) {
@@ -40,13 +39,12 @@ case 'submittimeform':
         foreach ($item as $id => $val) {
             $time[] = array('id' => $id);
         }
-        $result = $hermes->driver->markAs('submitted', $time);
-        if (is_a($result, 'PEAR_Error')) {
-            $notification->push(sprintf(_("There was an error submitting your time: %s"), $result->getMessage()), 'horde.error');
-        } else {
-            $notification->push(_("Your time was successfully submitted."),
-                                'horde.success');
+        try {
+            $GLOBALS['injector']->getInstance('Hermes_Driver')->markAs('submitted', $time);
+            $notification->push(_("Your time was successfully submitted."), 'horde.success');
             $vars = new Horde_Variables();
+        } catch (Horde_Exception $e) {
+            $notification->push(sprintf(_("There was an error submitting your time: %s"), $result->getMessage()), 'horde.error');
         }
     }
     break;