Impossible to overwrite checkout helper

  • Posts: 13
  • Thank you received: 0
3 years 2 months ago #328523

I created the overwrite class hikashopCheckoutHelperOverride correctly and it's loaded from templates/yootheme/html/com_hikashop/administrator/helpers/checkout.override.php

But the class hikashopCheckoutHelperOverride is not used because the code has direct calls to original class:

$checkoutHelper = hikashopCheckoutHelper::get();

And I can't declare my own hikashopCheckoutHelper class which should extend original hikashopCheckoutHelper

Please Log in or Create an account to join the conversation.

  • Posts: 81504
  • Thank you received: 13062
  • MODERATOR
3 years 2 months ago #328528

Hi,

Indeed if you want to extend from the original helper it's problematic. This class is called directly for some reasons on our end.
An easy solution would be to not extend from the original class and copy its code, but then, you might have issues in the future when updating.
Another solution could be to load the the content of the checkout.php helper file with file_get_contents, do a str_replace on the class name and then use exec on the string. That way, you dynamically rename the class name without directly modifying the core file.
Here are a page with different solutions to that problematic:
stackoverflow.com/questions/2658906/is-t...-class-safely-in-php
Using namespaces would be the cleanest solution I believe but I don't think it would be applicable in this situation.
Using runkit is interesting but it requires a special extension added to your PHP, so if your hosting doesn't have it, or you want to migrate to another hosting in the future where the extension is not available, it would be problematic.

Please Log in or Create an account to join the conversation.

  • Posts: 13
  • Thank you received: 0
3 years 2 months ago #328555

Just modify the get() method to load override:

	public static function get($cart_id = null) {
		if(self::$instance === null) {
			$classname = class_exists('hikashopCheckoutHelperOverride') ? 'hikashopCheckoutHelperOverride' : 'hikashopCheckoutHelper';
			self::$instance = new $classname($cart_id);
			self::$instance->config = hikashop_config();
			self::$instance->loadWorkflow();
		}
		return self::$instance;
	}

Last edit: 3 years 2 months ago by Denitz.

Please Log in or Create an account to join the conversation.

  • Posts: 81504
  • Thank you received: 13062
  • MODERATOR
3 years 2 months ago #328559

Hi,

That's a good proposition. We sure can add that for the next version of HikaShop.

Please Log in or Create an account to join the conversation.

  • Posts: 13
  • Thank you received: 0
3 years 2 months ago #328646

Thanks, but note that this method is not good: it caches instance created with or without $cart_id.
First call without $cart_id will cache instance without $cart_id, next call with $cart_id will return this cached instance without $cart_id.

It's unrelated to my proposition, just the current code is illogical.

Please Log in or Create an account to join the conversation.

  • Posts: 81504
  • Thank you received: 13062
  • MODERATOR
3 years 2 months ago #328651

Hi,

No worries. First, normally you only have one cart, the current cart. And thus no need to pass the cart_id.
It's only used for rare cases, like custom plugins, or HikaAuction to override the current cart to handle with another one.
And in that case, it's the same cart for the whole processing of the page since you only have one checkout interface per page.
So the cart that the initial instance is cached and provided regardless of what you supply the constructor is actually done on purpose so that once the checkout instance is initialized with the correct cart, regardless of whether other pieces of code have the correct cart_id, they will base themselves on the correct cart that the current page is handling.
Thank you for your concern.

Please Log in or Create an account to join the conversation.

Time to create page: 0.060 seconds
Powered by Kunena Forum