- Notifications
You must be signed in to change notification settings - Fork 25
Remove empty data after filtering in onRoute - option #102
Remove empty data after filtering in onRoute - option #102
Conversation
…_data' config key.
…ter the data, added function to determine config setting, added overwriting of data with filtered data if key set and true in config.
…out the key - adds what it does and how to set it
…ional checks for empty data on response of recursive calls to prevent possibility of returned empty array being left in final response.
| if (empty($value)) { | ||
| unset($data[$key]); | ||
| } | ||
| } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This can be simplified a ton:
foreach ($data as $key => $value) { if (! is_array($value) && ! empty($value)) { continue; } if (! is_array($value)) { unset($data[$key]); continue; } if (empty(array_filter($value, $removeNull))) { unset($data[$key]); continue; } $tmpValue = $this->removeEmptyData($value); if (empty(array_filter($tmpValue, $removeNull))) { unset($data[$key]); continue; } $data[$key] = $tmpValue; }You don't need to unset $tmpValue as it gets re-assigned when the appropriate conditional occurs. By flattening the structure, we can better understand the various paths through the loop, which will make testing easier.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ah thank you, will have a look at it again soon. Atm pushing deadlines, so might be a wee while.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done
| $this->assertEquals($params, $dataParams->getBodyParams()); | ||
| } | ||
| | ||
| public function testFilterEmptyEntriesFromDataByOptionWithNestedData() |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There are five different paths through the removeEmptyData() method, corresponding to five different conditions that can occur. You'll need five tests to fully exercise the method and verify it.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Will have another look. Was thinking today it wasn't enough, but as tests passed and I'm pushed for time, I was thinking of coming back to it.
| Woke up with the realization that this PR is slightly off at the moment. Will have to modify it some more (apart from @weierophinney's comments thus far). E.g. an address: "Farmroad 3a", consists of 2 required ( But, the address was a typo, should've been "Farmroad 3". As PATCH /address/2 As such, I need to add in functionality to compare the data from which (btw, posting that here so I don't forget. I'm aiming to pick this up today or tomorrow, but it's busy at the office.) |
… and clearer in use cases for data flow.
…t compatible with PHP < 7 and added TODO lines (2) for when module is bumpted to PHP > 7. Added comparisonData variable to onRoute function, later used for removeEmptyData, but it keeps unfiltered data instead of being overwritten at a later point.
| Must still update the tests |
a57d74f to 5084634 Compare …ived data (compareTo) - current situation deleted them in next if statement - this is all in ContentValidationListener.
weierophinney left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@rkeet I see you're still adding to this, so I did a quick review of what's here, and made a few more suggestions. In addition, I still need the tests I suggested before I can review to merge and release.
Thanks for all the great work so far!
src/ContentValidationListener.php Outdated
| * @return array | ||
| */ | ||
| // TODO strict types for PHP > 7 when module gets bumped | ||
| // protected function removeEmptyData(array $data, array $compareTo = []) : array |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Put this in the docblock, above the @param annotations, as an @todo annotation, please.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
done
src/ContentValidationListener.php Outdated
| protected function removeEmptyData($data, $compareTo = []) | ||
| { | ||
| // TODO when bumped to PHP > 7 and strict types above enforced this check may be removed | ||
| if (! is_array($data) || ! is_array($compareTo)) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
PHP 5.6 allows us to use the array typehint for arguments.; we do not need to wait for PHP 7 here.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
done
src/ContentValidationListener.php Outdated
| $removeNull = function ($value, $key = null) use ($compareTo) { | ||
| // If comparison array is empty, do a straight comparison | ||
| if (empty($compareTo)) { | ||
| return ! is_null($value); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We tend to use the construct null !== $value.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
done
src/ContentValidationListener.php Outdated
| return true; | ||
| } | ||
| | ||
| return ! is_null($value); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Same comment here: null !== $value
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
done
src/ContentValidationListener.php Outdated
| $tmpValue = $this->removeEmptyData($value, $compareTo[$key]); | ||
| } else { | ||
| $tmpValue = $this->removeEmptyData($value); | ||
| } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This could become:
$tmpValue = array_key_exists($key, $compareTo) && is_array($compareTo[$key]) ? $this->removeEmptyData($value, $compareTo[$key]) : $this->removeEmptyData($value);Ternary assignments are nice for this kind of either/or thing, and make reading the code easier.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
done
…ary. Replaced '! is_null()' with 'null !== '.
| TODO
|
…ContentValidationListener
…tionality for creatoin of listener and event into own functions, re-used for all 5 test functions
| I think I've got it all covered now. Please do check. |
| Small ping @weierophinney |
- Removed unnecessary import statement. - Simplified conditional in `shouldRemoveEmptyData()` to remove redundant `isset` check. - Removed `@todo` annotations that detail future signature changes; these will happen regardless. - Add parameter types to annotations where necessary. - Remove unnecessary parens. - Remove unnecessary whitespace.
- Extracts the `booleanProvider` for use with `testFilterEmptyEntriesFromDataByOptionWhenValueBooleanNotInComparison()` test case. - Moves annotations to the end of method docblocks. - If the only argument is an array, moves opening brace to same line as method invocation. - Ensure arrays have trailing commas.
weierophinney left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I've pushed a few minor consistency changes, mostly around formatting; otherwise, this is ready to go!
Thanks, @rkeet !
| Hello, I have found some problems in my api with this new PR. I have some forms that send zero value and this new PR unset me the body param. Its that ok? I need to set remove_empty_data in my config for every controller? Im using Apigility. |
| protected function shouldRemoveEmptyData($controllerService) | ||
| { | ||
| if (! isset($this->config[$controllerService]['remove_empty_data']) | ||
| || $this->config[$controllerService]['remove_empty_data'] === true |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
| @diego-sorribas It is already fixed in version 1.7.1 - see: |
Provide a narrative description of what you are trying to accomplish:
Issue #59 - When not using raw data (so filtered) and having requirements on the Entities (logically), the issue can exist that
nullvalues get attempted to be hydrated.Filtering the data (by not using raw data), causes all keys for of all InputFilter's to be added to the data array which gets passed to the
DoctrineObjecthydrator in the current happy flow.This PR gives an additional option: filter out the null values.
Same as
use_raw_dataandallows_only_fields_in_filter-> create config key withtruevalue.developbranch, and submit against that branch.CHANGELOG.mdentry for the new feature.Acceptance criteria
trueThis may not be the greatest solution, I'm open to suggestions/requests for improvement.
However, consider that this added bit does not change the current implementation, it just adds the possibility to filter out the null/empty values of a received data array.
It does not contain a bc-break as it must be enabled with config, the same way as 2 existing options.