Plugin Directory

Changeset 3430112


Ignore:
Timestamp:
12/31/2025 12:41:00 PM (8 weeks ago)
Author:
vinema
Message:

1.3.2 - translation to FI

Location:
vine-ma/trunk
Files:
3 added
3 edited

Legend:

Unmodified
Added
Removed
  • vine-ma/trunk/readme.txt

    r3429994 r3430112  
    33Tags: vine, marketing, automation, visitor tracking, email
    44Tested up to: 6.9
    5 Requires at least: 3.0.1
    6 Requires PHP: 5.2
    7 Stable tag: 1.3.1
     5Requires at least: 5.0
     6Requires PHP: 7.0
     7Stable tag: 1.3.2
    88License: GPLv2
    99License URI: http://www.gnu.org/licenses/gpl-2.0
     
    2121
    2222== Changelog ==
     23
     24= 1.3.2 =
     25* Finnish translation included now. Allow Vine form block usage in modern editors too
    2326
    2427= 1.3.1 =
  • vine-ma/trunk/vine_ma_plugin.php

    r3429994 r3430112  
    33/**
    44 * Plugin Name: Vine MA - Email Marketing, Forms, Interactive Bot Forms, Chatbot, Analytics
    5  * Version: 1.3.1
     5 * Version: 1.3.2
    66 * Description: Vine is a Marketing automation tool to generate more leads from your web site. Vine includes web forms, interactive bot forms, landing pages, AI chatbot, visitor tracking, and other functionality to help you to make your site more interesting and to know better what your visitors do there.
    77 * Author: Vine Oy
    88 * Author URI: https://vine.eu
    99 * Text Domain: vinema
     10 * Domain Path: /languages
    1011 * License: GPLv2
    1112 * License URI: http://www.gnu.org/licenses/gpl-2.0
    1213 */
    1314
     15define("VINEMA_VERSION", "1.3.2");
    1416define("VINEHOST", "https://vine.eu");
    1517define("VINECDNHOST", "https://cdn.vine.eu");
     
    2426add_action( 'admin_init', 'vine_ma_register_plugin_settings' );
    2527add_action( 'admin_enqueue_scripts', 'vine_ma_add_vine_script');
     28add_action( 'plugins_loaded', 'vine_ma_load_textdomain' );
     29
     30function vine_ma_load_textdomain() {
     31    load_plugin_textdomain( 'vinema', false, dirname( plugin_basename( __FILE__ ) ) . '/languages/' );
     32}
    2633
    2734function vine_ma_add_vine_script($hook) {
     
    4451    $links[] = '<a href="' .
    4552        admin_url( 'options-general.php?page=vine_ma_plugin' ) .
    46         '">' . __('Settings') . '</a>';
     53           '">' . __('Settings', 'vinema') . '</a>';
    4754    return $links;
    4855}
     
    6875    add_settings_field( 'vine_ma_plugin_setting_username', 'Username:', 'vine_ma_plugin_setting_username', 'vine_ma_plugin', 'vine_ma_general_settings');
    6976    add_settings_field( 'vine_ma_plugin_setting_organization_id', 'Organization ID:', 'vine_ma_plugin_setting_organization_id', 'vine_ma_plugin', 'vine_ma_general_settings');
    70     register_setting( 'vine-plugin-web-forms-cache', 'vine-plugin-web-forms-cache');
    7177}
    7278
    7379//render plugin page
    7480function vine_ma_render_help_text() {
    75     echo "<p>Vine is a Marketing automation tool to generate more leads from your web site. Vine includes web forms, interactive bot forms, landing pages, AI chatbot, visitor tracking, and other functionality to help you to make your site more interesting and to know better what your visitors do there.</p>";
     81    echo '<p>' . esc_html__( 'Vine is a Marketing automation tool to generate more leads from your web site. Vine includes web forms, interactive bot forms, landing pages, AI chatbot, visitor tracking, and other functionality to help you to make your site more interesting and to know better what your visitors do there.', 'vinema' ) . '</p>';
    7682   
    7783    $apikey = vine_ma_get_option('apikey');
     
    7985    if( $apikey != null )
    8086    {
    81         echo "<p>You are currently connected to MA</p>";
    82         echo "<p><a href='javascript:logoutFromMA();'>Logout from MA</a></p>";
     87        echo '<p>' . esc_html__( 'You are currently connected to MA', 'vinema' ) . '</p>';
     88        echo '<p><a href="javascript:logoutFromMA();">' . esc_html__( 'Logout from MA', 'vinema' ) . '</a></p>';
    8389    }
    8490    else {
    85         echo "<p>You need Vine account to use this plugin. If you do not have one, you can register trial account in <a target='_blank' href='https://vine.eu/en/try-for-free'>https://vine.eu/en/try-for-free</a></p>";
    86         echo "<p><a id='vinemaloginbtn' href='javascript:openMaLoginWindow();'>Login to MA</a></p>";
    87         echo "<p><b>Please do not use partner account which can be moved between different customers.</b></p>";
     91        echo '<p>' . wp_kses_post( sprintf(
     92            /* translators: %s is the registration link. */
     93            __( 'You need Vine account to use this plugin. If you do not have one, you can register trial account in %s', 'vinema' ),
     94            "<a target='_blank' href='https://vine.eu/en/try-for-free'>https://vine.eu/en/try-for-free</a>"
     95        ) ) . '</p>';
     96        echo '<p><a id="vinemaloginbtn" href="javascript:openMaLoginWindow();">' . esc_html__( 'Login to MA', 'vinema' ) . '</a></p>';
     97        echo '<p><b>' . esc_html__( 'Please do not use partner account which can be moved between different customers.', 'vinema' ) . '</b></p>';
    8898    }
    8999}
    90100function vine_ma_plugin_setting_organization_id() {
    91101    $orgid = vine_ma_get_option('organization_id');
    92     echo "<input id='vine_ma_plugin_setting_organization_id' name='vine-plugin-options[organization_id]' type='text' value='{$orgid}' readonly />";
     102    $orgid_attr = esc_attr($orgid ?? '');
     103    echo "<input id='vine_ma_plugin_setting_organization_id' name='vine-plugin-options[organization_id]' type='text' value='{$orgid_attr}' readonly />";
    93104}
    94105
     
    97108    if($username == null)
    98109        $username = '';
    99     echo "<input id='vine_ma_plugin_setting_username' name='vine-plugin-options[username]' type='text' value='{$username}' readonly />";
     110    $username_attr = esc_attr($username);
     111    echo "<input id='vine_ma_plugin_setting_username' name='vine-plugin-options[username]' type='text' value='{$username_attr}' readonly />";
    100112}
    101113
     
    104116    if ( is_user_logged_in() && isset($_GET['et_fb']) && isset($_GET['PageSpeed'])) return;
    105117    $orgid = vine_ma_get_option('organization_id');
    106     $src = VINECDNHOST."/vscript/{$orgid}.js";
    107     $srcac = VINECDNHOST."/vscript/allowCookies.js";
     118    if ( empty($orgid) ) {
     119        return;
     120    }
     121
     122    $orgid_encoded = rawurlencode($orgid);
     123    $src = esc_url(VINECDNHOST . "/vscript/{$orgid_encoded}.js");
     124    $srcac = esc_url(VINECDNHOST . '/vscript/allowCookies.js');
    108125    ?>
    109         <script type="text/javascript" src="<?php echo $src ?>" data-cookieconsent="ignore"></script>
    110         <script type="text/plain" src="<?php echo $srcac ?>" data-cookieconsent="marketing" async></script>
     126        <script type="text/javascript" src="<?php echo $src; ?>" data-cookieconsent="ignore"></script>
     127        <script type="text/plain" src="<?php echo $srcac; ?>" data-cookieconsent="marketing" async></script>
    111128    <?php
    112129}
     
    151168//get user organization id
    152169function vine_ma_get_organizationid_username($token) {
    153     $url=VINEHOST."/api/rest/2.0/user?\$authtoken={$token}";
    154     $args = array(
    155       'timeout' => 20,
    156       'user-agent'  =>  ''
    157     );
     170        $url = VINEHOST . "/api/rest/2.0/user";
     171        $args = array(
     172            'timeout' => 20,
     173            'user-agent'  =>  '',
     174            'headers' => array(
     175                '$authtoken' => $token,
     176            ),
     177        );
    158178    $html = wp_remote_get($url, $args);
    159179    $returncode = wp_remote_retrieve_response_code($html);
    160180    if ( $returncode === 200 || $returncode === 304) {
    161181        $body = wp_remote_retrieve_body($html);
    162         $xml = new SimpleXMLElement($body);
     182        $xml = vine_ma_parse_xml($body);
     183        if ( ! $xml ) {
     184            return null;
     185        }
     186
    163187        $orgid = '';
    164188        $username = '';
    165         foreach($xml->xpath('//m:properties') as $event) {
    166           $orgid = (string)$event->xpath('d:ORGANIZATIONID')[0];
    167           $firstname = (string)$event->xpath('d:FIRSTNAME')[0];
    168           $lastname = (string)$event->xpath('d:LASTNAME')[0];
    169           $email = (string)$event->xpath('d:EMAIL')[0];
    170           $username = $firstname . ' ' . $lastname . ' (' . $email . ')';
    171         }
     189        $properties = $xml->xpath('//m:properties');
     190        if ( is_array($properties) ) {
     191            foreach($properties as $event) {
     192              $orgid_node = $event->xpath('d:ORGANIZATIONID');
     193              $firstname_node = $event->xpath('d:FIRSTNAME');
     194              $lastname_node = $event->xpath('d:LASTNAME');
     195              $email_node = $event->xpath('d:EMAIL');
     196              $orgid = isset($orgid_node[0]) ? (string)$orgid_node[0] : '';
     197              $firstname = isset($firstname_node[0]) ? (string)$firstname_node[0] : '';
     198              $lastname = isset($lastname_node[0]) ? (string)$lastname_node[0] : '';
     199              $email = isset($email_node[0]) ? (string)$email_node[0] : '';
     200              $username = trim($firstname . ' ' . $lastname . ($email ? " ({$email})" : ''));
     201            }
     202        }
     203        if ( $orgid === '' ) {
     204            return null;
     205        }
     206
    172207        return array(
    173208            'orgid' => $orgid,
     
    210245    ));
    211246
     247    delete_transient('vine_web_forms_cache');
     248    delete_transient('vine_multiorg_status_cache');
     249
    212250    wp_send_json_success();
    213251}
     
    225263        'apikey' => '',
    226264    ));
    227     update_option('vine-plugin-web-forms-cache', array());
     265    delete_transient('vine_web_forms_cache');
     266    delete_transient('vine_multiorg_status_cache');
    228267
    229268    wp_send_json_success();
     
    233272function vine_ma_admin_notice()
    234273{
     274    if ( ! current_user_can( 'manage_options' ) ) {
     275        return;
     276    }
    235277    $vineLogo = <<<EOD
    236278        <svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" version="1.1" width="24" height="9" viewBox='0 0 134 34' style="margin-right: 10px">
     
    251293            <p>
    252294                <?php echo $vineLogo ?>
    253                 <?php _e('Warning! You are not connected to Vine MA. Vine services cannot work on your pages!', 'textdomain') ?>
     295                <?php esc_html_e('Warning! You are not connected to Vine MA. Vine services cannot work on your pages!', 'vinema') ?>
    254296            </p>
    255297        </div>
     
    265307            <p>
    266308                <?php echo $vineLogo ?>
    267                 <?php _e('An error occurred while communicating with Vine MA. Please try to relogin.', 'textdomain') ?>
     309                <?php esc_html_e('An error occurred while communicating with Vine MA. Please try to relogin.', 'vinema') ?>
    268310            </p>
    269311        </div>
     
    275317function vine_ma_admin_notice_multiorg_status()
    276318{
     319    if ( ! current_user_can( 'manage_options' ) ) {
     320        return;
     321    }
    277322    $vineLogo = <<<EOD
    278323        <svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" version="1.1" width="24" height="9" viewBox='0 0 134 34' style="margin-right: 10px">
     
    294339            <p>
    295340                <?php echo $vineLogo ?>
    296                 <?php _e('Warning! The account used should be account which cannot access multiple organizations. Please relogin with proper account.', 'textdomain') ?>
     341                <?php esc_html_e('Warning! The account used should be account which cannot access multiple organizations. Please relogin with proper account.', 'vinema') ?>
    297342            </p>
    298343        </div>
     
    310355//vine web block hook
    311356function vine_ma_gutenberg_register_web_form_block() {
    312     global $pagenow;
    313     if ( $pagenow != 'post.php' && $pagenow != 'post-new.php' )
    314         return;
    315357    if ( ! function_exists( 'register_block_type' ) ) {
    316358        // Gutenberg is not active.
     
    319361   
    320362    $block_script_path = plugin_dir_path(__FILE__) . 'web_form_block.js';
    321     $block_script_ver  = file_exists($block_script_path) ? filemtime($block_script_path) : false;
     363    $block_script_ver  = file_exists($block_script_path) ? filemtime($block_script_path) : VINEMA_VERSION;
    322364
    323365    wp_register_script(
    324366        'vine-web-form-01',
    325367        plugins_url( 'web_form_block.js', __FILE__ ),
    326         array( 'wp-blocks', 'wp-element' ),
     368        array( 'wp-blocks', 'wp-element', 'wp-data', 'wp-i18n' ),
    327369        $block_script_ver
    328370    );
    329    
    330     $webforms = vine_ma_get_web_forms();
    331    
    332     wp_localize_script('vine-web-form-01', 'VineFormsData', $webforms);
    333371   
    334372    register_block_type( 'vine-ma-plugin/vine-web-form', array(
     
    336374        )
    337375    );
     376}
     377
     378add_action( 'enqueue_block_editor_assets', 'vine_ma_localize_block_forms_data' );
     379
     380function vine_ma_localize_block_forms_data() {
     381    if ( ! wp_script_is( 'vine-web-form-01', 'registered' ) ) {
     382        return;
     383    }
     384
     385    $webforms = vine_ma_get_web_forms();
     386    wp_localize_script( 'vine-web-form-01', 'VineFormsData', $webforms );
     387
     388    $block_labels = array(
     389        'title'      => __( 'Vine: Web Form', 'vinema' ),
     390        'formsError' => __( 'Vine form data unavailable.', 'vinema' ),
     391        'formType'   => __( 'Form Type:', 'vinema' ),
     392        'staticForm' => __( 'Static Form', 'vinema' ),
     393        'botForm'    => __( 'Bot Form', 'vinema' ),
     394        'vineForm'   => __( 'Vine Form:', 'vinema' ),
     395        'notSet'     => __( '<not set>', 'vinema' ),
     396    );
     397    wp_localize_script( 'vine-web-form-01', 'VineFormsStrings', $block_labels );
    338398}
    339399
     
    346406}
    347407
     408function vine_ma_parse_xml($body) {
     409    if ( ! is_string($body) || $body === '' ) {
     410        return null;
     411    }
     412
     413    $previous = libxml_use_internal_errors(true);
     414    $xml = simplexml_load_string($body);
     415    libxml_clear_errors();
     416    libxml_use_internal_errors($previous);
     417
     418    if ( $xml === false ) {
     419        return null;
     420    }
     421
     422    return $xml;
     423}
     424
    348425//get vine web forms via rest api
    349426function vine_ma_get_web_forms() {
    350     $cache = get_option( 'vine-plugin-web-forms-cache' );
    351     if(is_array( $cache ) && isset($cache['timestamp']) && $cache['timestamp'] != null && (time() - $cache['timestamp']) < 120)
    352     {
    353         return array(
    354             'forms' => isset($cache['forms']) ? $cache['forms'] : array(),
    355             'error' => null
    356         );
     427    $cache = get_transient( 'vine_web_forms_cache' );
     428    if ( false !== $cache ) {
     429        return $cache;
    357430    }
    358431    $errorMessage = 'An error occurred while communicating with Vine MA. Please try to refresh page.';
     
    360433    if( $apikey != null) {
    361434      $tokendata = vine_ma_get_authtoken($apikey);
    362       $token = $tokendata['token'];
    363       $error = $tokendata['error'];
     435      $token = is_array($tokendata) ? ($tokendata['token'] ?? null) : null;
     436      $error = is_array($tokendata) ? ($tokendata['error'] ?? null) : null;
    364437      if( $token == null )
    365438          return array(
    366439            'forms' => array(),
    367             'error' => "{$errorMessage} Token:{$error}"
     440            'error' => "{$errorMessage} Token:" . ( $error !== null ? $error : 'Unknown error' )
    368441        );
    369442    } else {
     
    373446        );
    374447    }
    375     $url=VINEHOST."/api/rest/2.0/VS_TRACK_FORM([FORMTYPE] <> 1 and [FORMTYPE] <> 2 and [FORMTYPE] <> 3 and [FORMTYPE] <> 4)?order=name&\$authtoken={$token}";
    376     $args = array(
    377       'timeout' => 20,
    378       'user-agent'  =>  ''
    379     );
     448        $url = VINEHOST . "/api/rest/2.0/VS_TRACK_FORM([FORMTYPE] <> 1 and [FORMTYPE] <> 2 and [FORMTYPE] <> 3 and [FORMTYPE] <> 4)?order=name";
     449        $args = array(
     450            'timeout' => 20,
     451            'user-agent'  =>  '',
     452            'headers' => array(
     453                '$authtoken' => $token,
     454            ),
     455        );
    380456    $html = wp_remote_get($url,$args);
    381457    $returncode = wp_remote_retrieve_response_code($html);
    382         $body = wp_remote_retrieve_body($html);
    383      if ( $returncode === 200 || $returncode === 304 ) {
    384         $xml = new SimpleXMLElement($body);
     458    $body = wp_remote_retrieve_body($html);
     459    if ( $returncode === 200 || $returncode === 304 ) {
     460        $xml = vine_ma_parse_xml($body);
     461        if ( ! $xml ) {
     462            return array(
     463                'forms' => array(),
     464                'error' => "{$errorMessage} Forms:Invalid XML response"
     465            );
     466        }
     467
    385468        $webforms = array();
    386         foreach($xml->xpath('//m:properties') as $event) {
    387           array_push($webforms, array(
    388             'id' => (string)$event->xpath('d:ID')[0],
    389             'name' => (string)$event->xpath('d:NAME')[0],
    390             'type' => (string)$event->xpath('d:FORMTYPE')[0],
    391           ));
    392         }
    393         $timestamp = time();
    394         update_option( 'vine-plugin-web-forms-cache', array(
    395             'forms' => $webforms,
    396             'timestamp' => $timestamp
    397         ));
    398         return array(
     469        $properties = $xml->xpath('//m:properties');
     470        if ( is_array($properties) ) {
     471            foreach ( $properties as $event ) {
     472                $id_node   = $event->xpath( 'd:ID' );
     473                $name_node = $event->xpath( 'd:NAME' );
     474                $type_node = $event->xpath( 'd:FORMTYPE' );
     475
     476                $raw_id   = isset( $id_node[0] ) ? (string) $id_node[0] : '';
     477                $raw_name = isset( $name_node[0] ) ? (string) $name_node[0] : '';
     478                $raw_type = isset( $type_node[0] ) ? (string) $type_node[0] : '';
     479
     480                $sanitized_id = preg_replace( '/[^0-9A-Za-z_-]/', '', $raw_id );
     481                if ( $sanitized_id === '' ) {
     482                    continue;
     483                }
     484
     485                $sanitized_type = preg_replace( '/[^0-9]/', '', $raw_type );
     486
     487                $webforms[] = array(
     488                    'id'   => $sanitized_id,
     489                    'name' => sanitize_text_field( wp_strip_all_tags( $raw_name ) ),
     490                    'type' => $sanitized_type === '' ? '0' : $sanitized_type,
     491                );
     492            }
     493        }
     494
     495        $payload = array(
    399496            'forms' => $webforms,
    400497            'error' => null
    401498        );
     499        set_transient( 'vine_web_forms_cache', $payload, 120 );
     500        return $payload;
    402501    }
    403502    else {
     
    411510//check account multiorg status
    412511function vine_ma_get_multiorg_status() {
    413     $cache = get_option( 'vine-plugin-account-multiorgstatus-cache' );
    414     if(is_array( $cache ) && isset($cache['timestamp']) && $cache['timestamp'] != null && (time() - $cache['timestamp']) < 120)
    415     {
    416         return isset($cache['multiorgstatus']) ? $cache['multiorgstatus'] : false;
     512    $cache = get_transient( 'vine_multiorg_status_cache' );
     513    if ( false !== $cache ) {
     514        return (bool) $cache;
    417515    }
    418516    $errorMessage = 'An error occurred while communicating with Vine MA. Please try to refresh page.';
     
    420518    if( $apikey != null) {
    421519      $tokendata = vine_ma_get_authtoken($apikey);
    422       $token = $tokendata['token'];
    423       $error = $tokendata['error'];
     520      $token = is_array($tokendata) ? ($tokendata['token'] ?? null) : null;
     521      $error = is_array($tokendata) ? ($tokendata['error'] ?? null) : null;
    424522      if( $token == null )
    425523          return false;
     
    427525        return false;
    428526    }
    429     $url=VINEHOST."/api/rest/2.0/VY_USERGROUP([STATUS]='B' and [GROUPROLE] in ('SWITCHORGANIZATION','SWITCHTOANYORG'))?\$authtoken={$token}";
    430     $args = array(
    431       'timeout' => 20,
    432       'user-agent'  =>  ''
    433     );
     527        $url = VINEHOST . "/api/rest/2.0/VY_USERGROUP([STATUS]='B' and [GROUPROLE] in ('SWITCHORGANIZATION','SWITCHTOANYORG'))";
     528        $args = array(
     529            'timeout' => 20,
     530            'user-agent'  =>  '',
     531            'headers' => array(
     532                '$authtoken' => $token,
     533            ),
     534        );
    434535    $html = wp_remote_get($url,$args);
    435536    $returncode = wp_remote_retrieve_response_code($html);
    436      if ( $returncode === 200 || $returncode === 304 ) {
     537    if ( $returncode === 200 || $returncode === 304 ) {
    437538        $body = wp_remote_retrieve_body($html);
    438         $xml = new SimpleXMLElement($body);
    439         $status = $xml->xpath('//m:count')[0] == 0 ? false : true;
    440         $timestamp = time();
    441         update_option( 'vine-plugin-account-multiorgstatus-cache', array(
    442             'multiorgstatus' => $status,
    443             'timestamp' => $timestamp
    444         ));
     539        $xml = vine_ma_parse_xml($body);
     540        if ( ! $xml ) {
     541            return false;
     542        }
     543
     544        $counts = $xml->xpath('//m:count');
     545        $countValue = isset($counts[0]) ? (int)$counts[0] : 0;
     546        $status = $countValue === 0 ? false : true;
     547        set_transient( 'vine_multiorg_status_cache', $status ? '1' : '0', 120 );
    445548        return $status;
    446549    }
  • vine-ma/trunk/web_form_block.js

    r3429994 r3430112  
    1 (function (blocks, element) {
     1
     2(function (blocks, element, data) {
    23    var el = element.createElement;
     4    var translations = (typeof VineFormsStrings !== 'undefined' && VineFormsStrings) ? VineFormsStrings : {};
     5    function t(key, fallback) {
     6        return translations[key] || fallback;
     7    }
     8
     9    function sanitizeId(value) {
     10        return String(value || '').replace(/[^A-Za-z0-9_-]/g, '');
     11    }
    312
    413    function isBotForm(form) {
     
    1120    };
    1221
    13     if (VineFormsData.error != null)
    14         alert(VineFormsData.error);
    15     else
    16         blocks.registerBlockType('vine-ma-plugin/vine-web-form', {
    17             title: 'Vine: Web Form',
     22    var noticeDispatcher = (data && data.dispatch) ? data.dispatch('core/notices') : null;
     23    var createNotice = noticeDispatcher && noticeDispatcher.createNotice ? noticeDispatcher.createNotice : null;
     24    var hasFormsData = typeof VineFormsData !== 'undefined' && VineFormsData;
     25    var formsError = hasFormsData ? VineFormsData.error : t('formsError', 'Vine form data unavailable.');
     26    var vineforms = (hasFormsData && VineFormsData.forms) ? VineFormsData.forms : [];
     27
     28    if (formsError && createNotice) {
     29        createNotice('error', formsError, { isDismissible: true });
     30    }
     31
     32    var blockTitle = t('title', 'Vine: Web Form');
     33    blocks.registerBlockType('vine-ma-plugin/vine-web-form', {
     34                title: blockTitle,
    1835            icon: 'universal-access-alt',
    1936            category: 'layout',
     
    4562            },
    4663            edit: function (props) {
    47                 const vineforms = (VineFormsData && VineFormsData.forms) ? VineFormsData.forms : [];
    48                 const legacyBotMatch = (props.attributes.formclass || '').match(/(?:^|\s)B(\d+)(?:\s|$)/);
    49                 const legacyBotId = legacyBotMatch ? String(legacyBotMatch[1]) : '-1';
     64                if (formsError) {
     65                    return el('div', { style: { padding: '12px', border: '1px solid #ccc' } }, formsError);
     66                }
     67                const legacyBotMatch = (props.attributes.formclass || '').match(/(?:^|\s)B([A-Za-z0-9_-]+)(?:\s|$)/);
     68                const legacyBotId = legacyBotMatch ? sanitizeId(legacyBotMatch[1]) : '-1';
     69                const normalizedFormId = props.attributes.formid ? sanitizeId(props.attributes.formid) : '-1';
     70                const normalizedBotId = props.attributes.botformid ? sanitizeId(props.attributes.botformid) : '-1';
     71                if (props.attributes.formid && normalizedFormId !== props.attributes.formid) {
     72                    props.setAttributes({ formid: normalizedFormId || '-1' });
     73                }
     74                if (props.attributes.botformid && normalizedBotId !== props.attributes.botformid) {
     75                    props.setAttributes({ botformid: normalizedBotId || '-1' });
     76                }
    5077
    5178                // Auto-migrate legacy bot blocks (class-only) so next save writes data-bot-id.
     
    5481                }
    5582
    56                 const hasStaticId = props.attributes.formid && props.attributes.formid !== '-1';
    57                 const hasBotId = (props.attributes.botformid && props.attributes.botformid !== '-1') || legacyBotId !== '-1';
     83                const hasStaticId = normalizedFormId && normalizedFormId !== '-1';
     84                const hasBotId = (normalizedBotId && normalizedBotId !== '-1') || legacyBotId !== '-1';
    5885                const inferredType = hasBotId && !hasStaticId ? 'bot' : 'static';
    5986                const selectedType = (hasStaticId || hasBotId) ? inferredType : (props.attributes.formtype || 'static');
     
    7097
    7198                const els = [];
    72                 els.push(el('option', { value: '-1' }, '<not set>'));
     99                els.push(el('option', { value: '-1' }, t('notSet', '<not set>')));
    73100                for (const form of filteredForms) {
    74                     els.push(el('option', { value: String(form.id) }, form.name));
     101                    const safeId = sanitizeId(form.id);
     102                    if (!safeId) {
     103                        continue;
     104                    }
     105                    els.push(el('option', { value: safeId }, form.name));
    75106                }
    76107
     
    86117
    87118                function onChangeForm(event) {
    88                     const newValue = String(event.target.value || '-1');
     119                    const newValue = sanitizeId(event.target.value || '-1') || '-1';
    89120                    if (isBotType) {
    90121                        props.setAttributes({ botformid: newValue, formid: '-1', formtype: 'bot' });
     
    95126
    96127                const selectedId = isBotType
    97                     ? ((props.attributes.botformid && props.attributes.botformid !== '-1') ? props.attributes.botformid : legacyBotId)
    98                     : props.attributes.formid;
     128                    ? ((normalizedBotId && normalizedBotId !== '-1') ? normalizedBotId : legacyBotId)
     129                    : (normalizedFormId && normalizedFormId !== '-1' ? normalizedFormId : '-1');
    99130                return el(
    100131                    'div',
     
    105136                            {},
    106137                            [
    107                                 el('span', {}, 'Form Type:'),
     138                                el('span', {}, t('formType', 'Form Type:')),
    108139                                el(
    109140                                    'label',
     
    117148                                            onChange: onChangeType
    118149                                        }),
    119                                         ' Static Form'
     150                                        ' ' + t('staticForm', 'Static Form')
    120151                                    ]
    121152                                ),
     
    131162                                            onChange: onChangeType
    132163                                        }),
    133                                         ' Bot Form'
     164                                        ' ' + t('botForm', 'Bot Form')
    134165                                    ]
    135166                                )
     
    139170                            'span',
    140171                            {},
    141                             'Vine Form:'
     172                            t('vineForm', 'Vine Form:')
    142173                        ),
    143174                        el(
     
    149180                );
    150181            },
    151             save: function (props) {
     182                save: function (props) {
    152183                var form = (props.attributes.formtype === 'bot') ? props.attributes.botformid : props.attributes.formid;
    153184                if (form === '-1')
    154185                    form = props.attributes.formid === '-1' ? props.attributes.botformid : props.attributes.formid;
     186                form = sanitizeId(form);
    155187                var vineforms = VineFormsData.forms;
    156188                var targetForm = [];
     
    162194                var args = {
    163195                    className: 'VineForm' + (isDataForm ? '' : ' B' + form),
    164                     'data-form-id': isDataForm ? form : undefined,
    165                     'data-bot-id': !isDataForm ? form : undefined
     196                    'data-form-id': isDataForm && form ? form : undefined,
     197                    'data-bot-id': !isDataForm && form ? form : undefined
    166198                }
    167199                return el(
     
    171203                );
    172204            },
    173         });
     205            });
    174206}(
    175207    window.wp.blocks,
    176     window.wp.element
     208    window.wp.element,
     209    window.wp.data
    177210));
Note: See TracChangeset for help on using the changeset viewer.