Widget housekeeping: extend functionality and add check for existing data upon update#8480
Widget housekeeping: extend functionality and add check for existing data upon update#8480
Conversation
tyxla
left a comment
There was a problem hiding this comment.
Looks good overall, left some feedback and questions.
Jetpack_Widgets have not been used elsewhere, so we do not introduce regression with these changes.
Note that this is not entirely true, see https://github.com/Automattic/jetpack/blob/master/json-endpoints/class.wpcom-json-api-add-widget-endpoint.php - not sure if that endpoint is used anywhere though. In any case we need to make sure we don't break anything with these changes (if anything is using that endpoint, we should also be testing it). cc @eliorivero
_inc/lib/widgets.php
Outdated
There was a problem hiding this comment.
I know this was like that before, but to me it doesn't make sense for this to be a 500. Should it be a 400 instead?
_inc/lib/widgets.php
Outdated
There was a problem hiding this comment.
This one was useful in case we're moving an existing widget to another sidebar - could you please clarify why we're removing it?
There was a problem hiding this comment.
Thanks for reviewing @tyxla! 🙇♀️
FWIU, if a widget passed to update_widget is not in the sidebar (also passed as an arg)
$widgets_in_sidebar = self::get_widgets_in_sidebar( $sidebar );
if ( ! isset( $widgets_in_sidebar ) ) {
return new WP_Error( 'invalid_data', 'No such sidebar exists', 400 );
}
will return and we would not get to that call anyway. Wouldn't it be clearer to create a separate function e.g. move_widget for those cases? ( I mean in general, not for current iteration of JPO, as we always grab the first sidebar).
Let me know if I misunderstood your question :)
There was a problem hiding this comment.
Let me clarify further. The update_widget method is a kind of generic and supports many situations. One of the cases is where the widget is currently in sidebar "x" and you want to move it to sidebar "y" while updating it. Another case is when we want to change its position. In both of these cases, self::move_widget_to_sidebar would move the widget accordingly, but now that you removed that method, it'll no longer handle those cases. Makes sense?
There was a problem hiding this comment.
Fwiw, that error message No such sidebar exists does not reflect the actual check 🤔
There was a problem hiding this comment.
Good call, worth improving I guess....
There was a problem hiding this comment.
☝️ right, agreed. For a moment I read the $widgets_in_sidebar = self::get_widgets_in_sidebar( $sidebar ); as a check whether that specific widget is present.
Two extra points:
- the above shows another edge case: if a sidebar is empty and we want to place "our" widget in it, it will return before that happens (
if ( ! isset( $widgets_in_sidebar ) )). Is this by design? - how about we call the removed line only if required? ( after checking whether the widget is in the sidebar or not)
There was a problem hiding this comment.
Makes sense to me, maybe it's best to confirm with @eliorivero who wrote the initial code there.
There was a problem hiding this comment.
I added the logic mentioned above and updated the error message.
I still do not see the why behind returning on sidebar with no widgets. It is not a blocker at the moment though.
_inc/lib/widgets.php
Outdated
There was a problem hiding this comment.
Shame we can't use array_filter with an anonymous function here because of PHP version limitations in Jetpack.
_inc/lib/widgets.php
Outdated
There was a problem hiding this comment.
If we alter the return $found to return null and we alter $found = $widget to return $widget, we can omit $found = null at the top.
_inc/lib/widgets.php
Outdated
There was a problem hiding this comment.
With nesting this under the if ( isset( $widget_settings[ $instance_key ] ) ) { check, we'll never see the error if we try to update an incorrect widget?
The widget is already in the sidebar, so this call is redundant.
`set_widget_settings` is called both on first widget activation and when updating the content. However, we do not distinguish between the two actions and when the content is empty, an error is thrown when accessing widget settings on an empty `instance_key`. This commit corrects that.
1586368 to
2d33041
Compare
c91e856 to
434ae4a
Compare
Previous commit in the patch removed it assuming that the sidebar already contains the widget to be updated. This will not be the case in general, e.g. when placing a widget in another sidebar. This commit brings it back conditional on the check that the widget is absent from the sidebar. In addition: - it adds a helper function and leaves a couple of comments for clarity. - small code refactor to avoid declaring unnecessary variables - change error code when no sidebar is present - updates error message when no widget is present in a sidebar.'
c16fa18 to
04870a1
Compare
Adding a check of validity of widget`s ID base for new widgets.
|
Ready for another round of reviews 👍 Thanks! |
| * | ||
| * @return bool Whether present. | ||
| */ | ||
| public static function is_widget_in_sidebar( $widgets_all, $widget_id ) { |
| * @return bool Whether present. | ||
| */ | ||
| public static function is_widget_in_sidebar( $widgets_all, $widget_id ) { | ||
| foreach ( $widgets_all as $widget_el_id ) { |
There was a problem hiding this comment.
We should be able to replace this entire foreach with something like:
in_array( $widget_id, $widgets_all, true )
| if ( empty( $active_sidebars ) ) { | ||
| return false; | ||
| } | ||
| return array_shift( array_keys( $active_sidebars ) ); |
There was a problem hiding this comment.
This will throw a notice, because array_shift also updates the original referenced array (and there is no reference here).
|
|
||
| /** | ||
| * Find a widget in a list of all widgets retrieved from a sidebar | ||
| * using get_widgets_in_sidebar() |
There was a problem hiding this comment.
It doesn't seem to use get_widgets_in_sidebar()
| /** | ||
| * Find a widget in a list of all widgets retrieved from a sidebar | ||
| * using get_widgets_in_sidebar() | ||
| * @param string $widget The widget we want to look up in the sidebar |
There was a problem hiding this comment.
This doesn't document widgets_all properly.
| * | ||
| * @return array|false Active sidebar or false if none exists | ||
| */ | ||
| public function get_first_sidebar() { |
There was a problem hiding this comment.
I think we can make this method static, cf. https://github.com/Automattic/jetpack/pull/8426/files#r161009496
|
Closing in favor of #8523. |
Side effect of the JPO work on extending the endpoint to inject Business Address widget.
Changes proposed in this Pull Request:
remove redundant sidebar placement when updating the widgetwhen updating a widget, it adds a check of whether a widget is in a sidebar before calling a function that moves it thereid_base, not only bywidget_idset_widget_settings) is called both when activating a new and updating an existing widget with no checks in place.Testing instructions:
Jetpack_Widgetshave not been used elsewhere, so we do not introduce regression with these changes. UPDATE: outside of https://github.com/Automattic/jetpack/blob/master/json-endpoints/class.wpcom-json-api-add-widget-endpoint.php 😄Q: Should those changes include separate JP tests?