Tinebase_Export - add customfield, keyfield, virtual field resolving
authorPaul Mehrer <p.mehrer@metaways.de>
Mon, 17 Jul 2017 14:25:10 +0000 (16:25 +0200)
committerPaul Mehrer <p.mehrer@metaways.de>
Mon, 17 Jul 2017 16:40:09 +0000 (18:40 +0200)
Change-Id: I36989e268d3a503ad7a1d6d44d1a29690936d11a
Reviewed-on: http://gerrit.tine20.com/customers/5216
Tested-by: Jenkins CI (http://ci.tine20.com/)
Reviewed-by: Paul Mehrer <p.mehrer@metaways.de>
Tested-by: Paul Mehrer <p.mehrer@metaways.de>
tine20/Admin/Controller/Keyfield.php [deleted file]
tine20/Calendar/Export/definitions/cal_resource_doc.xml
tine20/Calendar/Model/Resource.php
tine20/Tinebase/CustomField.php
tine20/Tinebase/Export/Abstract.php

diff --git a/tine20/Admin/Controller/Keyfield.php b/tine20/Admin/Controller/Keyfield.php
deleted file mode 100644 (file)
index e273f5d..0000000
+++ /dev/null
@@ -1,150 +0,0 @@
-<?php
-/**
- * Tine 2.0
- *
- * @package     Admin
- * @subpackage  Controller
- * @license     http://www.gnu.org/licenses/agpl.html AGPL Version 3
- * @author      Cornelius WeiƟ <c.weiss@metaways.de>
- * @copyright   Copyright (c) 2015 Metaways Infosystems GmbH (http://www.metaways.de)
- */
-
-/**
- * Keyfield Controller for Admin application
- *
- * @package     Admin
- * @subpackage  Controller
- */
-class Admin_Controller_Keyfield extends Tinebase_Controller_Record_Abstract
-{
-    /**
-     * tinebase customfield controller/backend
-     * 
-     * @var Tinebase_Keyfield
-     */
-    protected $_keyfieldController = NULL;
-    
-    /**
-     * the constructor
-     *
-     * don't use the constructor. use the singleton 
-     */
-    private function __construct() 
-    {
-        $this->_applicationName       = 'Admin';
-        $this->_modelName             = 'Tinebase_Config_KeyField';
-        $this->_doContainerACLChecks  = FALSE;
-                
-        $this->_backend = new Tinebase_CustomField_Config();
-        
-        $this->_keyfieldController = Tinebase_CustomField::getInstance();
-    }
-
-    /**
-     * don't clone. Use the singleton.
-     *
-     */
-    private function __clone() 
-    {
-    }
-
-    /**
-     * holds the instance of the singleton
-     *
-     * @var Admin_Controller_Container
-     */
-    private static $_instance = NULL;
-
-    /**
-     * the singleton pattern
-     *
-     * @return Admin_Controller_Container
-     */
-    public static function getInstance() 
-    {
-        if (self::$_instance === NULL) {
-            self::$_instance = new Admin_Controller_Keyfield;
-        }
-        
-        return self::$_instance;
-    }
-    
-    /**************** overriden methods ***************************/
-    
-    /**
-     * add one record
-     *
-     * @param   Tinebase_Record_Interface $_record
-     * @return  Tinebase_Record_Interface
-     * @throws  Tinebase_Exception_AccessDenied
-     */
-    public function create(Tinebase_Record_Interface $_record)
-    {
-        return $this->_keyfieldController->addCustomField($_record);
-    }
-    
-    /**
-     * get by id
-     *
-     * @param string $_id
-     * @return Tinebase_Record_Interface
-     * @throws  Tinebase_Exception_AccessDenied
-     */
-    public function get($_id)
-    {
-        return $this->_keyfieldController->getCustomField($_id);
-    }
-    
-    /**
-     * Deletes a set of records.
-     *  
-     * @param   array array of record identifiers
-     * @return  array
-     * @throws Tinebase_Exception_NotFound|Tinebase_Exception
-     */
-    public function delete($ids)
-    {
-        $this->_checkCFUsage($ids);
-        foreach ((array) $ids as $id) {
-            $this->_keyfieldController->deleteCustomField($id);
-        }
-        
-        return (array) $ids;
-    }
-    
-    /**
-     * checks if customfield(s) are still in use (have values)
-     * 
-     * @param array $ids
-     * @throws Tinebase_Exception_SystemGeneric
-     */
-    protected function _checkCFUsage($ids)
-    {
-        $filter = new Tinebase_Model_CustomField_ValueFilter(array(array(
-            'field'     => 'customfield_id',
-            'operator'  => 'in',
-            'value'     => (array) $ids
-        )));
-
-        $result = $this->_keyfieldController->search($filter, NULL, FALSE, TRUE);
-        if ($result->count() > 0) {
-            if (Tinebase_Core::isLogLevel(Zend_Log::DEBUG)) Tinebase_Core::getLogger()->debug(__METHOD__ . '::' . __LINE__
-                . ' ' . count($result) . ' records still have custom field values.');
-            
-            throw new Tinebase_Exception_SystemGeneric('Keyfield is still in use!');
-        }
-    }
-    
-    /**
-    * inspect update of one record (after update)
-    *
-    * @param   Tinebase_Record_Interface $updatedRecord   the just updated record
-    * @param   Tinebase_Record_Interface $record          the update record
-    * @param   Tinebase_Record_Interface $currentRecord   the current record (before update)
-    * @return  void
-    */
-    protected function _inspectAfterUpdate($updatedRecord, $record, $currentRecord)
-    {
-        $this->_keyfieldController->clearCacheForConfig($updatedRecord);
-    }
-}
index d53357c..e4bd37f 100644 (file)
     <plugin>Calendar_Export_Resource_Doc</plugin>
     <icon_class>tinebase-action-export-doc</icon_class>
     <template>tine20:///Tinebase/folders/shared/export/templates/Calendar/calendar_resource_export.docx</template>
+    <virtualFields>
+        <virtualField>
+            <name>location</name>
+            <relatedModel>Addressbook_Model_Contact</relatedModel>
+            <relatedDegree>child</relatedDegree>
+            <type>SITE</type>
+        </virtualField>
+    </virtualFields>
+    <keyFields>
+        <keyField>
+            <name>resourceTypes</name>
+            <propertyName>type</propertyName>
+        </keyField>
+        <keyField>
+            <name>freebusyTypes</name>
+            <propertyName>busy_type</propertyName>
+        </keyField>
+        <keyField>
+            <name>attendeeStatus</name>
+            <propertyName>status</propertyName>
+        </keyField>
+    </keyFields>
 </config>
index 30a2628..bf10fe6 100644 (file)
@@ -56,6 +56,8 @@ class Calendar_Model_Resource extends Tinebase_Record_Abstract
         'max_number_of_people' => array(Zend_Filter_Input::ALLOW_EMPTY => true, Zend_Filter_Input::DEFAULT_VALUE => NULL),
         'type'                 => array('allowEmpty' => false         ),
         'is_location'          => array('allowEmpty' => true          ),
+        // location is a virtual field
+        'location'             => array('allowEmpty' => true          ),
         'status'               => array('allowEmpty' => true          ),
         'busy_type'            => array('allowEmpty' => true          ),
         'suppress_notification'=> array('allowEmpty' => true          ),
index 76cff56..408768d 100644 (file)
@@ -514,19 +514,27 @@ class Tinebase_CustomField implements Tinebase_Controller_SearchInterface
      * @param Tinebase_Record_Interface $record
      * @param Tinebase_Model_CustomField_Value $customField
      * @param Tinebase_Record_RecordSet $configs
+     * @param bool $extendedResolving
      */
-    protected function _setCfValueInRecord(Tinebase_Record_Interface $record, Tinebase_Model_CustomField_Value $customField, Tinebase_Record_RecordSet $configs)
+    protected function _setCfValueInRecord(Tinebase_Record_Interface $record, Tinebase_Model_CustomField_Value $customField, Tinebase_Record_RecordSet $configs, $extendedResolving = false)
     {
         $recordCfs = $record->customfields;
         $idx = $configs->getIndexById($customField->customfield_id);
         if ($idx !== FALSE) {
+            /** @var Tinebase_Model_CustomField_Config $config */
             $config = $configs[$idx];
             if (strtolower($config->definition->type) == 'record' || strtolower($config->definition->type) == 'recordlist') {
                 $value = $this->_getRecordTypeCfValue($config, $customField->value, strtolower($config->definition['type']));
             } else {
                 $value = $customField->value;
             }
-            $recordCfs[$config->name] = $value;
+            if (true === $extendedResolving) {
+                $definition = is_object($config->definition) ? $config->definition->toArray() : (array)$config->definition;
+                $definition['value'] = $value;
+                $recordCfs[$config->name] = $definition;
+            } else {
+                $recordCfs[$config->name] = $value;
+            }
         }
 
         // sort customfields by key
@@ -572,8 +580,9 @@ class Tinebase_CustomField implements Tinebase_Controller_SearchInterface
      * get all customfields of all given records
      * 
      * @param  Tinebase_Record_RecordSet $_records     records to get customfields for
+     * @param  bool                      $_extendedResolving
      */
-    public function resolveMultipleCustomfields(Tinebase_Record_RecordSet $_records)
+    public function resolveMultipleCustomfields(Tinebase_Record_RecordSet $_records, $_extendedResolving = false)
     {
         if (count($_records) == 0) {
             return;
@@ -598,7 +607,7 @@ class Tinebase_CustomField implements Tinebase_Controller_SearchInterface
             if (! $record || $record->getId() !== $customField->record_id) {
                 $record = $_records->getById($customField->record_id);
             }
-            $this->_setCfValueInRecord($record, $customField, $configs);
+            $this->_setCfValueInRecord($record, $customField, $configs, $_extendedResolving);
         }
         
         if (Tinebase_Core::isLogLevel(Zend_Log::TRACE)) Tinebase_Core::getLogger()->trace(__METHOD__ . '::' . __LINE__
index 1fc8635..ed3b0fe 100644 (file)
@@ -201,6 +201,12 @@ abstract class Tinebase_Export_Abstract implements Tinebase_Record_IteratableInt
 
     protected $_additionalRecords = array();
 
+    protected $_keyFields = array();
+
+    protected $_virtualFields = array();
+
+    protected $_foreignIdFields = array();
+
     /**
      * the constructor
      *
@@ -281,6 +287,43 @@ abstract class Tinebase_Export_Abstract implements Tinebase_Record_IteratableInt
                 $this->_additionalRecords[$key] = $record;
             }
         }
+
+        if ($this->_config->keyFields) {
+            foreach ($this->_config->keyFields as $keyFields) {
+                if ($keyFields->propertyName) {
+                    $keyFields = array($keyFields);
+                }
+                foreach($keyFields as $keyField) {
+                    $this->_keyFields[$keyField->propertyName] = $keyField->name;
+                }
+            }
+        }
+
+        if ($this->_config->foreignIds) {
+            foreach ($this->_config->foreignIds as $foreignIds) {
+                if ($foreignIds->controller) {
+                    $foreignIds = array($foreignIds);
+                }
+                foreach($foreignIds as $foreignId) {
+                    $this->_foreignIdFields[$foreignId->name] = $foreignId->controller;
+                }
+            }
+        }
+
+        if ($this->_config->virtualFields) {
+            foreach ($this->_config->virtualFields as $virtualFields) {
+                if ($virtualFields->relatedModel) {
+                    $virtualFields = array($virtualFields);
+                }
+                foreach($virtualFields as $virtualField) {
+                    $this->_virtualFields[$virtualField->name] = array(
+                        'relatedModel' => $virtualField->relatedModel,
+                        'relatedDegree' => $virtualField->relatedDegree,
+                        'type' => $virtualField->type
+                    );
+                }
+            }
+        }
     }
 
     /**
@@ -334,21 +377,6 @@ abstract class Tinebase_Export_Abstract implements Tinebase_Record_IteratableInt
         return $config;
     }
 
-    /**
-     * get custom field names for this app
-     *
-     * @return array
-     */
-    protected function _getCustomFieldNames()
-    {
-        if ($this->_customFieldNames === null) {
-            $this->_customFieldNames = Tinebase_CustomField::getInstance()->
-                getCustomFieldsForApplication($this->_applicationName, $this->_modelName)->name;
-        }
-
-        return $this->_customFieldNames;
-    }
-
     protected function _getTemplateFilename()
     {
         return $this->_templateFileName;
@@ -707,6 +735,60 @@ abstract class Tinebase_Export_Abstract implements Tinebase_Record_IteratableInt
             Tinebase_Container::getInstance()->getGrantsOfRecords($_records, Tinebase_Core::getUser());
         }
 
+        $_records->customfields = array();
+        Tinebase_CustomField::getInstance()->resolveMultipleCustomfields($_records, true);
+
+        /** @var Tinebase_Record_Abstract $modelName */
+        $modelName = $_records->getRecordClassName();
+
+        $relations = Tinebase_Relations::getInstance()->getMultipleRelations($modelName, 'Sql', $_records->getArrayOfIds());
+
+        $appConfig = Tinebase_Config::factory($this->_applicationName);
+        if (null === ($modelConfig = $modelName::getConfiguration())) {
+            /** @var Tinebase_Record_Abstract $record */
+            foreach ($_records as $idx => $record) {
+                if (isset($relations[$idx])) {
+                    $record->relations = $relations[$idx];
+                }
+
+                foreach ($this->_keyFields as $name => $keyField) {
+                    /** @var Tinebase_Config_KeyField $keyField */
+                    $keyField = $appConfig->{$keyField};
+                    $record->{$name} = $keyField->getTranslatedValue($record->{$name});
+                }
+
+                foreach ($this->_virtualFields as $name => $virtualField) {
+                    $value = null;
+                    if (!empty($record->relations)) {
+                        /** @var Tinebase_Model_Relation $relation */
+                        foreach($record->relations as $relation) {
+                            if (    $relation->related_model  === $virtualField['relatedModel']  &&
+                                    $relation->related_degree === $virtualField['relatedDegree'] &&
+                                    $relation->type           === $virtualField['type']) {
+                                $value = $relation->related_record;
+                                break;
+                            }
+                        }
+                    }
+                    $record->{$name} = $value;
+                }
+
+                foreach ($this->_foreignIdFields as $name => $controller) {
+                    if (!empty($record->{$name})) {
+                        $controller = $controller::getInstance();
+                        $record->{$name} = $controller->get($record->{$name});
+                    }
+                }
+            }
+        } else {
+            /** @var Tinebase_Record_Abstract $record */
+            /*foreach ($_records as $record) {
+                foreach ($modelConfig->getVirtualFields() as $field) {
+                    $modelConfig->
+                }
+            }*/
+        }
+
         $_records->setTimezone(Tinebase_Core::getUserTimezone());
     }