0010584: CLI function for resetting sync on devices
authorPhilipp Schüle <p.schuele@metaways.de>
Fri, 12 Dec 2014 10:47:21 +0000 (11:47 +0100)
committerPhilipp Schüle <p.schuele@metaways.de>
Mon, 15 Dec 2014 13:43:14 +0000 (14:43 +0100)
* allows to reset sync state for user + sync class (Calendar, Contacts,
...) via CLI
* adds a test
* moves parts of Syncroton init to ActiveSync_Controller

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

Change-Id: I1362fbee97c6a3cc6039233b2e23468fc846a7fb
Reviewed-on: http://gerrit.tine20.com/customers/1441
Tested-by: Jenkins CI (http://ci.tine20.com/)
Reviewed-by: Philipp Schüle <p.schuele@metaways.de>
tests/tine20/ActiveSync/Command/SyncTests.php
tine20/ActiveSync/Controller.php
tine20/ActiveSync/Controller/Abstract.php
tine20/ActiveSync/Frontend/Cli.php [new file with mode: 0644]
tine20/ActiveSync/Server/Http.php
tine20/Calendar/Frontend/Cli.php

index 0d02574..5ff2cf2 100644 (file)
@@ -4,7 +4,7 @@
  * 
  * @package     ActiveSync
  * @license     http://www.gnu.org/licenses/agpl.html AGPL Version 3
- * @copyright   Copyright (c) 2011-2013 Metaways Infosystems GmbH (http://www.metaways.de)
+ * @copyright   Copyright (c) 2011-2014 Metaways Infosystems GmbH (http://www.metaways.de)
  * @author      Lars Kneschke <l.kneschke@metaways.de>
  */
 
@@ -476,4 +476,34 @@ class ActiveSync_Command_SyncTests extends TestCase
         
         $emailTest->tearDown();
     }
+
+    
+    /**
+     * testResetSync
+     * 
+     * @see 0010584: CLI function for resetting sync on devices
+     */
+    public function testResetSync()
+    {
+        $class = 'Calendar';
+        $this->testSyncOfEvents();
+        
+        $result = ActiveSync_Controller::getInstance()->resetSyncForUser(Tinebase_Core::getUser()->accountLoginName, array($class));
+        
+        $this->assertTrue($result);
+        
+        // check if synckey = 0
+        $folderState = Syncroton_Registry::getFolderBackend()->getFolderState($this->_device->id, $class);
+        
+        $this->assertTrue(count($folderState) > 0);
+        
+        foreach ($folderState as $folder) {
+            try {
+               $syncState = Syncroton_Registry::getSyncStateBackend()->getSyncState($this->_device->id, $folder->id);
+               $this->fail('should not find sync state for folder');
+            } catch (Exception $e) {
+                $this->assertEquals('id not found', $e->getMessage());
+            }
+        }
+    }
 }
index 6f0e84c..bbdd6d0 100644 (file)
@@ -51,4 +51,75 @@ class ActiveSync_Controller extends Tinebase_Controller_Abstract
         
         return self::$_instance;
     }
