--- /dev/null
+<?php
+/*
+ +--------------------------------------------------------------------+
+ | Copyright CiviCRM LLC. All rights reserved. |
+ | |
+ | This work is published under the GNU AGPLv3 license with some |
+ | permitted exceptions and without any warranty. For full license |
+ | and copyright information, see https://civicrm.org/licensing |
+ +--------------------------------------------------------------------+
+ */
+
+namespace Civi\Api4\Query;
+
+/**
+ * Sql function
+ */
+class SqlFunctionDATE extends SqlFunction {
+
+ protected static $category = self::CATEGORY_DATE;
+
+ protected static function params(): array {
+ return [
+ [
+ 'max_expr' => 1,
+ 'optional' => FALSE,
+ ],
+ ];
+ }
+
+ /**
+ * @return string
+ */
+ public static function getTitle(): string {
+ 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;
+ }
+
+}
--- /dev/null
+<?php
+/*
+ +--------------------------------------------------------------------+
+ | Copyright CiviCRM LLC. All rights reserved. |
+ | |
+ | This work is published under the GNU AGPLv3 license with some |
+ | permitted exceptions and without any warranty. For full license |
+ | and copyright information, see https://civicrm.org/licensing |
+ +--------------------------------------------------------------------+
+ */
+
+namespace Civi\Api4\Query;
+
+/**
+ * Sql function
+ */
+class SqlFunctionTIME extends SqlFunction {
+
+ protected static $category = self::CATEGORY_DATE;
+
+ protected static function params(): array {
+ return [
+ [
+ 'max_expr' => 1,
+ 'optional' => FALSE,
+ ],
+ ];
+ }
+
+ /**
+ * @return string
+ */
+ public static function getTitle(): string {
+ 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;
+ }
+
+}
--- /dev/null
+<?php
+/*
+ +--------------------------------------------------------------------+
+ | Copyright CiviCRM LLC. All rights reserved. |
+ | |
+ | This work is published under the GNU AGPLv3 license with some |
+ | permitted exceptions and without any warranty. For full license |
+ | and copyright information, see https://civicrm.org/licensing |
+ +--------------------------------------------------------------------+
+ */
+
+namespace Civi\Api4\Query;
+
+/**
+ * Sql function
+ */
+class SqlFunctionYEAR extends SqlFunction {
+
+ protected static $category = self::CATEGORY_DATE;
+
+ protected static function params(): array {
+ return [
+ [
+ 'max_expr' => 1,
+ 'optional' => FALSE,
+ ],
+ ];
+ }
+
+ /**
+ * @return string
+ */
+ public static function getTitle(): string {
+ 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;
+ }
+
+}
$scope.$watch('$ctrl.expr', function(expr) {
var fieldInfo = searchMeta.parseExpr(expr);
ctrl.path = fieldInfo.path + fieldInfo.suffix;
- ctrl.field = fieldInfo.field;
+ ctrl.field = [fieldInfo.field];
ctrl.fn = !fieldInfo.fn ? '' : fieldInfo.fn.name;
ctrl.modifier = fieldInfo.modifier || null;
initFunction();
}
}
+ // On-demand options for dropdown function selector
this.getFunctions = function() {
var allowedTypes = [], functions = [];
if (ctrl.expr && ctrl.field) {
allowedTypes.push('aggregate');
} else {
allowedTypes.push('comparison', 'string');
- if (_.includes(['Integer', 'Float', 'Date', 'Timestamp'], ctrl.field.data_type)) {
+ if (_.includes(['Integer', 'Float', 'Date', 'Timestamp'], ctrl.field[0].data_type)) {
allowedTypes.push('math');
}
- if (_.includes(['Date', 'Timestamp'], ctrl.field.data_type)) {
+ if (_.includes(['Date', 'Timestamp'], ctrl.field[0].data_type)) {
allowedTypes.push('date');
}
}
- _.each(allowedTypes, function (type) {
+ _.each(allowedTypes, function(type) {
+ var allowedFunctions = _.filter(CRM.crmSearchAdmin.functions, function(fn) {
+ return fn.category === type &&
+ fn.params.length &&
+ // For now, only support functions that take a single field
+ fn.params[0].min_expr === 1 &&
+ fn.params[0].max_expr === 1 &&
+ !_.includes(fn.params[0].cant_be, 'SqlField') &&
+ (!fn.params[0].must_be.length || _.includes(fn.params[0].must_be, 'SqlField'));
+ });
functions.push({
text: allTypes[type],
- children: formatForSelect2(_.where(CRM.crmSearchAdmin.functions, {category: type}), 'name', 'title')
+ children: formatForSelect2(allowedFunctions, 'name', 'title')
});
});
}
<div class="form-inline">
- <label>{{ $ctrl.field.label }}:</label>
+ <label>{{ $ctrl.field[0].label }}:</label>
<input class="form-control" style="width: 15em;" ng-model="$ctrl.fn" crm-ui-select="{data: $ctrl.getFunctions, placeholder: ts('Select')}" ng-change="$ctrl.selectFunction()">
<label ng-if="$ctrl.modifierName">
<input type="checkbox" ng-checked="!!$ctrl.modifier" ng-click="$ctrl.toggleModifier()">