Merge branch '2015.11-develop' into 2016.11
authorPhilipp Schüle <p.schuele@metaways.de>
Wed, 26 Oct 2016 12:46:53 +0000 (14:46 +0200)
committerPhilipp Schüle <p.schuele@metaways.de>
Wed, 26 Oct 2016 12:46:53 +0000 (14:46 +0200)
20 files changed:
tests/tine20/Felamimail/Frontend/JsonTest.php
tests/tine20/Phone/Call/ControllerTest.php
tests/tine20/Phone/JsonTest.php
tine20/Felamimail/Sieve/Backend/Abstract.php
tine20/Felamimail/Sieve/Backend/Sql.php
tine20/Felamimail/Sieve/Rule/Action.php
tine20/Felamimail/js/sieve/RuleEditDialog.js
tine20/Felamimail/js/sieve/RulesGridPanel.js
tine20/Filemanager/Frontend/Json.php
tine20/Filemanager/Model/NodeFilter.php [new file with mode: 0644]
tine20/Phone/Controller.php
tine20/Phone/Controller/Call.php
tine20/Phone/Model/Call.php
tine20/Phone/Setup/Update/Release9.php
tine20/Phone/Setup/setup.xml
tine20/Phone/js/Phone.js
tine20/Tinebase/Container.php
tine20/Tinebase/Model/Filter/FilterGroup.php
tine20/Tinebase/Model/Filter/Relation.php
tine20/Tinebase/Relation/Backend/Sql.php

index 3ad3bd7..428c3b7 100644 (file)
@@ -1408,7 +1408,57 @@ IbVx8ZTO7dJRKrg72aFmWTf0uNla7vicAhpiLWobyNYcZbIjrAGDfg==
         $ruleData[0]['enabled'] = 0;
         $this->_sieveTestHelper($ruleData);
     }
-    
+
+    /**
+     * @see 0006222: Keep a copy from mails forwarded to another emailaddress
+     */
+    public function testSetForwardRuleWithCopy()
+    {
+        $ruleData = array(array(
+            'id'            => 1,
+            'action_type'   => Felamimail_Sieve_Rule_Action::REDIRECT,
+            'action_argument' => array(
+                'emails' => 'someaccount@example.org',
+                'copy'   => 1,
+            ),
+            'conjunction'     => 'allof',
+            'conditions'    => array(array(
+                'test'          => Felamimail_Sieve_Rule_Condition::TEST_ADDRESS,
+                'comperator'    => Felamimail_Sieve_Rule_Condition::COMPERATOR_CONTAINS,
+                'header'        => 'From',
+                'key'           => 'info@example.org',
+            )),
+            'enabled'       => 1,
+        ));
+
+        $this->_sieveTestHelper($ruleData);
+    }
+
+    /**
+     * @see 0006222: Keep a copy from mails forwarded to another emailaddress
+     */
+    public function testSetForwardRuleWithoutCopy()
+    {
+        $ruleData = array(array(
+            'id'            => 1,
+            'action_type'   => Felamimail_Sieve_Rule_Action::REDIRECT,
+            'action_argument' => array(
+                'emails' => 'someaccount@example.org',
+                'copy'   => 0,
+            ),
+            'conjunction'     => 'allof',
+            'conditions'    => array(array(
+                'test'          => Felamimail_Sieve_Rule_Condition::TEST_ADDRESS,
+                'comperator'    => Felamimail_Sieve_Rule_Condition::COMPERATOR_CONTAINS,
+                'header'        => 'From',
+                'key'           => 'info@example.org',
+            )),
+            'enabled'       => 1,
+        ));
+
+        $this->_sieveTestHelper($ruleData);
+    }
+
     /**
      * testGetVacationTemplates
      *
index 4d661bf..c4f3298 100644 (file)
@@ -16,7 +16,7 @@ class Phone_Call_ControllerTest extends TestCase
     /**
      * @see 0011934: show contacts in phone call grid
      */
