Evaluation result types
Hyvä Checkout offers a comprehensive selection of evaluation result types by default, ranging from basic messaging results to more sophisticated combinations. These include the capability to inject executable code directly into the navigation process, enabling specific JavaScript actions when users attempt to navigate forward or place an order.
The API is intentionally crafted to empower developers, providing them with the flexibility to create their own custom evaluation result types to meet unique requirements.
Batch
Available since Hyvä Checkout 1.1.13
- Class: \Hyva\Checkout\Model\Magewire\Component\Evaluation\Batch
- Frontend processor: batch
- Capabilities: N/A
As the name implies, a batch result is capable of containing multiple results, all of which will be processed on the frontend. There's no restriction on the number of result types a batch can carry. Batches operate akin to arrays and offer various functions to traverse, push, or merge new results into them. Utilizing a batch result is advisable as it facilitates the injection of additional functionality by others if needed.
<?php
class Foo extends \Magewirephp\Magewire\Component implements \Hyva\Checkout\Model\Magewire\Component\EvaluationInterface
{
public function evaluateCompletion(EvaluationResultFactory $resultFactory): EvaluationResult
{
$batch = $resultFactory->createBatch(
[
$resultFactory->createErrorMessage()
->withMessage('Something went wrong.')
->asWarning(),
$resultFactory->createEvent()
->withCustomEvent('my-batch-event')
->dispatch()
]
);
// Example on how to push additional result types.
if (false === $component->getEvaluationResultBatch()->owns(fn ($value) => $value instanceof Redirect)) {
$batch->clear()->push($resultFactory->createRedirect('https://hyva.io/hyva-checkout.html')
->withNotificationDialog()
->withNotificationMessage('You\'re being redirected to the Hyvä Checkout product page.')
->withTimeout(2500)
);
}
return $batch;
}
}
This example begins by creating a batch containing both a warning message and a JavaScript window event, both of which will be immediately dispatched.
Desire seamless access to the result factory without the need for manual injection?
You can achieve this by accessing a batch result. Within the batch result, there's a method named getFactory()
, which provides access to the factory instance for creating various other result types.
Blocking
- Class: \Hyva\Checkout\Model\Magewire\Component\Evaluation\Blocking
- Frontend processor: blocking
- Capabilities: Details, Blocking, Dispatch
Utilize a blocking result to completely disable all primary navigation buttons, preventing processes such as additional navigation tasks or validations from being triggered. However, be mindful that using this result from the user's perspective can potentially cause confusion. It's imperative to provide clear instructions to end-users, explaining what actions they need to take before they can proceed with navigating forward or placing an order. Additional information should be provided to ensure clarity and guide users effectively.
Use With Caution
Additional care must be taken when choosing to return a Blocking
result as there is currently no automated
mechanism by which to unblock the checkout - this can only be achieved by satisfying the criteria for the components
evaluateCompletion()
function to return a Success
result or by manually invoking the unblocking via the frontend
API.
Consider the example of a payment method which returns a Blocking
result until the customer has authorised their
payment. Upon selecting that payment method, the checkout becomes blocked. If the customer is unable to authorise
their payment for any reason, they are then unable to complete their purchase even if they are to select an
alternative payment method due to this Blocking
result not being unset.
To simplify your implementation, it is generally advised to avoid returning a Blocking
result in favour of an
ErrorMessage
result instead. The effects of preventing the customer from progressing through the checkout and
displaying an informative error message are maintained but without the need to conceive of every scenario where you
will have to handle the manual unblocking of the checkout.
<?php
class Foo extends \Magewirephp\Magewire\Component implements \Hyva\Checkout\Model\Magewire\Component\EvaluationInterface
{
public function evaluateCompletion(EvaluationResultFactory $resultFactory): EvaluationResult
{
return true ? $resultFactory->createBlocking() : $resultFactory->createSuccess();
}
}
Custom
Available since Hyvä Checkout 1.1.13
- Class: \Hyva\Checkout\Model\Magewire\Component\Evaluation\Custom
- Frontend processor: N/A
- Capabilities: Details, Blocking, Dispatch
If you exclusively have a frontend processor, consider utilizing a custom result type. By default, a custom result type encompasses all the necessary capabilities for dispatching, blocking, and adding additional details.
<?php
class Foo extends \Magewirephp\Magewire\Component implements \Hyva\Checkout\Model\Magewire\Component\EvaluationInterface
{
public function evaluateCompletion(EvaluationResultFactory $resultFactory): EvaluationResult
{
return $resultFactory->createCustom('foo')
->withDetails(['alert' => 'Something went wrong.']);
}
}
<script>
// Ensure that the evaluation API is fully initialized.
window.addEventListener('checkout:init:evaluation', () => {
// Register evaluation processor "foo".
hyvaCheckout.evaluation.registerProcessor('foo', (component, el, result) => {
alert(result.arguments.details.alert);
return result.result;
});
});
</script>
Register custom evaluation processors
To register a custom processor, you can add a .phtml file to the DOM via layout XML. Multiple designated locations
are available to ensure the custom processor is positioned correctly depending on the required hyvaCheckout
APIs.
The recommended practice is to inject your custom .phtml via layout handle hyva_checkout_index_index
with a
container preference of hyva.checkout.init-evaluation.after
.
Each API has its own after
container, ensuring custom code can be injected after its parent API.
For further information, please refer to view/frontend/layout/hyva_checkout_index_index.xml
.
ErrorMessage
- Class: \Hyva\Checkout\Model\Magewire\Component\Evaluation\ErrorMessage
- Frontend processor: message
- Capabilities: Blocking, Messaging, Dispatch
Utilize an error message either directly or during component validation.
<?php
class Foo extends \Magewirephp\Magewire\Component implements \Hyva\Checkout\Model\Magewire\Component\EvaluationInterface
{
public bool $dispatch = false;
public bool $successful = true;
public ?int $duration = null;
public function evaluateCompletion(EvaluationResultFactory $resultFactory): EvaluationResult
{
$message = $resultFactory->createErrorMessage('Something went wrong');
if ($this->dispatch) {
$message->dispatch();
}
if ($this->successful) {
$message->asCustomType('success');
}
if ($this->duration) {
$message->withVisibilityDuration($this->duration);
}
return $message;
}
}
This example initially throws a flash error message with options to be dispatched immediately, served as a success message and/or requiring a certain visibility duration, after which it will automatically be hidden.
Event
- Class: \Hyva\Checkout\Model\Magewire\Component\Evaluation\ErrorMessage
- Frontend processor: message
- Extends: ErrorMessageEvent, ErrorEvent, Success
- Capabilities: Details, Dispatch
In addition to its function as an event shell, the Event result type also extends ErrorMessageEvent
and ErrorEvent
.
The latter two provide specific markup required for error events and message events, enhancing their functionality.
<?php
class Foo extends \Magewirephp\Magewire\Component implements \Hyva\Checkout\Model\Magewire\Component\EvaluationInterface
{
public function evaluateCompletion(EvaluationResultFactory $resultFactory): EvaluationResult
{
// Can be caught with window.addEventListener('my-custom-event', event => {})
return $resultFactory->createEvent()
->withCustomEvent('my-custom-event')
->dispatch();
// Dispatch a custom window event with a specific message markup containing the message and its type.
return $resultFactory->createErrorMessageEvent()
->withCustomEvent('my-error-event')
->withMessage('Something went wrong')
->dispatch();
// Dispatch a custom window event with a false result and stick it onto the validation API by default.
return $resultFactory->createErrorEvent()
->withCustomEvent('my-custom-event');
}
}
Executable
Available since Hyvä Checkout 1.1.13
- Class: \Hyva\Checkout\Model\Magewire\Component\Evaluation\Executable
- Frontend processor: executable
- Capabilities: Dispatch
Utilize an executable, either in combination with the NavigationTask result type or independently, when you need a specific piece of code to be executed on the frontend. An executable can be thought of as a regular method that can receive its own argument parameters, which are set from the backend.
<?php
class Foo extends \Magewirephp\Magewire\Component implements \Hyva\Checkout\Model\Magewire\Component\EvaluationInterface
{
public function evaluateCompletion(EvaluationResultFactory $resultFactory): EvaluationResult
{
$executable = $resultFactory->createExecutable('custom-modal')
->withParams(['buttons' => ['confirm', 'cancel']]);
// Dispatch the executable immediately.
return $executable->withParam('title' => 'My Modal');
// Attach the executable to the navigation and trigger it only when a customer attempts to navigate.
return $resultFactory->createNavigationTask('foo', $executable)
}
}
To utilize an executable, it must be registered with a specific name and can function as either asynchronous or synchronous.
<script>
// Ensure that the evaluation API is fully initialized.
window.addEventListener('checkout:init:evaluation', () => {
// Open a modal after 5 seconds, including fetched data from an external API.
hyvaCheckout.evaluation.registerExecutable('custom-modal', async (result, el, component) => {
return new Promise(resolve => setTimeout(() => {
fetch('https://api.example.extension/random').then(result => {
// Custom logic to open a modal goes here.
})
resolve()
}, 5000))
})
})
</script>
NavigationTask
Available since Hyvä Checkout 1.1.13
- Class: \Hyva\Checkout\Model\Magewire\Component\Evaluation\NavigationTask
- Frontend processor: navigation_task
- Capabilities: Dispatch, Stacking
Incorporating a navigation task serves the purpose of delaying specific JavaScript-driven actions until the customer
chooses to advance to the subsequent step or place an order. These tasks remain pending until the customer clicks the
designated navigation button, upon which they are executed sequentially based on their assigned position (defaulted to 500
).
Consider, for instance, address form data that no other component depends on but still requires preservation. This approach negates the need for implementing an auto-save feature, as the navigation mechanism handles data retention when necessary.
A navigation task encompasses any type of evaluation result, which, if dispatchable, will be automatically handled for you.
It also possesses the capability to be assigned after the successful loading of the next step or the completion of the order.
<?php
class Foo extends \Magewirephp\Magewire\Component implements \Hyva\Checkout\Model\Magewire\Component\EvaluationInterface
{
public function evaluateCompletion(EvaluationResultFactory $resultFactory): EvaluationResult
{
$task = $resultFactory->createErrorMessage()
->withMessage('Welcome to the next step.')
->asCustomType('success');
// "fooCustomNavigationTask" will serve as the identifier for the navigation task on the frontend.
return $resultFactory->createNavigationTask('fooCustomNavigationTask', $task)->executeAfter();
}
}
This eventually manifests as an error message, presented as a success-type flash message at the top of the screen. This occurs either after the customer proceeds to the second page or after placing the order, prior to any redirection. For example, you might display a modal through an asynchronous Executable, ensuring navigation waits until the modal is resolved. Since the Redirect result is positioned late in the task stack, it permits other tasks to execute beforehand.
Redirect
Available since Hyvä Checkout 1.1.13
- Class: \Hyva\Checkout\Model\Magewire\Component\Evaluation\Redirect
- Frontend processor: redirect
- Capabilities: Dispatch, Stacking
A particularly valuable result type for payment vendors is the redirect option, which enables them to seamlessly redirect the customer to their external payment solution either just before or immediately after the order has been placed. This redirect functionality includes a modal that can optionally appear as a notification dialog. Alternatively, developers have the option to present a confirmation dialog to the customer, featuring both cancel and confirm buttons.
These options can be configured within the redirect system settings, allowing system administrators to enforce confirmation dialogs for all redirects, even if developers choose not to attach them initially.
<?php
class Foo extends \Magewirephp\Magewire\Component implements \Hyva\Checkout\Model\Magewire\Component\EvaluationInterface
{
public function evaluateCompletion(EvaluationResultFactory $resultFactory): EvaluationResult
{
$task = $resultFactory->createRedirect('https://hyva.io/hyva-checkout.html');
return $resultFactory->createNavigationTask('foo', $task)->executeAfter();
}
}
Success
- Class: \Hyva\Checkout\Model\Magewire\Component\Evaluation\Success
- Frontend processor: event
- Capabilities: Details, Dispatch
Although Success is simply a standard Event result type, it holds significance as it is the primary type used, particularly
for clearing a component and marking it as completed. In addition to dispatching a success result for the component,
which proves valuable on the frontend, it also returns a true
result, indicating the component's completion status.
It's important to note that other result types, such as a custom one returning a true
result, will also function effectively.
However, we provide a standardized type to streamline these common functionalities for your convenience.
<?php
class Foo extends \Magewirephp\Magewire\Component implements \Hyva\Checkout\Model\Magewire\Component\EvaluationInterface
{
public bool $success = true;
public function evaluateCompletion(EvaluationResultFactory $resultFactory): EvaluationResult
{
if ($this->success) {
return $resultFactory->createSuccess();
}
return $resultFactory->createErrorMessage()
->withMessage('Please mark this component as completed.')
->asInformally()
->dispatch()
}
}
Validation
Available since Hyvä Checkout 1.1.13
- Class: \Hyva\Checkout\Model\Magewire\Component\Evaluation\Validation
- Frontend processor: validation
- Capabilities: Stacking, Details
The validate result type is tightly integrated with the frontend Validation API, offering developers the flexibility to
inject custom validation logic onto primary navigation buttons. This validation occurs after navigation tasks have been
successfully fulfilled. Functionally, a validation result behaves similarly to a NavigationTask, with the main distinction
being that the registered callback serves as a validator. Additionally, developers have the option to specify another result type,
such as ErrorMessage, to handle failure scenarios automatically. This can be achieved using the withFailureResult
method.
<?php
class Foo extends \Magewirephp\Magewire\Component implements \Hyva\Checkout\Model\Magewire\Component\EvaluationInterface
{
public function evaluateCompletion(EvaluationResultFactory $resultFactory): EvaluationResult
{
// Reflects one of the tree register validators on the frontend.
$validator = ['a', 'b', 'c'][random_int(0, 2)];
return $resultFactory->createValidation($validator)
->withFailureResult($resultFactory->createErrorMessage()
->withMessage(sprintf('Validator "%s" failed.'))
->dispatch()
);
}
}
To utilize a validation, it must be registered with a specific name and can function as either asynchronous or synchronous.
<script>
window.addEventListener('checkout:init:evaluation', () => {
// Fails validation immediately.
hyvaCheckout.evaluation.registerValidator('a', (element, component) => {
throw new Error('Foo')
})
// Successful validation after 2.5 seconds.
hyvaCheckout.evaluation.registerValidator('b', async (element, component) => {
return new Promise(resolve => setTimeout(() => resolve(true), 2500))
})
// Rejects and fails validation after 2.5 seconds.
hyvaCheckout.evaluation.registerValidator('c', async (element, component) => {
return new Promise((resolve, reject) => setTimeout(() => reject(), 2500))
})
})
</script>
Register custom validator
To register a custom validator, you can add a .phtml file to the DOM via layout XML. Multiple designated locations
are available to ensure the custom processor is positioned correctly depending on the required hyvaCheckout
APIs.
The recommended practice is to inject your custom .phtml via layout handle hyva_checkout_index_index
with a
container preference of hyva.checkout.init-evaluation.after
.
Each API has its own after
container, ensuring custom code can be injected after its parent API.
For further information, please refer to view/frontend/layout/hyva_checkout_index_index.xml
.
EvaluationResult (abstract)
Available since Hyvä Checkout 1.1.13
For checkout versions before 1.1.13, every evaluation result type mandates an implementation of Hyva\Checkout\Model\Magewire\Component\EvaluationResultInterface
.
However, starting from version 1.1.13, this interface has been deprecated and replaced with \Hyva\Checkout\Model\Magewire\Component\Evaluation\EvaluationResult
.
Every core evaluation result type builds upon the EvaluationResult abstraction, ensuring that all necessary requirements are fulfilled. The recommended approach is to extend custom results from this abstraction, adhering to best practices.
<?php
namespace My\Module\Model\Magewire\Component\Evaluation;
class Foo extends \Hyva\Checkout\Model\Magewire\Component\Evaluation\EvaluationResult
{
public const TYPE = 'foo';
public function getArguments(Component $component): array
{
return [];
}
// Alternative for defining a TYPE constant.
public function getType(): string
{
return 'foo';
}
}