Tinebase_Model_Grants - overwrite (apply)(recordset)diff functions
authorPaul Mehrer <p.mehrer@metaways.de>
Fri, 14 Jul 2017 12:31:55 +0000 (14:31 +0200)
committerPaul Mehrer <p.mehrer@metaways.de>
Fri, 14 Jul 2017 14:15:39 +0000 (16:15 +0200)
Change-Id: Ie8a37b64dc9f77ef6a8b714391cbc9530469cb98
Reviewed-on: http://gerrit.tine20.com/customers/5174
Reviewed-by: Paul Mehrer <p.mehrer@metaways.de>
Tested-by: Paul Mehrer <p.mehrer@metaways.de>
tests/tine20/Tinebase/Timemachine/ModificationLogTest.php
tine20/Tinebase/Model/Grants.php
tine20/Tinebase/Record/Abstract.php
tine20/Tinebase/Record/Interface.php
tine20/Tinebase/Record/RecordSet.php

index 66493c4..28500b0 100644 (file)
@@ -774,8 +774,29 @@ class Tinebase_Timemachine_ModificationLogTest extends PHPUnit_Framework_TestCas
         $testPathNode->grants = new Tinebase_Record_RecordSet('Tinebase_Model_Grants', array($grantRecord));
         $testPathNode->acl_node = $testPathNode->getId();
         $testNodeGrants = $fmController->update($testPathNode);
+        $testNodeGrants->grants = null;
         Tinebase_Tree_NodeGrants::getInstance()->getGrantsForRecord($testNodeGrants);
 
+        // update Grants 1
+        $testPathNode->grants = null;
+        Tinebase_Tree_NodeGrants::getInstance()->getGrantsForRecord($testPathNode);
+        foreach (Tinebase_Model_Grants::getAllGrants() as $grant) {
+            $testPathNode->grants->getFirstRecord()->$grant = false;
+        }
+        $testPathNode->grants->getFirstRecord()->{Tinebase_Model_Grants::GRANT_ADMIN} = true;
+        $testPathNode->grants->getFirstRecord()->{Tinebase_Model_Grants::GRANT_EDIT} = true;
+        $updatedNodeGrants = $fmController->update($testPathNode);
+        $updatedNodeGrants->grants = null;
+        Tinebase_Tree_NodeGrants::getInstance()->getGrantsForRecord($updatedNodeGrants);
+
+        // update Grants 2
+        $testPathNode->grants = null;
+        Tinebase_Tree_NodeGrants::getInstance()->getGrantsForRecord($testPathNode);
+        $testPathNode->grants->getFirstRecord()->{Tinebase_Model_Grants::GRANT_EDIT} = false;
+        $updatedTwoNodeGrants = $fmController->update($testPathNode);
+        $updatedTwoNodeGrants->grants = null;
+        Tinebase_Tree_NodeGrants::getInstance()->getGrantsForRecord($updatedTwoNodeGrants);
+
         // unset Grants
         $testPathNode->acl_node = null;
         $fmController->update($testPathNode);
@@ -889,6 +910,52 @@ class Tinebase_Timemachine_ModificationLogTest extends PHPUnit_Framework_TestCas
         unset($newGrants['id']);
         static::assertEquals($oldGrants, $newGrants);
 
