X-Git-Url: https://vcs.fsf.org/?a=blobdiff_plain;f=api%2Fv3%2Futils.php;h=31c5d626da28e574d3326e3b9c2164e80d13282f;hb=9c7ec7086d8984dcc3dc11f643bfa0f4b3c6eeda;hp=76adc47b68e1292de2fccf6960c61122659779d1;hpb=c1c7a930efe9d1539a018b16d5725933e4843d2b;p=civicrm-core.git diff --git a/api/v3/utils.php b/api/v3/utils.php index 76adc47b68..31c5d626da 100644 --- a/api/v3/utils.php +++ b/api/v3/utils.php @@ -1,9 +1,9 @@ $data * @param array $data - * @param object $dao DAO / BAO object to be freed here * * @throws API_Exception * @return array */ -function civicrm_api3_create_error($msg, $data = array(), &$dao = NULL) { - //fix me - $dao should be param 4 & 3 should be $apiRequest - if (is_object($dao)) { - $dao->free(); - } - - if (is_array($dao)) { - if ($msg == 'DB Error: constraint violation' || substr($msg, 0,9) == 'DB Error:' || $msg == 'DB Error: already exists') { - try { - $fields = _civicrm_api3_api_getfields($dao); - _civicrm_api3_validate_fields($dao['entity'], $dao['action'], $dao['params'], $fields, TRUE); - } - catch(Exception $e) { - $msg = $e->getMessage(); - } - } - } +function civicrm_api3_create_error($msg, $data = array()) { $data['is_error'] = 1; $data['error_message'] = $msg; - // we will show sql to privelledged user only (not sure of a specific - // security hole here but seems sensible - perhaps should apply to the trace as well? + // we will show sql to privileged user only (not sure of a specific + // security hole here but seems sensible - perhaps should apply to the trace as well?) if(isset($data['sql']) && CRM_Core_Permission::check('Administer CiviCRM')) { - $data['debug_information'] = $data['sql']; - } - if (is_array($dao) && isset($dao['params']) && is_array($dao['params']) && !empty($dao['params']['api.has_parent'])) { - $errorCode = empty($data['error_code']) ? 'chained_api_failed' : $data['error_code']; - throw new API_Exception('Error in call to ' . $dao['entity'] . '_' . $dao['action'] . ' : ' . $msg, $errorCode, $data); + $data['debug_information'] = $data['sql']; // Isn't this redundant? + } else { + unset($data['sql']); } return $data; } @@ -216,7 +197,7 @@ function civicrm_api3_create_success($values = 1, $params = array(), $entity = N $allFields = array_keys($apiFields['values']); } $paramFields = array_keys($params); - $undefined = array_diff($paramFields, $allFields, array_keys($_COOKIE), array('action', 'entity', 'debug', 'version', 'check_permissions', 'IDS_request_uri', 'IDS_user_agent', 'return', 'sequential', 'rowCount', 'option_offset', 'option_limit', 'custom', 'option_sort', 'options')); + $undefined = array_diff($paramFields, $allFields, array_keys($_COOKIE), array('action', 'entity', 'debug', 'version', 'check_permissions', 'IDS_request_uri', 'IDS_user_agent', 'return', 'sequential', 'rowCount', 'option_offset', 'option_limit', 'custom', 'option_sort', 'options', 'prettyprint')); if ($undefined) { $result['undefined_fields'] = array_merge($undefined); } @@ -253,7 +234,7 @@ function civicrm_api3_create_success($values = 1, $params = array(), $entity = N } if(!empty($params['options']['metadata'])) { // we've made metadata an array but only supporting 'fields' atm - if(in_array('fields', $params['options']['metadata'])) { + if(in_array('fields', (array) $params['options']['metadata'])) { $fields = civicrm_api3($entity, 'getfields', array('action' => substr($action, 0, 3) == 'get' ? 'get' : 'create')); $result['metadata']['fields'] = $fields['values']; } @@ -286,7 +267,7 @@ function _civicrm_api3_get_DAO($name) { // len ('civicrm_api3_') == 13 $name = substr($name, 13, $last - 13); } - + $name = _civicrm_api_get_camel_name($name, 3); if ($name == 'Individual' || $name == 'Household' || $name == 'Organization') { @@ -318,7 +299,21 @@ function _civicrm_api3_get_DAO($name) { if ($name == 'Im' || $name == 'Acl') { $name = strtoupper($name); } - return CRM_Core_DAO_AllCoreTables::getFullName($name); + $dao = CRM_Core_DAO_AllCoreTables::getFullName($name); + if ($dao || !$name) { + return $dao; + } + + // Really weird apis can declare their own DAO name. Not sure if this is a good idea... + if(file_exists("api/v3/$name.php")) { + include_once "api/v3/$name.php"; + } + $daoFn = "_civicrm_api3_" . _civicrm_api_get_entity_name_from_camel($name) . "_DAO"; + if (function_exists($daoFn)) { + return $daoFn(); + } + + return NULL; } /** @@ -409,6 +404,8 @@ function _civicrm_api3_store_values(&$fields, &$params, &$values) { * others that use the query object. Note that this function passes permission information in. * The others don't * + * * Ideally this would be merged with _civicrm_get_query_object but we need to resolve differences in what the + * 2 variants call * @param $entity * @param array $params as passed into api get or getcount function * @param array $additional_options @@ -479,6 +476,7 @@ function _civicrm_api3_get_using_query_object($entity, $params, $additional_opti } } + $skipPermissions = !empty($params['check_permissions']) ? 0 :1; list($entities, $options) = CRM_Contact_BAO_Query::apiQuery( @@ -499,6 +497,45 @@ function _civicrm_api3_get_using_query_object($entity, $params, $additional_opti return $entities; } +/** + * get dao query object based on input params + * Ideally this would be merged with _civicrm_get_using_query_object but we need to resolve differences in what the + * 2 variants call + * + * @param array $params + * @param string $mode + * @param string $entity + * @return CRM_Core_DAO query object + */ +function _civicrm_api3_get_query_object($params, $mode, $entity) { + $options = _civicrm_api3_get_options_from_params($params, TRUE, $entity, 'get'); + $sort = CRM_Utils_Array::value('sort', $options, NULL); + $offset = CRM_Utils_Array::value('offset', $options); + $rowCount = CRM_Utils_Array::value('limit', $options); + $inputParams = CRM_Utils_Array::value('input_params', $options, array()); + $returnProperties = CRM_Utils_Array::value('return', $options, NULL); + if (empty($returnProperties)) { + $returnProperties = CRM_Contribute_BAO_Query::defaultReturnProperties($mode); + } + + $newParams = CRM_Contact_BAO_Query::convertFormValues($inputParams); + $query = new CRM_Contact_BAO_Query($newParams, $returnProperties, NULL, + FALSE, FALSE, $mode + ); + list($select, $from, $where, $having) = $query->query(); + + $sql = "$select $from $where $having"; + + if (!empty($sort)) { + $sql .= " ORDER BY $sort "; + } + if(!empty($rowCount)) { + $sql .= " LIMIT $offset, $rowCount "; + } + $dao = CRM_Core_DAO::executeQuery($sql); + return array($dao, $query); +} + /** * Function transfers the filters being passed into the DAO onto the params object */ @@ -533,9 +570,6 @@ function _civicrm_api3_dao_set_filter(&$dao, $params, $unique = TRUE, $entity) { } } } - // http://issues.civicrm.org/jira/browse/CRM-9150 - stick with 'simple' operators for now - // support for other syntaxes is discussed in ticket but being put off for now - $acceptedSQLOperators = array('=', '<=', '>=', '>', '<', 'LIKE', "<>", "!=", "NOT LIKE", 'IN', 'NOT IN', 'BETWEEN', 'NOT BETWEEN'); if (!$fields) { $fields = array(); } @@ -725,7 +759,9 @@ function _civicrm_api3_apply_options_to_dao(&$params, &$dao, $entity) { $options = _civicrm_api3_get_options_from_params($params,FALSE,$entity); if(!$options['is_count']) { - $dao->limit((int)$options['offset'], (int)$options['limit']); + if(!empty($options['limit'])) { + $dao->limit((int)$options['offset'], (int)$options['limit']); + } if (!empty($options['sort'])) { $dao->orderBy($options['sort']); } @@ -940,48 +976,6 @@ function _civicrm_api3_check_required_fields($params, $daoName, $return = FALSE) return TRUE; } -/** - * Check permissions for a given API call. - * - * @param $entity string API entity being accessed - * @param $action string API action being performed - * @param $params array params of the API call - * @param $throw deprecated bool whether to throw exception instead of returning false - * - * @throws Exception - * @return bool whether the current API user has the permission to make the call - */ -function _civicrm_api3_api_check_permission($entity, $action, &$params, $throw = TRUE) { - // return early unless we’re told explicitly to do the permission check - if (empty($params['check_permissions']) or $params['check_permissions'] == FALSE) { - return TRUE; - } - - require_once 'CRM/Core/DAO/permissions.php'; - $permissions = _civicrm_api3_permissions($entity, $action, $params); - - // $params might’ve been reset by the alterAPIPermissions() hook - if (isset($params['check_permissions']) and $params['check_permissions'] == FALSE) { - return TRUE; - } - - if (!CRM_Core_Permission::check($permissions)) { - if ($throw) { - if(is_array($permissions)) { - $permissions = implode(' and ', $permissions); - } - throw new Exception("API permission check failed for $entity/$action call; insufficient permission: require $permissions"); - } - else { - //@todo remove this - this is an internal api function called with $throw set to TRUE. It is only called with false - // in tests & that should be tidied up - return FALSE; - } - } - - return TRUE; -} - /** * Function to do a 'standard' api get - when the api is only doing a $bao->find then use this * @@ -1242,7 +1236,8 @@ function _civicrm_api3_validate_date(&$params, &$fieldName, &$fieldInfo) { if (strtotime($params[$fieldInfo['name']]) === FALSE) { throw new Exception($fieldInfo['name'] . " is not a valid date: " . $params[$fieldInfo['name']]); } - $params[$fieldInfo['name']] = CRM_Utils_Date::processDate($params[$fieldInfo['name']]); + $format = ($fieldInfo['type'] == CRM_Utils_Type::T_DATE) ? 'Ymd000000' : 'YmdHis'; + $params[$fieldInfo['name']] = CRM_Utils_Date::processDate($params[$fieldInfo['name']], NULL, FALSE, $format); } if ((CRM_Utils_Array::value('name', $fieldInfo) != $fieldName) && !empty($params[$fieldName])) { //If the unique field name differs from the db name & is set handle it here @@ -1289,7 +1284,7 @@ function _civicrm_api3_validate_uniquekey(&$params, &$fieldName, &$fieldInfo) { // an entry already exists for this unique field if ($existing['count'] == 1) { // question - could this ever be a security issue? - throw new Exception("Field: `$fieldName` must be unique. An conflicting entity already exists - id: " . $existing['id']); + throw new API_Exception("Field: `$fieldName` must be unique. An conflicting entity already exists - id: " . $existing['id']); } } @@ -1451,23 +1446,17 @@ function _civicrm_api_get_custom_fields($entity, &$params) { 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); - } + + $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']); - $customfields['custom_' . $key] = $value; - if (in_array('custom_' . $key, $getoptions)) { - $customfields['custom_' . $key]['options'] = CRM_Core_BAO_CustomOption::valuesByID($key); - } - unset($customfields[$key]); + $ret['custom_' . $key] = $value; } - return $customfields; + return $ret; } /** * Translate the custom field data_type attribute into a std 'type' @@ -1489,33 +1478,7 @@ function _getStandardTypeFromCustomDataType($dataType) { ); return $mapping[$dataType]; } -/** - * Return array of defaults for the given API (function is a wrapper on getfields) - */ -function _civicrm_api3_getdefaults($apiRequest, $fields) { - $defaults = array(); - - foreach ($fields as $field => $values) { - if (isset($values['api.default'])) { - $defaults[$field] = $values['api.default']; - } - } - return $defaults; -} -/** - * Return array of defaults for the given API (function is a wrapper on getfields) - */ -function _civicrm_api3_getrequired($apiRequest, $fields) { - $required = array('version'); - - foreach ($fields as $field => $values) { - if (!empty($values['api.required'])) { - $required[] = $field; - } - } - return $required; -} /** * Fill params array with alternate (alias) values where a field has an alias and that is filled & the main field isn't @@ -1611,12 +1574,9 @@ function _civicrm_api3_validate_integer(&$params, &$fieldName, &$fieldInfo, $ent function _civicrm_api3_resolve_contactID($contactIdExpr) { //if value = 'user_contact_id' replace value with logged in user id if ($contactIdExpr == "user_contact_id") { - $session = &CRM_Core_Session::singleton(); - if (!is_numeric($session->get('userID'))) { - return NULL; - } - return $session->get('userID'); - } elseif (preg_match('/^@user:(.*)$/', $contactIdExpr, $matches)) { + return CRM_Core_Session::getLoggedInContactID(); + } + elseif (preg_match('/^@user:(.*)$/', $contactIdExpr, $matches)) { $config = CRM_Core_Config::singleton(); $ufID = $config->userSystem->getUfId($matches[1]);