-    public function testContactRelation()
+    public function testContactId()
     {
         $phoneNumber = '0406437435';
         $myContact = Addressbook_Controller_Contact::getInstance()->getContactByUserId(Tinebase_Core::getUser()->getId());
@@ -32,7 +32,7 @@ class Phone_Call_ControllerTest extends TestCase
         ));
         $call = Phone_Controller_Call::getInstance()->create($call);
 
-        $this->assertEquals(1, count($call->relations), 'my contact should be added as relation to the call' . print_r($call->toArray(), true));
-        $this->assertEquals($myContact->getId(), $call->relations->getFirstRecord()->related_id);
+        $this->assertTrue(isset($call->contact_id));
+        $this->assertEquals($myContact->getId(), $call->contact_id);
     }
 }
index 8d1277e..5e8c581 100644 (file)
@@ -490,7 +490,7 @@ class Phone_JsonTest extends TestCase
     /**
      * @see 0011934: show contacts in phone call grid
      */
-    public function testContactRelations()
+    public function testContactId()
     {
         // search phone 2 calls (on should be linked to sclever)
         $result = $this->_json->searchCalls($this->_objects['filter3'], $this->_objects['paging']);
@@ -503,8 +503,7 @@ class Phone_JsonTest extends TestCase
         }
 
         $this->assertTrue($scleverCall !== null);
-        $this->assertTrue(isset($scleverCall['relations']));
-        $this->assertEquals(1, count($scleverCall['relations']), print_r($scleverCall, true));
-        $this->assertEquals('Susan', $scleverCall['relations'][0]['related_record']['n_given'], print_r($scleverCall, true));
+        $this->assertTrue(isset($scleverCall['contact_id']));
+        $this->assertEquals($this->_personas['sclever']->getId(), $scleverCall['contact_id']['account_id'], print_r($scleverCall['contact_id'], true));
     }
 }
