@@ -39,9 +39,23 @@ public function apply(QueryBuilder $queryBuilder, FilterDataDto $filterDataDto,
3939 return ;
4040 }
4141
42- $ isRange = SemverFilterType::COMPARISON_BETWEEN === $ comparison
43- || SemverFilterType::COMPARISON_BETWEEN_EXCLUSIVE === $ comparison ;
44- if ($ isRange && '' === $ value2 ) {
42+ // When the user fills the upper-bound field together with a directional
43+ // operator (>, >=, <, <=), treat the filter as a range. The operator's
44+ // inclusivity carries over (>= / <= → inclusive, > / < → exclusive),
45+ // so the natural reading "from X to Y" works regardless of which side
46+ // the user picked. Range operators (between / between_exclusive)
47+ // require both values and behave the same way. = and != are exact
48+ // matches, so value2 is ignored.
49+ $ isExplicitRange = in_array ($ comparison , [SemverFilterType::COMPARISON_BETWEEN , SemverFilterType::COMPARISON_BETWEEN_EXCLUSIVE ], true );
50+ $ autoRange = '' !== $ value2 && in_array ($ comparison , [
51+ SemverFilterType::COMPARISON_GT ,
52+ SemverFilterType::COMPARISON_GTE ,
53+ SemverFilterType::COMPARISON_LT ,
54+ SemverFilterType::COMPARISON_LTE ,
55+ ], true );
56+ $ isRange = $ isExplicitRange || $ autoRange ;
57+
58+ if ($ isExplicitRange && '' === $ value2 ) {
4559 return ;
4660 }
4761
@@ -70,9 +84,19 @@ public function apply(QueryBuilder $queryBuilder, FilterDataDto $filterDataDto,
7084 // references its argument five times) and PDO would complain about
7185 // bound-variable count.
7286 if ($ isRange ) {
73- [$ lowerOp , $ upperOp ] = SemverFilterType::COMPARISON_BETWEEN === $ comparison
74- ? ['>= ' , '<= ' ]
75- : ['> ' , '< ' ];
87+ $ inclusive = in_array ($ comparison , [
88+ SemverFilterType::COMPARISON_BETWEEN ,
89+ SemverFilterType::COMPARISON_GTE ,
90+ SemverFilterType::COMPARISON_LTE ,
91+ ], true );
92+ [$ lowerOp , $ upperOp ] = $ inclusive ? ['>= ' , '<= ' ] : ['> ' , '< ' ];
93+
94+ // Sort the two values numerically so the user can enter them in any
95+ // order — "< 11.3.0" with value2 = "10.0.0" still produces a sane
96+ // range, not an unsatisfiable WHERE.
97+ $ a = self ::toSemverNumeric ($ value );
98+ $ b = self ::toSemverNumeric ($ value2 );
99+ [$ min , $ max ] = $ a <= $ b ? [$ a , $ b ] : [$ b , $ a ];
76100
77101 $ queryBuilder
78102 ->andWhere (sprintf (
@@ -83,8 +107,8 @@ public function apply(QueryBuilder $queryBuilder, FilterDataDto $filterDataDto,
83107 $ parameter ,
84108 $ upperOp ,
85109 ))
86- ->setParameter ($ parameter .'_min ' , self :: toSemverNumeric ( $ value ) )
87- ->setParameter ($ parameter .'_max ' , self :: toSemverNumeric ( $ value2 ) )
110+ ->setParameter ($ parameter .'_min ' , $ min )
111+ ->setParameter ($ parameter .'_max ' , $ max )
88112 ;
89113
90114 return ;
0 commit comments