diff --git a/README.md b/README.md index 1deb739..07d0f0c 100644 --- a/README.md +++ b/README.md @@ -5,7 +5,7 @@ **Requires at least:** 5.1 **Tested up to:** 6.6.1 **Requires PHP:** 7.0 -**Stable tag:** 0.1.0 +**Stable tag:** 0.1.1 **License:** GPLv2 or later **License URI:** https://www.gnu.org/licenses/gpl-2.0.html @@ -16,13 +16,19 @@ A beautiful way to display products from affiliate network product feeds on your With the **Affiliate Product Highlights** plugin for WordPress you can create beautiful in-content sections showing relevant products from product feeds of various affiliate networks. -Currently supports TradeTracker and AdTraction. +Networks currently supported: +* AdTraction +* TradeTracker + +**Features:** * **Automatic product feed import**: Product feeds are updated daily for up-to-date pricing and product availability * **Cloaked links**: Affiliate links are redirected through your own website URL * **Fast & efficient**: Product data is stored locally, product images are sideloaded and optimized * **Flexible shortcode**: Show random products, specific products, search by (partial) product name +See the plugin in action [here](https://projectplatenspelers.nl/). + [![Twitter URL](https://img.shields.io/twitter/url/https/twitter.com/KoenReus.svg?style=social&label=Follow%20%40KoenReus)](https://twitter.com/KoenReus) ## Installation ## @@ -32,12 +38,37 @@ Currently supports TradeTracker and AdTraction. 1. Add one or more affiliate product feeds through 'Affiliate Product Highlights' > 'Feeds' 1. Place the [product-highlights] shortcode wherever you want to display your affiliate products using attributes below -**Supported shortcode attributes:** -* **selection**: An ID of a selection of products generated through 'Affiliate Product Highlights' > 'Selections' -* **limit**: The amount of products that should be displayed (default: 6) -* **product_ids**: Display specific product IDs. Separated by a comma, e.g. 123,323,312 (currently no easy way to get these IDs apart from going into PHPMyAdmin) -* **search**: Show only products containing this word or sentence in their title (may be inefficient with a lot of products in the database) -* **random**: Randomize the results +### Supported shortcode attributes + +* `selection`: An ID of a selection of products generated through 'Affiliate Product Highlights' > 'Selections' +* `limit`: The amount of products that should be displayed (default: 6) +* `product_ids`: Display specific product IDs. Separated by a comma, e.g. 123,323,312 (currently no easy way to get these IDs apart from going into PHPMyAdmin) +* `search`: Show only products containing this word or sentence in their title (may be inefficient with a lot of products in the database) +* `random`: Randomize the results + +#### Examples + +* `[product-highlights selection=107]`: Show products from the selection with ID 107 +* `[product-highlights selection=107 limit=1 random=1]`: Show a single random product from the selection with ID 107 +* `[product-highlights product_ids="2304,2306,2307,665"]`: Show products with specific IDs + +### Styling + +The plugin comes with minimal styling that can be easily adjusted with some custom CSS. + +* `phft-products-multiple` (div): Wrapper class around all products (if the `limit` parameter is higher than 1) +* `phft-product` (div): Product wrapper class +* `phft-product-image` (div): Product image wrapper (contains a > img) +* `phft-product-description` (div) +* `phft-product-price` (div) +* `phft-button-link` (a): The call-to-action button + +Colors can be adjusted by overriding the default CSS variables: + +* `--phft-button-text-color`: Button text color (default: #fff) +* `--phft-button-background-color`: Button background color (default: #611431) +* `--phft-button-hover-color`: Button hover color (default: #363636) +* `--phft-product-border-color`: Color for the border around the individual products ## Frequently Asked Questions ## @@ -52,6 +83,13 @@ Currently supports TradeTracker and AdTraction. ## Changelog ## +### 0.1.1 ### +* Added: Product ID and Feed in selection section +* Added: AdTraction sale price +* Fix: product_ids parameter +* Fix: selection logic +* Fix: AdTraction prices above 999 + ### 0.1.0 ### * Initial public alpha release diff --git a/affiliate-product-highlights.php b/affiliate-product-highlights.php index c80df8f..610be6c 100644 --- a/affiliate-product-highlights.php +++ b/affiliate-product-highlights.php @@ -7,7 +7,7 @@ * Author URI: https://koenreus.com * Text Domain: affiliate-product-highlights * Domain Path: /languages - * Version: 0.1.0 + * Version: 0.1.1 * * @package Affiliate_Product_Highlights */ diff --git a/css/front.css b/css/front.css index 01b8874..4c903d6 100644 --- a/css/front.css +++ b/css/front.css @@ -1,19 +1,25 @@ +:root { + --phft-button-text-color: #fff; + --phft-button-background-color: #611431; + --phft-button-hover-color: #363636; + --phft-product-border-color: #eee; +} + .phft-products-multiple { display: flex; flex-wrap: wrap; gap: 1rem; padding-top:15px; padding-bottom:15px; + justify-content: space-between; } .phft-product { box-sizing: border-box; padding: 1rem; - background-color: #fff; - border: 1px solid #eee; + border: 1px solid var(--phft-product-border-color); flex-direction: column; display: flex; - color:#000000; } .phft-products-multiple .phft-product{ @@ -23,7 +29,7 @@ .phft-product h3{ font-size:18px; display:block; - height:9rem; + height:2rem; } .phft-product img { @@ -45,19 +51,32 @@ font-size:20px; margin-top: auto; } + .phft-product.phft-sale-product .phft-product-price{ + color:#f16a52; + } + + .phft-product .phft-product-price .phft-original-price { + font-size:14px; + text-decoration: line-through; + margin-left:5px; + color:initial; + } + .phft-product .phft-product-price .phft-original-price::before { + content: "/"; + } .phft-product .phft-button-link{ display:block; width:100%; padding: 5px 0; - background-color:#611431; - color:#fff !important; + background-color:var(--phft-button-background-color); + color:var(--phft-button-text-color) !important; border-radius: 5px; text-align: center; text-decoration: none; } .phft-product .phft-button-link:hover{ - background-color:#363636; + background-color:var(--phft-button-hover-color); } /* Medium devices (tablets, 768px and up) */ @media (min-width: 768px) { diff --git a/package-lock.json b/package-lock.json index 35ef2c4..25ffa55 100644 --- a/package-lock.json +++ b/package-lock.json @@ -12,6 +12,7 @@ "@wordpress/components": "^25.14.0", "@wordpress/compose": "^6.25.0", "@wordpress/element": "^5.25.0", + "@wordpress/i18n": "^5.4.0", "@wordpress/scripts": "^27.0.0", "@wordpress/url": "^3.49.0" }, @@ -4417,6 +4418,26 @@ "node": ">=12" } }, + "node_modules/@wordpress/a11y/node_modules/@wordpress/i18n": { + "version": "4.58.0", + "resolved": "https://registry.npmjs.org/@wordpress/i18n/-/i18n-4.58.0.tgz", + "integrity": "sha512-VfvS3BWv/RDjRKD6PscIcvYfWKnGJcI/DEqyDgUMhxCM6NRwoL478CsUKTiGJIymeyRodNRfprdcF086DpGKYw==", + "license": "GPL-2.0-or-later", + "dependencies": { + "@babel/runtime": "^7.16.0", + "@wordpress/hooks": "^3.58.0", + "gettext-parser": "^1.3.1", + "memize": "^2.1.0", + "sprintf-js": "^1.1.1", + "tannin": "^1.2.0" + }, + "bin": { + "pot-to-php": "tools/pot-to-php.js" + }, + "engines": { + "node": ">=12" + } + }, "node_modules/@wordpress/api-fetch": { "version": "6.46.0", "resolved": "https://registry.npmjs.org/@wordpress/api-fetch/-/api-fetch-6.46.0.tgz", @@ -4430,6 +4451,26 @@ "node": ">=12" } }, + "node_modules/@wordpress/api-fetch/node_modules/@wordpress/i18n": { + "version": "4.58.0", + "resolved": "https://registry.npmjs.org/@wordpress/i18n/-/i18n-4.58.0.tgz", + "integrity": "sha512-VfvS3BWv/RDjRKD6PscIcvYfWKnGJcI/DEqyDgUMhxCM6NRwoL478CsUKTiGJIymeyRodNRfprdcF086DpGKYw==", + "license": "GPL-2.0-or-later", + "dependencies": { + "@babel/runtime": "^7.16.0", + "@wordpress/hooks": "^3.58.0", + "gettext-parser": "^1.3.1", + "memize": "^2.1.0", + "sprintf-js": "^1.1.1", + "tannin": "^1.2.0" + }, + "bin": { + "pot-to-php": "tools/pot-to-php.js" + }, + "engines": { + "node": ">=12" + } + }, "node_modules/@wordpress/babel-plugin-import-jsx-pragma": { "version": "4.32.0", "resolved": "https://registry.npmjs.org/@wordpress/babel-plugin-import-jsx-pragma/-/babel-plugin-import-jsx-pragma-4.32.0.tgz", @@ -4540,6 +4581,26 @@ "react-dom": "^18.0.0" } }, + "node_modules/@wordpress/components/node_modules/@wordpress/i18n": { + "version": "4.58.0", + "resolved": "https://registry.npmjs.org/@wordpress/i18n/-/i18n-4.58.0.tgz", + "integrity": "sha512-VfvS3BWv/RDjRKD6PscIcvYfWKnGJcI/DEqyDgUMhxCM6NRwoL478CsUKTiGJIymeyRodNRfprdcF086DpGKYw==", + "license": "GPL-2.0-or-later", + "dependencies": { + "@babel/runtime": "^7.16.0", + "@wordpress/hooks": "^3.58.0", + "gettext-parser": "^1.3.1", + "memize": "^2.1.0", + "sprintf-js": "^1.1.1", + "tannin": "^1.2.0" + }, + "bin": { + "pot-to-php": "tools/pot-to-php.js" + }, + "engines": { + "node": ">=12" + } + }, "node_modules/@wordpress/compose": { "version": "6.26.0", "resolved": "https://registry.npmjs.org/@wordpress/compose/-/compose-6.26.0.tgz", @@ -4791,9 +4852,10 @@ } }, "node_modules/@wordpress/hooks": { - "version": "3.49.0", - "resolved": "https://registry.npmjs.org/@wordpress/hooks/-/hooks-3.49.0.tgz", - "integrity": "sha512-GH546Jg8u/rw9I3fsvAhidwt8rUFNmkdXGByIPGsN3R6y+QwWMXPzsnoYdFmFOmDK9gOGCRDe5bXHikoWnaiKA==", + "version": "3.58.0", + "resolved": "https://registry.npmjs.org/@wordpress/hooks/-/hooks-3.58.0.tgz", + "integrity": "sha512-9LB0ZHnZRQlORttux9t/xbAskF+dk2ujqzPGsVzc92mSKpQP3K2a5Wy74fUnInguB1vLUNHT6nrNdkVom5qX1Q==", + "license": "GPL-2.0-or-later", "dependencies": { "@babel/runtime": "^7.16.0" }, @@ -4813,12 +4875,13 @@ } }, "node_modules/@wordpress/i18n": { - "version": "4.49.0", - "resolved": "https://registry.npmjs.org/@wordpress/i18n/-/i18n-4.49.0.tgz", - "integrity": "sha512-8aZmmRfOHzS/3pMWg+4f6QlPci0wK5V+PDllAwtwFFrXgc0pmk8VXu7Quajh1tiVoIQDCZpK6h1sqa+qrCLpZg==", + "version": "5.4.0", + "resolved": "https://registry.npmjs.org/@wordpress/i18n/-/i18n-5.4.0.tgz", + "integrity": "sha512-nU4vpcBn5X+O/lUw2zhg44iTxh3smmBT6wLDFigGXpBKcVjJjlhVkwWLqpP/ZIc+mfhplgu4TJcTSbHyKsQLgg==", + "license": "GPL-2.0-or-later", "dependencies": { "@babel/runtime": "^7.16.0", - "@wordpress/hooks": "^3.49.0", + "@wordpress/hooks": "^4.4.0", "gettext-parser": "^1.3.1", "memize": "^2.1.0", "sprintf-js": "^1.1.1", @@ -4828,7 +4891,21 @@ "pot-to-php": "tools/pot-to-php.js" }, "engines": { - "node": ">=12" + "node": ">=18.12.0", + "npm": ">=8.19.2" + } + }, + "node_modules/@wordpress/i18n/node_modules/@wordpress/hooks": { + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/@wordpress/hooks/-/hooks-4.4.0.tgz", + "integrity": "sha512-KO0gUx0KLhH3XCatg9ZOU1TH0fgyQUccAEIM8liErfgmrabHl8JhDoR2Uk5k0jNKZNPog7XxvKgPFVtCzvzQig==", + "license": "GPL-2.0-or-later", + "dependencies": { + "@babel/runtime": "^7.16.0" + }, + "engines": { + "node": ">=18.12.0", + "npm": ">=8.19.2" } }, "node_modules/@wordpress/icons": { @@ -4898,6 +4975,26 @@ "node": ">=12" } }, + "node_modules/@wordpress/keycodes/node_modules/@wordpress/i18n": { + "version": "4.58.0", + "resolved": "https://registry.npmjs.org/@wordpress/i18n/-/i18n-4.58.0.tgz", + "integrity": "sha512-VfvS3BWv/RDjRKD6PscIcvYfWKnGJcI/DEqyDgUMhxCM6NRwoL478CsUKTiGJIymeyRodNRfprdcF086DpGKYw==", + "license": "GPL-2.0-or-later", + "dependencies": { + "@babel/runtime": "^7.16.0", + "@wordpress/hooks": "^3.58.0", + "gettext-parser": "^1.3.1", + "memize": "^2.1.0", + "sprintf-js": "^1.1.1", + "tannin": "^1.2.0" + }, + "bin": { + "pot-to-php": "tools/pot-to-php.js" + }, + "engines": { + "node": ">=12" + } + }, "node_modules/@wordpress/npm-package-json-lint-config": { "version": "4.34.0", "resolved": "https://registry.npmjs.org/@wordpress/npm-package-json-lint-config/-/npm-package-json-lint-config-4.34.0.tgz", @@ -5012,6 +5109,26 @@ "react": "^18.0.0" } }, + "node_modules/@wordpress/rich-text/node_modules/@wordpress/i18n": { + "version": "4.58.0", + "resolved": "https://registry.npmjs.org/@wordpress/i18n/-/i18n-4.58.0.tgz", + "integrity": "sha512-VfvS3BWv/RDjRKD6PscIcvYfWKnGJcI/DEqyDgUMhxCM6NRwoL478CsUKTiGJIymeyRodNRfprdcF086DpGKYw==", + "license": "GPL-2.0-or-later", + "dependencies": { + "@babel/runtime": "^7.16.0", + "@wordpress/hooks": "^3.58.0", + "gettext-parser": "^1.3.1", + "memize": "^2.1.0", + "sprintf-js": "^1.1.1", + "tannin": "^1.2.0" + }, + "bin": { + "pot-to-php": "tools/pot-to-php.js" + }, + "engines": { + "node": ">=12" + } + }, "node_modules/@wordpress/scripts": { "version": "27.0.0", "resolved": "https://registry.npmjs.org/@wordpress/scripts/-/scripts-27.0.0.tgz", diff --git a/package.json b/package.json index bc6c6dd..6d11ffe 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "affiliate-product-highlights", - "version": "0.1.0", + "version": "0.1.1", "main": "Gruntfile.js", "author": "Koen Reus", "scripts": { @@ -20,6 +20,7 @@ "@wordpress/components": "^25.14.0", "@wordpress/compose": "^6.25.0", "@wordpress/element": "^5.25.0", + "@wordpress/i18n": "^5.4.0", "@wordpress/scripts": "^27.0.0", "@wordpress/url": "^3.49.0" } diff --git a/readme.txt b/readme.txt index 496028e..8de6e21 100644 --- a/readme.txt +++ b/readme.txt @@ -5,7 +5,7 @@ Tags: tradetracker, adtraction, affiliate, feed, products Requires at least: 5.1 Tested up to: 6.6.1 Requires PHP: 7.0 -Stable tag: 0.1.0 +Stable tag: 0.1.1 License: GPLv2 or later License URI: https://www.gnu.org/licenses/gpl-2.0.html @@ -16,13 +16,19 @@ A beautiful way to display products from affiliate network product feeds on your With the **Affiliate Product Highlights** plugin for WordPress you can create beautiful in-content sections showing relevant products from product feeds of various affiliate networks. -Currently supports TradeTracker and AdTraction. +Networks currently supported: +* AdTraction +* TradeTracker + +**Features:** * **Automatic product feed import**: Product feeds are updated daily for up-to-date pricing and product availability * **Cloaked links**: Affiliate links are redirected through your own website URL * **Fast & efficient**: Product data is stored locally, product images are sideloaded and optimized * **Flexible shortcode**: Show random products, specific products, search by (partial) product name +See the plugin in action [here](https://projectplatenspelers.nl/). + [![Twitter URL](https://img.shields.io/twitter/url/https/twitter.com/KoenReus.svg?style=social&label=Follow%20%40KoenReus)](https://twitter.com/KoenReus) == Installation == @@ -32,12 +38,37 @@ Currently supports TradeTracker and AdTraction. 1. Add one or more affiliate product feeds through 'Affiliate Product Highlights' > 'Feeds' 1. Place the [product-highlights] shortcode wherever you want to display your affiliate products using attributes below -**Supported shortcode attributes:** -* **selection**: An ID of a selection of products generated through 'Affiliate Product Highlights' > 'Selections' -* **limit**: The amount of products that should be displayed (default: 6) -* **product_ids**: Display specific product IDs. Separated by a comma, e.g. 123,323,312 (currently no easy way to get these IDs apart from going into PHPMyAdmin) -* **search**: Show only products containing this word or sentence in their title (may be inefficient with a lot of products in the database) -* **random**: Randomize the results +### Supported shortcode attributes + +* `selection`: An ID of a selection of products generated through 'Affiliate Product Highlights' > 'Selections' +* `limit`: The amount of products that should be displayed (default: 6) +* `product_ids`: Display specific product IDs. Separated by a comma, e.g. 123,323,312 (currently no easy way to get these IDs apart from going into PHPMyAdmin) +* `search`: Show only products containing this word or sentence in their title (may be inefficient with a lot of products in the database) +* `random`: Randomize the results + +#### Examples + +* `[product-highlights selection=107]`: Show products from the selection with ID 107 +* `[product-highlights selection=107 limit=1 random=1]`: Show a single random product from the selection with ID 107 +* `[product-highlights product_ids="2304,2306,2307,665"]`: Show products with specific IDs + +### Styling + +The plugin comes with minimal styling that can be easily adjusted with some custom CSS. + +* `phft-products-multiple` (div): Wrapper class around all products (if the `limit` parameter is higher than 1) +* `phft-product` (div): Product wrapper class +* `phft-product-image` (div): Product image wrapper (contains a > img) +* `phft-product-description` (div) +* `phft-product-price` (div) +* `phft-button-link` (a): The call-to-action button + +Colors can be adjusted by overriding the default CSS variables: + +* `--phft-button-text-color`: Button text color (default: #fff) +* `--phft-button-background-color`: Button background color (default: #611431) +* `--phft-button-hover-color`: Button hover color (default: #363636) +* `--phft-product-border-color`: Color for the border around the individual products == Frequently Asked Questions == @@ -48,6 +79,13 @@ Currently supports TradeTracker and AdTraction. == Changelog == += 0.1.1 = +* Added: Product ID and Feed in selection section +* Added: AdTraction sale price +* Fix: product_ids parameter +* Fix: selection logic +* Fix: AdTraction prices above 999 + = 0.1.0 = * Initial public alpha release diff --git a/src/js/components/ItemsList.js b/src/js/components/ItemsList.js index 92e43bf..afd6118 100644 --- a/src/js/components/ItemsList.js +++ b/src/js/components/ItemsList.js @@ -1,7 +1,7 @@ import {useState} from "@wordpress/element"; import {CheckboxControl, Popover} from "@wordpress/components"; - -export default function ItemsList({ items, selection, setSelection }){ +import {__} from "@wordpress/i18n"; +export default function ItemsList({ items, isSaving, selection, setSelection }){ const [ isVisible, setVisible ] = useState({}); const toggleVisible = (id) => { @@ -26,8 +26,10 @@ export default function ItemsList({ items, selection, setSelection }){ - Title - Price + ID + {__("Title", 'affiliate-product-highlights')} + {__('Price', 'affiliate-product-highlights')} + {__('Feed', 'affiliate-product-highlights')} @@ -36,9 +38,12 @@ export default function ItemsList({ items, selection, setSelection }){ handleCheckbox(checked, item.id) } checked={ selection[item.id] === true } + disabled={isSaving} /> + {item.id} toggleVisible(item.id)} onMouseEnter={ () => toggleVisible(item.id) }>{item.product_name}{ isVisible[item.id] && } {item.product_price} + ))} diff --git a/src/js/components/SelectionMetabox.js b/src/js/components/SelectionMetabox.js index 414c305..3ea5701 100644 --- a/src/js/components/SelectionMetabox.js +++ b/src/js/components/SelectionMetabox.js @@ -3,7 +3,9 @@ import {useEffect, useState} from "@wordpress/element"; import apiFetch from '@wordpress/api-fetch'; import {SearchControl, TextControl} from "@wordpress/components"; import {addQueryArgs} from "@wordpress/url"; -import {useDebounce, usePrevious} from "@wordpress/compose"; +import {useDebounce, usePrevious, useCopyToClipboard} from "@wordpress/compose"; +import {__} from "@wordpress/i18n"; + const { selection_id } = psfg_localize_metabox; @@ -16,6 +18,8 @@ export default function SelectionMetabox(){ const [selection, setSelection ] = useState({}); + const [isSaving, setSaving] = useState(false); + const loadItems = () => { apiFetch({path: addQueryArgs('/phft/v1/items', { 'search': searchTerm, @@ -25,8 +29,16 @@ export default function SelectionMetabox(){ setItems(data); }); } + + const saveSelection = () => { + setSaving(true); + apiFetch({path:'/phft/v1/selection', method:'POST', data: {'selection_id': selection_id, 'selection': selection}}).finally(()=> setSaving(false)); + } + const debouncedFetchData = useDebounce(loadItems, 500); + const debouncedSaveSelection = useDebounce(saveSelection, 500); + useEffect(() => { if(prevSearchTerm === undefined){ loadItems(); @@ -35,19 +47,20 @@ export default function SelectionMetabox(){ } }, [searchTerm]); - const saveSelection = () => { - apiFetch({path:'/phft/v1/selection', method:'POST', data: {'selection_id': selection_id, 'selection': selection}}).finally(); - } - useEffect(() => { - saveSelection(); + debouncedSaveSelection(); }, [selection]); + const updateSelection = (selection) => { + setSelection(selection); + // debouncedSaveSelection(); + } useEffect(() => { + setSaving(true); apiFetch({path:addQueryArgs('/phft/v1/selection', {'selection_id': selection_id})}).then((data) =>{ setSelection({...selection, ...data}); - }); + }).finally(() => setSaving(false)); }, []); return ( @@ -56,10 +69,10 @@ export default function SelectionMetabox(){ onChange={ setSearchTerm } value={ searchTerm } /> - +
diff --git a/src/php/Plugin.php b/src/php/Plugin.php index 9f0d47f..65fc434 100644 --- a/src/php/Plugin.php +++ b/src/php/Plugin.php @@ -15,7 +15,7 @@ class Plugin { const DOMAIN = 'affiliate-product-highlights'; - const VERSION = '0.1.0'; + const VERSION = '0.1.1'; const REST_NAMESPACE = 'phft/v1'; @@ -95,6 +95,7 @@ public static function activate(){ sku varchar(255) DEFAULT NULL, product_name varchar(255) NOT NULL, product_price DECIMAL(10,2) NOT NULL DEFAULT '0.00', + product_original_price DECIMAL(10,2) NOT NULL DEFAULT '0.00', product_currency varchar(3) NOT NULL, product_url varchar(255) NOT NULL, product_description TEXT, @@ -226,15 +227,22 @@ public function display_products_shortcode($atts){ 'feed_id' => null, 'search' => null, 'random' => null, + 'selection' => null, ], $atts, 'product-highlights'); $query = "SELECT p.*, i.image_url, i.wp_media_id, i.id AS image_id FROM {$wpdb->prefix}phft_products p LEFT JOIN {$wpdb->prefix}phft_images i ON p.id = i.product_id"; $params = []; + if(!is_null($atts['selection'])){ + $item_selection = get_post_meta((int)$atts['selection'], '_phft_item_selection', true); + $ids = array_keys($item_selection); + $atts['product_ids'] = implode(',', $ids); + } + if(!is_null($atts['product_ids'])){ $product_ids = explode(',', $atts['product_ids']); $placeholders = implode(',', array_fill(0, count($product_ids), '%d')); - $query .= " WHERE p.product_id IN ({$placeholders})"; + $query .= " WHERE p.id IN ({$placeholders})"; $params = array_merge($params, $product_ids); } @@ -294,7 +302,9 @@ public function draw_product($product){ $fmt = numfmt_create( $locale, NumberFormatter::CURRENCY ); $product_url = esc_url(home_url('/phft/' . urlencode($product->slug))); - $output = '
'; + $has_sale = $product->product_original_price > $product->product_price; + + $output = '
'; $output .= '

'.mb_strimwidth(esc_html($product->product_name), 0, 70, '...').'

'; if (!empty($product->images)) { $output .= '
'; @@ -302,7 +312,7 @@ public function draw_product($product){ $output .= '
'; } $output .= '
'. mb_strimwidth(wp_strip_all_tags($product->product_description), 0, 160, '...').'
'; - $output .= '
'.numfmt_format_currency($fmt, $product->product_price, $product->product_currency).'
'; + $output .= '
'.numfmt_format_currency($fmt, $product->product_price, $product->product_currency).($has_sale ? ''.numfmt_format_currency($fmt, $product->product_original_price, $product->product_currency).'':'').'
'; $output .= ''.esc_html__('View').''; $output .= '
'; diff --git a/src/php/Provider/AdTraction/ProductMapping.php b/src/php/Provider/AdTraction/ProductMapping.php index 96b7f8c..a62a088 100644 --- a/src/php/Provider/AdTraction/ProductMapping.php +++ b/src/php/Provider/AdTraction/ProductMapping.php @@ -17,13 +17,14 @@ public function __construct( SimpleXMLElement $product_xml ) { public function get_product_mapping(): array { return [ - 'sku' => (string)$this->product_xml->SKU, - 'product_name' => (string)$this->product_xml->Name, - 'product_price' => number_format((float)$this->product_xml->Price, 2), - 'product_currency' => (string)$this->product_xml->Currency, - 'product_url' => sanitize_url((string)$this->product_xml->TrackingUrl), - 'product_description' => (string)$this->product_xml->Description, - 'product_ean' => (string)$this->product_xml->Ean, + 'sku' => (string)$this->product_xml->SKU, + 'product_name' => (string)$this->product_xml->Name, + 'product_price' => number_format((float)$this->product_xml->Price, 2,'.', ''), + 'product_original_price' => number_format((float)$this->product_xml->OriginalPrice, 2, '.', ''), + 'product_currency' => (string)$this->product_xml->Currency, + 'product_url' => sanitize_url((string)$this->product_xml->TrackingUrl), + 'product_description' => (string)$this->product_xml->Description, + 'product_ean' => (string)$this->product_xml->Ean, ]; } diff --git a/src/php/Provider/TradeTracker/ProductMapping.php b/src/php/Provider/TradeTracker/ProductMapping.php index d13bff2..14b0fdf 100644 --- a/src/php/Provider/TradeTracker/ProductMapping.php +++ b/src/php/Provider/TradeTracker/ProductMapping.php @@ -21,7 +21,7 @@ public function get_product_mapping(): array { 'campaign_id' => (int)$this->product_xml->campaignID, 'product_id' => (int)$this->product_xml['ID'], 'product_name' => (string)$this->product_xml->name, - 'product_price' => number_format((float)$this->product_xml->price, 2), + 'product_price' => number_format((float)$this->product_xml->price, 2,'.', ''), 'product_currency' => (string)$this->product_xml->price['currency'], 'product_url' => sanitize_url((string)$this->product_xml->URL), 'product_description' => (string)$this->product_xml->description,