Skip to content

REST API: add functionality for saving Business Address in JPO#8426

Closed
AnnaMag wants to merge 8 commits intomasterfrom
add/jpo-save-business-address
Closed

REST API: add functionality for saving Business Address in JPO#8426
AnnaMag wants to merge 8 commits intomasterfrom
add/jpo-save-business-address

Conversation

@AnnaMag
Copy link
Copy Markdown
Contributor

@AnnaMag AnnaMag commented Dec 28, 2017

Depends on #8480.

Save Business Address in a sidebar widget during the JPO flow.

Changes proposed in this Pull Request:

  • This patch extends the onboarding endpoint to inject and subsequently update Business Address info as a sidebar widget. It is not included in the current JPO version.

Testing instructions:

  • Checkout current master in your local Calypso
  • Checkout this branch on your JP sandbox
  • Go to https://YourJetpackSandbox.com/wp-admin/admin.php?page=jetpack&action=onboard&calypso_env=development, where YourJetpackSandbox.com is the domain of your JP sandbox
  • Skip through the flow till the Add a business address step
  • Add input data and move to the Next step
  • Go to https://YourJetpackSandbox.com/wp-admin/widgets.php and/or your site and verify you see the newly created BA widget in the list of widgets and a post sidebar
  • Go back to Add a business address and modify the BA input
  • Verify that changes apply on your JP site

Note: enabling widget module when not done so is a separate PR

@AnnaMag AnnaMag self-assigned this Dec 28, 2017
@AnnaMag AnnaMag requested a review from a team as a code owner December 28, 2017 13:13
Copy link
Copy Markdown
Contributor

@eliorivero eliorivero Dec 28, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Since there are only two keys, the lines from sidebar option fetch up to the loop could be written as

$active_sidebars = get_option( 'sidebars_widgets', array() );
unset( $active_sidebars[ 'wp_inactive_widgets' ], $active_sidebars[ 'array_version' ] );

The unset won't fail if the array item is not set.

It could also be written with an uglier one liner that ends up being longer :D

$active_sidebars = array_diff_key( get_option( 'sidebars_widgets', array() ), array_flip( array( 'wp_inactive_widgets', 'array_version' ) ) );

Copy link
Copy Markdown
Contributor Author

@AnnaMag AnnaMag Jan 7, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I settled for the first option to aid readability 👍 Thank a lot!

Copy link
Copy Markdown
Contributor Author

@AnnaMag AnnaMag Jan 11, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Using Jetpack_Widgets does not allow wp_inactive_widgets, so there is in fact a single key :)

@AnnaMag AnnaMag force-pushed the add/jpo-save-business-address branch from c4715a9 to a462a65 Compare December 29, 2017 00:23
@jeherve jeherve added [Feature] WP REST API Enhancement Changes to an existing feature — removing, adding, or changing parts of it labels Dec 29, 2017
@AnnaMag AnnaMag force-pushed the add/jpo-save-business-address branch 4 times, most recently from d969051 to f1dbd45 Compare January 6, 2018 23:25
@AnnaMag AnnaMag changed the title Jetpack Onboarding: add functionality for saving Business Address REST API: add functionality for saving Business Address in JPO Jan 7, 2018
@AnnaMag AnnaMag force-pushed the add/jpo-save-business-address branch from f1dbd45 to 511caeb Compare January 7, 2018 20:27
Implement saving widget using activate and update `Jetpack_Widgets` functions to inject the widget
onto the page and update its content.
code cosmetics as we only have 2 keys here, no changes in functionality.
`set_widget_settings` updates options without checking whether they exist, so this patch adds such a check
`update_widget` unnecessarily adds widget to a sidebar
patch adds  helper function to look for a widget in a given sidebar by its `id_base`.
Copy link
Copy Markdown
Member

@tyxla tyxla left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This worked well upon initial testing 👍

Let's finish and merge #8480 and rebase this one against it.

Also, left some feedback, but looks like a really solid start 👍

if ( empty( $active_sidebars ) ) {
return false;
}
return array_shift( array_keys( $active_sidebars ) );
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This will throw a notice, because array_shift also updates the original referenced array (and there is no reference here):

PHP Notice:  Only variables should be passed by reference in .../jetpack/_inc/lib/core-api/class.jetpack-core-api-module-endpoints.php on line 1093


