<?php
-// $Id$
-
/*
+--------------------------------------------------------------------+
- | CiviCRM version 4.3 |
+ | CiviCRM version 4.4 |
+--------------------------------------------------------------------+
| Copyright CiviCRM LLC (c) 2004-2013 |
+--------------------------------------------------------------------+
}
$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?
+ 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']) && CRM_Utils_Array::value('api.has_parent', $dao['params'])) {
$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);
$values[$key]['id'] = $item[$entity . "_id"];
}
if(!empty($item['financial_type_id'])){
+ //4.3 legacy handling
$values[$key]['contribution_type_id'] = $item['financial_type_id'];
}
+ if(!empty($item['next_sched_contribution_date'])){
+ // 4.4 legacy handling
+ $values[$key]['next_sched_contribution'] = $item['next_sched_contribution_date'];
+ }
}
}
$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'));
+ $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'));
if ($undefined) {
$result['undefined_fields'] = array_merge($undefined);
}
$result['version'] = 3;
if (is_array($values)) {
- $result['count'] = count($values);
+ $result['count'] = (int) count($values);
// Convert value-separated strings to array
_civicrm_api3_separate_values($values);
if (is_array($params[$field])) {
//get the actual fieldname from db
$fieldName = $allfields[$field]['name'];
- //array is the syntax for SQL clause
- foreach ($params[$field] as $operator => $criteria) {
- if (in_array($operator, $acceptedSQLOperators)) {
- switch ($operator) {
- // unary operators
-
- case 'IS NULL':
- case 'IS NOT NULL':
- $dao->whereAdd(sprintf('%s %s', $fieldName, $operator));
- break;
-
- // ternary operators
-
- case 'BETWEEN':
- case 'NOT BETWEEN':
- if (empty($criteria[0]) || empty($criteria[1])) {
- throw new exception("invalid criteria for $operator");
- }
- $dao->whereAdd(sprintf('%s ' . $operator . ' "%s" AND "%s"', $fieldName, CRM_Core_DAO::escapeString($criteria[0]), CRM_Core_DAO::escapeString($criteria[1])));
- break;
-
- // n-ary operators
-
- case 'IN':
- case 'NOT IN':
- if (empty($criteria)) {
- throw new exception("invalid criteria for $operator");
- }
- $escapedCriteria = array_map(array('CRM_Core_DAO', 'escapeString'), $criteria);
- $dao->whereAdd(sprintf('%s %s ("%s")', $fieldName, $operator, implode('", "', $escapedCriteria)));
- break;
-
- // binary operators
-
- default:
-
- $dao->whereAdd(sprintf('%s %s "%s"', $fieldName, $operator, CRM_Core_DAO::escapeString($criteria)));
- }
- }
+ $where = CRM_Core_DAO::createSqlFilter($fieldName, $params[$field], 'String');
+ if(!empty($where)) {
+ $dao->whereAdd($where);
}
}
else {
}
}
}
- if (!empty($options['return']) && is_array($options['return'])) {
+ if (!empty($options['return']) && is_array($options['return']) && empty($options['is_count'])) {
$dao->selectAdd();
$options['return']['id'] = TRUE;// ensure 'id' is included
$allfields = _civicrm_api3_get_unique_name_array($dao);
* @return array $options options extracted from params
*/
function _civicrm_api3_get_options_from_params(&$params, $queryObject = FALSE, $entity = '', $action = '') {
+ $is_count = FALSE;
$sort = CRM_Utils_Array::value('sort', $params, 0);
$sort = CRM_Utils_Array::value('option.sort', $params, $sort);
$sort = CRM_Utils_Array::value('option_sort', $params, $sort);
$limit = CRM_Utils_Array::value('option_limit', $params, $limit);
if (is_array(CRM_Utils_Array::value('options', $params))) {
+ // is count is set by generic getcount not user
+ $is_count = CRM_Utils_Array::value('is_count', $params['options']);
$offset = CRM_Utils_Array::value('offset', $params['options'], $offset);
$limit = CRM_Utils_Array::value('limit', $params['options'], $limit);
$sort = CRM_Utils_Array::value('sort', $params['options'], $sort);
'offset' => $offset,
'sort' => $sort,
'limit' => $limit,
+ 'is_count' => $is_count,
'return' => !empty($returnProperties) ? $returnProperties : NULL,
);
+
if (!$queryObject) {
return $options;
}
function _civicrm_api3_apply_options_to_dao(&$params, &$dao, $entity) {
$options = _civicrm_api3_get_options_from_params($params,FALSE,$entity);
- $dao->limit((int)$options['offset'], (int)$options['limit']);
- if (!empty($options['sort'])) {
- $dao->orderBy($options['sort']);
+ if(!$options['is_count']) {
+ $dao->limit((int)$options['offset'], (int)$options['limit']);
+ if (!empty($options['sort'])) {
+ $dao->orderBy($options['sort']);
+ }
}
}
*/
function _civicrm_api3_dao_to_array($dao, $params = NULL, $uniqueFields = TRUE, $entity = "") {
$result = array();
+ if(isset($params['options']) && CRM_Utils_Array::value('is_count', $params['options'])) {
+ return $dao->count();
+ }
if (empty($dao) || !$dao->find()) {
return array();
}
+ if(isset($dao->count)) {
+ return $dao->count;
+ }
//if custom fields are required we will endeavour to set them . NB passing $entity in might be a bit clunky / unrequired
if (!empty($entity) && CRM_Utils_Array::value('return', $params) && is_array($params['return'])) {
foreach ($params['return'] as $return) {
$bao = new $bao_name();
_civicrm_api3_dao_set_filter($bao, $params, TRUE,$entity);
if ($returnAsSuccess) {
- return civicrm_api3_create_success(_civicrm_api3_dao_to_array($bao, $params, FALSE, $entity), $params, $entity);
+ return civicrm_api3_create_success(_civicrm_api3_dao_to_array($bao, $params, FALSE, $entity), $params, $entity);
}
else {
return _civicrm_api3_dao_to_array($bao, $params, FALSE, $entity);
else {
$values = array();
_civicrm_api3_object_to_array($bao, $values[$bao->id]);
- return civicrm_api3_create_success($values, $params, NULL, 'create', $bao);
+ return civicrm_api3_create_success($values, $params, $entity, 'create', $bao);
}
}
if ($bao !== FALSE) {
return civicrm_api3_create_success(TRUE);
}
- return civicrm_api3_create_error('Could not delete entity id ' . $params['id']);
+ throw new API_Exception('Could not delete entity id ' . $params['id']);
}
elseif (method_exists($bao_name, 'delete')) {
$dao = new $bao_name();
}
}
else {
- return civicrm_api3_create_error('Could not delete entity id ' . $params['id']);
+ throw new API_Exception('Could not delete entity id ' . $params['id']);
}
}
- return civicrm_api3_create_error('no delete method found');
+ throw new API_Exception('no delete method found');
}
/**
break;
case CRM_Utils_Type::T_MONEY:
- if (!CRM_Utils_Rule::money($params[$fieldName])) {
+ if (!CRM_Utils_Rule::money($params[$fieldName]) && !empty($params[$fieldName])) {
throw new Exception($fieldName . " is not a valid amount: " . $params[$fieldName]);
}
}
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);
}
return $customfields;
}
-
+/**
+ * Translate the custom field data_type attribute into a std 'type'
+ */
+function _getStandardTypeFromCustomDataType($dataType) {
+ $mapping = array(
+ 'String' => CRM_Utils_Type::T_STRING,
+ 'Int' => CRM_Utils_Type::T_INT,
+ 'Money' => CRM_Utils_Type::T_MONEY,
+ 'Memo' => CRM_Utils_Type::T_LONGTEXT,
+ 'Float' => CRM_Utils_Type::T_FLOAT,
+ 'Date' => CRM_Utils_Type::T_DATE,
+ 'Boolean' => CRM_Utils_Type::T_BOOLEAN,
+ 'StateProvince' => CRM_Utils_Type::T_INT,
+ 'File' => CRM_Utils_Type::T_STRING,
+ 'Link' => CRM_Utils_Type::T_STRING,
+ 'ContactReference' => CRM_Utils_Type::T_INT,
+ 'Country' => CRM_Utils_Type::T_INT,
+ );
+ return $mapping[$dataType];
+}
/**
* Return array of defaults for the given API (function is a wrapper on getfields)
*/
function _civicrm_api3_getdefaults($apiRequest) {
$defaults = array();
- $result = civicrm_api($apiRequest['entity'],
+ $result = civicrm_api3($apiRequest['entity'],
'getfields',
array(
- 'version' => 3,
'action' => $apiRequest['action'],
)
);
}
return;
}
- $result = civicrm_api($apiRequest['entity'],
+ $result = civicrm_api3($apiRequest['entity'],
'getfields',
array(
- 'version' => 3,
'action' => $apiRequest['action'],
)
);
*/
function _civicrm_api3_validate_integer(&$params, &$fieldName, &$fieldInfo, $entity) {
//if fieldname exists in params
- if (CRM_Utils_Array::value($fieldname, $params)) {
+ if (CRM_Utils_Array::value($fieldName, $params)) {
// if value = 'user_contact_id' (or similar), replace value with contact id
- if (!is_integer($params[$fieldname])) {
- $realContactId = _civicrm_api3_resolve_contactID($params[$fieldname]);
- if (!is_numeric($realContactId)) {
- throw new API_Exception("\"$fieldname\" cannot be resolved to a contact ID", 2002, array('error_field' => $fieldname,"type"=>"integer"));
+ if (!is_numeric($params[$fieldName]) && is_scalar($params[$fieldName])) {
+ $realContactId = _civicrm_api3_resolve_contactID($params[$fieldName]);
+ if ('unknown-user' === $realContactId) {
+ throw new API_Exception("\"$fieldName\" \"{$params[$fieldName]}\" cannot be resolved to a contact ID", 2002, array('error_field' => $fieldName,"type"=>"integer"));
+ } elseif (is_numeric($realContactId)) {
+ $params[$fieldName] = $realContactId;
}
- $params[$fieldname] = $realContactId;
}
if (!empty($fieldInfo['pseudoconstant']) || !empty($fieldInfo['options'])) {
_civicrm_api3_api_match_pseudoconstant($params, $entity, $fieldName, $fieldInfo);
* Determine a contact ID using a string expression
*
* @param string $contactIdExpr e.g. "user_contact_id" or "@user:username"
- * @return int|NULL
+ * @return int|NULL|'unknown-user'
*/
function _civicrm_api3_resolve_contactID($contactIdExpr) {
//if value = 'user_contact_id' replace value with logged in user id
$ufID = $config->userSystem->getUfId($matches[1]);
if (!$ufID) {
- return NULL;
+ return 'unknown-user';
}
$contactID = CRM_Core_BAO_UFMatch::getContactId($ufID);
- if (!$ufID) {
- return NULL;
+ if (!$contactID) {
+ return 'unknown-user';
}
return $contactID;
}
+ return NULL;
}
function _civicrm_api3_validate_html(&$params, &$fieldName, &$fieldInfo) {
if ($value = CRM_Utils_Array::value($fieldName, $params)) {
if (!CRM_Utils_Rule::xssString($value)) {
- throw new API_Exception('Illegal characters in input (potential scripting attack)',array("field"=>$fieldName,"error_code"=>"xss"));
+ throw new API_Exception('Illegal characters in input (potential scripting attack)', array("field"=>$fieldName,"error_code"=>"xss"));
}
}
}
throw new Exception("Currency not a valid code: $value");
}
}
- if (!empty($fieldInfo['pseudoconstant']) || !empty($fieldInfo['options'])) {
+ if (!empty($fieldInfo['pseudoconstant']) || !empty($fieldInfo['options']) || !empty($fieldInfo['enumValues'])) {
_civicrm_api3_api_match_pseudoconstant($params, $entity, $fieldName, $fieldInfo);
}
// Check our field length