Plugin Directory

Changeset 3316689


Ignore:
Timestamp:
06/24/2025 05:48:10 AM (9 months ago)
Author:
devnethr
Message:

v.1.0.2

Location:
price-alerts
Files:
2 added
30 edited
1 copied

Legend:

Unmodified
Added
Removed
  • price-alerts/tags/1.0.2/README.txt

    r3310498 r3316689  
    44Requires at least: 6.2
    55Requires PHP: 7.4
    6 Stable tag: 1.0.1
     6Stable tag: 1.0.2
    77Tested up to: 6.8
    88License: GPLv2 or later
     
    103103== Changelog ==
    104104
     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
    105115= 1.0.1 =
    106116
     
    112122* Performance: WC tested up to 9.9
    113123
    114 * Initial release.
    115 
    116124= 1.0.0 =
    117125
  • price-alerts/tags/1.0.2/admin/admin.php

    r3310498 r3316689  
    1717        add_action( 'admin_enqueue_scripts', [$this, 'enqueue_assets'] );
    1818        add_action( 'admin_menu', [$this, 'admin_menu'], 100 );
    19         add_action(
    20             'woocommerce_after_product_object_save',
    21             [$this, 'update_product'],
    22             10,
    23             2
    24         );
    2519        add_filter( 'plugin_action_links_' . DEVNET_PRICE_ALERTS_PATH_FILE, [$this, 'plugin_action_links'] );
    2620        add_filter( 'admin_footer_text', [$this, 'admin_credits'] );
     
    145139    }
    146140
    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 
    171141    public function plugin_action_links( $links ) {
    172142        $custom_links = [];
  • price-alerts/tags/1.0.2/admin/options.php

    r3309423 r3316689  
    1414            'label'   => esc_html__( 'Multilingual', 'price-alerts' ),
    1515            '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' ),
    1723        ], [
    1824            'type'    => 'checkbox',
     
    2026            'label'   => esc_html__( 'Delete all plugin data on uninstall', 'price-alerts' ),
    2127            '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' ),
    2329        ]];
    2430        return apply_filters( 'price_alerts_settings_general', $general );
     
    3238                'label'   => esc_html__( 'Enable', 'price-alerts' ),
    3339                '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' ),
    3451            ],
    3552            [
  • 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  
    99{
    1010
    11     public static function deactivate() {}
     11    public static function deactivate()
     12    {
     13        wp_clear_scheduled_hook('price_alerts_schedule');
     14    }
    1215}
  • price-alerts/tags/1.0.2/includes/defaults.php

    r3309423 r3316689  
    1111    {
    1212        $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,
    2316        ];
    2417
     
    3629        $options = [
    3730            'enable'                    => 0,
     31            'form_scope'                => 'all',
    3832            'only_logged_in_users'      => 0,
    3933            'display_mode'              => 'inline',
  • price-alerts/tags/1.0.2/includes/helper.php

    r3309423 r3316689  
    303303
    304304
     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
    305326    public static function evaluate_status_after_confirmation($subscription_id)
    306327    {
     
    607628        return [round($h), round($s * 100), round($l * 100)];
    608629    }
     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    }
    609654}
  • price-alerts/tags/1.0.2/includes/notifier.php

    r3309423 r3316689  
    33namespace Devnet\PriceAlerts\Includes;
    44
     5use Devnet\PriceAlerts\Includes\Compatibility\CompatibilityManager;
    56use Devnet\PriceAlerts\Includes\Helper;
    67use Devnet\PriceAlerts\Includes\Defaults;
     
    2122            return;
    2223        }
    23         $options = DEVNET_PRICE_ALERTS_OPTIONS['email_price_drop'];
     24        $options = DEVNET_PRICE_ALERTS_OPTIONS['email_price_drop'] ?? [];
    2425        $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' );
    3028        $email_data = [];
    3129        $__instance = new self();
     
    5856        $current_currency = $data['current_currency'] ?? '';
    5957        $products = $data['products'] ?? [];
     58        $multicurrency = DEVNET_PRICE_ALERTS_OPTIONS['general']['multicurrency'] ?? false;
    6059        $sent = false;
    6160        foreach ( $products as $key => &$p ) {
     
    6463                continue;
    6564            }
     65            $has_currency_mismatch = $current_currency !== $p['currency'];
    6666            $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            }
    6775            $price = apply_filters(
    6876                'price_alerts_notifier_product_price',
     
    7179                $product
    7280            );
    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             }
    8081            if ( (float) $price <= (float) $p['targetPrice'] ) {
    8182                $p['price'] = $price;
  • price-alerts/tags/1.0.2/includes/plugin.php

    r3309423 r3316689  
    44
    55use Devnet\PriceAlerts\Admin\AdminSide;
     6use Devnet\PriceAlerts\Admin\Product;
    67use Devnet\PriceAlerts\Frontend\PublicSide;
     8if ( !defined( 'ABSPATH' ) ) {
     9    exit;
     10}
     11class Plugin {
     12    protected $plugin_name;
    713
    8 if (! defined('ABSPATH')) exit;
     14    protected $version;
    915
     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    }
    1029
    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    }
    1345
    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    }
    1653
    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    }
    2457
    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    }
    3061
    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     }
    7362}
  • price-alerts/tags/1.0.2/includes/rest-api.php

    r3309423 r3316689  
    7676                    'type'     => 'number',
    7777                    'required' => true
     78                ],
     79                'currency'           => [
     80                    'type'              => 'string',
     81                    'sanitize_callback' => 'sanitize_text_field'
    7882                ],
    7983                'marketing'    => [
     
    149153        $email      = sanitize_email($request->get_param('email'));
    150154        $honeypot   = sanitize_text_field($request->get_param('hp'));
     155        $currency   = sanitize_text_field($request->get_param('currency'));
    151156
    152157        if ($honeypot) {
     
    174179        $raw_data['product_price'] = $product->get_price();
    175180        $raw_data['product_type']  = $product->get_type();
    176         $raw_data['currency']      = get_woocommerce_currency();
     181        $raw_data['currency']      = !empty($currency) ? $currency : get_woocommerce_currency();
    177182        $raw_data['double_opt_in'] = DEVNET_PRICE_ALERTS_OPTIONS['form']['double_opt_in'] ?? false;
    178183        $raw_data['origin_url']    = esc_url_raw($request->get_param('origin_url') ?? '');
  • price-alerts/tags/1.0.2/includes/uninstaller.php

    r3309423 r3316689  
    4949
    5050        $tables = [
     51            'price_alerts_meta',
    5152            'price_alerts_subscriptions',
    52             'price_alerts_meta',
    5353        ];
    5454
  • price-alerts/tags/1.0.2/languages/price-alerts.pot

    r3310498 r3316689  
    33msgid ""
    44msgstr ""
    5 "Project-Id-Version: Price Alerts for WooCommerce 1.0.0\n"
     5"Project-Id-Version: Price Alerts for WooCommerce 1.0.2\n"
    66"Report-Msgid-Bugs-To: https://wordpress.org/support/plugin/price-alerts\n"
    77"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
     
    1010"Content-Type: text/plain; charset=UTF-8\n"
    1111"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"
    1313"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"
    1515"X-Domain: price-alerts\n"
    1616
    1717#. Plugin Name of the plugin
    18 #: price-alerts.php
    1918msgid "Price Alerts for WooCommerce"
    2019msgstr ""
    2120
    2221#. Description of the plugin
    23 #: price-alerts.php
    2422msgid "Allow customers to subscribe to WooCommerce products and get notified when prices drop."
    2523msgstr ""
    2624
    2725#. Author of the plugin
    28 #: price-alerts.php
    2926msgid "Devnet"
    3027msgstr ""
    3128
    3229#. Author URI of the plugin
    33 #: price-alerts.php
    3430msgid "https://devnet.hr"
    3531msgstr ""
    3632
    37 #: admin/admin.php:61
     33#: admin/admin.php:60
    3834msgid "Migrate data from the previous plugin now?"
    3935msgstr ""
    4036
    41 #: admin/admin.php:81
     37#: admin/admin.php:80
    4238msgid "The notification has already been sent to certain users who were selected. Are you certain that you wish to send the notification again?"
    4339msgstr ""
    4440
    4541#. translators: %s: the number of notified users.
    46 #: admin/admin.php:83
     42#: admin/admin.php:82
    4743msgid "Successfully notified %s user(s)."
    4844msgstr ""
    4945
    5046#. translators: %s: the number of failed notifications.
     47#: admin/admin.php:84
     48msgid "%s selected user(s) were not notified."
     49msgstr ""
     50
    5151#: admin/admin.php:85
    52 msgid "%s selected user(s) were not notified."
    53 msgstr ""
    54 
    55 #: admin/admin.php:86
    5652msgid "Are you sure you want to proceed with this action?"
    5753msgstr ""
    5854
     55#: admin/admin.php:101
    5956#: admin/admin.php:102
    60 #: admin/admin.php:103
     57#: admin/product.php:99
    6158msgid "Price Alerts"
    6259msgstr ""
    6360
     61#: admin/admin.php:112
    6462#: admin/admin.php:113
    65 #: admin/admin.php:114
    66 #: admin/admin.php:166
     63#: admin/admin.php:137
    6764msgid "Settings"
    6865msgstr ""
    6966
     67#: admin/admin.php:120
    7068#: admin/admin.php:121
    71 #: admin/admin.php:122
    7269#: templates/admin-subscriptions-page.php:5
    7370msgid "Subscriptions"
     
    8380
    8481#: admin/options.php:25
     82msgid "Multi-currency support"
     83msgstr ""
     84
     85#: admin/options.php:26
     86msgid "Use customer’s currency when checking if the target price is reached."
     87msgstr ""
     88
     89#: admin/options.php:32
    8590msgid "Delete all plugin data on uninstall"
    8691msgstr ""
    8792
    88 #: admin/options.php:26
     93#: admin/options.php:33
    8994msgid "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."
    9095msgstr ""
    9196
    92 #: admin/options.php:40
     97#: admin/options.php:65
    9398msgid "Enable"
    9499msgstr ""
    95100
    96 #: admin/options.php:46
     101#: admin/options.php:73
     102msgid "All Products"
     103msgstr ""
     104
     105#: admin/options.php:74
     106#: admin/options.php:238
     107msgid "All Products (can be disabled per product)"
     108msgstr ""
     109
     110#: admin/options.php:75
     111#: admin/options.php:239
     112msgid "Manual Selection (enable per product)"
     113msgstr ""
     114
     115#: admin/options.php:82
    97116msgid "Double Opt-in"
    98117msgstr ""
    99118
    100 #: admin/options.php:47
     119#: admin/options.php:83
    101120msgid "After the user submits their email, they receive a confirmation email with a request to confirm their subscription"
    102121msgstr ""
    103122
    104 #: admin/options.php:53
     123#: admin/options.php:89
    105124msgid "Show only for logged in users"
    106125msgstr ""
    107126
    108 #: admin/options.php:59
     127#: admin/options.php:95
    109128msgid "Display mode"
    110129msgstr ""
    111130
    112 #: admin/options.php:61
    113 #: admin/options.php:202
     131#: admin/options.php:97
     132#: admin/options.php:247
    114133msgid "Modal (popup)"
    115134msgstr ""
    116135
    117 #: admin/options.php:62
    118 #: admin/options.php:203
     136#: admin/options.php:98
     137#: admin/options.php:248
    119138msgid "Inline (show form directly)"
    120139msgstr ""
    121140
    122 #: admin/options.php:69
     141#: admin/options.php:105
    123142msgid "Position"
    124143msgstr ""
    125144
    126 #: admin/options.php:71
    127 #: admin/options.php:211
     145#: admin/options.php:107
     146#: admin/options.php:256
    128147msgid "Before product meta"
    129148msgstr ""
    130149
    131 #: admin/options.php:72
    132 #: admin/options.php:212
     150#: admin/options.php:108
     151#: admin/options.php:257
    133152msgid "After product summary"
    134153msgstr ""
    135154
    136 #: admin/options.php:73
    137 #: admin/options.php:213
     155#: admin/options.php:109
     156#: admin/options.php:258
    138157msgid "Custom - I'll insert a shortcode"
    139158msgstr ""
    140159
    141 #: admin/options.php:80
     160#: admin/options.php:116
    142161msgid "Shortcode"
    143162msgstr ""
    144163
    145 #: admin/options.php:87
     164#: admin/options.php:123
    146165msgid "Trigger button"
    147166msgstr ""
    148167
    149 #: admin/options.php:93
     168#: admin/options.php:129
    150169msgid "Button text"
    151170msgstr ""
    152171
    153 #: admin/options.php:99
     172#: admin/options.php:135
    154173msgid "Fields"
    155174msgstr ""
    156175
    157 #: admin/options.php:105
     176#: admin/options.php:141
    158177msgid "Allow Higher Target Price"
    159178msgstr ""
    160179
    161 #: admin/options.php:106
     180#: admin/options.php:142
    162181msgid "Enable customers to set a target price higher than the product's current price."
    163182msgstr ""
    164183
    165 #: admin/options.php:112
     184#: admin/options.php:148
    166185#: templates/admin-subscriptions-page.php:33
    167186msgid "Marketing"
    168187msgstr ""
    169188
    170 #: admin/options.php:118
     189#: admin/options.php:154
    171190msgid "Marketing text"
    172191msgstr ""
    173192
    174 #: admin/options.php:125
     193#: admin/options.php:161
    175194msgid "GDPR"
    176195msgstr ""
    177196
    178 #: admin/options.php:131
     197#: admin/options.php:167
    179198msgid "GDPR text"
    180199msgstr ""
    181200
    182 #: admin/options.php:138
     201#: admin/options.php:174
    183202msgid "Honeypot - Anti-Spam"
    184203msgstr ""
    185204
    186 #: admin/options.php:139
     205#: admin/options.php:175
    187206msgid "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."
    188207msgstr ""
    189208
    190 #: admin/options.php:145
    191 #: admin/options.php:332
     209#: admin/options.php:181
     210#: admin/options.php:377
    192211msgid "Design"
    193212msgstr ""
    194213
    195 #: admin/options.php:151
     214#: admin/options.php:187
    196215msgid "Primary color"
    197216msgstr ""
    198217
    199 #: admin/options.php:157
     218#: admin/options.php:193
    200219msgid "Field style"
    201220msgstr ""
    202221
    203 #: admin/options.php:159
    204 #: admin/options.php:221
     222#: admin/options.php:195
     223#: admin/options.php:266
    205224msgid "Default"
    206225msgstr ""
    207226
    208 #: admin/options.php:160
    209 #: admin/options.php:222
     227#: admin/options.php:196
     228#: admin/options.php:267
    210229msgid "Standard"
    211230msgstr ""
    212231
    213 #: admin/options.php:161
    214 #: admin/options.php:223
     232#: admin/options.php:197
     233#: admin/options.php:268
    215234msgid "Outlined"
    216235msgstr ""
    217236
    218 #: admin/options.php:162
    219 #: admin/options.php:224
     237#: admin/options.php:198
     238#: admin/options.php:269
    220239msgid "Filled"
    221240msgstr ""
    222241
    223 #: admin/options.php:170
     242#: admin/options.php:206
    224243msgid "Intro text"
    225244msgstr ""
    226245
    227 #: admin/options.php:176
     246#: admin/options.php:212
    228247msgid "Intro headline"
    229248msgstr ""
    230249
    231 #: admin/options.php:182
     250#: admin/options.php:218
    232251msgid "Intro description"
    233252msgstr ""
    234253
    235 #: admin/options.php:244
     254#: admin/options.php:289
    236255msgid "Notifier interval"
    237256msgstr ""
    238257
    239 #: admin/options.php:246
    240 #: admin/options.php:275
     258#: admin/options.php:291
     259#: admin/options.php:320
    241260msgid "Manual - I'll do it myself"
    242261msgstr ""
    243262
    244 #: admin/options.php:247
    245 #: admin/options.php:276
    246 #: includes/notifier.php:48
     263#: admin/options.php:292
     264#: admin/options.php:321
     265#: includes/notifier.php:49
    247266msgid "Every 5 minutes"
    248267msgstr ""
    249268
    250 #: admin/options.php:248
    251 #: admin/options.php:277
    252 #: includes/notifier.php:43
     269#: admin/options.php:293
     270#: admin/options.php:322
     271#: includes/notifier.php:44
    253272msgid "Every 15 minutes"
    254273msgstr ""
    255274
    256 #: admin/options.php:249
    257 #: admin/options.php:278
    258 #: includes/notifier.php:38
     275#: admin/options.php:294
     276#: admin/options.php:323
     277#: includes/notifier.php:39
    259278msgid "Every 30 minutes"
    260279msgstr ""
    261280
    262 #: admin/options.php:250
    263 #: admin/options.php:279
     281#: admin/options.php:295
     282#: admin/options.php:324
    264283msgid "Every hour"
    265284msgstr ""
    266285
    267 #: admin/options.php:251
    268 #: admin/options.php:280
     286#: admin/options.php:296
     287#: admin/options.php:325
    269288msgid "Twice a day"
    270289msgstr ""
    271290
    272 #: admin/options.php:252
    273 #: admin/options.php:281
     291#: admin/options.php:297
     292#: admin/options.php:326
    274293msgid "Once a day"
    275294msgstr ""
    276295
    277 #: admin/options.php:253
    278 #: admin/options.php:282
     296#: admin/options.php:298
     297#: admin/options.php:327
    279298msgid "Once a week"
    280299msgstr ""
    281300
    282 #: admin/options.php:255
     301#: admin/options.php:300
    283302msgid "What is the frequency at which the notifier should verify for any price drops and send notifications to subscribed users"
    284303msgstr ""
    285304
    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
    289307msgid "Subject"
    290308msgstr ""
    291309
    292 #: admin/options.php:309
    293 #: admin/options.php:367
     310#: admin/options.php:354
     311#: admin/options.php:412
    294312msgid "Heading text"
    295313msgstr ""
    296314
    297 #: admin/options.php:316
    298 #: admin/options.php:374
     315#: admin/options.php:361
     316#: admin/options.php:419
    299317msgid "Content"
    300318msgstr ""
    301319
    302 #: admin/options.php:319
     320#: admin/options.php:364
    303321msgid "Use {price_drops} to display price drops."
    304322msgstr ""
    305323
    306 #: admin/options.php:325
    307 #: admin/options.php:383
     324#: admin/options.php:370
     325#: admin/options.php:428
    308326msgid "Footer text"
    309327msgstr ""
    310328
    311 #: admin/options.php:335
     329#: admin/options.php:380
    312330msgid "Colors and header image are inherited from the"
    313331msgstr ""
    314332
    315 #: admin/options.php:336
     333#: admin/options.php:381
    316334msgid "WooCommerce emails."
    317335msgstr ""
    318336
    319 #: admin/options.php:342
    320 #: admin/options.php:390
     337#: admin/options.php:387
     338#: admin/options.php:435
    321339msgid "Email Template"
    322340msgstr ""
    323341
    324 #: admin/options.php:346
    325 #: admin/options.php:394
     342#: admin/options.php:391
     343#: admin/options.php:439
    326344msgid "Click here to preview your email template."
    327345msgstr ""
    328346
    329 #: admin/options.php:377
     347#: admin/options.php:422
    330348msgid "Use {confirm_button} to display confirm button."
     349msgstr ""
     350
     351#: admin/product.php:121
     352msgid "Enabling or disabling the form per product is a PRO feature. Upgrade to PRO to use this option."
     353msgstr ""
     354
     355#: admin/product.php:132
     356msgid "Disable Form Display"
     357msgstr ""
     358
     359#: admin/product.php:134
     360msgid "Uncheck to follow the global setting (form enabled)."
     361msgstr ""
     362
     363#: admin/product.php:141
     364msgid "Enable Form Display"
     365msgstr ""
     366
     367#: admin/product.php:143
     368msgid "Check to enable the form on this product."
    331369msgstr ""
    332370
     
    360398msgstr ""
    361399
    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
    385401msgid "Notify me on price drop"
    386402msgstr ""
    387403
    388 #: includes/defaults.php:44
     404#: includes/defaults.php:38
    389405msgid "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."
    390406msgstr ""
    391407
     408#: includes/defaults.php:40
     409msgid "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."
     410msgstr ""
     411
     412#: includes/defaults.php:45
     413msgid "Get Notified When the Price Hits Your Target!"
     414msgstr ""
     415
    392416#: 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:51
    397 msgid "Get Notified When the Price Hits Your Target!"
    398 msgstr ""
    399 
    400 #: includes/defaults.php:52
    401417msgid "Enter your desired price and we’ll alert you as soon as the product price drops to your target."
    402418msgstr ""
    403419
    404 #: includes/defaults.php:82
     420#: includes/defaults.php:76
    405421msgid "Great news – Your watched item(s) just dropped in price!"
    406422msgstr ""
    407423
    408 #: includes/defaults.php:83
     424#: includes/defaults.php:77
    409425msgid "Price Drop Alert 🎉"
    410426msgstr ""
    411427
    412 #: includes/defaults.php:84
     428#: includes/defaults.php:78
    413429msgid ""
    414430"Hi there,\n"
     
    422438msgstr ""
    423439
    424 #: includes/defaults.php:92
    425 #: includes/defaults.php:112
     440#: includes/defaults.php:86
     441#: includes/defaults.php:106
    426442msgid "Powered by Price Alerts"
    427443msgstr ""
    428444
    429 #: includes/defaults.php:107
    430 #: includes/defaults.php:108
     445#: includes/defaults.php:101
     446#: includes/defaults.php:102
    431447msgid "Confirm Your Subscription"
    432448msgstr ""
    433449
    434 #: includes/defaults.php:109
     450#: includes/defaults.php:103
    435451msgid ""
    436452"Thank you for subscribing! Please confirm your subscription by clicking the button below:\n"
     
    439455msgstr ""
    440456
    441 #: includes/helper.php:472
     457#: includes/helper.php:493
    442458msgid "No legacy data found to migrate."
    443459msgstr ""
    444460
    445 #: includes/notifier.php:226
     461#: includes/notifier.php:250
    446462msgid "Unsubscribe from these alerts"
    447463msgstr ""
    448464
    449 #: includes/notifier.php:257
     465#: includes/notifier.php:281
    450466msgid "is now"
    451467msgstr ""
    452468
    453 #: includes/notifier.php:259
     469#: includes/notifier.php:283
    454470msgid "Price you were waiting for:"
    455471msgstr ""
    456472
    457 #: includes/notifier.php:261
     473#: includes/notifier.php:285
    458474msgid "since:"
    459475msgstr ""
    460476
    461477#. translators: %s: URL for confirming the subscription.
    462 #: includes/notifier.php:368
     478#: includes/notifier.php:392
    463479msgid "<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>"
    464480msgstr ""
    465481
    466 #: includes/rest-api.php:127
     482#: includes/rest-api.php:131
    467483msgid "OMG you can not view private data."
    468484msgstr ""
    469485
    470 #: includes/rest-api.php:153
     486#: includes/rest-api.php:158
    471487msgid "Spam detected."
    472488msgstr ""
    473489
    474 #: includes/rest-api.php:157
     490#: includes/rest-api.php:162
    475491msgid "Missing required fields."
    476492msgstr ""
    477493
    478 #: includes/rest-api.php:162
    479 #: includes/rest-api.php:206
     494#: includes/rest-api.php:167
     495#: includes/rest-api.php:211
    480496msgid "Invalid product ID."
    481497msgstr ""
    482498
    483 #: includes/rest-api.php:190
     499#: includes/rest-api.php:195
    484500msgid "Invalid or missing IDs."
    485501msgstr ""
    486502
    487 #: includes/rest-api.php:219
     503#: includes/rest-api.php:224
    488504msgid "Missing emailsAndProducts parameter."
    489505msgstr ""
    490506
    491 #: includes/rest-api.php:225
     507#: includes/rest-api.php:230
    492508msgid "Invalid emailsAndProducts JSON format."
    493509msgstr ""
    494510
    495511#. translators: %d is the number of subscriptions that were migrated.
    496 #: includes/rest-api.php:254
     512#: includes/rest-api.php:259
    497513msgid "%d subscription was migrated successfully."
    498514msgid_plural "%d subscriptions were migrated successfully."
     
    504520msgstr ""
    505521
    506 #: public/public.php:221
     522#: public/public.php:239
    507523msgid "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."
    508524msgstr ""
    509525
    510 #: public/public.php:252
     526#: public/public.php:270
    511527msgid "Your target price"
    512528msgstr ""
    513529
    514 #: public/public.php:253
     530#: public/public.php:271
    515531msgid "Your email address"
    516532msgstr ""
    517533
    518 #: public/public.php:320
     534#: public/public.php:338
    519535msgid "Email confirmed!"
    520536msgstr ""
    521537
    522 #: public/public.php:340
     538#: public/public.php:358
    523539msgid "Invalid or expired unsubscribe link."
    524540msgstr ""
    525541
    526 #: public/public.php:345
     542#: public/public.php:363
    527543msgid "You have been unsubscribed from these alerts."
    528544msgstr ""
  • price-alerts/tags/1.0.2/price-alerts.php

    r3310498 r3316689  
    44 * Plugin Name:       Price Alerts for WooCommerce
    55 * Description:       Allow customers to subscribe to WooCommerce products and get notified when prices drop.
    6  * Version:           1.0.1
     6 * Version:           1.0.2
    77 * Author:            Devnet
    88 * Author URI:        https://devnet.hr
     
    1313 * Requires Plugins:  woocommerce
    1414 * WC tested up to:   9.9
     15 *
    1516 */
    1617use Devnet\PriceAlerts\Includes\Activator;
     
    9293        devnet_pa_fs()->add_action( 'after_uninstall', 'devnet_pa_fs_uninstall_cleanup' );
    9394    }
    94     define( 'DEVNET_PRICE_ALERTS_VERSION', '1.0.1' );
     95    define( 'DEVNET_PRICE_ALERTS_VERSION', '1.0.2' );
    9596    define( 'DEVNET_PRICE_ALERTS_NAME', 'price-alerts' );
    9697    define( 'DEVNET_PRICE_ALERTS_PATH_DIR', plugin_dir_path( __FILE__ ) );
  • price-alerts/tags/1.0.2/public/public.php

    r3309423 r3316689  
    7474            return false;
    7575        }
    76         return true;
     76        $should_display = true;
     77        return $should_display;
    7778    }
    7879
  • price-alerts/trunk/README.txt

    r3310498 r3316689  
    44Requires at least: 6.2
    55Requires PHP: 7.4
    6 Stable tag: 1.0.1
     6Stable tag: 1.0.2
    77Tested up to: 6.8
    88License: GPLv2 or later
     
    103103== Changelog ==
    104104
     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
    105115= 1.0.1 =
    106116
     
    112122* Performance: WC tested up to 9.9
    113123
    114 * Initial release.
    115 
    116124= 1.0.0 =
    117125
  • price-alerts/trunk/admin/admin.php

    r3310498 r3316689  
    1717        add_action( 'admin_enqueue_scripts', [$this, 'enqueue_assets'] );
    1818        add_action( 'admin_menu', [$this, 'admin_menu'], 100 );
    19         add_action(
    20             'woocommerce_after_product_object_save',
    21             [$this, 'update_product'],
    22             10,
    23             2
    24         );
    2519        add_filter( 'plugin_action_links_' . DEVNET_PRICE_ALERTS_PATH_FILE, [$this, 'plugin_action_links'] );
    2620        add_filter( 'admin_footer_text', [$this, 'admin_credits'] );
     
    145139    }
    146140
    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 
    171141    public function plugin_action_links( $links ) {
    172142        $custom_links = [];
  • price-alerts/trunk/admin/options.php

    r3309423 r3316689  
    1414            'label'   => esc_html__( 'Multilingual', 'price-alerts' ),
    1515            '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' ),
    1723        ], [
    1824            'type'    => 'checkbox',
     
    2026            'label'   => esc_html__( 'Delete all plugin data on uninstall', 'price-alerts' ),
    2127            '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' ),
    2329        ]];
    2430        return apply_filters( 'price_alerts_settings_general', $general );
     
    3238                'label'   => esc_html__( 'Enable', 'price-alerts' ),
    3339                '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' ),
    3451            ],
    3552            [
  • 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  
    99{
    1010
    11     public static function deactivate() {}
     11    public static function deactivate()
     12    {
     13        wp_clear_scheduled_hook('price_alerts_schedule');
     14    }
    1215}
  • price-alerts/trunk/includes/defaults.php

    r3309423 r3316689  
    1111    {
    1212        $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,
    2316        ];
    2417
     
    3629        $options = [
    3730            'enable'                    => 0,
     31            'form_scope'                => 'all',
    3832            'only_logged_in_users'      => 0,
    3933            'display_mode'              => 'inline',
  • price-alerts/trunk/includes/helper.php

    r3309423 r3316689  
    303303
    304304
     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
    305326    public static function evaluate_status_after_confirmation($subscription_id)
    306327    {
     
    607628        return [round($h), round($s * 100), round($l * 100)];
    608629    }
     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    }
    609654}
  • price-alerts/trunk/includes/notifier.php

    r3309423 r3316689  
    33namespace Devnet\PriceAlerts\Includes;
    44
     5use Devnet\PriceAlerts\Includes\Compatibility\CompatibilityManager;
    56use Devnet\PriceAlerts\Includes\Helper;
    67use Devnet\PriceAlerts\Includes\Defaults;
     
    2122            return;
    2223        }
    23         $options = DEVNET_PRICE_ALERTS_OPTIONS['email_price_drop'];
     24        $options = DEVNET_PRICE_ALERTS_OPTIONS['email_price_drop'] ?? [];
    2425        $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' );
    3028        $email_data = [];
    3129        $__instance = new self();
     
    5856        $current_currency = $data['current_currency'] ?? '';
    5957        $products = $data['products'] ?? [];
     58        $multicurrency = DEVNET_PRICE_ALERTS_OPTIONS['general']['multicurrency'] ?? false;
    6059        $sent = false;
    6160        foreach ( $products as $key => &$p ) {
     
    6463                continue;
    6564            }
     65            $has_currency_mismatch = $current_currency !== $p['currency'];
    6666            $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            }
    6775            $price = apply_filters(
    6876                'price_alerts_notifier_product_price',
     
    7179                $product
    7280            );
    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             }
    8081            if ( (float) $price <= (float) $p['targetPrice'] ) {
    8182                $p['price'] = $price;
  • price-alerts/trunk/includes/plugin.php

    r3309423 r3316689  
    44
    55use Devnet\PriceAlerts\Admin\AdminSide;
     6use Devnet\PriceAlerts\Admin\Product;
    67use Devnet\PriceAlerts\Frontend\PublicSide;
     8if ( !defined( 'ABSPATH' ) ) {
     9    exit;
     10}
     11class Plugin {
     12    protected $plugin_name;
    713
    8 if (! defined('ABSPATH')) exit;
     14    protected $version;
    915
     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    }
    1029
    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    }
    1345
    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    }
    1653
    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    }
    2457
    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    }
    3061
    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     }
    7362}
  • price-alerts/trunk/includes/rest-api.php

    r3309423 r3316689  
    7676                    'type'     => 'number',
    7777                    'required' => true
     78                ],
     79                'currency'           => [
     80                    'type'              => 'string',
     81                    'sanitize_callback' => 'sanitize_text_field'
    7882                ],
    7983                'marketing'    => [
     
    149153        $email      = sanitize_email($request->get_param('email'));
    150154        $honeypot   = sanitize_text_field($request->get_param('hp'));
     155        $currency   = sanitize_text_field($request->get_param('currency'));
    151156
    152157        if ($honeypot) {
     
    174179        $raw_data['product_price'] = $product->get_price();
    175180        $raw_data['product_type']  = $product->get_type();
    176         $raw_data['currency']      = get_woocommerce_currency();
     181        $raw_data['currency']      = !empty($currency) ? $currency : get_woocommerce_currency();
    177182        $raw_data['double_opt_in'] = DEVNET_PRICE_ALERTS_OPTIONS['form']['double_opt_in'] ?? false;
    178183        $raw_data['origin_url']    = esc_url_raw($request->get_param('origin_url') ?? '');
  • price-alerts/trunk/includes/uninstaller.php

    r3309423 r3316689  
    4949
    5050        $tables = [
     51            'price_alerts_meta',
    5152            'price_alerts_subscriptions',
    52             'price_alerts_meta',
    5353        ];
    5454
  • price-alerts/trunk/languages/price-alerts.pot

    r3310498 r3316689  
    33msgid ""
    44msgstr ""
    5 "Project-Id-Version: Price Alerts for WooCommerce 1.0.0\n"
     5"Project-Id-Version: Price Alerts for WooCommerce 1.0.2\n"
    66"Report-Msgid-Bugs-To: https://wordpress.org/support/plugin/price-alerts\n"
    77"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
     
    1010"Content-Type: text/plain; charset=UTF-8\n"
    1111"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"
    1313"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"
    1515"X-Domain: price-alerts\n"
    1616
    1717#. Plugin Name of the plugin
    18 #: price-alerts.php
    1918msgid "Price Alerts for WooCommerce"
    2019msgstr ""
    2120
    2221#. Description of the plugin
    23 #: price-alerts.php
    2422msgid "Allow customers to subscribe to WooCommerce products and get notified when prices drop."
    2523msgstr ""
    2624
    2725#. Author of the plugin
    28 #: price-alerts.php
    2926msgid "Devnet"
    3027msgstr ""
    3128
    3229#. Author URI of the plugin
    33 #: price-alerts.php
    3430msgid "https://devnet.hr"
    3531msgstr ""
    3632
    37 #: admin/admin.php:61
     33#: admin/admin.php:60
    3834msgid "Migrate data from the previous plugin now?"
    3935msgstr ""
    4036
    41 #: admin/admin.php:81
     37#: admin/admin.php:80
    4238msgid "The notification has already been sent to certain users who were selected. Are you certain that you wish to send the notification again?"
    4339msgstr ""
    4440
    4541#. translators: %s: the number of notified users.
    46 #: admin/admin.php:83
     42#: admin/admin.php:82
    4743msgid "Successfully notified %s user(s)."
    4844msgstr ""
    4945
    5046#. translators: %s: the number of failed notifications.
     47#: admin/admin.php:84
     48msgid "%s selected user(s) were not notified."
     49msgstr ""
     50
    5151#: admin/admin.php:85
    52 msgid "%s selected user(s) were not notified."
    53 msgstr ""
    54 
    55 #: admin/admin.php:86
    5652msgid "Are you sure you want to proceed with this action?"
    5753msgstr ""
    5854
     55#: admin/admin.php:101
    5956#: admin/admin.php:102
    60 #: admin/admin.php:103
     57#: admin/product.php:99
    6158msgid "Price Alerts"
    6259msgstr ""
    6360
     61#: admin/admin.php:112
    6462#: admin/admin.php:113
    65 #: admin/admin.php:114
    66 #: admin/admin.php:166
     63#: admin/admin.php:137
    6764msgid "Settings"
    6865msgstr ""
    6966
     67#: admin/admin.php:120
    7068#: admin/admin.php:121
    71 #: admin/admin.php:122
    7269#: templates/admin-subscriptions-page.php:5
    7370msgid "Subscriptions"
     
    8380
    8481#: admin/options.php:25
     82msgid "Multi-currency support"
     83msgstr ""
     84
     85#: admin/options.php:26
     86msgid "Use customer’s currency when checking if the target price is reached."
     87msgstr ""
     88
     89#: admin/options.php:32
    8590msgid "Delete all plugin data on uninstall"
    8691msgstr ""
    8792
    88 #: admin/options.php:26
     93#: admin/options.php:33
    8994msgid "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."
    9095msgstr ""
    9196
    92 #: admin/options.php:40
     97#: admin/options.php:65
    9398msgid "Enable"
    9499msgstr ""
    95100
    96 #: admin/options.php:46
     101#: admin/options.php:73
     102msgid "All Products"
     103msgstr ""
     104
     105#: admin/options.php:74
     106#: admin/options.php:238
     107msgid "All Products (can be disabled per product)"
     108msgstr ""
     109
     110#: admin/options.php:75
     111#: admin/options.php:239
     112msgid "Manual Selection (enable per product)"
     113msgstr ""
     114
     115#: admin/options.php:82
    97116msgid "Double Opt-in"
    98117msgstr ""
    99118
    100 #: admin/options.php:47
     119#: admin/options.php:83
    101120msgid "After the user submits their email, they receive a confirmation email with a request to confirm their subscription"
    102121msgstr ""
    103122
    104 #: admin/options.php:53
     123#: admin/options.php:89
    105124msgid "Show only for logged in users"
    106125msgstr ""
    107126
    108 #: admin/options.php:59
     127#: admin/options.php:95
    109128msgid "Display mode"
    110129msgstr ""
    111130
    112 #: admin/options.php:61
    113 #: admin/options.php:202
     131#: admin/options.php:97
     132#: admin/options.php:247
    114133msgid "Modal (popup)"
    115134msgstr ""
    116135
    117 #: admin/options.php:62
    118 #: admin/options.php:203
     136#: admin/options.php:98
     137#: admin/options.php:248
    119138msgid "Inline (show form directly)"
    120139msgstr ""
    121140
    122 #: admin/options.php:69
     141#: admin/options.php:105
    123142msgid "Position"
    124143msgstr ""
    125144
    126 #: admin/options.php:71
    127 #: admin/options.php:211
     145#: admin/options.php:107
     146#: admin/options.php:256
    128147msgid "Before product meta"
    129148msgstr ""
    130149
    131 #: admin/options.php:72
    132 #: admin/options.php:212
     150#: admin/options.php:108
     151#: admin/options.php:257
    133152msgid "After product summary"
    134153msgstr ""
    135154
    136 #: admin/options.php:73
    137 #: admin/options.php:213
     155#: admin/options.php:109
     156#: admin/options.php:258
    138157msgid "Custom - I'll insert a shortcode"
    139158msgstr ""
    140159
    141 #: admin/options.php:80
     160#: admin/options.php:116
    142161msgid "Shortcode"
    143162msgstr ""
    144163
    145 #: admin/options.php:87
     164#: admin/options.php:123
    146165msgid "Trigger button"
    147166msgstr ""
    148167
    149 #: admin/options.php:93
     168#: admin/options.php:129
    150169msgid "Button text"
    151170msgstr ""
    152171
    153 #: admin/options.php:99
     172#: admin/options.php:135
    154173msgid "Fields"
    155174msgstr ""
    156175
    157 #: admin/options.php:105
     176#: admin/options.php:141
    158177msgid "Allow Higher Target Price"
    159178msgstr ""
    160179
    161 #: admin/options.php:106
     180#: admin/options.php:142
    162181msgid "Enable customers to set a target price higher than the product's current price."
    163182msgstr ""
    164183
    165 #: admin/options.php:112
     184#: admin/options.php:148
    166185#: templates/admin-subscriptions-page.php:33
    167186msgid "Marketing"
    168187msgstr ""
    169188
    170 #: admin/options.php:118
     189#: admin/options.php:154
    171190msgid "Marketing text"
    172191msgstr ""
    173192
    174 #: admin/options.php:125
     193#: admin/options.php:161
    175194msgid "GDPR"
    176195msgstr ""
    177196
    178 #: admin/options.php:131
     197#: admin/options.php:167
    179198msgid "GDPR text"
    180199msgstr ""
    181200
    182 #: admin/options.php:138
     201#: admin/options.php:174
    183202msgid "Honeypot - Anti-Spam"
    184203msgstr ""
    185204
    186 #: admin/options.php:139
     205#: admin/options.php:175
    187206msgid "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."
    188207msgstr ""
    189208
    190 #: admin/options.php:145
    191 #: admin/options.php:332
     209#: admin/options.php:181
     210#: admin/options.php:377
    192211msgid "Design"
    193212msgstr ""
    194213
    195 #: admin/options.php:151
     214#: admin/options.php:187
    196215msgid "Primary color"
    197216msgstr ""
    198217
    199 #: admin/options.php:157
     218#: admin/options.php:193
    200219msgid "Field style"
    201220msgstr ""
    202221
    203 #: admin/options.php:159
    204 #: admin/options.php:221
     222#: admin/options.php:195
     223#: admin/options.php:266
    205224msgid "Default"
    206225msgstr ""
    207226
    208 #: admin/options.php:160
    209 #: admin/options.php:222
     227#: admin/options.php:196
     228#: admin/options.php:267
    210229msgid "Standard"
    211230msgstr ""
    212231
    213 #: admin/options.php:161
    214 #: admin/options.php:223
     232#: admin/options.php:197
     233#: admin/options.php:268
    215234msgid "Outlined"
    216235msgstr ""
    217236
    218 #: admin/options.php:162
    219 #: admin/options.php:224
     237#: admin/options.php:198
     238#: admin/options.php:269
    220239msgid "Filled"
    221240msgstr ""
    222241
    223 #: admin/options.php:170
     242#: admin/options.php:206
    224243msgid "Intro text"
    225244msgstr ""
    226245
    227 #: admin/options.php:176
     246#: admin/options.php:212
    228247msgid "Intro headline"
    229248msgstr ""
    230249
    231 #: admin/options.php:182
     250#: admin/options.php:218
    232251msgid "Intro description"
    233252msgstr ""
    234253
    235 #: admin/options.php:244
     254#: admin/options.php:289
    236255msgid "Notifier interval"
    237256msgstr ""
    238257
    239 #: admin/options.php:246
    240 #: admin/options.php:275
     258#: admin/options.php:291
     259#: admin/options.php:320
    241260msgid "Manual - I'll do it myself"
    242261msgstr ""
    243262
    244 #: admin/options.php:247
    245 #: admin/options.php:276
    246 #: includes/notifier.php:48
     263#: admin/options.php:292
     264#: admin/options.php:321
     265#: includes/notifier.php:49
    247266msgid "Every 5 minutes"
    248267msgstr ""
    249268
    250 #: admin/options.php:248
    251 #: admin/options.php:277
    252 #: includes/notifier.php:43
     269#: admin/options.php:293
     270#: admin/options.php:322
     271#: includes/notifier.php:44
    253272msgid "Every 15 minutes"
    254273msgstr ""
    255274
    256 #: admin/options.php:249
    257 #: admin/options.php:278
    258 #: includes/notifier.php:38
     275#: admin/options.php:294
     276#: admin/options.php:323
     277#: includes/notifier.php:39
    259278msgid "Every 30 minutes"
    260279msgstr ""
    261280
    262 #: admin/options.php:250
    263 #: admin/options.php:279
     281#: admin/options.php:295
     282#: admin/options.php:324
    264283msgid "Every hour"
    265284msgstr ""
    266285
    267 #: admin/options.php:251
    268 #: admin/options.php:280
     286#: admin/options.php:296
     287#: admin/options.php:325
    269288msgid "Twice a day"
    270289msgstr ""
    271290
    272 #: admin/options.php:252
    273 #: admin/options.php:281
     291#: admin/options.php:297
     292#: admin/options.php:326
    274293msgid "Once a day"
    275294msgstr ""
    276295
    277 #: admin/options.php:253
    278 #: admin/options.php:282
     296#: admin/options.php:298
     297#: admin/options.php:327
    279298msgid "Once a week"
    280299msgstr ""
    281300
    282 #: admin/options.php:255
     301#: admin/options.php:300
    283302msgid "What is the frequency at which the notifier should verify for any price drops and send notifications to subscribed users"
    284303msgstr ""
    285304
    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
    289307msgid "Subject"
    290308msgstr ""
    291309
    292 #: admin/options.php:309
    293 #: admin/options.php:367
     310#: admin/options.php:354
     311#: admin/options.php:412
    294312msgid "Heading text"
    295313msgstr ""
    296314
    297 #: admin/options.php:316
    298 #: admin/options.php:374
     315#: admin/options.php:361
     316#: admin/options.php:419
    299317msgid "Content"
    300318msgstr ""
    301319
    302 #: admin/options.php:319
     320#: admin/options.php:364
    303321msgid "Use {price_drops} to display price drops."
    304322msgstr ""
    305323
    306 #: admin/options.php:325
    307 #: admin/options.php:383
     324#: admin/options.php:370
     325#: admin/options.php:428
    308326msgid "Footer text"
    309327msgstr ""
    310328
    311 #: admin/options.php:335
     329#: admin/options.php:380
    312330msgid "Colors and header image are inherited from the"
    313331msgstr ""
    314332
    315 #: admin/options.php:336
     333#: admin/options.php:381
    316334msgid "WooCommerce emails."
    317335msgstr ""
    318336
    319 #: admin/options.php:342
    320 #: admin/options.php:390
     337#: admin/options.php:387
     338#: admin/options.php:435
    321339msgid "Email Template"
    322340msgstr ""
    323341
    324 #: admin/options.php:346
    325 #: admin/options.php:394
     342#: admin/options.php:391
     343#: admin/options.php:439
    326344msgid "Click here to preview your email template."
    327345msgstr ""
    328346
    329 #: admin/options.php:377
     347#: admin/options.php:422
    330348msgid "Use {confirm_button} to display confirm button."
     349msgstr ""
     350
     351#: admin/product.php:121
     352msgid "Enabling or disabling the form per product is a PRO feature. Upgrade to PRO to use this option."
     353msgstr ""
     354
     355#: admin/product.php:132
     356msgid "Disable Form Display"
     357msgstr ""
     358
     359#: admin/product.php:134
     360msgid "Uncheck to follow the global setting (form enabled)."
     361msgstr ""
     362
     363#: admin/product.php:141
     364msgid "Enable Form Display"
     365msgstr ""
     366
     367#: admin/product.php:143
     368msgid "Check to enable the form on this product."
    331369msgstr ""
    332370
     
    360398msgstr ""
    361399
    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
    385401msgid "Notify me on price drop"
    386402msgstr ""
    387403
    388 #: includes/defaults.php:44
     404#: includes/defaults.php:38
    389405msgid "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."
    390406msgstr ""
    391407
     408#: includes/defaults.php:40
     409msgid "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."
     410msgstr ""
     411
     412#: includes/defaults.php:45
     413msgid "Get Notified When the Price Hits Your Target!"
     414msgstr ""
     415
    392416#: 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:51
    397 msgid "Get Notified When the Price Hits Your Target!"
    398 msgstr ""
    399 
    400 #: includes/defaults.php:52
    401417msgid "Enter your desired price and we’ll alert you as soon as the product price drops to your target."
    402418msgstr ""
    403419
    404 #: includes/defaults.php:82
     420#: includes/defaults.php:76
    405421msgid "Great news – Your watched item(s) just dropped in price!"
    406422msgstr ""
    407423
    408 #: includes/defaults.php:83
     424#: includes/defaults.php:77
    409425msgid "Price Drop Alert 🎉"
    410426msgstr ""
    411427
    412 #: includes/defaults.php:84
     428#: includes/defaults.php:78
    413429msgid ""
    414430"Hi there,\n"
     
    422438msgstr ""
    423439
    424 #: includes/defaults.php:92
    425 #: includes/defaults.php:112
     440#: includes/defaults.php:86
     441#: includes/defaults.php:106
    426442msgid "Powered by Price Alerts"
    427443msgstr ""
    428444
    429 #: includes/defaults.php:107
    430 #: includes/defaults.php:108
     445#: includes/defaults.php:101
     446#: includes/defaults.php:102
    431447msgid "Confirm Your Subscription"
    432448msgstr ""
    433449
    434 #: includes/defaults.php:109
     450#: includes/defaults.php:103
    435451msgid ""
    436452"Thank you for subscribing! Please confirm your subscription by clicking the button below:\n"
     
    439455msgstr ""
    440456
    441 #: includes/helper.php:472
     457#: includes/helper.php:493
    442458msgid "No legacy data found to migrate."
    443459msgstr ""
    444460
    445 #: includes/notifier.php:226
     461#: includes/notifier.php:250
    446462msgid "Unsubscribe from these alerts"
    447463msgstr ""
    448464
    449 #: includes/notifier.php:257
     465#: includes/notifier.php:281
    450466msgid "is now"
    451467msgstr ""
    452468
    453 #: includes/notifier.php:259
     469#: includes/notifier.php:283
    454470msgid "Price you were waiting for:"
    455471msgstr ""
    456472
    457 #: includes/notifier.php:261
     473#: includes/notifier.php:285
    458474msgid "since:"
    459475msgstr ""
    460476
    461477#. translators: %s: URL for confirming the subscription.
    462 #: includes/notifier.php:368
     478#: includes/notifier.php:392
    463479msgid "<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>"
    464480msgstr ""
    465481
    466 #: includes/rest-api.php:127
     482#: includes/rest-api.php:131
    467483msgid "OMG you can not view private data."
    468484msgstr ""
    469485
    470 #: includes/rest-api.php:153
     486#: includes/rest-api.php:158
    471487msgid "Spam detected."
    472488msgstr ""
    473489
    474 #: includes/rest-api.php:157
     490#: includes/rest-api.php:162
    475491msgid "Missing required fields."
    476492msgstr ""
    477493
    478 #: includes/rest-api.php:162
    479 #: includes/rest-api.php:206
     494#: includes/rest-api.php:167
     495#: includes/rest-api.php:211
    480496msgid "Invalid product ID."
    481497msgstr ""
    482498
    483 #: includes/rest-api.php:190
     499#: includes/rest-api.php:195
    484500msgid "Invalid or missing IDs."
    485501msgstr ""
    486502
    487 #: includes/rest-api.php:219
     503#: includes/rest-api.php:224
    488504msgid "Missing emailsAndProducts parameter."
    489505msgstr ""
    490506
    491 #: includes/rest-api.php:225
     507#: includes/rest-api.php:230
    492508msgid "Invalid emailsAndProducts JSON format."
    493509msgstr ""
    494510
    495511#. translators: %d is the number of subscriptions that were migrated.
    496 #: includes/rest-api.php:254
     512#: includes/rest-api.php:259
    497513msgid "%d subscription was migrated successfully."
    498514msgid_plural "%d subscriptions were migrated successfully."
     
    504520msgstr ""
    505521
    506 #: public/public.php:221
     522#: public/public.php:239
    507523msgid "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."
    508524msgstr ""
    509525
    510 #: public/public.php:252
     526#: public/public.php:270
    511527msgid "Your target price"
    512528msgstr ""
    513529
    514 #: public/public.php:253
     530#: public/public.php:271
    515531msgid "Your email address"
    516532msgstr ""
    517533
    518 #: public/public.php:320
     534#: public/public.php:338
    519535msgid "Email confirmed!"
    520536msgstr ""
    521537
    522 #: public/public.php:340
     538#: public/public.php:358
    523539msgid "Invalid or expired unsubscribe link."
    524540msgstr ""
    525541
    526 #: public/public.php:345
     542#: public/public.php:363
    527543msgid "You have been unsubscribed from these alerts."
    528544msgstr ""
  • price-alerts/trunk/price-alerts.php

    r3310498 r3316689  
    44 * Plugin Name:       Price Alerts for WooCommerce
    55 * Description:       Allow customers to subscribe to WooCommerce products and get notified when prices drop.
    6  * Version:           1.0.1
     6 * Version:           1.0.2
    77 * Author:            Devnet
    88 * Author URI:        https://devnet.hr
     
    1313 * Requires Plugins:  woocommerce
    1414 * WC tested up to:   9.9
     15 *
    1516 */
    1617use Devnet\PriceAlerts\Includes\Activator;
     
    9293        devnet_pa_fs()->add_action( 'after_uninstall', 'devnet_pa_fs_uninstall_cleanup' );
    9394    }
    94     define( 'DEVNET_PRICE_ALERTS_VERSION', '1.0.1' );
     95    define( 'DEVNET_PRICE_ALERTS_VERSION', '1.0.2' );
    9596    define( 'DEVNET_PRICE_ALERTS_NAME', 'price-alerts' );
    9697    define( 'DEVNET_PRICE_ALERTS_PATH_DIR', plugin_dir_path( __FILE__ ) );
  • price-alerts/trunk/public/public.php

    r3309423 r3316689  
    7474            return false;
    7575        }
    76         return true;
     76        $should_display = true;
     77        return $should_display;
    7778    }
    7879
Note: See TracChangeset for help on using the changeset viewer.