if( $first_sidebar ) {
$title = wp_unslash( $data[ 'businessAddress' ][ 'name' ] );
$address = wp_unslash(
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Order seems a little weird to me - city, state, street, zip. In the original JPO plugin it was street, city, state, zip - https://github.com/Automattic/jetpack-onboarding/blob/master/class.jetpack-onboarding-end-points.php#L708.

$first_sidebar = self::get_first_sidebar();

if( $first_sidebar ) {
$title = wp_unslash( $data[ 'businessAddress' ][ 'name' ] );
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do we want to store $data[ 'businessAddress' ] in a variable to make the code a little shorter by accessing all those fields with less code?

$first_sidebar = self::get_first_sidebar();

if( $first_sidebar ) {
$title = wp_unslash( $data[ 'businessAddress' ][ 'name' ] );
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Currently, we don't validate the presence of name, street or any of the others before using it; so we might end up using undeclared variables.


if( $first_sidebar ) {
$title = wp_unslash( $data[ 'businessAddress' ][ 'name' ] );
$address = wp_unslash(
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do we need those wp_unslash? Currently they might remove any backslashes that we have in the address.

return array_shift( array_keys( $active_sidebars ) );
}

public function has_business_info_widget( $sidebar ) {
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can we make this a method in Jetpack_Widgets that accepts a widget base ID (widget_contact_info in our case)? Could be useful, and would be the right place to keep this code IMHO.

Also, can we use something from Jetpack_Widgets to make this one simpler? get_widget_by_id_base() looks like a good candidate.

Copy link
Copy Markdown
Contributor Author

@AnnaMag AnnaMag Jan 11, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@tyxla, I see the point, and at the same time thinking that it is pretty much a JPO-specific method. Are there other contexts in could be reused if defined in a Jetpack module? 🤔

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No usages right now AFAIK, but it doesn't cost anything (other than just adding a parameter for the widget ID base) to do it, and in case we decide to use it in the future, it will be easier and will not require refactor PRs like this one #8464.

}

public function update_widget( $id_base, $sidebar, $position, $widget_options ) {

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Unnecessary whitespace in the beginning of a block.

return false;
}

public function update_widget( $id_base, $sidebar, $position, $widget_options ) {
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should this method be in _inc/lib/widgets.php instead? Guess we should figure another name for it? update_widget_by_id_base maybe?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I put it in a separate method when at the beginning of getting it up and running the code was much longer. Looking at it now, I reckon it is not needed in fact. Slightly re-written it becomes a two-liner and can be used in-place. Do you agree?

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not sure what exactly you mean - could you please elaborate?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.


$widget = Jetpack_Widgets::get_widget_by_id_base( $id_base );
$widget_id = $widget['id'];
Jetpack_Widgets::update_widget($widget_id, $sidebar, $position, $widget_options );
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Two consecutive spaces after $widget_id,.

return $found;
}

/**
Copy link
Copy Markdown
Member

@tyxla tyxla Jan 8, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Left some feedback in the other PR (#8480) about this one.

@AnnaMag
Copy link
Copy Markdown
Contributor Author

AnnaMag commented Jan 8, 2018

Thanks for the reviews @tyxla 🙏

I see that a lot of the comments are concerned with what to keep in the endpoint and what to move to module's methods. I kept a lot in the former, not being sure how much of that extends beyond JPO itself. I'll have another 👀 after we merge the previous related PRs.

$position = '0';
$id_base = 'widget_contact_info';

$has_ba_widget = self::has_business_info_widget( $first_sidebar );
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@AnnaMag one thing to consider here: for the GET endpoint, we'll need to be able to:

  1. Know whether business address has been set or not
  2. Retrieve all those business address fields, in order to be able to return them in the endpoint.

Right now, with your PR, for 1, we can use self::has_business_info_widget( $first_sidebar ), but for 2. we'll need something else, for example storing $data[ 'businessAddress' ] in an option. If you decide to do that, make sure to also add the option to the list of known options, in order it to be cleaned up after uninstalling JP (as done here: https://github.com/Automattic/jetpack/pull/8495/files#diff-cb166c81692a76d1a92d53cb5e80d67cR537).

Copy link
Copy Markdown
Contributor Author

@AnnaMag AnnaMag Jan 9, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As agreed on Slack let's handle it in the follow-up. As always, 💯 point.

@oskosk oskosk added this to the 5.8 milestone Jan 10, 2018
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.'
@AnnaMag AnnaMag force-pushed the add/jpo-save-business-address branch from 8b4f0b6 to aa6ccf5 Compare January 10, 2018 23:48
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There's a missing parens here

Copy link
Copy Markdown
Contributor Author

@AnnaMag AnnaMag Jan 11, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Was fixed in #8480 and now also ported here. Thanks for reviewing!

@AnnaMag AnnaMag force-pushed the add/jpo-save-business-address branch from 3367d09 to 3cd5b3a Compare January 11, 2018 13:27
// Add/update business address widget
if ( isset( $data['businessAddress'] ) ) {
//grab the first sidebar and proceed if it is present
$first_sidebar = Jetpack_Widgets::get_first_sidebar();
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This gives me

PHP Deprecated: Non-static method Jetpack_Widgets::get_first_sidebar() should not be called statically in jetpack/_inc/lib/core-api/class.jetpack-core-api-module-endpoints.php on line 1049

Since get_first_sidebar() doesn't seem to refer to the instance ( $this), I think we can actually make it static.

@ockham
Copy link
Copy Markdown
Contributor

ockham commented Jan 11, 2018

I can't seem to get this to work 🙁

How I'm testing: Using the Jetpack Beta Plugin, and selecting 'Bleeding Edge' -- which at this point was 'last updated 4 hours ago', so it doesn't include #8501. Thus, I'm manually applying #8501 and this PR's diff.

The error I'm getting is the 'Unexpected Error' notice, and checking /wp-admin/widgets.php, I see that no widget was added. My browser's 'Network' tab gives me

{"code":500,"headers":[{"name":"Content-Type","value":"application\/json"}],"body":{"error":"no_response_body","message":"Server could not read response."}}

The server debug log contains (a PHP Depracted and PHP Notice aside), the following PHP Warning:

PHP Warning: Cannot modify header information - headers already sent by (output started at wp-content/plugins/jetpack-dev/_inc/lib/core-api/class.jetpack-core-api-module-endpoints.php:1069) in wp-includes/rest-api/class-wp-rest-server.php on line 1256

@ockham
Copy link
Copy Markdown
Contributor

ockham commented Jan 11, 2018

Tried this now with simply checking out the add/jpo-save-business-address branch on my sandbox (per @AnnaMag's suggestion -- I was previously assuming I'd have to build JP for it to work), and making sure I'm using the corresponding update/jpo-save-business-address Calypso branch, but unfortunately, I'm still getting the same error 🙁

@AnnaMag
Copy link
Copy Markdown
Contributor Author

AnnaMag commented Jan 15, 2018

Closing in favor of #8523.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Enhancement Changes to an existing feature — removing, adding, or changing parts of it [Feature] WP REST API

Projects

None yet

Development

Successfully merging this pull request may close these issues.

7 participants