Commit 95b20606 authored by KevinLevie's avatar KevinLevie
Browse files

Refactor to make it easier to reuse this extension, use a custom resource...

Refactor to make it easier to reuse this extension, use a custom resource directory or alternative data formats
parent 53ea9e99
<?php
/**
* Class following Singleton pattern for specific extension configuration
* The actual configuration loader has moved to CRM_Civiconfig_Loader!
*
* @author Erik Hommel (CiviCooP) <erik.hommel@civicoop.org>
* @date 13 Jan 2016
* @license AGPL-3.0
*
* OOP-fixes Copyright Johan Vervloet (Chirojeugd-Vlaanderen vzw) 2016,
* licensed under the terms of AGPL-3.0.
*/
class CRM_Civiconfig_Config {
private static $_singleton;
protected $_resourcesPath = null;
/**
* CRM_Civiconfig_Config constructor.
* @var self $_singleton
*/
function __construct() {
// TODO: If the extensions dir is '[civicrm.files]/ext/' (which is the default)
// the construction below will not work.
$settings = civicrm_api3('Setting', 'Getsingle', array());
$this->resourcesPath = $settings['extensionsDir'].'/org.iida.civiconfig/resources/';
foreach ($this->getConfigurableEntityTypes() as $entityType) {
$configClass = "CRM_Civiconfig_Entity_$entityType";
// TODO: Check whether class exists.
$entityTypeConfig = new $configClass();
// Create all entities using the json files in the resources directory.
$entityTypeConfig->createAll(new CRM_Civiconfig_ParamsProvider_ResourcesDir($entityType));
}
}
private static $_singleton;
/**
* Singleton method
*
* @return CRM_Civiconfig_Config
* @access public
* @static
* Return class instance.
* @return self
*/
public static function singleton() {
if (!self::$_singleton) {
self::$_singleton = new CRM_Civiconfig_Config();
self::$_singleton = new \CRM_Civiconfig_Config();
}
return self::$_singleton;
}
/**
* Returns all entity types that can be configured with this extension.
*
* The order of this array determines the order of configuration of the
* entity types.
*
*
* @return array array of entity type names.
*/
private function getConfigurableEntityTypes() {
public function getSupportedEntityTypes() {
// TODO: make this list configurable.
return array(
'ContactType',
......@@ -68,7 +45,7 @@ class CRM_Civiconfig_Config {
'Tag',
'LocationType',
'CustomGroup',
// customGroep as last one because it might need one of the previous ones (option group, relationship types)
// customGroup as last one because it might need one of the previous ones (option group, relationship types)
// DO NOT INCLUDE CustomField, because custom fields are updated together
// with custom groups.
);
......
......@@ -7,6 +7,7 @@
* @license AGPL-3.0
*/
abstract class CRM_Civiconfig_Entity {
/**
* Method to create or update any entity
*
......@@ -18,15 +19,14 @@ abstract class CRM_Civiconfig_Entity {
/**
* Creates/updates all objects at once.
*
* @param $paramsProvider ParamsProvider to provide the 'params' for the
* objects to be created.
* This function now simply gets an array of items instead of having to fetch it here.
*
* @param array $paramsArray
*/
public function createAll(CRM_Civiconfig_ParamsProvider $paramsProvider) {
$paramsArray = $paramsProvider->getParamsArray();
public function createAll($paramsArray) {
foreach ($paramsArray as $params) {
$this->create($params);
}
}
}
<?php
/**
* Class CRM_Civiconfig_EntityException
* Exception thrown when an error occurs processing a single entity.
* (Further up, we'll consider this non fatal and continue processing other entity types.)
*/
class CRM_Civiconfig_EntityException extends \Exception {
}
\ No newline at end of file
<?php
/**
* Class CRM_Civiconfig_Exception
* Exception thrown when a general error occurs (will be considered fatal further up).
*/
class CRM_Civiconfig_Exception extends \Exception {
}
\ No newline at end of file
<?php
/**
* This class contains this extension's main function, to update the configuration based on files provided.
* Call the updateConfiguration and pass a custom ParamsProvider for custom loading implementations.
* The API method calls the updateConfigurationFromJson function in this class.
*
* @hashtag #extensiongraffitiwall
* @author Erik Hommel (CiviCooP) <erik.hommel@civicoop.org>
* @author Johan Vervloet (Chirojeugd-Vlaanderen vzw) <helpdesk@chiro.be>
* @author Kevin Levie <kevin.levie@civicoop.org>
* @license AGPL-3.0
*/
class CRM_Civiconfig_Loader {
/**
* Update configuration using the JSON files in the $resourcePath directory.
*
* @param string $resourcePath Resource path
* @return bool Success
* @throws \CRM_Civiconfig_Exception Thrown if resource path isn't valid
*/
public function updateConfigurationFromJson($resourcePath) {
$paramsProvider = new \CRM_Civiconfig_ParamsProvider_ResourcesDir($resourcePath);
return $this->updateConfiguration($paramsProvider);
}
/**
* Update configuration by walking supported entity types and trying to fetch data from the passed ParamsProvider.
*
* @param \CRM_Civiconfig_ParamsProvider $paramsProvider ParamsProvider implementation
* @return array Array with loader status per entity type (SUCCESS or ERROR + caught EntityException message)
*/
public function updateConfiguration(\CRM_Civiconfig_ParamsProvider $paramsProvider) {
$ret = [];
// Get supported entity types
$config = \CRM_Civiconfig_Config::singleton();
$supportedEntityTypes = $config->getSupportedEntityTypes();
// Walk all types and try to fetch and process data for each one
foreach ($supportedEntityTypes as $entityType) {
try {
// Check if we have a class to support this type
$configClass = "\\CRM_Civiconfig_Entity_$entityType";
if (!class_exists($configClass)) {
throw new \CRM_Civiconfig_EntityException("Class '{$configClass}' does not exist!");
}
// Fetch data from ParamsProvider
$params = $paramsProvider->getParamsArray($entityType);
// Instantiate class and try to process the data provided
/** @var \CRM_Civiconfig_Entity $entityTypeConfig */
$entityTypeConfig = new $configClass();
$entityTypeConfig->createAll($params);
$ret[$entityType] = "SUCCESS";
} catch (\CRM_Civiconfig_EntityException $e) {
$ret[$entityType] = "ERROR: " . $e->getMessage();
}
}
return $ret;
}
}
\ No newline at end of file
......@@ -51,10 +51,20 @@ class CRM_Civiconfig_Utils {
}
$valueList[0] = ts('- select -');
asort($valueList);
} catch (CiviCRM_API3_Exception $ex) {
} catch (\CiviCRM_API3_Exception $ex) {
throw new Exception('Could not find an option group with name '.$optionGroupName
.' contact your system administrator. Error from API OptionGroup Getvalue: '.$ex->getMessage());
}
return $valueList;
}
/**
* Get the default resources path: /resources/ within this extension's root directory.
* (this way should work in all configurations, right?)
*
* @return string Default Path
*/
public static function getDefaultResourcesPath() {
return realpath(__DIR__ . '/../../') . '/resources/';
}
}
\ No newline at end of file
<?php
/**
* Civiconfig.Update API Updates the configuration with new settings
*
* @param array $params
* @return array API result descriptor
* @see civicrm_api3_create_success
* @see civicrm_api3_create_error
* @throws API_Exception
*/
function civicrm_api3_civiconfig_update($params) {
try {
// Get default path if it isn't set ([this.extension]/resources/)
if (empty($params['path'])) {
$params['path'] = \CRM_Civiconfig_Utils::getDefaultResourcesPath();
}
// Run loader and try to parse some JSON files!
$loader = new \CRM_Civiconfig_Loader;
$result = $loader->updateConfigurationFromJson($params['path']);
// Seems everything went well!
// Individual entity types may or may have not run correctly - this will be shown in $result
return civicrm_api3_create_success($result, $params, 'Civiconfig', 'Update');
} catch(\CRM_Civiconfig_Exception $e) {
// A serious error occurred, loader couldn't continue: return exception message
return civicrm_api3_create_error($e->getMessage());
}
}
/**
* Civiconfig.Update API specification
* This is used for documentation and validation.
* @see http://wiki.civicrm.org/confluence/display/CRM/API+Architecture+Standards
*
* @param array $params description of fields supported by this API call
* @return void
*/
function _civicrm_api3_civiconfig_update_spec(&$params) {
$params = [
'path' => [
'required' => 0,
'name' => 'path',
'title' => 'Resource Directory Path (default: org.civicoop.configitems/resources)',
'type' => \CRM_Utils_Type::T_STRING,
],
];
}
\ No newline at end of file
<?php
/**
* IidaConfig.Update API Updates the configuration of IIDA with new settings
*
* @param array $params
* @return array API result descriptor
* @see civicrm_api3_create_success
* @see civicrm_api3_create_error
* @throws API_Exception
*/
function civicrm_api3_iida_config_update($params) {
CRM_Civiconfig_Config::singleton();
return civicrm_api3_create_success(array(ts('Updated IIDA CiviCRM installation')), $params, 'IidaConfig', 'Update');
}
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment