function getTemplateFileName () { $request = CRM_Utils_System::currentPath(); if (false !== strpos($request, '..')) { die ("SECURITY FATAL: the url can't contain '..'. Please report the issue on the forum at civicrm.org"); } $request = split ('/',$request); $tplfile = NULL; $smarty= CRM_Core_Smarty::singleton( ); $smarty->assign("options",array()); if (CRM_Utils_Array::value(2, $request)) { $tplfile = _civicrm_api_get_camel_name($request[2]); $tplfile = explode('?', $tplfile); $tpl = 'dataviz/'.$tplfile[0].'.tpl'; } if (CRM_Utils_Array::value(3, $request)) { $r3 = _civicrm_api_get_camel_name($request[3]); $smarty->assign("id",$r3); } if (!$tplfile) { $tpl = "CRM/Civizualise/Page/Main.tpl"; } if( !$smarty->template_exists($tpl) ){ header("Status: 404 Not Found"); die ("Can't find the requested template file templates/$tpl"); } return $tpl; }
/** * Get information about fields for a given api request. * * Getfields information is used for documentation, validation, default setting * We first query the scheme using the $dao->fields function & then augment * that information by calling the _spec functions that apply to the relevant function * Note that we use 'unique' field names as described in the xml/schema files * for get requests & just field name for create. This is because some get functions * access multiple objects e.g. contact api accesses is_deleted from the activity * table & from the contact table * * @param array $apiRequest * Api request as an array. Keys are. * - entity: string * - action: string * - version: string * - function: callback (mixed) * - params: array, varies * * @param bool $unique * Determines whether to key by unique field names (only affects get-type) actions * * @return array * API success object */ function civicrm_api3_generic_getfields($apiRequest, $unique = TRUE) { static $results = array(); if (CRM_Utils_Array::value('cache_clear', $apiRequest['params'])) { $results = array(); // we will also clear pseudoconstants here - should potentially be moved to relevant BAO classes CRM_Core_PseudoConstant::flush(); if (!empty($apiRequest['params']['fieldname'])) { CRM_Utils_PseudoConstant::flushConstant($apiRequest['params']['fieldname']); } if (!empty($apiRequest['params']['option_group_id'])) { $optionGroupName = civicrm_api('option_group', 'getvalue', array('version' => 3, 'id' => $apiRequest['params']['option_group_id'], 'return' => 'name')); if (is_string($optionGroupName)) { CRM_Utils_PseudoConstant::flushConstant(_civicrm_api_get_camel_name($optionGroupName)); } } } $entity = $apiRequest['entity']; $lowercase_entity = _civicrm_api_get_entity_name_from_camel($entity); $subentity = CRM_Utils_Array::value('contact_type', $apiRequest['params']); $action = CRM_Utils_Array::value('action', $apiRequest['params']); $sequential = empty($apiRequest['params']['sequential']) ? 0 : 1; $apiRequest['params']['options'] = CRM_Utils_Array::value('options', $apiRequest['params'], array()); $optionsToResolve = (array) CRM_Utils_Array::value('get_options', $apiRequest['params']['options'], array()); if (!$action || $action == 'getvalue' || $action == 'getcount') { $action = 'get'; } // If no options, return results from cache if (!$apiRequest['params']['options'] && isset($results[$entity . $subentity]) && isset($action, $results[$entity . $subentity]) && isset($action, $results[$entity . $subentity][$sequential])) { return $results[$entity . $subentity][$action][$sequential]; } // defaults based on data model and API policy switch ($action) { case 'getfields': $values = _civicrm_api_get_fields($entity, FALSE, $apiRequest['params']); return civicrm_api3_create_success($values, $apiRequest['params'], $entity, 'getfields'); case 'create': case 'update': case 'replace': $unique = FALSE; case 'get': case 'getsingle': case 'getcount': case 'getstat': $metadata = _civicrm_api_get_fields($apiRequest['entity'], $unique, $apiRequest['params']); if (empty($metadata['id'])) { // if id is not set we will set it eg. 'id' from 'case_id', case_id will be an alias if (!empty($metadata[strtolower($apiRequest['entity']) . '_id'])) { $metadata['id'] = $metadata[$lowercase_entity . '_id']; unset($metadata[$lowercase_entity . '_id']); $metadata['id']['api.aliases'] = array($lowercase_entity . '_id'); } } else { // really the preference would be to set the unique name in the xml // question is which is a less risky fix this close to a release - setting in xml for the known failure // (note) or setting for all api where fields is returning 'id' & we want to accept 'note_id' @ the api layer // nb we don't officially accept note_id anyway - rationale here is more about centralising a now-tested // inconsistency $metadata['id']['api.aliases'] = array($lowercase_entity . '_id'); } break; case 'delete': $metadata = array('id' => array('title' => $entity . ' ID', 'api.required' => 1, 'api.aliases' => array($lowercase_entity . '_id'), 'type' => CRM_Utils_Type::T_INT)); break; // Note: adding setvalue case here instead of in a generic spec function because // some APIs override the generic setvalue fn which causes the generic spec to be overlooked. // Note: adding setvalue case here instead of in a generic spec function because // some APIs override the generic setvalue fn which causes the generic spec to be overlooked. case 'setvalue': $metadata = array('field' => array('title' => 'Field name', 'api.required' => 1, 'type' => CRM_Utils_Type::T_STRING), 'id' => array('title' => $entity . ' ID', 'api.required' => 1, 'type' => CRM_Utils_Type::T_INT), 'value' => array('title' => 'Value', 'description' => "Field value to set", 'api.required' => 1)); if (array_intersect(array('all', 'field'), $optionsToResolve)) { $options = civicrm_api3_generic_getfields(array('entity' => $entity, array('params' => array('action' => 'create')))); $metadata['field']['options'] = CRM_Utils_Array::collect('title', $options['values']); } break; default: // oddballs are on their own $metadata = array(); } // Normalize this for the sake of spec funcions $apiRequest['params']['options']['get_options'] = $optionsToResolve; // find any supplemental information $hypApiRequest = array('entity' => $apiRequest['entity'], 'action' => $action, 'version' => $apiRequest['version']); try { list($apiProvider, $hypApiRequest) = \Civi::service('civi_api_kernel')->resolve($hypApiRequest); if (isset($hypApiRequest['function'])) { $helper = '_' . $hypApiRequest['function'] . '_spec'; } else { // not implemented MagicFunctionProvider $helper = NULL; } } catch (\Civi\API\Exception\NotImplementedException $e) { $helper = NULL; } if (function_exists($helper)) { // alter $helper($metadata, $apiRequest); } foreach ($metadata as $fieldname => $fieldSpec) { // Ensure 'name' is set if (!isset($fieldSpec['name'])) { $metadata[$fieldname]['name'] = $fieldname; } _civicrm_api3_generic_get_metadata_options($metadata, $apiRequest, $fieldname, $fieldSpec); // Convert options to "sequential" format if ($sequential && !empty($metadata[$fieldname]['options'])) { $metadata[$fieldname]['options'] = CRM_Utils_Array::makeNonAssociative($metadata[$fieldname]['options']); } } $results[$entity][$action][$sequential] = civicrm_api3_create_success($metadata, $apiRequest['params'], $entity, 'getfields'); return $results[$entity][$action][$sequential]; }
/** * used to load a template "inline", eg. for ajax, without having to build a menu for each template */ public static function loadTemplate() { $request = CRM_Utils_Request::retrieve('q', 'String'); if (FALSE !== strpos($request, '..')) { die("SECURITY FATAL: the url can't contain '..'. Please report the issue on the forum at civicrm.org"); } $request = explode('/', $request); $entity = _civicrm_api_get_camel_name($request[2]); $tplfile = _civicrm_api_get_camel_name($request[3]); $tpl = 'CRM/' . $entity . '/Page/Inline/' . $tplfile . '.tpl'; $smarty = CRM_Core_Smarty::singleton(); CRM_Utils_System::setTitle("{$entity}::{$tplfile} inline {$tpl}"); if (!$smarty->template_exists($tpl)) { header("Status: 404 Not Found"); die("Can't find the requested template file templates/{$tpl}"); } if (array_key_exists('id', $_GET)) { // special treatmenent, because it's often used $smarty->assign('id', (int) $_GET['id']); // an id is always positive } $pos = strpos(implode(array_keys($_GET)), '<'); if ($pos !== FALSE) { die("SECURITY FATAL: one of the param names contains <"); } $param = array_map('htmlentities', $_GET); unset($param['q']); $smarty->assign_by_ref("request", $param); if (!array_key_exists('HTTP_X_REQUESTED_WITH', $_SERVER) || $_SERVER['HTTP_X_REQUESTED_WITH'] != "XMLHttpRequest") { $smarty->assign('tplFile', $tpl); $config = CRM_Core_Config::singleton(); $content = $smarty->fetch('CRM/common/' . strtolower($config->userFramework) . '.tpl'); if (!defined('CIVICRM_UF_HEAD') && ($region = CRM_Core_Region::instance('html-header', FALSE))) { CRM_Utils_System::addHTMLHead($region->render('')); } CRM_Utils_System::appendTPLFile($tpl, $content); return CRM_Utils_System::theme($content); } else { $content = "<!-- .tpl file embeded: {$tpl} -->\n"; CRM_Utils_System::appendTPLFile($tpl, $content); echo $content . $smarty->fetch($tpl); CRM_Utils_System::civiExit(); } }
function testToCamel() { $cases = array('Contribution' => 'Contribution', 'contribution' => 'Contribution', 'OptionValue' => 'OptionValue', 'optionValue' => 'OptionValue', 'option_value' => 'OptionValue', 'UFJoin' => 'UFJoin', 'uf_join' => 'UFJoin'); foreach ($cases as $input => $expected) { $actual = _civicrm_api_get_camel_name($input); $this->assertEquals($expected, $actual, sprintf('input=%s expected=%s actual=%s', $input, $expected, $actual)); } }
/** * Create test generated example in api/v3/examples. * * To turn this off (e.g. on the server) set * define(DONT_DOCUMENT_TEST_CONFIG ,1); * in your settings file * * @param string $entity * @param string $action * @param array $params * Array as passed to civicrm_api function. * @param array $result * Array as received from the civicrm_api function. * @param string $testFunction * Calling function - generally __FUNCTION__. * @param string $testFile * Called from file - generally __FILE__. * @param string $description * Descriptive text for the example file. * @param string $exampleName * Name for this example file (CamelCase) - if omitted the action name will be substituted. */ private function documentMe($entity, $action, $params, $result, $testFunction, $testFile, $description = "", $exampleName = NULL) { if (defined('DONT_DOCUMENT_TEST_CONFIG') && DONT_DOCUMENT_TEST_CONFIG) { return; } $entity = _civicrm_api_get_camel_name($entity); $action = strtolower($action); if (empty($exampleName)) { // Attempt to convert lowercase action name to CamelCase. // This is clunky/imperfect due to the convention of all lowercase actions. $exampleName = CRM_Utils_String::convertStringToCamel($action); $knownPrefixes = array('Get', 'Set', 'Create', 'Update', 'Send'); foreach ($knownPrefixes as $prefix) { if (strpos($exampleName, $prefix) === 0 && $prefix != $exampleName) { $exampleName[strlen($prefix)] = strtoupper($exampleName[strlen($prefix)]); } } } $this->tidyExampleResult($result); if (isset($params['version'])) { unset($params['version']); } // Format multiline description as array $desc = array(); if (is_string($description) && strlen($description)) { foreach (explode("\n", $description) as $line) { $desc[] = trim($line); } } $smarty = CRM_Core_Smarty::singleton(); $smarty->assign('testFunction', $testFunction); $smarty->assign('function', _civicrm_api_get_entity_name_from_camel($entity) . "_{$action}"); $smarty->assign('params', $params); $smarty->assign('entity', $entity); $smarty->assign('testFile', basename($testFile)); $smarty->assign('description', $desc); $smarty->assign('result', $result); $smarty->assign('action', $action); global $civicrm_root; if (file_exists($civicrm_root . '/tests/templates/documentFunction.tpl')) { if (!is_dir($civicrm_root . "/api/v3/examples/{$entity}")) { mkdir($civicrm_root . "/api/v3/examples/{$entity}"); } $f = fopen($civicrm_root . "/api/v3/examples/{$entity}/{$exampleName}.php", "w+b"); fwrite($f, $smarty->fetch($civicrm_root . '/tests/templates/documentFunction.tpl')); fclose($f); } }
/** * Load/require all files related to an entity. * * This should not normally be called because it's does a file-system scan; it's * only appropriate when introspection is really required (eg for "getActions"). * * @param string $entity * API entity name. * @param int $version * API version. */ protected function loadEntity($entity, $version) { $camelName = _civicrm_api_get_camel_name($entity, $version); // Check for master entity file; to match _civicrm_api_resolve(), only load the first one $stdFile = 'api/v' . $version . '/' . $camelName . '.php'; if (\CRM_Utils_File::isIncludable($stdFile)) { require_once $stdFile; } // Check for standalone action files; to match _civicrm_api_resolve(), only load the first one $loaded_files = array(); // array($relativeFilePath => TRUE) $include_dirs = array_unique(explode(PATH_SEPARATOR, get_include_path())); foreach ($include_dirs as $include_dir) { foreach (array($camelName, 'Generic') as $name) { $action_dir = implode(DIRECTORY_SEPARATOR, array($include_dir, 'api', "v{$version}", $name)); if (!is_dir($action_dir)) { continue; } $iterator = new \DirectoryIterator($action_dir); foreach ($iterator as $fileinfo) { $file = $fileinfo->getFilename(); if (array_key_exists($file, $loaded_files)) { continue; // action provided by an earlier item on include_path } $parts = explode(".", $file); if (end($parts) == "php" && !preg_match('/Tests?\\.php$/', $file)) { require_once $action_dir . DIRECTORY_SEPARATOR . $file; $loaded_files[$file] = TRUE; } } } } }
function _civicrm_api_get_custom_fields($entity, &$params) { require_once 'CRM/Core/BAO/CustomField.php'; $customfields = array(); $entity = _civicrm_api_get_camel_name($entity); if (strtolower($entity) == 'contact') { $entity = CRM_Utils_Array::value('contact_type', $params); } $customfields = CRM_Core_BAO_CustomField::getFields($entity, FALSE, FALSE, CRM_Utils_Array::value('contact_sub_type', $params, FALSE), NULL, empty($params['contact_sub_type']), FALSE, FALSE); foreach ($customfields as $key => $value) { $customfields['custom_' . $key] = $value; unset($customfields[$key]); } return $customfields; }
/** * Return an array of fields for a given entity. * * This is the same as the BAO function but fields are prefixed with 'custom_' to represent api params. * * @param $entity * @param array $params * * @return array */ function _civicrm_api_get_custom_fields($entity, &$params) { $entity = _civicrm_api_get_camel_name($entity); if ($entity == 'Contact') { // Use sub-type if available, otherwise "NULL" to fetch from all contact types $entity = CRM_Utils_Array::value('contact_type', $params); } $customfields = CRM_Core_BAO_CustomField::getFields($entity, FALSE, FALSE, CRM_Utils_Array::value('contact_sub_type', $params), NULL, FALSE, FALSE, FALSE); $ret = array(); foreach ($customfields as $key => $value) { // Regular fields have a 'name' property $value['name'] = 'custom_' . $key; $value['title'] = $value['label']; $value['type'] = _getStandardTypeFromCustomDataType($value); $ret['custom_' . $key] = $value; } return $ret; }
/** * @inheritDoc * @param int $version * @param string $entity * @return array */ public function getActionNames($version, $entity) { $entity = _civicrm_api_get_camel_name($entity, $version); return isset($this->actions[$entity]) ? $this->actions[$entity] : $this->actions['*']; }
/** * Get information about fields for a given api request. Getfields information * is used for documentation, validation, default setting * We first query the scheme using the $dao->fields function & then augment * that information by calling the _spec functions that apply to the relevant function * Note that we use 'unique' field names as described in the xml/schema files * for get requests & just field name for create. This is because some get functions * access multiple objects e.g. contact api accesses is_deleted from the activity * table & from the contact table * * @param array $apiRequest api request as an array. Keys are * - entity: string * - action: string * - version: string * - function: callback (mixed) * - params: array, varies * @return array API success object */ function civicrm_api3_generic_getfields($apiRequest) { static $results = array(); if (CRM_Utils_Array::value('cache_clear', $apiRequest['params'])) { $results = array(); // we will also clear pseudoconstants here - should potentially be moved to relevant BAO classes CRM_Core_PseudoConstant::flush(); if (!empty($apiRequest['params']['fieldname'])) { CRM_Utils_PseudoConstant::flushConstant($apiRequest['params']['fieldname']); } if (!empty($apiRequest['params']['option_group_id'])) { $optionGroupName = civicrm_api('option_group', 'getvalue', array('version' => 3, 'id' => $apiRequest['params']['option_group_id'], 'return' => 'name')); if (is_string($optionGroupName)) { CRM_Utils_PseudoConstant::flushConstant(_civicrm_api_get_camel_name($optionGroupName)); } } } $entity = _civicrm_api_get_camel_name($apiRequest['entity']); $lcase_entity = _civicrm_api_get_entity_name_from_camel($entity); $subentity = CRM_Utils_Array::value('contact_type', $apiRequest['params']); $action = strtolower(CRM_Utils_Array::value('action', $apiRequest['params'])); $sequential = empty($apiRequest['params']) ? 0 : 1; $apiOptions = CRM_Utils_Array::value('options', $apiRequest['params'], array()); if ($action == 'getvalue' || $action == 'getvalue' || $action == 'getcount') { $action = 'get'; } if (empty($action)) { $action = 'get'; } // determines whether to use unique field names - seem comment block above $unique = TRUE; if (empty($apiOptions) && isset($results[$entity . $subentity]) && isset($action, $results[$entity . $subentity]) && isset($action, $results[$entity . $subentity][$sequential])) { return $results[$entity . $subentity][$action][$sequential]; } // defaults based on data model and API policy switch ($action) { case 'getfields': $values = _civicrm_api_get_fields($entity, false, $apiRequest['params']); return civicrm_api3_create_success($values, $apiRequest['params'], $entity, 'getfields'); case 'create': case 'update': case 'replace': $unique = FALSE; case 'get': $metadata = _civicrm_api_get_fields($apiRequest['entity'], $unique, $apiRequest['params']); if (empty($metadata['id'])) { // if id is not set we will set it eg. 'id' from 'case_id', case_id will be an alias if (!empty($metadata[strtolower($apiRequest['entity']) . '_id'])) { $metadata['id'] = $metadata[$lcase_entity . '_id']; unset($metadata[$lcase_entity . '_id']); $metadata['id']['api.aliases'] = array($lcase_entity . '_id'); } } else { // really the preference would be to set the unique name in the xml // question is which is a less risky fix this close to a release - setting in xml for the known failure // (note) or setting for all api where fields is returning 'id' & we want to accept 'note_id' @ the api layer // nb we don't officially accept note_id anyway - rationale here is more about centralising a now-tested // inconsistency $metadata['id']['api.aliases'] = array($lcase_entity . '_id'); } break; case 'delete': $metadata = array('id' => array('title' => 'Unique Identifier', 'api.required' => 1, 'api.aliases' => array($lcase_entity . '_id'), 'type' => CRM_Utils_Type::T_INT)); break; case 'getoptions': $metadata = array('field' => array('title' => 'Field to retrieve options for', 'api.required' => 1), 'context' => array('title' => 'Context string')); break; default: // oddballs are on their own $metadata = array(); } // find any supplemental information $hypApiRequest = array('entity' => $apiRequest['entity'], 'action' => $action, 'version' => $apiRequest['version']); $hypApiRequest += _civicrm_api_resolve($hypApiRequest); $helper = '_' . $hypApiRequest['function'] . '_spec'; if (function_exists($helper)) { // alter $helper($metadata, $apiRequest); } $fieldsToResolve = (array) CRM_Utils_Array::value('get_options', $apiOptions, array()); foreach ($metadata as $fieldname => $fieldSpec) { _civicrm_api3_generic_get_metadata_options($metadata, $apiRequest['entity'], $fieldname, $fieldSpec, $fieldsToResolve); } $results[$entity][$action][$sequential] = civicrm_api3_create_success($metadata, $apiRequest['params'], NULL, 'getfields'); return $results[$entity][$action][$sequential]; }
/** * Ajax callback to display code docs */ public static function getDoc() { if (!empty($_GET['entity']) && strpos($_GET['entity'], '.') === FALSE) { $entity = _civicrm_api_get_camel_name($_GET['entity']); $action = CRM_Utils_Array::value('action', $_GET); $doc = self::getDocblock($entity, $action); $result = array('doc' => $doc ? self::formatDocBlock($doc[0]) : 'Not found.', 'code' => $doc ? $doc[1] : NULL, 'file' => $doc ? $doc[2] : NULL); if (!$action) { $actions = civicrm_api3($entity, 'getactions'); $result['actions'] = CRM_Utils_Array::makeNonAssociative(array_combine($actions['values'], $actions['values'])); } CRM_Utils_JSON::output($result); } CRM_Utils_System::permissionDenied(); }
/** * Load/require all files related to an entity. * * This should not normally be called because it's does a file-system scan; it's * only appropriate when introspection is really required (eg for "getActions"). * * @param string $entity * @param int $version * * @return void */ function _civicrm_api_loadEntity($entity, $version = 3) { /* $apiRequest = array(); $apiRequest['entity'] = $entity; $apiRequest['action'] = 'pretty sure it will never exist. Trick to [try to] force resolve to scan everywhere'; $apiRequest['version'] = $version; // look up function, file, is_generic $apiRequest = _civicrm_api_resolve($apiRequest); */ $camelName = _civicrm_api_get_camel_name($entity, $version); // Check for master entity file; to match _civicrm_api_resolve(), only load the first one $stdFile = 'api/v' . $version . '/' . $camelName . '.php'; if (CRM_Utils_File::isIncludable($stdFile)) { require_once $stdFile; } // Check for standalone action files; to match _civicrm_api_resolve(), only load the first one $loaded_files = array(); // array($relativeFilePath => TRUE) $include_dirs = array_unique(explode(PATH_SEPARATOR, get_include_path())); foreach ($include_dirs as $include_dir) { $action_dir = implode(DIRECTORY_SEPARATOR, array($include_dir, 'api', "v{$version}", $camelName)); if (!is_dir($action_dir)) { continue; } $iterator = new DirectoryIterator($action_dir); foreach ($iterator as $fileinfo) { $file = $fileinfo->getFilename(); if (array_key_exists($file, $loaded_files)) { continue; // action provided by an earlier item on include_path } $parts = explode(".", $file); if (end($parts) == "php" && !preg_match('/Tests?\\.php$/', $file)) { require_once $action_dir . DIRECTORY_SEPARATOR . $file; $loaded_files[$file] = TRUE; } } } }
/** * Return an array of fields for a given entity - this is the same as the BAO function but * fields are prefixed with 'custom_' to represent api params */ function _civicrm_api_get_custom_fields($entity, &$params) { $customfields = array(); $entity = _civicrm_api_get_camel_name($entity); if (strtolower($entity) == 'contact') { // Use sub-type if available, otherwise stick with 'Contact' $entity = CRM_Utils_Array::value('contact_type', $params); } $retrieveOnlyParent = FALSE; // we could / should probably test for other subtypes here - e.g. activity_type_id if ($entity == 'Contact') { empty($params['contact_sub_type']); } $customfields = CRM_Core_BAO_CustomField::getFields($entity, FALSE, FALSE, CRM_Utils_Array::value('contact_sub_type', $params, FALSE), NULL, $retrieveOnlyParent, FALSE, FALSE); $ret = array(); foreach ($customfields as $key => $value) { // Regular fields have a 'name' property $value['name'] = 'custom_' . $key; $value['title'] = $value['label']; $value['type'] = _getStandardTypeFromCustomDataType($value['data_type']); $ret['custom_' . $key] = $value; } return $ret; }
/** * Get information about fields for a given api request. Getfields information * is used for documentation, validation, default setting * We first query the scheme using the $dao->fields function & then augment * that information by calling the _spec functions that apply to the relevant function * Note that we use 'unique' field names as described in the xml/schema files * for get requests & just field name for create. This is because some get functions * access multiple objects e.g. contact api accesses is_deleted from the activity * table & from the contact table * * @param array $apiRequest api request as an array. Keys are * - entity: string * - action: string * - version: string * - function: callback (mixed) * - params: array, varies * @return array API success object */ function civicrm_api3_generic_getfields($apiRequest) { static $results = array(); if (CRM_Utils_Array::value('cache_clear', $apiRequest['params'])) { $results = array(); } $entity = _civicrm_api_get_camel_name($apiRequest['entity']); $lcase_entity = _civicrm_api_get_entity_name_from_camel($entity); $subentity = CRM_Utils_Array::value('contact_type', $apiRequest['params']); $action = strtolower(CRM_Utils_Array::value('action', $apiRequest['params'])); if ($action == 'getvalue' || $action == 'getvalue' || $action == 'getcount') { $action = 'get'; } if (empty($action)) { if (CRM_Utils_Array::value($entity . $subentity, $results) && CRM_Utils_Array::value('values', $results[$entity . $subentity])) { return $results[$entity . $subentity]; } else { $values = _civicrm_api_get_fields($entity); $results[$entity] = civicrm_api3_create_success($values, $apiRequest['params'], $entity, 'getfields'); return $results[$entity]; } } // determines whether to use unique field names - seem comment block above $unique = TRUE; if (isset($results[$entity . $subentity]) && CRM_Utils_Array::value($action, $results[$entity])) { return $results[$entity . $subentity][$action]; } // defaults based on data model and API policy switch ($action) { case 'getfields': $values = _civicrm_api_get_fields($entity, $apiRequest['params']); $results[$entity][$action] = civicrm_api3_create_success($values, $apiRequest['params'], $entity, 'getfields'); return $results[$entity][$action]; case 'create': case 'update': case 'replace': $unique = FALSE; case 'get': $metadata = _civicrm_api_get_fields($apiRequest['entity'], $unique, $apiRequest['params']); if (empty($metadata['id']) && !empty($metadata[$apiRequest['entity'] . '_id'])) { $metadata['id'] = $metadata[$lcase_entity . '_id']; $metadata['id']['api.aliases'] = array($lcase_entity . '_id'); unset($metadata[$lcase_entity . '_id']); } break; case 'delete': $metadata = array('id' => array('title' => 'Unique Identifier', 'api.required' => 1, 'api.aliases' => array($lcase_entity . '_id'))); break; default: // oddballs are on their own $metadata = array(); } // find any supplemental information $hypApiRequest = array('entity' => $apiRequest['entity'], 'action' => $action, 'version' => $apiRequest['version']); $hypApiRequest += _civicrm_api_resolve($hypApiRequest); $helper = '_' . $hypApiRequest['function'] . '_spec'; if (function_exists($helper)) { // alter $helper($metadata); } foreach ($metadata as $fieldname => $field) { if (array_key_exists('pseudoconstant', $field) && !CRM_Utils_Array::value('FKClassName', $field)) { $options = civicrm_api('constant', 'get', array('version' => 3, 'name' => $field['pseudoconstant'])); if (is_array(CRM_Utils_Array::value('values', $options))) { $metadata[$fieldname]['options'] = $options['values']; } } if (array_key_exists('enumValues', $field)) { $metadata[$fieldname]['options'] = explode(',', $field['enumValues']); } } $results[$entity][$action] = civicrm_api3_create_success($metadata, $apiRequest['params'], NULL, 'getfields'); return $results[$entity][$action]; }
/** * Return an array of fields for a given entity - this is the same as the BAO function but * fields are prefixed with 'custom_' to represent api params */ function _civicrm_api_get_custom_fields($entity, &$params) { $customfields = array(); $entity = _civicrm_api_get_camel_name($entity); if (strtolower($entity) == 'contact') { // Use sub-type if available, otherwise stick with 'Contact' $entity = CRM_Utils_Array::value('contact_type', $params); } $retrieveOnlyParent = FALSE; // we could / should probably test for other subtypes here - e.g. activity_type_id if ($entity == 'Contact') { empty($params['contact_sub_type']); } $customfields = CRM_Core_BAO_CustomField::getFields($entity, FALSE, FALSE, CRM_Utils_Array::value('contact_sub_type', $params, FALSE), NULL, $retrieveOnlyParent, FALSE, FALSE); // find out if we have any requests to resolve options $getoptions = CRM_Utils_Array::value('get_options', CRM_Utils_Array::value('options', $params)); if (!is_array($getoptions)) { $getoptions = array($getoptions); } foreach ($customfields as $key => $value) { // Regular fields have a 'name' property $value['name'] = 'custom_' . $key; $value['type'] = _getStandardTypeFromCustomDataType($value['data_type']); $customfields['custom_' . $key] = $value; if (in_array('custom_' . $key, $getoptions)) { $customfields['custom_' . $key]['options'] = CRM_Core_BAO_CustomOption::valuesByID($key); } unset($customfields[$key]); } return $customfields; }