Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Customizer: keep Simple Payments Widget Customizer in sync between instances #9814

Merged

Conversation

rodrigoi
Copy link
Contributor

@rodrigoi rodrigoi commented Jun 22, 2018

Changes proposed in this Pull Request:

Keeps all the instances of the Simple Payments Widget Customizer in sync by observing the widget-synced and widget-updated events, querying the server for the updated list of products.

Before After
before after

Testing instructions:

Starting with a Jetpack Professional site with at least one product loaded (two for dramatic effect):

  • Add a Simple Payments Widget to the site sidebar or footer.
  • Add a new Product by clicking Add New and filling the form.
  • Add a second Simple Payments Widget to the site sidebar or footer.
  • Expand the list of products on the second widget.

The list of products should show the newly added product on the correct position.

  • Add a new Product by clicking Add New and filling the form on the second widget.
  • Expand the first widget.
  • Expand the list of products on the first widget.

The list of products should show the newly created product on the second widget on the product list on the correct position.

  • On the first widget, edit the currently selected product name.
  • Expand the second widget.
  • Expand the list of products on the second widget.

The edited product should have the new name.

@rodrigoi rodrigoi self-assigned this Jun 22, 2018
@rodrigoi rodrigoi requested a review from a team as a code owner June 22, 2018 23:19
@rodrigoi rodrigoi added [Type] Bug When a feature is broken and / or not performing as intended [Feature] Extra Sidebar Widgets [Status] Needs Review To request a review from Crew. Label will be renamed soon. [Pri] High Simple Payments and removed [Status] In Progress labels Jun 23, 2018
@rodrigoi rodrigoi requested a review from a team June 23, 2018 03:17
@rodrigoi rodrigoi added this to the 6.3 milestone Jun 23, 2018
@rodrigoi rodrigoi force-pushed the add/simple-payments-widget-products-sync branch from beff2be to 3a6117c Compare June 23, 2018 16:30
$select
.find( 'option' )
.remove()
.end()
Copy link
Contributor

Choose a reason for hiding this comment

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

will this end up jarring the dropdown if someone has it open? could we do a replacement only on the items that need inserting or removal? are we instead ready to accept this rare glitch?

Copy link
Contributor

Choose a reason for hiding this comment

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

So, this is a valid concern, but with the upcoming code freeze this is not the right time to do something too clever.

If we edit a SP product and then immediately (before the widget-sync completes) reopen the dropdown, the worse that can happen is that the dropdown will disappear and reappear, which imho, is not like the highest priority bug ever. 😄

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I agree that a better reconciliation process between the server and the client would be better, but I'd rather add that later as janitorial task.

Copy link
Contributor

Choose a reason for hiding this comment

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

all good. I mainly want to make sure we're aware of the behaviors we're introducing and not be surprised by them later 👍

.append( $.map( data, function( product ) {
return $( '<option>', { value: product.ID, text: product.post_title } );
} ) )
.val( selectedProduct );
Copy link
Contributor

Choose a reason for hiding this comment

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

what does this line do? could we add a comment at the end tersely explaining what selectedProduct is here for and what its value will be?

Copy link
Contributor

Choose a reason for hiding this comment

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

The logic there is:

  • temporarily store the <select> selected product
  • empty the <select>
  • fill the <select> with the updated products
  • re-select the product that was selected before the switcheroo

I'm fine with over-documenting stuff, but in this particular case I'd say it's just a matter of remembering the good old days of yore when we were more used to look at jQuery code. 😄

Copy link
Contributor

Choose a reason for hiding this comment

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

I guess I'm getting lost even with the jQuery calls

the end() in the sequence is awkward since it's not at the end
the last .val( selectedProduct ) is also a bit puzzling to me since it gives me the impression that it's resetting the value of the select to the value polled in line 87R.

even quick explanation of what's being set to what in line 96R would go a long way.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

jQuery, known for it's awkwardness defines end() as:

End the most recent filtering operation in the current chain and return the set of matched elements to its previous state.

In this particular case, it ends the find filter operation by returning $select, where we can append the updated list of option elements and restore the selected value.

Copy link
Contributor

Choose a reason for hiding this comment

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

I won't say anymore after this 🤝 but I think that the fact that we have to refer to documentation and answer this here is indication that someone in the future is going to come in and have no idea what's going on when a single sentence or fragment could lead them in on it…


	.end() // end current operation and return original element
	
	.val( selectedProduct ); // and append into the original `<select>`

