Merge branch '2017.11' into 2017.11-develop
authorjenkins <tine20-jenkins@metaways.de>
Wed, 9 Aug 2017 13:11:41 +0000 (15:11 +0200)
committerjenkins <tine20-jenkins@metaways.de>
Wed, 9 Aug 2017 13:11:41 +0000 (15:11 +0200)
68 files changed:
tests/tine20/ActiveSync/Frontend/JsonTests.php
tests/tine20/Felamimail/Frontend/JsonTest.php
tine20/ActiveSync/Acl/Rights.php
tine20/ActiveSync/Controller/SyncDevices.php
tine20/ActiveSync/Frontend/Json.php
tine20/ActiveSync/Model/Device.php
tine20/ActiveSync/Setup/Update/Release10.php [new file with mode: 0644]
tine20/ActiveSync/Setup/setup.xml
tine20/Addressbook/Setup/Update/Release10.php
tine20/Addressbook/Setup/setup.xml
tine20/Admin/Setup/Update/Release10.php [new file with mode: 0644]
tine20/Admin/Setup/setup.xml
tine20/Calendar/Controller/Event.php
tine20/Calendar/Event/InspectEventAfterUpdate.php [new file with mode: 0644]
tine20/Calendar/Setup/Update/Release10.php
tine20/Calendar/Setup/setup.xml
tine20/CoreData/Setup/Update/Release10.php [new file with mode: 0644]
tine20/CoreData/Setup/setup.xml
tine20/Courses/Setup/Update/Release10.php [new file with mode: 0644]
tine20/Courses/Setup/setup.xml
tine20/Crm/Setup/Update/Release10.php
tine20/Crm/Setup/setup.xml
tine20/Events/Setup/Update/Release10.php
tine20/Events/Setup/setup.xml
tine20/ExampleApplication/Setup/Update/Release10.php [new file with mode: 0644]
tine20/ExampleApplication/Setup/setup.xml
tine20/Felamimail/Setup/Update/Release10.php
tine20/Felamimail/Setup/setup.xml
tine20/Filemanager/Setup/Update/Release10.php [new file with mode: 0644]
tine20/Filemanager/Setup/setup.xml
tine20/HumanResources/Setup/Update/Release10.php
tine20/HumanResources/Setup/setup.xml
tine20/Inventory/Setup/Update/Release10.php
tine20/Inventory/Setup/setup.xml
tine20/MailFiler/Controller/Message.php
tine20/MailFiler/Controller/Node.php
tine20/MailFiler/Frontend/Json.php
tine20/MailFiler/Model/Message.php
tine20/MailFiler/Model/Node.php
tine20/MailFiler/Setup/Update/Release10.php [new file with mode: 0644]
tine20/MailFiler/Setup/Update/Release11.php [new file with mode: 0644]
tine20/MailFiler/Setup/setup.xml
tine20/Phone/Setup/Update/Release10.php
tine20/Phone/Setup/setup.xml
tine20/Projects/Setup/Update/Release10.php
tine20/Projects/Setup/setup.xml
tine20/Sales/Setup/Update/Release10.php
tine20/Sales/Setup/setup.xml
tine20/SimpleFAQ/Setup/Update/Release10.php [new file with mode: 0644]
tine20/SimpleFAQ/Setup/setup.xml
tine20/Tasks/Setup/Update/Release10.php
tine20/Tasks/Setup/setup.xml
tine20/Timetracker/Setup/Update/Release10.php
tine20/Timetracker/Setup/setup.xml
tine20/Tinebase/Export/Abstract.php
tine20/Tinebase/Frontend/Json.php
tine20/Tinebase/Frontend/Json/Abstract.php
tine20/Tinebase/ImportExportDefinition.php
tine20/Tinebase/Model/Pagination.php
tine20/Tinebase/ModelConfiguration.php
tine20/Tinebase/Record/Abstract.php
tine20/Tinebase/Setup/Update/Release10.php
tine20/Tinebase/Setup/setup.xml
tine20/Tinebase/js/data/Record.js
tine20/Tinebase/js/widgets/ContentTypeTreePanel.js
tine20/Voipmanager/Setup/Update/Release10.php [new file with mode: 0644]
tine20/Voipmanager/Setup/Update/Release9.php
tine20/Voipmanager/Setup/setup.xml

index 8c0b2c6..105ee9e 100644 (file)
@@ -4,7 +4,7 @@
  * 
  * @package     ActiveSync
  * @license     http://www.gnu.org/licenses/agpl.html AGPL Version 3
