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

Allow custom extensions on backend and frontend #416

Open
neekfenwick opened this issue Jun 6, 2024 · 4 comments
Open

Allow custom extensions on backend and frontend #416

neekfenwick opened this issue Jun 6, 2024 · 4 comments

Comments

@neekfenwick
Copy link

I have half an idea and am wondering how to solve the other half, maybe you can help me out on the Javascript side.

When a customer selects a specific payment method in our store, we want to show a warning message next to the Submit button on One Page Checkout. Normally, changing payment method calls zcAjaxOnePageCheckout::updatePaymentMethod, which returns an array of data containing order_totals output, error message etc. My hack solution so far is:

  1. Add a show_submit_message element to the array returned from updatePaymentMethod depending on the value of $_SESSION['payment'], containing the message to show.
  2. Modify jquery.checkout_one.js response handler from calling updatePaymentMethod to check the returned object for show_submit_message and add a <div> if it's present.
  3. Some CSS shenanigans too, because the container of the submit button is float:right and adding a <div> there causes the submit button to left align in that floated container meaning it jumps to the left of the page.

A simple solution on the PHP side is to add a $this->notify() call near the end of updatePaymentMethod so an observer can modify the returned array. This would be one code modification to this project. My problem comes on the Javascript side. What is the correct way to introduce custom behaviour hooks to the javascript code, similar to NotifierManager?

A quick look tells me I could use Ajax Events https://api.jquery.com/Ajax_Events/ to add a hook function to every request, and inspect each one for updatePaymentMethod, but this seems pretty clumsy.

Is there a more elegant way in jQuery?

@lat9
Copy link
Owner

lat9 commented Jun 6, 2024

Interesting idea, @neekfenwick. I'll give that additional thought over the weekend and see if I can provide some possibilities.

@neekfenwick
Copy link
Author

Interesting idea, @neekfenwick. I'll give that additional thought over the weekend and see if I can provide some possibilities.

With the Dojo framework I'm used to having two eventing mechanisms, either 1/ a class you're developing can extend from Evented (https://dojotoolkit.org/reference-guide/1.9/dojo/Evented.html) and call emit(...) on itself, so other JS can subscribe to events with "thing.on(..., handlerFn)" or 2/ a global message bus they call the Topic bus (https://dojotoolkit.org/reference-guide/1.9/dojo/topic.html) where you can subscribe to events on a global object topic.on(topicName, handlerFn) and other code can publish to that global channel with topic.publish(topicName, ....).

I can't see a similar centralised event bus in jQuery, the closest I can see is to use trigger() (https://api.jquery.com/trigger/) on the document object and subscribe to it elsewhere, e.g. my quick codepen This approach wouldn't bubble the event more than necessary but it still seems fairly clumsy. Would be nice to have an event system disconnected from the DOM.

@neekfenwick
Copy link
Author

@lat9 Just wanted to mention another point where I find a modification is required in my case. Not everything can be done via the Ajax handler, some more work needs doing on initial page load in the PHP.

When the checkout_one page first loads, there may be a $_SESSION['payment'] already defined (for example, second time through the checkout process after selecting a payment method first time round), and in my case I need to get my warning message on screen immediately. As the page loads, there is no ajax call made such as updatePaymentMethod, so something in the header_php.php and main page needs a chance to react.

Near the end of header_php.php the code inspects $_SESSION['payment'], so I'm adding a notifier call there, exactly the same as the notifier call made in updatePaymentMethod Ajax handler:

$zco_notifier->notify(
    'NOTIFY_CHECKOUT_ONE_CHECK_PAYMENT',
    $_SESSION['payment'],
    $paymentSubmitData);

In this way, the header and the Ajax handler both trigger the same observer, to get whatever data is required about the payment method.

This new variable $paymentSubmitMessage is then used in tpl_modules_opc_submit_block.php to create a message <div> and optionally fill it with an initial message. This same message node can be used to update the message in the updatePaymentMethod Ajax handler.

So, the PHP code now needs to have explicit knowledge of a message DOM node, instead of my first implementation which dynamically created the message DOM node in response to the Ajax call. But, this message node is not used at all by the core addon, it's only given a message to display by my custom observer responding to NOTIFY_CHECKOUT_ONE_CHECK_PAYMENT.

The changes are getting more intrusive than I first thought, more core modifications to the addon, so you may want to have some input.

@lat9
Copy link
Owner

lat9 commented Jun 21, 2024

Noting that the checkout_one page already issues the notification NOTIFY_HEADER_END_CHECKOUT_ONE at the end of its processing, giving an observer a chance to do the above check.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants