Merge pull request #972 from deepak-srivastava/hr
[civicrm-core.git] / api / v3 / utils.php
index 7a38ff89ef661da692a1ba3a84f4b4f3e3eb65a8..b80e317dede020d740ffe836d2f8f85f56ba59e7 100644 (file)
  * Initialize CiviCRM - should be run at the start of each API function
  */
 function _civicrm_api3_initialize() {
-  require_once 'CRM/Core/Config.php';
-  $config = CRM_Core_Config::singleton();
-  }
+  require_once 'CRM/Core/ClassLoader.php';
+  CRM_Core_ClassLoader::singleton()->register();
+  CRM_Core_Config::singleton();
+}
 
-/*
+/**
  * Wrapper Function for civicrm_verify_mandatory to make it simple to pass either / or fields for checking
  *
  * @param array $params array of fields to check
@@ -66,7 +67,7 @@ function civicrm_api3_verify_one_mandatory($params, $daoName = NULL, $keyoptions
   civicrm_api3_verify_mandatory($params, $daoName, $keys);
 }
 
-/*
+/**
  * Function to check mandatory fields are included
  *
  * @param array $params array of fields to check
@@ -134,8 +135,7 @@ function civicrm_api3_verify_mandatory($params, $daoName = NULL, $keys = array(
  *
  * @return <type>
  */
