0009542: load event relations on demand
authorCornelius Weiß <mail@corneliusweiss.de>
Mon, 22 Dec 2014 16:05:22 +0000 (17:05 +0100)
committerPhilipp Schüle <p.schuele@metaways.de>
Mon, 29 Dec 2014 12:02:25 +0000 (13:02 +0100)
* exclude recurring events (not exceptions)
* adds generic getRelations() to Tinebase JSON frontend

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

Change-Id: I88a5311e42b2f9aae8d6665a21714bfb5fb181ef
Reviewed-on: http://gerrit.tine20.com/customers/1484
Tested-by: Jenkins CI (http://ci.tine20.com/)
Reviewed-by: Philipp Schüle <p.schuele@metaways.de>
tests/tine20/Calendar/JsonTests.php
tine20/Calendar/Model/Event.php
tine20/Calendar/js/EventEditDialog.js
tine20/Tinebase/Frontend/Json.php
tine20/Tinebase/js/widgets/relation/GenericPickerGridPanel.js

index f8843d2..53e983f 100644 (file)
@@ -849,7 +849,7 @@ class Calendar_JsonTests extends Calendar_TestCase
         
         // assert effective grants are set
         $this->assertEquals((bool) $expectedEventData[Tinebase_Model_Grants::GRANT_EDIT], (bool) $eventData[Tinebase_Model_Grants::GRANT_EDIT], $msg . ': effective grants mismatch');
-        // container, assert attendee, tags, relations
+        // container, assert attendee, tags
         $this->assertEquals($expectedEventData['dtstart'], $eventData['dtstart'], $msg . ': dtstart mismatch');
         $this->assertTrue(is_array($eventData['container_id']), $msg . ': failed to "resolve" container');
         $this->assertTrue(is_array($eventData['container_id']['account_grants']), $msg . ': failed to "resolve" container account_grants');
@@ -1492,4 +1492,36 @@ class Calendar_JsonTests extends Calendar_TestCase
         $event = $this->_uit->saveEvent($eventData);
         $this->assertEquals(1, $event['attendee'][1]['quantity'], 'The invalid quantity should be saved as 1');
     }
+    
+    /**
+     * testGetRelations
+     * 
+     * @see 0009542: load event relations on demand
+     */
+    public function testGetRelations()
+    {
+        $contact = Addressbook_Controller_Contact::getInstance()->create(new Addressbook_Model_Contact(array(
+            'n_family' => 'Contact for relations test'
+        )));
+        $eventData = $this->_getEvent()->toArray();
+        $eventData['relations'] = array(
+        array(
+            'own_model'              => 'Calendar_Model_Event',
+            'own_backend'            => 'Sql',
+            'own_id'                 => 0,
+            'own_degree'             => Tinebase_Model_Relation::DEGREE_SIBLING,
+            'type'                   => '',
+            'related_backend'        => 'Sql',
+            'related_id'             => $contact->getId(),
+            'related_model'          => 'Addressbook_Model_Contact',
+            'remark'                 => NULL,
+        ));
+        $event = $this->_uit->saveEvent($eventData);
+        
+        $tfj = new Tinebase_Frontend_Json();
+        $relations = $tfj->getRelations('Calendar_Model_Event', $event['id']);
+        
+        $this->assertEquals(1, $relations['totalcount']);
+        $this->assertEquals($contact->n_fn, $relations['results'][0]['related_record']['n_family'], print_r($relations['results'], true));
+    }
 }
index a938810..ecb70be 100644 (file)
@@ -114,7 +114,6 @@ class Calendar_Model_Event extends Tinebase_Record_Abstract
         'alarms'                => array(Zend_Filter_Input::ALLOW_EMPTY => true         ), // RecordSet of Tinebase_Model_Alarm
         'tags'                  => array(Zend_Filter_Input::ALLOW_EMPTY => true         ), // originally categories handled by Tinebase_Tags
         'notes'                 => array(Zend_Filter_Input::ALLOW_EMPTY => true         ), // originally comment handled by Tinebase_Notes
-        'relations'             => array(Zend_Filter_Input::ALLOW_EMPTY => true         ),
         'attachments'           => array(Zend_Filter_Input::ALLOW_EMPTY => true),
         
         //'contact'               => array(Zend_Filter_Input::ALLOW_EMPTY => true         ),
