diff --git a/docs/manual/developer/hooks/_index.en.md b/docs/manual/developer/hooks/_index.en.md index b7b80a9..0fd2e70 100644 --- a/docs/manual/developer/hooks/_index.en.md +++ b/docs/manual/developer/hooks/_index.en.md @@ -80,7 +80,7 @@ This is a list of all hooks available in isotope (as of version 2.8): - calculatePrice - collectionLocked - compileCart -- convertCurrency +- [convertCurrency](convertCurrency) - copiedCollectionItems - copyCollectionItem - createFromProductCollection @@ -95,13 +95,13 @@ This is a list of all hooks available in isotope (as of version 2.8): - generateFilters - generateOrderLog - [generateProduct](generateProduct) -- generateProductList +- [generateProductList](generateProductList) - getAllowedProductIds - getOrderConditionsValue -- getOrderNotificationTokens +- [getOrderNotificationTokens](getOrderNotificationTokens) - initializePostsale - itemIsAvailable -- modifyAddressFields +- [modifyAddressFields](modifyAddressFields) - [postAddProductToCollection](postAddProductToCollection) - [postCheckout](postCheckout) - postDeleteCollection @@ -118,4 +118,4 @@ This is a list of all hooks available in isotope (as of version 2.8): - updateDraftOrder - [updateItemInCollection](updateItemInCollection) - updateProductInCollection -- useTaxRate \ No newline at end of file +- useTaxRate diff --git a/docs/manual/developer/hooks/convertCurrency/_index.en.md b/docs/manual/developer/hooks/convertCurrency/_index.en.md new file mode 100644 index 0000000..76f115a --- /dev/null +++ b/docs/manual/developer/hooks/convertCurrency/_index.en.md @@ -0,0 +1,74 @@ +--- +title: "convertCurrency" +--- + +The `convertCurrency` hook will be triggered if your [store configuration](/en/backend-configuration/store-configuration/general-settings/configuration/#currency-conversion) +uses custom currency conversion provider (i.e. other than `ecb.int` or `admin.ch` that Isotope ships by default). +This hook will be triggered by Isotope Automator according to cronjob schedule (`daily` by default), +and this is where you should pull the up-to-date exchange rate and save it to the database. + +## Parameter + +1. \Isotope\Model\Config `$config` + + The instance of the `Config` model. The hook is called once for each store config that + has custom provider set up. + +## Example + +```php +// contao/config/config.php +$GLOBALS['TL_DCA']['tl_iso_config']['fields']['currencyProvider']['options'][] = 'cbr_ru'; +``` + +```php +// src/EventListener/Isotope/ConvertCurrencyListener.php +namespace App\EventListener\Isotope; + +use Isotope\Model\Config; +use Isotope\ServiceAnnotation\IsotopeHook; +use Psr\Log\LoggerInterface; +use Symfony\Contract\HttpClient\HttpClientInterface; + +/** + * @IsotopeHook("convertCurrency") + */ +class ConvertCurrencyListener +{ + private HttpClientInterface $client; + private LoggerInterface $logger; + + public function __construct(HttpClientInterface $client, LoggerInterface $contaoErrorLogger) { + $this->client = $client; + $this->logger = $contaoErrorLogger; + } + + public function __invoke(Config $config): void + { + // Query custom exchange rate provider + if ('cbr_ru' != $config->currencyProvider) { + return; + } + + try { + $response = $this->client->request('GET', 'https://www.cbr.ru/scripts/XML_daily.asp'); + } catch (\Exception $e) { + $this->logger->error('Error retrieving data from cbr.ru: ' . $e->getMessage()); + + return; + } + + // Process API response... + $fltCourse = ...; + $fltCourseOrigin = ...; + + // Save updated exchange rate + $config->priceCalculateFactor = round($fltCourse / $fltCourseOrigin, 10); + $config->save(); + } +} +``` + +## References + +* [\Isotope\Automator#L170-L177](https://github.com/isotope/core/blob/2.8/system/modules/isotope/library/Isotope/Automator.php#L170-L177) diff --git a/docs/manual/developer/hooks/generateProduct/_index.en.md b/docs/manual/developer/hooks/generateProduct/_index.en.md index b304134..937a2e1 100644 --- a/docs/manual/developer/hooks/generateProduct/_index.en.md +++ b/docs/manual/developer/hooks/generateProduct/_index.en.md @@ -10,7 +10,7 @@ The `generateProduct` hook is called when the product page (reader) is rendered. The template object. -1. \Isotope\Interfaces\IsotopeProduct `$product` +2. \Isotope\Interfaces\IsotopeProduct `$product` The product model. diff --git a/docs/manual/developer/hooks/generateProductList/_index.en.md b/docs/manual/developer/hooks/generateProductList/_index.en.md new file mode 100644 index 0000000..89bca78 --- /dev/null +++ b/docs/manual/developer/hooks/generateProductList/_index.en.md @@ -0,0 +1,67 @@ +--- +title: "generateProductList" +--- + +The `generateProductList` hook is called when the product list page is rendered. +It can be used to add custom context variables to the products list page, filter +rendered products or even to modify parsed HTML directly. + +## Parameters + +1. array `$buffer` + + Array that holds information used to render each product in the list. + Array items have the following shape: + + ```php + [ + 'cssID' => '', // HTML "id" attribute + 'class' => '', // HTML "class" attribute + 'html' => '', // parsed product template (iso_reader_default.html5) + 'product' => \Isotope\Model\Product // product model + ] + ``` + +2. array `$products` + + Array of product models. + +3. \Contao\Template `$template` + + Frontend template instance that is used to render `mod_iso_productlist` template. + +4. \Isotope\Module\ProductList `$module` + + Instance of `ProductList` frontend module. + +## Return values + +Return the `$buffer` array. + +## Example + +```php +// src/EventListener/Isotope/GenerateProductListListener.php +namespace App\EventListener\Isotope; + +use Contao\Template; +use Isotope\Module\ProductList; +use Isotope\ServiceAnnotation\IsotopeHook; + +/** + * @IsotopeHook("generateProductList") + */ +class GenerateProductListListener +{ + public function __invoke(array $buffer, array $products, Template $template, ProductList $module): array + { + // Do something ... + + return $buffer; + } +} +``` + +## References + +* [\Isotope\Module\ProductList#L286-L293](https://github.com/isotope/core/blob/2.8/system/modules/isotope/library/Isotope/Module/ProductList.php#L286-L293) diff --git a/docs/manual/developer/hooks/getOrderNotificationTokens/_index.en.md b/docs/manual/developer/hooks/getOrderNotificationTokens/_index.en.md new file mode 100644 index 0000000..2e0c1c7 --- /dev/null +++ b/docs/manual/developer/hooks/getOrderNotificationTokens/_index.en.md @@ -0,0 +1,53 @@ +--- +title: "getOrderNotificationTokens" +--- + +The `getOrderNotificationTokens` hook is invoked each time when order notifications +are triggered, for instance on checkout or order status update. It can be used to +update the values of [simple tokens](/en/simple-tokens) or add custom ones. + + +## Parameters + +1. Isotope\Model\ProductCollection\Order `$order` + + The order object. + +2. array `$tokens` + + The notification center tokens. + +## Return values + +Return array of notification tokens with their values + +## Example + +```php +// src/EventListener/Isotope/PostAddProductToCollectionListener.php +namespace App\EventListener\Isotope; + +use Isotope\Model\ProductCollection\Order; +use Isotope\ServiceAnnotation\IsotopeHook; + +/** + * @IsotopeHook("postAddProductToCollection") + */ +class PostAddProductToCollectionListener +{ + public function __invoke(Order $order, array $tokens): array + { + // Add ##first_product## token that displays the name of the first product in cart + $products = $order->getItems(); + $firstProduct = reset($products); + + $tokens['first_product'] = $firstProduct->getName(); + + return $tokens; + } +} +``` + +## References + +* [\Isotope\Model\ProductCollection\Order#L545-L552](https://github.com/isotope/core/blob/2.8/system/modules/isotope/library/Isotope/Model/ProductCollection/Order.php#L545-L552) diff --git a/docs/manual/developer/hooks/modifyAddressFields/_index.en.md b/docs/manual/developer/hooks/modifyAddressFields/_index.en.md new file mode 100644 index 0000000..0625904 --- /dev/null +++ b/docs/manual/developer/hooks/modifyAddressFields/_index.en.md @@ -0,0 +1,60 @@ +--- +title: "modifyAddressFields" +--- + +The `modifyAddressFields` hook is triggered by "Billing Address" and "Shipping Address" +checkout steps. Each checkout step triggers the hook twice – first when address form is +being rendered, then upon submit when fields are validated. + +It can be used to modify fields configuration, add or remove fields, or do something with +the submitted values. + +## Parameters + +1. array `$fields` + + Array of form fields configurations (similar to DCA). + +2. \Isotope\Model\Address `$address` + + Instance of the Address model. + +3. string `$class` + + Standardized version of the current CheckoutStep class, that can be used in CSS context, + e.g. `'billingaddress'` + +## Return value + +Return the `$fields` array. + +## Example + +```php +// src/EventListener/Isotope/ModifyAddressFieldsListener.php +namespace App\EventListener\Isotope; + +use Contao\Input; +use Isotope\Model\Address; +use Isotope\ServiceAnnotation\IsotopeHook; + +/** + * @IsotopeHook("modifyAddressFields") + */ +class ModifyAddressFieldsListener +{ + public function __invoke(array $fields, Address $address, string $class): array + { + // Normalize email addresses to lower-case form + if (Input::post('FORM_SUBMIT') === 'iso_mod_checkout_billingaddress') { + Input::setPost('billingaddress_email', strtolower(Input::post('billingaddress_email'))); + } + + return $fields; + } +} +``` + +## References + +* [\Isotope\CheckoutStep\Address#L238-L245](https://github.com/isotope/core/blob/2.8/system/modules/isotope/library/Isotope/CheckoutStep/Address.php#L238-L245) diff --git a/docs/manual/developer/hooks/postCheckout/_index.en.md b/docs/manual/developer/hooks/postCheckout/_index.en.md index dab11c8..65722aa 100644 --- a/docs/manual/developer/hooks/postCheckout/_index.en.md +++ b/docs/manual/developer/hooks/postCheckout/_index.en.md @@ -3,6 +3,8 @@ title: "postCheckout" --- The `postCheckout` hook is called after the checkout process is finished. +It can be used e.g. to store additional information about the order, process +analytics etc. ## Parameters @@ -23,15 +25,37 @@ namespace App\EventListener\Isotope; use Isotope\Model\ProductCollection\Order; use Isotope\Module\Checkout; use Isotope\ServiceAnnotation\IsotopeHook; +use MailchimpMarketing\ApiClient; /** * @IsotopeHook("postCheckout") */ class PostCheckoutListener { + private ApiClient $mailchimp; + + public function __construct(ApiClient $mailchimp){ + $this->mailchimp = $mailchimp; + } + public function __invoke(Order $order, array $tokens): void { - // Do something ... + // Update customer's information on Mailchimp subscribers list + $billingAddress = $order->getBillingAddress(); + + $listMemberInfo = [ + 'email_address' => $billingAddress->email, + 'merge_fields' => [ + 'FNAME' => $billingAddress->firstname, + 'LNAME' => $billingAddress->lastname + ] + ]; + + $this->mailchimp->lists->updateListMember( + 'listId', + md5(strtolower($billingAddress->email)), + $listMemberInfo + ); } } ```