+        // update grants 1
+        $mod = $modifications->getFirstRecord();
+        $modifications->removeRecord($mod);
+        $result = Tinebase_Timemachine_ModificationLog::getInstance()->applyReplicationModLogs(new Tinebase_Record_RecordSet('Tinebase_Model_ModificationLog', array($mod)));
+        $this->assertTrue($result, 'applyReplicationModLogs failed');
+        $mod = $modifications->getFirstRecord();
+        $modifications->removeRecord($mod);
+        $result = Tinebase_Timemachine_ModificationLog::getInstance()->applyReplicationModLogs(new Tinebase_Record_RecordSet('Tinebase_Model_ModificationLog', array($mod)));
+        $this->assertTrue($result, 'applyReplicationModLogs failed');
+        $mod = $modifications->getFirstRecord();
+        $modifications->removeRecord($mod);
+        $result = Tinebase_Timemachine_ModificationLog::getInstance()->applyReplicationModLogs(new Tinebase_Record_RecordSet('Tinebase_Model_ModificationLog', array($mod)));
+        $this->assertTrue($result, 'applyReplicationModLogs failed');
+        $filesystem->clearStatCache();
+        $testPathNode = $filesystem->stat(Tinebase_Model_Tree_Node_Path::createFromPath($fmController->addBasePath($testPath . '/subfolder'))->statpath);
+        Tinebase_Tree_NodeGrants::getInstance()->getGrantsForRecord($testPathNode);
+        static::assertEquals($updatedNodeGrants->grants->count(), $testPathNode->grants->count());
+        $oldGrants = $updatedNodeGrants->grants->getFirstRecord()->toArray();
+        unset($oldGrants['id']);
+        $newGrants = $testPathNode->grants->getFirstRecord()->toArray();
+        unset($newGrants['id']);
+        static::assertEquals($oldGrants, $newGrants);
+
+        // update grants 2
+        $mod = $modifications->getFirstRecord();
+        $modifications->removeRecord($mod);
+        $result = Tinebase_Timemachine_ModificationLog::getInstance()->applyReplicationModLogs(new Tinebase_Record_RecordSet('Tinebase_Model_ModificationLog', array($mod)));
+        $this->assertTrue($result, 'applyReplicationModLogs failed');
+        $mod = $modifications->getFirstRecord();
+        $modifications->removeRecord($mod);
+        $result = Tinebase_Timemachine_ModificationLog::getInstance()->applyReplicationModLogs(new Tinebase_Record_RecordSet('Tinebase_Model_ModificationLog', array($mod)));
+        $this->assertTrue($result, 'applyReplicationModLogs failed');
+        $mod = $modifications->getFirstRecord();
+        $modifications->removeRecord($mod);
+        $result = Tinebase_Timemachine_ModificationLog::getInstance()->applyReplicationModLogs(new Tinebase_Record_RecordSet('Tinebase_Model_ModificationLog', array($mod)));
+        $this->assertTrue($result, 'applyReplicationModLogs failed');
+        $filesystem->clearStatCache();
+        $testPathNode = $filesystem->stat(Tinebase_Model_Tree_Node_Path::createFromPath($fmController->addBasePath($testPath . '/subfolder'))->statpath);
+        Tinebase_Tree_NodeGrants::getInstance()->getGrantsForRecord($testPathNode);
+        static::assertEquals($updatedTwoNodeGrants->grants->count(), $testPathNode->grants->count());
+        $oldGrants = $updatedTwoNodeGrants->grants->getFirstRecord()->toArray();
+        unset($oldGrants['id']);
+        $newGrants = $testPathNode->grants->getFirstRecord()->toArray();
+        unset($newGrants['id']);
+        static::assertEquals($oldGrants, $newGrants);
+
         // unset grants
         $mod = $modifications->getFirstRecord();
         $modifications->removeRecord($mod);