index a45ccc9..e1b5ec6 100644 (file)
@@ -127,6 +127,7 @@ abstract class Felamimail_Sieve_Backend_Abstract
         if (! empty($this->_rules)) {
             $require[] = '"fileinto"';
             $require[] = '"reject"';
+            $require[] = '"copy"';
             
             foreach ($this->_rules as $rule) {
                 if ($rule->hasRegexCondition()) {
index be80730..96cb5fe 100644 (file)
@@ -94,6 +94,10 @@ class Felamimail_Sieve_Backend_Sql extends Felamimail_Sieve_Backend_Abstract
         $this->_rules = array();
         foreach ($ruleRecords as $ruleRecord) {
             $ruleRecord->conditions = Zend_Json::decode($ruleRecord->conditions);
+            if (Tinebase_Helper::is_json($ruleRecord->action_argument)) {
+                $ruleRecord->action_argument = Zend_Json::decode($ruleRecord->action_argument);
+            }
+
             $this->_rules[] = $ruleRecord->getFSR();
         }
     }
@@ -159,6 +163,9 @@ class Felamimail_Sieve_Backend_Sql extends Felamimail_Sieve_Backend_Abstract
                 $ruleRecord->setFromFSR($rule);
                 $ruleRecord->account_id = $this->_accountId;
                 $ruleRecord->conditions = Zend_Json::encode($ruleRecord->conditions);
+                if (is_array($ruleRecord->action_argument)) {
+                    $ruleRecord->action_argument = Zend_Json::encode($ruleRecord->action_argument);
+                }
                 $this->_rulesBackend->create($ruleRecord);
             }
             
index 469cd69..4f0a4d4 100644 (file)
@@ -6,7 +6,7 @@
  * @subpackage  Sieve
  * @license     http://www.gnu.org/licenses/agpl.html AGPL Version 3
  * @author      Lars Kneschke <l.kneschke@metaways.de>
- * @copyright   Copyright (c) 2010 Metaways Infosystems GmbH (http://www.metaways.de)
+ * @copyright   Copyright (c) 2010-2016 Metaways Infosystems GmbH (http://www.metaways.de)
  * 
  */
 
@@ -78,7 +78,20 @@ class Felamimail_Sieve_Rule_Action
             case self::DISCARD:
                 return "    $this->_type;";
                 break;
-                
+
+            case self::REDIRECT:
+                if (is_array($this->_argument)) {
+                    if (isset($this->_argument['copy']) && $this->_argument['copy'] == 1) {
+                        $argument = $this->_quoteString($this->_argument['emails']);
+                        return "    $this->_type :copy $argument;";
+                    } else {
+                        $argument = $this->_quoteString($this->_argument['emails']);
+                        return "    $this->_type $argument;";
+                    }
+
+                    break;
+                }
+
             default:
                 $argument = $this->_quoteString($this->_argument);
                 return "    $this->_type $argument;";
index 4c8bd91..5a6fa96 100644 (file)
@@ -76,7 +76,16 @@ Tine.Felamimail.sieve.RuleEditDialog = Ext.extend(Tine.widgets.dialog.EditDialog
             if (this.record.get('action_type') == type) {
                 var field = this.getForm().findField('action_argument_' + type);
                 if (field !== null) {
-                    field.setValue(this.record.get('action_argument'));
+                    switch (type) {
+                        case 'redirect':
+                           var data = this.record.get('action_argument'),
+                               checkbox = this.getForm().findField('action_argument_redirect_copy');
+                           field.setValue(data.emails);
+                           checkbox.setValue(data.copy);
+                           break;
+                        default:
+                           field.setValue(this.record.get('action_argument'));
+                    }
                 }
             }
         }
@@ -111,9 +120,19 @@ Tine.Felamimail.sieve.RuleEditDialog = Ext.extend(Tine.widgets.dialog.EditDialog
         Tine.Felamimail.sieve.RuleEditDialog.superclass.onRecordUpdate.call(this);
         
         this.record.set('conditions', this.getConditions());
-        
-        var argumentField = this.getForm().findField('action_argument_' + this.actionTypeCombo.getValue()),
+
+        var argumentFieldName = 'action_argument_' + this.actionTypeCombo.getValue();
+            argumentField = this.getForm().findField(argumentFieldName),
             argumentValue = (argumentField !== null) ? argumentField.getValue() : '';
+
+        // add additional action arguments
+        if (argumentFieldName === 'action_argument_redirect') {
+            argumentValue = {
+                emails: argumentValue,
+                copy: this.getForm().findField('action_argument_redirect_copy').getValue()
+            };
+        }
+        
         this.record.set('action_argument', argumentValue);
     },
     
@@ -359,6 +378,10 @@ Tine.Felamimail.sieve.RuleEditDialog = Ext.extend(Tine.widgets.dialog.EditDialog
                             emptyText: 'test@example.org',
                             width: 200,
                             hideLabel: true
+                        }, {
+                            name: 'action_argument_redirect_copy',
+                            xtype: 'checkbox',
+                            fieldLabel: this.app.i18n._('Keep a copy')
                         }]
                     }, {
                         id: this.idPrefix + 'reject',
index ba8d18e..a977295 100644 (file)
@@ -266,16 +266,19 @@ Tine.Felamimail.sieve.RulesGridPanel = Ext.extend(Tine.widgets.grid.GridPanel, {
      */
     actionRenderer: function(type, metadata, record) {
         var types = Tine.Felamimail.sieve.RuleEditDialog.getActionTypes(this.app),
-            result = type;
-        
+            result = type,
+            action_argument = record.get('action_argument');
+
         for (i=0; i < types.length; i++) {
             if (types[i][0] == type) {
                 result = types[i][1];
             }
         }
         
-        if (record.get('action_argument') && record.get('action_argument') != '') {
-            result += ' ' + record.get('action_argument');
+        if (action_argument && action_argument != '') {
+            result += Ext.isObject(action_argument)
+                ? ': '  + action_argument.emails + (action_argument.copy ? ' (' + this.app.i18n._('Keep a copy') + ')' : '')
+                : action_argument;
         }
             
         return Ext.util.Format.htmlEncode(result);
index 4499315..3b5a023 100644 (file)
@@ -36,7 +36,7 @@ class Filemanager_Frontend_Json extends Tinebase_Frontend_Json_Abstract
      */
     public function searchNodes($filter, $paging)
     {
-        $result = $this->_search($filter, $paging, Filemanager_Controller_Node::getInstance(), 'Tinebase_Model_Tree_Node_Filter');
+        $result = $this->_search($filter, $paging, Filemanager_Controller_Node::getInstance(), 'Filemanager_Model_NodeFilter');
         $this->_removeAppIdFromPathFilter($result);
         
         return $result;
diff --git a/tine20/Filemanager/Model/NodeFilter.php b/tine20/Filemanager/Model/NodeFilter.php
new file mode 100644 (file)
index 0000000..18c3f5c
--- /dev/null
@@ -0,0 +1,34 @@
+<?php
+/**
+ * Tine 2.0
+ *
+ * @package     Filemanager
+ * @subpackage  Model
+ * @license     http://www.gnu.org/licenses/agpl.html AGPL Version 3
+ * @author      Paul Mehrer <p.mehrer@metaways.de>
+ * @copyright   Copyright (c) 2016 Metaways Infosystems GmbH (http://www.metaways.de)
+ */
+
+
+class Filemanager_Model_NodeFilter extends Tinebase_Model_Tree_Node_Filter
+{
+    /**
+     * sets this filter group from filter data in array representation
+     *
+     * @param array $_data
+     */
+    public function setFromArray($_data)
+    {
+        foreach ($_data as $key => &$filterData) {
+            if (isset($filterData['field']) && $filterData['field'] === 'foreignRecord' &&
+                $filterData['value']['linkType'] === 'relation') {
+                if (!isset($filterData['options']) || !is_array($filterData['options'])) {
+                    $filterData['options'] = array();
+                }
+                $filterData['options']['own_model'] = 'Filemanager_Model_Node';
+            }
+        }
+
+        parent::setFromArray($_data);
+    }
+}
index 1f138ba..5c308d2 100644 (file)
@@ -181,11 +181,9 @@ class Phone_Controller extends Tinebase_Controller_Abstract
             $_call->callerid = $_call->line_id;
         }
 
-        $call = $backend->create($_call);
-
         // resolve telephone number to contacts if possible
         $phoneController = Phone_Controller_Call::getInstance();
-        $telNumber = Addressbook_Model_Contact::normalizeTelephoneNoCountry($phoneController->resolveInternalNumber($call->destination));
+        $telNumber = Addressbook_Model_Contact::normalizeTelephoneNoCountry($phoneController->resolveInternalNumber($_call->destination));
         if (null !== $telNumber) {
             $filter = new Addressbook_Model_ContactFilter(array(
                 array('field' => 'telephone_normalized', 'operator' => 'equals', 'value' => $telNumber),
@@ -193,30 +191,18 @@ class Phone_Controller extends Tinebase_Controller_Abstract
 
             $controller = Addressbook_Controller_Contact::getInstance();
             $oldAclChecks = $controller->doContainerACLChecks();
+
             $controller->doContainerACLChecks(false);
             $contacts = $controller->search($filter);
+            $controller->doContainerACLChecks($oldAclChecks);
 
-            $relationBackend = new Tinebase_Relation_Backend_Sql();
-            foreach ($contacts as $contact) {
-
-                // we dont add the relations to the call record as this is called by the phone server, so no need to return the relations
-                $relationBackend->addRelation(
-                    new Tinebase_Model_Relation(array(
-                        'own_model' => 'Phone_Model_Call',
-                        'own_id' => $call->getId(),
-                        'own_backend' => Tinebase_Model_Relation::DEFAULT_RECORD_BACKEND,
-                        'related_model' => 'Addressbook_Model_Contact',
-                        'related_id' => $contact->getId(),
-                        'related_degree' => Tinebase_Model_Relation::DEGREE_SIBLING,
-                        'related_backend' => Tinebase_Model_Relation::DEFAULT_RECORD_BACKEND,
-                        'type' => 'CALLER',
-                    ))
-                );
+            if ($contacts->count() > 0) {
+                $_call->contact_id = $contacts->getFirstRecord()->getId();
             }
-
-            $controller->doContainerACLChecks($oldAclChecks);
         }
-        
+
+        $call = $backend->create($_call);
+
         return $call;
     }
     
index 8405158..2a80592 100644 (file)
@@ -72,17 +72,9 @@ class Phone_Controller_Call extends Tinebase_Controller_Record_Abstract
             $controller = Addressbook_Controller_Contact::getInstance();
             $contacts = $controller->search($filter);
 
-            $relations = $_record->relations;
-            foreach ($contacts as $contact) {
-                $relations[] = array(
-                    'related_model' => 'Addressbook_Model_Contact',
-                    'related_id' => $contact->getId(),
-                    'related_degree' => Tinebase_Model_Relation::DEGREE_SIBLING,
-                    'related_backend' => Tinebase_Model_Relation::DEFAULT_RECORD_BACKEND,
-                    'type' => 'CALLER',
-                );
+            if ($contacts->count() > 0) {
+                $_record->contact_id = $contacts->getFirstRecord()->getId();
             }
-            $_record->relations = $relations;
         }
     }
 
index 8e943a5..29d241b 100644 (file)
@@ -121,16 +121,14 @@ class Phone_Model_Call extends Tinebase_Record_Abstract
                 'validators' => array(Zend_Filter_Input::ALLOW_EMPTY => true),
                 'queryFilter' => TRUE,
             ),
-            'contact' => array(
-                'type' => 'virtual',
+            'contact_id'              => array(
+                'label'      => 'Contact',
+                'validators' => array(Zend_Filter_Input::ALLOW_EMPTY => true),
+                'type'       => 'record',
                 'config' => array(
-                    'type' => 'relation',
-                    'label' => 'Contact',    // _('Contact')
-                    'config' => array(
-                        'appName'   => 'Addressbook',
-                        'modelName' => 'Contact',
-                        'type' => 'CALLER'
-                    )
+                    'appName'     => 'Addressbook',
+                    'modelName'   => 'Contact',
+                    'idProperty'  => 'id',
                 )
             ),
         )
index e240503..cbec446 100644 (file)
@@ -17,6 +17,9 @@ class Phone_Setup_Update_Release9 extends Setup_Update_Abstract
      */
     public function update_0()
     {
+        /**
+         * this is obsolete due to update_1, in case it was not yet applied, we skip it!
+
         // we need at least addressbook version 9,7
         if (version_compare($this->getApplicationVersion('Addressbook'), '9.8') < 0 ) {
             return;
@@ -69,6 +72,65 @@ class Phone_Setup_Update_Release9 extends Setup_Update_Abstract
             }
         }
 
+        // we dont even want to move to that app version, as update_1 will check for it!
         $this->setApplicationVersion('Phone', '9.1');
+         * */
+    }
+
+    /**
+     * update to 9.2
+     *
+     * @return void
+     */
+    public function update_1()
+    {
+        // we need at least addressbook version 9,7
+        if (version_compare($this->getApplicationVersion('Addressbook'), '9.8') < 0) {
+            return;
+        }
+
+        // undo update_0
+        if (version_compare($this->getApplicationVersion('Phone'), '9.1') == 0) {
+            $relationBackend = new Tinebase_Relation_Backend_Sql();
+            $relationBackend->purgeRelationsByType('CALLER');
+        }
+
+        $setupUser = $this->_getSetupFromConfigOrCreateOnTheFly();
+
+        if ($setupUser) {
+            Tinebase_Core::set(Tinebase_Core::USER, $setupUser);
+
+            $filter = new Phone_Model_CallFilter(array(array(
+                'field' => 'start',
+                'operator' => 'after',
+                'value' => date('Y-m-d H:i:s', time() - 3600 * 24 * 30 * 3)) // <= 3 month back
+            ), 'AND', array('ignoreAcl' => true));
+
+            $addressbookController = Addressbook_Controller_Contact::getInstance();
+            $phoneController = Phone_Controller_Call::getInstance();
+            $calls = $phoneController->search($filter);
+
+            foreach ($calls as $_record) {
+                // resolve telephone number to contacts if possible
+                $telNumber = Addressbook_Model_Contact::normalizeTelephoneNoCountry(
+                    $phoneController->resolveInternalNumber($_record->destination));
+
+                if (null === $telNumber)
+                    continue;
+
+                $filter = new Addressbook_Model_ContactFilter(array(
+                    array('field' => 'telephone_normalized', 'operator' => 'equals', 'value' => $telNumber),
+                ));
+
+                $contacts = $addressbookController->search($filter);
+
+                if ($contacts->count() > 0) {
+                    $_record->contact_id = $contacts->getFirstRecord()->getId();
+                    $phoneController->update($_record);
+                }
+            }
+        }
+
+        $this->setApplicationVersion('Phone', '9.2');
     }
 }
index 1650343..063af08 100644 (file)
@@ -1,7 +1,7 @@
 <?xml version="1.0" encoding="utf-8"?>
 <application>
     <name>Phone</name>
-    <version>9.1</version>
+    <version>9.2</version>
     <order>11</order>
     <depends>
         <application>Admin</application>
                     <length>64</length>
                     <notnull>true</notnull>
                 </field>
+                <field>
+                    <name>contact_id</name>
+                    <type>text</type>
+                    <length>40</length>
+                </field>
                 <index>
                     <name>id</name>
                     <primary>true</primary>
index a81172e..865bee8 100644 (file)
@@ -119,6 +119,10 @@ Tine.widgets.grid.RendererManager.register('Phone', 'Call', 'line_id', function(
     return (v && v.hasOwnProperty('linenumber')) ? v.linenumber : '';
 });
 
+Tine.widgets.grid.RendererManager.register('Phone', 'Call', 'contact_id', function(v) {
+    return (v && v.hasOwnProperty('n_fn')) ? v.n_fn : '';
+});
+
 /***************************** utils ****************************************/
 
 Ext.namespace('Tine.Phone.utils');
index 76b1417..00a998b 100644 (file)
@@ -1157,21 +1157,27 @@ class Tinebase_Container extends Tinebase_Backend_Sql_Abstract
             $acl = $controller->doContainerACLChecks(FALSE);
         }
         if ($controller && class_exists($filterName)) {
-            Tinebase_Core::getLogger()->info(__METHOD__ . '::' . __LINE__
-                . ' Delete ' . $model . ' records in container ' . $container->getId());
 
-            $filter = new $filterName(array(array(
-                'field'    => 'container_id',
-                'operator' => 'equals',
-                'value'    => intval($container->id)
-            )), Tinebase_Model_Filter_FilterGroup::CONDITION_AND, array('ignoreAcl' => $_ignoreAcl));
+            // workaround to fix Filemanager as Tinebase_Filesystem does not implement search
+            $backend = $controller::getInstance()->getBackend();
+            if (method_exists($backend, 'search')) {
+                Tinebase_Core::getLogger()->info(__METHOD__ . '::' . __LINE__
+                    . ' Delete ' . $model . ' records in container ' . $container->getId());
 
-            if ($_ignoreAcl) {
-                $backend = $controller::getInstance()->getBackend();
-                $idsToDelete = $backend->search($filter, null, /* $_onlyIds */ true);
-                $controller::getInstance()->delete($idsToDelete);
-            } else {
-                $controller::getInstance()->deleteByFilter($filter);
+                $filter = new $filterName(array(array(
+                    'field' => 'container_id',
+                    'operator' => 'equals',
+                    'value' => intval($container->id)
+                )), Tinebase_Model_Filter_FilterGroup::CONDITION_AND, array('ignoreAcl' => $_ignoreAcl));
+
+                if ($_ignoreAcl) {
+
+                    $idsToDelete = $backend->search($filter, null, /* $_onlyIds */
+                        true);
+                    $controller::getInstance()->delete($idsToDelete);
+                } else {
+                    $controller::getInstance()->deleteByFilter($filter);
+                }
             }
         }
 
index f558aca..83315ea 100644 (file)
@@ -305,6 +305,9 @@ class Tinebase_Model_Filter_FilterGroup implements Iterator
                 $model = new $this->_modelName();
                 $filterData['options']['related_model'] = $modelName;
                 $filterData['options']['idProperty'] = $model->getIdProperty();
+                if (isset($_filterData['options']) && isset($_filterData['options']['own_model'])) {
+                    $filterData['options']['own_model'] = $_filterData['options']['own_model'];
+                }
                 $filter = new Tinebase_Model_Filter_Relation($filterData);
                 break;
 
index 219016e..b89c365 100644 (file)
@@ -84,11 +84,16 @@ class Tinebase_Model_Filter_Relation extends Tinebase_Model_Filter_ForeignRecord
      */
     public function appendFilterSql($_select, $_backend)
     {
+        if (isset($this->_options['own_model'])) {
+            $ownModel = $this->_options['own_model'];
+        } else {
+            $ownModel = $_backend->getModelName();
+        }
         if (Tinebase_Core::isLogLevel(Zend_Log::DEBUG)) Tinebase_Core::getLogger()->debug(__METHOD__ . '::' . __LINE__ . ' ' 
-            . 'Adding Relation filter: ' . $_backend->getModelName() . ' <-> ' . $this->_options['related_model']);
+            . 'Adding Relation filter: ' . $ownModel . ' <-> ' . $this->_options['related_model']);
         
         $this->_resolveForeignIds();
-        $ownIds = $this->_getOwnIds($_backend->getModelName());
+        $ownIds = $this->_getOwnIds($ownModel);
         
         $idField = (isset($this->_options['idProperty']) || array_key_exists('idProperty', $this->_options)) ? $this->_options['idProperty'] : 'id';
         $db = $_backend->getAdapter();
index adb8e80..dcb6381 100644 (file)
@@ -509,4 +509,30 @@ class Tinebase_Relation_Backend_Sql extends Tinebase_Backend_Sql_Abstract
             }
         } while(true);
     }
+
+    /**
+     * remove all relations of a specific type
+     *
+     * @param string $_type
+     *
+     * @return void
+     */
+    public function purgeRelationsByType($_type)
+    {
+        $tableName = SQL_TABLE_PREFIX . 'relations';
+
+        $select = $this->_db->select()->from($tableName, array('rel_id'))
+            ->where($this->_db->quoteIdentifier('type') . ' = ?', $_type)
+            ->limit(10000);
+
+        do {
+            $relation_ids = $this->_db->fetchCol($select);
+
+            if (is_array($relation_ids) && count($relation_ids) > 0) {
+                $this->_db->delete($tableName, $this->_db->quoteInto($this->_db->quoteIdentifier('rel_id') . ' IN (?)', $relation_ids));
+            } else {
+                break;
+            }
+        } while(true);
+    }
 }