0011764: allow to create apps without json frontend
authorPhilipp Schüle <p.schuele@metaways.de>
Tue, 28 Jun 2016 09:07:52 +0000 (11:07 +0200)
committerPhilipp Schüle <p.schuele@metaways.de>
Wed, 29 Jun 2016 07:14:18 +0000 (09:14 +0200)
* reordered getRegistryData for apps
* it is no longer required to have a json frontend class in app
* removed duplication in json server (frontend classes)

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

Change-Id: If9ae2cb30f6f86b7107c9b08e9d7efba7289149c
Reviewed-on: http://gerrit.tine20.com/customers/3283
Tested-by: Jenkins CI (http://ci.tine20.com/)
Reviewed-by: Philipp Schüle <p.schuele@metaways.de>
Tested-by: Philipp Schüle <p.schuele@metaways.de>
tine20/Tinebase/Frontend/Json.php
tine20/Tinebase/Frontend/Json/Abstract.php
tine20/Tinebase/ModelConfiguration.php
tine20/Tinebase/Server/Json.php

index c649222..47e9691 100644 (file)
@@ -838,65 +838,40 @@ class Tinebase_Frontend_Json extends Tinebase_Frontend_Json_Abstract
             }
             
             foreach ($userApplications as $application) {
-                $jsonAppName = $application->name . '_Frontend_Json';
-                
-                if (class_exists($jsonAppName)) {
-                    if (Tinebase_Core::isLogLevel(Zend_Log::DEBUG)) {
-                        Tinebase_Core::getLogger()->debug(__METHOD__ . '::' . __LINE__ . ' Getting registry data for app ' . $application->name);
-                    }
-                    
-                    try {
-                        $applicationJson = new $jsonAppName();
-                        $registryData[$application->name] = ((isset($registryData[$application->name]) || array_key_exists($application->name, $registryData)))
-                            ? array_merge_recursive($registryData[$application->name], $applicationJson->getRegistryData()) 
-                            : $applicationJson->getRegistryData();
-                    
-                    } catch (Exception $e) {
-                        Tinebase_Exception::log($e);
-                        if (! $e instanceof Tinebase_Exception_AccessDenied && ! in_array($application->name, array('Tinebase', 'Addressbook', 'Admin'))) {
-                            Tinebase_Core::getLogger()->warn(__METHOD__ . '::' . __LINE__ . ' Disabling ' . $application->name . ': ' . $e);
-                            Tinebase_Application::getInstance()->setApplicationState(array($application->getId()), Tinebase_Application::DISABLED);
-                        }
-                        unset($registryData[$application->name]);
-                        continue;
-                    }
-                    
-                    $registryData[$application->name]['rights'] = Tinebase_Core::getUser()->getRights($application->name);
-                    $registryData[$application->name]['config'] = isset($clientConfig[$application->name]) ? $clientConfig[$application->name]->toArray() : array();
-                    $registryData[$application->name]['models'] = $applicationJson->getModelsConfiguration();
-                    $registryData[$application->name]['defaultModel'] = $applicationJson->getDefaultModel();
-                    
-                    foreach ($applicationJson->getRelatableModels() as $relModel) {
-                        $registryData[$relModel['ownApp']]['relatableModels'][] = $relModel;
-                    }
+                $appRegistry = array();
+                $appRegistry['rights'] = Tinebase_Core::getUser()->getRights($application->name);
+                $appRegistry['config'] = isset($clientConfig[$application->name])
+                    ? $clientConfig[$application->name]->toArray()
+                    : array();
 
-                    // @todo do we need this for all apps?
-                    $exportDefinitions = Tinebase_ImportExportDefinition::getInstance()->getExportDefinitionsForApplication($application);
-                    $registryData[$application->name]['exportDefinitions'] = array(
-                        'results'               => $exportDefinitions->toArray(),
-                        'totalcount'            => count($exportDefinitions),
-                    );
-                    
-                    $customfields = Tinebase_CustomField::getInstance()->getCustomFieldsForApplication($application);
-                    Tinebase_CustomField::getInstance()->resolveConfigGrants($customfields);
-                    $registryData[$application->name]['customfields'] = $customfields->toArray();
-                    
-                    // add preferences for app
-                    $appPrefs = Tinebase_Core::getPreference($application->name);
-                    if ($appPrefs !== NULL) {
-                        $allPrefs = $appPrefs->getAllApplicationPreferences();
-                        if (Tinebase_Core::isLogLevel(Zend_Log::TRACE)) Tinebase_Core::getLogger()->trace(__METHOD__ . '::' . __LINE__ 
-                            . ' ' . print_r($allPrefs, TRUE));
-                        
-                        foreach ($allPrefs as $pref) {
-                            try {
-                                $registryData[$application->name]['preferences'][$pref] = $appPrefs->{$pref};
-                            } catch (Exception $e) {
-                                Tinebase_Core::getLogger()->warn(__METHOD__ . '::' . __LINE__ . ' Could not get ' . $pref . '  preference: ' . $e);
-                            }
-                        }
-                    }
+                // @todo do we need this for all apps?
+                $exportDefinitions = Tinebase_ImportExportDefinition::getInstance()->getExportDefinitionsForApplication($application);
+                $appRegistry['exportDefinitions'] = array(
+                    'results'               => $exportDefinitions->toArray(),
+                    'totalcount'            => count($exportDefinitions),
+                );
+
+                $customfields = Tinebase_CustomField::getInstance()->getCustomFieldsForApplication($application);
+                Tinebase_CustomField::getInstance()->resolveConfigGrants($customfields);
+                $appRegistry['customfields'] = $customfields->toArray();
+
+                // add preferences for app
+                $prefRegistry = $this->_getAppPreferencesForRegistry($application);
+                $appRegistry = array_merge_recursive($appRegistry, $prefRegistry);
+
+                $customAppRegistry = $this->_getCustomAppRegistry($application);
+                if (empty($customAppRegistry)) {
+                    // TODO always get this from app controller (and remove from _getCustomAppRegistry)
+                    $appController = Tinebase_Core::getApplicationInstance($application->name);
+                    $models = $appController->getModels();
+                    $appRegistry['models'] = Tinebase_ModelConfiguration::getFrontendConfigForModels($models);
+                    $appRegistry['defaultModel'] = $appController::getDefaultModel();
+
+                } else {
+                    $appRegistry = array_merge_recursive($appRegistry, $customAppRegistry);
                 }
+
+                $registryData[$application->name] = $appRegistry;
             }
         } else {
             $registryData['Tinebase'] = $this->getRegistryData();
@@ -904,6 +879,76 @@ class Tinebase_Frontend_Json extends Tinebase_Frontend_Json_Abstract
         
         return $registryData;
     }
