Changeset 3750893
- Timestamp:
- 10/16/2026 05:56:02 PM (4 weeks ago)
- Location:
- viswapp-chat-widget
- Files:
-
- 18 added
- 4 edited
-
tags/1.4.0 (added)
-
tags/1.4.0/assets (added)
-
tags/1.4.0/assets/admin.css (added)
-
tags/1.4.0/assets/admin.js (added)
-
tags/1.4.0/assets/cart-capture.js (added)
-
tags/1.4.0/assets/form-block.js (added)
-
tags/1.4.0/includes (added)
-
tags/1.4.0/includes/class-viswapp-forms.php (added)
-
tags/1.4.0/includes/class-viswapp-login.php (added)
-
tags/1.4.0/includes/class-viswapp-widget-frontend.php (added)
-
tags/1.4.0/includes/class-viswapp-widget-options.php (added)
-
tags/1.4.0/includes/class-viswapp-widget-settings.php (added)
-
tags/1.4.0/includes/class-viswapp-woo-carts.php (added)
-
tags/1.4.0/readme.txt (added)
-
tags/1.4.0/uninstall.php (added)
-
tags/1.4.0/viswapp-chat-widget.php (added)
-
trunk/assets/form-block.js (added)
-
trunk/includes/class-viswapp-forms.php (added)
-
trunk/includes/class-viswapp-widget-settings.php (modified) (6 diffs)
-
trunk/readme.txt (modified) (8 diffs)
-
trunk/uninstall.php (modified) (2 diffs)
-
trunk/viswapp-chat-widget.php (modified) (5 diffs)
Legend:
- Unmodified
- Added
- Removed
-
viswapp-chat-widget/trunk/includes/class-viswapp-widget-settings.php
r3739838 r3750893 65 65 ]); 66 66 67 // Web forms ([viswapp_form] and the VisWapp form block) 68 register_setting(self::GROUP, VisWapp_Forms::OPTION, [ 69 'type' => 'array', 70 'sanitize_callback' => [$this, 'sanitize_forms'], 71 'default' => VisWapp_Forms::defaults(), 72 ]); 73 67 74 // WooCommerce abandoned carts (the tab is only shown, and so only posted, with WooCommerce) 68 75 if (VisWapp_Woo_Carts::woo_active()) { … … 111 118 } 112 119 120 public function sanitize_forms($input): array 121 { 122 $input = is_array($input) ? wp_unslash($input) : []; 123 124 // A pasted embed code (a form's Share tab) fills both addresses 125 $code = trim((string) ($input['embed'] ?? '')); 126 if ($code !== '') { 127 $parsed = VisWapp_Forms::parse_embed($code); 128 if (empty($parsed['api'])) { 129 add_settings_error(self::PAGE, 'forms_embed', __('That embed code has no data-api. Copy the “Embed on a page” code from VisWapp → Web Forms → Share.', 'viswapp-chat-widget')); 130 } 131 $input = array_merge($input, $parsed); 132 } 133 134 $clean = VisWapp_Forms::sanitize($input); 135 // Only when forms are being set up: the tab is posted with every save 136 if (($code !== '' || $clean['api'] !== '' || $clean['src'] !== '') && !VisWapp_Forms::ready($clean)) { 137 add_settings_error(self::PAGE, 'forms_api', __('Forms need the VisWapp API address: paste a form’s embed code, or set up the chat widget first.', 'viswapp-chat-widget'), 'warning'); 138 } 139 140 return $clean; 141 } 142 113 143 public function sanitize_login($input): array 114 144 { … … 201 231 $wo = $woo ? VisWapp_Woo_Carts::get() : []; 202 232 $wooReady = $woo && VisWapp_Woo_Carts::ready($wo); 233 $fo = VisWapp_Forms::get(); 234 $formsReady = VisWapp_Forms::ready($fo); 203 235 // phpcs:ignore WordPress.Security.NonceVerification.Recommended -- only picks the open tab 204 236 $tab = isset($_GET['vw_tab']) ? sanitize_key(wp_unslash($_GET['vw_tab'])) : 'chat'; 205 if (!in_array($tab, $woo ? ['chat', 'login', ' woo'] : ['chat', 'login'], true)) {237 if (!in_array($tab, $woo ? ['chat', 'login', 'forms', 'woo'] : ['chat', 'login', 'forms'], true)) { 206 238 $tab = 'chat'; 207 239 } … … 217 249 <?php esc_html_e('Login with WhatsApp', 'viswapp-chat-widget'); ?> 218 250 <span class="vw-dot <?php echo esc_attr($loginReady ? 'is-on' : ''); ?>" aria-hidden="true"></span></a> 251 <a href="<?php echo esc_url(add_query_arg('vw_tab', 'forms')); ?>" class="nav-tab <?php echo esc_attr($tab === 'forms' ? 'nav-tab-active' : ''); ?>" data-tab="forms"> 252 <?php esc_html_e('Web forms', 'viswapp-chat-widget'); ?> 253 <span class="vw-dot <?php echo esc_attr($formsReady ? 'is-on' : ''); ?>" aria-hidden="true"></span></a> 219 254 <?php if ($woo) : ?> 220 255 <a href="<?php echo esc_url(add_query_arg('vw_tab', 'woo')); ?>" class="nav-tab <?php echo esc_attr($tab === 'woo' ? 'nav-tab-active' : ''); ?>" data-tab="woo"> … … 448 483 449 484 <?php 485 $this->render_forms($fo, $formsReady, $tab === 'forms'); 450 486 if ($woo) { 451 487 $this->render_woo($wo, $wooReady, $tab === 'woo'); … … 456 492 </form> 457 493 </div> 494 <?php 495 } 496 497 /** Web forms tab: where forms load from, and how to add one */ 498 private function render_forms(array $fo, bool $ready, bool $open): void 499 { 500 $name = VisWapp_Forms::OPTION; 501 ?> 502 <div class="vw-pane" data-pane="forms" <?php echo esc_attr($open ? '' : 'hidden'); ?>> 503 <div class="vw-status <?php echo esc_attr($ready ? 'is-on' : 'is-off'); ?>"> 504 <?php if ($ready) : ?> 505 <strong><?php esc_html_e('Forms are ready to add to your pages.', 'viswapp-chat-widget'); ?></strong> 506 <span><?php echo esc_html((string) wp_parse_url(VisWapp_Forms::api($fo), PHP_URL_HOST)); ?></span> 507 <?php else : ?> 508 <strong><?php esc_html_e('Not set up yet.', 'viswapp-chat-widget'); ?></strong> 509 <span><?php esc_html_e('Paste a form’s embed code below and save.', 'viswapp-chat-widget'); ?></span> 510 <?php endif; ?> 511 </div> 512 513 <div class="vw-card"> 514 <h2><?php esc_html_e('1. Connect to VisWapp', 'viswapp-chat-widget'); ?></h2> 515 <p class="description"> 516 <?php esc_html_e('Build lead forms in VisWapp → Web Forms. Every response becomes a contact, and can create a lead, send a WhatsApp message, add a Google Sheet row or call your webhook. If the chat widget is set up, forms already work: its API address is used.', 'viswapp-chat-widget'); ?> 517 </p> 518 <table class="form-table" role="presentation"> 519 <tr> 520 <th scope="row"><label for="vw-forms-embed"><?php esc_html_e('Embed code', 'viswapp-chat-widget'); ?></label></th> 521 <td><textarea id="vw-forms-embed" class="large-text code" rows="3" name="<?php echo esc_attr($name); ?>[embed]" placeholder="<?php esc_attr_e('Paste the embed code from VisWapp → Web Forms → Share', 'viswapp-chat-widget'); ?>"></textarea> 522 <p class="description"><?php esc_html_e('Optional. Any form’s “Embed on a page” code from VisWapp → Web Forms → Share fills the two addresses below.', 'viswapp-chat-widget'); ?></p></td> 523 </tr> 524 <tr> 525 <th scope="row"><label for="vw-forms-api"><?php esc_html_e('API address', 'viswapp-chat-widget'); ?></label></th> 526 <td><input id="vw-forms-api" type="url" class="regular-text code" name="<?php echo esc_attr($name); ?>[api]" value="<?php echo esc_attr($fo['api']); ?>" placeholder="<?php echo esc_attr(VisWapp_Forms::api(array_merge($fo, ['api' => ''])) ?: 'https://…/api'); ?>"> 527 <p class="description"><?php esc_html_e('The data-api of the embed code. Empty: the chat widget’s Data API address.', 'viswapp-chat-widget'); ?></p></td> 528 </tr> 529 <tr> 530 <th scope="row"><label for="vw-forms-src"><?php esc_html_e('Script address', 'viswapp-chat-widget'); ?></label></th> 531 <td><input id="vw-forms-src" type="url" class="regular-text code" name="<?php echo esc_attr($name); ?>[src]" value="<?php echo esc_attr($fo['src']); ?>" placeholder="<?php echo esc_attr(VisWapp_Forms::src(array_merge($fo, ['src' => '']))); ?>"> 532 <p class="description"><?php esc_html_e('Where f.js loads from. Empty: next to the chat widget script. It is only added to pages that show a form.', 'viswapp-chat-widget'); ?></p></td> 533 </tr> 534 </table> 535 </div> 536 537 <div class="vw-card"> 538 <h2><?php esc_html_e('2. Add a form to a page', 'viswapp-chat-widget'); ?></h2> 539 <p class="description"><?php esc_html_e('In the block editor, add the “VisWapp form” block and paste the form key. Or use the shortcode anywhere shortcodes work:', 'viswapp-chat-widget'); ?></p> 540 <p><code>[viswapp_form id="vw_frm_…"]</code> — <?php esc_html_e('the form in the page', 'viswapp-chat-widget'); ?></p> 541 <p><code>[viswapp_form id="vw_frm_…" mode="popup" label="Get a quote" position="right"]</code> — <?php esc_html_e('a floating button that opens it', 'viswapp-chat-widget'); ?></p> 542 <p class="description"> 543 <?php 544 printf( 545 /* translators: %s: this site's domain */ 546 esc_html__('If a form limits where it can be embedded (Share → Where can it be embedded?), add %s there.', 'viswapp-chat-widget'), 547 '<code>' . esc_html((string) wp_parse_url(home_url(), PHP_URL_HOST)) . '</code>' 548 ); 549 ?> 550 </p> 551 </div> 552 553 <p class="vw-foot"> 554 <?php esc_html_e('Privacy: form answers are sent straight to VisWapp and are not stored in WordPress. Page caching: forms work on cached pages.', 'viswapp-chat-widget'); ?> 555 </p> 556 </div> 458 557 <?php 459 558 } -
viswapp-chat-widget/trunk/readme.txt
r3739838 r3750893 1 1 === VisWapp Chat Widget === 2 2 Contributors: vectorilo 3 Tags: chat, live chat, whatsapp, whatsapp login, abandoned cart3 Tags: chat, whatsapp, lead form, whatsapp login, abandoned cart 4 4 Requires at least: 5.8 5 5 Tested up to: 7.1 6 6 Requires PHP: 7.4 7 Stable tag: 1. 3.17 Stable tag: 1.4.0 8 8 License: GPLv2 or later 9 9 License URI: https://www.gnu.org/licenses/gpl-2.0.html 10 10 11 VisWapp chat widget, one-tap "Continue with WhatsApp" login and WhatsApp reminders for abandoned WooCommerce carts.11 VisWapp chat widget, lead forms, one-tap "Continue with WhatsApp" login and WhatsApp reminders for abandoned WooCommerce carts. 12 12 13 13 == Description == … … 21 21 * When an identified customer logs out, their chat is cleared from that browser. 22 22 * Login with WhatsApp: a "Continue with WhatsApp" button on the WordPress login page, WooCommerce My account and checkout, or anywhere with the [viswapp_login] shortcode. WhatsApp opens with a message ready; the customer taps send and is logged in. Existing users are matched by WhatsApp number or WooCommerce billing phone; new numbers can get an account automatically. 23 * Lead forms: add a form from VisWapp → Web Forms to any page with the "VisWapp form" block or the [viswapp_form] shortcode, in the page or as a popup button. Every response becomes a VisWapp contact and can create a lead, send a WhatsApp message, add a Google Sheet row or call your webhook. 23 24 * Abandoned cart recovery (WooCommerce): carts are sent to VisWapp once the shopper's phone or email is known, and VisWapp sends a WhatsApp reminder with a link that restores the cart and opens checkout. 24 25 … … 43 44 4. In VisWapp, click Go live when you are ready (test mode works on your allowed domains too). 44 45 46 To add a lead form: 47 48 1. In VisWapp, build and publish a form under Web Forms, and copy its form key (vw_frm_…) from the Share tab. 49 2. In WordPress, add the "VisWapp form" block to a page and paste the key, or use the shortcode [viswapp_form id="vw_frm_…"]. 50 3. Forms use the chat widget's API address. Without the chat widget, paste the form's "Embed on a page" code in Settings → VisWapp → Web forms. 51 45 52 To turn on abandoned cart recovery (WooCommerce): 46 53 … … 69 76 }, 10, 2 ); 70 77 78 == Lead forms == 79 80 The block and the shortcode print a placeholder that the VisWapp forms script (f.js) fills in. The script is added only to pages that show a form, and each form is drawn in its own isolated area, so your theme's styles don't change it. 81 82 [viswapp_form id="vw_frm_…"] 83 [viswapp_form id="vw_frm_…" mode="popup" label="Get a quote" position="left"] 84 85 * id: the form key from VisWapp → Web Forms → Share (required). 86 * mode: inline (the form in the page, default) or popup (a floating button in the form's colour that opens it). 87 * label and position: the popup button's text (default: the form title) and corner (right or left). 88 89 The form's look, questions, thank-you message and what happens with each response are all set in VisWapp; changes show on your site straight away. Responses record the page they came from and its UTM tags. 90 91 Developers can change the printed markup with the viswapp_form_markup filter ($html, $key, $atts); its output is checked against an allow-list. 92 71 93 == External services == 72 94 … … 75 97 * Chat widget. On the pages you choose, visitors' browsers load the widget script from the address in your install snippet (by default https://cdn.viswapp.com/w.js) and talk to your VisWapp Data API address. The widget sends the page address and referrer, the page and browser language, basic device details (browser, screen size, time zone), UTM parameters and what the visitor types in the chat. With "Identify logged-in users" on, the logged-in user's ID, name, email and phone number are sent, signed on your server. 76 98 * Login with WhatsApp. On the login, My account and checkout pages (and wherever you place [viswapp_login]) browsers load login.js from your VisWapp sign-in address. When a customer signs in, your server sends the one-time code and your client credentials to that address (/oauth/token) and receives the customer's verified WhatsApp number. 99 * Lead forms. On pages that show a [viswapp_form] shortcode or a VisWapp form block, browsers load f.js (by default from next to the chat widget script, e.g. https://cdn.viswapp.com/f.js) and read the form from your VisWapp API address. When a visitor submits, their answers, the page address and referrer and the page's UTM parameters are sent to VisWapp. In the block editor, the form's title is read from the same address for the preview. 77 100 * Abandoned cart recovery (WooCommerce). Once a shopper's phone number or email is known, your server sends the cart (products, quantities, prices, totals, cart link) and the shopper's name, phone number, email, country and marketing consent to your VisWapp delivery URL, and again when the cart changes or the order is placed. 78 101 … … 82 105 == Privacy == 83 106 107 Lead form answers (for example name, phone number and email) are sent straight from the visitor's browser to VisWapp and are not stored in WordPress. Mention your forms in your privacy policy, and add a consent checkbox to forms that lead to WhatsApp messages. 108 84 109 With abandoned cart recovery on, cart contents (products, quantities, prices, totals) and the shopper's name, phone number and email address are sent to VisWapp so WhatsApp cart reminders can be sent. The plugin adds suggested text to Settings → Privacy → Policy guide; add it to your privacy policy. Use the consent checkbox where the law requires opt-in for marketing messages. Cart links are stored on your site for 14 days. 85 110 86 111 == Frequently Asked Questions == 112 113 = How do I add a lead form? = 114 115 Add the "VisWapp form" block and paste the form key (vw_frm_…) from VisWapp → Web Forms → Share, or use [viswapp_form id="vw_frm_…"]. Set mode="popup" for a floating button instead. The form must be published in VisWapp; until then visitors see that it is not accepting responses. 116 117 = The form says it is not available on this website = 118 119 The form only allows some websites. In VisWapp → Web Forms → Share → Where can it be embedded?, add your site's domain. 87 120 88 121 = Can I put the WhatsApp login button on my own page? = … … 138 171 = What happens when I delete the plugin? = 139 172 140 Its settings , the saved Identity secret, the WhatsApp Login and abandoned-cart secrets, and saved cart links are removed from WordPress. Chats, contacts and carts stay in VisWapp.173 Its settings (including the Web forms tab), the saved Identity secret, the WhatsApp Login and abandoned-cart secrets, and saved cart links are removed from WordPress. Chats, contacts and carts stay in VisWapp. 141 174 142 175 == Screenshots == … … 148 181 5. Abandoned cart recovery settings for WooCommerce and The WhatsApp reminder with a link that restores the cart. 149 182 150 151 183 == Changelog == 184 185 = 1.4.0 = 186 * Lead forms from VisWapp → Web Forms: the "VisWapp form" block (with a preview of the form in the editor) and the [viswapp_form] shortcode, in the page or as a popup button. The forms script loads only on pages with a form. 187 * Settings → VisWapp → Web forms tab: paste a form's embed code, or let forms use the chat widget's API address. 152 188 153 189 = 1.3.1 = -
viswapp-chat-widget/trunk/uninstall.php
r3739838 r3750893 3 3 * Deleting the plugin removes its settings, the saved Identity secret, the 4 4 * WhatsApp Login client secret, the abandoned-cart settings and webhook 5 * secret, and the saved cart-recovery links. Users keep their viswapp_phone5 * secret, the web forms settings, and the saved cart-recovery links. Users keep their viswapp_phone 6 6 * meta. Chats, contacts and carts stay in VisWapp. 7 7 */ … … 21 21 delete_option('viswapp_woo_carts'); 22 22 delete_option('viswapp_woo_carts_secret'); 23 delete_option('viswapp_forms_settings'); 23 24 24 25 // Cart-recovery links and rate-limit counters (transients stored in the options table) -
viswapp-chat-widget/trunk/viswapp-chat-widget.php
r3739838 r3750893 3 3 * Plugin Name: VisWapp Chat Widget 4 4 * Plugin URI: https://viswapp.com 5 * Description: Login with WhatsApp (one tap on wp-login, WooCommerce and the [viswapp_login] shortcode), the VisWapp website chat widget and WooCommerce abandoned cart reminders on WhatsApp. Settings → VisWapp.6 * Version: 1. 3.15 * Description: Login with WhatsApp (one tap on wp-login, WooCommerce and the [viswapp_login] shortcode), the VisWapp website chat widget, VisWapp lead forms (the [viswapp_form] shortcode and block) and WooCommerce abandoned cart reminders on WhatsApp. Settings → VisWapp. 6 * Version: 1.4.0 7 7 * Requires at least: 5.8 8 8 * Requires PHP: 7.4 … … 18 18 } 19 19 20 define('VISWAPP_WIDGET_VERSION', '1. 3.1');20 define('VISWAPP_WIDGET_VERSION', '1.4.0'); 21 21 define('VISWAPP_WIDGET_FILE', __FILE__); 22 22 define('VISWAPP_WIDGET_DIR', plugin_dir_path(__FILE__)); … … 28 28 require_once VISWAPP_WIDGET_DIR . 'includes/class-viswapp-login.php'; 29 29 require_once VISWAPP_WIDGET_DIR . 'includes/class-viswapp-woo-carts.php'; 30 require_once VISWAPP_WIDGET_DIR . 'includes/class-viswapp-forms.php'; 30 31 31 32 // The Identity secret is read only when signing, so it isn't loaded on every request … … 36 37 add_option(VisWapp_Login::OPTION, VisWapp_Login::defaults()); 37 38 VisWapp_Woo_Carts::install(); 39 add_option(VisWapp_Forms::OPTION, VisWapp_Forms::defaults()); 38 40 }); 39 41 … … 45 47 (new VisWapp_Login())->register(); 46 48 (new VisWapp_Woo_Carts())->register(); // does nothing without WooCommerce 49 (new VisWapp_Forms())->register(); 47 50 }); 48 51
Note:
See TracChangeset
for help on using the changeset viewer.