- * @copyright   Copyright (c) 2015 Metaways Infosystems GmbH (http://www.metaways.de)
+ * @copyright   Copyright (c) 2015-2017 Metaways Infosystems GmbH (http://www.metaways.de)
  * @author      Philipp Schüle <p.schuele@metaways.de>
  */
 
@@ -19,12 +19,12 @@ class ActiveSync_Frontend_JsonTests extends ActiveSync_TestCase
      * lazy init of uit
      *
      * @return ActiveSync_Frontend_Json
-     *
-     * @todo fix ide object class detection for completions
      */
     protected function _getUit()
     {
-        return parent::_getUit();
+        /** @var ActiveSync_Frontend_Json $uit */
+        $uit = parent::_getUit();
+        return $uit;
     }
     
     /**
@@ -32,7 +32,7 @@ class ActiveSync_Frontend_JsonTests extends ActiveSync_TestCase
      */
     public function testSearchSyncDevices()
     {
-        $device = $this->_getDevice(Syncroton_Model_Device::TYPE_IPHONE);
+        $this->_getDevice(Syncroton_Model_Device::TYPE_IPHONE);
         
         $result = $this->_getUit()->searchSyncDevices(array(), array());
         
@@ -73,12 +73,32 @@ class ActiveSync_Frontend_JsonTests extends ActiveSync_TestCase
      */
     public function testSaveSyncDevice()
     {
+        $uit = $this->_getUit();
         $device = $this->testGetSyncDevice();
         
         $device['friendlyname'] = 'Very friendly name';
         $device['owner_id'] = $device['owner_id']['accountId'];
-        $updatedDevice = $this->_getUit()->saveSyncDevice($device);
-        
-        $this->assertEquals($device['friendlyname'], $updatedDevice['friendlyname']);
+        $device['remotewipe'] = 1;
+        $updatedDevice = $uit->saveSyncDevice($device);
+
+        static::assertEquals($device['friendlyname'], $updatedDevice['friendlyname']);
+        static::assertEquals(0, $updatedDevice['remotewipe']);
+
+
+        $result = $uit->remoteResetDevices(array($updatedDevice['id']));
+        static::assertTrue(is_array($result) && isset($result['success']) && true === $result['success'] &&
+            count($result) === 1, 'result of remoteResetDevices should be array(\'success\' => true)');
+
+        $fetchedDevice = $uit->getSyncDevice($updatedDevice['id']);
+        static::assertEquals(1, $fetchedDevice['remotewipe'], 'remote wipe not set successfully!');
+
+        $catched = false;
+        try {
+            unset($updatedDevice['id']);
+            $uit->saveSyncDevice($updatedDevice);
+        } catch (Tinebase_Exception_AccessDenied $tead) {
+            $catched = true;
+        }
+        static::assertTrue($catched, 'misuse of saveSyncDevice to create a new device must not be possible');
     }
 }
index 416c7a4..253b27a 100644 (file)
@@ -1219,15 +1219,21 @@ class Felamimail_Frontend_JsonTest extends TestCase
             /* $_emailFrom */ '',
             /*$_subject */ 'test\test' // is converted to 'test_test'
         );
+        $message2 = $this->_sendMessage(
+            'INBOX',
+            /* $addtionalHeaders */ array(),
+            /* $_emailFrom */ '',
+            /*$_subject */ 'abctest'
+        );
         $path = '/' . Tinebase_Model_Container::TYPE_PERSONAL
             . '/' . $user->accountLoginName
             . '/' . $personalFilemanagerContainer->name;
         $filter = array(array(
-            'field' => 'id', 'operator' => 'in', 'value' => array($message['id'])
+            'field' => 'id', 'operator' => 'in', 'value' => array($message['id'], $message2['id'])
         ));
         $result = $this->_json->fileMessages($filter, $appName, $path);
         $this->assertTrue(isset($result['totalcount']));
-        $this->assertEquals(1, $result['totalcount'], 'message should be filed in ' . $appName . ': ' . print_r($result, true));
+        $this->assertEquals(2, $result['totalcount'], 'message should be filed in ' . $appName . ': ' . print_r($result, true));
 
         // check if message exists in $appName
         $filter = new Tinebase_Model_Tree_Node_Filter(array(array(
@@ -1282,9 +1288,9 @@ class Felamimail_Frontend_JsonTest extends TestCase
             'value'    => 'test'
         ));
         $mailFilerJson = new MailFiler_Frontend_Json();
-        $emlNodes = $mailFilerJson->searchNodes($filter, array());
-        $this->assertGreaterThan(0, $emlNodes['totalcount'], 'could not find eml file node with subject filter');
-        $emlNode = $emlNodes['results'][0];
+        $emlNodes = $mailFilerJson->searchNodes($filter, array('sort' => 'subject', 'order' => 'ASC'));
+        $this->assertEquals(2, $emlNodes['totalcount'], 'could not find eml file node with subject filter');
+        $emlNode = $emlNodes['results'][1];
 
         // check email fields
         $this->assertTrue(isset($emlNode['message']), 'message not found in node array: ' . print_r($emlNodes['results'], true));
@@ -1292,6 +1298,10 @@ class Felamimail_Frontend_JsonTest extends TestCase
         $this->assertTrue(isset($emlNode['message']['structure']) && is_array($emlNode['message']['structure']), 'structure not found or not an array: ' . print_r($emlNode['message'], true));
         $this->assertTrue(isset($emlNode['message']['body']) && is_string($emlNode['message']['body']), 'body not found or not a string: ' . print_r($emlNode['message'], true));
         $this->assertContains('aaaaaä', $emlNode['message']['body'], print_r($emlNode['message'], true));
+
+        $emlNodesDesc = $mailFilerJson->searchNodes($filter, array('sort' => 'subject', 'order' => 'DESC'));
+        $this->assertEquals(2, $emlNodesDesc['totalcount'], 'could not find eml file node with subject filter');
+        $this->assertEquals($emlNode['id'], $emlNodesDesc['results'][1]['id'], 'sort did not work');
     }
 
     /**
index adb367b..8a3580f 100644 (file)
@@ -32,6 +32,11 @@ class ActiveSync_Acl_Rights extends Tinebase_Acl_Rights_Abstract
      * @staticvar string
      */
     const MANAGE_DEVICES = 'manage_devices';
+
+    /**
+     * the right to reset a device to factory state, wiping all data
+     */
+    const RESET_DEVICES = 'reset_devices';
     
     /**
      * holds the instance of the singleton
@@ -84,6 +89,7 @@ class ActiveSync_Acl_Rights extends Tinebase_Acl_Rights_Abstract
         
         $addRights = array(
             self::MANAGE_DEVICES,
+            self::RESET_DEVICES,
         );
         $allRights = array_merge($allRights, $addRights);
         
@@ -104,6 +110,10 @@ class ActiveSync_Acl_Rights extends Tinebase_Acl_Rights_Abstract
                 'text'          => $translate->_('Manage ActiveSync devices'),
                 'description'   => $translate->_('See, edit and delete ActiveSync devices'),
             ),
+            self::RESET_DEVICES => array(
+                'text'          => $translate->_('Reset ActiveSync devices'),
+                'description'   => $translate->_('Remotely reset ActiveSync devices to factory state, deleting all data'),
+            )
         );
         
         $rightDescriptions = array_merge($rightDescriptions, parent::getTranslatedRightDescriptions());
index f9066c3..1935ef5 100644 (file)
@@ -6,7 +6,7 @@
  * @subpackage  Controller
  * @license     http://www.gnu.org/licenses/agpl.html AGPL Version 3
  * @author      Lars Kneschke <l.kneschke@metaways.de>
- * @copyright   Copyright (c) 2014-2016 Metaways Infosystems GmbH (http://www.metaways.de)
+ * @copyright   Copyright (c) 2014-2017 Metaways Infosystems GmbH (http://www.metaways.de)
  */
 
 /**
@@ -39,6 +39,8 @@ class ActiveSync_Controller_SyncDevices extends Tinebase_Controller_Record_Abstr
      * @todo rename to containerACLChecks
      */
     protected $_doContainerACLChecks = false;
+
+    protected $_allowRemoteWipeFlag = false;
     
     /**
      * holds the instance of the singleton
@@ -114,6 +116,7 @@ class ActiveSync_Controller_SyncDevices extends Tinebase_Controller_Record_Abstr
      * delete access log entries
      *
      * @param   array $_ids list of logIds to delete
+     * @return Tinebase_Record_RecordSet
      */
     public function delete($_ids)
     {
@@ -123,6 +126,27 @@ class ActiveSync_Controller_SyncDevices extends Tinebase_Controller_Record_Abstr
     }
 
     /**
+     * set remoteWipe flag for devices
+     *
+     * @param   array $_ids list of devices to flag for remote wipe
+     */
+    public function remoteResetDevices($_ids)
+    {
+        $this->checkRight('RESET_DEVICES');
+        $this->_allowRemoteWipeFlag = true;
+
+        try {
+            /** @var ActiveSync_Model_Device $record */
+            foreach ($this->getMultiple($_ids) as $record) {
+                $record->remotewipe = true;
+                $this->update($record);
+            }
+        } finally {
+            $this->_allowRemoteWipeFlag = false;
+        }
+    }
+
+    /**
      * inspect update of one record (before update)
      *
      * @param   Tinebase_Record_Interface $_record      the update record
@@ -133,11 +157,26 @@ class ActiveSync_Controller_SyncDevices extends Tinebase_Controller_Record_Abstr
     {
         // spoofing protection
         $fieldsToUnset = array('id', 'deviceid', 'devicetype', 'policy_id', 'acsversion', 'useragent',
-            'model', 'os', 'oslanguage', 'pinglifetime', 'pingfolder', 'remotewipe', 'calendarfilter_id',
+            'model', 'os', 'oslanguage', 'pinglifetime', 'pingfolder', 'calendarfilter_id',
             'contactsfilter_id', 'emailfilter_id', 'tasksfilter_id', 'lastping');
+        if (false === $this->_allowRemoteWipeFlag) {
+            $fieldsToUnset[] = 'remotewipe';
+        }
         
         foreach ($fieldsToUnset as $field) {
             $_record->{$field} = $_oldRecord{$field};
         }
     }
+
+    /**
+     * inspect creation of one record (before create)
+     *
+     * @param   Tinebase_Record_Interface $_record
+     * @return  void
+     * @throws Tinebase_Exception_AccessDenied
+     */
+    protected function _inspectBeforeCreate(Tinebase_Record_Interface $_record)
+    {
+        throw new Tinebase_Exception_AccessDenied('this is not allowed!');
+    }
 }
index 317741e..b6800b6 100755 (executable)
@@ -6,7 +6,7 @@
  * @subpackage  Frontend
  * @license     http://www.gnu.org/licenses/agpl.html AGPL Version 3
  * @author      Lars Kneschke <l.kneschke@metaways.de>
