From b0aa346355f4b4c1375e7485b0a9e4f053f95eec Mon Sep 17 00:00:00 2001 From: Coleman Watts Date: Thu, 29 Jul 2021 00:25:06 -0400 Subject: [PATCH] SearchKit - Use dataType from functions as well as fields --- CRM/Api4/Page/Api4Explorer.php | 1 + Civi/Api4/Query/SqlFunction.php | 29 +++++++++++++++++++ Civi/Api4/Query/SqlFunctionCOALESCE.php | 15 ++-------- Civi/Api4/Query/SqlFunctionCONCAT.php | 15 ++-------- Civi/Api4/Query/SqlFunctionCOUNT.php | 16 ++-------- Civi/Api4/Query/SqlFunctionDATE.php | 15 ++-------- Civi/Api4/Query/SqlFunctionGROUP_CONCAT.php | 6 ++-- Civi/Api4/Query/SqlFunctionIF.php | 15 ++-------- Civi/Api4/Query/SqlFunctionISNULL.php | 16 ++-------- Civi/Api4/Query/SqlFunctionTIME.php | 15 ++-------- Civi/Api4/Query/SqlFunctionYEAR.php | 15 ++-------- Civi/Api4/Utils/FormattingUtil.php | 5 +--- .../crmSearchAdmin.component.js | 5 +--- .../crmSearchAdminDisplay.component.js | 2 +- 14 files changed, 52 insertions(+), 118 deletions(-) diff --git a/CRM/Api4/Page/Api4Explorer.php b/CRM/Api4/Page/Api4Explorer.php index 0f1125f5ca..9cd4508fc5 100644 --- a/CRM/Api4/Page/Api4Explorer.php +++ b/CRM/Api4/Page/Api4Explorer.php @@ -61,6 +61,7 @@ class CRM_Api4_Page_Api4Explorer extends CRM_Core_Page { 'title' => $className::getTitle(), 'params' => $className::getParams(), 'category' => $className::getCategory(), + 'dataType' => $className::getDataType(), ]; } } diff --git a/Civi/Api4/Query/SqlFunction.php b/Civi/Api4/Query/SqlFunction.php index e62262d828..c7ee3ad713 100644 --- a/Civi/Api4/Query/SqlFunction.php +++ b/Civi/Api4/Query/SqlFunction.php @@ -30,6 +30,13 @@ abstract class SqlFunction extends SqlExpression { */ protected static $category; + /** + * Data type output by this function + * + * @var string + */ + protected static $dataType; + const CATEGORY_AGGREGATE = 'aggregate', CATEGORY_COMPARISON = 'comparison', CATEGORY_DATE = 'date', @@ -78,6 +85,21 @@ abstract class SqlFunction extends SqlExpression { } } + /** + * Change $dataType according to output of function + * + * @see \Civi\Api4\Utils\FormattingUtil::formatOutputValues + * @param string $value + * @param string $dataType + * @return string + */ + public function formatOutputValue($value, &$dataType) { + if (static::$dataType) { + $dataType = static::$dataType; + } + return $value; + } + /** * Shift a keyword off the beginning of the argument string and return it. * @@ -266,6 +288,13 @@ abstract class SqlFunction extends SqlExpression { return static::$category; } + /** + * @return string|NULL + */ + public static function getDataType():? string { + return static::$dataType; + } + /** * @return string */ diff --git a/Civi/Api4/Query/SqlFunctionCOALESCE.php b/Civi/Api4/Query/SqlFunctionCOALESCE.php index 16f9ec8e67..62622be45f 100644 --- a/Civi/Api4/Query/SqlFunctionCOALESCE.php +++ b/Civi/Api4/Query/SqlFunctionCOALESCE.php @@ -18,6 +18,8 @@ class SqlFunctionCOALESCE extends SqlFunction { protected static $category = self::CATEGORY_COMPARISON; + protected static $dataType = 'String'; + protected static function params(): array { return [ [ @@ -34,17 +36,4 @@ class SqlFunctionCOALESCE extends SqlFunction { return ts('Coalesce'); } - /** - * Prevent reformatting - * - * @see \Civi\Api4\Utils\FormattingUtil::formatOutputValues - * @param string $value - * @param string $dataType - * @return string|array - */ - public function formatOutputValue($value, &$dataType) { - $dataType = NULL; - return $value; - } - } diff --git a/Civi/Api4/Query/SqlFunctionCONCAT.php b/Civi/Api4/Query/SqlFunctionCONCAT.php index 6143277b66..a1c201fec2 100644 --- a/Civi/Api4/Query/SqlFunctionCONCAT.php +++ b/Civi/Api4/Query/SqlFunctionCONCAT.php @@ -18,6 +18,8 @@ class SqlFunctionCONCAT extends SqlFunction { protected static $category = self::CATEGORY_STRING; + protected static $dataType = 'String'; + protected static function params(): array { return [ [ @@ -35,17 +37,4 @@ class SqlFunctionCONCAT extends SqlFunction { return ts('Combine'); } - /** - * Prevent reformatting of result - * - * @see \Civi\Api4\Utils\FormattingUtil::formatOutputValues - * @param string $value - * @param string $dataType - * @return string|array - */ - public function formatOutputValue($value, &$dataType) { - $dataType = NULL; - return $value; - } - } diff --git a/Civi/Api4/Query/SqlFunctionCOUNT.php b/Civi/Api4/Query/SqlFunctionCOUNT.php index 10808e4322..c51e024856 100644 --- a/Civi/Api4/Query/SqlFunctionCOUNT.php +++ b/Civi/Api4/Query/SqlFunctionCOUNT.php @@ -18,6 +18,8 @@ class SqlFunctionCOUNT extends SqlFunction { protected static $category = self::CATEGORY_AGGREGATE; + protected static $dataType = 'Integer'; + protected static function params(): array { return [ [ @@ -29,20 +31,6 @@ class SqlFunctionCOUNT extends SqlFunction { ]; } - /** - * Reformat result as integer - * - * @see \Civi\Api4\Utils\FormattingUtil::formatOutputValues - * @param string $value - * @param string $dataType - * @return string|array - */ - public function formatOutputValue($value, &$dataType) { - // Count is always an integer - $dataType = 'Integer'; - return (int) $value; - } - /** * @return string */ diff --git a/Civi/Api4/Query/SqlFunctionDATE.php b/Civi/Api4/Query/SqlFunctionDATE.php index 5c198b94f2..05362a5103 100644 --- a/Civi/Api4/Query/SqlFunctionDATE.php +++ b/Civi/Api4/Query/SqlFunctionDATE.php @@ -18,6 +18,8 @@ class SqlFunctionDATE extends SqlFunction { protected static $category = self::CATEGORY_DATE; + protected static $dataType = 'Date'; + protected static function params(): array { return [ [ @@ -34,17 +36,4 @@ class SqlFunctionDATE extends SqlFunction { return ts('Date Only'); } - /** - * Ensure is processed as type Date - * - * @see \Civi\Api4\Utils\FormattingUtil::formatOutputValues - * @param string $value - * @param string $dataType - * @return string|array - */ - public function formatOutputValue($value, &$dataType) { - $dataType = 'Date'; - return $value; - } - } diff --git a/Civi/Api4/Query/SqlFunctionGROUP_CONCAT.php b/Civi/Api4/Query/SqlFunctionGROUP_CONCAT.php index f79e54a965..939c2c7553 100644 --- a/Civi/Api4/Query/SqlFunctionGROUP_CONCAT.php +++ b/Civi/Api4/Query/SqlFunctionGROUP_CONCAT.php @@ -62,13 +62,13 @@ class SqlFunctionGROUP_CONCAT extends SqlFunction { if (isset($exprArgs[2]['expr'][0]->expr) && $exprArgs[2]['expr'][0]->expr === \CRM_Core_DAO::VALUE_SEPARATOR) { $value = explode(\CRM_Core_DAO::VALUE_SEPARATOR, $value); // If the first expression is another sqlFunction, allow it to control the dataType - if ($exprArgs[0]['expr'][0] instanceof SqlFunction && is_callable([$exprArgs[0]['expr'][0], 'formatOutputValue'])) { + if ($exprArgs[0]['expr'][0] instanceof SqlFunction) { $exprArgs[0]['expr'][0]->formatOutputValue(NULL, $dataType); } } - // If using custom separator, unset $dataType to preserve raw string + // If using custom separator, preserve raw string else { - $dataType = NULL; + $dataType = 'String'; } return $value; } diff --git a/Civi/Api4/Query/SqlFunctionIF.php b/Civi/Api4/Query/SqlFunctionIF.php index 3e024a9217..1b120d4fed 100644 --- a/Civi/Api4/Query/SqlFunctionIF.php +++ b/Civi/Api4/Query/SqlFunctionIF.php @@ -18,6 +18,8 @@ class SqlFunctionIF extends SqlFunction { protected static $category = self::CATEGORY_COMPARISON; + protected static $dataType = 'String'; + protected static function params(): array { return [ [ @@ -35,17 +37,4 @@ class SqlFunctionIF extends SqlFunction { return ts('If'); } - /** - * Prevent formatting based on first field - * - * @see \Civi\Api4\Utils\FormattingUtil::formatOutputValues - * @param string $value - * @param string $dataType - * @return string|array - */ - public function formatOutputValue($value, &$dataType) { - $dataType = NULL; - return $value; - } - } diff --git a/Civi/Api4/Query/SqlFunctionISNULL.php b/Civi/Api4/Query/SqlFunctionISNULL.php index cfec8d82d8..beeaebc77d 100644 --- a/Civi/Api4/Query/SqlFunctionISNULL.php +++ b/Civi/Api4/Query/SqlFunctionISNULL.php @@ -18,6 +18,8 @@ class SqlFunctionISNULL extends SqlFunction { protected static $category = self::CATEGORY_COMPARISON; + protected static $dataType = 'Boolean'; + protected static function params(): array { return [ [ @@ -33,18 +35,4 @@ class SqlFunctionISNULL extends SqlFunction { return ts('Is null'); } - /** - * Reformat result as boolean - * - * @see \Civi\Api4\Utils\FormattingUtil::formatOutputValues - * @param string $value - * @param string $dataType - * @return string|array - */ - public function formatOutputValue($value, &$dataType) { - // Value is always TRUE or FALSE - $dataType = 'Boolean'; - return $value; - } - } diff --git a/Civi/Api4/Query/SqlFunctionTIME.php b/Civi/Api4/Query/SqlFunctionTIME.php index 56641345af..e55b48b867 100644 --- a/Civi/Api4/Query/SqlFunctionTIME.php +++ b/Civi/Api4/Query/SqlFunctionTIME.php @@ -18,6 +18,8 @@ class SqlFunctionTIME extends SqlFunction { protected static $category = self::CATEGORY_DATE; + protected static $dataType = 'Time'; + protected static function params(): array { return [ [ @@ -34,17 +36,4 @@ class SqlFunctionTIME extends SqlFunction { return ts('Time Only'); } - /** - * Prevent reformatting - * - * @see \Civi\Api4\Utils\FormattingUtil::formatOutputValues - * @param string $value - * @param string $dataType - * @return string|array - */ - public function formatOutputValue($value, &$dataType) { - $dataType = NULL; - return $value; - } - } diff --git a/Civi/Api4/Query/SqlFunctionYEAR.php b/Civi/Api4/Query/SqlFunctionYEAR.php index 6632e6016a..81b0ae52a5 100644 --- a/Civi/Api4/Query/SqlFunctionYEAR.php +++ b/Civi/Api4/Query/SqlFunctionYEAR.php @@ -18,6 +18,8 @@ class SqlFunctionYEAR extends SqlFunction { protected static $category = self::CATEGORY_DATE; + protected static $dataType = 'Integer'; + protected static function params(): array { return [ [ @@ -34,17 +36,4 @@ class SqlFunctionYEAR extends SqlFunction { return ts('Year Only'); } - /** - * Prevent reformatting - * - * @see \Civi\Api4\Utils\FormattingUtil::formatOutputValues - * @param string $value - * @param string $dataType - * @return string|array - */ - public function formatOutputValue($value, &$dataType) { - $dataType = NULL; - return $value; - } - } diff --git a/Civi/Api4/Utils/FormattingUtil.php b/Civi/Api4/Utils/FormattingUtil.php index 065ab8ea9d..8bcc5de9c3 100644 --- a/Civi/Api4/Utils/FormattingUtil.php +++ b/Civi/Api4/Utils/FormattingUtil.php @@ -200,13 +200,10 @@ class FormattingUtil { $fieldName = \CRM_Utils_Array::first($fieldExpr->getFields()); $field = $fieldName && isset($fields[$fieldName]) ? $fields[$fieldName] : NULL; $dataType = $field['data_type'] ?? ($fieldName == 'id' ? 'Integer' : NULL); - // If Sql Function e.g. GROUP_CONCAT or COUNT wants to do its own formatting, apply + // Allow Sql Functions to do special formatting and/or alter the $dataType if (method_exists($fieldExpr, 'formatOutputValue') && is_string($value)) { $result[$key] = $value = $fieldExpr->formatOutputValue($value, $dataType); } - if (!$field) { - continue; - } if (!empty($field['output_formatters'])) { self::applyFormatters($result, $fieldName, $field, $value); $dataType = NULL; diff --git a/ext/search_kit/ang/crmSearchAdmin/crmSearchAdmin.component.js b/ext/search_kit/ang/crmSearchAdmin/crmSearchAdmin.component.js index 2472af053b..532726c2a2 100644 --- a/ext/search_kit/ang/crmSearchAdmin/crmSearchAdmin.component.js +++ b/ext/search_kit/ang/crmSearchAdmin/crmSearchAdmin.component.js @@ -660,9 +660,6 @@ $scope.formatResult = function(row, col) { var info = searchMeta.parseExpr(col), value = row[info.alias]; - if (info.fn && info.fn.name === 'COUNT') { - return value; - } return formatFieldValue(row, info, value); }; @@ -697,7 +694,7 @@ } function formatFieldValue(row, info, value, index) { - var type = info.field.data_type, + var type = (info.fn && info.fn.dataType) || info.field.data_type, result = value, link; if (_.isArray(value)) { diff --git a/ext/search_kit/ang/crmSearchAdmin/crmSearchAdminDisplay.component.js b/ext/search_kit/ang/crmSearchAdmin/crmSearchAdminDisplay.component.js index c53851836c..f151226aa3 100644 --- a/ext/search_kit/ang/crmSearchAdmin/crmSearchAdminDisplay.component.js +++ b/ext/search_kit/ang/crmSearchAdmin/crmSearchAdminDisplay.component.js @@ -184,7 +184,7 @@ values.label = searchMeta.getDefaultLabel(fieldExpr); } if (defaults.dataType) { - values.dataType = (info.fn && info.fn.name === 'COUNT') ? 'Integer' : info.field && info.field.data_type; + values.dataType = (info.fn && info.fn.dataType) || (info.field && info.field.data_type); } return values; } -- 2.25.1