Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
23 changes: 22 additions & 1 deletion Block/ExpressCheckout/AbstractExpressCheckoutBlock.php
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,12 @@ abstract class AbstractExpressCheckoutBlock extends Template
* @var string|null
*/
private ?string $state = null;
/**
* Memoized merchant-configured button style blob for the current request.
*
* @var string|null
*/
private ?string $buttonStyle = null;

/**
* @param ScopeResolverInterface $scopeResolver
Expand Down Expand Up @@ -109,6 +115,18 @@ public function getUnavailableMessage(): string
return (string)__('SeQura is not available for your account.');
}

/**
* The merchant-configured button style blob, forwarded verbatim to the checkout library.
*
* @return string|null
*/
public function getButtonStyle(): ?string
{
$this->resolveState();

return $this->buttonStyle;
}

/**
* The storefront solicit URL the CDN-library button fetches (GET, raw HTML response).
*
Expand Down Expand Up @@ -161,7 +179,7 @@ private function resolveState(): string
? (string)$this->shippingResolver->getResolvableShippingCountry($quote)
: '';

$this->state = $this->availabilityEvaluator->evaluate(
$result = $this->availabilityEvaluator->evaluate(
(string)$this->_storeManager->getStore()->getId(),
$this->getExpressCheckoutPage(),
$isLoggedIn,
Expand All @@ -172,6 +190,9 @@ private function resolveState(): string
$this->getCartCategoryIds($quote)
);

$this->state = $result['state'];
$this->buttonStyle = $result['buttonStyle'];

return $this->state;
} catch (Exception $e) {
Logger::logError('Checking Express Checkout availability failed: ' . $e->getMessage() .
Expand Down
23 changes: 22 additions & 1 deletion Block/ExpressCheckout/ProductPage.php
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,12 @@ class ProductPage extends Template
* @var string|null
*/
private ?string $state = null;
/**
* Memoized merchant-configured button style blob for the current request.
*
* @var string|null
*/
private ?string $buttonStyle = null;
/**
* Memoized product for the current request (null also means "resolved to nothing").
*
Expand Down Expand Up @@ -109,6 +115,18 @@ public function isAvailable(): bool
return $this->resolveState() === AvailabilityEvaluator::STATE_BUTTON;
}

/**
* The merchant-configured button style blob, forwarded verbatim to the checkout library.
*
* @return string|null
*/
public function getButtonStyle(): ?string
{
$this->resolveState();

return $this->buttonStyle;
}