index 566cc91..c946fbb 100644 (file)
@@ -32,14 +32,6 @@ Tine.Calendar.EventEditDialog = Ext.extend(Tine.widgets.dialog.EditDialog, {
     showContainerSelector: false,
     tbarItems: [{xtype: 'widget-activitiesaddbutton'}],
     
-    /**
-     * hide relations panel because we can't load them on demand yet
-     * 
-     * @see 0009412: event loses saved relations on reload
-     * @type Boolean
-     */
-    hideRelationsPanel: true,
-    
     mode: 'local',
     
     // note: we need up use new action updater here or generally in the widget!
@@ -470,7 +462,11 @@ Tine.Calendar.EventEditDialog = Ext.extend(Tine.widgets.dialog.EditDialog, {
      */
     onAfterRecordLoad: function() {
         Tine.Calendar.EventEditDialog.superclass.onAfterRecordLoad.call(this);
-        
+
+        // disable relations panel for non persistent exceptions till we have the baseEventId
+        if (this.record.isRecurInstance()) {
+            this.relationsPanel.setDisabled(true);
+        }
         this.attendeeGridPanel.onRecordLoad(this.record);
         this.rrulePanel.onRecordLoad(this.record);
         this.alarmPanel.onRecordLoad(this.record);
index 9a3b44d..d0420e6 100644 (file)
@@ -1011,6 +1011,35 @@ class Tinebase_Frontend_Json extends Tinebase_Frontend_Json_Abstract
         return $result;
     }
 
+    /************************* relation functions ***************************/
+
+    /**
+     * get all relations of a given record
+     *
+     * @param  string       $_model         own model to get relations for
+     * @param  string       $_id            own id to get relations for
+     * @param  string       $_degree        only return relations of given degree
+     * @param  array        $_type          only return relations of given type
+     * @param  string       $_relatedModel  only return relations having this related model
+     * @return array
+     */
+    public function getRelations($model, $id, $degree = NULL, $type = array(), $relatedModel = NULL)
+    {
+        $relations = Tinebase_Relations::getInstance()->getRelations($model, 'Sql', $id, $degree, $type, false, $relatedModel);
+
+        // @TODO we still have no converter for relations :-(
+        // -> related records returned here are different to the records returned by the apps itself!
+        // -> this problem also applies to to generic json converter!
+        $relations->setTimezone(Tinebase_Core::get(Tinebase_Core::USERTIMEZONE));
+        $relations->bypassFilters = true;
+        $result = $relations->toArray();
+
+        return array(
+            'results'       => array_values($result),
+            'totalcount'    => count($result),
+        );
+    }
+
     /************************ config functions ******************************/
 
     /**
index bf54dee..ccd0314 100644 (file)
@@ -33,6 +33,7 @@ Tine.widgets.relation.GenericPickerGridPanel = Ext.extend(Tine.widgets.grid.Pick
      * @type Record
      */
     record: null,
+
     /**
      *
      * @type {String}
@@ -170,9 +171,9 @@ Tine.widgets.relation.GenericPickerGridPanel = Ext.extend(Tine.widgets.grid.Pick
         
         this.editDialog.on('save', this.onSaveRecord, this);
         this.editDialog.on('load', this.loadRecord, this);
-        
+
         Tine.widgets.relation.GenericPickerGridPanel.superclass.initComponent.call(this);
-        
+
         this.selModel.on('selectionchange', function(sm) {
             this.actionEditInNewWindow.setDisabled(sm.getCount() != 1);
         }, this);
@@ -1116,7 +1117,22 @@ Tine.widgets.relation.GenericPickerGridPanel = Ext.extend(Tine.widgets.grid.Pick
     loadRecord: function(dialog, record, ticketFn) {
         this.store.removeAll();
         var interceptor = ticketFn();
-        var relations = record.get('relations');
+
+
+        if (dialog.mode == 'local') {
+            // if dialog is local, relations must be fetched async
+            Tine.Tinebase.getRelations('Calendar_Model_Event', record.get('id'), null, [], null, function (response, request) {
+                this.loadRelations(response.results, interceptor);
+            }.createDelegate(this));
+        } else {
+            var relations = record.get('relations');
+            this.loadRelations(relations, interceptor);
+        }
+
+
+    },
+
+    loadRelations: function(relations, interceptor) {
         if (relations && relations.length > 0) {
             var relationRecords = [];