X-Git-Url: https://vcs.fsf.org/?a=blobdiff_plain;f=CRM%2FCore%2FDAO.php;h=9dea4c8676c42c669c29ef1ff6012a5e55c7a365;hb=9ab99c19a4663b23a3175405e07b27b6eadafcd8;hp=3420ca100ae70e0247e0779504eeefda32be8fa0;hpb=ce4fd42f89389d27c1ddd061b5ad2e92809ebe9a;p=civicrm-core.git diff --git a/CRM/Core/DAO.php b/CRM/Core/DAO.php index 3420ca100a..9dea4c8676 100644 --- a/CRM/Core/DAO.php +++ b/CRM/Core/DAO.php @@ -70,6 +70,8 @@ class CRM_Core_DAO extends DB_DataObject { */ static $_factory = NULL; + static $_checkedSqlFunctionsExist = FALSE; + /** * Class constructor * @@ -194,6 +196,7 @@ class CRM_Core_DAO extends DB_DataObject { */ function initialize() { $this->_connect(); + $this->query("SET NAMES utf8"); } /** @@ -598,7 +601,7 @@ LIKE %1 * * @return boolean true if CONSTRAINT keyword exists, false otherwise */ - function schemaRequiresRebuilding($tables = array("civicrm_contact")) { + static function schemaRequiresRebuilding($tables = array("civicrm_contact")) { $show = array(); foreach($tables as $tableName){ if (!array_key_exists($tableName, $show)) { @@ -1262,6 +1265,11 @@ SELECT contact_id $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', @@ -1293,6 +1301,10 @@ SELECT contact_id //skip the FK if it is not required // if it's contact id we should create even if not required // we'll have a go @ fetching first though + // we WILL create campaigns though for so tests with a campaign pseudoconstant will complete + if($FKClassName === 'CRM_Campaign_DAO_Campaign' && $daoName != $FKClassName) { + $required = TRUE; + } if (!$required && $dbName != 'contact_id') { $fkDAO = new $FKClassName; if($fkDAO->find(TRUE)){ @@ -1346,7 +1358,12 @@ SELECT contact_id case CRM_Utils_Type::T_DATE: case CRM_Utils_Type::T_TIMESTAMP: + case CRM_Utils_Type::T_DATE + CRM_Utils_Type::T_TIME: $object->$dbName = '19700101'; + if($dbName == 'end_date') { + // put this in the future + $object->$dbName = '20200101'; + } break; case CRM_Utils_Type::T_TIME: @@ -1416,8 +1433,12 @@ SELECT contact_id 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)) @@ -1526,11 +1547,11 @@ SELECT contact_id * @param $tableName string the specific table requiring a rebuild; or NULL to rebuild all tables * @see CRM-9716 */ - static function triggerRebuild($tableName = NULL) { + static function triggerRebuild($tableName = NULL, $force = FALSE) { $info = array(); $logging = new CRM_Logging_Schema; - $logging->triggerInfo($info, $tableName); + $logging->triggerInfo($info, $tableName, $force); CRM_Core_I18n_Schema::triggerInfo($info, $tableName); CRM_Contact_BAO_Contact::triggerInfo($info, $tableName); @@ -1544,6 +1565,23 @@ SELECT contact_id self::createTriggers($info); } + /** + * Because sql functions are sometimes lost, esp during db migration, we check here to avoid numerous support requests + * @see http://issues.civicrm.org/jira/browse/CRM-13822 + * TODO: Alternative solutions might be + * * Stop using functions and find another way to strip numeric characters from phones + * * Give better error messages (currently a missing fn fatals with "unknown error") + */ + static function checkSqlFunctionsExist() { + if (!self::$_checkedSqlFunctionsExist) { + self::$_checkedSqlFunctionsExist = TRUE; + $dao = CRM_Core_DAO::executeQuery("SHOW function status WHERE db = database() AND name = 'civicrm_strip_non_numeric'"); + if (!$dao->fetch()) { + self::triggerRebuild(); + } + } + } + /** * Wrapper function to drop triggers * @@ -1650,7 +1688,8 @@ SELECT contact_id foreach ($events as $whenName => $parts) { $varString = implode("\n", $parts['variables']); $sqlString = implode("\n", $parts['sql']); - $triggerName = "{$tableName}_{$whenName}_{$eventName}"; + $validName = CRM_Core_DAO::shortenSQLName($tableName, 48, TRUE); + $triggerName = "{$validName}_{$whenName}_{$eventName}"; $triggerSQL = "CREATE TRIGGER $triggerName $whenName $eventName ON $tableName FOR EACH ROW BEGIN $varString $sqlString END"; CRM_Core_DAO::executeQuery("DROP TRIGGER IF EXISTS $triggerName"); @@ -1777,7 +1816,7 @@ EOS; public function getOptionLabels() { $fields = $this->fields(); if ($fields === NULL) { - throw new exception ('Cannot call getOptionLabels on CRM_Core_DAO'); + throw new Exception ('Cannot call getOptionLabels on CRM_Core_DAO'); } foreach ($fields as $field) { $name = CRM_Utils_Array::value('name', $field); @@ -1806,7 +1845,7 @@ EOS; ); // Validation: enforce uniformity of this param if ($context !== NULL && !isset($contexts[$context])) { - throw new exception("'$context' is not a valid context for buildOptions."); + throw new Exception("'$context' is not a valid context for buildOptions."); } return $contexts; } @@ -1856,7 +1895,7 @@ EOS; case 'BETWEEN': case 'NOT BETWEEN': if (empty($criteria[0]) || empty($criteria[1])) { - throw new exception("invalid criteria for $operator"); + throw new Exception("invalid criteria for $operator"); } if(!$returnSanitisedArray) { return (sprintf('%s ' . $operator . ' "%s" AND "%s"', $fieldName, CRM_Core_DAO::escapeString($criteria[0]), CRM_Core_DAO::escapeString($criteria[1]))); @@ -1870,7 +1909,7 @@ EOS; case 'IN': case 'NOT IN': if (empty($criteria)) { - throw new exception("invalid criteria for $operator"); + throw new Exception("invalid criteria for $operator"); } $escapedCriteria = array_map(array( 'CRM_Core_DAO', @@ -1895,4 +1934,37 @@ EOS; } } } + + /** + * SQL has a limit of 64 characters on various names: + * table name, trigger name, column name ... + * + * For custom groups and fields we generated names from user entered input + * which can be longer than this length, this function helps with creating + * strings that meet various criteria. + * + * @param string $string - the string to be shortened + * @param int $length - the max length of the string + */ + public static function shortenSQLName($string, $length = 60, $makeRandom = FALSE) { + // early return for strings that meet the requirements + if (strlen($string) <= $length) { + return $string; + } + + // easy return for calls that dont need a randomized uniq string + if (! $makeRandom) { + return substr($string, 0, $length); + } + + // the string is longer than the length and we need a uniq string + // for the same tablename we need the same uniq string everytime + // hence we use md5 on the string, which is not random + // we'll append 8 characters to the end of the tableName + $md5string = substr(md5($string), 0, 8); + return substr($string, 0, $length - 8) . "_{$md5string}"; + } + + function setApiFilter(&$params) {} + }