X-Git-Url: https://vcs.fsf.org/?a=blobdiff_plain;f=Civi%2FApi4%2FQuery%2FApi4SelectQuery.php;h=009095ebc91d3e150027b5c5e19a20041e98c75b;hb=5df3f1075c0834e807239bb6f0430982c210677d;hp=ea8cad5f3fe2e119dd7d102c9711dbf453388d9d;hpb=0cec9c220bbbc592a023ce5c31ad925a9f83a702;p=civicrm-core.git diff --git a/Civi/Api4/Query/Api4SelectQuery.php b/Civi/Api4/Query/Api4SelectQuery.php index ea8cad5f3f..009095ebc9 100644 --- a/Civi/Api4/Query/Api4SelectQuery.php +++ b/Civi/Api4/Query/Api4SelectQuery.php @@ -26,8 +26,8 @@ use Civi\Api4\Utils\SelectUtil; * Leaf operators are one of: * * * '=', '<=', '>=', '>', '<', 'LIKE', "<>", "!=", - * * "NOT LIKE", 'IN', 'NOT IN', 'BETWEEN', 'NOT BETWEEN', - * * 'IS NOT NULL', or 'IS NULL'. + * * 'NOT LIKE', 'IN', 'NOT IN', 'BETWEEN', 'NOT BETWEEN', + * * 'IS NOT NULL', or 'IS NULL', 'CONTAINS'. */ class Api4SelectQuery { @@ -187,10 +187,25 @@ class Api4SelectQuery { $select = array_merge(['id'], $select); } + // Expand the superstar 'custom.*' to select all fields in all custom groups + $customStar = array_search('custom.*', array_values($select), TRUE); + if ($customStar !== FALSE) { + $customGroups = civicrm_api4($this->getEntity(), 'getFields', [ + 'checkPermissions' => FALSE, + 'where' => [['custom_group', 'IS NOT NULL']], + ], ['custom_group' => 'custom_group']); + $customSelect = []; + foreach ($customGroups as $groupName) { + $customSelect[] = "$groupName.*"; + } + array_splice($select, $customStar, 1, $customSelect); + } + // Expand wildcards in joins (the api wrapper already expanded non-joined wildcards) $wildFields = array_filter($select, function($item) { return strpos($item, '*') !== FALSE && strpos($item, '.') !== FALSE && strpos($item, '(') === FALSE && strpos($item, ' ') === FALSE; }); + foreach ($wildFields as $item) { $pos = array_search($item, array_values($select)); $this->autoJoinFK($item); @@ -260,7 +275,7 @@ class Api4SelectQuery { $suffix = strstr($item, ':'); if ($suffix && $expr->getType() === 'SqlField') { $field = $this->getField($item); - $options = FormattingUtil::getPseudoconstantList($field['entity'], $field['name'], substr($suffix, 1)); + $options = FormattingUtil::getPseudoconstantList($field, substr($suffix, 1)); if ($options) { asort($options); $column = "FIELD($column,'" . implode("','", array_keys($options)) . "')"; @@ -347,7 +362,7 @@ class Api4SelectQuery { protected function composeClause(array $clause, string $type) { // Pad array for unary operators list($expr, $operator, $value) = array_pad($clause, 3, NULL); - if (!in_array($operator, \CRM_Core_DAO::acceptedSQLOperators(), TRUE)) { + if (!in_array($operator, CoreUtil::getOperators(), TRUE)) { throw new \API_Exception('Illegal operator'); } @@ -364,7 +379,8 @@ class Api4SelectQuery { $fieldAlias = $expr; // Attempt to format if this is a real field if (isset($this->apiFieldSpec[$expr])) { - FormattingUtil::formatInputValue($value, $expr, $this->apiFieldSpec[$expr]); + $field = $this->getField($expr); + FormattingUtil::formatInputValue($value, $expr, $field); } } // Expr references a non-field expression like a function; convert to alias @@ -377,7 +393,8 @@ class Api4SelectQuery { foreach ($this->selectAliases as $selectAlias => $selectExpr) { list($selectField) = explode(':', $selectAlias); if ($selectAlias === $selectExpr && $fieldName === $selectField && isset($this->apiFieldSpec[$fieldName])) { - FormattingUtil::formatInputValue($value, $expr, $this->apiFieldSpec[$fieldName]); + $field = $this->getField($fieldName); + FormattingUtil::formatInputValue($value, $expr, $field); $fieldAlias = $selectAlias; break; } @@ -400,7 +417,29 @@ class Api4SelectQuery { return sprintf('%s %s %s', $fieldAlias, $operator, $valExpr->render($this->apiFieldSpec)); } elseif ($fieldName) { - FormattingUtil::formatInputValue($value, $fieldName, $this->apiFieldSpec[$fieldName]); + $field = $this->getField($fieldName); + FormattingUtil::formatInputValue($value, $fieldName, $field); + } + } + + if ($operator === 'CONTAINS') { + switch ($field['serialize'] ?? NULL) { + case \CRM_Core_DAO::SERIALIZE_JSON: + $operator = 'LIKE'; + $value = '%"' . $value . '"%'; + // FIXME: Use this instead of the above hack once MIN_INSTALL_MYSQL_VER is bumped to 5.7. + // return sprintf('JSON_SEARCH(%s, "one", "%s") IS NOT NULL', $fieldAlias, \CRM_Core_DAO::escapeString($value)); + break; + + case \CRM_Core_DAO::SERIALIZE_SEPARATOR_BOOKEND: + $operator = 'LIKE'; + $value = '%' . \CRM_Core_DAO::VALUE_SEPARATOR . $value . \CRM_Core_DAO::VALUE_SEPARATOR . '%'; + break; + + default: + $operator = 'LIKE'; + $value = '%' . $value . '%'; + break; } }