index 2ca3f3e..cc39e55 100644 (file)
@@ -325,18 +325,12 @@ class Tinebase_Model_Grants extends Tinebase_Record_Abstract
         $idProperty = $modelInstance->getIdProperty();
 
         foreach($_recordSetDiff->removed as $data) {
-            if (!isset($data[$idProperty])) {
-                throw new Tinebase_Exception_InvalidArgument('failed to apply record set diff because removed data contained bad data, id property missing (' . $idProperty . '): ' . print_r($data, true));
-            }
-            if (false !== ($record = $_recordSet->getById($data[$idProperty]))) {
-                $_recordSet->removeRecord($record);
-            }
             $found = false;
             /** @var Tinebase_Model_Grants $record */
             foreach ($_recordSet as $record) {
                 if (    $record->record_id      === $data['record_id']      &&
                         $record->account_id     === $data['account_id']     &&
-                        $record->account_type   === $data['account_type']) {
+                        $record->account_type   === $data['account_type']       ) {
                     $found = true;
                     break;
                 }
@@ -347,29 +341,23 @@ class Tinebase_Model_Grants extends Tinebase_Record_Abstract
         }
 
         foreach($_recordSetDiff->modified as $data) {
-            $diff = new Tinebase_Record_Diff();
-            $diff->id = $data[$idProperty];
-            $diff->diff = $data;
-            if (false !== ($record = $_recordSet->getById($diff->getId()))) {
+            $diff = new Tinebase_Record_Diff($data);
+            $found = false;
+            /** @var Tinebase_Model_Grants $record */
+            foreach ($_recordSet as $record) {
+                if (    $record->record_id      === $diff->diff['record_id']      &&
+                        $record->account_id     === $diff->diff['account_id']     &&
+                        $record->account_type   === $diff->diff['account_type']       ) {
+                    $found = true;
+                    break;
+                }
+            }
+            if (true === $found) {
                 $record->applyDiff($diff);
             } else {
-                $found = false;
-                /** @var Tinebase_Model_Grants $record */
-                foreach ($_recordSet as $record) {
-                    if (    $record->record_id      === $data['record_id']      &&
-                            $record->account_id     === $data['account_id']     &&
-                            $record->account_type   === $data['account_type']) {
-                        $found = true;
-                        break;
-                    }
-                }
-                if (true === $found) {
-                    $record->applyDiff($diff);
-                } else {
-                    Tinebase_Core::getLogger()->err(__METHOD__ . '::' . __LINE__
-                        . ' Did not find the record supposed to be modified with id: ' . $data[$idProperty]);
-                    throw new Tinebase_Exception_InvalidArgument('Did not find the record supposed to be modified with id: ' . $data[$idProperty]);
-                }
+                Tinebase_Core::getLogger()->err(__METHOD__ . '::' . __LINE__
+                    . ' Did not find the record supposed to be modified with id: ' . $data[$idProperty]);
+                throw new Tinebase_Exception_InvalidArgument('Did not find the record supposed to be modified with id: ' . $data[$idProperty]);
             }
         }
 
@@ -379,7 +367,7 @@ class Tinebase_Model_Grants extends Tinebase_Record_Abstract
             foreach ($_recordSet as $record) {
                 if (    $record->record_id      === $data['record_id']      &&
                         $record->account_id     === $data['account_id']     &&
-                        $record->account_type   === $data['account_type']) {
+                        $record->account_type   === $data['account_type']       ) {
                     $found = true;
                     break;
                 }
@@ -393,4 +381,65 @@ class Tinebase_Model_Grants extends Tinebase_Record_Abstract
 
         return true;
     }
+
+    /**
+     * @param Tinebase_Record_RecordSet $_recordSetOne
+     * @param Tinebase_Record_RecordSet $_recordSetTwo
+     * @return null|Tinebase_Record_RecordSetDiff
+     */
+    public static function recordSetDiff(Tinebase_Record_RecordSet $_recordSetOne, Tinebase_Record_RecordSet $_recordSetTwo)
+    {
+        $shallowCopyTwo = new Tinebase_Record_RecordSet(self::class);
+        $removed = new Tinebase_Record_RecordSet(self::class);
+        $added = new Tinebase_Record_RecordSet(self::class);
+        $modified = new Tinebase_Record_RecordSet('Tinebase_Record_Diff');
+
+        foreach ($_recordSetTwo as $grantTwo) {
+            $shallowCopyTwo->addRecord($grantTwo);
+        }
+
+        /** @var Tinebase_Model_Grants $grantOne */
+        foreach ($_recordSetOne as $grantOne) {
+            $found = false;
+            /** @var Tinebase_Model_Grants $grantTwo */
+            foreach ($shallowCopyTwo as $grantTwo) {
+                if (    $grantOne->record_id      === $grantTwo->record_id      &&
+                        $grantOne->account_id     === $grantTwo->account_id     &&
+                        $grantOne->account_type   === $grantTwo->account_type       ) {
+                    $found = true;
+                    break;
+                }
+            }
+
+            if (true === $found) {
+                $shallowCopyTwo->removeRecord($grantTwo);
+                $diff = $grantOne->diff($grantTwo, array('id', 'account_grant'));
+                if (!$diff->isEmpty()) {
+                    $diff->xprops('diff')['record_id']    = $grantTwo->record_id;
+                    $diff->xprops('diff')['account_id']   = $grantTwo->account_id;
+                    $diff->xprops('diff')['account_type'] = $grantTwo->account_type;
+                    $diff->xprops('oldData')['record_id']    = $grantTwo->record_id;
+                    $diff->xprops('oldData')['account_id']   = $grantTwo->account_id;
+                    $diff->xprops('oldData')['account_type'] = $grantTwo->account_type;
+                    $modified->addRecord($diff);
+                }
+            } else {
+                $added->addRecord($grantOne);
+            }
+        }
+
+        /** @var Tinebase_Model_Grants $grantTwo */
+        foreach ($shallowCopyTwo as $grantTwo) {
+            $removed->addRecord($grantTwo);
+        }
+
+        $result = new Tinebase_Record_RecordSetDiff(array(
+            'model'    => self::class,
+            'added'    => $added,
+            'removed'  => $removed,
+            'modified' => $modified,
+        ));
+
+        return $result;
+    }
 }
index 645c743..13c7230 100644 (file)
@@ -1471,4 +1471,14 @@ abstract class Tinebase_Record_Abstract implements Tinebase_Record_Interface
 
         return $this->_properties[$_property];
     }
