/** * 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 * * As of writing only date was implemented. * * @param string $entity * @param string $action * @param array $params * -. * @param array $fields * Response from getfields all variables are the same as per civicrm_api. * @param bool $errorMode * ErrorMode do intensive post fail checks?. * * @throws Exception */ function _civicrm_api3_validate_fields($entity, $action, &$params, $fields, $errorMode = FALSE) { //CRM-15792 handle datetime for custom fields below code handles chain api call $chainApikeys = array_flip(preg_grep("/^api./", array_keys($params))); if (!empty($chainApikeys) && is_array($chainApikeys)) { foreach ($chainApikeys as $key => $value) { if (is_array($params[$key])) { $chainApiParams = array_intersect_key($fields, $params[$key]); $customFields = array_fill_keys(array_keys($params[$key]), $key); } } } $fields = array_intersect_key($fields, $params); if (!empty($chainApiParams)) { $fields = array_merge($fields, $chainApiParams); } foreach ($fields as $fieldName => $fieldInfo) { switch (CRM_Utils_Array::value('type', $fieldInfo)) { case CRM_Utils_Type::T_INT: //field is of type integer _civicrm_api3_validate_integer($params, $fieldName, $fieldInfo, $entity); break; case CRM_Utils_Type::T_DATE: case CRM_Utils_Type::T_DATE + CRM_Utils_Type::T_TIME: case CRM_Utils_Type::T_TIMESTAMP: //field is of type date or datetime if (!empty($customFields) && array_key_exists($fieldName, $customFields)) { $dateParams =& $params[$customFields[$fieldName]]; } else { $dateParams =& $params; } _civicrm_api3_validate_date($dateParams, $fieldName, $fieldInfo); break; case 32: //blob _civicrm_api3_validate_html($params, $fieldName, $fieldInfo); break; case CRM_Utils_Type::T_STRING: _civicrm_api3_validate_string($params, $fieldName, $fieldInfo, $entity); break; case CRM_Utils_Type::T_MONEY: list($fieldValue, $op) = _civicrm_api3_field_value_check($params, $fieldName); if (strpos($op, 'NULL') !== FALSE || strpos($op, 'EMPTY') !== FALSE) { break; } foreach ((array) $fieldValue as $fieldvalue) { if (!CRM_Utils_Rule::money($fieldvalue) && !empty($fieldvalue)) { throw new Exception($fieldName . " is not a valid amount: " . $params[$fieldName]); } } break; } // intensive checks - usually only called after DB level fail if (!empty($errorMode) && strtolower($action) == 'create') { if (!empty($fieldInfo['FKClassName'])) { if (!empty($fieldValue)) { _civicrm_api3_validate_constraint($params, $fieldName, $fieldInfo); } elseif (!empty($fieldInfo['required'])) { throw new Exception("DB Constraint Violation - possibly {$fieldName} should possibly be marked as mandatory for this API. If so, please raise a bug report"); } } if (!empty($fieldInfo['api.unique'])) { $params['entity'] = $entity; _civicrm_api3_validate_unique_key($params, $fieldName); } } } }
/** * 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 * * As of writing only date was implemented. * @param string $entity * @param string $action * @param array $params - * @param array $fields response from getfields all variables are the same as per civicrm_api * @param bool $errorMode errorMode do intensive post fail checks? * @throws Exception */ function _civicrm_api3_validate_fields($entity, $action, &$params, $fields, $errorMode = False) { $fields = array_intersect_key($fields, $params); foreach ($fields as $fieldName => $fieldInfo) { switch (CRM_Utils_Array::value('type', $fieldInfo)) { case CRM_Utils_Type::T_INT: //field is of type integer _civicrm_api3_validate_integer($params, $fieldName, $fieldInfo, $entity); break; case 4: case 12: case CRM_Utils_Type::T_TIMESTAMP: //field is of type date or datetime _civicrm_api3_validate_date($params, $fieldName, $fieldInfo); break; case 32: //blob _civicrm_api3_validate_html($params, $fieldName, $fieldInfo); break; case CRM_Utils_Type::T_STRING: _civicrm_api3_validate_string($params, $fieldName, $fieldInfo, $entity); break; case CRM_Utils_Type::T_MONEY: if (!CRM_Utils_Rule::money($params[$fieldName]) && !empty($params[$fieldName])) { throw new Exception($fieldName . " is not a valid amount: " . $params[$fieldName]); } } // intensive checks - usually only called after DB level fail if (!empty($errorMode) && strtolower($action) == 'create') { if (!empty($fieldInfo['FKClassName'])) { if (!empty($params[$fieldName])) { _civicrm_api3_validate_constraint($params, $fieldName, $fieldInfo); } elseif (!empty($fieldInfo['required'])) { throw new Exception("DB Constraint Violation - possibly {$fieldName} should possibly be marked as mandatory for this API. If so, please raise a bug report"); } } if (!empty($fieldInfo['api.unique'])) { $params['entity'] = $entity; _civicrm_api3_validate_uniquekey($params, $fieldName, $fieldInfo); } } } }
function _civicrm_api3_validate_fields($entity, $action, &$params, $errorMode = NULL) { //skip any entities without working getfields functions $skippedEntities = array('entity', 'mailinggroup', 'customvalue', 'custom_value', 'mailing_group'); if (in_array(strtolower($entity), $skippedEntities) || strtolower($action) == 'getfields') { return; } $fields = civicrm_api($entity, 'getfields', array('version' => 3, 'action' => $action)); $fields = array_intersect_key($fields['values'], $params); foreach ($fields as $fieldname => $fieldInfo) { switch (CRM_Utils_Array::value('type', $fieldInfo)) { case CRM_Utils_Type::T_INT: //field is of type integer _civicrm_api3_validate_integer($params, $fieldname, $fieldInfo); break; case 4: case 12: //field is of type date or datetime _civicrm_api3_validate_date($params, $fieldname, $fieldInfo); break; case 32: //blob _civicrm_api3_validate_html($params, $fieldname, $fieldInfo); break; case CRM_Utils_Type::T_STRING: _civicrm_api3_validate_string($params, $fieldname, $fieldInfo); break; case CRM_Utils_Type::T_MONEY: if (!CRM_Utils_Rule::money($params[$fieldname])) { throw new Exception($fieldname . " is not a valid amount: " . $params[$fieldname]); } } // intensive checks - usually only called after DB level fail if (!empty($errorMode) && strtolower($action) == 'create') { if (CRM_Utils_Array::value('FKClassName', $fieldInfo)) { if (CRM_Utils_Array::value($fieldname, $params)) { _civicrm_api3_validate_constraint($params, $fieldname, $fieldInfo); } elseif (CRM_Utils_Array::value('required', $fieldInfo)) { throw new Exception("DB Constraint Violation - possibly {$fieldname} should possibly be marked as mandatory for this API. If so, please raise a bug report"); } } if (CRM_Utils_Array::value('api.unique', $fieldInfo)) { $params['entity'] = $entity; _civicrm_api3_validate_uniquekey($params, $fieldname, $fieldInfo); } } } }
/** * Validate foreign key values of fields being passed into API. * * This function relies on the getFields function working accurately * for the given API. * * @param string $entity * @param string $action * @param array $params * * @param array $fields * Response from getfields all variables are the same as per civicrm_api. * * @throws Exception */ function _civicrm_api3_validate_foreign_keys($entity, $action, &$params, $fields) { // intensive checks - usually only called after DB level fail foreach ($fields as $fieldName => $fieldInfo) { if (!empty($fieldInfo['FKClassName'])) { if (!empty($params[$fieldName])) { _civicrm_api3_validate_constraint($params[$fieldName], $fieldName, $fieldInfo); } elseif (!empty($fieldInfo['required'])) { throw new Exception("DB Constraint Violation - possibly {$fieldName} should possibly be marked as mandatory for this API. If so, please raise a bug report."); } } if (!empty($fieldInfo['api.unique'])) { $params['entity'] = $entity; _civicrm_api3_validate_unique_key($params, $fieldName); } } }