- * @copyright   Copyright (c) 2009-2015 Metaways Infosystems GmbH (http://www.metaways.de)
+ * @copyright   Copyright (c) 2009-2017 Metaways Infosystems GmbH (http://www.metaways.de)
  *
  */
 
@@ -94,6 +94,9 @@ class ActiveSync_Frontend_Json extends Tinebase_Frontend_Json_Abstract
      */
     public function saveSyncDevice($recordData)
     {
+        if (empty($recordData['id'])) {
+            throw new Tinebase_Exception_AccessDenied('you are not allowed to create a sync device');
+        }
         return $this->_save($recordData, ActiveSync_Controller_SyncDevices::getInstance(), 'ActiveSync_Model_Device', 'id');
     }
     
@@ -107,4 +110,15 @@ class ActiveSync_Frontend_Json extends Tinebase_Frontend_Json_Abstract
     {
         return $this->_delete($ids, ActiveSync_Controller_SyncDevices::getInstance());
     }
+
+    /**
+     * @param array $ids
+     * @return array
+     */
+    public function remoteResetDevices($ids)
+    {
+        ActiveSync_Controller_SyncDevices::getInstance()->remoteResetDevices($ids);
+
+        return array('success' => true);
+    }
 }
index 92034cb..df2f8cf 100644 (file)
@@ -22,6 +22,7 @@
  * @property  string  $policy_id          the current policy_id
  * @property  string  $policykey          the current policykey
  * @property  string  $tasksfilter_id     the tasks filter id
+ * @property  boolean $remotewipe
  */
 class ActiveSync_Model_Device extends Tinebase_Record_Abstract
 {
diff --git a/tine20/ActiveSync/Setup/Update/Release10.php b/tine20/ActiveSync/Setup/Update/Release10.php
new file mode 100644 (file)
index 0000000..902d3b6
--- /dev/null
@@ -0,0 +1,29 @@
+<?php
+/**
+ * Tine 2.0
+ *
+ * @package     ActiveSync
+ * @subpackage  Setup
+ * @license     http://www.gnu.org/licenses/agpl.html AGPL Version 3
+ * @copyright   Copyright (c) 2013-2017 Metaways Infosystems GmbH (http://www.metaways.de)
+ * @author      Stefanie Stamer <s.stamer@metaways.de>
+ */
+
+/**
+ * updates for major release 10
+ *
+ * @package     ActiveSync
+ * @subpackage  Setup
+ */
+class ActiveSync_Setup_Update_Release10 extends Setup_Update_Abstract
+{
+    /**
+     * update to 11.0
+     *
+     * @return void
+     */
+    public function update_0()
+    {
+        $this->setApplicationVersion('ActiveSync', '11.0');
+    }
+}
index 786a35e..7b7fb9f 100644 (file)
@@ -1,7 +1,7 @@
 <?xml version="1.0" encoding="utf-8"?>
 <application>
     <name>ActiveSync</name>
-    <version>10.0</version>
+    <version>11.0</version>
     <order>90</order>
     <depends>
         <application>Tinebase</application>
index 155c1a3..0ed65dc 100644 (file)
@@ -109,4 +109,9 @@ class Addressbook_Setup_Update_Release10 extends Setup_Update_Abstract
     {
         $this->setApplicationVersion('Addressbook', '10.6');
     }
+
+    public function update_6()
+    {
+        $this->setApplicationVersion('Addressbook', '11.0');
+    }
 }
index a1f90a7..4b0851f 100644 (file)
@@ -1,7 +1,7 @@
 <?xml version="1.0" encoding="utf-8"?>
 <application>
     <name>Addressbook</name>
-    <version>10.6</version>
+    <version>11.0</version>
     <order>10</order>
     <depends>
         <application>Admin</application>
diff --git a/tine20/Admin/Setup/Update/Release10.php b/tine20/Admin/Setup/Update/Release10.php
new file mode 100644 (file)
index 0000000..a0b4fe1
--- /dev/null
@@ -0,0 +1,22 @@
+<?php
+/**
+ * Tine 2.0
+ *
+ * @package     Admin
+ * @license     http://www.gnu.org/licenses/agpl.html AGPL3
+ * @copyright   Copyright (c) 2016-2017 Metaways Infosystems GmbH (http://www.metaways.de)
+ * @author      Stefanie Stamer <s.stamer@metaways.de>
+ */
+
+class Admin_Setup_Update_Release10 extends Setup_Update_Abstract
+{
+    /**
+     * update to 11.0
+     *
+     * @return void
+     */
+    public function update_0()
+    {
+        $this->setApplicationVersion('Admin', '11.0');
+    }
+}
index b8afee3..e7df27f 100644 (file)
@@ -1,7 +1,7 @@
 <?xml version="1.0" encoding="utf-8"?>
 <application>
     <name>Admin</name>
-    <version>10.0</version>
+    <version>11.0</version>
     <order>1</order>
     <depends>
         <application>Tinebase</application>
index 64e0d06..7636cf1 100644 (file)
@@ -961,6 +961,10 @@ class Calendar_Controller_Event extends Tinebase_Controller_Record_Abstract impl
         $this->_saveAttendee($record, $currentRecord, $record->isRescheduled($currentRecord));
         // need to save new attendee set in $updatedRecord for modlog
         $updatedRecord->attendee = clone($record->attendee);
+
+        Tinebase_Record_PersistentObserver::getInstance()->fireEvent(new Calendar_Event_InspectEventAfterUpdate([
+            'observable' => $updatedRecord
+        ]));
     }
     
     /**
diff --git a/tine20/Calendar/Event/InspectEventAfterUpdate.php b/tine20/Calendar/Event/InspectEventAfterUpdate.php
new file mode 100644 (file)
index 0000000..01e0a3c
--- /dev/null
@@ -0,0 +1,24 @@
+<?php
+/**
+ * Tine 2.0
+ *
+ * @license      http://www.gnu.org/licenses/agpl.html AGPL Version 3
+ * @author       Michael Spahn <m.spahn@metaways.de>
+ * @copyright    Copyright (c) 2017 Metaways Infosystems GmbH (http://www.metaways.de)
+ *
+ */
+
+/**
+ * event class for event inspection after update
+ *
+ * @package     Calendar
+ */
+class Calendar_Event_InspectEventAfterUpdate extends Tinebase_Event_Observer_Abstract
+{
+    /**
+     * the event to inspect
+     *
+     * @var Calendar_Model_Event
+     */
+    public $observable;
+}
\ No newline at end of file
index 8aa430b..0c6ff0e 100644 (file)
@@ -5,7 +5,7 @@
  * @package     Calendar
  * @subpackage  Setup
  * @license     http://www.gnu.org/licenses/agpl.html AGPL3