+
+    /**
+     * reset sync for user
+     *
+     * @param string $username
+     * @param array $classesToReset
+     * @return boolean
+     */
+    public function resetSyncForUser($username, $classesToReset)
+    {
+        if (Tinebase_Core::isLogLevel(Zend_Log::INFO)) Tinebase_Core::getLogger()->info(__METHOD__ . '::' . __LINE__
+                . ' Resetting sync for user ' . $username . ' collections: ' . print_r($classesToReset, true));
+        
+        $user = Tinebase_User::getInstance()->getUserByPropertyFromSqlBackend('accountLoginName', $username);
+        
+        self::initSyncrotonRegistry();
+        
+        $devices = $this->_getDevicesForUser($user);
+        
+        foreach ($devices as $device) {
+            if (Tinebase_Core::isLogLevel(Zend_Log::INFO)) Tinebase_Core::getLogger()->info(__METHOD__ . '::' . __LINE__
+                    . ' Resetting device' . $device->friendlyname . ' / id: ' . $device->getId());
+            
+            foreach ($classesToReset as $class) {
+                $folderToReset = $this->_getFoldersForDeviceAndClass($device, $class);
+                
+                if (Tinebase_Core::isLogLevel(Zend_Log::INFO)) Tinebase_Core::getLogger()->info(__METHOD__ . '::' . __LINE__
+                        . ' Resetting ' . count($folderToReset) . ' folder(s) for class ' . $class);
+                
+                foreach ($folderToReset as $folderState) {
+                    Syncroton_Registry::getSyncStateBackend()->resetState($device->getId(), $folderState->id);
+                }
+            }
+        }
+        
+        return true;
+    }
+    
+    /**
+     * fetch devices for user
+     * 
+     * @param Tinebase_Model_FullUser $user
+     */
+    protected function _getDevicesForUser($user)
+    {
+        $deviceBackend = new ActiveSync_Backend_Device();
+        $deviceFilter = new ActiveSync_Model_DeviceFilter(array(
+            array('field' => 'owner_id', 'operator' => 'equals', 'value' => $user->getId())
+        ));
+        $devices = $deviceBackend->search($deviceFilter);
+        return $devices;
+    }
+    
+    protected function _getFoldersForDeviceAndClass($device, $class)
+    {
+        $folderState = Syncroton_Registry::getFolderBackend()->getFolderState($device->getId(), $class);
+        return $folderState;
+    }
+    
+    public static function initSyncrotonRegistry()
+    {
+        Syncroton_Registry::setDatabase(Tinebase_Core::getDb());
+        Syncroton_Registry::setTransactionManager(Tinebase_TransactionManager::getInstance());
+        
+        Syncroton_Registry::set(Syncroton_Registry::DEVICEBACKEND,       new Syncroton_Backend_Device(Tinebase_Core::getDb(), SQL_TABLE_PREFIX . 'acsync_'));
+        Syncroton_Registry::set(Syncroton_Registry::FOLDERBACKEND,       new Syncroton_Backend_Folder(Tinebase_Core::getDb(), SQL_TABLE_PREFIX . 'acsync_'));
+        Syncroton_Registry::set(Syncroton_Registry::SYNCSTATEBACKEND,    new Syncroton_Backend_SyncState(Tinebase_Core::getDb(), SQL_TABLE_PREFIX . 'acsync_'));
+        Syncroton_Registry::set(Syncroton_Registry::CONTENTSTATEBACKEND, new Syncroton_Backend_Content(Tinebase_Core::getDb(), SQL_TABLE_PREFIX . 'acsync_'));
+        Syncroton_Registry::set(Syncroton_Registry::POLICYBACKEND,       new Syncroton_Backend_Policy(Tinebase_Core::getDb(), SQL_TABLE_PREFIX . 'acsync_'));
+        Syncroton_Registry::set('loggerBackend',       Tinebase_Core::getLogger());
+    }
 }
index 5c0b1c5..abae4b6 100644 (file)
@@ -740,7 +740,6 @@ abstract class ActiveSync_Controller_Abstract implements Syncroton_Data_IData
 
     }
 