+
+    /**
+     * @param Tinebase_Record_RecordSet $_recordSetOne
+     * @param Tinebase_Record_RecordSet $_recordSetTwo
+     * @return null|Tinebase_Record_RecordSetDiff
+     */
+    public static function recordSetDiff(Tinebase_Record_RecordSet $_recordSetOne, Tinebase_Record_RecordSet $_recordSetTwo)
+    {
+        return null;
+    }
 }
index 3bfe79a..4ca90ba 100644 (file)
@@ -309,4 +309,11 @@ interface Tinebase_Record_Interface extends ArrayAccess, IteratorAggregate
      * @return bool
      */
     public static function applyRecordSetDiff(Tinebase_Record_RecordSet $_recordSet, Tinebase_Record_RecordSetDiff $_recordSetDiff);
+
+    /**
+     * @param Tinebase_Record_RecordSet $_recordSetOne
+     * @param Tinebase_Record_RecordSet $_recordSetTwo
+     * @return null|Tinebase_Record_RecordSetDiff
+     */
+    public static function recordSetDiff(Tinebase_Record_RecordSet $_recordSetOne, Tinebase_Record_RecordSet $_recordSetTwo);
 }
index ab90774..906e102 100644 (file)
@@ -658,6 +658,12 @@ class Tinebase_Record_RecordSet implements IteratorAggregate, Countable, ArrayAc
         if ($this->getRecordClassName() !== $recordSet->getRecordClassName()) {
             throw new Tinebase_Exception_InvalidArgument('can only compare recordsets with the same type of records');
         }
+
+        /** @var Tinebase_Record_Interface $model */
+        $model = $this->getRecordClassName();
+        if (null !== ($result = $model::recordSetDiff($this, $recordSet))) {
+            return $result;
+        }
         
         $existingRecordsIds = $this->getArrayOfIds();
         $toCompareWithRecordsIds = $recordSet->getArrayOfIds();