}
}
else {
- if (!array_key_exists($key, $params) || empty($params[$key])) {
+ // Disallow empty values except for the number zero.
+ // TODO: create a utility for this since it's needed in many places
+ if (!array_key_exists($key, $params) || (empty($params[$key]) && $params[$key] !== 0 && $params[$key] !== '0')) {
$unmatched[] = $key;
}
}
// len ('civicrm_api3_') == 13
$name = substr($name, 13, $last - 13);
}
+
+ $name = _civicrm_api_get_camel_name($name, 3);
- if (strtolower($name) == 'individual' || strtolower($name) == 'household' || strtolower($name) == 'organization') {
+ if ($name == 'Individual' || $name == 'Household' || $name == 'Organization') {
$name = 'Contact';
}
- //hack to deal with incorrectly named BAO/DAO - see CRM-10859 -
- // several of these have been removed but am not confident mailing_recipients is
- // tests so have not tackled.
- // correct approach for im is unclear
- if($name == 'mailing_recipients' || $name == 'MailingRecipients'){
- return 'CRM_Mailing_BAO_Recipients';
+ // hack to deal with incorrectly named BAO/DAO - see CRM-10859
+
+ // FIXME: DAO should be renamed CRM_Mailing_DAO_MailingRecipients
+ // but am not confident mailing_recipients is tested so have not tackled.
+ if ($name == 'MailingRecipients') {
+ return 'CRM_Mailing_DAO_Recipients';
+ }
+ // FIXME: DAO should be renamed CRM_Mailing_DAO_MailingComponent
+ if ($name == 'MailingComponent') {
+ return 'CRM_Mailing_DAO_Component';
+ }
+ // FIXME: DAO should be renamed CRM_ACL_DAO_AclRole
+ if ($name == 'AclRole') {
+ return 'CRM_ACL_DAO_EntityRole';
}
- if(strtolower($name) == 'im'){
- return 'CRM_Core_BAO_IM';
+ // FIXME: DAO should be renamed CRM_SMS_DAO_SmsProvider
+ // But this would impact SMS extensions so need to coordinate
+ // Probably best approach is to migrate them to use the api and decouple them from core BAOs
+ if ($name == 'SmsProvider') {
+ return 'CRM_SMS_DAO_Provider';
}
- return CRM_Core_DAO_AllCoreTables::getFullName(_civicrm_api_get_camel_name($name, 3));
+ // FIXME: DAO names should follow CamelCase convention
+ if ($name == 'Im' || $name == 'Acl') {
+ $name = strtoupper($name);
+ }
+ return CRM_Core_DAO_AllCoreTables::getFullName($name);
}
/**
* @return mixed
*/
function _civicrm_api3_get_BAO($name) {
+ // FIXME: DAO should be renamed CRM_Badge_DAO_BadgeLayout
+ if ($name == 'PrintLabel') {
+ return 'CRM_Badge_BAO_Layout';
+ }
$dao = _civicrm_api3_get_DAO($name);
- $dao = str_replace("DAO", "BAO", $dao);
- return $dao;
+ if (!$dao) {
+ return NULL;
+ }
+ $bao = str_replace("DAO", "BAO", $dao);
+ $file = strtr($bao, '_', '/') . '.php';
+ // Check if this entity actually has a BAO. Fall back on the DAO if not.
+ return stream_resolve_include_path($file) ? $bao : $dao;
}
/**
}
}
- $skipPermissions = CRM_Utils_Array::value('check_permissions', $params)? 0 :1;
+ $skipPermissions = !empty($params['check_permissions']) ? 0 :1;
list($entities, $options) = CRM_Contact_BAO_Query::apiQuery(
$newParams,
$returnProperties = array_fill_keys($returnProperties, 1);
}
}
- if($entity && $action =='get' ){
- if(CRM_Utils_Array::value('id',$returnProperties)){
+ if ($entity && $action =='get') {
+ if (CRM_Utils_Array::value('id',$returnProperties)) {
$returnProperties[$entity . '_id'] = 1;
unset($returnProperties['id']);
}
}
}
-
$options = array(
- 'offset' => $offset,
- 'sort' => $sort,
- 'limit' => $limit,
+ 'offset' => CRM_Utils_Rule::integer($offset) ? $offset : NULL,
+ 'sort' => CRM_Utils_Rule::string($sort) ? $sort : NULL,
+ 'limit' => CRM_Utils_Rule::integer($limit) ? $limit : NULL,
'is_count' => $is_count,
'return' => !empty($returnProperties) ? $returnProperties : NULL,
);
+ if ($options['sort'] && stristr($options['sort'], 'SELECT')) {
+ throw new API_Exception('invalid string in sort options');
+ }
+
if (!$queryObject) {
return $options;
}
if (substr($n, 0, 7) == 'return.') {
$legacyreturnProperties[substr($n, 7)] = $v;
}
- elseif($n == 'id'){
+ elseif ($n == 'id') {
$inputParams[$entity. '_id'] = $v;
}
elseif (in_array($n, $otherVars)) {}
- else{
+ else {
$inputParams[$n] = $v;
+ if ($v && !is_array($v) && stristr($v, 'SELECT')) {
+ throw new API_Exception('invalid string');
+ }
}
}
$options['return'] = array_merge($returnProperties, $legacyreturnProperties);
* @param $entity string API entity being accessed
* @param $action string API action being performed
* @param $params array params of the API call
- * @param $throw bool whether to throw exception instead of returning false
+ * @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
return TRUE;
}
- foreach ($permissions as $perm) {
- if (!CRM_Core_Permission::check($perm)) {
- if ($throw) {
- throw new Exception("API permission check failed for $entity/$action call; missing permission: $perm.");
- }
- else {
- return FALSE;
+ 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;
}
if (is_null($bao)) {
return civicrm_api3_create_error('Entity not created (' . $fct_name . ')');
}
+ elseif (is_a($bao, 'CRM_Core_Error')) {
+ //some wierd circular thing means the error takes itself as an argument
+ $msg = $bao->getMessages($bao);
+ // the api deals with entities on a one-by-one basis. However, the contribution bao pushes entities
+ // onto the error object - presumably because the contribution import is not handling multiple errors correctly
+ // so we need to reset the error object here to avoid getting concatenated errors
+ //@todo - the mulitple error handling should be moved out of the contribution object to the import / multiple entity processes
+ CRM_Core_Error::singleton()->reset();
+ throw new API_Exception($msg);
+ }
else {
$values = array();
_civicrm_api3_object_to_array($bao, $values[$bao->id]);
* @return CRM_Core_DAO|NULL an instance of the BAO
*/
function _civicrm_api3_basic_create_fallback($bao_name, &$params) {
- $entityName = CRM_Core_DAO_AllCoreTables::getBriefName(get_parent_class($bao_name));
+ $dao_name = get_parent_class($bao_name);
+ if ($dao_name === 'CRM_Core_DAO' || !$dao_name) {
+ $dao_name = $bao_name;
+ }
+ $entityName = CRM_Core_DAO_AllCoreTables::getBriefName($dao_name);
if (empty($entityName)) {
throw new API_Exception("Class \"$bao_name\" does not map to an entity name", "unmapped_class_to_entity", array(
'class_name' => $bao_name,
$hook = empty($params['id']) ? 'create' : 'edit';
CRM_Utils_Hook::pre($hook, $entityName, CRM_Utils_Array::value('id', $params), $params);
- $instance = new $bao_name();
+ $instance = new $dao_name();
$instance->copyValues($params);
$instance->save();
CRM_Utils_Hook::post($hook, $entityName, $instance->id, $instance);