X-Git-Url: https://vcs.fsf.org/?a=blobdiff_plain;f=CRM%2FContact%2FBAO%2FQuery.php;h=990cca71e3c89291931b43d559fe7b5027d5291a;hb=ba41614e99343a658d9eb585bac13185698ed798;hp=2882b429f41e1507c8b39c116c6c21363ab54417;hpb=86b65114fa5817d70c0e3d10ec9f7d6e50391c35;p=civicrm-core.git diff --git a/CRM/Contact/BAO/Query.php b/CRM/Contact/BAO/Query.php index 2882b429f4..990cca71e3 100644 --- a/CRM/Contact/BAO/Query.php +++ b/CRM/Contact/BAO/Query.php @@ -1770,6 +1770,8 @@ class CRM_Contact_BAO_Query { CRM_Activity_BAO_Query::whereClauseSingle($values, $this); return; + case 'age_low': + case 'age_high': case 'birth_date_low': case 'birth_date_high': case 'deceased_date_low': @@ -1777,6 +1779,10 @@ class CRM_Contact_BAO_Query { $this->demographics($values); return; + case 'age_asof_date': + // handled by demographics + return; + case 'log_date_low': case 'log_date_high': $this->modifiedDates($values); @@ -2918,6 +2924,9 @@ class CRM_Contact_BAO_Query { elseif (strpos($op, 'IN') !== FALSE) { $groups = array($op => $groups); } + elseif (is_array($groups) && count($groups)) { + $groups = array('IN' => $groups); + } // Find all the groups that are part of a saved search. $smartGroupClause = self::buildClause("id", $op, $groups, 'Int'); @@ -3853,7 +3862,12 @@ WHERE $smartGroupClause public function demographics(&$values) { list($name, $op, $value, $grouping, $wildcard) = $values; - if (($name == 'birth_date_low') || ($name == 'birth_date_high')) { + if (($name == 'age_low') || ($name == 'age_high')) { + $this->ageRangeQueryBuilder($values, + 'contact_a', 'age', 'birth_date', ts('Age') + ); + } + elseif (($name == 'birth_date_low') || ($name == 'birth_date_high')) { $this->dateQueryBuilder($values, 'contact_a', 'birth_date', 'birth_date', ts('Birth Date') @@ -5155,6 +5169,104 @@ SELECT COUNT( conts.total_amount ) as cancel_count, } } + + /** + * @param $values + * @param string $tableName + * @param string $fieldName + * @param string $dbFieldName + * @param $fieldTitle + * @param null $options + */ + public function ageRangeQueryBuilder( + &$values, + $tableName, $fieldName, + $dbFieldName, $fieldTitle, + $options = NULL + ) { + list($name, $op, $value, $grouping, $wildcard) = $values; + + $asofDateValues = $this->getWhereValues("{$fieldName}_asof_date", $grouping); + $asofDate = NULL; // will be treated as current day + if ($asofDateValues) { + $asofDate = CRM_Utils_Date::processDate($asofDateValues[2]); + $asofDateFormat = CRM_Utils_Date::customFormat(substr($asofDate, 0, 8)); + $fieldTitle .= ' ' . ts('as of') . ' ' . $asofDateFormat; + } + + if ($name == "{$fieldName}_low" || + $name == "{$fieldName}_high" + ) { + if (isset($this->_rangeCache[$fieldName])) { + return; + } + $this->_rangeCache[$fieldName] = 1; + + $secondOP = $secondPhrase = $secondValue = NULL; + + if ($name == "{$fieldName}_low") { + $firstPhrase = ts('greater than or equal to'); + // NB: age > X means date of birth < Y + $firstOP = '<='; + $firstDate = self::calcDateFromAge($asofDate, $value, 'min'); + + $secondValues = $this->getWhereValues("{$fieldName}_high", $grouping); + if (!empty($secondValues)) { + $secondOP = '>='; + $secondPhrase = ts('less than or equal to'); + $secondValue = $secondValues[2]; + $secondDate = self::calcDateFromAge($asofDate, $secondValue, 'max'); + } + } + else { + $firstOP = '>='; + $firstPhrase = ts('less than or equal to'); + $firstDate = self::calcDateFromAge($asofDate, $value, 'max'); + + $secondValues = $this->getWhereValues("{$fieldName}_low", $grouping); + if (!empty($secondValues)) { + $secondOP = '<='; + $secondPhrase = ts('greater than or equal to'); + $secondValue = $secondValues[2]; + $secondDate = self::calcDateFromAge($asofDate, $secondValue, 'min'); + } + } + + if ($secondOP) { + $this->_where[$grouping][] = " +( {$tableName}.{$dbFieldName} $firstOP '$firstDate' ) AND +( {$tableName}.{$dbFieldName} $secondOP '$secondDate' ) +"; + $displayValue = $options ? $options[$value] : $value; + $secondDisplayValue = $options ? $options[$secondValue] : $secondValue; + + $this->_qill[$grouping][] + = "$fieldTitle - $firstPhrase \"$displayValue\" " . ts('AND') . " $secondPhrase \"$secondDisplayValue\""; + } + else { + $this->_where[$grouping][] = "{$tableName}.{$dbFieldName} $firstOP '$firstDate'"; + $displayValue = $options ? $options[$value] : $value; + $this->_qill[$grouping][] = "$fieldTitle - $firstPhrase \"$displayValue\""; + } + $this->_tables[$tableName] = $this->_whereTables[$tableName] = 1; + return; + } + } + + public static function calcDateFromAge($asofDate, $age, $type) { + $date = new DateTime($asofDate); + if ($type == "min") { + // minimum age is $age: dob <= date - age "235959" + $date->sub(new DateInterval("P" . $age . "Y")); + return $date->format('Ymd') . "235959"; + } + else { + // max age is $age: dob >= date - (age + 1y) + 1d "000000" + $date->sub(new DateInterval("P" . ($age + 1) . "Y"))->add(new DateInterval("P1D")); + return $date->format('Ymd') . "000000"; + } + } + /** * Given the field name, operator, value & its data type * builds the where Clause for the query @@ -5189,6 +5301,12 @@ SELECT COUNT( conts.total_amount ) as cancel_count, $clause = " (NULLIF($field, '') IS NOT NULL) "; return $clause; + case 'IN': + case 'NOT IN': + if (!empty($value) && is_array($value) && !array_key_exists($op, $value)) { + $value = array($op => $value); + } + default: if (empty($dataType)) { $dataType = 'String'; @@ -5212,7 +5330,14 @@ SELECT COUNT( conts.total_amount ) as cancel_count, return $queryString; } } + else { + $dragonPlace = $iAmAnIntentionalENoticeThatWarnsOfAProblemYouShouldReportUsingOldFormat; + if (($queryString = CRM_Core_DAO::createSqlFilter($field, array($op => array_keys($value)), $dataType)) != FALSE) { + return $queryString; + } + } } + $value = CRM_Utils_Type::escape($value, $dataType); // if we don't have a dataType we should assume if ($dataType == 'String' || $dataType == 'Text') {