-
     /**
      * convert contact from xml to Tinebase_Record_Interface
      *
diff --git a/tine20/ActiveSync/Frontend/Cli.php b/tine20/ActiveSync/Frontend/Cli.php
new file mode 100644 (file)
index 0000000..31fe457
--- /dev/null
@@ -0,0 +1,50 @@
+<?php
+/**
+ * Tine 2.0
+ * @package     ActiveSync
+ * @license     http://www.gnu.org/licenses/agpl.html AGPL Version 3
+ * @author      Philipp Schüle <p.schuele@metaways.de>
+ * @copyright   Copyright (c) 2014 Metaways Infosystems GmbH (http://www.metaways.de)
+ */
+
+/**
+ * Cli frontend for ActiveSync
+ *
+ * This class handles cli requests for the ActiveSync
+ *
+ * @package     ActiveSync
+ */
+class ActiveSync_Frontend_Cli extends Tinebase_Frontend_Cli_Abstract
+{
+    /**
+     * the internal name of the application
+     * 
+     * @var string
+     */
+    protected $_applicationName = 'ActiveSync';
+    
+    /**
+     * reset sync
+     * 
+     * @param Zend_Console_Getopt $_opts
+     */
+    public function resetSync(Zend_Console_Getopt $_opts)
+    {
+        $this->_addOutputLogWriter(6);
+        
+        $args = $this->_parseArgs($opts, array('username'));
+        
+        if ($args['username'] != Tinebase_Core::getUser()->accountLoginName && ! $this->_checkAdminRight()) {
+            return 1;
+        }
+        
+        $possibleClasses = array('Calendar', 'Contacts', 'Tasks', 'Email');
+        $classesToReset = (isset($args['collection']) && in_array($args['collection'], $possibleClasses))
+            ? array($args['collection'])
+            : $possibleClasses;
+        
+        ActiveSync_Controller::getInstance()->resetSyncForUser($args['username'], $classesToReset);
+        
+        return ($result) ? 0 : 1;
+    }
+}
index 1bf468e..a12b5a8 100644 (file)
@@ -198,15 +198,7 @@ class ActiveSync_Server_Http extends Tinebase_Server_Abstract implements Tinebas
      */
     protected function _initializeRegistry()
     {
-        Syncroton_Registry::setDatabase(Tinebase_Core::getDb());
-        Syncroton_Registry::setTransactionManager(Tinebase_TransactionManager::getInstance());
-        
-        Syncroton_Registry::set(Syncroton_Registry::DEVICEBACKEND,       new Syncroton_Backend_Device(Tinebase_Core::getDb(), SQL_TABLE_PREFIX . 'acsync_'));
-        Syncroton_Registry::set(Syncroton_Registry::FOLDERBACKEND,       new Syncroton_Backend_Folder(Tinebase_Core::getDb(), SQL_TABLE_PREFIX . 'acsync_'));
-        Syncroton_Registry::set(Syncroton_Registry::SYNCSTATEBACKEND,    new Syncroton_Backend_SyncState(Tinebase_Core::getDb(), SQL_TABLE_PREFIX . 'acsync_'));
-        Syncroton_Registry::set(Syncroton_Registry::CONTENTSTATEBACKEND, new Syncroton_Backend_Content(Tinebase_Core::getDb(), SQL_TABLE_PREFIX . 'acsync_'));
-        Syncroton_Registry::set(Syncroton_Registry::POLICYBACKEND,       new Syncroton_Backend_Policy(Tinebase_Core::getDb(), SQL_TABLE_PREFIX . 'acsync_'));
-        Syncroton_Registry::set('loggerBackend',       Tinebase_Core::getLogger());
+        ActiveSync_Controller::initSyncrotonRegistry();
         
         if (Tinebase_Core::getUser()->hasRight('Addressbook', Tinebase_Acl_Rights::RUN) === true) {
             Syncroton_Registry::setContactsDataClass('ActiveSync_Controller_Contacts');
index aad1242..93294c8 100644 (file)
@@ -128,9 +128,7 @@ class Calendar_Frontend_Cli extends Tinebase_Frontend_Cli_Abstract
      */
     public function deleteDuplicateEvents($opts)
     {
-        $writer = new Zend_Log_Writer_Stream('php://output');
-        $writer->addFilter(new Zend_Log_Filter_Priority(6));
-        Tinebase_Core::getLogger()->addWriter($writer);
+        $this->_addOutputLogWriter(6);
         
         $args = $this->_parseArgs($opts);