0010080: caldav client: update tasks
authorPhilipp Schüle <p.schuele@metaways.de>
Fri, 29 Aug 2014 07:53:33 +0000 (09:53 +0200)
committerPhilipp Schüle <p.schuele@metaways.de>
Thu, 4 Sep 2014 09:26:47 +0000 (11:26 +0200)
* adds etag column to tasks
* moves etag functions to abstract sql backend
* activates cli update for tasks

https://forge.tine20.org/mantisbt/view.php?id=10080

Change-Id: Ibf977c2c7782e947ae909ccd5e53cfd7d7fe3fd5
Reviewed-on: http://gerrit.tine20.com/customers/1063
Tested-by: Jenkins CI (http://ci.tine20.com/)
Reviewed-by: Philipp Schüle <p.schuele@metaways.de>
tine20/Calendar/Backend/Sql.php
tine20/Tasks/Backend/Sql.php
tine20/Tasks/Import/CalDav/Client.php
tine20/Tasks/Model/Task.php
tine20/Tasks/Model/TaskFilter.php
tine20/Tasks/Setup/Update/Release8.php [new file with mode: 0644]
tine20/Tasks/Setup/setup.xml
tine20/Tinebase/Backend/Sql/Abstract.php

index e824bb2..275146b 100644 (file)
@@ -826,76 +826,4 @@ class Calendar_Backend_Sql extends Tinebase_Backend_Sql_Abstract
             }
         }
     }
-    
-    /**
-     * sets etags, expects ids as keys and etags as value
-     * 
-     * @param array $etags
-     */
-    public function setETags(array $etags)
-    {
-        foreach ($etags as $id => $etag) {
-            //$etag = replaceSpecialChars($etag);
-            
-            $where  = array(
-                $this->_db->quoteInto($this->_db->quoteIdentifier($this->_identifier) . ' = ?', $id),
-            );
-            $this->_db->update($this->_tablePrefix . $this->_tableName, array('etag' => $etag), $where);
-        }
-    }
-    
-    /**
-     * checks if there is an event with this id and etag, or an event with the same id 
-     * 
-     * @param string $id
-     * @param string $etag
-     * @return boolean
-     * @throws Tinebase_Exception_NotFound
-     */
-    public function checkETag($id, $etag)
-    {
-        //$etag = replaceSpecialChars($etag);
-        
-        $select = $this->_db->select();
-        $select->from(array($this->_tableName => $this->_tablePrefix . $this->_tableName), $this->_identifier);
-        $select->where($this->_db->quoteIdentifier($this->_identifier) . ' = ?', $id);
-        $select->orWhere($this->_db->quoteIdentifier('uid') . ' = ?', $id);
-        
-        $stmt = $select->query();
-        $queryResult = $stmt->fetch();
-        $stmt->closeCursor();
-        
-        if ($queryResult === false) {
-            throw new Tinebase_Exception_NotFound('no event with id ' . $id .' found');
-        }
-        
-        $select->where($this->_db->quoteIdentifier('etag') . ' = ?', $etag);
-        $stmt = $select->query();
-        $queryResult = $stmt->fetch();
-        $stmt->closeCursor();
-        
-        return ($queryResult !== false);
-    }
-
-    /**
-     * return etag set for given container
-     * @param unknown $containerId
-     * @return multitype:Ambigous <mixed, Ambigous <string, boolean, mixed>>
-     */
-    public function getEtagsForContainerId($containerId)
-    {
-        $select = $this->_db->select();
-        $select->from(array($this->_tableName => $this->_tablePrefix . $this->_tableName), array($this->_identifier, 'etag', 'uid'));
-        $select->where($this->_db->quoteIdentifier('container_id') . ' = ?', $containerId);
-        $select->where($this->_db->quoteIdentifier('is_deleted') . ' = ?', 0);
-        
-        $stmt = $select->query();
-        $queryResult = $stmt->fetchAll();
-        
-        $result = array();
-        foreach ($queryResult as $row) {
-            $result[$row['id']] = $row;
-        }
-        return $result;
-    }
 }
index 72850b9..6fbf515 100644 (file)
@@ -187,4 +187,4 @@ class Tasks_Backend_Sql extends Tinebase_Backend_Sql_Abstract
         }
         return $this->_tables[$_tablename];
     }