I clearly don't understand what I'm talking about, but I question whether the next person who comes around to this will either

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I've added a comment for the end call on 719071c9d9e5e62b0e6aa222ca02bd65be750518.

$select
.find( 'option' )
.remove()
.end() //cancels the find operation and returns the original <select /> element.
Copy link
Contributor

Choose a reason for hiding this comment

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

Let's make this into multiple statements, if folks are finding this difficult to read. eg

$select.find( 'option' ).remove();
$select.append( addOptions );
$select.val( selectedProduct );

Copy link
Contributor Author

Choose a reason for hiding this comment

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

updated on 8e8f21b55a67a7e0d97b8dcd51a2e1c1c0ac7fca.

@Copons
Copy link
Contributor

Copons commented Jun 26, 2018

This LGTM, although there's one thing that bugs me a little bit: we've got 3 ajax functions that start with the exact same checks:

  • check the nonce
  • check if the user can use the customizer
  • check if the user has enough capabilities to create and publish a SP (although, we don't check if the user can delete them!).

So, I'm wondering if we could move (in a follow up is good as well) these checks into their own separate methods. Something like:

private function user_can_do_simple_payments( $action = 'get' ) {
  if ( ! check_ajax_referer( 'customize-jetpack-simple-payments', 'customize-jetpack-simple-payments-nonce', false ) ) {
    return( array( 'bad_nonce', 400 ) );
  }

  if ( ! current_user_can( 'customize' ) ) {
    return( array( 'customize_not_allowed', 403 ) );
  }

  $post_type_object = get_post_type_object( Jetpack_Simple_Payments::$post_type_product );
  if (
    ( 'save' === $action && (
      ! current_user_can( $post_type_object->cap->create_posts ) ||
      ! current_user_can( $post_type_object->cap->publish_posts )
    ) ) ||
    ( 'delete' === $action && ! current_user_can( $post_type_object->cap->delete_posts ) )
  ) {
    return( array( 'insufficient_post_permissions', 403 ) );
  }

  return true;
}

// ...

public function ajax_save_payment_button() {
  $user_can = $this->user_can_do_simple_payments( 'save' );
  if ( $user_can !== true ) {
    wp_send_json_error( $user_can[0], $user_can[1] );
  }
  // ...
}

(this also needs rebasing!)

@rodrigoi rodrigoi force-pushed the add/simple-payments-widget-products-sync branch from 8e8f21b to 1c0b9e4 Compare June 26, 2018 15:08
@rodrigoi rodrigoi merged commit 1b216b8 into add/simple-payments-widget Jun 26, 2018
@rodrigoi rodrigoi deleted the add/simple-payments-widget-products-sync branch June 26, 2018 15:17
oskosk pushed a commit that referenced this pull request Jun 26, 2018
* Widgets: Adds support for Simple Payment Buttons as Widgets

* Simple Payments Widget: Add style overrides (#9580)

Override the media query and ensure that Simple Payments widgets are always displayed as a single column.

* Widgets: Only render the Simple Payments widget if its button exists (#9673)

In the frontend, only show the widget if the Simple Payments shortcode is parsed successfully.

In the customizer, show the widget regardless, so that it can be modified via the pencil icon.

* Simple Payment Widget: Manage Products from the Customizer (#9699)

* Customizer: Simple Payments Widget breaks when starting without products (#9809)

* Widgets: Hide Simple Payments create and edit buttons in widgets.php (#9811)

* Widgets: Record events for the Simple Payments widget (#9803)

* Widgets: Add Plan Check to the Simple Payments Widget (#9824)

* Customizer: keep Simple Payments Widget Customizer in sync between instances (#9814)

* Customizer: improves price validation on the Simple Payments Widget Customizer

* Customizer: improves the behaviour of the action buttons on the Simple Payments Widget Customizer
@dmsnell
Copy link
Contributor

dmsnell commented Jun 27, 2018

This LGTM, although there's one thing that bugs me a little bit: we've got 3 ajax functions that start with the exact same checks…So, I'm wondering if we could move (in a follow up is good as well) these checks into their own separate methods

ahhhh, looks like the start of discovering a hidden API semantic, looks like we are learning what kind of design needs we might have for the Simple Payments API 🤔 😉

@kraftbj kraftbj removed the [Status] Needs Review To request a review from Crew. Label will be renamed soon. label Sep 29, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
[Feature] Extra Sidebar Widgets [Feature] Pay with PayPal aka Simple Payments [Pri] High Touches WP.com Files [Type] Bug When a feature is broken and / or not performing as intended
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

8 participants