+
+    /**
+     * get app preferences for registry
+     *
+     * @param Tinebase_Model_Application $application
+     * @return array
+     * @throws Tinebase_Exception_NotFound
+     */
+    protected function _getAppPreferencesForRegistry(Tinebase_Model_Application $application)
+    {
+        $registryData = array();
+        $appPrefs = Tinebase_Core::getPreference($application->name);
+        if ($appPrefs !== NULL) {
+            $allPrefs = $appPrefs->getAllApplicationPreferences();
+            if (Tinebase_Core::isLogLevel(Zend_Log::TRACE)) Tinebase_Core::getLogger()->trace(__METHOD__ . '::' . __LINE__
+                . ' ' . print_r($allPrefs, TRUE));
+
+            foreach ($allPrefs as $pref) {
+                try {
+                    $registryData['preferences'][$pref] = $appPrefs->{$pref};
+                } catch (Exception $e) {
+                    Tinebase_Core::getLogger()->warn(__METHOD__ . '::' . __LINE__ . ' Could not get ' . $pref . '  preference: ' . $e);
+                }
+            }
+        }
+
+        return $registryData;
+    }
+
+    /**
+     * get registry data from application frontend json class
+     *
+     * @param Tinebase_Model_Application $application
+     * @return array
+     * @throws Tinebase_Exception_InvalidArgument
+     */
+    protected function _getCustomAppRegistry(Tinebase_Model_Application $application)
+    {
+        $jsonAppName = $application->name . '_Frontend_Json';
+        if (! class_exists($jsonAppName)) {
+            return array();
+        }
+
+        if (Tinebase_Core::isLogLevel(Zend_Log::DEBUG)) {
+            Tinebase_Core::getLogger()->debug(__METHOD__ . '::' . __LINE__
+                . ' Getting registry data for app ' . $application->name);
+        }
+
+        try {
+            $applicationJson = new $jsonAppName();
+            $registryData = $applicationJson->getRegistryData();
+
+        } catch (Exception $e) {
+            Tinebase_Exception::log($e);
+            if (! $e instanceof Tinebase_Exception_AccessDenied && ! in_array($application->name, array('Tinebase', 'Addressbook', 'Admin'))) {
+                Tinebase_Core::getLogger()->warn(__METHOD__ . '::' . __LINE__ . ' Disabling ' . $application->name . ': ' . $e);
+                Tinebase_Application::getInstance()->setApplicationState(array($application->getId()), Tinebase_Application::DISABLED);
+            }
+            return array();
+        }
+
+        // TODO get this from app controller / modelconfig
+        foreach ($applicationJson->getRelatableModels() as $relModel) {
+            $registryData[$relModel['ownApp']]['relatableModels'][] = $relModel;
+        }
+        $registryData['models'] = $applicationJson->getModelsConfiguration();
+        $registryData['defaultModel'] = $applicationJson->getDefaultModel();
+
+        return $registryData;
+    }
     
     /**
      * search / get custom field values
index da7d57f..74e6ba8 100644 (file)
@@ -96,10 +96,7 @@ abstract class Tinebase_Frontend_Json_Abstract extends Tinebase_Frontend_Abstrac
     {
         $ret = NULL;
         if ($this->_configuredModels) {
-            foreach ($this->_configuredModels as $modelName) {
-                $recordClass = $this->_applicationName . '_Model_' . $modelName;
-                $ret[$modelName] = $recordClass::getConfiguration()->getFrontendConfiguration();
-            }
+            return Tinebase_ModelConfiguration::getFrontendConfigForModels($this->_configuredModels, $this->_applicationName);
         }
         
         return $ret;
index f3adfc4..d66a15e 100644 (file)
@@ -964,6 +964,27 @@ class Tinebase_ModelConfiguration {
         $this->_filterModel['query'] = $queryFilterData;
     }
 
+    /**
+     * get modelconfig for an array of models
+     *
+     * @param array $models
+     * @param string $appname
+     * @return array
+     */
+    public static function getFrontendConfigForModels($models, $appname = null)
+    {
+        $modelconfig = array();
+        foreach ($models as $modelName) {
+            $recordClass = $appname ? $appname . '_Model_' . $modelName : $modelName;
+            $config = $recordClass::getConfiguration();
+            if ($config) {
+                $modelconfig[$modelName] = $config->getFrontendConfiguration();
+            }
+        }
+
+        return $modelconfig;
+    }
+
     public function getIdProperty()
     {
         return $this->_idProperty;
index 1b07357..981e7c9 100644 (file)
@@ -238,9 +238,9 @@ class Tinebase_Server_Json extends Tinebase_Server_Abstract implements Tinebase_
             }
         }
 
