<?php
/*
+--------------------------------------------------------------------+
- | CiviCRM version 4.4 |
+ | CiviCRM version 4.5 |
+--------------------------------------------------------------------+
- | Copyright CiviCRM LLC (c) 2004-2013 |
+ | Copyright CiviCRM LLC (c) 2004-2014 |
+--------------------------------------------------------------------+
| This file is a part of CiviCRM. |
| |
* Our base DAO class. All DAO classes should inherit from this class.
*
* @package CRM
- * @copyright CiviCRM LLC (c) 2004-2013
+ * @copyright CiviCRM LLC (c) 2004-2014
* $Id$
*
*/
*/
function initialize() {
$this->_connect();
+ $this->query("SET NAMES utf8");
}
/**
if ($fields) {
foreach ($fields as $name => $value) {
$table[$value['name']] = $value['type'];
- if (CRM_Utils_Array::value('required', $value)) {
+ if (!empty($value['required'])) {
$table[$value['name']] += self::DB_DAO_NOTNULL;
}
}
}
if ($trapException) {
- CRM_Core_Error::ignoreException();
+ $errorScope = CRM_Core_TemporaryErrorScope::ignoreException();
}
$result = $dao->query($queryStr, $i18nRewrite);
- if ($trapException) {
- CRM_Core_Error::setCallback();
- }
-
if (is_a($result, 'DB_Error')) {
return $result;
}
* execute a query and get the single result
*
* @param string $query query to be executed
+ * @param array $params
+ * @param bool $abort
+ * @param bool $i18nRewrite
+ * @return string|null the result of the query if any
*
- * @return string the result of the query
* @static
* @access public
*/
$fieldsToSuffix = array();
$fieldsToReplace = array();
}
- if (CRM_Utils_Array::value('prefix', $fieldsFix)) {
+ if (!empty($fieldsFix['prefix'])) {
$fieldsToPrefix = $fieldsFix['prefix'];
}
- if (CRM_Utils_Array::value('suffix', $fieldsFix)) {
+ if (!empty($fieldsFix['suffix'])) {
$fieldsToSuffix = $fieldsFix['suffix'];
}
- if (CRM_Utils_Array::value('replace', $fieldsFix)) {
+ if (!empty($fieldsFix['replace'])) {
$fieldsToReplace = $fieldsFix['replace'];
}
return self::escapeString($string);
}
- //Creates a test object, including any required objects it needs via recursion
- //createOnly: only create in database, do not store or return the objects (useful for perf testing)
- //ONLY USE FOR TESTING
+ /**
+ * Creates a test object, including any required objects it needs via recursion
+ *createOnly: only create in database, do not store or return the objects (useful for perf testing)
+ *ONLY USE FOR TESTING
+ */
static function createTestObject(
$daoName,
$params = array(),
$numObjects = 1,
$createOnly = FALSE
) {
+ //this is a test function also backtrace is set for the test suite it sometimes unsets itself
+ // so we re-set here in case
+ $config = CRM_Core_Config::singleton();
+ $config->backtrace = TRUE;
+
static $counter = 0;
CRM_Core_DAO::$_testEntitiesToSkip = array(
'CRM_Core_DAO_Worldregion',
case CRM_Utils_Type::T_INT:
case CRM_Utils_Type::T_FLOAT:
case CRM_Utils_Type::T_MONEY:
- $object->$dbName = $counter;
+ if (isset($value['precision'])) {
+ // $object->$dbName = CRM_Utils_Number::createRandomDecimal($value['precision']);
+ $object->$dbName = CRM_Utils_Number::createTruncatedDecimal($counter, $value['precision']);
+ } else {
+ $object->$dbName = $counter;
+ }
break;
case CRM_Utils_Type::T_BOOLEAN:
case CRM_Utils_Type::T_LONGTEXT:
case CRM_Utils_Type::T_EMAIL:
default:
- if (isset($value['enumValues'])) {
+ // WAS: if (isset($value['enumValues'])) {
+ // TODO: see if this works with all pseudoconstants
+ if (isset($value['pseudoconstant'], $value['pseudoconstant']['callback'])) {
if (isset($value['default'])) {
$object->$dbName = $value['default'];
}
else {
- if (is_array($value['enumValues'])) {
- $object->$dbName = $value['enumValues'][0];
+ $options = CRM_Core_PseudoConstant::get($daoName, $name);
+ if (is_array($options)) {
+ $object->$dbName = $options[0];
}
else {
- $defaultValues = explode(',', $value['enumValues']);
+ $defaultValues = explode(',', $options);
$object->$dbName = $defaultValues[0];
}
}
else return $objects;
}
- //deletes the this object plus any dependent objects that are associated with it
- //ONLY USE FOR TESTING
-
+ /**
+ * deletes the this object plus any dependent objects that are associated with it
+ * ONLY USE FOR TESTING
+ */
static function deleteTestObjects($daoName, $params = array(
)) {
+ //this is a test function also backtrace is set for the test suite it sometimes unsets itself
+ // so we re-set here in case
+ $config = CRM_Core_Config::singleton();
+ $config->backtrace = TRUE;
- $object = new $daoName ( );
+ $object = new $daoName();
$object->id = CRM_Utils_Array::value('id', $params);
$deletions = array(); // array(array(0 => $daoName, 1 => $daoParams))
// test for create view and trigger permissions and if allowed, add the option to go multilingual
// and logging
// I'm not sure why we use the getStaticProperty for an error, rather than checking for DB_Error
- CRM_Core_Error::ignoreException();
+ $errorScope = CRM_Core_TemporaryErrorScope::ignoreException();
$dao = new CRM_Core_DAO();
if ($view) {
$dao->query('CREATE OR REPLACE VIEW civicrm_domain_view AS SELECT * FROM civicrm_domain');
if (PEAR::getStaticProperty('DB_DataObject', 'lastError')) {
- CRM_Core_Error::setCallback();
return FALSE;
}
}
if ($trigger) {
$result = $dao->query('CREATE TRIGGER civicrm_domain_trigger BEFORE INSERT ON civicrm_domain FOR EACH ROW BEGIN END');
if (PEAR::getStaticProperty('DB_DataObject', 'lastError') || is_a($result, 'DB_Error')) {
- CRM_Core_Error::setCallback();
if ($view) {
$dao->query('DROP VIEW IF EXISTS civicrm_domain_view');
}
$dao->query('DROP TRIGGER IF EXISTS civicrm_domain_trigger');
if (PEAR::getStaticProperty('DB_DataObject', 'lastError')) {
- CRM_Core_Error::setCallback();
if ($view) {
$dao->query('DROP VIEW IF EXISTS civicrm_domain_view');
}
if ($view) {
$dao->query('DROP VIEW IF EXISTS civicrm_domain_view');
if (PEAR::getStaticProperty('DB_DataObject', 'lastError')) {
- CRM_Core_Error::setCallback();
return FALSE;
}
}
- CRM_Core_Error::setCallback();
return TRUE;
}
* The overriding function will generally call the lower-level CRM_Core_PseudoConstant::get
*
* @param string $fieldName
- * @param string $context: @see CRM_Core_DAO::buildOptionsContext
- * @param array $props: whatever is known about this bao object
+ * @param string $context : @see CRM_Core_DAO::buildOptionsContext
+ * @param array $props : whatever is known about this bao object
+ *
+ * @return Array|bool
*/
public static function buildOptions($fieldName, $context = NULL, $props = array()) {
// If a given bao does not override this function
return $contexts;
}
+ /**
+ * @param $fieldName
+ * @return bool|array
+ */
+ function getFieldSpec($fieldName) {
+ $fields = $this->fields();
+ $fieldKeys = $this->fieldKeys();
+
+ // Support "unique names" as well as sql names
+ $fieldKey = $fieldName;
+ if (empty($fields[$fieldKey])) {
+ $fieldKey = CRM_Utils_Array::value($fieldName, $fieldKeys);
+ }
+ // If neither worked then this field doesn't exist. Return false.
+ if (empty($fields[$fieldKey])) {
+ return FALSE;
+ }
+ return $fields[$fieldKey];
+ }
+
/**
* SQL version of api function to assign filters to the DAO based on the syntax
* $field => array('IN' => array(4,6,9))
* $field => array('LIKE' => array('%me%))
* etc
*
- * @param $fieldname string name of fields
+ * @param $fieldName
* @param $filter array filter to be applied indexed by operator
* @param $type String type of field (not actually used - nor in api @todo )
* @param $alias String alternative field name ('as') @todo- not actually used
* @param bool $returnSanitisedArray return a sanitised array instead of a clause
* this is primarily so we can add filters @ the api level to the Query object based fields
- * @todo a better solutution would be for the query object to apply these filters based on the
+ *
+ * @throws Exception
+ * @internal param string $fieldname name of fields
+ * @todo a better solutution would be for the query object to apply these filters based on the
* api supported format (but we don't want to risk breakage in alpha stage & query class is scary
- * @todo @time of writing only IN & NOT IN are supported for the array style syntax (as test is
+ * @todo @time of writing only IN & NOT IN are supported for the array style syntax (as test is
* required to extend further & it may be the comments per above should be implemented. It may be
* preferable to not double-banger the return context next refactor of this - but keeping the attention
* in one place has some advantages as we try to extend this format
*
- * @return NULL|string|array a string is returned if $returnSanitisedArray is not set, otherwise and Array or NULL
+ * @return NULL|string|array a string is returned if $returnSanitisedArray is not set, otherwise and Array or NULL
* depending on whether it is supported as yet
- **/
+ */
public static function createSQLFilter($fieldName, $filter, $type, $alias = NULL, $returnSanitisedArray = FALSE) {
// http://issues.civicrm.org/jira/browse/CRM-9150 - stick with 'simple' operators for now
// support for other syntaxes is discussed in ticket but being put off for now
- $acceptedSQLOperators = array('=', '<=', '>=', '>', '<', 'LIKE', "<>", "!=", "NOT LIKE", 'IN', 'NOT IN', 'BETWEEN', 'NOT BETWEEN');
foreach ($filter as $operator => $criteria) {
- if (in_array($operator, $acceptedSQLOperators)) {
+ if (in_array($operator, self::acceptedSQLOperators())) {
switch ($operator) {
// unary operators
case 'IS NULL':
}
}
+ /**
+ * @see http://issues.civicrm.org/jira/browse/CRM-9150
+ * support for other syntaxes is discussed in ticket but being put off for now
+ * @return array
+ */
+ public static function acceptedSQLOperators() {
+ return array('=', '<=', '>=', '>', '<', 'LIKE', "<>", "!=", "NOT LIKE", 'IN', 'NOT IN', 'BETWEEN', 'NOT BETWEEN');
+ }
+
/**
* SQL has a limit of 64 characters on various names:
* table name, trigger name, column name ...
* strings that meet various criteria.
*
* @param string $string - the string to be shortened
- * @param int $length - the max length of the string
+ * @param int $length - the max length of the string
+ *
+ * @param bool $makeRandom
+ *
+ * @return string
*/
public static function shortenSQLName($string, $length = 60, $makeRandom = FALSE) {
// early return for strings that meet the requirements