- * @copyright   Copyright (c) 2015-2016 Metaways Infosystems GmbH (http://www.metaways.de)
+ * @copyright   Copyright (c) 2015-2017 Metaways Infosystems GmbH (http://www.metaways.de)
  * @author      Philipp Schüle <p.schuele@metaways.de>
  */
 class Calendar_Setup_Update_Release10 extends Setup_Update_Abstract
@@ -187,4 +187,9 @@ class Calendar_Setup_Update_Release10 extends Setup_Update_Abstract
     {
         $this->setApplicationVersion('Calendar', '10.8');
     }
+
+    public function update_8()
+    {
+        $this->setApplicationVersion('Calendar', '11.0');
+    }
 }
index 5006651..3e49252 100644 (file)
@@ -2,7 +2,7 @@
 <application>
     <name>Calendar</name>
     <!-- gettext('Calendar') -->   
-    <version>10.8</version>
+    <version>11.0</version>
     <order>15</order>
     <status>enabled</status>
     <tables>
diff --git a/tine20/CoreData/Setup/Update/Release10.php b/tine20/CoreData/Setup/Update/Release10.php
new file mode 100644 (file)
index 0000000..b1bf326
--- /dev/null
@@ -0,0 +1,23 @@
+<?php
+/**
+ * Tine 2.0
+ *
+ * @package     CoreData
+ * @subpackage  Setup
+ * @license     http://www.gnu.org/licenses/agpl.html AGPL3
+ * @copyright   Copyright (c) 2016-2017 Metaways Infosystems GmbH (http://www.metaways.de)
+ * @author      Philipp Schüle <p.schuele@metaways.de>
+ */
+
+class CoreData_Setup_Update_Release10 extends Setup_Update_Abstract
+{
+    /**
+     * update to 11.0
+     *
+     * @return void
+     */
+    public function update_0()
+    {
+        $this->setApplicationVersion('CoreData', '11.0');
+    }
+}
index 42a3c9a..58a2397 100644 (file)
@@ -2,7 +2,7 @@
 <application>
     <name>CoreData</name>
     <!-- gettext('CoreData') -->
-    <version>10.0</version>
+    <version>11.0</version>
     <order>30</order>
     <status>enabled</status>
     <tables>
diff --git a/tine20/Courses/Setup/Update/Release10.php b/tine20/Courses/Setup/Update/Release10.php
new file mode 100644 (file)
index 0000000..54c07ca
--- /dev/null
@@ -0,0 +1,22 @@
+<?php
+/**
+ * Tine 2.0
+ *
+ * @package     Courses
+ * @subpackage  Setup
+ * @license     http://www.gnu.org/licenses/agpl.html AGPL3
+ * @copyright   Copyright (c) 2012-2017 Metaways Infosystems GmbH (http://www.metaways.de)
+ * @author      Stefanie Stamer <s.stamer@metaways.de>
+ */
+class Courses_Setup_Update_Release10 extends Setup_Update_Abstract
+{
+    /**
+     * update to 11.0
+     *
+     * @return void
+     */
+    public function update_0()
+    {
+        $this->setApplicationVersion('Courses', '11.0');
+    }
+}
index f6973a0..90727bd 100644 (file)
@@ -2,7 +2,7 @@
 <application>
     <name>Courses</name>
     <!-- gettext('Courses') -->   
-    <version>10.0</version>
+    <version>11.0</version>
     <order>50</order>
     <status>enabled</status>
     <depends>
index ec71e94..6bb828a 100644 (file)
@@ -37,4 +37,9 @@ class Crm_Setup_Update_Release10 extends Setup_Update_Abstract
     {
         $this->setApplicationVersion('Crm', '10.2');
     }
+
+    public function update_2()
+    {
+        $this->setApplicationVersion('Crm', '11.0');
+    }
 }
index ee9829f..eb72bb3 100644 (file)
@@ -1,7 +1,7 @@
 <?xml version="1.0" encoding="utf-8"?>
 <application>
     <name>Crm</name>
-    <version>10.2</version>
+    <version>11.0</version>
     <order>20</order>
     <depends>
         <application>Admin</application>
index b7ef90e..50fbcdf 100644 (file)
@@ -38,4 +38,9 @@ class Events_Setup_Update_Release10 extends Setup_Update_Abstract
     {
         $this->setApplicationVersion('Events', '10.2');
     }
+
+    public function update_2()
+    {
+        $this->setApplicationVersion('Events', '11.0');
+    }
 }
index 12d1cbf..301b932 100644 (file)
@@ -2,7 +2,7 @@
 <application>
     <name>Events</name>
     <!-- gettext('Events') -->   
-    <version>10.2</version>
+    <version>11.0</version>
     <order>60</order>
     <status>enabled</status>
     <tables>
diff --git a/tine20/ExampleApplication/Setup/Update/Release10.php b/tine20/ExampleApplication/Setup/Update/Release10.php
new file mode 100644 (file)
index 0000000..3acccf8
--- /dev/null
@@ -0,0 +1,20 @@
+<?php
+/**
+ * Tine 2.0
+ *
+ * @package     ExampleApplication
+ * @license     http://www.gnu.org/licenses/agpl.html AGPL3
+ * @copyright   Copyright (c) 2009-2017 Metaways Infosystems GmbH (http://www.metaways.de)
+ * @author      Philipp Schüle <p.schuele@metaways.de>
+ */
+
+class ExampleApplication_Setup_Update_Release10 extends Setup_Update_Abstract
+{
+    /**
+     * example update script
+     */
+    public function update_0()
+    {
+        $this->setApplicationVersion('ExampleApplication', '11.0');
+    }
+}
index 19ff6d1..f39222f 100644 (file)
@@ -2,7 +2,7 @@
 <application>
     <name>ExampleApplication</name>
     <!-- gettext('ExampleApplication') -->   
-    <version>1.0</version>
+    <version>11.0</version>
     <order>60</order>
     <status>enabled</status>
 </application>
index a2efeb7..5dc7da1 100644 (file)
@@ -199,4 +199,12 @@ sieveFile
 
         $this->setApplicationVersion('Felamimail', '10.5');
     }
+
+    /**
+     * update to 11.0
+     */
+    public function update_5()
+    {
+        $this->setApplicationVersion('Felamimail', '11.0');
+    }
 }
index dfd0dd3..57d9a2a 100644 (file)
@@ -1,7 +1,7 @@
 <?xml version="1.0" encoding="utf-8"?>
 <application>
     <name>Felamimail</name>
-    <version>10.5</version>
+    <version>11.0</version>
     <order>30</order>
     <status>enabled</status>
     <tables>
diff --git a/tine20/Filemanager/Setup/Update/Release10.php b/tine20/Filemanager/Setup/Update/Release10.php
new file mode 100644 (file)
index 0000000..ef966ad
--- /dev/null
@@ -0,0 +1,23 @@
+<?php
+/**
+ * Tine 2.0
+ *
+ * @package     Filemanager
+ * @subpackage  Setup
+ * @license     http://www.gnu.org/licenses/agpl.html AGPL3
+ * @copyright   Copyright (c) 2014-2017 Metaways Infosystems GmbH (http://www.metaways.de)
+ * @author      Stefanie Stamer <s.stamer@metaways.de>
+ */
+
+class Filemanager_Setup_Update_Release10 extends Setup_Update_Abstract
+{
+    /**
+     * update to 11.0
+     *
+     * @return void
+     */
+    public function update_0()
+    {
+        $this->setApplicationVersion('Filemanager', '11.0');
+    }
+}
index 18c21e9..f272247 100644 (file)
@@ -1,7 +1,7 @@
 <?xml version="1.0" encoding="utf-8"?>
 <application>
     <name>Filemanager</name>
-    <version>10.0</version>
+    <version>11.0</version>
     <order>11</order>
     <depends>
         <application>Admin</application>
index f33b7bf..28a82b4 100644 (file)
@@ -5,7 +5,7 @@
  * @package     HumanResources
  * @subpackage  Setup
  * @license     http://www.gnu.org/licenses/agpl.html AGPL3
- * @copyright   Copyright (c) 2016 Metaways Infosystems GmbH (http://www.metaways.de)
+ * @copyright   Copyright (c) 2016-2017 Metaways Infosystems GmbH (http://www.metaways.de)
  * @author      Stefanie Stamer <s.stamer@metaways.de>
  */
 class HumanResources_Setup_Update_Release10 extends Setup_Update_Abstract
@@ -58,4 +58,9 @@ class HumanResources_Setup_Update_Release10 extends Setup_Update_Abstract
 
         $this->setApplicationVersion('HumanResources', '10.3');
     }
+
+    public function update_3()
+    {
+        $this->setApplicationVersion('HumanResources', '11.0');
+    }
 }
index 2433524..e7b5ee9 100644 (file)
@@ -1,7 +1,7 @@
 <?xml version="1.0" encoding="utf-8"?>
 <application>
     <name>HumanResources</name>
-    <version>10.3</version>
+    <version>11.0</version>
     <order>51</order>
     <depends>
         <application>Calendar</application>
index 5bed423..bd81326 100644 (file)
@@ -5,7 +5,7 @@
  * @package     Inventory
  * @subpackage  Setup
  * @license     http://www.gnu.org/licenses/agpl.html AGPL3