-        if (Tinebase_Core::isRegistered(Tinebase_Core::USER)) {
-            // TODO pass classes here??
-            self::_addModelConfigMethods($server);
+        if (Tinebase_Core::isRegistered(Tinebase_Core::USER) && is_object(Tinebase_Core::getUser())) {
+            $definitions = self::_getModelConfigMethods();
+            $server->loadFunctions($definitions);
         }
         
         if (isset($cache)) {
@@ -250,12 +250,6 @@ class Tinebase_Server_Json extends Tinebase_Server_Abstract implements Tinebase_
         return $server;
     }
 
-    protected static function _addModelConfigMethods(Zend_Json_Server $server)
-    {
-        $definitions = self::_getModelConfigMethods();
-        $server->loadFunctions($definitions);
-    }
-    
     /**
      * handler for JSON api requests
      * @todo session expire handling
@@ -278,35 +272,8 @@ class Tinebase_Server_Json extends Tinebase_Server_Abstract implements Tinebase_
             }
             
             $this->_methods[] = $method;
-            
-            $classes = array();
-            
-            // add json apis which require no auth
-            $classes['Tinebase_Frontend_Json'] = 'Tinebase';
-            
-            // register additional Json apis only available for authorised users
-            if (Tinebase_Session::isStarted() && Zend_Auth::getInstance()->hasIdentity()) {
-                
-                $applicationParts = explode('.', $method);
-                $applicationName = ucfirst($applicationParts[0]);
-                
-                switch($applicationName) {
-                    // additional Tinebase json apis
-                    case 'Tinebase_Container':
-                        $classes['Tinebase_Frontend_Json_Container'] = 'Tinebase_Container';
-                        break;
-                    case 'Tinebase_PersistentFilter':
-                        $classes['Tinebase_Frontend_Json_PersistentFilter'] = 'Tinebase_PersistentFilter';
-                        break;
-                        
-                    default;
-                        if(Tinebase_Core::getUser() && Tinebase_Core::getUser()->hasRight($applicationName, Tinebase_Acl_Rights_Abstract::RUN)) {
-                            $classes[$applicationName.'_Frontend_Json'] = $applicationName;
-                        }
-                        break;
-                }
-            }
-            
+
+            $classes = self::_getServerClasses();
             $server = self::_getServer($classes);
 
             $response = $server->handle($request);
@@ -370,29 +337,45 @@ class Tinebase_Server_Json extends Tinebase_Server_Abstract implements Tinebase_
      */
     public static function getServiceMap()
     {
-        $classes = array();
+        $classes = self::_getServerClasses();
+        $server = self::_getServer($classes);
         
+        $server->setTarget('index.php')
+               ->setEnvelope(Zend_Json_Server_Smd::ENV_JSONRPC_2);
+            
+        $smd = $server->getServiceMap();
+
+        return $smd;
+    }
+
+    /**
+     * get frontend classes for json server
+     *
+     * @return array
+     */
+    protected static function _getServerClasses()
+    {
+        $classes = array();
+
         $classes['Tinebase_Frontend_Json'] = 'Tinebase';
-        
+
         if (Tinebase_Core::isRegistered(Tinebase_Core::USER)) {
             $classes['Tinebase_Frontend_Json_Container'] = 'Tinebase_Container';
             $classes['Tinebase_Frontend_Json_PersistentFilter'] = 'Tinebase_PersistentFilter';
-            
+
             $userApplications = Tinebase_Core::getUser()->getApplications(TRUE);
-            foreach($userApplications as $application) {
+            foreach ($userApplications as $application) {
                 $jsonAppName = $application->name . '_Frontend_Json';
-                $classes[$jsonAppName] = $application->name;
+                if (class_exists($jsonAppName)) {
+                    $classes[$jsonAppName] = $application->name;
+                }
             }
         }
-        
-        $server = self::_getServer($classes);
-        
-        $server->setTarget('index.php')
-               ->setEnvelope(Zend_Json_Server_Smd::ENV_JSONRPC_2);
-            
-        $smd = $server->getServiceMap();
 
-        return $smd;
+        if (Tinebase_Core::isLogLevel(Zend_Log::TRACE)) Tinebase_Core::getLogger()->trace(__METHOD__ . '::' . __LINE__
+            . ' Got frontend classes: ' . print_r($classes, true));
+
+        return $classes;
     }
 
     /**
@@ -491,6 +474,9 @@ class Tinebase_Server_Json extends Tinebase_Server_Abstract implements Tinebase_
             }
         }
 
+        if (Tinebase_Core::isLogLevel(Zend_Log::TRACE)) Tinebase_Core::getLogger()->trace(__METHOD__ . '::' . __LINE__
+            . ' Got MC definitions: ' . print_r(array_keys($definitions), true));
+
         return $definitions;
     }