Modifications pour le document Macros de résultats Livetable
Modifié par Florent Charton le 2026/03/13 11:03
Depuis la version 4.1
modifié par Florent Charton
sur 2026/01/08 10:56
sur 2026/01/08 10:56
Commentaire de modification :
Install extension [org.xwiki.platform:xwiki-platform-livetable-ui/17.4.8]
À la version 6.1
modifié par Florent Charton
sur 2026/03/13 11:03
sur 2026/03/13 11:03
Commentaire de modification :
Install extension [org.xwiki.platform:xwiki-platform-livetable-ui/17.10.4]
Résumé
-
Propriétés de la Page (1 modifications, 0 ajouts, 0 suppressions)
Détails
- Propriétés de la Page
-
- Contenu
-
... ... @@ -37,9 +37,10 @@ 37 37 #foreach($colname in $collist) 38 38 ## If a classname is defined and the class field corresponding to the column name, 39 39 ## we check the type of the field and skip it if it's Password. 40 - #if ($className != '' && $class.get($colname)) 41 - #set ($isPasswordType = $class.get($colname).classType == 'Password') 42 - #set ($isEmailType = $class.get($colname).classType == 'Email') 40 + #livetable_getPropertyClassAndType($colname) 41 + #if ($propType != '') 42 + #set ($isPasswordType = $propClass.get($colname).classType == 'Password') 43 + #set ($isEmailType = $propClass.get($colname).classType == 'Email') 43 43 #set ($emailObfuscated = $services.mail.general.shouldObfuscate()) 44 44 #if (!($isPasswordType || ($isEmailType && $emailObfuscated))) 45 45 #livetable_addColumnToQuery($colname) ... ... @@ -692,6 +692,19 @@ 692 692 #elseif ($colName == 'doc.date' || $colName == 'doc.creationDate' || $colName == 'doc.contentUpdateDate') 693 693 #livetable_getTableAlias($colName) 694 694 #livetable_filterDateProperty() 696 + #elseif ($colName == 'doc.hidden' || $colName == 'doc.minorEdit1' || $colName == 'doc.enforceRequiredRights') 697 + ## Boolean document fields need special handling to work across all databases 698 + ## (HSQLDB/PostgreSQL use true/false, MySQL/MariaDB/Oracle use 1/0). 699 + ## Support both true/false and 1/0 as Live Data uses the former while LiveTable uses the latter. 700 + #set ($booleanValue = ($filterValue.toLowerCase() == 'true' || $filterValue == '1')) 701 + ## No need to clean the column name since it's only one of the given values. 702 + #if ($whereParams.entrySet()) 703 + #set ($whereSql = "${whereSql} and $colName = :${colName.replace('.', '_')}_filter") 704 + #set ($discard = $whereParams.put("${colName.replace('.', '_')}_filter", $booleanValue)) 705 + #else 706 + #set ($whereSql = "${whereSql} and $colName = ?") 707 + #set ($discard = $whereParams.add($booleanValue)) 708 + #end 695 695 #else 696 696 #set ($safeColName = $colName.replaceAll('[^a-zA-Z0-9_.]', '').replace('_', '.')) 697 697 #if ($whereParams.entrySet()) ... ... @@ -884,34 +884,79 @@ 884 884 *# 885 885 #macro (livetable_filterDBStringListProperty) 886 886 ## Perform exact matching by default if no match type is specified. 887 - ## Note that for DBStringList properties we takeintoaccount onlythefirstmatch type,evenifmultiplefilter888 - ## valuesare specified. Basicallythefirst match type isused for allfilter values.901 + ## For DBStringList properties we still apply a single match type to all non-empty values, but we also allow 902 + ## combining the special "empty" match type with other match types. 889 889 #livetable_getMatchTypes($colname $filterValues.size() 'exact') 890 - #if ($matchType == 'partial' || $matchType == 'prefix') 891 - ## We need to join with the list of values in order to be able to use the LIKE operator. 892 - #set ($matchTarget = "${safe_tableAlias}_item") 893 - #if ($whereParams.entrySet()) 894 - #set ($paramPrefix = "${safe_tableAlias}_item_") 904 + #livetable_getJoinOperator($colname) 905 + 906 + ## Collect non-empty filter values (those whose match type is not 'empty'). 907 + #set ($nonEmptyValues = []) 908 + #set ($hasEmpty = false) 909 + #set ($matchType = 'invalid') 910 + #foreach ($filterValue in $filterValues) 911 + #if ($matchTypes.get($foreach.index) == 'empty') 912 + #set ($hasEmpty = true) 913 + ## When we want to match empty values, we can't have other match types than exact for non-empty values as for 914 + ## other match types, we need to join with the list of values, which is not compatible with checking for 915 + ## emptiness. 916 + #set ($matchType = 'exact') 917 + #elseif ("$!filterValue" != '') 918 + #set ($discard = $nonEmptyValues.add($filterValue)) 919 + ## Store the first non-empty match type. 920 + #if ($matchType == 'invalid') 921 + #set ($matchType = $matchTypes.get($foreach.index)) 922 + #end 923 + #end 924 + #end 925 + 926 + ## 1) Apply the non-empty constraints. 927 + #if (!$nonEmptyValues.isEmpty()) 928 + #if ($matchType == 'partial' || $matchType == 'prefix') 929 + ## We need to join with the list of values in order to be able to use the LIKE operator. 930 + #set ($matchTarget = "${safe_tableAlias}_item") 931 + #if ($whereParams.entrySet()) 932 + #set ($paramPrefix = "${safe_tableAlias}_item_") 933 + #else 934 + #set ($paramPrefix = $NULL) 935 + #end 936 + #set ($joinPos = $mathtool.add($fromSql.lastIndexOf(" $safe_tableAlias"), $mathtool.add($safe_tableAlias.length(), 1))) 937 + #set ($fromSql = "$fromSql.substring(0, $joinPos) join ${safe_tableAlias}.list as $matchTarget $fromSql.substring($joinPos)") 895 895 #else 896 - #set ($paramPrefix = $NULL) 939 + ## Fall-back on exact matching even if the match type is specified, when its value is not supported. 940 + #set ($matchType = 'exact') 941 + #set ($matchTarget = "${safe_tableAlias}.list") 942 + #if ($whereParams.entrySet()) 943 + #set ($paramPrefix = "${safe_tableAlias}_list_") 944 + #else 945 + #set ($paramPrefix = $NULL) 946 + #end 897 897 #end 898 - #set ($joinPos = $mathtool.add($fromSql.lastIndexOf(" $safe_tableAlias"), $mathtool.add($safe_tableAlias.length(), 1))) 899 - #set ($fromSql = "$fromSql.substring(0, $joinPos) join ${safe_tableAlias}.list as $matchTarget $fromSql.substring($joinPos)") 900 - #else 901 - ## Fall-back on exact matching even if the match type is specified, when its value is not supported. 902 - #set ($matchType = 'exact') 903 - #set ($matchTarget = "${safe_tableAlias}.list") 904 - #if ($whereParams.entrySet()) 905 - #set ($paramPrefix = "${safe_tableAlias}_list_") 948 + 949 + #set ($filterQuery = "#livetable_getFilterQuery($matchTarget $matchType true $nonEmptyValues.size() $paramPrefix $NULL)") 950 + #if (!$hasEmpty) 951 + ## Only non-empty values are used, combine directly with the existing constraints, otherwise, they will be 952 + ## combined later together with the empty constraint. 953 + #set ($whereSql = "$whereSql and ($filterQuery.trim())") 954 + #end 955 + #foreach ($filterValue in $nonEmptyValues) 956 + #livetable_addFilterParam($filterValue $matchType $whereParams "${paramPrefix}${foreach.count}") 957 + #end 958 + #end 959 + 960 + ## 2) Optionally add a single constraint if any match type is 'empty'. 961 + #if ($hasEmpty) 962 + ## "empty" means that there is no list item stored for this property on the filtered object. 963 + ## The proper way to check for that would be "${safe_tableAlias}.list IS EMPTY", but JSQL cannot parse "IS EMPTY" 964 + ## which means that we cannot use it without programming right. 965 + #set ($emptyConstraint = "size(${safe_tableAlias}.list) = 0") 966 + #if ($nonEmptyValues.isEmpty()) 967 + ## Only 'empty' is used, combine with the existing constraints. 968 + #set ($whereSql = "${whereSql} and ${emptyConstraint}") 906 906 #else 907 - #set ($paramPrefix = $NULL) 970 + ## Combine non-empty group and empty condition using the join operator. 971 + #set ($whereSql = "${whereSql} and ($filterQuery.trim() ${joinOperator} ${emptyConstraint})") 908 908 #end 909 909 #end 910 - #set ($filterQuery = "#livetable_getFilterQuery($matchTarget $matchType true $filterValues.size() $paramPrefix $NULL)") 911 - #set ($whereSql = "$whereSql and ($filterQuery.trim())") 912 - #foreach ($filterValue in $filterValues) 913 - #livetable_addFilterParam($filterValue $matchType $whereParams "${paramPrefix}${foreach.count}") 914 - #end 915 915 #end 916 916 917 917 ... ... @@ -1006,9 +1006,9 @@ 1006 1006 #if ($matchType == 'partial' || $matchType == 'prefix') 1007 1007 #livetable_repeatParams("upper($column) like upper(?)", " $joinOperator ", $valueCount, $paramPrefix, $paramOffset) 1008 1008 #elseif($matchType == 'empty') 1009 - ## Check if the value of the column is like the empty parameter (which is often the empty string), or if the value 1068 + ## Check if the value of the column is like the empty parameter (which is often the empty string), or if the value 1010 1010 ## of the column is null (to be compliant with Oracle which stores the empty string as a NULL value). 1011 - #livetable_repeatParams("($column like ? or $column is null)", " $joinOperator ", $valueCount, $paramPrefix, 1070 + #livetable_repeatParams("($column like ? or $column is null)", " $joinOperator ", $valueCount, $paramPrefix, 1012 1012 $paramOffset) 1013 1013 #elseif ($isList) 1014 1014 #livetable_repeatParams("? in elements($column)", " $joinOperator ", $valueCount, $paramPrefix, $paramOffset)