- * @copyright   Copyright (c) 2012-2016 Metaways Infosystems GmbH (http://www.metaways.de)
+ * @copyright   Copyright (c) 2012-2017 Metaways Infosystems GmbH (http://www.metaways.de)
  * @author      Stefanie Stamer <s.stamer@metaways.de>
  */
 class Inventory_Setup_Update_Release10 extends Setup_Update_Abstract
@@ -89,4 +89,14 @@ class Inventory_Setup_Update_Release10 extends Setup_Update_Abstract
 
         $this->setApplicationVersion('Inventory', '10.4');
     }
+
+    /**
+     * update to 11.0
+     *
+     * @return void
+     */
+    public function update_4()
+    {
+        $this->setApplicationVersion('Inventory', '11.0');
+    }
 }
index 2c4c53e..d7f6b98 100644 (file)
@@ -2,7 +2,7 @@
 <application>
     <name>Inventory</name>
     <!-- gettext('Inventory') -->   
-    <version>10.4</version>
+    <version>11.0</version>
     <order>60</order>
     <status>enabled</status>
 </application>
index c78a394..12b2e4d 100644 (file)
@@ -79,7 +79,7 @@ class MailFiler_Controller_Message extends Felamimail_Controller_Message
      * @param Tinebase_Model_Filter_FilterGroup $_filter
      * @param string                            $_action get|update
      */
-    public function checkFilterACL(Tinebase_Model_Filter_FilterGroup $_filter, $_action = 'get')
+    public function checkFilterACL(Tinebase_Model_Filter_FilterGroup $_filter = null, $_action = 'get')
     {
         // TODO acl - we already checked acl on the nodes and this has no public api
     }
index bdd14a9..95914ac 100644 (file)
@@ -155,6 +155,9 @@ class MailFiler_Controller_Node extends Filemanager_Controller_Node
         $mailFilerMessage->setFromJsonInUsersTimezone($message->toArray());
         $mailFilerMessage->structure = $message->structure;
         $mailFilerMessage->node_id = $node->getId();
+        $to = $mailFilerMessage->to;
+        sort($to);
+        $mailFilerMessage->to_flat = join(', ', $to);
 
         MailFiler_Controller_Message::getInstance()->create($mailFilerMessage);
     }
index 2c2f8b6..fb5a5cc 100644 (file)
@@ -36,10 +36,16 @@ class MailFiler_Frontend_Json extends Tinebase_Frontend_Json_Abstract
      */
     public function searchNodes($filter, $paging)
     {
-        $result = $this->_search($filter, $paging, MailFiler_Controller_Node::getInstance(), 'MailFiler_Model_NodeFilter');
-        $this->_removeAppIdFromPathFilter($result);
-        
-        return $result;
+        $this->_paginationModel = 'MailFiler_Model_Node';
+        try {
+            $result = $this->_search($filter, $paging, MailFiler_Controller_Node::getInstance(),
+                'MailFiler_Model_NodeFilter');
+            $this->_removeAppIdFromPathFilter($result);
+
+            return $result;
+        } finally {
+            $this->_paginationModel = null;
+        }
     }
     
     /**
index dd3471d..68e861f 100644 (file)
  * @property    string  $sender         the sender of the email
  * @property    string  $content_type   the content type of the message
  * @property    string  $body_content_type   the content type of the message body
- * @property    array   $to             the to receipients
- * @property    array   $cc             the cc receipients
- * @property    array   $bcc            the bcc receipients
+ * @property    array   $to             the to recipients
+ * @property    string  $to_flat        the to recipients as one string, comma separated email list
+ * @property    array   $cc             the cc recipients
+ * @property    array   $bcc            the bcc recipients
  * @property    array   $structure      the message structure
  * @property    array   $attachments    the attachments
  * @property    string  $messageuid     the message uid on the imap server
@@ -50,6 +51,7 @@ class MailFiler_Model_Message extends Felamimail_Model_Message
         'from_name'             => array(Zend_Filter_Input::ALLOW_EMPTY => true),
         'sender'                => array(Zend_Filter_Input::ALLOW_EMPTY => true),
         'to'                    => array(Zend_Filter_Input::ALLOW_EMPTY => true),
+        'to_flat'               => array(Zend_Filter_Input::ALLOW_EMPTY => true),
         'cc'                    => array(Zend_Filter_Input::ALLOW_EMPTY => true),
         'bcc'                   => array(Zend_Filter_Input::ALLOW_EMPTY => true),
         'received'              => array(Zend_Filter_Input::ALLOW_EMPTY => true),
index 0e96174..c40531b 100644 (file)
@@ -5,8 +5,8 @@
  * @package     MailFiler
  * @subpackage  Model
  * @license     http://www.gnu.org/licenses/agpl.html AGPL Version 3
- * @author      AirMike <airmike23@gmail.com>
- * @copyright   Copyright (c) 2012 Metaways Infosystems GmbH (http://www.metaways.de)
+ * @author      Philipp Schüle <p.schuele@metaways.de>
+ * @copyright   Copyright (c) 2017 Metaways Infosystems GmbH (http://www.metaways.de)
  */
 
 /**
@@ -32,6 +32,33 @@ class MailFiler_Model_Node extends Tinebase_Model_Tree_Node
      */
     protected $_application = 'MailFiler';
 
