N°9687 - Fix incorrect return type for the DBObjectSearch::ApplyDataFilter() function#939
Conversation
|
Draft until unit tests are pushed |
|
@greptileai review please |
|
| Filename | Overview |
|---|---|
| core/dbobjectsearch.class.php | Return type now matches the existing DBSearch abstraction used by callers. |
| core/dbunionsearch.class.php | Return type now stays compatible with recursive filter application. |
| tests/php-unit-tests/unitary-tests/core/DBSearch/DBSearchApplyDataFiltersTest.php | Regression coverage exercises a user-rights filter that returns a union search and restores the selected module afterward. |
Reviews (4): Last reviewed commit: "N°9687 - Improve unit test after code re..." | Re-trigger Greptile
There was a problem hiding this comment.
Pull request overview
Fixes a fatal PHP TypeError caused by DBObjectSearch::ApplyDataFilters() being declared to return DBObjectSearch while it can legitimately return a DBUnionSearch (eg. when user rights filters produce union searches). The change aligns method signatures with actual runtime behavior by using the common base type DBSearch.
Changes:
- Broadened
ApplyDataFilters()return type inDBObjectSearchfromDBObjectSearchtoDBSearchto prevent runtime return type violations. - Broadened
ApplyDataFilters()return type inDBUnionSearchfromDBUnionSearchtoDBSearchfor consistency and to accommodateparent::ApplyDataFilters()behavior.
Reviewed changes
Copilot reviewed 2 out of 2 changed files in this pull request and generated no comments.
| File | Description |
|---|---|
| core/dbobjectsearch.class.php | Updates ApplyDataFilters() return type to DBSearch to avoid TypeError when filtering returns a DBUnionSearch. |
| core/dbunionsearch.class.php | Updates ApplyDataFilters() return type to DBSearch, matching the base contract and supporting delegation to parent::ApplyDataFilters(). |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| protected function ApplyDataFilters(): DBObjectSearch | ||
| protected function ApplyDataFilters(): DBSearch | ||
| { | ||
| if ($this->IsAllDataAllowed() || $this->IsDataFiltered()) { |
There was a problem hiding this comment.
IsDataFiltered() is doing the opposite of what the name seems to tell... hard to understand at first sight.
There was a problem hiding this comment.
I strongly advice to complete PHPDOC of all used methods... some are missing or incomplete (mixed).
ie GetSearches, FromEmptySet, GetSelectedClasses, GetJoinedClasses.
There was a problem hiding this comment.
apart from that if we do the minimum to change the code, it could be nice to have full test cover of 3 distincts kinds of ApplyDataFilters (DBUnionSearch, DBsearch, DBObjSearch().
for example security.disable_joined_classes_filter in the conf can change the behaviour. just as UserRightsGetSelectFilter extensibility.... we can discuss it if you want
There was a problem hiding this comment.
last but not least it could be nice to refactor in one common method. where we would pass an array of string (coming from either GetSearches, GetSelectedClasses or GetJoinedClasses).
// Apply filter (this is similar to the one in DBSearch but the factorization could make it less readable)
foreach ($aClassesToFilter as $sClassAlias => $sClass) {
$oVisibleObjects = UserRights::GetSelectFilter($sClass, $this->GetModifierProperties('UserRightsGetSelectFilter'));
if ($oVisibleObjects === false) {
$oVisibleObjects = DBObjectSearch::FromEmptySet($sClass);
}
if (is_object($oVisibleObjects)) {
$oVisibleObjects->AllowAllData();
$oSearch = $oSearch->Filter($sClassAlias, $oVisibleObjects);
$oSearch->SetDataFiltered();
}
}
There was a problem hiding this comment.
no need to compute GetSelectedClass if 'security.disable_joined_classes_filter' is disabled.
odain-cbd
left a comment
There was a problem hiding this comment.
we should discuss... my guess is that we will focus on the minimum. which is not 100% sure from what i see in the code. i understand that i dont understand everything....
| protected function ApplyDataFilters(): DBObjectSearch | ||
| protected function ApplyDataFilters(): DBSearch | ||
| { | ||
| if ($this->IsAllDataAllowed() || $this->IsDataFiltered()) { |
There was a problem hiding this comment.
I strongly advice to complete PHPDOC of all used methods... some are missing or incomplete (mixed).
ie GetSearches, FromEmptySet, GetSelectedClasses, GetJoinedClasses.
| protected function ApplyDataFilters(): DBObjectSearch | ||
| protected function ApplyDataFilters(): DBSearch | ||
| { | ||
| if ($this->IsAllDataAllowed() || $this->IsDataFiltered()) { |
There was a problem hiding this comment.
apart from that if we do the minimum to change the code, it could be nice to have full test cover of 3 distincts kinds of ApplyDataFilters (DBUnionSearch, DBsearch, DBObjSearch().
for example security.disable_joined_classes_filter in the conf can change the behaviour. just as UserRightsGetSelectFilter extensibility.... we can discuss it if you want
| protected function ApplyDataFilters(): DBObjectSearch | ||
| protected function ApplyDataFilters(): DBSearch | ||
| { | ||
| if ($this->IsAllDataAllowed() || $this->IsDataFiltered()) { |
There was a problem hiding this comment.
last but not least it could be nice to refactor in one common method. where we would pass an array of string (coming from either GetSearches, GetSelectedClasses or GetJoinedClasses).
// Apply filter (this is similar to the one in DBSearch but the factorization could make it less readable)
foreach ($aClassesToFilter as $sClassAlias => $sClass) {
$oVisibleObjects = UserRights::GetSelectFilter($sClass, $this->GetModifierProperties('UserRightsGetSelectFilter'));
if ($oVisibleObjects === false) {
$oVisibleObjects = DBObjectSearch::FromEmptySet($sClass);
}
if (is_object($oVisibleObjects)) {
$oVisibleObjects->AllowAllData();
$oSearch = $oSearch->Filter($sClassAlias, $oVisibleObjects);
$oSearch->SetDataFiltered();
}
}
| protected function ApplyDataFilters(): DBObjectSearch | ||
| protected function ApplyDataFilters(): DBSearch | ||
| { | ||
| if ($this->IsAllDataAllowed() || $this->IsDataFiltered()) { |
There was a problem hiding this comment.
no need to compute GetSelectedClass if 'security.disable_joined_classes_filter' is disabled.
| * @return DBUnionSearch | ||
| */ | ||
| protected function ApplyDataFilters(): DBUnionSearch | ||
| protected function ApplyDataFilters(): DBSearch |
There was a problem hiding this comment.
it is a pity that we compute further times IsDataAllowed and IsDataFiltered when dealing with Union....
first time in DBUnion. and 2nd time in the loop when calling each sub item.
|
@greptileai review again please. |
Thanks for the review. We can discuss IRL tomorrow for sure. |
|
@greptileai review again please. |
Base information
Symptom (bug)
Fatal error when accessing the backoffice with a non-admin user.
Reproduction procedure (bug)
Cause (bug)
Fix a fatal type mismatch in data filtering when user rights filters return a union search.
DBObjectSearch::ApplyDataFilters()is currently typed to returnDBObjectSearch, but in some valid scenarios (custom rights profile / team silos), filters returnDBUnionSearch.This causes a runtime
TypeErrorand breaks login, impersonation, and some non-admin actions (for example ticket creation).Proposed solution (bug and enhancement)
The fix is to broaden the return type from
DBObjectSearchtoDBSearch, which matches actual behavior and accepted filter outputs.Checklist before requesting a review