*
* This is a simple get function, but it should be usable for any kind of
* entity. I created it to work around CRM-16036.
- *
+ *
* @param string $dao_name
* Name of DAO
* @param array $params
- * As passed into api get function.
+ * As passed into api get function.
+ * @param bool $return_as_success
+ * Return in api success format.
+ *
* @return array
*/
-function _civicrm_api3_get_using_query_object_simple($dao_name, $params) {
- // TODO: count() query
+function _civicrm_api3_get_using_query_object_simple($dao_name, $params, $return_as_success = TRUE) {
$dao = new $dao_name();
$entity = _civicrm_api_get_entity_name_from_dao($dao);
$custom_fields = _civicrm_api3_custom_fields_for_entity($entity);
// values.
$select_fields = array();
- // array with elements {'column' => 'value'}
- // again, column is prefixed by 'a.' or the name of the custom field
- // table.
- // TODO: change this to something like {'column', 'operator', 'value'}
- $where_clauses=array();
+ // array with elements array('colummn', 'operator', 'value');
+ $where_clauses = array();
// Tables we need to join with to retrieve the custom values.
- $tables_to_join=array();
+ $tables_to_join = array();
// populate $select_fields
- if (empty($options['return']) || !is_array($options['return'])) {
- // return every field if no return option exists.
- foreach ($entity_field_names as $field_name) {
+ $return_all_fields = (empty($options['return']) || !is_array($options['return']));
+
+ // default fields
+ foreach ($entity_field_names as $field_name) {
+ if ($return_all_fields || !empty($options['return'][$field_name])) {
// 'a.' is an alias for the entity table.
$select_fields["a.$field_name"] = $field_name;
}
- foreach ($custom_fields as $cf_id => $custom_field) {
+ }
+
+ // custom fields
+ foreach ($custom_fields as $cf_id => $custom_field) {
+ $field_name = "custom_$cf_id";
+ if ($return_all_fields || !empty($options['return'][$field_name])) {
$table_name = $custom_field["table_name"];
$column_name = $custom_field["column_name"];
$select_fields["$table_name.$column_name"] = "custom_$cf_id";
+ // remember that we will need to join the correct table.
if (!in_array($table_name, $tables_to_join)) {
$tables_to_join[] = $table_name;
}
}
}
- else {
- // look at return option.
- foreach ($options['return'] as $field_name => $value) {
- if (in_array($field_name, $entity_field_names)) {
- // select entity field
- $select_fields["a.$field_name"] = $field_name;
- }
- else {
- // always select ID.
- $select_fields["a.id"] = "id";
- $cf_id = CRM_Core_BAO_CustomField::getKeyID($field_name);
- if ($cf_id) {
- $table_name = $custom_fields[$cf_id]["table_name"];
- $column_name = $custom_fields[$cf_id]["column_name"];
- $select_fields["$table_name.$column_name"] = "custom_$cf_id";
- if (!in_array($table_name, $tables_to_join)) {
- $tables_to_join[] = $table_name;
- }
- }
- }
- }
+ if (!in_array("a.id", $select_fields)) {
+ // Always select the ID.
+ $select_fields["a.id"] = "id";
}
// populate $where_clauses
- foreach($params as $key => $value) {
+ foreach ($params as $key => $value) {
+ if (!is_array($value)) {
+ $operator = "=";
+ $rhs = $value;
+ }
+ else {
+ // We expect only one element in the array, of the form
+ // "operator" => "rhs".
+ $dummy = array_keys($value);
+ $operator = $dummy[0];
+ if (!in_array($operator, CRM_Core_DAO::acceptedSQLOperators())) {
+ // if operator not found, use = as default.
+ $operator = "=";
+ }
+ $rhs = $value[$operator];
+ }
+
if (in_array($key, $entity_field_names)) {
- $where_clauses["a.$key"] = $value;
+ $where_clauses[] = array("a.$key", $operator, $rhs);
}
else {
$cf_id = CRM_Core_BAO_CustomField::getKeyID($key);
if ($cf_id) {
$table_name = $custom_fields[$cf_id]["table_name"];
$column_name = $custom_fields[$cf_id]["column_name"];
- $where_clauses["$table_name.$column_name"] = $value;
+ $where_clauses[] = array(
+ "$table_name.$column_name",
+ $operator,
+ $rhs,
+ );
if (!in_array($table_name, $tables_to_join)) {
$tables_to_join[] = $table_name;
}
};
// build query
+ $query = CRM_Utils_SQL_Select::from($dao->tableName() . " a");
- $select = "SELECT 1";
- $from = "FROM " . $dao->tableName() . " a";
- $where = "WHERE 1=1";
- $query_params = array();
-
+ $i = 0;
foreach ($select_fields as $column => $alias) {
- $select .= ", $column as $alias";
+ ++$i;
+ $query = $query->select("!column_$i as !alias_$i", array("!column_$i" => $column, "!alias_$i" => $alias));
}
foreach ($tables_to_join as $table_name) {
- $from .= " LEFT OUTER JOIN $table_name ON $table_name.entity_id = a.id";
+ ++$i;
+ $query = $query->join(
+ "!table_name_$i",
+ "LEFT OUTER JOIN !table_name_$i ON !table_name_$i.entity_id = a.id",
+ array("!table_name_$i" => $table_name)
+ );
}
- $param_nr = 0;
- foreach ($where_clauses as $key => $value) {
- ++$param_nr;
- $where .= " AND $key = %$param_nr";
- // TODO: check whether tis works with datetime, null,...
- $query_params[$param_nr] = array($value, 'String');
+ foreach ($where_clauses as $clause) {
+ ++$i;
+ if (substr($clause[1], -4) == "NULL") {
+ $query->where("!columnName_$i !nullThing_$i", array(
+ "!columnName_$i" => $clause[0],
+ "!nullThing_$i" => $clause[1],
+ ));
+ }
+ else {
+ $query->where("!columnName_$i !operator_$i @value_$i", array(
+ "!columnName_$i" => $clause[0],
+ "!operator_$i" => $clause[1],
+ "@value_$i" => $clause[2],
+ ));
+ }
};
- // TODO: limit, sort
+ // order by
+ if (!empty($options['sort'])) {
+ $sort_fiels = array();
+ foreach (explode(',', $options['sort']) as $sort_option) {
+ $words = preg_split("/[\s]+/", $sort_option);
+ if (count($words) > 0 && in_array($words[0], array_values($select_fields))) {
+ $tmp = $words[0];
+ if (strtoupper($words[1]) == 'DESC') {
+ $tmp .= " DESC";
+ }
+ $sort_fields[] = $tmp;
+ }
+ }
+ if (count($sort_fields) > 0) {
+ $query->orderBy(implode(",", $sort_fields));
+ }
+ }
- $query = "$select $from $where";
+ // limit
+ if (!empty($options['limit']) || !empty($options['offset'])) {
+ $query->limit($options['limit'], $options['offset']);
+ }
$result_entities = array();
-
- $result_dao = CRM_Core_DAO::executeQuery($query, $query_params);
+ $result_dao = CRM_Core_DAO::executeQuery($query->toSQL());
while ($result_dao->fetch()) {
$result_entities[$result_dao->id] = array();
foreach ($select_fields as $column => $alias) {
}
};
}
+ $result_dao->free();
- return civicrm_api3_create_success($result_entities, $params, $entity, 'get', $dao);
+ if ($return_as_success) {
+ return civicrm_api3_create_success($result_entities, $params, $entity, 'get', $dao);
+ }
+ else {
+ return $result_entities;
+ }
}
/**
*/
function _civicrm_api3_field_names($fields) {
$result = array();
- foreach ($fields as $key=>$value) {
+ foreach ($fields as $key => $value) {
if (!empty($value['name'])) {
- $result[]=$value['name'];
+ $result[] = $value['name'];
}
}
return $result;
* an array that maps the custom field ID's to table name and
* column name. E.g.:
* {
- * '1' => array {
- * 'table_name' => 'table_name_1',
- * 'column_name' => ''column_name_1',
+ * '1' => array {
+ * 'table_name' => 'table_name_1',
+ * 'column_name' => ''column_name_1',
* },
* }
*/
AND g.extends = %1";
$params = array(
- '1' => array($entity, 'String')
+ '1' => array($entity, 'String'),
);
$dao = CRM_Core_DAO::executeQuery($query, $params);
* @return array
*/
function _civicrm_api3_basic_get($bao_name, &$params, $returnAsSuccess = TRUE, $entity = "") {
+ // if $params refers to a custom field, use a hack to
+ // avoid CRM-16036
+ foreach (array_keys($params) as $key) {
+ if (substr($key, 0, 7) == 'custom_') {
+ return _civicrm_api3_get_using_query_object_simple(
+ $bao_name, $params, $returnAsSuccess);
+ }
+ }
+
$bao = new $bao_name();
_civicrm_api3_dao_set_filter($bao, $params, TRUE);
if ($returnAsSuccess) {