+    protected static $_sortExternalMapping = array(
+        'subject'       => array(
+            'table'         => 'mailfiler_message',
+            'on'            => 'tree_nodes.id = mailfiler_message.node_id'
+        ),
+        'from_email'    => array(
+            'table'         => 'mailfiler_message',
+            'on'            => 'tree_nodes.id = mailfiler_message.node_id'
+        ),
+        'from_name'     => array(
+            'table'         => 'mailfiler_message',
+            'on'            => 'tree_nodes.id = mailfiler_message.node_id'
+        ),
+        'sender'        => array(
+            'table'         => 'mailfiler_message',
+            'on'            => 'tree_nodes.id = mailfiler_message.node_id'
+        ),
+        'received'      => array(
+            'table'         => 'mailfiler_message',
+            'on'            => 'tree_nodes.id = mailfiler_message.node_id'
+        ),
+        'sent'          => array(
+            'table'         => 'mailfiler_message',
+            'on'            => 'tree_nodes.id = mailfiler_message.node_id'
+        ),
+    );
+
     /**
      * overwrite constructor to add more filters
      *
diff --git a/tine20/MailFiler/Setup/Update/Release10.php b/tine20/MailFiler/Setup/Update/Release10.php
new file mode 100644 (file)
index 0000000..693e1be
--- /dev/null
@@ -0,0 +1,22 @@
+<?php
+/**
+ * Tine 2.0
+ *
+ * @package     MailFiler
+ * @subpackage  Setup
+ * @license     http://www.gnu.org/licenses/agpl.html AGPL3
+ * @copyright   Copyright (c) 2017 Metaways Infosystems GmbH (http://www.metaways.de)
+ * @author      Philipp Schüle <p.schuele@metaways.de>
+ */
+class MailFiler_Setup_Update_Release10 extends Setup_Update_Abstract
+{
+    /**
+     * update to 11.0
+     *
+     * @return void
+     */
+    public function update_0()
+    {
+        $this->setApplicationVersion('MailFiler', '11.0');
+    }
+}
diff --git a/tine20/MailFiler/Setup/Update/Release11.php b/tine20/MailFiler/Setup/Update/Release11.php
new file mode 100644 (file)
index 0000000..0297849
--- /dev/null
@@ -0,0 +1,47 @@
+<?php
+/**
+ * Tine 2.0
+ *
+ * @package     MailFiler
+ * @subpackage  Setup
+ * @license     http://www.gnu.org/licenses/agpl.html AGPL3
+ * @copyright   Copyright (c) 2017 Metaways Infosystems GmbH (http://www.metaways.de)
+ * @author      Paul Mehrer <p.mehrer@metaways.de>
+ */
+class MailFiler_Setup_Update_Release11 extends Setup_Update_Abstract
+{
+    /**
+     * update to 11.1
+     *
+     * @return void
+     */
+    public function update_0()
+    {
+        if (!$this->_backend->columnExists('to_flat', 'mailfiler_message')) {
+            $this->_backend->addCol('mailfiler_message',
+                new Setup_Backend_Schema_Field_Xml('<field>
+                    <name>to_flat</name>
+                    <type>text</type>
+                </field>')
+            );
+            $this->setTableVersion('mailfiler_message', 2);
+        }
+
+        $mailFilerMessageController = MailFiler_Controller_Message::getInstance();
+        $pagination = new Tinebase_Model_Pagination(array('start' => 0, 'limit' => 1000, 'sort' => 'id'));
+        do {
+            $result = $mailFilerMessageController->search(null, $pagination);
+            $pagination->start += 1000;
+
+            /** @var MailFiler_Model_Message $message */
+            foreach ($result as $message) {
+                $to = $message->to;
+                sort($to);
+                $message->to_flat = join(', ', $to);
+                $mailFilerMessageController->update($message);
+            }
+        } while ($result->count() > 0);
+
+        $this->setApplicationVersion('MailFiler', '11.1');
+    }
+}
index ce436b5..06741c5 100644 (file)
@@ -1,7 +1,7 @@
 <?xml version="1.0" encoding="utf-8"?>
 <application>
     <name>MailFiler</name>
-    <version>10.0</version>
+    <version>11.1</version>
     <order>12</order>
     <depends>
         <application>Felamimail</application>
         </table>
         <table>
             <name>mailfiler_message</name>
-            <version>1</version>
+            <version>2</version>
             <declaration>
                 <field>
                     <name>id</name>
                     <name>timestamp</name>
                     <type>datetime</type>
                 </field>
+                <field>
+                    <name>to_flat</name>
+                    <type>text</type>
+                </field>
                 <index>
                     <name>id</name>
                     <primary>true</primary>
index 7d3e1c4..9d3abf0 100644 (file)
@@ -5,7 +5,7 @@
  * @package     Phone
  * @subpackage  Setup
  * @license     http://www.gnu.org/licenses/agpl.html AGPL3
- * @copyright   Copyright (c) 2016 Metaways Infosystems GmbH (http://www.metaways.de)
+ * @copyright   Copyright (c) 2016-2017 Metaways Infosystems GmbH (http://www.metaways.de)
  * @author      Paul Mehrer <p.mehrer@metaways.de>
  */
 class Phone_Setup_Update_Release10 extends Setup_Update_Abstract
@@ -31,4 +31,14 @@ class Phone_Setup_Update_Release10 extends Setup_Update_Abstract
         $update9->update_2();
         $this->setApplicationVersion('Phone', '10.2');
     }
+
+    /**
+     * update to 11.0
+     *
+     * @return void
+     */
+    public function update_2()
+    {
+        $this->setApplicationVersion('Phone', '11.0');
+    }
 }
index 16af648..8feb847 100644 (file)
@@ -1,7 +1,7 @@
 <?xml version="1.0" encoding="utf-8"?>
 <application>
     <name>Phone</name>
-    <version>10.2</version>
+    <version>11.0</version>
     <order>11</order>
     <depends>
         <application>Admin</application>
index 7744a2c..2a8240a 100644 (file)
@@ -37,4 +37,9 @@ class Projects_Setup_Update_Release10 extends Setup_Update_Abstract
     {
         $this->setApplicationVersion('Projects', '10.2');
     }
+
+    public function update_2()
+    {
+        $this->setApplicationVersion('Projects', '11.0');
+    }
 }
index e7a2822..d30e262 100644 (file)
@@ -2,7 +2,7 @@
 <application>
     <name>Projects</name>
     <!-- gettext('Projects') -->   
-    <version>10.2</version>
+    <version>11.0</version>
     <order>60</order>
     <status>enabled</status>
     <tables>
index 8e8163c..85b7909 100644 (file)
@@ -5,7 +5,7 @@
  * @package     Sales
  * @subpackage  Setup
  * @license     http://www.gnu.org/licenses/agpl.html AGPL3
- * @copyright   Copyright (c) 2015-2016 Metaways Infosystems GmbH (http://www.metaways.de)
+ * @copyright   Copyright (c) 2015-2017 Metaways Infosystems GmbH (http://www.metaways.de)
  * @author      Philipp Schüle <p.schuele@metaways.de>
  */
 class Sales_Setup_Update_Release10 extends Setup_Update_Abstract
@@ -209,4 +209,12 @@ class Sales_Setup_Update_Release10 extends Setup_Update_Abstract
         $this->setTableVersion('sales_orderconf', 2);
         $this->setApplicationVersion('Sales', '10.9');
     }
+
+    /**
+     * update to 11.0
+     */
+    public function update_9()
+    {
+        $this->setApplicationVersion('Sales', '11.0');
+    }
 }
index 0d1b8c2..5b7e59a 100644 (file)
@@ -1,7 +1,7 @@
 <?xml version="1.0" encoding="utf-8"?>
 <application>
     <name>Sales</name>
-    <version>10.9</version>
+    <version>11.0</version>
     <order>50</order>
     <status>enabled</status>
     <tables>
diff --git a/tine20/SimpleFAQ/Setup/Update/Release10.php b/tine20/SimpleFAQ/Setup/Update/Release10.php
new file mode 100644 (file)
index 0000000..4430bf0
--- /dev/null
@@ -0,0 +1,32 @@
+<?php
+/**
+ * Tine 2.0
+ *
+ * @package     SimpleFAQ
+ * @subpackage  Setup
+ * @license     http://www.gnu.org/licenses/agpl.html AGPL3
+ * @copyright   Copyright (c) 2013-2017 Metaways Infosystems GmbH (http://www.metaways.de)
+ * @author      Stefanie Stamer <s.stamer@metaways.de>
+ */
+class SimpleFAQ_Setup_Update_Release10 extends Setup_Update_Abstract
+{
+    /**
+     * update to 10.1
+     *
+     * @return void
+     */
+    public function update_0()
+    {
+        $this->setApplicationVersion('SimpleFAQ', '10.1');
+    }
+
+    /**
+     * update to 11.0
+     *
+     * @return void
+     */
+    public function update_1()
+    {
+        $this->setApplicationVersion('SimpleFAQ', '11.0');
+    }
+}
index 8ea2ac2..0db9adf 100644 (file)
@@ -1,7 +1,7 @@
 <?xml version="1.0" encoding="utf-8"?>
 <application>
     <name>SimpleFAQ</name>
-    <version>10.1</version>
+    <version>11.0</version>
     <order>62</order>
     <status>enabled</status>
     <depends>
index d51e60e..01d7406 100644 (file)
@@ -37,4 +37,9 @@ class Tasks_Setup_Update_Release10 extends Setup_Update_Abstract
     {
         $this->setApplicationVersion('Tasks', '10.2');
     }
+
+    public function update_2()
+    {
+        $this->setApplicationVersion('Tasks', '11.0');
+    }
 }
index b1d29ea..facd1f9 100644 (file)
@@ -1,7 +1,7 @@
 <?xml version="1.0" encoding="utf-8"?>
 <application>
     <name>Tasks</name>
-    <version>10.2</version>
+    <version>11.0</version>
     <order>30</order>
     <depends>
         <application>Admin</application>
index 51042e2..f71a857 100644 (file)
@@ -194,4 +194,12 @@ class Timetracker_Setup_Update_Release10 extends Setup_Update_Abstract
         $this->update_1();
         $this->setApplicationVersion('Timetracker', '10.6');
     }
+
+    /**
+     * update to 11.0
+     */
+    public function update_6()
+    {
+        $this->setApplicationVersion('Timetracker', '11.0');
+    }
 }
index f11a258..3f4cade 100644 (file)
@@ -2,7 +2,7 @@
 <application>
     <name>Timetracker</name>
     <!-- gettext('Timetracker') -->   
