Changeset 3316689
- Timestamp:
- 06/24/2025 05:48:10 AM (9 months ago)
- Location:
- price-alerts
- Files:
-
- 2 added
- 30 edited
- 1 copied
-
tags/1.0.2 (copied) (copied from price-alerts/trunk)
-
tags/1.0.2/README.txt (modified) (3 diffs)
-
tags/1.0.2/admin/admin.php (modified) (2 diffs)
-
tags/1.0.2/admin/options.php (modified) (3 diffs)
-
tags/1.0.2/admin/product.php (added)
-
tags/1.0.2/assets/build/public.asset.php (modified) (1 diff)
-
tags/1.0.2/assets/build/public.js (modified) (1 diff)
-
tags/1.0.2/includes/deactivator.php (modified) (1 diff)
-
tags/1.0.2/includes/defaults.php (modified) (2 diffs)
-
tags/1.0.2/includes/helper.php (modified) (2 diffs)
-
tags/1.0.2/includes/notifier.php (modified) (5 diffs)
-
tags/1.0.2/includes/plugin.php (modified) (1 diff)
-
tags/1.0.2/includes/rest-api.php (modified) (3 diffs)
-
tags/1.0.2/includes/uninstaller.php (modified) (1 diff)
-
tags/1.0.2/languages/price-alerts.pot (modified) (7 diffs)
-
tags/1.0.2/price-alerts.php (modified) (3 diffs)
-
tags/1.0.2/public/public.php (modified) (1 diff)
-
trunk/README.txt (modified) (3 diffs)
-
trunk/admin/admin.php (modified) (2 diffs)
-
trunk/admin/options.php (modified) (3 diffs)
-
trunk/admin/product.php (added)
-
trunk/assets/build/public.asset.php (modified) (1 diff)
-
trunk/assets/build/public.js (modified) (1 diff)
-
trunk/includes/deactivator.php (modified) (1 diff)
-
trunk/includes/defaults.php (modified) (2 diffs)
-
trunk/includes/helper.php (modified) (2 diffs)
-
trunk/includes/notifier.php (modified) (5 diffs)
-
trunk/includes/plugin.php (modified) (1 diff)
-
trunk/includes/rest-api.php (modified) (3 diffs)
-
trunk/includes/uninstaller.php (modified) (1 diff)
-
trunk/languages/price-alerts.pot (modified) (7 diffs)
-
trunk/price-alerts.php (modified) (3 diffs)
-
trunk/public/public.php (modified) (1 diff)
Legend:
- Unmodified
- Added
- Removed
-
price-alerts/tags/1.0.2/README.txt
r3310498 r3316689 4 4 Requires at least: 6.2 5 5 Requires PHP: 7.4 6 Stable tag: 1.0. 16 Stable tag: 1.0.2 7 7 Tested up to: 6.8 8 8 License: GPLv2 or later … … 103 103 == Changelog == 104 104 105 = 1.0.2 = 106 107 *2025-06-24* 108 109 * Fix: Checkbox value saving 110 * Fix: Database cleanup error caused by foreign key constraints upon uninstall 111 * Fix: Cron task not being removed on plugin deactivation 112 * Tweak: Admin UI styling 113 114 105 115 = 1.0.1 = 106 116 … … 112 122 * Performance: WC tested up to 9.9 113 123 114 * Initial release.115 116 124 = 1.0.0 = 117 125 -
price-alerts/tags/1.0.2/admin/admin.php
r3310498 r3316689 17 17 add_action( 'admin_enqueue_scripts', [$this, 'enqueue_assets'] ); 18 18 add_action( 'admin_menu', [$this, 'admin_menu'], 100 ); 19 add_action(20 'woocommerce_after_product_object_save',21 [$this, 'update_product'],22 10,23 224 );25 19 add_filter( 'plugin_action_links_' . DEVNET_PRICE_ALERTS_PATH_FILE, [$this, 'plugin_action_links'] ); 26 20 add_filter( 'admin_footer_text', [$this, 'admin_credits'] ); … … 145 139 } 146 140 147 public function update_product( $product, $data_store ) {148 $args = [149 'product_id' => $product->get_id(),150 'price' => (float) $product->get_price(),151 'currency' => get_option( 'woocommerce_currency' ),152 ];153 /*154 * Update status for products that meets users target prices.155 */156 Helper::update_status_on_price_change( [157 'new_status' => 'pending',158 'status' => ['assigned'],159 'target_price_is' => 'higher',160 ] + $args );161 /*162 * Revert pending statuses if price is again higher than target price.163 */164 Helper::update_status_on_price_change( [165 'new_status' => 'assigned',166 'status' => ['pending'],167 'target_price_is' => 'lower',168 ] + $args );169 }170 171 141 public function plugin_action_links( $links ) { 172 142 $custom_links = []; -
price-alerts/tags/1.0.2/admin/options.php
r3309423 r3316689 14 14 'label' => esc_html__( 'Multilingual', 'price-alerts' ), 15 15 'desc' => esc_html__( 'Use your own translated strings.', 'price-alerts' ), 16 'default' => 0, 16 'default' => Defaults::general( 'multilingual' ), 17 ], [ 18 'type' => 'checkbox', 19 'name' => 'multicurrency__disabled', 20 'label' => esc_html__( 'Multi-currency support', 'price-alerts' ), 21 'desc' => esc_html__( "Use customer’s currency when checking if the target price is reached.", 'price-alerts' ), 22 'default' => Defaults::general( 'multicurrency' ), 17 23 ], [ 18 24 'type' => 'checkbox', … … 20 26 'label' => esc_html__( 'Delete all plugin data on uninstall', 'price-alerts' ), 21 27 'desc' => esc_html__( 'Enabling this option will ensure that all data associated with the plugin, including settings and subscribers, will be completely removed from the database upon uninstallation of the plugin.', 'price-alerts' ), 22 'default' => 0,28 'default' => Defaults::general( 'delete_plugin_data' ), 23 29 ]]; 24 30 return apply_filters( 'price_alerts_settings_general', $general ); … … 32 38 'label' => esc_html__( 'Enable', 'price-alerts' ), 33 39 'default' => Defaults::form( 'enable' ), 40 ], 41 [ 42 'type' => 'select', 43 'name' => 'form_scope', 44 'label' => esc_html__( 'Form scope', 'easy-subscribe-woocommerce' ), 45 'options' => [ 46 'all' => esc_html__( 'All Products', 'price-alerts' ), 47 '_disabled_1' => esc_html__( 'All Products (can be disabled per product)', 'price-alerts' ), 48 '_disabled_2' => esc_html__( 'Manual Selection (enable per product)', 'price-alerts' ), 49 ], 50 'default' => Defaults::form( 'form_scope' ), 34 51 ], 35 52 [ -
price-alerts/tags/1.0.2/assets/build/public.asset.php
r3309423 r3316689 1 <?php return array('dependencies' => array(), 'version' => ' e27b7d5b6dc9d8a5a284');1 <?php return array('dependencies' => array(), 'version' => '2f5fb3f7daa73a3f5a13'); -
price-alerts/tags/1.0.2/assets/build/public.js
r3309423 r3316689 1 (()=>{"use strict";jQuery(document).ready((function(){const e=jQuery,{ajaxurl:t,nonce:n,text:s,options:o}=devnet_price_alerts_script_data, a={processing:!1,processingElement:{},productType:"simple",isVariation:!1,loader(t){t&&this.processingElement instanceof jQuery?this.processingElement.append('<div id="devnet-pa-spinner" class="al-spinner-backdrop"></div>'):e("#devnet-pa-spinner").remove()},get isProcessing(){return this.processing},set isProcessing(e){this.processing=e,this.loader(this.processing)}},i=e("form.devnet-pa-form"),r=e(".price-alerts-form-wrapper");function c(){r.removeClass("devnet-pa-modal-open")}e(".devnet-pa-open-modal").on("click",(function(t){t.preventDefault(),function(t){const n='button, [href], input, select, textarea, [tabindex]:not([tabindex="-1"])',s=t.find(n)[0],o=t.find(n),a=o[o.length-1];setTimeout((()=>{s.focus()}),0),e(document).on("keydown",(function(e){("Tab"===e.key||9===e.keyCode)&&(e.shiftKey?document.activeElement===s&&(a.focus(),e.preventDefault()):document.activeElement===a&&(s.focus(),e.preventDefault()))}))}(i),r.css("display",""),r[0].offsetHeight,r.addClass("devnet-pa-modal-open")})),e(".devnet-pa-close").on("click",(function(e){e.preventDefault(),c()})),r.on("mousedown touchstart",(function(e){e.target===this&&c()})),e(document).on("keydown",(function(e){"Escape"===e.key&&c()})),i.on("submit",(async function(t){if(t.preventDefault(),a.isProcessing)return;const o=e(this);a.processingElement=o,a.isProcessing=!0,o.addClass("processing"),o.find("button").prop("disabled",!0);const i=o.serializeArray().reduce(((e,t)=>(e[t.name.replace("price_alerts_","")]=t.value,e)),{});i.origin_url=window.location.href;const r=await async function({endpoint:e,method:t="GET",nonce:n="",data:s=null}){const o={method:t,headers:{"X-WP-Nonce":n}};s&&(o.headers["Content-Type"]="application/json",o.body=JSON.stringify(s));try{const t=await fetch(e,o);return await t.json()}catch(e){return console.error("API Request failed:",e),{status:"error",message:"Request failed"}}}({endpoint:"/wp-json/price-alerts/v1/subscribe",method:"POST",nonce:n,data:i});a.isProcessing=!1,["created","updated"].includes(r.response)?(!0===r.pending_confirmation?o.append(`<div class="devnet-pa-message">${s.confirm_email}</div>`):o.append('<div class="devnet-pa-success-animation">\n\t\t\t<svg class="checkmark" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 52 52">\n\t\t\t\t<circle class="checkmark__circle" cx="26" cy="26" r="25" fill="none" />\n\t\t\t\t<path class="checkmark__check" fill="none" d="M14.1 27.2l7.1 7.2 16.7-16.8" />\n\t\t\t</svg>\n\t\t</div>'),o.addClass("submitted")):o.append(`<div class="devnet-pa-message error">${r.message}</div>`),o.find("button").prop("disabled",!1),o.removeClass("processing")})),e(document).on("found_variation","form.cart",(function(t,n){const s=n.variation_id,a=n.display_price,i=e('[name="price_alerts_target_price"]');e('[name="price_alerts_product_id"]').val(s),1==o.allow_higher_target_price?i.attr("max",""):i.attr("max",a)})),e(document).on("reset_data","form.cart",(function(){const t=e(this).data("product_id"),n=e('[name="price_alerts_product_id"]');t!==n.val()&&n.val(t)})),e("form.devnet-pa-field-style-outlined .devnet-pa-text-field").each((function(){const t=e(this),n=t.find("input"),s=t.find("label");function o(){s.css("background-color",function(e){for(;e.length&&!e.is("html");){const t=e.css("background-color");if(t&&"rgba(0, 0, 0, 0)"!==t&&"transparent"!==t)return t;e=e.parent()}return"#fff"}(t))}n.length&&s.length&&(o(),n.on("focus blur",o))}))}))})();1 (()=>{"use strict";jQuery(document).ready((function(){const e=jQuery,{ajaxurl:t,nonce:n,text:s,options:o}=devnet_price_alerts_script_data,i={processing:!1,processingElement:{},productType:"simple",isVariation:!1,loader(t){t&&this.processingElement instanceof jQuery?this.processingElement.append('<div id="devnet-pa-spinner" class="al-spinner-backdrop"></div>'):e("#devnet-pa-spinner").remove()},get isProcessing(){return this.processing},set isProcessing(e){this.processing=e,this.loader(this.processing)}},a=e("form.devnet-pa-form"),r=e(".price-alerts-form-wrapper");function c(){r.removeClass("devnet-pa-modal-open")}e(".devnet-pa-open-modal").on("click",(function(t){t.preventDefault(),function(t){const n='button, [href], input, select, textarea, [tabindex]:not([tabindex="-1"])',s=t.find(n)[0],o=t.find(n),i=o[o.length-1];setTimeout((()=>{s.focus()}),0),e(document).on("keydown",(function(e){("Tab"===e.key||9===e.keyCode)&&(e.shiftKey?document.activeElement===s&&(i.focus(),e.preventDefault()):document.activeElement===i&&(s.focus(),e.preventDefault()))}))}(a),r.css("display",""),r[0].offsetHeight,r.addClass("devnet-pa-modal-open")})),e(".devnet-pa-close").on("click",(function(e){e.preventDefault(),c()})),r.on("mousedown touchstart",(function(e){e.target===this&&c()})),e(document).on("keydown",(function(e){"Escape"===e.key&&c()})),a.on("submit",(async function(t){if(t.preventDefault(),i.isProcessing)return;const o=e(this);i.processingElement=o,i.isProcessing=!0,o.addClass("processing"),o.find("button").prop("disabled",!0);const a=o.serializeArray().reduce(((e,t)=>(e[t.name.replace("price_alerts_","")]=t.value,e)),{});a.origin_url=window.location.href,a.currency=window?.wcml_mc_settings?.current_currency?.code;const r=await async function({endpoint:e,method:t="GET",nonce:n="",data:s=null}){const o={method:t,headers:{"X-WP-Nonce":n}};s&&(o.headers["Content-Type"]="application/json",o.body=JSON.stringify(s));try{const t=await fetch(e,o);return await t.json()}catch(e){return console.error("API Request failed:",e),{status:"error",message:"Request failed"}}}({endpoint:"/wp-json/price-alerts/v1/subscribe",method:"POST",nonce:n,data:a});i.isProcessing=!1,["created","updated"].includes(r.response)?(!0===r.pending_confirmation?o.append(`<div class="devnet-pa-message">${s.confirm_email}</div>`):o.append('<div class="devnet-pa-success-animation">\n\t\t\t<svg class="checkmark" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 52 52">\n\t\t\t\t<circle class="checkmark__circle" cx="26" cy="26" r="25" fill="none" />\n\t\t\t\t<path class="checkmark__check" fill="none" d="M14.1 27.2l7.1 7.2 16.7-16.8" />\n\t\t\t</svg>\n\t\t</div>'),o.addClass("submitted")):o.append(`<div class="devnet-pa-message error">${r.message}</div>`),o.find("button").prop("disabled",!1),o.removeClass("processing")})),e(document).on("found_variation","form.cart",(function(t,n){const s=n.variation_id,i=n.display_price,a=e('[name="price_alerts_target_price"]');e('[name="price_alerts_product_id"]').val(s),1==o.allow_higher_target_price?a.attr("max",""):a.attr("max",i)})),e(document).on("reset_data","form.cart",(function(){const t=e(this).data("product_id"),n=e('[name="price_alerts_product_id"]');t!==n.val()&&n.val(t)})),e("form.devnet-pa-field-style-outlined .devnet-pa-text-field").each((function(){const t=e(this),n=t.find("input"),s=t.find("label");function o(){s.css("background-color",function(e){for(;e.length&&!e.is("html");){const t=e.css("background-color");if(t&&"rgba(0, 0, 0, 0)"!==t&&"transparent"!==t)return t;e=e.parent()}return"#fff"}(t))}n.length&&s.length&&(o(),n.on("focus blur",o))}))}))})(); -
price-alerts/tags/1.0.2/includes/deactivator.php
r3309423 r3316689 9 9 { 10 10 11 public static function deactivate() {} 11 public static function deactivate() 12 { 13 wp_clear_scheduled_hook('price_alerts_schedule'); 14 } 12 15 } -
price-alerts/tags/1.0.2/includes/defaults.php
r3309423 r3316689 11 11 { 12 12 $options = [ 13 'notifier_interval' => '', 14 'email_subject' => esc_html__('Subject', 'price-alerts'), 15 'email_heading' => esc_html__('Heading', 'price-alerts'), 16 'email_content_1' => esc_html__("Hi there,\ngood news! We are excited to inform you that the product(s) you were interested in is now available at a lower price than your target price. Here is a list of the product(s) you showed interest in, along with their current prices:", 'price-alerts'), 17 'email_content_2' => esc_html__("It is a great opportunity to make your purchase and take advantage of these deals. If you have any questions or need help, please feel free to reach out. We are always here to help you out!\nThank you for choosing our company for your shopping needs.\nBest regards", 'price-alerts'), 18 'email_footer' => sprintf( 19 // translators: %s: Site name. 20 esc_html__('%s - Powered by Price Alerts', 'price-alerts'), 21 get_bloginfo('name', 'display') 22 ) 13 'multilingual' => 0, 14 'multicurrency' => 0, 15 'delete_plugin_data' => 0, 23 16 ]; 24 17 … … 36 29 $options = [ 37 30 'enable' => 0, 31 'form_scope' => 'all', 38 32 'only_logged_in_users' => 0, 39 33 'display_mode' => 'inline', -
price-alerts/tags/1.0.2/includes/helper.php
r3309423 r3316689 303 303 304 304 305 /** 306 * Return all distinct currencies that have active subscriptions 307 * for this product (assigned + pending only). 308 */ 309 public static function get_sub_currencies_for_product($product_id) 310 { 311 global $wpdb; 312 $table = self::get_table_name('subs'); 313 314 return $wpdb->get_col( 315 $wpdb->prepare( 316 "SELECT DISTINCT currency 317 FROM {$table} 318 WHERE product_id = %d 319 AND status IN ('assigned','pending')", 320 $product_id 321 ) 322 ); 323 } 324 325 305 326 public static function evaluate_status_after_confirmation($subscription_id) 306 327 { … … 607 628 return [round($h), round($s * 100), round($l * 100)]; 608 629 } 630 631 632 /** 633 * Check if price is valid. 634 * 635 */ 636 public static function is_valid_price($price) 637 { 638 // Check if the price is numeric or a string that can be converted to a float 639 return is_numeric($price) || (is_string($price) && preg_match('/^\d+(\,\d+)?$/', $price)); 640 } 641 642 /** 643 * Convert number/numeric string to float. 644 * 645 */ 646 public static function convert_to_float($price) 647 { 648 // Convert a price formatted with a comma to a float 649 if (is_string($price)) { 650 $price = str_replace(',', '.', $price); 651 } 652 return floatval($price); 653 } 609 654 } -
price-alerts/tags/1.0.2/includes/notifier.php
r3309423 r3316689 3 3 namespace Devnet\PriceAlerts\Includes; 4 4 5 use Devnet\PriceAlerts\Includes\Compatibility\CompatibilityManager; 5 6 use Devnet\PriceAlerts\Includes\Helper; 6 7 use Devnet\PriceAlerts\Includes\Defaults; … … 21 22 return; 22 23 } 23 $options = DEVNET_PRICE_ALERTS_OPTIONS['email_price_drop'] ;24 $options = DEVNET_PRICE_ALERTS_OPTIONS['email_price_drop'] ?? []; 24 25 $email_subject = $options['subject'] ?? Defaults::email_price_drop( 'subject' ); 25 // $enabled = $options['enable'] ?? false; 26 // if (!$enabled) { 27 // return; 28 // } 29 $current_currency = get_woocommerce_currency(); 26 // Get the default WooCommerce currency directly from settings to avoid any filters applied by plugins. 27 $current_currency = get_option( 'woocommerce_currency' ); 30 28 $email_data = []; 31 29 $__instance = new self(); … … 58 56 $current_currency = $data['current_currency'] ?? ''; 59 57 $products = $data['products'] ?? []; 58 $multicurrency = DEVNET_PRICE_ALERTS_OPTIONS['general']['multicurrency'] ?? false; 60 59 $sent = false; 61 60 foreach ( $products as $key => &$p ) { … … 64 63 continue; 65 64 } 65 $has_currency_mismatch = $current_currency !== $p['currency']; 66 66 $price = wc_get_price_to_display( $product ); 67 if ( $has_currency_mismatch ) { 68 $is_converted = false; 69 if ( !$is_converted ) { 70 $this->update_status( $p['entryId'], 'failed' ); 71 unset($products[$key]); 72 continue; 73 } 74 } 67 75 $price = apply_filters( 68 76 'price_alerts_notifier_product_price', … … 71 79 $product 72 80 ); 73 $has_currency_mismatch = $current_currency !== $p['currency'];74 $has_currency_mismatch = apply_filters( 'price_alerts_notifier_currency_check', $has_currency_mismatch );75 if ( $has_currency_mismatch ) {76 $this->update_status( $p['entryId'], 'blocked' );77 unset($products[$key]);78 continue;79 }80 81 if ( (float) $price <= (float) $p['targetPrice'] ) { 81 82 $p['price'] = $price; -
price-alerts/tags/1.0.2/includes/plugin.php
r3309423 r3316689 4 4 5 5 use Devnet\PriceAlerts\Admin\AdminSide; 6 use Devnet\PriceAlerts\Admin\Product; 6 7 use Devnet\PriceAlerts\Frontend\PublicSide; 8 if ( !defined( 'ABSPATH' ) ) { 9 exit; 10 } 11 class Plugin { 12 protected $plugin_name; 7 13 8 if (! defined('ABSPATH')) exit;14 protected $version; 9 15 16 public function __construct() { 17 if ( defined( 'DEVNET_PRICE_ALERTS_VERSION' ) ) { 18 $this->version = DEVNET_PRICE_ALERTS_VERSION; 19 } else { 20 $this->version = '1.0.0'; 21 } 22 if ( defined( 'DEVNET_PRICE_ALERTS_NAME' ) ) { 23 $this->plugin_name = DEVNET_PRICE_ALERTS_NAME; 24 } else { 25 $this->plugin_name = 'price-alerts'; 26 } 27 $this->load_dependencies(); 28 } 10 29 11 class Plugin 12 { 30 private function load_dependencies() { 31 require_once plugin_dir_path( dirname( __FILE__ ) ) . 'includes/defaults.php'; 32 require_once plugin_dir_path( dirname( __FILE__ ) ) . 'includes/helper.php'; 33 require_once plugin_dir_path( dirname( __FILE__ ) ) . 'includes/notifier.php'; 34 require_once plugin_dir_path( dirname( __FILE__ ) ) . 'includes/rest-api.php'; 35 require_once plugin_dir_path( dirname( __FILE__ ) ) . 'includes/queue/wp-async-request.php'; 36 require_once plugin_dir_path( dirname( __FILE__ ) ) . 'includes/queue/wp-background-process.php'; 37 require_once plugin_dir_path( dirname( __FILE__ ) ) . 'includes/queue/queue.php'; 38 require_once plugin_dir_path( dirname( __FILE__ ) ) . 'admin/settings-api.php'; 39 require_once plugin_dir_path( dirname( __FILE__ ) ) . 'admin/options.php'; 40 require_once plugin_dir_path( dirname( __FILE__ ) ) . 'admin/settings.php'; 41 require_once plugin_dir_path( dirname( __FILE__ ) ) . 'admin/admin.php'; 42 require_once plugin_dir_path( dirname( __FILE__ ) ) . 'admin/product.php'; 43 require_once plugin_dir_path( dirname( __FILE__ ) ) . 'public/public.php'; 44 } 13 45 14 protected $plugin_name; 15 protected $version; 46 public function run() { 47 new RestApi(); 48 new Notifier(); 49 new Product(); 50 new AdminSide($this->get_plugin_name(), $this->get_version()); 51 new PublicSide($this->get_plugin_name(), $this->get_version()); 52 } 16 53 17 public function __construct() 18 { 19 if (defined('DEVNET_PRICE_ALERTS_VERSION')) { 20 $this->version = DEVNET_PRICE_ALERTS_VERSION; 21 } else { 22 $this->version = '1.0.0'; 23 } 54 public function get_plugin_name() { 55 return $this->plugin_name; 56 } 24 57 25 if (defined('DEVNET_PRICE_ALERTS_NAME')) { 26 $this->plugin_name = DEVNET_PRICE_ALERTS_NAME; 27 } else { 28 $this->plugin_name = 'price-alerts'; 29 } 58 public function get_version() { 59 return $this->version; 60 } 30 61 31 $this->load_dependencies();32 }33 34 private function load_dependencies()35 {36 require_once plugin_dir_path(dirname(__FILE__)) . 'includes/defaults.php';37 require_once plugin_dir_path(dirname(__FILE__)) . 'includes/helper.php';38 require_once plugin_dir_path(dirname(__FILE__)) . 'includes/notifier.php';39 require_once plugin_dir_path(dirname(__FILE__)) . 'includes/rest-api.php';40 41 require_once plugin_dir_path(dirname(__FILE__)) . 'includes/queue/wp-async-request.php';42 require_once plugin_dir_path(dirname(__FILE__)) . 'includes/queue/wp-background-process.php';43 require_once plugin_dir_path(dirname(__FILE__)) . 'includes/queue/queue.php';44 45 46 require_once plugin_dir_path(dirname(__FILE__)) . 'admin/settings-api.php';47 require_once plugin_dir_path(dirname(__FILE__)) . 'admin/options.php';48 require_once plugin_dir_path(dirname(__FILE__)) . 'admin/settings.php';49 require_once plugin_dir_path(dirname(__FILE__)) . 'admin/admin.php';50 51 require_once plugin_dir_path(dirname(__FILE__)) . 'public/public.php';52 }53 54 55 public function run()56 {57 new RestApi();58 new Notifier();59 new AdminSide($this->get_plugin_name(), $this->get_version());60 new PublicSide($this->get_plugin_name(), $this->get_version());61 }62 63 64 public function get_plugin_name()65 {66 return $this->plugin_name;67 }68 69 public function get_version()70 {71 return $this->version;72 }73 62 } -
price-alerts/tags/1.0.2/includes/rest-api.php
r3309423 r3316689 76 76 'type' => 'number', 77 77 'required' => true 78 ], 79 'currency' => [ 80 'type' => 'string', 81 'sanitize_callback' => 'sanitize_text_field' 78 82 ], 79 83 'marketing' => [ … … 149 153 $email = sanitize_email($request->get_param('email')); 150 154 $honeypot = sanitize_text_field($request->get_param('hp')); 155 $currency = sanitize_text_field($request->get_param('currency')); 151 156 152 157 if ($honeypot) { … … 174 179 $raw_data['product_price'] = $product->get_price(); 175 180 $raw_data['product_type'] = $product->get_type(); 176 $raw_data['currency'] = get_woocommerce_currency();181 $raw_data['currency'] = !empty($currency) ? $currency : get_woocommerce_currency(); 177 182 $raw_data['double_opt_in'] = DEVNET_PRICE_ALERTS_OPTIONS['form']['double_opt_in'] ?? false; 178 183 $raw_data['origin_url'] = esc_url_raw($request->get_param('origin_url') ?? ''); -
price-alerts/tags/1.0.2/includes/uninstaller.php
r3309423 r3316689 49 49 50 50 $tables = [ 51 'price_alerts_meta', 51 52 'price_alerts_subscriptions', 52 'price_alerts_meta',53 53 ]; 54 54 -
price-alerts/tags/1.0.2/languages/price-alerts.pot
r3310498 r3316689 3 3 msgid "" 4 4 msgstr "" 5 "Project-Id-Version: Price Alerts for WooCommerce 1.0. 0\n"5 "Project-Id-Version: Price Alerts for WooCommerce 1.0.2\n" 6 6 "Report-Msgid-Bugs-To: https://wordpress.org/support/plugin/price-alerts\n" 7 7 "Last-Translator: FULL NAME <EMAIL@ADDRESS>\n" … … 10 10 "Content-Type: text/plain; charset=UTF-8\n" 11 11 "Content-Transfer-Encoding: 8bit\n" 12 "POT-Creation-Date: 2025-06- 12T11:52:16+00:00\n"12 "POT-Creation-Date: 2025-06-23T20:05:30+00:00\n" 13 13 "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" 14 "X-Generator: WP-CLI 2. 11.0\n"14 "X-Generator: WP-CLI 2.5.1-alpha-70ffdce\n" 15 15 "X-Domain: price-alerts\n" 16 16 17 17 #. Plugin Name of the plugin 18 #: price-alerts.php19 18 msgid "Price Alerts for WooCommerce" 20 19 msgstr "" 21 20 22 21 #. Description of the plugin 23 #: price-alerts.php24 22 msgid "Allow customers to subscribe to WooCommerce products and get notified when prices drop." 25 23 msgstr "" 26 24 27 25 #. Author of the plugin 28 #: price-alerts.php29 26 msgid "Devnet" 30 27 msgstr "" 31 28 32 29 #. Author URI of the plugin 33 #: price-alerts.php34 30 msgid "https://devnet.hr" 35 31 msgstr "" 36 32 37 #: admin/admin.php:6 133 #: admin/admin.php:60 38 34 msgid "Migrate data from the previous plugin now?" 39 35 msgstr "" 40 36 41 #: admin/admin.php:8 137 #: admin/admin.php:80 42 38 msgid "The notification has already been sent to certain users who were selected. Are you certain that you wish to send the notification again?" 43 39 msgstr "" 44 40 45 41 #. translators: %s: the number of notified users. 46 #: admin/admin.php:8 342 #: admin/admin.php:82 47 43 msgid "Successfully notified %s user(s)." 48 44 msgstr "" 49 45 50 46 #. translators: %s: the number of failed notifications. 47 #: admin/admin.php:84 48 msgid "%s selected user(s) were not notified." 49 msgstr "" 50 51 51 #: admin/admin.php:85 52 msgid "%s selected user(s) were not notified."53 msgstr ""54 55 #: admin/admin.php:8656 52 msgid "Are you sure you want to proceed with this action?" 57 53 msgstr "" 58 54 55 #: admin/admin.php:101 59 56 #: admin/admin.php:102 60 #: admin/ admin.php:10357 #: admin/product.php:99 61 58 msgid "Price Alerts" 62 59 msgstr "" 63 60 61 #: admin/admin.php:112 64 62 #: admin/admin.php:113 65 #: admin/admin.php:114 66 #: admin/admin.php:166 63 #: admin/admin.php:137 67 64 msgid "Settings" 68 65 msgstr "" 69 66 67 #: admin/admin.php:120 70 68 #: admin/admin.php:121 71 #: admin/admin.php:12272 69 #: templates/admin-subscriptions-page.php:5 73 70 msgid "Subscriptions" … … 83 80 84 81 #: admin/options.php:25 82 msgid "Multi-currency support" 83 msgstr "" 84 85 #: admin/options.php:26 86 msgid "Use customer’s currency when checking if the target price is reached." 87 msgstr "" 88 89 #: admin/options.php:32 85 90 msgid "Delete all plugin data on uninstall" 86 91 msgstr "" 87 92 88 #: admin/options.php: 2693 #: admin/options.php:33 89 94 msgid "Enabling this option will ensure that all data associated with the plugin, including settings and subscribers, will be completely removed from the database upon uninstallation of the plugin." 90 95 msgstr "" 91 96 92 #: admin/options.php: 4097 #: admin/options.php:65 93 98 msgid "Enable" 94 99 msgstr "" 95 100 96 #: admin/options.php:46 101 #: admin/options.php:73 102 msgid "All Products" 103 msgstr "" 104 105 #: admin/options.php:74 106 #: admin/options.php:238 107 msgid "All Products (can be disabled per product)" 108 msgstr "" 109 110 #: admin/options.php:75 111 #: admin/options.php:239 112 msgid "Manual Selection (enable per product)" 113 msgstr "" 114 115 #: admin/options.php:82 97 116 msgid "Double Opt-in" 98 117 msgstr "" 99 118 100 #: admin/options.php: 47119 #: admin/options.php:83 101 120 msgid "After the user submits their email, they receive a confirmation email with a request to confirm their subscription" 102 121 msgstr "" 103 122 104 #: admin/options.php: 53123 #: admin/options.php:89 105 124 msgid "Show only for logged in users" 106 125 msgstr "" 107 126 108 #: admin/options.php: 59127 #: admin/options.php:95 109 128 msgid "Display mode" 110 129 msgstr "" 111 130 112 #: admin/options.php: 61113 #: admin/options.php:2 02131 #: admin/options.php:97 132 #: admin/options.php:247 114 133 msgid "Modal (popup)" 115 134 msgstr "" 116 135 117 #: admin/options.php: 62118 #: admin/options.php:2 03136 #: admin/options.php:98 137 #: admin/options.php:248 119 138 msgid "Inline (show form directly)" 120 139 msgstr "" 121 140 122 #: admin/options.php: 69141 #: admin/options.php:105 123 142 msgid "Position" 124 143 msgstr "" 125 144 126 #: admin/options.php: 71127 #: admin/options.php:2 11145 #: admin/options.php:107 146 #: admin/options.php:256 128 147 msgid "Before product meta" 129 148 msgstr "" 130 149 131 #: admin/options.php: 72132 #: admin/options.php:2 12150 #: admin/options.php:108 151 #: admin/options.php:257 133 152 msgid "After product summary" 134 153 msgstr "" 135 154 136 #: admin/options.php: 73137 #: admin/options.php:2 13155 #: admin/options.php:109 156 #: admin/options.php:258 138 157 msgid "Custom - I'll insert a shortcode" 139 158 msgstr "" 140 159 141 #: admin/options.php: 80160 #: admin/options.php:116 142 161 msgid "Shortcode" 143 162 msgstr "" 144 163 145 #: admin/options.php: 87164 #: admin/options.php:123 146 165 msgid "Trigger button" 147 166 msgstr "" 148 167 149 #: admin/options.php: 93168 #: admin/options.php:129 150 169 msgid "Button text" 151 170 msgstr "" 152 171 153 #: admin/options.php: 99172 #: admin/options.php:135 154 173 msgid "Fields" 155 174 msgstr "" 156 175 157 #: admin/options.php:1 05176 #: admin/options.php:141 158 177 msgid "Allow Higher Target Price" 159 178 msgstr "" 160 179 161 #: admin/options.php:1 06180 #: admin/options.php:142 162 181 msgid "Enable customers to set a target price higher than the product's current price." 163 182 msgstr "" 164 183 165 #: admin/options.php:1 12184 #: admin/options.php:148 166 185 #: templates/admin-subscriptions-page.php:33 167 186 msgid "Marketing" 168 187 msgstr "" 169 188 170 #: admin/options.php:1 18189 #: admin/options.php:154 171 190 msgid "Marketing text" 172 191 msgstr "" 173 192 174 #: admin/options.php:1 25193 #: admin/options.php:161 175 194 msgid "GDPR" 176 195 msgstr "" 177 196 178 #: admin/options.php:1 31197 #: admin/options.php:167 179 198 msgid "GDPR text" 180 199 msgstr "" 181 200 182 #: admin/options.php:1 38201 #: admin/options.php:174 183 202 msgid "Honeypot - Anti-Spam" 184 203 msgstr "" 185 204 186 #: admin/options.php:1 39205 #: admin/options.php:175 187 206 msgid "Silently blocks bots and reduces spam submissions with an invisible field that real users won't see. Recommended to keep this enabled for better protection." 188 207 msgstr "" 189 208 190 #: admin/options.php:1 45191 #: admin/options.php:3 32209 #: admin/options.php:181 210 #: admin/options.php:377 192 211 msgid "Design" 193 212 msgstr "" 194 213 195 #: admin/options.php:1 51214 #: admin/options.php:187 196 215 msgid "Primary color" 197 216 msgstr "" 198 217 199 #: admin/options.php:1 57218 #: admin/options.php:193 200 219 msgid "Field style" 201 220 msgstr "" 202 221 203 #: admin/options.php:1 59204 #: admin/options.php:2 21222 #: admin/options.php:195 223 #: admin/options.php:266 205 224 msgid "Default" 206 225 msgstr "" 207 226 208 #: admin/options.php:1 60209 #: admin/options.php:2 22227 #: admin/options.php:196 228 #: admin/options.php:267 210 229 msgid "Standard" 211 230 msgstr "" 212 231 213 #: admin/options.php:1 61214 #: admin/options.php:2 23232 #: admin/options.php:197 233 #: admin/options.php:268 215 234 msgid "Outlined" 216 235 msgstr "" 217 236 218 #: admin/options.php:1 62219 #: admin/options.php:2 24237 #: admin/options.php:198 238 #: admin/options.php:269 220 239 msgid "Filled" 221 240 msgstr "" 222 241 223 #: admin/options.php: 170242 #: admin/options.php:206 224 243 msgid "Intro text" 225 244 msgstr "" 226 245 227 #: admin/options.php: 176246 #: admin/options.php:212 228 247 msgid "Intro headline" 229 248 msgstr "" 230 249 231 #: admin/options.php: 182250 #: admin/options.php:218 232 251 msgid "Intro description" 233 252 msgstr "" 234 253 235 #: admin/options.php:2 44254 #: admin/options.php:289 236 255 msgid "Notifier interval" 237 256 msgstr "" 238 257 239 #: admin/options.php:2 46240 #: admin/options.php: 275258 #: admin/options.php:291 259 #: admin/options.php:320 241 260 msgid "Manual - I'll do it myself" 242 261 msgstr "" 243 262 244 #: admin/options.php:2 47245 #: admin/options.php: 276246 #: includes/notifier.php:4 8263 #: admin/options.php:292 264 #: admin/options.php:321 265 #: includes/notifier.php:49 247 266 msgid "Every 5 minutes" 248 267 msgstr "" 249 268 250 #: admin/options.php:2 48251 #: admin/options.php: 277252 #: includes/notifier.php:4 3269 #: admin/options.php:293 270 #: admin/options.php:322 271 #: includes/notifier.php:44 253 272 msgid "Every 15 minutes" 254 273 msgstr "" 255 274 256 #: admin/options.php:2 49257 #: admin/options.php: 278258 #: includes/notifier.php:3 8275 #: admin/options.php:294 276 #: admin/options.php:323 277 #: includes/notifier.php:39 259 278 msgid "Every 30 minutes" 260 279 msgstr "" 261 280 262 #: admin/options.php:2 50263 #: admin/options.php: 279281 #: admin/options.php:295 282 #: admin/options.php:324 264 283 msgid "Every hour" 265 284 msgstr "" 266 285 267 #: admin/options.php:2 51268 #: admin/options.php: 280286 #: admin/options.php:296 287 #: admin/options.php:325 269 288 msgid "Twice a day" 270 289 msgstr "" 271 290 272 #: admin/options.php:2 52273 #: admin/options.php: 281291 #: admin/options.php:297 292 #: admin/options.php:326 274 293 msgid "Once a day" 275 294 msgstr "" 276 295 277 #: admin/options.php:2 53278 #: admin/options.php: 282296 #: admin/options.php:298 297 #: admin/options.php:327 279 298 msgid "Once a week" 280 299 msgstr "" 281 300 282 #: admin/options.php: 255301 #: admin/options.php:300 283 302 msgid "What is the frequency at which the notifier should verify for any price drops and send notifications to subscribed users" 284 303 msgstr "" 285 304 286 #: admin/options.php:302 287 #: admin/options.php:360 288 #: includes/defaults.php:14 305 #: admin/options.php:347 306 #: admin/options.php:405 289 307 msgid "Subject" 290 308 msgstr "" 291 309 292 #: admin/options.php:3 09293 #: admin/options.php: 367310 #: admin/options.php:354 311 #: admin/options.php:412 294 312 msgid "Heading text" 295 313 msgstr "" 296 314 297 #: admin/options.php:3 16298 #: admin/options.php: 374315 #: admin/options.php:361 316 #: admin/options.php:419 299 317 msgid "Content" 300 318 msgstr "" 301 319 302 #: admin/options.php:3 19320 #: admin/options.php:364 303 321 msgid "Use {price_drops} to display price drops." 304 322 msgstr "" 305 323 306 #: admin/options.php:3 25307 #: admin/options.php: 383324 #: admin/options.php:370 325 #: admin/options.php:428 308 326 msgid "Footer text" 309 327 msgstr "" 310 328 311 #: admin/options.php:3 35329 #: admin/options.php:380 312 330 msgid "Colors and header image are inherited from the" 313 331 msgstr "" 314 332 315 #: admin/options.php:3 36333 #: admin/options.php:381 316 334 msgid "WooCommerce emails." 317 335 msgstr "" 318 336 319 #: admin/options.php:3 42320 #: admin/options.php: 390337 #: admin/options.php:387 338 #: admin/options.php:435 321 339 msgid "Email Template" 322 340 msgstr "" 323 341 324 #: admin/options.php:3 46325 #: admin/options.php: 394342 #: admin/options.php:391 343 #: admin/options.php:439 326 344 msgid "Click here to preview your email template." 327 345 msgstr "" 328 346 329 #: admin/options.php: 377347 #: admin/options.php:422 330 348 msgid "Use {confirm_button} to display confirm button." 349 msgstr "" 350 351 #: admin/product.php:121 352 msgid "Enabling or disabling the form per product is a PRO feature. Upgrade to PRO to use this option." 353 msgstr "" 354 355 #: admin/product.php:132 356 msgid "Disable Form Display" 357 msgstr "" 358 359 #: admin/product.php:134 360 msgid "Uncheck to follow the global setting (form enabled)." 361 msgstr "" 362 363 #: admin/product.php:141 364 msgid "Enable Form Display" 365 msgstr "" 366 367 #: admin/product.php:143 368 msgid "Check to enable the form on this product." 331 369 msgstr "" 332 370 … … 360 398 msgstr "" 361 399 362 #: includes/defaults.php:15 363 msgid "Heading" 364 msgstr "" 365 366 #: includes/defaults.php:16 367 msgid "" 368 "Hi there,\n" 369 "good news! We are excited to inform you that the product(s) you were interested in is now available at a lower price than your target price. Here is a list of the product(s) you showed interest in, along with their current prices:" 370 msgstr "" 371 372 #: includes/defaults.php:17 373 msgid "" 374 "It is a great opportunity to make your purchase and take advantage of these deals. If you have any questions or need help, please feel free to reach out. We are always here to help you out!\n" 375 "Thank you for choosing our company for your shopping needs.\n" 376 "Best regards" 377 msgstr "" 378 379 #. translators: %s: Site name. 380 #: includes/defaults.php:20 381 msgid "%s - Powered by Price Alerts" 382 msgstr "" 383 384 #: includes/defaults.php:41 400 #: includes/defaults.php:35 385 401 msgid "Notify me on price drop" 386 402 msgstr "" 387 403 388 #: includes/defaults.php: 44404 #: includes/defaults.php:38 389 405 msgid "We would like to keep you updated on our latest products and services. To do this, we need your permission to send you marketing communications." 390 406 msgstr "" 391 407 408 #: includes/defaults.php:40 409 msgid "I consent to the collection and processing of my personal data in accordance with the General Data Protection Regulation (GDPR) for the purpose of notifying me when the product price drops below my target price. I understand that I have the right to withdraw my consent at any time." 410 msgstr "" 411 412 #: includes/defaults.php:45 413 msgid "Get Notified When the Price Hits Your Target!" 414 msgstr "" 415 392 416 #: includes/defaults.php:46 393 msgid "I consent to the collection and processing of my personal data in accordance with the General Data Protection Regulation (GDPR) for the purpose of notifying me when the product price drops below my target price. I understand that I have the right to withdraw my consent at any time."394 msgstr ""395 396 #: includes/defaults.php:51397 msgid "Get Notified When the Price Hits Your Target!"398 msgstr ""399 400 #: includes/defaults.php:52401 417 msgid "Enter your desired price and we’ll alert you as soon as the product price drops to your target." 402 418 msgstr "" 403 419 404 #: includes/defaults.php: 82420 #: includes/defaults.php:76 405 421 msgid "Great news – Your watched item(s) just dropped in price!" 406 422 msgstr "" 407 423 408 #: includes/defaults.php: 83424 #: includes/defaults.php:77 409 425 msgid "Price Drop Alert 🎉" 410 426 msgstr "" 411 427 412 #: includes/defaults.php: 84428 #: includes/defaults.php:78 413 429 msgid "" 414 430 "Hi there,\n" … … 422 438 msgstr "" 423 439 424 #: includes/defaults.php: 92425 #: includes/defaults.php:1 12440 #: includes/defaults.php:86 441 #: includes/defaults.php:106 426 442 msgid "Powered by Price Alerts" 427 443 msgstr "" 428 444 429 #: includes/defaults.php:10 7430 #: includes/defaults.php:10 8445 #: includes/defaults.php:101 446 #: includes/defaults.php:102 431 447 msgid "Confirm Your Subscription" 432 448 msgstr "" 433 449 434 #: includes/defaults.php:10 9450 #: includes/defaults.php:103 435 451 msgid "" 436 452 "Thank you for subscribing! Please confirm your subscription by clicking the button below:\n" … … 439 455 msgstr "" 440 456 441 #: includes/helper.php:4 72457 #: includes/helper.php:493 442 458 msgid "No legacy data found to migrate." 443 459 msgstr "" 444 460 445 #: includes/notifier.php:2 26461 #: includes/notifier.php:250 446 462 msgid "Unsubscribe from these alerts" 447 463 msgstr "" 448 464 449 #: includes/notifier.php:2 57465 #: includes/notifier.php:281 450 466 msgid "is now" 451 467 msgstr "" 452 468 453 #: includes/notifier.php:2 59469 #: includes/notifier.php:283 454 470 msgid "Price you were waiting for:" 455 471 msgstr "" 456 472 457 #: includes/notifier.php:2 61473 #: includes/notifier.php:285 458 474 msgid "since:" 459 475 msgstr "" 460 476 461 477 #. translators: %s: URL for confirming the subscription. 462 #: includes/notifier.php:3 68478 #: includes/notifier.php:392 463 479 msgid "<a href=\"%s\" style=\"background-color:#4caf50;color:#ffffff;padding:10px 15px;text-decoration:none;display:inline-block;font-weight:bold;border-radius:5px;\">Confirm Subscription</a>" 464 480 msgstr "" 465 481 466 #: includes/rest-api.php:1 27482 #: includes/rest-api.php:131 467 483 msgid "OMG you can not view private data." 468 484 msgstr "" 469 485 470 #: includes/rest-api.php:15 3486 #: includes/rest-api.php:158 471 487 msgid "Spam detected." 472 488 msgstr "" 473 489 474 #: includes/rest-api.php:1 57490 #: includes/rest-api.php:162 475 491 msgid "Missing required fields." 476 492 msgstr "" 477 493 478 #: includes/rest-api.php:16 2479 #: includes/rest-api.php:2 06494 #: includes/rest-api.php:167 495 #: includes/rest-api.php:211 480 496 msgid "Invalid product ID." 481 497 msgstr "" 482 498 483 #: includes/rest-api.php:19 0499 #: includes/rest-api.php:195 484 500 msgid "Invalid or missing IDs." 485 501 msgstr "" 486 502 487 #: includes/rest-api.php:2 19503 #: includes/rest-api.php:224 488 504 msgid "Missing emailsAndProducts parameter." 489 505 msgstr "" 490 506 491 #: includes/rest-api.php:2 25507 #: includes/rest-api.php:230 492 508 msgid "Invalid emailsAndProducts JSON format." 493 509 msgstr "" 494 510 495 511 #. translators: %d is the number of subscriptions that were migrated. 496 #: includes/rest-api.php:25 4512 #: includes/rest-api.php:259 497 513 msgid "%d subscription was migrated successfully." 498 514 msgid_plural "%d subscriptions were migrated successfully." … … 504 520 msgstr "" 505 521 506 #: public/public.php:2 21522 #: public/public.php:239 507 523 msgid "Before submitting your request, please ensure that you have selected the specific variation you are interested in. Otherwise, you will receive a notification if any of the variations' prices drop below your desired target price." 508 524 msgstr "" 509 525 510 #: public/public.php:2 52526 #: public/public.php:270 511 527 msgid "Your target price" 512 528 msgstr "" 513 529 514 #: public/public.php:2 53530 #: public/public.php:271 515 531 msgid "Your email address" 516 532 msgstr "" 517 533 518 #: public/public.php:3 20534 #: public/public.php:338 519 535 msgid "Email confirmed!" 520 536 msgstr "" 521 537 522 #: public/public.php:3 40538 #: public/public.php:358 523 539 msgid "Invalid or expired unsubscribe link." 524 540 msgstr "" 525 541 526 #: public/public.php:3 45542 #: public/public.php:363 527 543 msgid "You have been unsubscribed from these alerts." 528 544 msgstr "" -
price-alerts/tags/1.0.2/price-alerts.php
r3310498 r3316689 4 4 * Plugin Name: Price Alerts for WooCommerce 5 5 * Description: Allow customers to subscribe to WooCommerce products and get notified when prices drop. 6 * Version: 1.0. 16 * Version: 1.0.2 7 7 * Author: Devnet 8 8 * Author URI: https://devnet.hr … … 13 13 * Requires Plugins: woocommerce 14 14 * WC tested up to: 9.9 15 * 15 16 */ 16 17 use Devnet\PriceAlerts\Includes\Activator; … … 92 93 devnet_pa_fs()->add_action( 'after_uninstall', 'devnet_pa_fs_uninstall_cleanup' ); 93 94 } 94 define( 'DEVNET_PRICE_ALERTS_VERSION', '1.0. 1' );95 define( 'DEVNET_PRICE_ALERTS_VERSION', '1.0.2' ); 95 96 define( 'DEVNET_PRICE_ALERTS_NAME', 'price-alerts' ); 96 97 define( 'DEVNET_PRICE_ALERTS_PATH_DIR', plugin_dir_path( __FILE__ ) ); -
price-alerts/tags/1.0.2/public/public.php
r3309423 r3316689 74 74 return false; 75 75 } 76 return true; 76 $should_display = true; 77 return $should_display; 77 78 } 78 79 -
price-alerts/trunk/README.txt
r3310498 r3316689 4 4 Requires at least: 6.2 5 5 Requires PHP: 7.4 6 Stable tag: 1.0. 16 Stable tag: 1.0.2 7 7 Tested up to: 6.8 8 8 License: GPLv2 or later … … 103 103 == Changelog == 104 104 105 = 1.0.2 = 106 107 *2025-06-24* 108 109 * Fix: Checkbox value saving 110 * Fix: Database cleanup error caused by foreign key constraints upon uninstall 111 * Fix: Cron task not being removed on plugin deactivation 112 * Tweak: Admin UI styling 113 114 105 115 = 1.0.1 = 106 116 … … 112 122 * Performance: WC tested up to 9.9 113 123 114 * Initial release.115 116 124 = 1.0.0 = 117 125 -
price-alerts/trunk/admin/admin.php
r3310498 r3316689 17 17 add_action( 'admin_enqueue_scripts', [$this, 'enqueue_assets'] ); 18 18 add_action( 'admin_menu', [$this, 'admin_menu'], 100 ); 19 add_action(20 'woocommerce_after_product_object_save',21 [$this, 'update_product'],22 10,23 224 );25 19 add_filter( 'plugin_action_links_' . DEVNET_PRICE_ALERTS_PATH_FILE, [$this, 'plugin_action_links'] ); 26 20 add_filter( 'admin_footer_text', [$this, 'admin_credits'] ); … … 145 139 } 146 140 147 public function update_product( $product, $data_store ) {148 $args = [149 'product_id' => $product->get_id(),150 'price' => (float) $product->get_price(),151 'currency' => get_option( 'woocommerce_currency' ),152 ];153 /*154 * Update status for products that meets users target prices.155 */156 Helper::update_status_on_price_change( [157 'new_status' => 'pending',158 'status' => ['assigned'],159 'target_price_is' => 'higher',160 ] + $args );161 /*162 * Revert pending statuses if price is again higher than target price.163 */164 Helper::update_status_on_price_change( [165 'new_status' => 'assigned',166 'status' => ['pending'],167 'target_price_is' => 'lower',168 ] + $args );169 }170 171 141 public function plugin_action_links( $links ) { 172 142 $custom_links = []; -
price-alerts/trunk/admin/options.php
r3309423 r3316689 14 14 'label' => esc_html__( 'Multilingual', 'price-alerts' ), 15 15 'desc' => esc_html__( 'Use your own translated strings.', 'price-alerts' ), 16 'default' => 0, 16 'default' => Defaults::general( 'multilingual' ), 17 ], [ 18 'type' => 'checkbox', 19 'name' => 'multicurrency__disabled', 20 'label' => esc_html__( 'Multi-currency support', 'price-alerts' ), 21 'desc' => esc_html__( "Use customer’s currency when checking if the target price is reached.", 'price-alerts' ), 22 'default' => Defaults::general( 'multicurrency' ), 17 23 ], [ 18 24 'type' => 'checkbox', … … 20 26 'label' => esc_html__( 'Delete all plugin data on uninstall', 'price-alerts' ), 21 27 'desc' => esc_html__( 'Enabling this option will ensure that all data associated with the plugin, including settings and subscribers, will be completely removed from the database upon uninstallation of the plugin.', 'price-alerts' ), 22 'default' => 0,28 'default' => Defaults::general( 'delete_plugin_data' ), 23 29 ]]; 24 30 return apply_filters( 'price_alerts_settings_general', $general ); … … 32 38 'label' => esc_html__( 'Enable', 'price-alerts' ), 33 39 'default' => Defaults::form( 'enable' ), 40 ], 41 [ 42 'type' => 'select', 43 'name' => 'form_scope', 44 'label' => esc_html__( 'Form scope', 'easy-subscribe-woocommerce' ), 45 'options' => [ 46 'all' => esc_html__( 'All Products', 'price-alerts' ), 47 '_disabled_1' => esc_html__( 'All Products (can be disabled per product)', 'price-alerts' ), 48 '_disabled_2' => esc_html__( 'Manual Selection (enable per product)', 'price-alerts' ), 49 ], 50 'default' => Defaults::form( 'form_scope' ), 34 51 ], 35 52 [ -
price-alerts/trunk/assets/build/public.asset.php
r3309423 r3316689 1 <?php return array('dependencies' => array(), 'version' => ' e27b7d5b6dc9d8a5a284');1 <?php return array('dependencies' => array(), 'version' => '2f5fb3f7daa73a3f5a13'); -
price-alerts/trunk/assets/build/public.js
r3309423 r3316689 1 (()=>{"use strict";jQuery(document).ready((function(){const e=jQuery,{ajaxurl:t,nonce:n,text:s,options:o}=devnet_price_alerts_script_data, a={processing:!1,processingElement:{},productType:"simple",isVariation:!1,loader(t){t&&this.processingElement instanceof jQuery?this.processingElement.append('<div id="devnet-pa-spinner" class="al-spinner-backdrop"></div>'):e("#devnet-pa-spinner").remove()},get isProcessing(){return this.processing},set isProcessing(e){this.processing=e,this.loader(this.processing)}},i=e("form.devnet-pa-form"),r=e(".price-alerts-form-wrapper");function c(){r.removeClass("devnet-pa-modal-open")}e(".devnet-pa-open-modal").on("click",(function(t){t.preventDefault(),function(t){const n='button, [href], input, select, textarea, [tabindex]:not([tabindex="-1"])',s=t.find(n)[0],o=t.find(n),a=o[o.length-1];setTimeout((()=>{s.focus()}),0),e(document).on("keydown",(function(e){("Tab"===e.key||9===e.keyCode)&&(e.shiftKey?document.activeElement===s&&(a.focus(),e.preventDefault()):document.activeElement===a&&(s.focus(),e.preventDefault()))}))}(i),r.css("display",""),r[0].offsetHeight,r.addClass("devnet-pa-modal-open")})),e(".devnet-pa-close").on("click",(function(e){e.preventDefault(),c()})),r.on("mousedown touchstart",(function(e){e.target===this&&c()})),e(document).on("keydown",(function(e){"Escape"===e.key&&c()})),i.on("submit",(async function(t){if(t.preventDefault(),a.isProcessing)return;const o=e(this);a.processingElement=o,a.isProcessing=!0,o.addClass("processing"),o.find("button").prop("disabled",!0);const i=o.serializeArray().reduce(((e,t)=>(e[t.name.replace("price_alerts_","")]=t.value,e)),{});i.origin_url=window.location.href;const r=await async function({endpoint:e,method:t="GET",nonce:n="",data:s=null}){const o={method:t,headers:{"X-WP-Nonce":n}};s&&(o.headers["Content-Type"]="application/json",o.body=JSON.stringify(s));try{const t=await fetch(e,o);return await t.json()}catch(e){return console.error("API Request failed:",e),{status:"error",message:"Request failed"}}}({endpoint:"/wp-json/price-alerts/v1/subscribe",method:"POST",nonce:n,data:i});a.isProcessing=!1,["created","updated"].includes(r.response)?(!0===r.pending_confirmation?o.append(`<div class="devnet-pa-message">${s.confirm_email}</div>`):o.append('<div class="devnet-pa-success-animation">\n\t\t\t<svg class="checkmark" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 52 52">\n\t\t\t\t<circle class="checkmark__circle" cx="26" cy="26" r="25" fill="none" />\n\t\t\t\t<path class="checkmark__check" fill="none" d="M14.1 27.2l7.1 7.2 16.7-16.8" />\n\t\t\t</svg>\n\t\t</div>'),o.addClass("submitted")):o.append(`<div class="devnet-pa-message error">${r.message}</div>`),o.find("button").prop("disabled",!1),o.removeClass("processing")})),e(document).on("found_variation","form.cart",(function(t,n){const s=n.variation_id,a=n.display_price,i=e('[name="price_alerts_target_price"]');e('[name="price_alerts_product_id"]').val(s),1==o.allow_higher_target_price?i.attr("max",""):i.attr("max",a)})),e(document).on("reset_data","form.cart",(function(){const t=e(this).data("product_id"),n=e('[name="price_alerts_product_id"]');t!==n.val()&&n.val(t)})),e("form.devnet-pa-field-style-outlined .devnet-pa-text-field").each((function(){const t=e(this),n=t.find("input"),s=t.find("label");function o(){s.css("background-color",function(e){for(;e.length&&!e.is("html");){const t=e.css("background-color");if(t&&"rgba(0, 0, 0, 0)"!==t&&"transparent"!==t)return t;e=e.parent()}return"#fff"}(t))}n.length&&s.length&&(o(),n.on("focus blur",o))}))}))})();1 (()=>{"use strict";jQuery(document).ready((function(){const e=jQuery,{ajaxurl:t,nonce:n,text:s,options:o}=devnet_price_alerts_script_data,i={processing:!1,processingElement:{},productType:"simple",isVariation:!1,loader(t){t&&this.processingElement instanceof jQuery?this.processingElement.append('<div id="devnet-pa-spinner" class="al-spinner-backdrop"></div>'):e("#devnet-pa-spinner").remove()},get isProcessing(){return this.processing},set isProcessing(e){this.processing=e,this.loader(this.processing)}},a=e("form.devnet-pa-form"),r=e(".price-alerts-form-wrapper");function c(){r.removeClass("devnet-pa-modal-open")}e(".devnet-pa-open-modal").on("click",(function(t){t.preventDefault(),function(t){const n='button, [href], input, select, textarea, [tabindex]:not([tabindex="-1"])',s=t.find(n)[0],o=t.find(n),i=o[o.length-1];setTimeout((()=>{s.focus()}),0),e(document).on("keydown",(function(e){("Tab"===e.key||9===e.keyCode)&&(e.shiftKey?document.activeElement===s&&(i.focus(),e.preventDefault()):document.activeElement===i&&(s.focus(),e.preventDefault()))}))}(a),r.css("display",""),r[0].offsetHeight,r.addClass("devnet-pa-modal-open")})),e(".devnet-pa-close").on("click",(function(e){e.preventDefault(),c()})),r.on("mousedown touchstart",(function(e){e.target===this&&c()})),e(document).on("keydown",(function(e){"Escape"===e.key&&c()})),a.on("submit",(async function(t){if(t.preventDefault(),i.isProcessing)return;const o=e(this);i.processingElement=o,i.isProcessing=!0,o.addClass("processing"),o.find("button").prop("disabled",!0);const a=o.serializeArray().reduce(((e,t)=>(e[t.name.replace("price_alerts_","")]=t.value,e)),{});a.origin_url=window.location.href,a.currency=window?.wcml_mc_settings?.current_currency?.code;const r=await async function({endpoint:e,method:t="GET",nonce:n="",data:s=null}){const o={method:t,headers:{"X-WP-Nonce":n}};s&&(o.headers["Content-Type"]="application/json",o.body=JSON.stringify(s));try{const t=await fetch(e,o);return await t.json()}catch(e){return console.error("API Request failed:",e),{status:"error",message:"Request failed"}}}({endpoint:"/wp-json/price-alerts/v1/subscribe",method:"POST",nonce:n,data:a});i.isProcessing=!1,["created","updated"].includes(r.response)?(!0===r.pending_confirmation?o.append(`<div class="devnet-pa-message">${s.confirm_email}</div>`):o.append('<div class="devnet-pa-success-animation">\n\t\t\t<svg class="checkmark" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 52 52">\n\t\t\t\t<circle class="checkmark__circle" cx="26" cy="26" r="25" fill="none" />\n\t\t\t\t<path class="checkmark__check" fill="none" d="M14.1 27.2l7.1 7.2 16.7-16.8" />\n\t\t\t</svg>\n\t\t</div>'),o.addClass("submitted")):o.append(`<div class="devnet-pa-message error">${r.message}</div>`),o.find("button").prop("disabled",!1),o.removeClass("processing")})),e(document).on("found_variation","form.cart",(function(t,n){const s=n.variation_id,i=n.display_price,a=e('[name="price_alerts_target_price"]');e('[name="price_alerts_product_id"]').val(s),1==o.allow_higher_target_price?a.attr("max",""):a.attr("max",i)})),e(document).on("reset_data","form.cart",(function(){const t=e(this).data("product_id"),n=e('[name="price_alerts_product_id"]');t!==n.val()&&n.val(t)})),e("form.devnet-pa-field-style-outlined .devnet-pa-text-field").each((function(){const t=e(this),n=t.find("input"),s=t.find("label");function o(){s.css("background-color",function(e){for(;e.length&&!e.is("html");){const t=e.css("background-color");if(t&&"rgba(0, 0, 0, 0)"!==t&&"transparent"!==t)return t;e=e.parent()}return"#fff"}(t))}n.length&&s.length&&(o(),n.on("focus blur",o))}))}))})(); -
price-alerts/trunk/includes/deactivator.php
r3309423 r3316689 9 9 { 10 10 11 public static function deactivate() {} 11 public static function deactivate() 12 { 13 wp_clear_scheduled_hook('price_alerts_schedule'); 14 } 12 15 } -
price-alerts/trunk/includes/defaults.php
r3309423 r3316689 11 11 { 12 12 $options = [ 13 'notifier_interval' => '', 14 'email_subject' => esc_html__('Subject', 'price-alerts'), 15 'email_heading' => esc_html__('Heading', 'price-alerts'), 16 'email_content_1' => esc_html__("Hi there,\ngood news! We are excited to inform you that the product(s) you were interested in is now available at a lower price than your target price. Here is a list of the product(s) you showed interest in, along with their current prices:", 'price-alerts'), 17 'email_content_2' => esc_html__("It is a great opportunity to make your purchase and take advantage of these deals. If you have any questions or need help, please feel free to reach out. We are always here to help you out!\nThank you for choosing our company for your shopping needs.\nBest regards", 'price-alerts'), 18 'email_footer' => sprintf( 19 // translators: %s: Site name. 20 esc_html__('%s - Powered by Price Alerts', 'price-alerts'), 21 get_bloginfo('name', 'display') 22 ) 13 'multilingual' => 0, 14 'multicurrency' => 0, 15 'delete_plugin_data' => 0, 23 16 ]; 24 17 … … 36 29 $options = [ 37 30 'enable' => 0, 31 'form_scope' => 'all', 38 32 'only_logged_in_users' => 0, 39 33 'display_mode' => 'inline', -
price-alerts/trunk/includes/helper.php
r3309423 r3316689 303 303 304 304 305 /** 306 * Return all distinct currencies that have active subscriptions 307 * for this product (assigned + pending only). 308 */ 309 public static function get_sub_currencies_for_product($product_id) 310 { 311 global $wpdb; 312 $table = self::get_table_name('subs'); 313 314 return $wpdb->get_col( 315 $wpdb->prepare( 316 "SELECT DISTINCT currency 317 FROM {$table} 318 WHERE product_id = %d 319 AND status IN ('assigned','pending')", 320 $product_id 321 ) 322 ); 323 } 324 325 305 326 public static function evaluate_status_after_confirmation($subscription_id) 306 327 { … … 607 628 return [round($h), round($s * 100), round($l * 100)]; 608 629 } 630 631 632 /** 633 * Check if price is valid. 634 * 635 */ 636 public static function is_valid_price($price) 637 { 638 // Check if the price is numeric or a string that can be converted to a float 639 return is_numeric($price) || (is_string($price) && preg_match('/^\d+(\,\d+)?$/', $price)); 640 } 641 642 /** 643 * Convert number/numeric string to float. 644 * 645 */ 646 public static function convert_to_float($price) 647 { 648 // Convert a price formatted with a comma to a float 649 if (is_string($price)) { 650 $price = str_replace(',', '.', $price); 651 } 652 return floatval($price); 653 } 609 654 } -
price-alerts/trunk/includes/notifier.php
r3309423 r3316689 3 3 namespace Devnet\PriceAlerts\Includes; 4 4 5 use Devnet\PriceAlerts\Includes\Compatibility\CompatibilityManager; 5 6 use Devnet\PriceAlerts\Includes\Helper; 6 7 use Devnet\PriceAlerts\Includes\Defaults; … … 21 22 return; 22 23 } 23 $options = DEVNET_PRICE_ALERTS_OPTIONS['email_price_drop'] ;24 $options = DEVNET_PRICE_ALERTS_OPTIONS['email_price_drop'] ?? []; 24 25 $email_subject = $options['subject'] ?? Defaults::email_price_drop( 'subject' ); 25 // $enabled = $options['enable'] ?? false; 26 // if (!$enabled) { 27 // return; 28 // } 29 $current_currency = get_woocommerce_currency(); 26 // Get the default WooCommerce currency directly from settings to avoid any filters applied by plugins. 27 $current_currency = get_option( 'woocommerce_currency' ); 30 28 $email_data = []; 31 29 $__instance = new self(); … … 58 56 $current_currency = $data['current_currency'] ?? ''; 59 57 $products = $data['products'] ?? []; 58 $multicurrency = DEVNET_PRICE_ALERTS_OPTIONS['general']['multicurrency'] ?? false; 60 59 $sent = false; 61 60 foreach ( $products as $key => &$p ) { … … 64 63 continue; 65 64 } 65 $has_currency_mismatch = $current_currency !== $p['currency']; 66 66 $price = wc_get_price_to_display( $product ); 67 if ( $has_currency_mismatch ) { 68 $is_converted = false; 69 if ( !$is_converted ) { 70 $this->update_status( $p['entryId'], 'failed' ); 71 unset($products[$key]); 72 continue; 73 } 74 } 67 75 $price = apply_filters( 68 76 'price_alerts_notifier_product_price', … … 71 79 $product 72 80 ); 73 $has_currency_mismatch = $current_currency !== $p['currency'];74 $has_currency_mismatch = apply_filters( 'price_alerts_notifier_currency_check', $has_currency_mismatch );75 if ( $has_currency_mismatch ) {76 $this->update_status( $p['entryId'], 'blocked' );77 unset($products[$key]);78 continue;79 }80 81 if ( (float) $price <= (float) $p['targetPrice'] ) { 81 82 $p['price'] = $price; -
price-alerts/trunk/includes/plugin.php
r3309423 r3316689 4 4 5 5 use Devnet\PriceAlerts\Admin\AdminSide; 6 use Devnet\PriceAlerts\Admin\Product; 6 7 use Devnet\PriceAlerts\Frontend\PublicSide; 8 if ( !defined( 'ABSPATH' ) ) { 9 exit; 10 } 11 class Plugin { 12 protected $plugin_name; 7 13 8 if (! defined('ABSPATH')) exit;14 protected $version; 9 15 16 public function __construct() { 17 if ( defined( 'DEVNET_PRICE_ALERTS_VERSION' ) ) { 18 $this->version = DEVNET_PRICE_ALERTS_VERSION; 19 } else { 20 $this->version = '1.0.0'; 21 } 22 if ( defined( 'DEVNET_PRICE_ALERTS_NAME' ) ) { 23 $this->plugin_name = DEVNET_PRICE_ALERTS_NAME; 24 } else { 25 $this->plugin_name = 'price-alerts'; 26 } 27 $this->load_dependencies(); 28 } 10 29 11 class Plugin 12 { 30 private function load_dependencies() { 31 require_once plugin_dir_path( dirname( __FILE__ ) ) . 'includes/defaults.php'; 32 require_once plugin_dir_path( dirname( __FILE__ ) ) . 'includes/helper.php'; 33 require_once plugin_dir_path( dirname( __FILE__ ) ) . 'includes/notifier.php'; 34 require_once plugin_dir_path( dirname( __FILE__ ) ) . 'includes/rest-api.php'; 35 require_once plugin_dir_path( dirname( __FILE__ ) ) . 'includes/queue/wp-async-request.php'; 36 require_once plugin_dir_path( dirname( __FILE__ ) ) . 'includes/queue/wp-background-process.php'; 37 require_once plugin_dir_path( dirname( __FILE__ ) ) . 'includes/queue/queue.php'; 38 require_once plugin_dir_path( dirname( __FILE__ ) ) . 'admin/settings-api.php'; 39 require_once plugin_dir_path( dirname( __FILE__ ) ) . 'admin/options.php'; 40 require_once plugin_dir_path( dirname( __FILE__ ) ) . 'admin/settings.php'; 41 require_once plugin_dir_path( dirname( __FILE__ ) ) . 'admin/admin.php'; 42 require_once plugin_dir_path( dirname( __FILE__ ) ) . 'admin/product.php'; 43 require_once plugin_dir_path( dirname( __FILE__ ) ) . 'public/public.php'; 44 } 13 45 14 protected $plugin_name; 15 protected $version; 46 public function run() { 47 new RestApi(); 48 new Notifier(); 49 new Product(); 50 new AdminSide($this->get_plugin_name(), $this->get_version()); 51 new PublicSide($this->get_plugin_name(), $this->get_version()); 52 } 16 53 17 public function __construct() 18 { 19 if (defined('DEVNET_PRICE_ALERTS_VERSION')) { 20 $this->version = DEVNET_PRICE_ALERTS_VERSION; 21 } else { 22 $this->version = '1.0.0'; 23 } 54 public function get_plugin_name() { 55 return $this->plugin_name; 56 } 24 57 25 if (defined('DEVNET_PRICE_ALERTS_NAME')) { 26 $this->plugin_name = DEVNET_PRICE_ALERTS_NAME; 27 } else { 28 $this->plugin_name = 'price-alerts'; 29 } 58 public function get_version() { 59 return $this->version; 60 } 30 61 31 $this->load_dependencies();32 }33 34 private function load_dependencies()35 {36 require_once plugin_dir_path(dirname(__FILE__)) . 'includes/defaults.php';37 require_once plugin_dir_path(dirname(__FILE__)) . 'includes/helper.php';38 require_once plugin_dir_path(dirname(__FILE__)) . 'includes/notifier.php';39 require_once plugin_dir_path(dirname(__FILE__)) . 'includes/rest-api.php';40 41 require_once plugin_dir_path(dirname(__FILE__)) . 'includes/queue/wp-async-request.php';42 require_once plugin_dir_path(dirname(__FILE__)) . 'includes/queue/wp-background-process.php';43 require_once plugin_dir_path(dirname(__FILE__)) . 'includes/queue/queue.php';44 45 46 require_once plugin_dir_path(dirname(__FILE__)) . 'admin/settings-api.php';47 require_once plugin_dir_path(dirname(__FILE__)) . 'admin/options.php';48 require_once plugin_dir_path(dirname(__FILE__)) . 'admin/settings.php';49 require_once plugin_dir_path(dirname(__FILE__)) . 'admin/admin.php';50 51 require_once plugin_dir_path(dirname(__FILE__)) . 'public/public.php';52 }53 54 55 public function run()56 {57 new RestApi();58 new Notifier();59 new AdminSide($this->get_plugin_name(), $this->get_version());60 new PublicSide($this->get_plugin_name(), $this->get_version());61 }62 63 64 public function get_plugin_name()65 {66 return $this->plugin_name;67 }68 69 public function get_version()70 {71 return $this->version;72 }73 62 } -
price-alerts/trunk/includes/rest-api.php
r3309423 r3316689 76 76 'type' => 'number', 77 77 'required' => true 78 ], 79 'currency' => [ 80 'type' => 'string', 81 'sanitize_callback' => 'sanitize_text_field' 78 82 ], 79 83 'marketing' => [ … … 149 153 $email = sanitize_email($request->get_param('email')); 150 154 $honeypot = sanitize_text_field($request->get_param('hp')); 155 $currency = sanitize_text_field($request->get_param('currency')); 151 156 152 157 if ($honeypot) { … … 174 179 $raw_data['product_price'] = $product->get_price(); 175 180 $raw_data['product_type'] = $product->get_type(); 176 $raw_data['currency'] = get_woocommerce_currency();181 $raw_data['currency'] = !empty($currency) ? $currency : get_woocommerce_currency(); 177 182 $raw_data['double_opt_in'] = DEVNET_PRICE_ALERTS_OPTIONS['form']['double_opt_in'] ?? false; 178 183 $raw_data['origin_url'] = esc_url_raw($request->get_param('origin_url') ?? ''); -
price-alerts/trunk/includes/uninstaller.php
r3309423 r3316689 49 49 50 50 $tables = [ 51 'price_alerts_meta', 51 52 'price_alerts_subscriptions', 52 'price_alerts_meta',53 53 ]; 54 54 -
price-alerts/trunk/languages/price-alerts.pot
r3310498 r3316689 3 3 msgid "" 4 4 msgstr "" 5 "Project-Id-Version: Price Alerts for WooCommerce 1.0. 0\n"5 "Project-Id-Version: Price Alerts for WooCommerce 1.0.2\n" 6 6 "Report-Msgid-Bugs-To: https://wordpress.org/support/plugin/price-alerts\n" 7 7 "Last-Translator: FULL NAME <EMAIL@ADDRESS>\n" … … 10 10 "Content-Type: text/plain; charset=UTF-8\n" 11 11 "Content-Transfer-Encoding: 8bit\n" 12 "POT-Creation-Date: 2025-06- 12T11:52:16+00:00\n"12 "POT-Creation-Date: 2025-06-23T20:05:30+00:00\n" 13 13 "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" 14 "X-Generator: WP-CLI 2. 11.0\n"14 "X-Generator: WP-CLI 2.5.1-alpha-70ffdce\n" 15 15 "X-Domain: price-alerts\n" 16 16 17 17 #. Plugin Name of the plugin 18 #: price-alerts.php19 18 msgid "Price Alerts for WooCommerce" 20 19 msgstr "" 21 20 22 21 #. Description of the plugin 23 #: price-alerts.php24 22 msgid "Allow customers to subscribe to WooCommerce products and get notified when prices drop." 25 23 msgstr "" 26 24 27 25 #. Author of the plugin 28 #: price-alerts.php29 26 msgid "Devnet" 30 27 msgstr "" 31 28 32 29 #. Author URI of the plugin 33 #: price-alerts.php34 30 msgid "https://devnet.hr" 35 31 msgstr "" 36 32 37 #: admin/admin.php:6 133 #: admin/admin.php:60 38 34 msgid "Migrate data from the previous plugin now?" 39 35 msgstr "" 40 36 41 #: admin/admin.php:8 137 #: admin/admin.php:80 42 38 msgid "The notification has already been sent to certain users who were selected. Are you certain that you wish to send the notification again?" 43 39 msgstr "" 44 40 45 41 #. translators: %s: the number of notified users. 46 #: admin/admin.php:8 342 #: admin/admin.php:82 47 43 msgid "Successfully notified %s user(s)." 48 44 msgstr "" 49 45 50 46 #. translators: %s: the number of failed notifications. 47 #: admin/admin.php:84 48 msgid "%s selected user(s) were not notified." 49 msgstr "" 50 51 51 #: admin/admin.php:85 52 msgid "%s selected user(s) were not notified."53 msgstr ""54 55 #: admin/admin.php:8656 52 msgid "Are you sure you want to proceed with this action?" 57 53 msgstr "" 58 54 55 #: admin/admin.php:101 59 56 #: admin/admin.php:102 60 #: admin/ admin.php:10357 #: admin/product.php:99 61 58 msgid "Price Alerts" 62 59 msgstr "" 63 60 61 #: admin/admin.php:112 64 62 #: admin/admin.php:113 65 #: admin/admin.php:114 66 #: admin/admin.php:166 63 #: admin/admin.php:137 67 64 msgid "Settings" 68 65 msgstr "" 69 66 67 #: admin/admin.php:120 70 68 #: admin/admin.php:121 71 #: admin/admin.php:12272 69 #: templates/admin-subscriptions-page.php:5 73 70 msgid "Subscriptions" … … 83 80 84 81 #: admin/options.php:25 82 msgid "Multi-currency support" 83 msgstr "" 84 85 #: admin/options.php:26 86 msgid "Use customer’s currency when checking if the target price is reached." 87 msgstr "" 88 89 #: admin/options.php:32 85 90 msgid "Delete all plugin data on uninstall" 86 91 msgstr "" 87 92 88 #: admin/options.php: 2693 #: admin/options.php:33 89 94 msgid "Enabling this option will ensure that all data associated with the plugin, including settings and subscribers, will be completely removed from the database upon uninstallation of the plugin." 90 95 msgstr "" 91 96 92 #: admin/options.php: 4097 #: admin/options.php:65 93 98 msgid "Enable" 94 99 msgstr "" 95 100 96 #: admin/options.php:46 101 #: admin/options.php:73 102 msgid "All Products" 103 msgstr "" 104 105 #: admin/options.php:74 106 #: admin/options.php:238 107 msgid "All Products (can be disabled per product)" 108 msgstr "" 109 110 #: admin/options.php:75 111 #: admin/options.php:239 112 msgid "Manual Selection (enable per product)" 113 msgstr "" 114 115 #: admin/options.php:82 97 116 msgid "Double Opt-in" 98 117 msgstr "" 99 118 100 #: admin/options.php: 47119 #: admin/options.php:83 101 120 msgid "After the user submits their email, they receive a confirmation email with a request to confirm their subscription" 102 121 msgstr "" 103 122 104 #: admin/options.php: 53123 #: admin/options.php:89 105 124 msgid "Show only for logged in users" 106 125 msgstr "" 107 126 108 #: admin/options.php: 59127 #: admin/options.php:95 109 128 msgid "Display mode" 110 129 msgstr "" 111 130 112 #: admin/options.php: 61113 #: admin/options.php:2 02131 #: admin/options.php:97 132 #: admin/options.php:247 114 133 msgid "Modal (popup)" 115 134 msgstr "" 116 135 117 #: admin/options.php: 62118 #: admin/options.php:2 03136 #: admin/options.php:98 137 #: admin/options.php:248 119 138 msgid "Inline (show form directly)" 120 139 msgstr "" 121 140 122 #: admin/options.php: 69141 #: admin/options.php:105 123 142 msgid "Position" 124 143 msgstr "" 125 144 126 #: admin/options.php: 71127 #: admin/options.php:2 11145 #: admin/options.php:107 146 #: admin/options.php:256 128 147 msgid "Before product meta" 129 148 msgstr "" 130 149 131 #: admin/options.php: 72132 #: admin/options.php:2 12150 #: admin/options.php:108 151 #: admin/options.php:257 133 152 msgid "After product summary" 134 153 msgstr "" 135 154 136 #: admin/options.php: 73137 #: admin/options.php:2 13155 #: admin/options.php:109 156 #: admin/options.php:258 138 157 msgid "Custom - I'll insert a shortcode" 139 158 msgstr "" 140 159 141 #: admin/options.php: 80160 #: admin/options.php:116 142 161 msgid "Shortcode" 143 162 msgstr "" 144 163 145 #: admin/options.php: 87164 #: admin/options.php:123 146 165 msgid "Trigger button" 147 166 msgstr "" 148 167 149 #: admin/options.php: 93168 #: admin/options.php:129 150 169 msgid "Button text" 151 170 msgstr "" 152 171 153 #: admin/options.php: 99172 #: admin/options.php:135 154 173 msgid "Fields" 155 174 msgstr "" 156 175 157 #: admin/options.php:1 05176 #: admin/options.php:141 158 177 msgid "Allow Higher Target Price" 159 178 msgstr "" 160 179 161 #: admin/options.php:1 06180 #: admin/options.php:142 162 181 msgid "Enable customers to set a target price higher than the product's current price." 163 182 msgstr "" 164 183 165 #: admin/options.php:1 12184 #: admin/options.php:148 166 185 #: templates/admin-subscriptions-page.php:33 167 186 msgid "Marketing" 168 187 msgstr "" 169 188 170 #: admin/options.php:1 18189 #: admin/options.php:154 171 190 msgid "Marketing text" 172 191 msgstr "" 173 192 174 #: admin/options.php:1 25193 #: admin/options.php:161 175 194 msgid "GDPR" 176 195 msgstr "" 177 196 178 #: admin/options.php:1 31197 #: admin/options.php:167 179 198 msgid "GDPR text" 180 199 msgstr "" 181 200 182 #: admin/options.php:1 38201 #: admin/options.php:174 183 202 msgid "Honeypot - Anti-Spam" 184 203 msgstr "" 185 204 186 #: admin/options.php:1 39205 #: admin/options.php:175 187 206 msgid "Silently blocks bots and reduces spam submissions with an invisible field that real users won't see. Recommended to keep this enabled for better protection." 188 207 msgstr "" 189 208 190 #: admin/options.php:1 45191 #: admin/options.php:3 32209 #: admin/options.php:181 210 #: admin/options.php:377 192 211 msgid "Design" 193 212 msgstr "" 194 213 195 #: admin/options.php:1 51214 #: admin/options.php:187 196 215 msgid "Primary color" 197 216 msgstr "" 198 217 199 #: admin/options.php:1 57218 #: admin/options.php:193 200 219 msgid "Field style" 201 220 msgstr "" 202 221 203 #: admin/options.php:1 59204 #: admin/options.php:2 21222 #: admin/options.php:195 223 #: admin/options.php:266 205 224 msgid "Default" 206 225 msgstr "" 207 226 208 #: admin/options.php:1 60209 #: admin/options.php:2 22227 #: admin/options.php:196 228 #: admin/options.php:267 210 229 msgid "Standard" 211 230 msgstr "" 212 231 213 #: admin/options.php:1 61214 #: admin/options.php:2 23232 #: admin/options.php:197 233 #: admin/options.php:268 215 234 msgid "Outlined" 216 235 msgstr "" 217 236 218 #: admin/options.php:1 62219 #: admin/options.php:2 24237 #: admin/options.php:198 238 #: admin/options.php:269 220 239 msgid "Filled" 221 240 msgstr "" 222 241 223 #: admin/options.php: 170242 #: admin/options.php:206 224 243 msgid "Intro text" 225 244 msgstr "" 226 245 227 #: admin/options.php: 176246 #: admin/options.php:212 228 247 msgid "Intro headline" 229 248 msgstr "" 230 249 231 #: admin/options.php: 182250 #: admin/options.php:218 232 251 msgid "Intro description" 233 252 msgstr "" 234 253 235 #: admin/options.php:2 44254 #: admin/options.php:289 236 255 msgid "Notifier interval" 237 256 msgstr "" 238 257 239 #: admin/options.php:2 46240 #: admin/options.php: 275258 #: admin/options.php:291 259 #: admin/options.php:320 241 260 msgid "Manual - I'll do it myself" 242 261 msgstr "" 243 262 244 #: admin/options.php:2 47245 #: admin/options.php: 276246 #: includes/notifier.php:4 8263 #: admin/options.php:292 264 #: admin/options.php:321 265 #: includes/notifier.php:49 247 266 msgid "Every 5 minutes" 248 267 msgstr "" 249 268 250 #: admin/options.php:2 48251 #: admin/options.php: 277252 #: includes/notifier.php:4 3269 #: admin/options.php:293 270 #: admin/options.php:322 271 #: includes/notifier.php:44 253 272 msgid "Every 15 minutes" 254 273 msgstr "" 255 274 256 #: admin/options.php:2 49257 #: admin/options.php: 278258 #: includes/notifier.php:3 8275 #: admin/options.php:294 276 #: admin/options.php:323 277 #: includes/notifier.php:39 259 278 msgid "Every 30 minutes" 260 279 msgstr "" 261 280 262 #: admin/options.php:2 50263 #: admin/options.php: 279281 #: admin/options.php:295 282 #: admin/options.php:324 264 283 msgid "Every hour" 265 284 msgstr "" 266 285 267 #: admin/options.php:2 51268 #: admin/options.php: 280286 #: admin/options.php:296 287 #: admin/options.php:325 269 288 msgid "Twice a day" 270 289 msgstr "" 271 290 272 #: admin/options.php:2 52273 #: admin/options.php: 281291 #: admin/options.php:297 292 #: admin/options.php:326 274 293 msgid "Once a day" 275 294 msgstr "" 276 295 277 #: admin/options.php:2 53278 #: admin/options.php: 282296 #: admin/options.php:298 297 #: admin/options.php:327 279 298 msgid "Once a week" 280 299 msgstr "" 281 300 282 #: admin/options.php: 255301 #: admin/options.php:300 283 302 msgid "What is the frequency at which the notifier should verify for any price drops and send notifications to subscribed users" 284 303 msgstr "" 285 304 286 #: admin/options.php:302 287 #: admin/options.php:360 288 #: includes/defaults.php:14 305 #: admin/options.php:347 306 #: admin/options.php:405 289 307 msgid "Subject" 290 308 msgstr "" 291 309 292 #: admin/options.php:3 09293 #: admin/options.php: 367310 #: admin/options.php:354 311 #: admin/options.php:412 294 312 msgid "Heading text" 295 313 msgstr "" 296 314 297 #: admin/options.php:3 16298 #: admin/options.php: 374315 #: admin/options.php:361 316 #: admin/options.php:419 299 317 msgid "Content" 300 318 msgstr "" 301 319 302 #: admin/options.php:3 19320 #: admin/options.php:364 303 321 msgid "Use {price_drops} to display price drops." 304 322 msgstr "" 305 323 306 #: admin/options.php:3 25307 #: admin/options.php: 383324 #: admin/options.php:370 325 #: admin/options.php:428 308 326 msgid "Footer text" 309 327 msgstr "" 310 328 311 #: admin/options.php:3 35329 #: admin/options.php:380 312 330 msgid "Colors and header image are inherited from the" 313 331 msgstr "" 314 332 315 #: admin/options.php:3 36333 #: admin/options.php:381 316 334 msgid "WooCommerce emails." 317 335 msgstr "" 318 336 319 #: admin/options.php:3 42320 #: admin/options.php: 390337 #: admin/options.php:387 338 #: admin/options.php:435 321 339 msgid "Email Template" 322 340 msgstr "" 323 341 324 #: admin/options.php:3 46325 #: admin/options.php: 394342 #: admin/options.php:391 343 #: admin/options.php:439 326 344 msgid "Click here to preview your email template." 327 345 msgstr "" 328 346 329 #: admin/options.php: 377347 #: admin/options.php:422 330 348 msgid "Use {confirm_button} to display confirm button." 349 msgstr "" 350 351 #: admin/product.php:121 352 msgid "Enabling or disabling the form per product is a PRO feature. Upgrade to PRO to use this option." 353 msgstr "" 354 355 #: admin/product.php:132 356 msgid "Disable Form Display" 357 msgstr "" 358 359 #: admin/product.php:134 360 msgid "Uncheck to follow the global setting (form enabled)." 361 msgstr "" 362 363 #: admin/product.php:141 364 msgid "Enable Form Display" 365 msgstr "" 366 367 #: admin/product.php:143 368 msgid "Check to enable the form on this product." 331 369 msgstr "" 332 370 … … 360 398 msgstr "" 361 399 362 #: includes/defaults.php:15 363 msgid "Heading" 364 msgstr "" 365 366 #: includes/defaults.php:16 367 msgid "" 368 "Hi there,\n" 369 "good news! We are excited to inform you that the product(s) you were interested in is now available at a lower price than your target price. Here is a list of the product(s) you showed interest in, along with their current prices:" 370 msgstr "" 371 372 #: includes/defaults.php:17 373 msgid "" 374 "It is a great opportunity to make your purchase and take advantage of these deals. If you have any questions or need help, please feel free to reach out. We are always here to help you out!\n" 375 "Thank you for choosing our company for your shopping needs.\n" 376 "Best regards" 377 msgstr "" 378 379 #. translators: %s: Site name. 380 #: includes/defaults.php:20 381 msgid "%s - Powered by Price Alerts" 382 msgstr "" 383 384 #: includes/defaults.php:41 400 #: includes/defaults.php:35 385 401 msgid "Notify me on price drop" 386 402 msgstr "" 387 403 388 #: includes/defaults.php: 44404 #: includes/defaults.php:38 389 405 msgid "We would like to keep you updated on our latest products and services. To do this, we need your permission to send you marketing communications." 390 406 msgstr "" 391 407 408 #: includes/defaults.php:40 409 msgid "I consent to the collection and processing of my personal data in accordance with the General Data Protection Regulation (GDPR) for the purpose of notifying me when the product price drops below my target price. I understand that I have the right to withdraw my consent at any time." 410 msgstr "" 411 412 #: includes/defaults.php:45 413 msgid "Get Notified When the Price Hits Your Target!" 414 msgstr "" 415 392 416 #: includes/defaults.php:46 393 msgid "I consent to the collection and processing of my personal data in accordance with the General Data Protection Regulation (GDPR) for the purpose of notifying me when the product price drops below my target price. I understand that I have the right to withdraw my consent at any time."394 msgstr ""395 396 #: includes/defaults.php:51397 msgid "Get Notified When the Price Hits Your Target!"398 msgstr ""399 400 #: includes/defaults.php:52401 417 msgid "Enter your desired price and we’ll alert you as soon as the product price drops to your target." 402 418 msgstr "" 403 419 404 #: includes/defaults.php: 82420 #: includes/defaults.php:76 405 421 msgid "Great news – Your watched item(s) just dropped in price!" 406 422 msgstr "" 407 423 408 #: includes/defaults.php: 83424 #: includes/defaults.php:77 409 425 msgid "Price Drop Alert 🎉" 410 426 msgstr "" 411 427 412 #: includes/defaults.php: 84428 #: includes/defaults.php:78 413 429 msgid "" 414 430 "Hi there,\n" … … 422 438 msgstr "" 423 439 424 #: includes/defaults.php: 92425 #: includes/defaults.php:1 12440 #: includes/defaults.php:86 441 #: includes/defaults.php:106 426 442 msgid "Powered by Price Alerts" 427 443 msgstr "" 428 444 429 #: includes/defaults.php:10 7430 #: includes/defaults.php:10 8445 #: includes/defaults.php:101 446 #: includes/defaults.php:102 431 447 msgid "Confirm Your Subscription" 432 448 msgstr "" 433 449 434 #: includes/defaults.php:10 9450 #: includes/defaults.php:103 435 451 msgid "" 436 452 "Thank you for subscribing! Please confirm your subscription by clicking the button below:\n" … … 439 455 msgstr "" 440 456 441 #: includes/helper.php:4 72457 #: includes/helper.php:493 442 458 msgid "No legacy data found to migrate." 443 459 msgstr "" 444 460 445 #: includes/notifier.php:2 26461 #: includes/notifier.php:250 446 462 msgid "Unsubscribe from these alerts" 447 463 msgstr "" 448 464 449 #: includes/notifier.php:2 57465 #: includes/notifier.php:281 450 466 msgid "is now" 451 467 msgstr "" 452 468 453 #: includes/notifier.php:2 59469 #: includes/notifier.php:283 454 470 msgid "Price you were waiting for:" 455 471 msgstr "" 456 472 457 #: includes/notifier.php:2 61473 #: includes/notifier.php:285 458 474 msgid "since:" 459 475 msgstr "" 460 476 461 477 #. translators: %s: URL for confirming the subscription. 462 #: includes/notifier.php:3 68478 #: includes/notifier.php:392 463 479 msgid "<a href=\"%s\" style=\"background-color:#4caf50;color:#ffffff;padding:10px 15px;text-decoration:none;display:inline-block;font-weight:bold;border-radius:5px;\">Confirm Subscription</a>" 464 480 msgstr "" 465 481 466 #: includes/rest-api.php:1 27482 #: includes/rest-api.php:131 467 483 msgid "OMG you can not view private data." 468 484 msgstr "" 469 485 470 #: includes/rest-api.php:15 3486 #: includes/rest-api.php:158 471 487 msgid "Spam detected." 472 488 msgstr "" 473 489 474 #: includes/rest-api.php:1 57490 #: includes/rest-api.php:162 475 491 msgid "Missing required fields." 476 492 msgstr "" 477 493 478 #: includes/rest-api.php:16 2479 #: includes/rest-api.php:2 06494 #: includes/rest-api.php:167 495 #: includes/rest-api.php:211 480 496 msgid "Invalid product ID." 481 497 msgstr "" 482 498 483 #: includes/rest-api.php:19 0499 #: includes/rest-api.php:195 484 500 msgid "Invalid or missing IDs." 485 501 msgstr "" 486 502 487 #: includes/rest-api.php:2 19503 #: includes/rest-api.php:224 488 504 msgid "Missing emailsAndProducts parameter." 489 505 msgstr "" 490 506 491 #: includes/rest-api.php:2 25507 #: includes/rest-api.php:230 492 508 msgid "Invalid emailsAndProducts JSON format." 493 509 msgstr "" 494 510 495 511 #. translators: %d is the number of subscriptions that were migrated. 496 #: includes/rest-api.php:25 4512 #: includes/rest-api.php:259 497 513 msgid "%d subscription was migrated successfully." 498 514 msgid_plural "%d subscriptions were migrated successfully." … … 504 520 msgstr "" 505 521 506 #: public/public.php:2 21522 #: public/public.php:239 507 523 msgid "Before submitting your request, please ensure that you have selected the specific variation you are interested in. Otherwise, you will receive a notification if any of the variations' prices drop below your desired target price." 508 524 msgstr "" 509 525 510 #: public/public.php:2 52526 #: public/public.php:270 511 527 msgid "Your target price" 512 528 msgstr "" 513 529 514 #: public/public.php:2 53530 #: public/public.php:271 515 531 msgid "Your email address" 516 532 msgstr "" 517 533 518 #: public/public.php:3 20534 #: public/public.php:338 519 535 msgid "Email confirmed!" 520 536 msgstr "" 521 537 522 #: public/public.php:3 40538 #: public/public.php:358 523 539 msgid "Invalid or expired unsubscribe link." 524 540 msgstr "" 525 541 526 #: public/public.php:3 45542 #: public/public.php:363 527 543 msgid "You have been unsubscribed from these alerts." 528 544 msgstr "" -
price-alerts/trunk/price-alerts.php
r3310498 r3316689 4 4 * Plugin Name: Price Alerts for WooCommerce 5 5 * Description: Allow customers to subscribe to WooCommerce products and get notified when prices drop. 6 * Version: 1.0. 16 * Version: 1.0.2 7 7 * Author: Devnet 8 8 * Author URI: https://devnet.hr … … 13 13 * Requires Plugins: woocommerce 14 14 * WC tested up to: 9.9 15 * 15 16 */ 16 17 use Devnet\PriceAlerts\Includes\Activator; … … 92 93 devnet_pa_fs()->add_action( 'after_uninstall', 'devnet_pa_fs_uninstall_cleanup' ); 93 94 } 94 define( 'DEVNET_PRICE_ALERTS_VERSION', '1.0. 1' );95 define( 'DEVNET_PRICE_ALERTS_VERSION', '1.0.2' ); 95 96 define( 'DEVNET_PRICE_ALERTS_NAME', 'price-alerts' ); 96 97 define( 'DEVNET_PRICE_ALERTS_PATH_DIR', plugin_dir_path( __FILE__ ) ); -
price-alerts/trunk/public/public.php
r3309423 r3316689 74 74 return false; 75 75 } 76 return true; 76 $should_display = true; 77 return $should_display; 77 78 } 78 79
Note: See TracChangeset
for help on using the changeset viewer.