Plugin Directory

Changeset 3397694


Ignore:
Timestamp:
11/18/2025 03:20:33 AM (4 months ago)
Author:
linguise
Message:

Updating to version 2.2.5

Location:
linguise
Files:
46 edited
1 copied

Legend:

Unmodified
Added
Removed
  • linguise/tags/2.2.5/linguise.php

    r3393999 r3397694  
    55 * Plugin URI: https://www.linguise.com/
    66 * Description: Linguise translation plugin
    7  * Version:2.2.4
     7 * Version:2.2.5
    88 * Text Domain: linguise
    99 * Domain Path: /languages
  • linguise/tags/2.2.5/readme.txt

    r3393999 r3397694  
    44Requires at least: 4.0
    55Tested up to: 6.8
    6 Stable tag: 2.2.4
     6Stable tag: 2.2.5
    77Requires PHP: 7.0
    88License: GPLv2 or later
     
    107107
    108108== Changelog ==
     109= 2.2.5 =
     110- Fix: Issues with fragment i18n is not getting translated because of CDATA
     111- Feature: Try to capture and translate preloaded API request
     112- Fix: Some fragment data not captured in WooCommerce should be translated now
     113
    109114= 2.2.4 =
    110115- Feature: Support kinyarwanda (rw) language
  • linguise/tags/2.2.5/src/AttributeHandler.php

    r3366846 r3397694  
    5454                ],
    5555            ];
     56
     57            $current_list[] = [
     58                'name' => 'linguise-demo-string-encoded',
     59                'key' => 'data-label-encoded',
     60                'mode' => 'string-encoded',
     61                'matchers' => [
     62                    [
     63                        'key' => 'sc-linguise-demo-encoded',
     64                        'type' => 'tag'
     65                    ]
     66                ],
     67            ];
    5668        }
    5769
     
    213225                        ]
    214226                    ];
     227                } elseif (isset($matcher['mode']) && $matcher['mode'] === 'string-encoded') {
     228                    $cast_data = isset($matcher['cast']) ? $matcher['cast'] : 'html-main';
     229
     230                    $collected_temp = [
     231                        [
     232                            'key' => $matcher['key'],
     233                            'value' => html_entity_decode($key_data, ENT_QUOTES | ENT_SUBSTITUTE, 'utf-8'),
     234                            'format' => $cast_data,
     235                        ]
     236                    ];
    215237                } else {
    216238                    $json_data = json_decode($key_data, true);
     
    349371
    350372                    $protected_json = HTMLHelper::protectEntity($replaced_text);
     373                } elseif (isset($matched['mode']) && $matched['mode'] === 'string-encoded') {
     374                    // Get first item
     375                    $first_fragment = isset($fragment_list['fragments'][0]) ? $fragment_list['fragments'][0] : null;
     376                    if (empty($first_fragment)) {
     377                        continue;
     378                    }
     379
     380                    $first_value = isset($first_fragment['value']) ? $first_fragment['value'] : null;
     381                    if (empty($first_value)) {
     382                        continue;
     383                    }
     384
     385                    // Replace the data
     386                    $replaced_text = htmlspecialchars($first_value, ENT_QUOTES, 'UTF-8', false);
     387                    if ($should_encode) {
     388                        $replaced_text = rawurlencode($replaced_text);
     389                    }
     390
     391                    $protected_json = HTMLHelper::protectEntity($replaced_text);
    351392                } else {
    352393                    // JSON mode, we need to decode the JSON data
  • linguise/tags/2.2.5/src/FragmentBase.php

    r3381590 r3397694  
    249249
    250250        if (empty($value) || !is_string($value)) {
     251            return false;
     252        }
     253
     254        if (is_string($value) && empty($value)) {
    251255            return false;
    252256        }
     
    570574        ];
    571575
     576        $current_list[] = [
     577            'name' => 'wc-settings-encoded-alt',
     578            'match' => 'var wcSettings = JSON\.parse\( decodeURIComponent\( \'(.*?)\' \) \);',
     579            'replacement' => 'var wcSettings = JSON.parse( decodeURIComponent( \'$$JSON_DATA$$\' ) );',
     580            'encode' => true,
     581        ];
     582
     583        $current_list[] = [
     584            'name' => 'wc-settings-api-inject',
     585            'match' => 'wp\.apiFetch\.createPreloadingMiddleware\(\s*JSON\.parse\(\s*decodeURIComponent\(\s*\'(.*?)\'\s*\)\s*\)\s*\)',
     586            'replacement' => 'wp.apiFetch.createPreloadingMiddleware( JSON.parse( decodeURIComponent( \'$$JSON_DATA$$\' ) ) )',
     587            'encode' => true,
     588        ];
     589
    572590        if (defined('CFCORE_VER')) {
    573591            $current_list[] = [
  • linguise/tags/2.2.5/src/FragmentHandler.php

    r3393354 r3397694  
    9191            }
    9292            if ($tl_string || $tl_link || is_string($tl_dom) || $allowed_filters) {
    93                 $collected_fragments[] = [
    94                     'key' => $use_key,
    95                     'value' => $value,
    96                     'format' => $format,
    97                 ];
     93                // Extra check
     94                if (is_string($value) && !empty($value)) {
     95                    $collected_fragments[] = [
     96                        'key' => $use_key,
     97                        'value' => $value,
     98                        'format' => $format,
     99                    ];
     100                }
    98101            }
    99102        }
     
    125128        }
    126129        return $collected_fragments;
     130    }
     131
     132    /**
     133     * Protect sprintf templates in the text by wrapping them in a span tag
     134     *
     135     * @param string $text The text to be protected
     136     *
     137     * @return string The protected text
     138     */
     139    private static function protectSprintfTemplates($text)
     140    {
     141        $pattern = '/(%(?:\d+\$)?[+-]?(?:\d+)?(?:\.\d+)?[bcdeEfFgGosuxX])/';
     142        $replacement = '<span-ling translate="no">$1</span-ling>';
     143        $result = preg_replace($pattern, $replacement, $text);
     144        if (!empty($result)) {
     145            return $result;
     146        }
     147        return $text;
     148    }
     149
     150    /**
     151     * Restore sprintf templates in the text by unwrapping them from the span tag
     152     *
     153     * @param string $text The text to be restored
     154     *
     155     * @return string The restored text
     156     */
     157    private static function restoreSprintfTemplates($text)
     158    {
     159        $pattern = '/<span-ling translate="no">(%(?:\d+\$)?[+-]?(?:\d+)?(?:\.\d+)?[bcdeEfFgGosuxX])<\/span-ling>/';
     160        $result = preg_replace($pattern, '$1', $text);
     161        if (!empty($result)) {
     162            return $result;
     163        }
     164        return $text;
    127165    }
    128166
     
    175213                $html .= ' ' . $tag_select . '="' . $fragment['value'] . '">';
    176214            } else {
    177                 $html .= '>' . $frag_value;
     215                $html .= '>' . self::protectSprintfTemplates($frag_value);
    178216            }
    179217            $html .= '</' . $tag . '>' . "\n";
     
    230268            }
    231269
     270            $fragment_value = self::restoreSprintfTemplates($fragment_value);
     271
    232272            if (!isset($fragments[$fragment_name])) {
    233273                $fragments[$fragment_name] = [];
     
    293333        $override_list = self::getJSONOverrideMatcher($html_data);
    294334
     335        $multi_matched = [];
    295336        foreach ($override_list as $override_item) {
    296337            $script_content = HTMLHelper::unclobberCdataInternal($script_content);
     
    344385            $collected_temp = self::collectFragmentFromJson($json_data, $is_strict);
    345386            if (!empty($collected_temp)) {
    346                 return [
     387                $multi_matched[] = [
    347388                    'name' => $override_item['name'],
    348389                    'fragments' => $collected_temp,
     
    351392        }
    352393
    353         return null;
     394        if (empty($multi_matched)) {
     395            return null;
     396        }
     397
     398        return $multi_matched;
    354399    }
    355400
     
    442487                $overridden_temp = self::tryMatchWithOverride($script, $html_data);
    443488                if (is_array($overridden_temp)) {
    444                     $all_fragments[$overridden_temp['name']][$overridden_temp['name']] = [
    445                         'mode' => 'override',
    446                         'fragments' => $overridden_temp['fragments'],
    447                     ];
     489                    foreach ($overridden_temp as $overridden_temp_item) {
     490                        $all_fragments[$overridden_temp_item['name']][$overridden_temp_item['name']] = [
     491                            'mode' => 'override',
     492                            'fragments' => $overridden_temp_item['fragments'],
     493                        ];
     494                    }
    448495
    449496                    continue;
     
    475522                    $overridden_temp = self::tryMatchWithOverride($script, $html_data);
    476523                    if (is_array($overridden_temp)) {
    477                         $all_fragments[$frag_id][$overridden_temp['name']] = [
    478                             'mode' => 'override',
    479                             'fragments' => $overridden_temp['fragments'],
    480                         ];
     524                        foreach ($overridden_temp as $overridden_temp_item) {
     525                            $all_fragments[$frag_id][$overridden_temp_item['name']] = [
     526                                'mode' => 'override',
     527                                'fragments' => $overridden_temp_item['fragments'],
     528                            ];
     529                        }
    481530                    }
    482531                    continue;
     
    567616                }
    568617                $decoded_key = self::unwrapKey($fragment['key']);
     618                $merged_key = strpos($decoded_key, '[') === 0 ? '$' . $decoded_key : '$.' . $decoded_key;
    569619                try {
    570                     $json_data->set('$.' . $decoded_key, $fragment['value']);
     620                    $json_data->set($merged_key, $fragment['value']);
    571621                } catch (\Linguise\Vendor\JsonPath\InvalidJsonPathException $e) {
    572                     Debug::log('Failed to set key in override: ' . $decoded_key . ' -> ' . $e->getMessage());
     622                    Debug::log('Failed to set key in override: ' . $merged_key . ' -> ' . $e->getMessage());
    573623                }
    574624            }
     
    601651                }
    602652                $decoded_key = self::unwrapKey($fragment['key']);
     653                $merged_key = strpos($decoded_key, '[') === 0 ? '$' . $decoded_key : '$.' . $decoded_key;
    603654                try {
    604                     $json_data->set('$.' . $decoded_key, $fragment['value']);
     655                    $json_data->set($merged_key, $fragment['value']);
    605656                } catch (\Linguise\Vendor\JsonPath\InvalidJsonPathException $e) {
    606                     Debug::log('Failed to set key in override: ' . $decoded_key . ' -> ' . $e->getMessage());
     657                    Debug::log('Failed to set key in override: ' . $merged_key . ' -> ' . $e->getMessage());
    607658                }
    608659            }
     
    676727    {
    677728        $full_param_name = $param_name . '-js-translations';
    678         $overall_matchers = preg_match('/id=["\']' . preg_quote($full_param_name) . '.*?>\s*\(\s*function\(\s*domain,\s*translations\s*\)\s*\{.*?\}\s*\)\s*\(\s*["\']([\w_\-]+)["\']\s*,\s*\{(.*?)\}\s*\)\s*;\s*<\/script>/si', $html_data, $html_matches);
     729        $overall_matchers = preg_match('/id=["\']' . preg_quote($full_param_name) . '["\'].*?>.*?\(\s*function\(\s*domain,\s*translations\s*\)\s*\{.*?\}\s*\)\s*\(\s*["\']([\w_\-]+)["\']\s*,\s*\{(.*?)\}\s*\)\s*;.*?<\/script>/si', $html_data, $html_matches);
    679730        if ($overall_matchers === false || $overall_matchers === 0) {
    680731            return $html_data;
     
    732783        // dump back to JSON
    733784        $replaced_json = json_encode($json_data);
    734         $substr_ptrn = '/(id=["\']' . preg_quote($full_param_name) . '["\'].*?>\s*\(\s*function\(\s*domain,\s*translations\s*\)\s*\{.*?\}\s*\)\s*\(\s*["\']([\w_\-]+)["\']\s*,\s*)(.*?)(\s*\)\s*;\s*<\/script>)/si';
     785        $substr_ptrn = '/(id=["\']' . preg_quote($full_param_name) . '["\'].*?>.*?\(\s*function\(\s*domain,\s*translations\s*\)\s*\{.*?\}\s*\)\s*\(\s*["\']([\w_\-]+)["\']\s*,\s*)(.*?)(\s*\)\s*;.*?<\/script>)/si';
    735786
    736787        $replacement = preg_replace($substr_ptrn, '$1' . $replaced_json . '$4', $html_data, 1, $count);
  • linguise/tags/2.2.5/src/Helper.php

    r3379190 r3397694  
    165165            // If not set, we use the same as $language
    166166            // If set and NULL we should return null
    167             if (isset($languages->$language->wp_code) && !empty($languages->$language->wp_code)) {
     167            if (!array_key_exists('wp_code', (array)$languages->$language)) {
     168                return $language;
     169            }
     170            if (!empty($languages->$language->wp_code)) {
    168171                return $languages->$language->wp_code;
    169             } elseif (!isset($languages->$language->wp_code)) {
    170                 return $language;
    171172            }
    172173
  • linguise/tags/2.2.5/src/constants.php

    r3393999 r3397694  
    11<?php
    22if (!defined('LINGUISE_SCRIPT_TRANSLATION_VERSION')) {
    3     define('LINGUISE_SCRIPT_TRANSLATION_VERSION', 'wordpress_plugin/2.2.4');
     3    define('LINGUISE_SCRIPT_TRANSLATION_VERSION', 'wordpress_plugin/2.2.5');
    44}
    55
    66if (!defined('LINGUISE_VERSION')) {
    7     define('LINGUISE_VERSION', '2.2.4');
     7    define('LINGUISE_VERSION', '2.2.5');
    88}
  • linguise/tags/2.2.5/src/rest-ajax.php

    r3291510 r3397694  
    120120    $ch = curl_init();
    121121    list($translated_content, $response_code) = Translation::getInstance()->_translate($ch, $boundary);
    122     curl_close($ch);
     122    if (PHP_VERSION_ID < 80000) {
     123        // phpcs:ignore PHPCompatibility.FunctionUse.RemovedFunctions.curl_closeDeprecated,Generic.PHP.DeprecatedFunctions.Deprecated -- Since PHP 8.0+, we guard it here
     124        curl_close($ch); // Since, PHP 8+ this thing actually does not do anything (deprecated in PHP 8.5)
     125    }
    123126
    124127    if (!$translated_content || $response_code !== 200) {
     
    138141    $req_reflect = new \ReflectionClass($req_object);
    139142    $reflect_lang = $req_reflect->getProperty('language');
    140     $reflect_lang->setAccessible(true);
     143    if (PHP_VERSION_ID < 80100) {
     144        // phpcs:ignore Generic.PHP.DeprecatedFunctions.Deprecated -- Since PHP 8.0+, we guard it here
     145        $reflect_lang->setAccessible(true); // Since PHP 8.1+, this does not do anything anymore
     146    }
    141147    // Get the old value first
    142148    $req_language = $req_object->getLanguage();
  • linguise/tags/2.2.5/src/thirdparty/base-class.php

    r3339453 r3397694  
    241241        $request = Request::getInstance();
    242242        $language_reflection = new \ReflectionProperty(get_class($request), 'language');
    243         $language_reflection->setAccessible(true);
     243        if (PHP_VERSION_ID < 80100) {
     244            // phpcs:ignore Generic.PHP.DeprecatedFunctions.Deprecated -- Since PHP 8.0+, we guard it here
     245            $language_reflection->setAccessible(true); // Since PHP 8.1+, this does not do anything anymore
     246        }
    244247        $language_reflection->setValue($request, $linguise_language);
    245248   
    246249        $hostname_reflection = new \ReflectionProperty(get_class($request), 'hostname');
    247         $hostname_reflection->setAccessible(true);
     250        if (PHP_VERSION_ID < 80100) {
     251            // phpcs:ignore Generic.PHP.DeprecatedFunctions.Deprecated -- Since PHP 8.0+, we guard it here
     252            $hostname_reflection->setAccessible(true); // Since PHP 8.1+, this does not do anything anymore
     253        }
    248254        $hostname_reflection->setValue($request, $hostname);
    249255   
    250256        $protocol_reflection = new \ReflectionProperty(get_class($request), 'protocol');
    251         $protocol_reflection->setAccessible(true);
     257        if (PHP_VERSION_ID < 80100) {
     258            // phpcs:ignore Generic.PHP.DeprecatedFunctions.Deprecated -- Since PHP 8.0+, we guard it here
     259            $protocol_reflection->setAccessible(true); // Since PHP 8.1+, this does not do anything anymore
     260        }
    252261        $protocol_reflection->setValue($request, $protocol);
    253262   
     
    326335        $ch = curl_init();
    327336        list($translated_content, $response_code) = Translation::getInstance()->_translate($ch, $boundary);
    328         curl_close($ch);
     337        if (PHP_VERSION_ID < 80000) {
     338            // phpcs:ignore PHPCompatibility.FunctionUse.RemovedFunctions.curl_closeDeprecated,Generic.PHP.DeprecatedFunctions.Deprecated -- Since PHP 8.0+, we guard it here
     339            curl_close($ch); // Since, PHP 8+ this thing actually does not do anything (deprecated in PHP 8.5)
     340        }
    329341   
    330342        if (!$translated_content || $response_code !== 200) {
     
    349361        $req_reflect = new \ReflectionClass($request);
    350362        $reflect_lang = $req_reflect->getProperty('language');
    351         $reflect_lang->setAccessible(true);
     363        if (PHP_VERSION_ID < 80100) {
     364            // phpcs:ignore Generic.PHP.DeprecatedFunctions.Deprecated -- Since PHP 8.0+, we guard it here
     365            $reflect_lang->setAccessible(true); // Since PHP 8.1+, this does not do anything anymore
     366        }
    352367        // Get the old value first
    353368        $req_language = $request->getLanguage();
  • linguise/tags/2.2.5/src/thirdparty/fluentcrm.php

    r3291510 r3397694  
    3131     * Determines if the integration should be loaded.
    3232     *
     33     * @codeCoverageIgnore
     34     *
    3335     * @return boolean
    3436     */
     
    4143    /**
    4244     * Load the integration
     45     *
     46     * @codeCoverageIgnore
    4347     *
    4448     * @return void
     
    5862    /**
    5963     * Unload the integration
     64     *
     65     * @codeCoverageIgnore
    6066     *
    6167     * @return void
     
    117123     * @param \FluentCrm\App\Models\Subscriber $subscriber The subscriber model itself
    118124     *
     125     * @codeCoverageIgnore
     126     *
    119127     * @return void
    120128     */
     
    155163     * @param \FluentCrm\App\Models\Subscriber $subscriber The subscriber model itself
    156164     *
     165     * @codeCoverageIgnore
     166     *
    157167     * @return void
    158168     */
     
    172182     * @param \FluentCrm\App\Models\Subscriber $subscriber FluentCRM Subscriber model
    173183     *
     184     * @codeCoverageIgnore
     185     *
    174186     * @return string|null Language code, null if missing
    175187     */
    176188    protected function getLanguageFromSubscriber($subscriber)
    177189    {
     190        // @codeCoverageIgnoreStart
    178191        if (!function_exists('fluentcrm_get_subscriber_meta')) {
    179192            // Try importing fluentcrm
     
    182195            include_once $fluentcrm_path;
    183196        }
     197        // @codeCoverageIgnoreEnd
    184198
    185199        // Still check in case import still fails
  • linguise/tags/2.2.5/src/thirdparty/kickflip-customizer.php

    r3317948 r3397694  
    2424     * Decides if the integration should be loaded.
    2525     *
     26     * @codeCoverageIgnore
     27     *
    2628     * @return boolean
    2729     */
     
    3335    /**
    3436     * Load the integration
     37     *
     38     * @codeCoverageIgnore
    3539     *
    3640     * @return void
     
    7983     * Common initialization for the integration
    8084     *
     85     * @codeCoverageIgnore
     86     *
    8187     * @return void
    8288     */
     
    8995     * Unload the integration
    9096     *
     97     * @codeCoverageIgnore
     98     *
    9199     * @return void
    92100     */
     
    98106    /**
    99107     * Reload the integration
     108     *
     109     * @codeCoverageIgnore
    100110     *
    101111     * @return void
     
    123133                return $output;
    124134            }
    125            
     135
    126136            // Map language to WordPress locale
    127137            $wp_locale = WPHelper::mapLanguageToWordPressLocale($language);
     
    158168        if (preg_match_all('/<iframe[^>]+src=["\']([^"]+)["\']/', $buffer, $full_matches, PREG_SET_ORDER, 0)) {
    159169            foreach ($full_matches as $matches) {
     170                // @codeCoverageIgnoreStart
    160171                if (strpos($matches[0], 'mczrMainIframe') === false) {
    161172                    // No Kickflip iframe found, return the buffer as is
    162173                    continue;
    163174                }
     175                // @codeCoverageIgnoreEnd
    164176
    165177                $iframeUrl = $matches[1];
  • linguise/tags/2.2.5/src/thirdparty/wc/woocommerce.php

    r3382283 r3397694  
    3232        'wc/store/v1/batch',
    3333        'wc/store/v1/checkout',
     34        'wc/store/v1/select-shipping-rate',
    3435    ];
    3536
     
    9091                    'key' => 'name',
    9192                    'value' => 'payment_method'
     93                ]
     94            ]
     95        ],
     96        [
     97            'name' => 'wc-cart-order-summary-header',
     98            'key' => 'data-content',
     99            'mode' => 'string',
     100            'matchers' => [
     101                [
     102                    'type' => 'attribute',
     103                    'key' => 'data-block-name',
     104                    'value' => 'woocommerce/cart-order-summary-heading-block'
     105                ]
     106            ]
     107        ],
     108        [
     109            'name' => 'wc-checkout-terms',
     110            'key' => 'data-text',
     111            'mode' => 'string-encoded',
     112            'matchers' => [
     113                [
     114                    'type' => 'attribute',
     115                    'key' => 'data-block-name',
     116                    'value' => 'woocommerce/checkout-terms-block'
    92117                ]
    93118            ]
     
    147172
    148173        // Used in payment method
    149         $merged_defaults[] = [
    150             'key' => 'currency',
    151             'mode' => 'exact',
    152             'kind' => 'deny',
     174        $exact_disallowed = [
     175            'currency',
     176            'srcset',
     177            'rate_id',
     178            'method_id',
     179            'catalog_visibility',
     180            'sku',
     181            'Nonce',
     182            'Cart-Hash',
     183            'Cart-Token',
    153184        ];
     185        foreach ($exact_disallowed as $disallowed_key) {
     186            $fragment_keys[] = [
     187                'key' => $disallowed_key,
     188                'mode' => 'exact',
     189                'kind' => 'deny',
     190            ];
     191        }
     192
     193        $disallowed_extras = [
     194            '(shipping|billing)_address\..*',
     195            'totals\..*',
     196            'prices\..*',
     197            'currency_(prefix|suffix|symbol|code|decimal_separator|thousand_separator|minor_unit)',
     198            'meta_data\.\d+\.key',
     199            'items\.\d+\.key',
     200            'shipping_rates\.\d+\.destination\..*',
     201        ];
     202        foreach ($disallowed_extras as $disallowed_key) {
     203            $fragment_keys[] = [
     204                'key' => $disallowed_key,
     205                'mode' => 'regex_full',
     206                'kind' => 'deny',
     207            ];
     208        }
     209
     210        /* More AJAX specific allowed matches */
     211        $allowed_matches = [
     212            'shipping_rates\.\d+\.name$',
     213            'shipping_rates\.\d+\.items\.\d+\.name$',
     214            'shipping_rates\.\d+\.shipping_rates\.\d+\.(name|description|delivery_time)$',
     215        ];
     216        foreach ($allowed_matches as $allowed_key) {
     217            $fragment_keys[] = [
     218                'key' => $allowed_key,
     219                'mode' => 'regex_full',
     220                'kind' => 'allow',
     221            ];
     222        }
    154223
    155224        self::$fragment_keys = $fragment_keys;
  • linguise/tags/2.2.5/vendor/composer/installed.json

    r3393999 r3397694  
    5757        {
    5858            "name": "linguise/script-php",
    59             "version": "v1.3.40",
    60             "version_normalized": "1.3.40.0",
     59            "version": "v1.3.41",
     60            "version_normalized": "1.3.41.0",
    6161            "source": {
    6262                "type": "git",
    6363                "url": "git@bitbucket.org:linguise/script-php.git",
    64                 "reference": "f6196c984ea70ec37b51f35c02598e9f0baaa918"
     64                "reference": "dd11ab02f87a02c275f1621254068f795f7046fb"
    6565            },
    6666            "require": {
     
    7575                "vlucas/phpdotenv": "^5.6"
    7676            },
    77             "time": "2025-11-12T03:56:00+00:00",
     77            "time": "2025-11-18T03:16:07+00:00",
    7878            "type": "library",
    7979            "installation-source": "source",
  • linguise/tags/2.2.5/vendor/composer/installed.php

    r3393999 r3397694  
    44        'pretty_version' => 'dev-master',
    55        'version' => 'dev-master',
    6         'reference' => '4a1d79317c6c26de2d4c936d1b4cf94af231914f',
     6        'reference' => '8bdaaf1d32585b5280a4c2cc6ab9b9722d0e8b00',
    77        'type' => 'library',
    88        'install_path' => __DIR__ . '/../../',
     
    2121        ),
    2222        'linguise/script-php' => array(
    23             'pretty_version' => 'v1.3.40',
    24             'version' => '1.3.40.0',
    25             'reference' => 'f6196c984ea70ec37b51f35c02598e9f0baaa918',
     23            'pretty_version' => 'v1.3.41',
     24            'version' => '1.3.41.0',
     25            'reference' => 'dd11ab02f87a02c275f1621254068f795f7046fb',
    2626            'type' => 'library',
    2727            'install_path' => __DIR__ . '/../linguise/script-php',
     
    3232            'pretty_version' => 'dev-master',
    3333            'version' => 'dev-master',
    34             'reference' => '4a1d79317c6c26de2d4c936d1b4cf94af231914f',
     34            'reference' => '8bdaaf1d32585b5280a4c2cc6ab9b9722d0e8b00',
    3535            'type' => 'library',
    3636            'install_path' => __DIR__ . '/../../',
  • linguise/tags/2.2.5/vendor/linguise/script-php/.version

    r3393999 r3397694  
    1 1.3.40
     11.3.41
  • linguise/tags/2.2.5/vendor/linguise/script-php/src/Certificates.php

    r3300467 r3397694  
    106106            $etag = $this->getEtag($headers);
    107107
    108             curl_close($ch);
     108            if (PHP_VERSION_ID < 80000) {
     109                curl_close($ch); // Since, PHP 8+ this thing actually does not do anything (deprecated in PHP 8.5)
     110            }
    109111        }
    110112
     
    130132
    131133        if ($info['http_code'] !== 200 || $info['content_type'] !== 'application/x-pem-file') {
     134            if (PHP_VERSION_ID < 80000) {
     135                curl_close($ch); // Since, PHP 8+ this thing actually does not do anything (deprecated in PHP 8.5)
     136            }           
    132137            // Something went wrong
    133138            return;
     
    139144        $info = curl_getinfo($ch);
    140145
     146        if (PHP_VERSION_ID < 80000) {
     147            curl_close($ch); // Since, PHP 8+ this thing actually does not do anything (deprecated in PHP 8.5)
     148        }
     149
    141150        if ($info['http_code'] !== 200) {
    142151            // Something went wrong
  • linguise/tags/2.2.5/vendor/linguise/script-php/src/Debug.php

    r2747856 r3397694  
    33namespace Linguise\Vendor\Linguise\Script\Core;
    44
    5 defined('LINGUISE_SCRIPT_TRANSLATION') or die();
     5defined('LINGUISE_SCRIPT_TRANSLATION') or die(); // @codeCoverageIgnore
    66
    77class Debug
     
    1919        self::$error_file = dirname(__FILE__) . '/../debug.php';
    2020
    21         if (!file_exists(self::$error_file)) {
     21        $is_testing = defined('LINGUISE_SCRIPT_TESTING') && LINGUISE_SCRIPT_TESTING;
     22
     23        if (!file_exists(self::$error_file) && !$is_testing) {
    2224            file_put_contents(self::$error_file, '<?php die(); ?>' . PHP_EOL);
    2325        }
     
    4143        }
    4244
     45        if (defined('LINGUISE_SCRIPT_TESTING') && LINGUISE_SCRIPT_TESTING) {
     46            // during testing, do not write to file
     47            return;
     48        }
     49
    4350        if (!is_writable(self::$error_file)) {
    4451            return;
     
    5562    {
    5663        if (self::$enabled === false) {
     64            return;
     65        }
     66
     67        if (defined('LINGUISE_SCRIPT_TESTING') && LINGUISE_SCRIPT_TESTING) {
     68            // during testing, do not write to file
    5769            return;
    5870        }
     
    8698    public static function saveError($error)
    8799    {
     100        if (defined('LINGUISE_SCRIPT_TESTING') && LINGUISE_SCRIPT_TESTING) {
     101            // during testing, do not write to file
     102            return;
     103        }
     104
    88105        $file = dirname(__FILE__) . '/../errors.php';
    89106
  • linguise/tags/2.2.5/vendor/linguise/script-php/src/JsonWalker.php

    r3257498 r3397694  
    33namespace Linguise\Vendor\Linguise\Script\Core;
    44
    5 defined('LINGUISE_SCRIPT_TRANSLATION') or die();
     5defined('LINGUISE_SCRIPT_TRANSLATION') or die(); // @codeCoverageIgnore
    66
    77/**
    88 * Check if the array is an actual object or not.
     9 *
     10 * @codeCoverageIgnore
    911 *
    1012 * @param array|object $arr_or_object The array or object to be checked
  • linguise/tags/2.2.5/vendor/linguise/script-php/src/Management.php

    r3388557 r3397694  
    509509        curl_exec($ch);
    510510        $response_code = curl_getinfo($ch, CURLINFO_HTTP_CODE);
    511         // log error to apache error
    512         curl_close($ch);
     511        if (PHP_VERSION_ID < 80000) {
     512            curl_close($ch); // Since, PHP 8+ this thing actually does not do anything (deprecated in PHP 8.5)
     513        }
    513514
    514515        if ($response_code !== 200) {
     
    546547        $response = curl_exec($ch);
    547548        $response_code = curl_getinfo($ch, CURLINFO_HTTP_CODE);
    548         curl_close($ch);
     549        if (PHP_VERSION_ID < 80000) {
     550            curl_close($ch); // Since, PHP 8+ this thing actually does not do anything (deprecated in PHP 8.5)
     551        }
    549552
    550553        if ($response_code !== 200) {
     
    603606        $response = curl_exec($ch);
    604607        $response_code = curl_getinfo($ch, CURLINFO_HTTP_CODE);
    605         curl_close($ch);
     608        if (PHP_VERSION_ID < 80000) {
     609            curl_close($ch); // Since, PHP 8+ this thing actually does not do anything (deprecated in PHP 8.5)
     610        }
    606611
    607612        if ($response_code !== 200) {
  • linguise/tags/2.2.5/vendor/linguise/script-php/src/Platforms/PrestaShop.php

    r3393999 r3397694  
    346346        $ch = curl_init();
    347347        list($translated_content, $response_code) = Translation::getInstance()->_translate($ch, $boundary);
    348         curl_close($ch);
     348        if (PHP_VERSION_ID < 80000) {
     349            curl_close($ch); // Since, PHP 8+ this thing actually does not do anything (deprecated in PHP 8.5)
     350        }
    349351
    350352        if (!$translated_content || $response_code !== 200) {
  • linguise/tags/2.2.5/vendor/linguise/script-php/src/Processor.php

    r3377801 r3397694  
    22namespace Linguise\Vendor\Linguise\Script\Core;
    33
    4 defined('LINGUISE_SCRIPT_TRANSLATION') or die();
     4defined('LINGUISE_SCRIPT_TRANSLATION') or die(); // @codeCoverageIgnore
    55
    66class Processor {
     
    2727
    2828        // Finalize defer actions on shutdown
     29        // @codeCoverageIgnoreStart
    2930        register_shutdown_function(function() {
    3031            Defer::getInstance()->finalize();
    3132            Database::getInstance()->close();
    3233        });
     34        // @codeCoverageIgnoreEnd
    3335    }
    3436
     
    3941    {
    4042        if (!isset($_GET['linguise_language'])) {
    41             die();
     43            if (defined('LINGUISE_SCRIPT_TESTING') && LINGUISE_SCRIPT_TESTING) {
     44                // during testing, do not write to file
     45                return;
     46            }
     47            die(); // @codeCoverageIgnore
    4248        }
    4349
    4450        // AI Translation Stuff
    45         if ( $_SERVER['REQUEST_METHOD'] === 'POST' && isset($_POST['live_editor_ai_translation']) ) {
     51        if ($_SERVER['REQUEST_METHOD'] === 'POST' && isset($_POST['live_editor_ai_translation']) ) {
    4652            $_SERVER['REQUEST_METHOD'] = 'GET';
    4753            Translation::getInstance()->enableAiTranslation($_POST['live_editor_ai_translation']);
     
    6167        if (Response::getInstance()->getResponseCode() === 304) {
    6268            Debug::log('304 Not modified');
    63             Response::getInstance()->end();
     69            return Response::getInstance()->end();
    6470        }
    6571
     
    8793    }
    8894
     95    /**
     96     * Update the Linguise Script PHP to the latest version
     97     *
     98     * @codeCoverageIgnore
     99     *
     100     * @return void
     101     */
    89102    public function update()
    90103    {
     
    100113                echo '<p>It seems you were trying the Live Editor with the wrong domain configuration. </p>
    101114                      <p>Please double-check on your configuration in your Linguise dashboard or reach out to our support team</p>';
    102                 die();
     115
     116                if (defined('LINGUISE_SCRIPT_TESTING') && LINGUISE_SCRIPT_TESTING) {
     117                    // stop execution for testing purposes
     118                    return;
     119                }
     120                die(); // @codeCoverageIgnore
    103121            }
    104122
     
    120138                echo '<p>It seems you were trying the Live Editor with the wrong domain configuration. </p>
    121139                      <p>Please double-check on your configuration in your Linguise dashboard or reach out to our support team</p>';
    122                 die();
     140
     141                if (defined('LINGUISE_SCRIPT_TESTING') && LINGUISE_SCRIPT_TESTING) {
     142                    // stop execution for testing purposes
     143                    return;
     144                }
     145                die(); // @codeCoverageIgnore
    123146            }
    124147
     
    152175        Certificates::getInstance()->downloadCertificates();
    153176    }
    154 
    155177}
  • linguise/tags/2.2.5/vendor/linguise/script-php/src/Translation.php

    r3388557 r3397694  
    9797        }
    9898
    99         curl_close($ch);
     99        if (PHP_VERSION_ID < 80000) {
     100            curl_close($ch); // Since, PHP 8+ this thing actually does not do anything (deprecated in PHP 8.5)
     101        }
    100102
    101103        $result = json_decode($translated_content);
     
    223225        Debug::log('Translated content: ' . PHP_EOL . '######################' . PHP_EOL . $translated_content . PHP_EOL . '######################', 5);
    224226
    225         curl_close($ch);
     227        if (PHP_VERSION_ID < 80000) {
     228            curl_close($ch); // Since, PHP 8+ this thing actually does not do anything (deprecated in PHP 8.5)
     229        }
    226230
    227231        if (!$translated_content || $response_code !== 200) {
  • linguise/tags/2.2.5/vendor/linguise/script-php/src/Updater.php

    r2652292 r3397694  
    5757        }
    5858        $content = curl_exec($ch);
    59         curl_close($ch);
     59        if (PHP_VERSION_ID < 80000) {
     60            curl_close($ch); // Since, PHP 8+ this thing actually does not do anything (deprecated in PHP 8.5)
     61        }
    6062
    6163        if (!$content) {
     
    9395        }
    9496        $file_content = curl_exec($ch);
    95         curl_close($ch);
     97        if (PHP_VERSION_ID < 80000) {
     98            curl_close($ch); // Since, PHP 8+ this thing actually does not do anything (deprecated in PHP 8.5)
     99        }
    96100
    97101        if (!$file_content) {
  • linguise/trunk/linguise.php

    r3393999 r3397694  
    55 * Plugin URI: https://www.linguise.com/
    66 * Description: Linguise translation plugin
    7  * Version:2.2.4
     7 * Version:2.2.5
    88 * Text Domain: linguise
    99 * Domain Path: /languages
  • linguise/trunk/readme.txt

    r3393999 r3397694  
    44Requires at least: 4.0
    55Tested up to: 6.8
    6 Stable tag: 2.2.4
     6Stable tag: 2.2.5
    77Requires PHP: 7.0
    88License: GPLv2 or later
     
    107107
    108108== Changelog ==
     109= 2.2.5 =
     110- Fix: Issues with fragment i18n is not getting translated because of CDATA
     111- Feature: Try to capture and translate preloaded API request
     112- Fix: Some fragment data not captured in WooCommerce should be translated now
     113
    109114= 2.2.4 =
    110115- Feature: Support kinyarwanda (rw) language
  • linguise/trunk/src/AttributeHandler.php

    r3366846 r3397694  
    5454                ],
    5555            ];
     56
     57            $current_list[] = [
     58                'name' => 'linguise-demo-string-encoded',
     59                'key' => 'data-label-encoded',
     60                'mode' => 'string-encoded',
     61                'matchers' => [
     62                    [
     63                        'key' => 'sc-linguise-demo-encoded',
     64                        'type' => 'tag'
     65                    ]
     66                ],
     67            ];
    5668        }
    5769
     
    213225                        ]
    214226                    ];
     227                } elseif (isset($matcher['mode']) && $matcher['mode'] === 'string-encoded') {
     228                    $cast_data = isset($matcher['cast']) ? $matcher['cast'] : 'html-main';
     229
     230                    $collected_temp = [
     231                        [
     232                            'key' => $matcher['key'],
     233                            'value' => html_entity_decode($key_data, ENT_QUOTES | ENT_SUBSTITUTE, 'utf-8'),
     234                            'format' => $cast_data,
     235                        ]
     236                    ];
    215237                } else {
    216238                    $json_data = json_decode($key_data, true);
     
    349371
    350372                    $protected_json = HTMLHelper::protectEntity($replaced_text);
     373                } elseif (isset($matched['mode']) && $matched['mode'] === 'string-encoded') {
     374                    // Get first item
     375                    $first_fragment = isset($fragment_list['fragments'][0]) ? $fragment_list['fragments'][0] : null;
     376                    if (empty($first_fragment)) {
     377                        continue;
     378                    }
     379
     380                    $first_value = isset($first_fragment['value']) ? $first_fragment['value'] : null;
     381                    if (empty($first_value)) {
     382                        continue;
     383                    }
     384
     385                    // Replace the data
     386                    $replaced_text = htmlspecialchars($first_value, ENT_QUOTES, 'UTF-8', false);
     387                    if ($should_encode) {
     388                        $replaced_text = rawurlencode($replaced_text);
     389                    }
     390
     391                    $protected_json = HTMLHelper::protectEntity($replaced_text);
    351392                } else {
    352393                    // JSON mode, we need to decode the JSON data
  • linguise/trunk/src/FragmentBase.php

    r3381590 r3397694  
    249249
    250250        if (empty($value) || !is_string($value)) {
     251            return false;
     252        }
     253
     254        if (is_string($value) && empty($value)) {
    251255            return false;
    252256        }
     
    570574        ];
    571575
     576        $current_list[] = [
     577            'name' => 'wc-settings-encoded-alt',
     578            'match' => 'var wcSettings = JSON\.parse\( decodeURIComponent\( \'(.*?)\' \) \);',
     579            'replacement' => 'var wcSettings = JSON.parse( decodeURIComponent( \'$$JSON_DATA$$\' ) );',
     580            'encode' => true,
     581        ];
     582
     583        $current_list[] = [
     584            'name' => 'wc-settings-api-inject',
     585            'match' => 'wp\.apiFetch\.createPreloadingMiddleware\(\s*JSON\.parse\(\s*decodeURIComponent\(\s*\'(.*?)\'\s*\)\s*\)\s*\)',
     586            'replacement' => 'wp.apiFetch.createPreloadingMiddleware( JSON.parse( decodeURIComponent( \'$$JSON_DATA$$\' ) ) )',
     587            'encode' => true,
     588        ];
     589
    572590        if (defined('CFCORE_VER')) {
    573591            $current_list[] = [
  • linguise/trunk/src/FragmentHandler.php

    r3393354 r3397694  
    9191            }
    9292            if ($tl_string || $tl_link || is_string($tl_dom) || $allowed_filters) {
    93                 $collected_fragments[] = [
    94                     'key' => $use_key,
    95                     'value' => $value,
    96                     'format' => $format,
    97                 ];
     93                // Extra check
     94                if (is_string($value) && !empty($value)) {
     95                    $collected_fragments[] = [
     96                        'key' => $use_key,
     97                        'value' => $value,
     98                        'format' => $format,
     99                    ];
     100                }
    98101            }
    99102        }
     
    125128        }
    126129        return $collected_fragments;
     130    }
     131
     132    /**
     133     * Protect sprintf templates in the text by wrapping them in a span tag
     134     *
     135     * @param string $text The text to be protected
     136     *
     137     * @return string The protected text
     138     */
     139    private static function protectSprintfTemplates($text)
     140    {
     141        $pattern = '/(%(?:\d+\$)?[+-]?(?:\d+)?(?:\.\d+)?[bcdeEfFgGosuxX])/';
     142        $replacement = '<span-ling translate="no">$1</span-ling>';
     143        $result = preg_replace($pattern, $replacement, $text);
     144        if (!empty($result)) {
     145            return $result;
     146        }
     147        return $text;
     148    }
     149
     150    /**
     151     * Restore sprintf templates in the text by unwrapping them from the span tag
     152     *
     153     * @param string $text The text to be restored
     154     *
     155     * @return string The restored text
     156     */
     157    private static function restoreSprintfTemplates($text)
     158    {
     159        $pattern = '/<span-ling translate="no">(%(?:\d+\$)?[+-]?(?:\d+)?(?:\.\d+)?[bcdeEfFgGosuxX])<\/span-ling>/';
     160        $result = preg_replace($pattern, '$1', $text);
     161        if (!empty($result)) {
     162            return $result;
     163        }
     164        return $text;
    127165    }
    128166
     
    175213                $html .= ' ' . $tag_select . '="' . $fragment['value'] . '">';
    176214            } else {
    177                 $html .= '>' . $frag_value;
     215                $html .= '>' . self::protectSprintfTemplates($frag_value);
    178216            }
    179217            $html .= '</' . $tag . '>' . "\n";
     
    230268            }
    231269
     270            $fragment_value = self::restoreSprintfTemplates($fragment_value);
     271
    232272            if (!isset($fragments[$fragment_name])) {
    233273                $fragments[$fragment_name] = [];
     
    293333        $override_list = self::getJSONOverrideMatcher($html_data);
    294334
     335        $multi_matched = [];
    295336        foreach ($override_list as $override_item) {
    296337            $script_content = HTMLHelper::unclobberCdataInternal($script_content);
     
    344385            $collected_temp = self::collectFragmentFromJson($json_data, $is_strict);
    345386            if (!empty($collected_temp)) {
    346                 return [
     387                $multi_matched[] = [
    347388                    'name' => $override_item['name'],
    348389                    'fragments' => $collected_temp,
     
    351392        }
    352393
    353         return null;
     394        if (empty($multi_matched)) {
     395            return null;
     396        }
     397
     398        return $multi_matched;
    354399    }
    355400
     
    442487                $overridden_temp = self::tryMatchWithOverride($script, $html_data);
    443488                if (is_array($overridden_temp)) {
    444                     $all_fragments[$overridden_temp['name']][$overridden_temp['name']] = [
    445                         'mode' => 'override',
    446                         'fragments' => $overridden_temp['fragments'],
    447                     ];
     489                    foreach ($overridden_temp as $overridden_temp_item) {
     490                        $all_fragments[$overridden_temp_item['name']][$overridden_temp_item['name']] = [
     491                            'mode' => 'override',
     492                            'fragments' => $overridden_temp_item['fragments'],
     493                        ];
     494                    }
    448495
    449496                    continue;
     
    475522                    $overridden_temp = self::tryMatchWithOverride($script, $html_data);
    476523                    if (is_array($overridden_temp)) {
    477                         $all_fragments[$frag_id][$overridden_temp['name']] = [
    478                             'mode' => 'override',
    479                             'fragments' => $overridden_temp['fragments'],
    480                         ];
     524                        foreach ($overridden_temp as $overridden_temp_item) {
     525                            $all_fragments[$frag_id][$overridden_temp_item['name']] = [
     526                                'mode' => 'override',
     527                                'fragments' => $overridden_temp_item['fragments'],
     528                            ];
     529                        }
    481530                    }
    482531                    continue;
     
    567616                }
    568617                $decoded_key = self::unwrapKey($fragment['key']);
     618                $merged_key = strpos($decoded_key, '[') === 0 ? '$' . $decoded_key : '$.' . $decoded_key;
    569619                try {
    570                     $json_data->set('$.' . $decoded_key, $fragment['value']);
     620                    $json_data->set($merged_key, $fragment['value']);
    571621                } catch (\Linguise\Vendor\JsonPath\InvalidJsonPathException $e) {
    572                     Debug::log('Failed to set key in override: ' . $decoded_key . ' -> ' . $e->getMessage());
     622                    Debug::log('Failed to set key in override: ' . $merged_key . ' -> ' . $e->getMessage());
    573623                }
    574624            }
     
    601651                }
    602652                $decoded_key = self::unwrapKey($fragment['key']);
     653                $merged_key = strpos($decoded_key, '[') === 0 ? '$' . $decoded_key : '$.' . $decoded_key;
    603654                try {
    604                     $json_data->set('$.' . $decoded_key, $fragment['value']);
     655                    $json_data->set($merged_key, $fragment['value']);
    605656                } catch (\Linguise\Vendor\JsonPath\InvalidJsonPathException $e) {
    606                     Debug::log('Failed to set key in override: ' . $decoded_key . ' -> ' . $e->getMessage());
     657                    Debug::log('Failed to set key in override: ' . $merged_key . ' -> ' . $e->getMessage());
    607658                }
    608659            }
     
    676727    {
    677728        $full_param_name = $param_name . '-js-translations';
    678         $overall_matchers = preg_match('/id=["\']' . preg_quote($full_param_name) . '.*?>\s*\(\s*function\(\s*domain,\s*translations\s*\)\s*\{.*?\}\s*\)\s*\(\s*["\']([\w_\-]+)["\']\s*,\s*\{(.*?)\}\s*\)\s*;\s*<\/script>/si', $html_data, $html_matches);
     729        $overall_matchers = preg_match('/id=["\']' . preg_quote($full_param_name) . '["\'].*?>.*?\(\s*function\(\s*domain,\s*translations\s*\)\s*\{.*?\}\s*\)\s*\(\s*["\']([\w_\-]+)["\']\s*,\s*\{(.*?)\}\s*\)\s*;.*?<\/script>/si', $html_data, $html_matches);
    679730        if ($overall_matchers === false || $overall_matchers === 0) {
    680731            return $html_data;
     
    732783        // dump back to JSON
    733784        $replaced_json = json_encode($json_data);
    734         $substr_ptrn = '/(id=["\']' . preg_quote($full_param_name) . '["\'].*?>\s*\(\s*function\(\s*domain,\s*translations\s*\)\s*\{.*?\}\s*\)\s*\(\s*["\']([\w_\-]+)["\']\s*,\s*)(.*?)(\s*\)\s*;\s*<\/script>)/si';
     785        $substr_ptrn = '/(id=["\']' . preg_quote($full_param_name) . '["\'].*?>.*?\(\s*function\(\s*domain,\s*translations\s*\)\s*\{.*?\}\s*\)\s*\(\s*["\']([\w_\-]+)["\']\s*,\s*)(.*?)(\s*\)\s*;.*?<\/script>)/si';
    735786
    736787        $replacement = preg_replace($substr_ptrn, '$1' . $replaced_json . '$4', $html_data, 1, $count);
  • linguise/trunk/src/Helper.php

    r3379190 r3397694  
    165165            // If not set, we use the same as $language
    166166            // If set and NULL we should return null
    167             if (isset($languages->$language->wp_code) && !empty($languages->$language->wp_code)) {
     167            if (!array_key_exists('wp_code', (array)$languages->$language)) {
     168                return $language;
     169            }
     170            if (!empty($languages->$language->wp_code)) {
    168171                return $languages->$language->wp_code;
    169             } elseif (!isset($languages->$language->wp_code)) {
    170                 return $language;
    171172            }
    172173
  • linguise/trunk/src/constants.php

    r3393999 r3397694  
    11<?php
    22if (!defined('LINGUISE_SCRIPT_TRANSLATION_VERSION')) {
    3     define('LINGUISE_SCRIPT_TRANSLATION_VERSION', 'wordpress_plugin/2.2.4');
     3    define('LINGUISE_SCRIPT_TRANSLATION_VERSION', 'wordpress_plugin/2.2.5');
    44}
    55
    66if (!defined('LINGUISE_VERSION')) {
    7     define('LINGUISE_VERSION', '2.2.4');
     7    define('LINGUISE_VERSION', '2.2.5');
    88}
  • linguise/trunk/src/rest-ajax.php

    r3291510 r3397694  
    120120    $ch = curl_init();
    121121    list($translated_content, $response_code) = Translation::getInstance()->_translate($ch, $boundary);
    122     curl_close($ch);
     122    if (PHP_VERSION_ID < 80000) {
     123        // phpcs:ignore PHPCompatibility.FunctionUse.RemovedFunctions.curl_closeDeprecated,Generic.PHP.DeprecatedFunctions.Deprecated -- Since PHP 8.0+, we guard it here
     124        curl_close($ch); // Since, PHP 8+ this thing actually does not do anything (deprecated in PHP 8.5)
     125    }
    123126
    124127    if (!$translated_content || $response_code !== 200) {
     
    138141    $req_reflect = new \ReflectionClass($req_object);
    139142    $reflect_lang = $req_reflect->getProperty('language');
    140     $reflect_lang->setAccessible(true);
     143    if (PHP_VERSION_ID < 80100) {
     144        // phpcs:ignore Generic.PHP.DeprecatedFunctions.Deprecated -- Since PHP 8.0+, we guard it here
     145        $reflect_lang->setAccessible(true); // Since PHP 8.1+, this does not do anything anymore
     146    }
    141147    // Get the old value first
    142148    $req_language = $req_object->getLanguage();
  • linguise/trunk/src/thirdparty/base-class.php

    r3339453 r3397694  
    241241        $request = Request::getInstance();
    242242        $language_reflection = new \ReflectionProperty(get_class($request), 'language');
    243         $language_reflection->setAccessible(true);
     243        if (PHP_VERSION_ID < 80100) {
     244            // phpcs:ignore Generic.PHP.DeprecatedFunctions.Deprecated -- Since PHP 8.0+, we guard it here
     245            $language_reflection->setAccessible(true); // Since PHP 8.1+, this does not do anything anymore
     246        }
    244247        $language_reflection->setValue($request, $linguise_language);
    245248   
    246249        $hostname_reflection = new \ReflectionProperty(get_class($request), 'hostname');
    247         $hostname_reflection->setAccessible(true);
     250        if (PHP_VERSION_ID < 80100) {
     251            // phpcs:ignore Generic.PHP.DeprecatedFunctions.Deprecated -- Since PHP 8.0+, we guard it here
     252            $hostname_reflection->setAccessible(true); // Since PHP 8.1+, this does not do anything anymore
     253        }
    248254        $hostname_reflection->setValue($request, $hostname);
    249255   
    250256        $protocol_reflection = new \ReflectionProperty(get_class($request), 'protocol');
    251         $protocol_reflection->setAccessible(true);
     257        if (PHP_VERSION_ID < 80100) {
     258            // phpcs:ignore Generic.PHP.DeprecatedFunctions.Deprecated -- Since PHP 8.0+, we guard it here
     259            $protocol_reflection->setAccessible(true); // Since PHP 8.1+, this does not do anything anymore
     260        }
    252261        $protocol_reflection->setValue($request, $protocol);
    253262   
     
    326335        $ch = curl_init();
    327336        list($translated_content, $response_code) = Translation::getInstance()->_translate($ch, $boundary);
    328         curl_close($ch);
     337        if (PHP_VERSION_ID < 80000) {
     338            // phpcs:ignore PHPCompatibility.FunctionUse.RemovedFunctions.curl_closeDeprecated,Generic.PHP.DeprecatedFunctions.Deprecated -- Since PHP 8.0+, we guard it here
     339            curl_close($ch); // Since, PHP 8+ this thing actually does not do anything (deprecated in PHP 8.5)
     340        }
    329341   
    330342        if (!$translated_content || $response_code !== 200) {
     
    349361        $req_reflect = new \ReflectionClass($request);
    350362        $reflect_lang = $req_reflect->getProperty('language');
    351         $reflect_lang->setAccessible(true);
     363        if (PHP_VERSION_ID < 80100) {
     364            // phpcs:ignore Generic.PHP.DeprecatedFunctions.Deprecated -- Since PHP 8.0+, we guard it here
     365            $reflect_lang->setAccessible(true); // Since PHP 8.1+, this does not do anything anymore
     366        }
    352367        // Get the old value first
    353368        $req_language = $request->getLanguage();
  • linguise/trunk/src/thirdparty/fluentcrm.php

    r3291510 r3397694  
    3131     * Determines if the integration should be loaded.
    3232     *
     33     * @codeCoverageIgnore
     34     *
    3335     * @return boolean
    3436     */
     
    4143    /**
    4244     * Load the integration
     45     *
     46     * @codeCoverageIgnore
    4347     *
    4448     * @return void
     
    5862    /**
    5963     * Unload the integration
     64     *
     65     * @codeCoverageIgnore
    6066     *
    6167     * @return void
     
    117123     * @param \FluentCrm\App\Models\Subscriber $subscriber The subscriber model itself
    118124     *
     125     * @codeCoverageIgnore
     126     *
    119127     * @return void
    120128     */
     
    155163     * @param \FluentCrm\App\Models\Subscriber $subscriber The subscriber model itself
    156164     *
     165     * @codeCoverageIgnore
     166     *
    157167     * @return void
    158168     */
     
    172182     * @param \FluentCrm\App\Models\Subscriber $subscriber FluentCRM Subscriber model
    173183     *
     184     * @codeCoverageIgnore
     185     *
    174186     * @return string|null Language code, null if missing
    175187     */
    176188    protected function getLanguageFromSubscriber($subscriber)
    177189    {
     190        // @codeCoverageIgnoreStart
    178191        if (!function_exists('fluentcrm_get_subscriber_meta')) {
    179192            // Try importing fluentcrm
     
    182195            include_once $fluentcrm_path;
    183196        }
     197        // @codeCoverageIgnoreEnd
    184198
    185199        // Still check in case import still fails
  • linguise/trunk/src/thirdparty/kickflip-customizer.php

    r3317948 r3397694  
    2424     * Decides if the integration should be loaded.
    2525     *
     26     * @codeCoverageIgnore
     27     *
    2628     * @return boolean
    2729     */
     
    3335    /**
    3436     * Load the integration
     37     *
     38     * @codeCoverageIgnore
    3539     *
    3640     * @return void
     
    7983     * Common initialization for the integration
    8084     *
     85     * @codeCoverageIgnore
     86     *
    8187     * @return void
    8288     */
     
    8995     * Unload the integration
    9096     *
     97     * @codeCoverageIgnore
     98     *
    9199     * @return void
    92100     */
     
    98106    /**
    99107     * Reload the integration
     108     *
     109     * @codeCoverageIgnore
    100110     *
    101111     * @return void
     
    123133                return $output;
    124134            }
    125            
     135
    126136            // Map language to WordPress locale
    127137            $wp_locale = WPHelper::mapLanguageToWordPressLocale($language);
     
    158168        if (preg_match_all('/<iframe[^>]+src=["\']([^"]+)["\']/', $buffer, $full_matches, PREG_SET_ORDER, 0)) {
    159169            foreach ($full_matches as $matches) {
     170                // @codeCoverageIgnoreStart
    160171                if (strpos($matches[0], 'mczrMainIframe') === false) {
    161172                    // No Kickflip iframe found, return the buffer as is
    162173                    continue;
    163174                }
     175                // @codeCoverageIgnoreEnd
    164176
    165177                $iframeUrl = $matches[1];
  • linguise/trunk/src/thirdparty/wc/woocommerce.php

    r3382283 r3397694  
    3232        'wc/store/v1/batch',
    3333        'wc/store/v1/checkout',
     34        'wc/store/v1/select-shipping-rate',
    3435    ];
    3536
     
    9091                    'key' => 'name',
    9192                    'value' => 'payment_method'
     93                ]
     94            ]
     95        ],
     96        [
     97            'name' => 'wc-cart-order-summary-header',
     98            'key' => 'data-content',
     99            'mode' => 'string',
     100            'matchers' => [
     101                [
     102                    'type' => 'attribute',
     103                    'key' => 'data-block-name',
     104                    'value' => 'woocommerce/cart-order-summary-heading-block'
     105                ]
     106            ]
     107        ],
     108        [
     109            'name' => 'wc-checkout-terms',
     110            'key' => 'data-text',
     111            'mode' => 'string-encoded',
     112            'matchers' => [
     113                [
     114                    'type' => 'attribute',
     115                    'key' => 'data-block-name',
     116                    'value' => 'woocommerce/checkout-terms-block'
    92117                ]
    93118            ]
     
    147172
    148173        // Used in payment method
    149         $merged_defaults[] = [
    150             'key' => 'currency',
    151             'mode' => 'exact',
    152             'kind' => 'deny',
     174        $exact_disallowed = [
     175            'currency',
     176            'srcset',
     177            'rate_id',
     178            'method_id',
     179            'catalog_visibility',
     180            'sku',
     181            'Nonce',
     182            'Cart-Hash',
     183            'Cart-Token',
    153184        ];
     185        foreach ($exact_disallowed as $disallowed_key) {
     186            $fragment_keys[] = [
     187                'key' => $disallowed_key,
     188                'mode' => 'exact',
     189                'kind' => 'deny',
     190            ];
     191        }
     192
     193        $disallowed_extras = [
     194            '(shipping|billing)_address\..*',
     195            'totals\..*',
     196            'prices\..*',
     197            'currency_(prefix|suffix|symbol|code|decimal_separator|thousand_separator|minor_unit)',
     198            'meta_data\.\d+\.key',
     199            'items\.\d+\.key',
     200            'shipping_rates\.\d+\.destination\..*',
     201        ];
     202        foreach ($disallowed_extras as $disallowed_key) {
     203            $fragment_keys[] = [
     204                'key' => $disallowed_key,
     205                'mode' => 'regex_full',
     206                'kind' => 'deny',
     207            ];
     208        }
     209
     210        /* More AJAX specific allowed matches */
     211        $allowed_matches = [
     212            'shipping_rates\.\d+\.name$',
     213            'shipping_rates\.\d+\.items\.\d+\.name$',
     214            'shipping_rates\.\d+\.shipping_rates\.\d+\.(name|description|delivery_time)$',
     215        ];
     216        foreach ($allowed_matches as $allowed_key) {
     217            $fragment_keys[] = [
     218                'key' => $allowed_key,
     219                'mode' => 'regex_full',
     220                'kind' => 'allow',
     221            ];
     222        }
    154223
    155224        self::$fragment_keys = $fragment_keys;
  • linguise/trunk/vendor/composer/installed.json

    r3393999 r3397694  
    5757        {
    5858            "name": "linguise/script-php",
    59             "version": "v1.3.40",
    60             "version_normalized": "1.3.40.0",
     59            "version": "v1.3.41",
     60            "version_normalized": "1.3.41.0",
    6161            "source": {
    6262                "type": "git",
    6363                "url": "git@bitbucket.org:linguise/script-php.git",
    64                 "reference": "f6196c984ea70ec37b51f35c02598e9f0baaa918"
     64                "reference": "dd11ab02f87a02c275f1621254068f795f7046fb"
    6565            },
    6666            "require": {
     
    7575                "vlucas/phpdotenv": "^5.6"
    7676            },
    77             "time": "2025-11-12T03:56:00+00:00",
     77            "time": "2025-11-18T03:16:07+00:00",
    7878            "type": "library",
    7979            "installation-source": "source",
  • linguise/trunk/vendor/composer/installed.php

    r3393999 r3397694  
    44        'pretty_version' => 'dev-master',
    55        'version' => 'dev-master',
    6         'reference' => '4a1d79317c6c26de2d4c936d1b4cf94af231914f',
     6        'reference' => '8bdaaf1d32585b5280a4c2cc6ab9b9722d0e8b00',
    77        'type' => 'library',
    88        'install_path' => __DIR__ . '/../../',
     
    2121        ),
    2222        'linguise/script-php' => array(
    23             'pretty_version' => 'v1.3.40',
    24             'version' => '1.3.40.0',
    25             'reference' => 'f6196c984ea70ec37b51f35c02598e9f0baaa918',
     23            'pretty_version' => 'v1.3.41',
     24            'version' => '1.3.41.0',
     25            'reference' => 'dd11ab02f87a02c275f1621254068f795f7046fb',
    2626            'type' => 'library',
    2727            'install_path' => __DIR__ . '/../linguise/script-php',
     
    3232            'pretty_version' => 'dev-master',
    3333            'version' => 'dev-master',
    34             'reference' => '4a1d79317c6c26de2d4c936d1b4cf94af231914f',
     34            'reference' => '8bdaaf1d32585b5280a4c2cc6ab9b9722d0e8b00',
    3535            'type' => 'library',
    3636            'install_path' => __DIR__ . '/../../',
  • linguise/trunk/vendor/linguise/script-php/.version

    r3393999 r3397694  
    1 1.3.40
     11.3.41
  • linguise/trunk/vendor/linguise/script-php/src/Certificates.php

    r3300467 r3397694  
    106106            $etag = $this->getEtag($headers);
    107107
    108             curl_close($ch);
     108            if (PHP_VERSION_ID < 80000) {
     109                curl_close($ch); // Since, PHP 8+ this thing actually does not do anything (deprecated in PHP 8.5)
     110            }
    109111        }
    110112
     
    130132
    131133        if ($info['http_code'] !== 200 || $info['content_type'] !== 'application/x-pem-file') {
     134            if (PHP_VERSION_ID < 80000) {
     135                curl_close($ch); // Since, PHP 8+ this thing actually does not do anything (deprecated in PHP 8.5)
     136            }           
    132137            // Something went wrong
    133138            return;
     
    139144        $info = curl_getinfo($ch);
    140145
     146        if (PHP_VERSION_ID < 80000) {
     147            curl_close($ch); // Since, PHP 8+ this thing actually does not do anything (deprecated in PHP 8.5)
     148        }
     149
    141150        if ($info['http_code'] !== 200) {
    142151            // Something went wrong
  • linguise/trunk/vendor/linguise/script-php/src/Debug.php

    r2747856 r3397694  
    33namespace Linguise\Vendor\Linguise\Script\Core;
    44
    5 defined('LINGUISE_SCRIPT_TRANSLATION') or die();
     5defined('LINGUISE_SCRIPT_TRANSLATION') or die(); // @codeCoverageIgnore
    66
    77class Debug
     
    1919        self::$error_file = dirname(__FILE__) . '/../debug.php';
    2020
    21         if (!file_exists(self::$error_file)) {
     21        $is_testing = defined('LINGUISE_SCRIPT_TESTING') && LINGUISE_SCRIPT_TESTING;
     22
     23        if (!file_exists(self::$error_file) && !$is_testing) {
    2224            file_put_contents(self::$error_file, '<?php die(); ?>' . PHP_EOL);
    2325        }
     
    4143        }
    4244
     45        if (defined('LINGUISE_SCRIPT_TESTING') && LINGUISE_SCRIPT_TESTING) {
     46            // during testing, do not write to file
     47            return;
     48        }
     49
    4350        if (!is_writable(self::$error_file)) {
    4451            return;
     
    5562    {
    5663        if (self::$enabled === false) {
     64            return;
     65        }
     66
     67        if (defined('LINGUISE_SCRIPT_TESTING') && LINGUISE_SCRIPT_TESTING) {
     68            // during testing, do not write to file
    5769            return;
    5870        }
     
    8698    public static function saveError($error)
    8799    {
     100        if (defined('LINGUISE_SCRIPT_TESTING') && LINGUISE_SCRIPT_TESTING) {
     101            // during testing, do not write to file
     102            return;
     103        }
     104
    88105        $file = dirname(__FILE__) . '/../errors.php';
    89106
  • linguise/trunk/vendor/linguise/script-php/src/JsonWalker.php

    r3257498 r3397694  
    33namespace Linguise\Vendor\Linguise\Script\Core;
    44
    5 defined('LINGUISE_SCRIPT_TRANSLATION') or die();
     5defined('LINGUISE_SCRIPT_TRANSLATION') or die(); // @codeCoverageIgnore
    66
    77/**
    88 * Check if the array is an actual object or not.
     9 *
     10 * @codeCoverageIgnore
    911 *
    1012 * @param array|object $arr_or_object The array or object to be checked
  • linguise/trunk/vendor/linguise/script-php/src/Management.php

    r3388557 r3397694  
    509509        curl_exec($ch);
    510510        $response_code = curl_getinfo($ch, CURLINFO_HTTP_CODE);
    511         // log error to apache error
    512         curl_close($ch);
     511        if (PHP_VERSION_ID < 80000) {
     512            curl_close($ch); // Since, PHP 8+ this thing actually does not do anything (deprecated in PHP 8.5)
     513        }
    513514
    514515        if ($response_code !== 200) {
     
    546547        $response = curl_exec($ch);
    547548        $response_code = curl_getinfo($ch, CURLINFO_HTTP_CODE);
    548         curl_close($ch);
     549        if (PHP_VERSION_ID < 80000) {
     550            curl_close($ch); // Since, PHP 8+ this thing actually does not do anything (deprecated in PHP 8.5)
     551        }
    549552
    550553        if ($response_code !== 200) {
     
    603606        $response = curl_exec($ch);
    604607        $response_code = curl_getinfo($ch, CURLINFO_HTTP_CODE);
    605         curl_close($ch);
     608        if (PHP_VERSION_ID < 80000) {
     609            curl_close($ch); // Since, PHP 8+ this thing actually does not do anything (deprecated in PHP 8.5)
     610        }
    606611
    607612        if ($response_code !== 200) {
  • linguise/trunk/vendor/linguise/script-php/src/Platforms/PrestaShop.php

    r3393999 r3397694  
    346346        $ch = curl_init();
    347347        list($translated_content, $response_code) = Translation::getInstance()->_translate($ch, $boundary);
    348         curl_close($ch);
     348        if (PHP_VERSION_ID < 80000) {
     349            curl_close($ch); // Since, PHP 8+ this thing actually does not do anything (deprecated in PHP 8.5)
     350        }
    349351
    350352        if (!$translated_content || $response_code !== 200) {
  • linguise/trunk/vendor/linguise/script-php/src/Processor.php

    r3377801 r3397694  
    22namespace Linguise\Vendor\Linguise\Script\Core;
    33
    4 defined('LINGUISE_SCRIPT_TRANSLATION') or die();
     4defined('LINGUISE_SCRIPT_TRANSLATION') or die(); // @codeCoverageIgnore
    55
    66class Processor {
     
    2727
    2828        // Finalize defer actions on shutdown
     29        // @codeCoverageIgnoreStart
    2930        register_shutdown_function(function() {
    3031            Defer::getInstance()->finalize();
    3132            Database::getInstance()->close();
    3233        });
     34        // @codeCoverageIgnoreEnd
    3335    }
    3436
     
    3941    {
    4042        if (!isset($_GET['linguise_language'])) {
    41             die();
     43            if (defined('LINGUISE_SCRIPT_TESTING') && LINGUISE_SCRIPT_TESTING) {
     44                // during testing, do not write to file
     45                return;
     46            }
     47            die(); // @codeCoverageIgnore
    4248        }
    4349
    4450        // AI Translation Stuff
    45         if ( $_SERVER['REQUEST_METHOD'] === 'POST' && isset($_POST['live_editor_ai_translation']) ) {
     51        if ($_SERVER['REQUEST_METHOD'] === 'POST' && isset($_POST['live_editor_ai_translation']) ) {
    4652            $_SERVER['REQUEST_METHOD'] = 'GET';
    4753            Translation::getInstance()->enableAiTranslation($_POST['live_editor_ai_translation']);
     
    6167        if (Response::getInstance()->getResponseCode() === 304) {
    6268            Debug::log('304 Not modified');
    63             Response::getInstance()->end();
     69            return Response::getInstance()->end();
    6470        }
    6571
     
    8793    }
    8894
     95    /**
     96     * Update the Linguise Script PHP to the latest version
     97     *
     98     * @codeCoverageIgnore
     99     *
     100     * @return void
     101     */
    89102    public function update()
    90103    {
     
    100113                echo '<p>It seems you were trying the Live Editor with the wrong domain configuration. </p>
    101114                      <p>Please double-check on your configuration in your Linguise dashboard or reach out to our support team</p>';
    102                 die();
     115
     116                if (defined('LINGUISE_SCRIPT_TESTING') && LINGUISE_SCRIPT_TESTING) {
     117                    // stop execution for testing purposes
     118                    return;
     119                }
     120                die(); // @codeCoverageIgnore
    103121            }
    104122
     
    120138                echo '<p>It seems you were trying the Live Editor with the wrong domain configuration. </p>
    121139                      <p>Please double-check on your configuration in your Linguise dashboard or reach out to our support team</p>';
    122                 die();
     140
     141                if (defined('LINGUISE_SCRIPT_TESTING') && LINGUISE_SCRIPT_TESTING) {
     142                    // stop execution for testing purposes
     143                    return;
     144                }
     145                die(); // @codeCoverageIgnore
    123146            }
    124147
     
    152175        Certificates::getInstance()->downloadCertificates();
    153176    }
    154 
    155177}
  • linguise/trunk/vendor/linguise/script-php/src/Translation.php

    r3388557 r3397694  
    9797        }
    9898
    99         curl_close($ch);
     99        if (PHP_VERSION_ID < 80000) {
     100            curl_close($ch); // Since, PHP 8+ this thing actually does not do anything (deprecated in PHP 8.5)
     101        }
    100102
    101103        $result = json_decode($translated_content);
     
    223225        Debug::log('Translated content: ' . PHP_EOL . '######################' . PHP_EOL . $translated_content . PHP_EOL . '######################', 5);
    224226
    225         curl_close($ch);
     227        if (PHP_VERSION_ID < 80000) {
     228            curl_close($ch); // Since, PHP 8+ this thing actually does not do anything (deprecated in PHP 8.5)
     229        }
    226230
    227231        if (!$translated_content || $response_code !== 200) {
  • linguise/trunk/vendor/linguise/script-php/src/Updater.php

    r2652292 r3397694  
    5757        }
    5858        $content = curl_exec($ch);
    59         curl_close($ch);
     59        if (PHP_VERSION_ID < 80000) {
     60            curl_close($ch); // Since, PHP 8+ this thing actually does not do anything (deprecated in PHP 8.5)
     61        }
    6062
    6163        if (!$content) {
     
    9395        }
    9496        $file_content = curl_exec($ch);
    95         curl_close($ch);
     97        if (PHP_VERSION_ID < 80000) {
     98            curl_close($ch); // Since, PHP 8+ this thing actually does not do anything (deprecated in PHP 8.5)
     99        }
    96100
    97101        if (!$file_content) {
Note: See TracChangeset for help on using the changeset viewer.