-    <version>10.6</version>
+    <version>11.0</version>
     <order>60</order>
     <status>enabled</status>
     <depends>
index 36f7d31..4756cc2 100644 (file)
@@ -244,6 +244,12 @@ abstract class Tinebase_Export_Abstract implements Tinebase_Record_IteratableInt
         if ($this->_config->template) {
             $this->_templateFileName = $this->_config->template;
         }
+        if ($this->_config->templateFileId) {
+            try {
+                $path = Tinebase_Model_Tree_Node_Path::createFromStatPath(Tinebase_FileSystem::getInstance()->getPathOfNode($this->_config->templateFileId, true));
+                $this->_templateFileName = $path->streamwrapperpath;
+            } catch (Exception $e) {}
+        }
         if (isset($_additionalOptions['template'])) {
             try {
                 $path = Tinebase_Model_Tree_Node_Path::createFromStatPath(Tinebase_FileSystem::getInstance()->getPathOfNode($_additionalOptions['template'], true));
index e46e216..707c411 100644 (file)
@@ -1432,18 +1432,14 @@ class Tinebase_Frontend_Json extends Tinebase_Frontend_Json_Abstract
             throw new Tinebase_Exception_InvalidArgument('A controller for the given appName and modelName does not exist!');
         }
         
-        if (! class_exists($filterClassName)) {
-            throw new Tinebase_Exception_InvalidArgument('A filter for the given appName and modelName does not exist!');
-        }
-        
         if (! in_array($property, $recordClassName::getAutocompleteFields())) {
             throw new Tinebase_Exception_UnexpectedValue('bad property name');
         }
-        
-        $filter = new $filterClassName(array(
+
+        $filter = Tinebase_Model_Filter_FilterGroup::getFilterForModel($recordClassName, array(
             array('field' => $property, 'operator' => 'startswith', 'value' => $startswith),
         ));
-        
+
         $paging = new Tinebase_Model_Pagination(array('sort' => $property));
         
         $values = array_unique($controller->search($filter, $paging)->{$property});
index 77130fd..026b3a4 100644 (file)
@@ -49,6 +49,13 @@ abstract class Tinebase_Frontend_Json_Abstract extends Tinebase_Frontend_Abstrac
     protected $_defaultImportDefinitionName = null;
 
     /**
+     * the model from which the pagination object should read its configuration
+     *
+     * @var string
+     */
+    protected $_paginationModel = null;
+
+    /**
      * Configured plugins for filter model
      * @var array
      */
@@ -187,6 +194,11 @@ abstract class Tinebase_Frontend_Json_Abstract extends Tinebase_Frontend_Abstrac
     protected function _search($_filter, $_paging, Tinebase_Controller_SearchInterface $_controller, $_filterModel, $_getRelations = FALSE, $_totalCountMethod = self::TOTALCOUNT_CONTROLLER)
     {
         $decodedPagination = $this->_prepareParameter($_paging);
+        if (null !== $this->_paginationModel) {
+            $decodedPagination['model'] = $this->_paginationModel;
+        } else {
+            unset($decodedPagination['model']);
+        }
         $pagination = new Tinebase_Model_Pagination($decodedPagination);
         $filter = $this->_decodeFilter($_filter, $_filterModel);
         
index 950046e..1984d82 100644 (file)
@@ -87,6 +87,37 @@ class Tinebase_ImportExportDefinition extends Tinebase_Controller_Record_Abstrac
             array('field' => 'type',            'operator' => 'equals',  'value' => 'export'),
         ));
         $result = $this->search($filter);
+
+        $fileSystem = Tinebase_FileSystem::getInstance();
+        $toRemove = new Tinebase_Record_RecordSet('Tinebase_Model_ImportExportDefinition');
+        /** @var Tinebase_Model_ImportExportDefinition $definition */
+        foreach($result as $definition) {
+            if ($definition->plugin_options) {
+                $config = Tinebase_ImportExportDefinition::getInstance()->
+                    getOptionsAsZendConfigXml($definition, array());
+                if (!empty($config->template)) {
+                    if (strpos($config->template, 'tine20://') === false) {
+                        continue;
+                    }
+                    try {
+                        $node = $fileSystem->stat(substr($config->template, 9));
+                        if (false === $fileSystem->hasGrant(Tinebase_Core::getUser()->getId(), $node->getId(),
+                                Tinebase_Model_Grants::GRANT_READ)) {
+                            $toRemove[] = $definition;
+                        }
+                    } catch (Exception $e) {
+                        $toRemove[] = $definition;
+                    }
+                } elseif (!empty($config->templateFileId)) {
+                    if (false === $fileSystem->hasGrant(Tinebase_Core::getUser()->getId(), $config->templateFileId,
+                            Tinebase_Model_Grants::GRANT_READ)) {
+                        $toRemove[] = $definition;
+                    }
+                }
+            }
+        }
+
+        $result->removeRecords($toRemove);
         
         return $result;
     }
index a0502ea..240bbf4 100644 (file)
@@ -5,7 +5,7 @@
  * @package     Tinebase
  * @license     http://www.gnu.org/licenses/agpl.html AGPL3
  * @author      Cornelius Weiss <c.weiss@metaways.de>
- * @copyright   Copyright (c) 2008-2016 Metaways Infosystems GmbH (http://www.metaways.de)
+ * @copyright   Copyright (c) 2008-2017 Metaways Infosystems GmbH (http://www.metaways.de)
  *
  */
 
@@ -18,6 +18,7 @@
  * @property string limit
  * @property string sort
  * @property string dir
+ * @property string model
  */
 class Tinebase_Model_Pagination extends Tinebase_Record_Abstract
 {
@@ -48,7 +49,9 @@ class Tinebase_Model_Pagination extends Tinebase_Record_Abstract
         'dir'                  => array('presence'      => 'required',
                                         'allowEmpty'    => false,
                                         array('InArray', array('ASC', 'DESC')),
-                                        'default'       => 'ASC'        )
+                                        'default'       => 'ASC'        ),
+        'model'                => array('allowEmpty'    => true,
+                                        'default'       => NULL         ),
     );
     
     /**
@@ -59,19 +62,54 @@ class Tinebase_Model_Pagination extends Tinebase_Record_Abstract
      */
     public function appendPaginationSql($_select)
     {
+        // check model for required joins etc.
+        $this->appendModelConfig($_select);
+
         $this->appendLimit($_select);
         $this->appendSort($_select);
     }
-    
+
+    /**
+     * Appends limit statement to a given select object
+     *
+     * @param  Zend_Db_Select $_select
+     * @return void
+     */
+    public function appendModelConfig($_select)
+    {
+        if (empty($this->model) || empty($this->sort) || empty($this->dir)) {
+            return;
+        }
+
+        /** @var Tinebase_Record_Abstract $model */
+        $model = $this->model;
+        if (empty($mapping = $model::getSortExternalMapping())) {
+            return;
+        }
+        $joined = array();
+        foreach ((array)$this->sort as $field) {
+            if (!isset($mapping[$field])) {
+                continue;
+            }
+            $mappingDef = $mapping[$field];
+            if (isset($joined[$mappingDef['table']])) {
+                continue;
+            }
+            $_select->joinLeft(array($mappingDef['table'] => SQL_TABLE_PREFIX . $mappingDef['table']), $mappingDef['on'],
+                array());
+            $joined[$mappingDef['table']] = true;
+        }
+    }
+
     /**
      * Appends limit statement to a given select object
      * 
-     * @param  Zend_Db_Select
+     * @param  Zend_Db_Select $_select
      * @return void
      */
     public function appendLimit($_select)
     {
-        if (! empty($this->limit)) {
+        if (!empty($this->limit)) {
             $start = ($this->start >= 0) ? $this->start : 0;
             $_select->limit($this->limit, $start);
         }
@@ -80,7 +118,7 @@ class Tinebase_Model_Pagination extends Tinebase_Record_Abstract
     /**
      * Appends sort statement to a given select object
      * 
-     * @param  Zend_Db_Select
+     * @param  Zend_Db_Select $_select
      * @return void
      */
     public function appendSort($_select)
@@ -97,15 +135,10 @@ class Tinebase_Model_Pagination extends Tinebase_Record_Abstract
      */
     protected function _getSortCols()
     {
-        if (is_array($this->sort)) {
-            $order = array();
-            foreach ($this->sort as $sort) {
-                $order[] = $sort . ' ' . $this->dir;
-            }
-        } else {
-            $order = array($this->sort . ' ' . $this->dir);
+        $order = array();
+        foreach ((array)$this->sort as $sort) {
+            $order[] = $sort . ' ' . $this->dir;
         }
-        
         return $order;
     }
 }
index 9388b96..148b36c 100644 (file)
@@ -25,6 +25,7 @@
  * @property string     $identifier legacy
  * @property string     $recordName Human readable name of the record
  * @property string     $recordsName Human readable name of multiple records
+ * @property string     $moduleName The name of the module if it doesn't fit to the recordsName, e.g. used in frontend module tree panel
  * @property string     $containerProperty The property of the container, if any
  * @property boolean    $containerUsesFilter set this to false, if no filter and grid column should be created - default is true
  * @property boolean    $hasPersonalContainer set this to false, if personal containers should be ommited - default is true
@@ -701,7 +702,7 @@ class Tinebase_ModelConfiguration {
         'containerProperty', 'containersName', 'containerName', 'defaultSortInfo', 'fieldKeys', 'filterModel',
         'defaultFilter', 'requiredRight', 'singularContainerMode', 'fields', 'defaultData', 'titleProperty',
         'useGroups', 'fieldGroupFeDefaults', 'fieldGroupRights', 'multipleEdit', 'multipleEditRequiredRight',
-        'copyEditAction', 'copyOmitFields', 'recordName', 'recordsName', 'appName', 'modelName', 'createModule',
+        'copyEditAction', 'copyOmitFields', 'recordName', 'recordsName', 'appName', 'modelName', 'createModule', 'moduleName',
         'isDependent', 'hasCustomFields', 'modlogActive', 'hasAttachments', 'idProperty', 'splitButton',
         'attributeConfig', 'hasPersonalContainer', 'import', 'export', 'virtualFields', 'group',
     );
@@ -1441,7 +1442,12 @@ class Tinebase_ModelConfiguration {
             
             // add calculated values to frontend configuration
             foreach ($this->_frontendProperties as $prop) {
-                $this->_frontendConfiguration[$prop] = $this->{'_' . $prop};
+                // There should be no need to require all properties, the frontend should handle the abstinence.
+                $property = '_' . $prop;
+                if (!property_exists($this, $property)) {
+                    continue;
+                }
+                $this->_frontendConfiguration[$prop] = $this->{$property};
             }
         }
         return $this->_frontendConfiguration;
index bf91c85..9ae05b3 100644 (file)
@@ -215,6 +215,8 @@ abstract class Tinebase_Record_Abstract implements Tinebase_Record_Interface
      */
     protected static $_requiredRight = NULL;
 
+    protected static $_sortExternalMapping = array();
+
 
     /******************************** functions ****************************************/
     
@@ -1481,4 +1483,9 @@ abstract class Tinebase_Record_Abstract implements Tinebase_Record_Interface
     {
         return null;
     }
+
+    public static function getSortExternalMapping()
+    {
+        return static::$_sortExternalMapping;
+    }
 }
index b1f2f92..eee179f 100644 (file)
@@ -2070,4 +2070,12 @@ class Tinebase_Setup_Update_Release10 extends Setup_Update_Abstract
         Tinebase_Scheduler_Task::addAccountSyncTask($scheduler);
         $this->setApplicationVersion('Tinebase', '10.42');
     }
+
+    /**
+     * update to 11.0
+     */
+    public function update_42()
+    {
+        $this->setApplicationVersion('Tinebase', '11.0');
+    }
 }
index ba72f04..6e0c91f 100644 (file)
@@ -1,7 +1,7 @@
 <?xml version="1.0" encoding="utf-8"?>
 <application>
     <name>Tinebase</name>
-    <version>10.42</version>
+    <version>11.0</version>
     <tables>
         <table>
             <name>applications</name>
index 84c0a8b..1b7bee3 100644 (file)
@@ -286,6 +286,17 @@ Tine.Tinebase.data.Record.create = function(o, meta) {
             
         return i18n.n_(p.recordName, p.recordsName, 1);
     };
+    f.getModuleName = function () {
+        var app = Tine.Tinebase.appMgr.get(p.appName),
+            i18n = app && app.i18n ? app.i18n : i18n,
+            moduleName;
+
+        if (p.modelConfiguration && p.modelConfiguration.moduleName) {
+            return i18n._(p.modelConfiguration.moduleName);
+        }
+
+        return p.moduleName ? i18n._(p.moduleName) : f.getRecordsName();
+    };
     f.getRecordsName = function() {
         var app = Tine.Tinebase.appMgr.get(p.appName),
             i18n = app && app.i18n ? app.i18n :i18n;
index 0e16ddd..d057598 100644 (file)
@@ -166,7 +166,7 @@ Ext.extend(Tine.widgets.ContentTypeTreePanel, Ext.tree.TreePanel, {
                 id : 'treenode-' + recordClass.getMeta('modelName'),
                 contentType: recordClass.getMeta('modelName'),
                 iconCls: modelApp.appName + modelName,
-                text: recordClass.getRecordsName(),
+                text: recordClass.getModuleName(),
                 leaf : true
             };
             
diff --git a/tine20/Voipmanager/Setup/Update/Release10.php b/tine20/Voipmanager/Setup/Update/Release10.php
new file mode 100644 (file)
index 0000000..7c8cf89
--- /dev/null
@@ -0,0 +1,23 @@
+<?php
+/**
+ * Tine 2.0
+ *
+ * @package     Voipmanager
+ * @subpackage  Setup
+ * @license     http://www.gnu.org/licenses/agpl.html AGPL Version 3
+ * @author      Stefanie Stamer <s.stamer@metaways.de>
+ * @copyright   Copyright (c) 2013 Metaways Infosystems GmbH (http://www.metaways.de)
+ */
+
+class Voipmanager_Setup_Update_Release9 extends Setup_Update_Abstract
+{
+    /**
+     * update to 10.0
+     *
+     * @return void
+     */
+    public function update_0()
+    {
+        $this->setApplicationVersion('Voipmanager', '10.0');
+    }
+}
index 7c8cf89..72df52c 100644 (file)
@@ -6,10 +6,10 @@
  * @subpackage  Setup
  * @license     http://www.gnu.org/licenses/agpl.html AGPL Version 3
  * @author      Stefanie Stamer <s.stamer@metaways.de>
- * @copyright   Copyright (c) 2013 Metaways Infosystems GmbH (http://www.metaways.de)
+ * @copyright   Copyright (c) 2013-2017 Metaways Infosystems GmbH (http://www.metaways.de)
  */
 
-class Voipmanager_Setup_Update_Release9 extends Setup_Update_Abstract
+class Voipmanager_Setup_Update_Release10 extends Setup_Update_Abstract
 {
     /**
      * update to 10.0
@@ -18,6 +18,6 @@ class Voipmanager_Setup_Update_Release9 extends Setup_Update_Abstract
      */
     public function update_0()
     {
-        $this->setApplicationVersion('Voipmanager', '10.0');
+        $this->setApplicationVersion('Voipmanager', '11.0');
     }
 }
index 050a211..080437d 100644 (file)
@@ -1,7 +1,7 @@
 <?xml version="1.0" encoding="utf-8"?>
 <application>
     <name>Voipmanager</name>
-    <version>10.0</version>
+    <version>11.0</version>
     <order>50</order>
     <depends>
         <application>Admin</application>