-}
\ No newline at end of file
+}
index 75f2300..ff5bc9f 100644 (file)
@@ -18,7 +18,6 @@
  * @subpackage  Import
  * 
  * @todo        move generic parts from Calendar_Import_CalDav_Client to Tinebase and extend Tinebase_Import_CalDav_Client
- * @todo        finish update
  */
 class Tasks_Import_CalDav_Client extends Calendar_Import_CalDav_Client
 {
@@ -29,103 +28,6 @@ class Tasks_Import_CalDav_Client extends Calendar_Import_CalDav_Client
     protected $webdavFrontend = 'Tasks_Frontend_WebDAV_Task';
     protected $_uuidPrefix = 'aa-';
     
-    /**
-     * 
-     * @param string $onlyCurrentUserOrganizer
-     * @return boolean
-     * 
-     * @todo generalize
-     * @todo implement for tasks
-     */
-    public function updateAllCalendarData($onlyCurrentUserOrganizer = false)
-    {
-//         if (count($this->calendarICSs) < 1 && ! $this->findAllCalendarICSs()) {
-//             if (Tinebase_Core::isLogLevel(Zend_Log::INFO))
-//                 Tinebase_Core::getLogger()->info(__METHOD__ . '::' . __LINE__ . ' no calendars found for: ' . $this->userName);
-//             return false;
-//         }
-        
-//         $newICSs = array();
-//         $calendarEventBackend = Tasks_Controller_Task::getInstance()->getBackend();
-        
-//         foreach ($this->calendarICSs as $calUri => $calICSs) {
-//             $start = 0;
-//             $max = count($calICSs);
-//             $etags = array();
-//             do {
-//                 $requestEnd = '';
-//                 for ($i = $start; $i < $max && $i < ($this->maxBulkRequest+$start); ++$i) {
-//                     $requestEnd .= '  <a:href>' . $calICSs[$i] . "</a:href>\n";
-//                 }
-//                 $start = $i;
-//                 $requestEnd .= '</b:calendar-multiget>';
-//                 $result = $this->calDavRequest('REPORT', $calUri, self::getEventETagsRequest . $requestEnd, 1);
-                
-//                 foreach ($result as $key => $value) {
-//                     if (isset($value['{DAV:}getetag'])) {
-//                         $name = explode('/', $key);
-//                         $name = end($name);
-//                         $id = $this->_getEventIdFromName($name);
-//                         $etags[$key] = array( 'id' => $id, 'etag' => $value['{DAV:}getetag']);
-//                     }
-//                 }
-//             } while($start < $max);
-            
-//             //check etags
-//             if (Tinebase_Core::isLogLevel(Zend_Log::DEBUG)) Tinebase_Core::getLogger()->debug(__METHOD__ . '::' . __LINE__ . ' '
-//                 . ' Got ' . count($etags) . ' etags');
-//             if (Tinebase_Core::isLogLevel(Zend_Log::TRACE)) Tinebase_Core::getLogger()->trace(__METHOD__ . '::' . __LINE__ . ' '
-//                 . ' etags: ' . print_r($etags, true));
-            
-//             // @todo find out deleted events
-//             foreach ($etags as $ics => $data) {
-//                 try {
-//                     $etagCheck = $calendarEventBackend->checkETag($data['id'], $data['etag']);
-//                     if ($etagCheck) {
-//                         continue; // same
-//                     } else {
-//                         $eventExists = true; // different
-//                     }
-//                 } catch (Tinebase_Exception_NotFound $tenf) {
-//                     $eventExists = false;
-//                 }
-                
-//                 if (!isset($newICSs[$calUri])) {
-//                     $newICSs[$calUri] = array();
-//                     $this->existingRecordIds[$calUri] = array();
-//                 }
-//                 $newICSs[$calUri][] = $ics;
-//                 if ($eventExists) {
-//                     $this->existingRecordIds[$calUri][] = $data['id'];
-//                 }
-//             }
-//         }
-        
-//         if (($count = count($newICSs)) > 0) {
-//             if (Tinebase_Core::isLogLevel(Zend_Log::INFO)) Tinebase_Core::getLogger()->info(__METHOD__ . '::' . __LINE__ . ' ' 
-//                     . $count . ' calendar(s) changed for: ' . $this->userName);
-//             if (Tinebase_Core::isLogLevel(Zend_Log::DEBUG)) Tinebase_Core::getLogger()->info(__METHOD__ . '::' . __LINE__ . ' ' 
-//                     . ' events changed: ' . print_r($newICSs, true));
-//             $this->calendarICSs = $newICSs;
-//             $this->importAllCalendarData($onlyCurrentUserOrganizer, /* $update = */ true);
-//         } else {
-//             if (Tinebase_Core::isLogLevel(Zend_Log::NOTICE))
-//                 Tinebase_Core::getLogger()->notice(__METHOD__ . '::' . __LINE__ . ' no changes found for: ' . $this->userName);
-//         }
-    }
-    
-    /**
-     * (non-PHPdoc)
-     * @see Calendar_Import_CalDav_Client::_setEtags()
-     * 
-     * @todo implement
-     */
-    protected function _setEtags($etags)
-    {
-//         $calendarEventBackend = Tinebase_Core::getApplicationInstance($this->appName, $this->modelName)->getBackend();
-//         $calendarEventBackend->setETags($etags);
-    }
-
     protected function _getAllGrants()
     {
         return array(
index 73f6df3..443e735 100644 (file)
@@ -88,6 +88,7 @@ class Tasks_Model_Task extends Tinebase_Record_Abstract
         'summary'              => array(Zend_Filter_Input::PRESENCE => 'required'      ),
         'url'                  => array(Zend_Filter_Input::ALLOW_EMPTY => true         ),
         'uid'                  => array(Zend_Filter_Input::ALLOW_EMPTY => true         ),
+        'etag'                 => array(Zend_Filter_Input::ALLOW_EMPTY => true         ),
         // ical common fields with multiple appearance
         'attach'               => array(Zend_Filter_Input::ALLOW_EMPTY => true        ),
         'attendee'             => array(Zend_Filter_Input::ALLOW_EMPTY => true        ),
index 10bd308..ff214e7 100644 (file)
@@ -38,6 +38,7 @@ class Tasks_Model_TaskFilter extends Tinebase_Model_Filter_FilterGroup
     protected $_filterModel = array(
         'id'                   => array('filter' => 'Tinebase_Model_Filter_Id', 'options' => array('modelName' => 'Tasks_Model_Task')),
         'uid'                  => array('filter' => 'Tinebase_Model_Filter_Text'),
+        'etag'                 => array('filter' => 'Tinebase_Model_Filter_Text'),
         'query'                => array('filter' => 'Tinebase_Model_Filter_Query', 'options' => array('fields' => array('summary', 'description'))),
         'organizer'            => array('filter' => 'Tinebase_Model_Filter_User'),
         'status'               => array('filter' => 'Tinebase_Model_Filter_Text'),
diff --git a/tine20/Tasks/Setup/Update/Release8.php b/tine20/Tasks/Setup/Update/Release8.php
new file mode 100644 (file)
index 0000000..7d2181d
--- /dev/null
@@ -0,0 +1,40 @@
+<?php
+/**
+ * Tine 2.0
+ *
+ * @package     Tasks
+ * @subpackage  Setup
+ * @license     http://www.gnu.org/licenses/agpl.html AGPL3
+ * @copyright   Copyright (c) 2014 Metaways Infosystems GmbH (http://www.metaways.de)
+ * @author      Philipp Schüle <p.schuele@metaways.de>
+ */
+class Tasks_Setup_Update_Release8 extends Setup_Update_Abstract
+{
+    /**
+     * update to 8.1
+     *
+     * - adds etag column
+     */
+    public function update_0()
+    {
+        $declaration = new Setup_Backend_Schema_Field_Xml('
+            <field>
+                <name>etag</name>
+                <type>text</type>
+                <length>60</length>
+            </field>');
+        $this->_backend->addCol('tasks', $declaration);
+    
+        $declaration = new Setup_Backend_Schema_Index_Xml('
+            <index>
+                <name>etag</name>
+                <field>
+                    <name>etag</name>
+                </field>
+            </index>');
+        $this->_backend->addIndex('cal_events', $declaration);
+    
+        $this->setTableVersion('tasks', 8);
+        $this->setApplicationVersion('Tasks', '8.1');
+    }
+}
index d53b911..d9f8fab 100644 (file)
@@ -1,7 +1,7 @@
 <?xml version="1.0" encoding="utf-8"?>
 <application>
     <name>Tasks</name>
-    <version>8.0</version>
+    <version>8.1</version>
     <order>30</order>
     <depends>
         <application>Admin</application>
@@ -9,7 +9,7 @@
     <tables>
         <table>
             <name>tasks</name>
-            <version>7</version>
+            <version>8</version>
             <declaration>
                 <field>
                     <name>id</name>
@@ -92,7 +92,7 @@
                     <type>text</type>
                     <length>255</length>
                     <notnull>false</notnull>
-                </field>            
+                </field>
                     <field>
                     <name>organizer</name>
                     <type>text</type>
                     <length>255</length>
                     <notnull>true</notnull>
                 </field>
+                <field>
+                    <name>etag</name>
+                    <type>text</type>
+                    <length>60</length>
+                </field>
                 <index>
                     <name>id</name>
                     <primary>true</primary>
                         <name>id</name>
                     </field>
                 </index>
+                <index>
+                    <name>etag</name>
+                    <field>
+                        <name>etag</name>
+                    </field>
+                </index>
             </declaration>
         </table>
         
index f44390b..3cb68a6 100644 (file)
@@ -1447,4 +1447,75 @@ abstract class Tinebase_Backend_Sql_Abstract extends Tinebase_Backend_Abstract i
         
         $select->group($group);
     }
+
+    /**
+     * sets etags, expects ids as keys and etags as value
+     *
+     * @param array $etags
+     * 
+     * @todo maybe we should find a better place for the etag functions as this is currently only used in Calendar + Tasks
+     */
+    public function setETags(array $etags)
+    {
+        foreach ($etags as $id => $etag) {
+            $where  = array(
+                $this->_db->quoteInto($this->_db->quoteIdentifier($this->_identifier) . ' = ?', $id),
+            );
+            $this->_db->update($this->_tablePrefix . $this->_tableName, array('etag' => $etag), $where);
+        }
+    }
+    
+    /**
+     * checks if there is an event with this id and etag, or an event with the same id
+     *
+     * @param string $id
+     * @param string $etag
+     * @return boolean
+     * @throws Tinebase_Exception_NotFound
+     */
+    public function checkETag($id, $etag)
+    {
+        $select = $this->_db->select();
+        $select->from(array($this->_tableName => $this->_tablePrefix . $this->_tableName), $this->_identifier);
+        $select->where($this->_db->quoteIdentifier($this->_identifier) . ' = ?', $id);
+        $select->orWhere($this->_db->quoteIdentifier('uid') . ' = ?', $id);
+    
+        $stmt = $select->query();
+        $queryResult = $stmt->fetch();
+        $stmt->closeCursor();
+    
+        if ($queryResult === false) {
+            throw new Tinebase_Exception_NotFound('no record with id ' . $id .' found');
+        }
+    
+        $select->where($this->_db->quoteIdentifier('etag') . ' = ?', $etag);
+        $stmt = $select->query();
+        $queryResult = $stmt->fetch();
+        $stmt->closeCursor();
+    
+        return ($queryResult !== false);
+    }
+    
+    /**
+     * return etag set for given container
+     * 
+     * @param string $containerId
+     * @return multitype:Ambigous <mixed, Ambigous <string, boolean, mixed>>
+     */
+    public function getEtagsForContainerId($containerId)
+    {
+        $select = $this->_db->select();
+        $select->from(array($this->_tableName => $this->_tablePrefix . $this->_tableName), array($this->_identifier, 'etag', 'uid'));
+        $select->where($this->_db->quoteIdentifier('container_id') . ' = ?', $containerId);
+        $select->where($this->_db->quoteIdentifier('is_deleted') . ' = ?', 0);
+    
+        $stmt = $select->query();
+        $queryResult = $stmt->fetchAll();
+    
+        $result = array();
+        foreach ($queryResult as $row) {
+            $result[$row['id']] = $row;
+        }
+        return $result;
+    }
 }