-function civicrm_api3_create_error($msg, $data = array(
-  ), &$dao = NULL) {
+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();
@@ -144,7 +144,7 @@ function civicrm_api3_create_error($msg, $data = array(
   if (is_array($dao)) {
     if ($msg == 'DB Error: constraint violation' || substr($msg, 0,9)  == 'DB Error:' || $msg == 'DB Error: already exists') {
       try {
-        _civicrm_api3_validate_fields($dao['entity'], $dao['action'], $dao['params'], True);
+        _civicrm_api3_validate_fields($dao['entity'], $dao['action'], $dao['params'], TRUE);
       }
       catch(Exception $e) {
         $msg = $e->getMessage();
@@ -183,18 +183,13 @@ function civicrm_api3_create_success($values = 1, $params = array(
       if (empty($item['id']) && !empty($item[$entity . "_id"])) {
         $values[$key]['id'] = $item[$entity . "_id"];
       }
+      if(!empty($item['financial_type_id'])){
+        $values[$key]['contribution_type_id'] = $item['financial_type_id'];
+      }
     }
   }
   //if ( array_key_exists ('debug',$params) && is_object ($dao)) {
   if (is_array($params) && array_key_exists('debug', $params)) {
-    if (!is_object($dao)) {
-      $d = _civicrm_api3_get_DAO(CRM_Utils_Array::value('entity', $params));
-      if (!empty($d)) {
-        $file = str_replace('_', '/', $d) . ".php";
-        require_once ($file);
-        $dao = new $d();
-      }
-    }
     if (is_string($action) && $action != 'getfields') {
       $apiFields = civicrm_api($entity, 'getfields', array('version' => 3, 'action' => $action) + $params);
     }
@@ -248,7 +243,8 @@ function civicrm_api3_create_success($values = 1, $params = array(
 
   return array_merge($result, $extraReturnValues);
 }
-/*
+
+/**
  * Load the DAO of the entity
  */
 function _civicrm_api3_load_DAO($entity) {
@@ -256,23 +252,17 @@ function _civicrm_api3_load_DAO($entity) {
   if (empty($dao)) {
     return FALSE;
   }
-  $file = str_replace('_', '/', $dao) . ".php";
-  require_once ($file);
   $d = new $dao();
   return $d;
 }
-/*
+
+/**
  * Function to return the DAO of the function or Entity
  * @param  $name is either a function of the api (civicrm_{entity}_create or the entity name
  * return the DAO name to manipulate this function
  * eg. "civicrm_api3_contact_create" or "Contact" will return "CRM_Contact_BAO_Contact"
  */
 function _civicrm_api3_get_DAO($name) {
-  static $dao = NULL;
-  if (!$dao) {
-    require ('CRM/Core/DAO/listAll.php');
-  }
-
   if (strpos($name, 'civicrm_api3') !== FALSE) {
     $last = strrpos($name, '_');
     // len ('civicrm_api3_') == 13
@@ -284,13 +274,13 @@ function _civicrm_api3_get_DAO($name) {
   }
 
   //hack to deal with incorrectly named BAO/DAO - see CRM-10859 - remove after rename
-  if($name == 'price_set'){
+  if($name == 'price_set' || $name == 'PriceSet'){
     return 'CRM_Price_DAO_Set';
   }
-  if($name == 'price_field'){
+  if($name == 'price_field' || $name == 'PriceField'){
     return 'CRM_Price_DAO_Field';
   }
-  if($name == 'price_field_value'){
+  if($name == 'price_field_value' || $name == 'PriceFieldValue'){
     return 'CRM_Price_DAO_FieldValue';
   }
   // these aren't listed on ticket CRM-10859 - but same problem - lack of standardisation
@@ -303,12 +293,10 @@ function _civicrm_api3_get_DAO($name) {
   if(strtolower($name) == 'im'){
     return 'CRM_Core_BAO_IM';
   }
-
-
-  return CRM_Utils_Array::value(_civicrm_api_get_camel_name($name, 3), $dao);
+  return CRM_Core_DAO_AllCoreTables::getFullName(_civicrm_api_get_camel_name($name, 3));
 }
 
-/*
+/**
  * Function to return the DAO of the function or Entity
  * @param  $name is either a function of the api (civicrm_{entity}_create or the entity name
  * return the DAO name to manipulate this function
@@ -340,7 +328,8 @@ function _civicrm_api3_separate_values(&$values) {
     }
   }
 }
-/*
+
+/**
  * This is a wrapper for api_store_values which will check the suitable fields using getfields
  * rather than DAO->fields
  *
@@ -388,7 +377,7 @@ function _civicrm_api3_store_values(&$fields, &$params, &$values) {
  * @param array $options array of options (so we can modify the filter)
  * @param bool $getCount are we just after the count
  */
-function _civicrm_api3_get_using_query_object($entity, $params, $additional_options = array(), $getCount = null){
+function _civicrm_api3_get_using_query_object($entity, $params, $additional_options = array(), $getCount = NULL){
 
   // Convert id to e.g. contact_id
   if (empty($params[$entity . '_id']) && isset($params['id'])) {
@@ -407,7 +396,7 @@ function _civicrm_api3_get_using_query_object($entity, $params, $additional_opti
     CRM_Utils_Array::value('return', $additional_options, array())
   );
   if(empty($returnProperties)){
-    $returnProperties = null;
+    $returnProperties = NULL;
   }
   if(!empty($params['check_permissions'])){
     // we will filter query object against getfields
@@ -456,7 +445,8 @@ function _civicrm_api3_get_using_query_object($entity, $params, $additional_opti
 
   return $entities;
 }
-/*
+
+/**
  * Function transfers the filters being passed into the DAO onto the params object
  */
 function _civicrm_api3_dao_set_filter(&$dao, $params, $unique = TRUE, $entity) {
@@ -469,6 +459,8 @@ function _civicrm_api3_dao_set_filter(&$dao, $params, $unique = TRUE, $entity) {
     //if entity_id is set then treat it as ID (will be overridden by id if set)
     $dao->id = $params[$entity . "_id"];
   }
+
+  $options = _civicrm_api3_get_options_from_params($params);
   //apply options like sort
   _civicrm_api3_apply_options_to_dao($params, $dao, $entity);
 
@@ -542,20 +534,25 @@ function _civicrm_api3_dao_set_filter(&$dao, $params, $unique = TRUE, $entity) {
     }
     else {
       if ($unique) {
-        $dao->$allfields[$field]['name'] = $params[$field];
+        $daoFieldName = $allfields[$field]['name'];
+        if (empty($daoFieldName)) {
+          throw new API_Exception("Failed to determine field name for \"$field\"");
+        }
+        $dao->{$daoFieldName} = $params[$field];
       }
       else {
         $dao->$field = $params[$field];
       }
     }
   }
-  if (!empty($params['return']) && is_array($params['return'])) {
+  if (!empty($options['return']) && is_array($options['return'])) {
     $dao->selectAdd();
+    $options['return']['id'] = TRUE;// ensure 'id' is included
     $allfields =  _civicrm_api3_get_unique_name_array($dao);
-    $returnMatched = array_intersect($params['return'], $allfields);
+    $returnMatched = array_intersect(array_keys($options['return']), $allfields);
     $returnUniqueMatched = array_intersect(
       array_diff(// not already matched on the field names
-        $params['return'],
+        $options['return'],
         $returnMatched),
         array_flip($allfields)// but a match for the field keys
     );
@@ -567,11 +564,10 @@ function _civicrm_api3_dao_set_filter(&$dao, $params, $unique = TRUE, $entity) {
       $dao->selectAdd($allfields[$uniqueVal]);
 
     }
-    $dao->selectAdd('id');
   }
 }
 
-/*
+/**
  * Apply filters (e.g. high, low) to DAO object (prior to find)
  * @param string $filterField field name of filter
  * @param string $filterValue field value of filter
@@ -595,8 +591,8 @@ function _civicrm_api3_apply_filters_to_dao($filterField, $filterValue, &$dao) {
     }
   }
 }
-/*
- *
+
+/**
  * Get sort, limit etc options from the params - supporting old & new formats.
  * get returnproperties for legacy
  * @param array $params params array as passed into civicrm_api
@@ -604,7 +600,7 @@ function _civicrm_api3_apply_filters_to_dao($filterField, $filterValue, &$dao) {
  * for legacy report & return a unique fields array
  * @return array $options options extracted from params
  */
-function _civicrm_api3_get_options_from_params(&$params, $queryObject = false, $entity = '', $action = '') {
+function _civicrm_api3_get_options_from_params(&$params, $queryObject = FALSE, $entity = '', $action = '') {
   $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);
@@ -681,22 +677,22 @@ function _civicrm_api3_get_options_from_params(&$params, $queryObject = false, $
   $options['input_params'] = $inputParams;
   return $options;
 }
-/*
+
+/**
  * Apply options (e.g. sort, limit, order by) to DAO object (prior to find)
  * @param array $params params array as passed into civicrm_api
  * @param object $dao DAO object
  */
 function _civicrm_api3_apply_options_to_dao(&$params, &$dao, $entity) {
 
-  $options = _civicrm_api3_get_options_from_params($params,false,$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']);
   }
 }
 
-
-/*
+/**
  * build fields array. This is the array of fields as it relates to the given DAO
  * returns unique fields as keys by default but if set but can return by DB fields
  */
@@ -717,7 +713,7 @@ function _civicrm_api3_build_fields_array(&$bao, $unique = TRUE) {
   return $dbFields;
 }
 
-/*
+/**
  * build fields array. This is the array of fields as it relates to the given DAO
  * returns unique fields as keys by default but if set but can return by DB fields
  */
@@ -729,7 +725,6 @@ function _civicrm_api3_get_unique_name_array(&$bao) {
   return $uniqueFields;
 }
 
-
 /**
  * Converts an DAO object to an array
  *
@@ -797,7 +792,7 @@ function _civicrm_api3_object_to_array(&$dao, &$values, $uniqueFields = FALSE) {
   }
 }
 
-/*
+/**
  * Wrapper for _civicrm_object_to_array when api supports unique fields
  */
 function _civicrm_api3_object_to_array_unique_fields(&$dao, &$values) {
@@ -902,8 +897,6 @@ function _civicrm_api3_api_check_permission($entity, $action, &$params, $throw =
     return TRUE;
   }
 
-  require_once 'CRM/Core/Permission.php';
-
   require_once 'CRM/Core/DAO/permissions.php';
   $permissions = _civicrm_api3_permissions($entity, $action, $params);
 
@@ -925,7 +918,7 @@ function _civicrm_api3_api_check_permission($entity, $action, &$params, $throw =
   return TRUE;
 }
 
-/*
+/**
  * Function to do a 'standard' api get - when the api is only doing a $bao->find then use this
  *
  * @param string $bao_name name of BAO
@@ -943,13 +936,13 @@ function _civicrm_api3_basic_get($bao_name, &$params, $returnAsSuccess = TRUE, $
   }
 }
 
-/*
+/**
  * Function to do a 'standard' api create - when the api is only doing a $bao::create then use this
  * @param string $bao_name Name of BAO Class
  * @param array $params parameters passed into the api call
  * @param string $entity Entity - pass in if entity is non-standard & required $ids array
  */
-function _civicrm_api3_basic_create($bao_name, &$params, $entity = null) {
+function _civicrm_api3_basic_create($bao_name, &$params, $entity = NULL) {
 
   $args = array(&$params);
   if(!empty($entity)){
@@ -972,11 +965,11 @@ function _civicrm_api3_basic_create($bao_name, &$params, $entity = null) {
   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, NULL, 'create', $bao);
   }
 }
 
-/*
+/**
  * Function to do a 'standard' api del - when the api is only doing a $bao::del then use this
  * if api::del doesn't exist it will try DAO delete method
  */
@@ -986,7 +979,10 @@ function _civicrm_api3_basic_delete($bao_name, &$params) {
   $args = array(&$params['id']);
   if (method_exists($bao_name, 'del')) {
     $bao = call_user_func_array(array($bao_name, 'del'), $args);
-    return civicrm_api3_create_success(TRUE);
+    if ($bao !== FALSE) {
+      return civicrm_api3_create_success(TRUE);
+    }
+    return civicrm_api3_create_error('Could not delete entity id ' . $params['id']);
   }
   elseif (method_exists($bao_name, 'delete')) {
     $dao = new $bao_name();
@@ -1005,7 +1001,7 @@ function _civicrm_api3_basic_delete($bao_name, &$params) {
   return civicrm_api3_create_error('no delete method found');
 }
 
-/*
+/**
  * Get custom data for the given entity & Add it to the returnArray as 'custom_123' = 'custom string' AND 'custom_123_1' = 'custom string'
  * Where 123 is field value & 1 is the id within the custom group data table (value ID)
  *
@@ -1017,8 +1013,6 @@ function _civicrm_api3_basic_delete($bao_name, &$params) {
  *
  */
 function _civicrm_api3_custom_data_get(&$returnArray, $entity, $entity_id, $groupID = NULL, $subType = NULL, $subName = NULL) {
-  require_once 'CRM/Core/BAO/CustomGroup.php';
-  require_once 'CRM/Core/BAO/CustomField.php';
   $groupTree = &CRM_Core_BAO_CustomGroup::getTree($entity,
     CRM_Core_DAO::$_nullObject,
     $entity_id,
@@ -1047,7 +1041,7 @@ function _civicrm_api3_custom_data_get(&$returnArray, $entity, $entity_id, $grou
   }
 }
 
-/*
+/**
  * Validate fields being passed into API. This function relies on the getFields function working accurately
  * for the given API. If error mode is set to TRUE then it will also check
  * foreign keys
@@ -1078,11 +1072,12 @@ function _civicrm_api3_validate_fields($entity, $action, &$params, $errorMode =
         //field is of type date or datetime
         _civicrm_api3_validate_date($params, $fieldname, $fieldInfo);
         break;
-    case 32://blob
+
+      case 32://blob
         _civicrm_api3_validate_html($params, $fieldname, $fieldInfo);
         break;
-      case CRM_Utils_Type::T_STRING:
 
+      case CRM_Utils_Type::T_STRING:
         _civicrm_api3_validate_string($params, $fieldname, $fieldInfo);
         break;
 
@@ -1110,7 +1105,7 @@ function _civicrm_api3_validate_fields($entity, $action, &$params, $errorMode =
   }
 }
 
-/*
+/**
  * Validate date fields being passed into API.
  * It currently converts both unique fields and DB field names to a mysql date.
  * @todo - probably the unique field handling & the if exists handling is now done before this
@@ -1141,7 +1136,8 @@ function _civicrm_api3_validate_date(&$params, &$fieldname, &$fieldInfo) {
     $params[$fieldname] = CRM_Utils_Date::processDate($params[$fieldname]);
   }
 }
-/*
+
+/**
  * Validate foreign constraint fields being passed into API.
  *
  * @param array $params params from civicrm_api
@@ -1149,8 +1145,6 @@ function _civicrm_api3_validate_date(&$params, &$fieldname, &$fieldInfo) {
  * @param array $fieldinfo array of fields from getfields function
  */
 function _civicrm_api3_validate_constraint(&$params, &$fieldname, &$fieldInfo) {
-  $file = str_replace('_', '/', $fieldInfo['FKClassName']) . ".php";
-  require_once ($file);
   $dao = new $fieldInfo['FKClassName'];
   $dao->id = $params[$fieldname];
   $dao->selectAdd();
@@ -1160,7 +1154,7 @@ function _civicrm_api3_validate_constraint(&$params, &$fieldname, &$fieldInfo) {
   }
 }
 
-/*
+/**
  * Validate foreign constraint fields being passed into API.
  *
  * @param array $params params from civicrm_api
@@ -1195,7 +1189,6 @@ function _civicrm_api3_validate_uniquekey(&$params, &$fieldname, &$fieldInfo) {
  */
 function _civicrm_api3_generic_replace($entity, $params) {
 
-  require_once 'CRM/Core/Transaction.php';
   $transaction = new CRM_Core_Transaction();
   try {
     if (!is_array($params['values'])) {
@@ -1258,7 +1251,7 @@ function _civicrm_api3_generic_replace($entity, $params) {
   }
 }
 
-/*
+/**
  * returns fields allowable by api
  * @param $entity string Entity to query
  * @param bool $unique index by unique fields?
@@ -1270,8 +1263,6 @@ function _civicrm_api_get_fields($entity, $unique = FALSE, &$params = array(
   if (empty($dao)) {
     return array();
   }
-  $file = str_replace('_', '/', $dao) . ".php";
-  require_once ($file);
   $d = new $dao();
   $fields = $d->fields();
   // replace uniqueNames by the normal names as the key
@@ -1300,12 +1291,11 @@ function _civicrm_api_get_fields($entity, $unique = FALSE, &$params = array(
   return $fields;
 }
 
-/*
+/**
  * 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) {
-  require_once 'CRM/Core/BAO/CustomField.php';
   $customfields = array();
   $entity = _civicrm_api_get_camel_name($entity);
   if (strtolower($entity) == 'contact') {
@@ -1340,7 +1330,8 @@ function _civicrm_api_get_custom_fields($entity, &$params) {
   }
   return $customfields;
 }
-/*
+
+/**
  * Return array of defaults for the given API (function is a wrapper on getfields)
  */
 function _civicrm_api3_getdefaults($apiRequest) {
@@ -1362,7 +1353,7 @@ function _civicrm_api3_getdefaults($apiRequest) {
   return $defaults;
 }
 
-/*
+/**
  * Return array of defaults for the given API (function is a wrapper on getfields)
  */
 function _civicrm_api3_getrequired($apiRequest) {
@@ -1383,7 +1374,7 @@ function _civicrm_api3_getrequired($apiRequest) {
   return $required;
 }
 
-/*
+/**
  * Fill params array with alternate (alias) values where a field has an alias and that is filled & the main field isn't
  * If multiple aliases the last takes precedence
  *
@@ -1440,7 +1431,8 @@ function _civicrm_api3_swap_out_aliases(&$apiRequest) {
   }
 
 }
-/*
+
+/**
  * Validate integer fields being passed into API.
  * It currently converts the incoming value 'user_contact_id' into the id of the currenty logged in user
  *
@@ -1456,7 +1448,7 @@ function _civicrm_api3_validate_integer(&$params, &$fieldname, &$fieldInfo, $ent
       $session = &CRM_Core_Session::singleton();
       $params[$fieldname] = $session->get('userID');
     }
-    if (CRM_Utils_Array::value('pseudoconstant', $fieldInfo) ) {
+    if (!empty($fieldInfo['options'])) {
       $constant = CRM_Utils_Array::value('options', $fieldInfo);
       if (is_numeric($params[$fieldname]) && !CRM_Utils_Array::value('FKClassName',$fieldInfo) && !array_key_exists($params[$fieldname], $fieldInfo['options'])) {
         throw new API_Exception("$fieldname is not valid", 2001, array('error_field' => $fieldname,"type"=>"integer"));
@@ -1502,7 +1494,7 @@ function _civicrm_api3_validate_html(&$params, &$fieldname, &$fieldInfo) {
   }
 }
 
-/*
+/**
  * Validate string fields being passed into API.
  * @param array $params params from civicrm_api
  * @param string $fieldname uniquename of field being checked
@@ -1510,7 +1502,15 @@ function _civicrm_api3_validate_html(&$params, &$fieldname, &$fieldInfo) {
  */
 function _civicrm_api3_validate_string(&$params, &$fieldname, &$fieldInfo) {
   // If fieldname exists in params
-  $value = (string) CRM_Utils_Array::value($fieldname, $params,'');
+  $value = CRM_Utils_Array::value($fieldname, $params, '');
+  if(!is_array($value)){
+    $value = (string) $value;
+  }
+  else{
+    //@todo what do we do about passed in arrays. For many of these fields
+    // the missing piece of functionality is separating them to a separated string
+    // & many save incorrectly. But can we change them wholesale?
+  }
   if ($value ) {
     if (!CRM_Utils_Rule::xssString($value)) {
       throw new Exception('Illegal characters in input (potential scripting attack)');
@@ -1526,7 +1526,7 @@ function _civicrm_api3_validate_string(&$params, &$fieldname, &$fieldInfo) {
       $lowerCaseOptions = array_map("strtolower", $options);
       // If value passed is not a key, it may be a label
       // Try to lookup key from label - if it can't be found throw error
-      if (!isset($options[strtolower($value)]) && !isset($options[$value]) ) {
+      if (!is_array($value) && !isset($options[strtolower($value)]) && !isset($options[$value]) ) {
         if (!in_array(strtolower($value), $lowerCaseOptions)) {
           throw new Exception("$fieldname `$value` is not valid.");
         }