/**
* The viewed product's entity ID, for the JS controller.
*
Expand Down Expand Up @@ -171,7 +189,7 @@ private function resolveState(): string

// Always the guest (customer-agnostic) evaluation: the page is full-page cached, so
// the session is depersonalized during render and the HTML is shared by all shoppers.
$this->state = $this->availabilityEvaluator->evaluate(
$result = $this->availabilityEvaluator->evaluate(
(string)$this->_storeManager->getStore()->getId(),
ExpressCheckoutPage::product()->getPage(),
false,
Expand All @@ -182,6 +200,9 @@ private function resolveState(): string
$this->getProductCategoryIds($product)
);

$this->state = $result['state'];
$this->buttonStyle = $result['buttonStyle'];

return $this->state;
} catch (Exception $e) {
Logger::logError('Checking Express Checkout availability for product failed: ' . $e->getMessage() .
Expand Down
47 changes: 27 additions & 20 deletions Model/ExpressCheckout/AvailabilityEvaluator.php
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ class AvailabilityEvaluator
* @param string[] $productIds Product entity IDs in context.
* @param string[] $categoryIds Category IDs in context.
*
* @return string One of self::STATE_*.
* @return array{state: string, buttonStyle: string|null} State is one of self::STATE_*.
*/
public function evaluate(
string $storeId,
Expand All @@ -59,7 +59,7 @@ public function evaluate(
string $ipAddress,
array $productIds,
array $categoryIds
): string {
): array {
try {
if ($isLoggedIn) {
/** @var ExpressCheckoutAvailabilityResponse $response */
Expand All @@ -73,31 +73,38 @@ public function evaluate(
$categoryIds
)
);

$available = $response->isSuccessful() && !empty($response->toArray()['available']);

return $available ? self::STATE_BUTTON : self::STATE_MESSAGE;
$unavailableState = self::STATE_MESSAGE;
} else {
/** @var GuestExpressCheckoutAvailabilityResponse $response */
$response = CheckoutAPI::get()->expressCheckout($storeId)->isAvailableForGuest(
new GuestExpressCheckoutAvailabilityRequest(
$page,
$currency,
$ipAddress,
$productIds,
$categoryIds
)
);
$unavailableState = self::STATE_HIDDEN;
}

/** @var GuestExpressCheckoutAvailabilityResponse $response */
$response = CheckoutAPI::get()->expressCheckout($storeId)->isAvailableForGuest(
new GuestExpressCheckoutAvailabilityRequest(
$page,
$currency,
$ipAddress,
$productIds,
$categoryIds
)
);
$data = $response->toArray();
$buttonStyle = $data['buttonStyle'] ?? null;

return ($response->isSuccessful() && !empty($response->toArray()['available']))
? self::STATE_BUTTON
: self::STATE_HIDDEN;
return [
'state' => ($response->isSuccessful() && !empty($data['available']))
? self::STATE_BUTTON
: $unavailableState,
'buttonStyle' => is_string($buttonStyle) ? $buttonStyle : null,
];
} catch (Exception $e) {
Logger::logError('Checking Express Checkout availability failed: ' . $e->getMessage() .
' Trace: ' . $e->getTraceAsString());

return self::STATE_HIDDEN;
return [
'state' => self::STATE_HIDDEN,
'buttonStyle' => null,
];
}
}
}
2 changes: 1 addition & 1 deletion composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@
"prefer-stable": true,
"require": {
"php": ">=7.4 <8.6",
"sequra/integration-core": "v5.5.0",
"sequra/integration-core": "v5.7.0",
"ext-json": "*"
},
"autoload": {
Expand Down
4 changes: 4 additions & 0 deletions view/frontend/templates/express/cart.phtml
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,13 @@
/** @var \Magento\Framework\Escaper $escaper */

if ($block->isAvailable()):
$buttonStyle = (string)$block->getButtonStyle();
?>
<div class="sequra-express-checkout" data-role="sequra-express-checkout">
<div class="sequra-express-checkout-button"
<?php if ($buttonStyle !== ''): ?>
data-button-style="<?= $escaper->escapeHtmlAttr($buttonStyle); ?>"
<?php endif; ?>
data-url="<?= $escaper->escapeHtmlAttr($block->getSolicitUrl()); ?>"></div>
</div>
<script type="text/x-magento-init">
Expand Down
4 changes: 4 additions & 0 deletions view/frontend/templates/express/minicart.phtml
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
/** @var \Magento\Framework\Escaper $escaper */

if ($block->isAvailable()):
$buttonStyle = (string)$block->getButtonStyle();
?>
<?php // data-mage-init (not x-magento-init): the markup is re-injected by the Knockout
// mini-cart on every `cart` section refresh, and only attribute-form init re-runs
Expand All @@ -12,6 +13,9 @@ if ($block->isAvailable()):
data-mage-init='{"Sequra_Core/js/express/cart-express": {}}'
data-availability-url="<?= $escaper->escapeHtmlAttr($block->getAvailabilityUrl()); ?>">
<div class="sequra-express-checkout-button"
<?php if ($buttonStyle !== ''): ?>
data-button-style="<?= $escaper->escapeHtmlAttr($buttonStyle); ?>"
<?php endif; ?>
data-url="<?= $escaper->escapeHtmlAttr($block->getSolicitUrl()); ?>"></div>
</div>
<?php
Expand Down
4 changes: 4 additions & 0 deletions view/frontend/templates/express/product.phtml
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,15 @@

if ($block->isAvailable()):
$solicitUrl = $block->getProductSolicitUrl() . '?product=' . $block->getProductId() . '&qty=1';
$buttonStyle = (string)$block->getButtonStyle();
?>
<div class="sequra-express-checkout sequra-express-checkout--product sequra-express-checkout--disabled"
data-role="sequra-express-checkout-product">
<div class="sequra-express-checkout-button"
data-amount="0"
<?php if ($buttonStyle !== ''): ?>
data-button-style="<?= $escaper->escapeHtmlAttr($buttonStyle); ?>"
<?php endif; ?>
data-url="<?= $escaper->escapeHtmlAttr($solicitUrl); ?>"></div>
</div>
<script type="text/x-magento-init">
Expand Down