Plugin Directory

Changeset 3155849


Ignore:
Timestamp:
09/22/2024 04:27:31 AM (19 months ago)
Author:
mvpis
Message:

Real HTML5 processing has been added. This release fixes bugs and has many performance improvements

Location:
fluentc-translation
Files:
627 added
11 edited

Legend:

Unmodified
Added
Removed
  • fluentc-translation/trunk/.gitignore

    r3122693 r3155849  
    11
    2 vendor/bin
    32vendor/dealerdirect
    43vendor/phpcsstandards
    54vendor/squizlabs
     5vendor/dealerdirect
     6vendor/phpcsstandards
     7vendor/bin
    68vendor/wp-coding-standards
    79.DS_Store
  • fluentc-translation/trunk/fluentc_wordpress_plugin.php

    r3153653 r3155849  
    77 * Plugin URI: https://github.com/fluentc/wordpress-plugin
    88 * Description: A plugin that enables website owners to easily install the FluentC Translation on their WordPress site.
    9  * Version: 1.8.6
     9 * Version: 1.8.7
    1010 * Author: FluentC
    1111 * Author URI: https://www.fluentc.ai
     
    1717define( 'FLUENTC_DIR', __DIR__ );
    1818define( 'FLUENTC_SLUG', 'fluentc_translation' );
    19 define( 'FLUENTC_TRANSLATION_VERSION', "1.8.6" );
     19define( 'FLUENTC_TRANSLATION_VERSION', "1.8.7" );
    2020define( 'FLUENTC_TRANSLATION_PLUGIN_DIR', plugin_dir_path(__FILE__) );
    2121define( 'FLUENTC_TRANSLATION_PLUGIN_URL', plugin_dir_url(__FILE__) );
  • fluentc-translation/trunk/readme.txt

    r3153653 r3155849  
    55Requires at least: 4.6
    66Tested up to: 6.6.2
    7 Stable tag: 1.8.6
     7Stable tag: 1.8.7
    88Requires PHP: 7.3
    99License: GPLv2 or later
  • fluentc-translation/trunk/src/actions/class-siteorigin.php

    r3153653 r3155849  
    114114       
    115115        if (is_array($instance))  {
    116                
     116            if(array_key_exists("text",$instance)) {
    117117            $key = hash('md5', $instance['text']);
    118118            $cache_key = $site_language . $language_code . $key;
     
    135135                        }
    136136                }
    137 
     137            }
     138            if(array_key_exists("title",$instance)) {
    138139                $key = hash('md5', $instance['title']);
    139140                $cache_key = $site_language . $language_code . $key;
     
    154155                        }
    155156                    }
     157            }
    156158                return $instance;
    157159               
  • fluentc-translation/trunk/src/actions/class-wordpress.php

    r3153653 r3155849  
    3333     * @var object
    3434     */
    35     protected $fluentc_connenct;
     35    protected $fluentc_connect;
    3636
    3737    /**
     
    9898     */
    9999    public function __construct() {
    100         $this->fluentc_connenct = new Connect();
     100        $this->fluentc_connect = new Connect();
    101101        $this->fluentc_language = new Language();
    102102        $this->fluentc_htmltags = new Htmltags();
     
    139139     * @param  string $block Block Object.
    140140     */
    141     public function filter_block($block_content, $block) {
    142     $language_code = $this->language_code;
    143     if (!$language_code || is_null($block_content) || $block_content === '') {
     141    public function filter_block($block_content, $block)
     142{
     143    do_action('qm/info', 'Starting filter_block');
     144    do_action('qm/info', 'Original content: ' . substr($block_content, 0, 100) . '...');
     145
     146    if (!$this->should_process_content($block_content)) {
     147        do_action('qm/info', 'Content not processed: language code missing or content empty');
    144148        return $block_content;
    145149    }
    146150
    147     $html = html_entity_decode($block_content, ENT_QUOTES | ENT_HTML5, 'UTF-8');
    148 
    149     if (empty($html)) {
    150         return $block_content;
    151     }
    152 
    153     $options = new Options();
    154     $options->setCleanupInput(false);
    155     $options->setWhitespaceTextNode(false);
    156     $options->setRemoveStyles(false);
    157     $options->setPreserveLineBreaks(true);
    158     $dom = new Dom;
    159     $dom->loadStr($html, $options);
    160 
    161     $texts_to_translate = [];
    162     $entry_map = [];
    163     $entry_skip_map = [];
    164 
    165     $elements = $dom->find('*:not(script):not(style):not(doctype):not(code):not(figure):not(pre):not(noscript):not(iframe):not(object):not(embed):not(svg):not(math):not(canvas)');
    166     foreach ($elements as $element) {
    167         $nodes = ($element instanceof \PHPHtmlParser\Dom\Node\HtmlNode) ? $element->getChildren() : [$element];
    168         foreach ($nodes as $node) {
    169             $this->processNode($node, $texts_to_translate, $entry_map, $entry_skip_map);
    170         }
    171     }
     151    $dom = $this->load_dom($block_content);
     152    do_action('qm/info', 'DOM loaded. Root children count: ' . count($dom->root->getChildren()));
     153
     154    $texts_to_translate = $entry_map = $entry_skip_map = [];
     155
     156    $this->process_dom_elements($dom, $texts_to_translate, $entry_map, $entry_skip_map);
     157    do_action('qm/info', 'DOM processed. Texts to translate: ' . count($texts_to_translate) . ', Entry map: ' . count($entry_map) . ', Skip map: ' . count($entry_skip_map));
    172158
    173159    if (!empty($texts_to_translate)) {
    174         $uncached_texts = [];
    175         $cached_translations = [];
    176 
    177         foreach ($texts_to_translate as $text) {
    178             $key = hash('md5', $text);
    179             $cache_key = $this->site_language . $language_code . $key;
    180             $cached_translation = $this->fluentc_cache->get($cache_key);
    181 
    182             if ($cached_translation) {
    183                 $json_cache = json_decode($cached_translation);
    184                 if (isset($json_cache->data->translateSite->body)) {
    185                     $cached_translations[] = $json_cache->data->translateSite->body;
     160        $this->process_translations($texts_to_translate, $entry_map, $entry_skip_map);
     161        do_action('qm/info', 'Translations processed');
     162    } else {
     163        do_action('qm/info', 'No texts to translate');
     164    }
     165    do_action('qm/info', 'Pre Processed HTML: ' . substr($dom->root->outerHtml(), 0, 600) . '...');
     166    $html = $this->get_processed_html($dom);
     167    do_action('qm/info', 'Processed HTML: ' . substr($html, 0, 600) . '...');
     168   
     169    do_action('qm/info', 'Finished filter_block');
     170    return $html ?: $block_content;
     171}
     172   
     173 /**
     174     * Apply translations to nodes
     175     */
     176    private function applyTranslations($entry_map, $translated_texts, $language_code)
     177    {
     178        foreach ($translated_texts as $translatedText) {
     179            $original_text = $translatedText->originalText;
     180            $translated_text = $translatedText->translatedText;
     181           
     182            if (isset($entry_map[$original_text]) && $translated_text !== null && $translated_text !== '') {
     183                foreach ($entry_map[$original_text] as $node) {
     184                    $this->applyTranslationToNode($node, $translated_text, $node->getDataAttributes());
    186185                }
     186               
     187                $this->update_translation_cache($original_text, $translated_text, $language_code);
    187188            } else {
    188                 $uncached_texts[] = $text;
    189             }
    190         }
    191 
    192         if (!empty($uncached_texts)) {
    193             $text_labels = $this->process_text_labels($uncached_texts);
    194 
    195             $translated_texts = $this->fluentc_connenct->get_translation_content(
    196                 $this->widgetapikey,
    197                 $this->site_language,
    198                 $language_code,
    199                 $text_labels
    200             );
    201 
    202             if (isset($translated_texts->data->translateSite->body) && !empty($translated_texts->data->translateSite->body)) {
    203                 $cached_translations = array_merge($cached_translations, $translated_texts->data->translateSite->body);
    204             } else {
    205                 do_action('qm/debug', 'Translation error: Data not found in response.');
    206             }
    207         }
    208 
    209         $this->applyTranslations($entry_map, $cached_translations, $language_code);
    210     } else {
    211        // do_action('qm/info', 'No translation needed.');
    212     }
    213 
    214     $this->applySkippedTranslations($entry_skip_map);
    215 
    216     $root = $dom->root;
    217     if ($root && method_exists($root, 'innerHtml')) {
    218         try {
    219             $html = $root->innerHtml();
    220             if ($html !== null && $html !== '') {
    221                 // Additional check to ensure $html is a valid string
    222                 if (is_string($html) && strlen(trim($html)) > 0) {
    223                     $html = $this->fluentc_html->find_and_replace($html, null, $language_code, $this->fluentc_connenct->get_language_list_string($this->widgetapikey));
    224                     return $html;
    225                 }
    226             }
    227         } catch (\Exception $e) {
    228             // Log the error for debugging
    229             error_log('Error in filter_block: ' . $e->getMessage());
    230         }
    231     }
    232    
    233     // If we reach here, it means there was no valid innerHTML
    234     return $block_content;
    235 }
    236    
    237 private function applyTranslations($entry_map, $translated_texts, $language_code) {
    238     foreach ($translated_texts as $translatedText) {
    239         $original_text = $translatedText->originalText;
    240         $translated_text = $translatedText->translatedText;
     189                do_action('qm/info', 'No Translated Text or No Matching Nodes');
     190            }
     191        }
     192    }
     193
     194    /**
     195     * Apply skipped translations
     196     */
     197    private function applySkippedTranslations($entry_skip_map)
     198    {
     199        foreach ($entry_skip_map as $node) {
     200            $original_text = $node->text();
     201            $key = hash('md5', $original_text);
     202           
     203            if (isset($this->translated_text[$key]) && null !== $this->translated_text[$key]) {
     204                $this->applyTranslationToNode($node, $this->translated_text[$key], $node->getDataAttributes());
     205            }
     206        }
     207    }
     208
     209    /**
     210     * Process individual node
     211     */
     212    private function processNode($node, &$texts_to_translate, &$entry_map, &$entry_skip_map)
     213    {
     214        if (!($node instanceof \PHPHtmlParser\Dom\Node\TextNode)) {
     215            return;
     216        }
     217
     218        if ($this->should_skip_node($node)) {
     219            return;
     220        }
     221
     222        $text = $node->text();
     223
     224        if ($this->is_empty_or_numeric($text)) {
     225            return;
     226        }
     227
     228        if (in_array($text, $this->fluentc_htmltags->forbidden_selectors)) {
     229            $node->setText('');
     230            return;
     231        }
     232
     233        $this->process_node_text($node, $text, $texts_to_translate, $entry_map, $entry_skip_map);
     234    }
     235
     236    /**
     237     * Apply translation to node
     238     */
     239    private function applyTranslationToNode($node, $translatedText, $dataAttributes)
     240    {
     241        $node->setText($translatedText);
     242        foreach ($dataAttributes as $dataKey => $dataValue) {
     243            $node->tag->setAttribute($dataKey, $dataValue);
     244        }
     245    }
     246    /**
     247     * Filters Content
     248     *
     249     * @param  string $content Content Object.
     250     */
     251    public function filter_content( $content ) {
     252        do_action('qm/info', 'Starting filter_block');
    241253       
    242         if (isset($entry_map[$original_text]) && $translated_text !== null && $translated_text !== '') {
    243             foreach ($entry_map[$original_text] as $node) {
    244                 $node->setText($translated_text);
    245             }
    246            
    247             $key = hash('md5', $original_text);
    248             $translated_key = hash('md5', $translated_text);
    249            
    250             do_action('qm/info', 'applyTranslations $translated_text ' . $translated_key . ' text' . $translated_text);
    251            
    252             $this->translated_text[$key] = $translated_text;
    253             $this->translated_text[$translated_key] = $translated_text;
    254            
    255             $cache_key = $this->site_language . $language_code . $key;
    256             $this->fluentc_cache->set($cache_key, json_encode([
    257                 'data' => ['translateSite' => ['body' => ['sourceLanguage' => $this->site_language, 'targetLanguage' => $language_code, 'translatedText' => $translated_text, 'originalText' => $original_text ]]]
    258             ]));
    259         } else {
    260             do_action('qm/info', 'No Translated Text or No Matching Nodes');
    261         }
    262     }
    263 }
    264 
    265 private function applySkippedTranslations($entry_skip_map) {
    266     foreach ($entry_skip_map as $node) {
    267         $original_text = $node->text();
    268         $key = hash('md5', $original_text);
    269        
    270         if (isset($this->translated_text[$key]) && null !== $this->translated_text[$key] ) {
    271             $node->setText($this->translated_text[$key]);
    272         }
    273        
    274     }
    275 }
    276    
    277 private function processNode($node, &$texts_to_translate, &$entry_map, &$entry_skip_map) {
    278     if (!($node instanceof \PHPHtmlParser\Dom\Node\TextNode)) {
    279         return;
    280     }
    281    
    282     // Check if this text node is a child of a style or script tag
    283     $parent = $node->getParent();
    284     while ($parent !== null) {
    285         if ($parent instanceof \PHPHtmlParser\Dom\Node\HtmlNode) {
    286             $tag_name = strtolower($parent->tag->name());
    287             if (in_array($tag_name, ['style'])) {
    288                 //echo $node->text();
    289                 return; // Skip processing for text within style and script tags
    290             }
    291         }
    292         $parent = $parent->getParent();
    293     }
    294    
    295     $text = $node->text();
    296 
    297     if (preg_match($this->fluentc_htmltags->regex_only_whitespace, $text) ||
    298         preg_match($this->fluentc_htmltags->regex_only_digits_whitespace_punctuation, $text)) {
    299         return;
    300     }
    301     if ( in_array($text, $this->fluentc_htmltags->forbidden_selectors) ) {
    302         // Skip or delete the DOCTYPE node
    303         $node->setText('');
    304         return;
    305     }
    306     if ($node->name === 'style') {
    307         echo 'Style tag found, not skipped.';
    308     }
    309    
    310     $key = hash('md5', $text);
    311    
    312     // Check if the text has already been translated
    313     if (array_key_exists($key, $this->translated_text)) {
    314         $node->setText($this->translated_text[$key]);
    315         $entry_skip_map[] = $node;
    316         return;
    317     }
    318    
    319     $cache_key = $this->site_language . $this->language_code . $key;
    320     $cached_translation = $this->fluentc_cache->get($cache_key);
    321    
    322     if ($cached_translation) {
    323         $json_cache = json_decode($cached_translation);
    324         if (isset($json_cache->data->translateSite->body->translatedText)) {
    325             $translated_text = $json_cache->data->translateSite->body->translatedText;
    326             $node->setText($translated_text);
    327             $translated_key = hash('md5', $translated_text);
    328             $this->translated_text[$key] = $translated_text;
    329             $this->translated_text[$translated_key] = $translated_text;
    330             $entry_skip_map[] = $node;
    331             return;
    332         }
    333     }
    334 
    335     // If we reach here, the text needs translation
    336     if (!in_array($text, $texts_to_translate)) {
    337         $texts_to_translate[] = $text;
    338     }
    339    
    340     if (!isset($entry_map[$text])) {
    341         $entry_map[$text] = [];
    342     }
    343     $entry_map[$text][] = $node;
    344 }
    345    
    346 
    347     /**
    348      * Filters Content
    349      *
    350      * @param  string $content Content Object.
    351      */
    352     public function filter_content( $content ) {
    353     $language_code = $this->language_code;
    354     if (!$language_code || is_null($content) || $content === '') {
    355         return $content;
    356     }
    357     if ( function_exists( 'wc_get_page_id' ) ) {
    358         if ( is_page( wc_get_page_id( 'checkout' ) ) || is_page( wc_get_page_id( 'cart' ) ) ) {
    359             return $content;
    360         }
    361     }
    362     $html = html_entity_decode($content, ENT_QUOTES | ENT_HTML5, 'UTF-8');
    363 
    364     if (empty($html)) {
    365         return $content;
    366     }
    367 
    368     $options = new Options();
    369     $options->setCleanupInput(false);
    370     $options->setWhitespaceTextNode(false);
    371 
    372     $dom = new Dom;
    373     $dom->loadStr($html, $options);
    374 
    375     $texts_to_translate = [];
    376     $entry_map = [];
    377     $entry_skip_map = [];
    378 
    379     $elements = $dom->find(selector: '*:not(script):not(style):not(code):not(doctype):not(figure):not(pre):not(noscript):not(iframe):not(object):not(embed):not(svg):not(math):not(canvas)');
    380     foreach ($elements as $element) {
    381         $nodes = ($element instanceof \PHPHtmlParser\Dom\Node\HtmlNode) ? $element->getChildren() : [$element];
    382         foreach ($nodes as $node) {
    383             $this->processNode($node, $texts_to_translate, $entry_map, $entry_skip_map);
    384         }
    385     }
    386 
    387     if (!empty($texts_to_translate)) {
    388         $uncached_texts = [];
    389         $cached_translations = [];
    390 
    391         foreach ($texts_to_translate as $text) {
    392             $key = hash('md5', $text);
    393             $cache_key = $this->site_language . $language_code . $key;
    394             $cached_translation = $this->fluentc_cache->get($cache_key);
    395 
    396             if ($cached_translation) {
    397                 $json_cache = json_decode($cached_translation);
    398                 if (isset($json_cache->data->translateSite->body)) {
    399                     $cached_translations[] = $json_cache->data->translateSite->body;
    400                 }
    401             } else {
    402                 $uncached_texts[] = $text;
    403             }
    404         }
    405 
    406         if (!empty($uncached_texts)) {
    407             $text_labels = $this->process_text_labels($uncached_texts);
    408 
    409             $translated_texts = $this->fluentc_connenct->get_translation_content(
    410                 $this->widgetapikey,
    411                 $this->site_language,
    412                 $language_code,
    413                 $text_labels
    414             );
    415 
    416             if (isset($translated_texts->data->translateSite->body) && !empty($translated_texts->data->translateSite->body)) {
    417                 $cached_translations = array_merge($cached_translations, $translated_texts->data->translateSite->body);
    418             } else {
    419                 do_action('qm/debug', 'Translation error: Data not found in response.');
    420             }
    421         }
    422 
    423         $this->applyTranslations($entry_map, $cached_translations, $language_code);
    424     } else {
    425        // do_action('qm/info', 'No translation needed.');
    426     }
    427 
    428     $this->applySkippedTranslations($entry_skip_map);
    429 
    430     $root = $dom->root;
    431     if ($root && method_exists($root, 'innerHtml')) {
    432         try {
    433             $html = $root->innerHtml();
    434             if ($html !== null && $html !== '') {
    435                 // Additional check to ensure $html is a valid string
    436                 if (is_string($html) && strlen(trim($html)) > 0) {
    437                     $html = $this->fluentc_html->find_and_replace($html, null, $language_code, $this->fluentc_connenct->get_language_list_string($this->widgetapikey));
    438                     return $html;
    439                 }
    440             }
    441         } catch (\Exception $e) {
    442             // Log the error for debugging
    443             error_log('Error in filter_block: ' . $e->getMessage());
    444         }
    445     }
    446 
    447 // If we reach here, it means there was no valid innerHTML
    448 return $content;
    449 }
     254        if (!$this->should_process_content($content)) {
     255            return $content;
     256        }
     257
     258        $dom = $this->load_dom($content);
     259        $texts_to_translate = $entry_map = $entry_skip_map = [];
     260
     261        $this->process_dom_elements($dom, $texts_to_translate, $entry_map, $entry_skip_map);
     262
     263        if (!empty($texts_to_translate)) {
     264            $this->process_translations($texts_to_translate, $entry_map, $entry_skip_map);
     265        }
     266
     267        $html = $this->get_processed_html($dom);
     268       
     269        do_action('qm/info', 'Finished filter_block');
     270        return $html ?: $content;
     271    }
    450272
    451273    /**
     
    455277     * @param  string $id id of the post.
    456278     */
    457     public function fluentcFilterTitle($title, $id = null) {
    458         $language_code = $this->fluentc_language->get_fluentc_language();
    459         $widgetapikey = get_option('fluentc_api_key');
    460        
    461    
    462         if (!$language_code) {
    463             // If no language code, return the default output.
    464             return $title;
    465         }
    466    
    467         // Generate a unique key for this title
    468         $key = hash('md5', $title . ($id ? "_$id" : ''));
    469    
    470         // Check if we've already translated this title
    471         if (isset($this->translated_text[$key])) {
    472            
    473         }
    474 
    475 
    476     // Check if the text has already been translated
    477     if (array_key_exists($key, $this->translated_text)) {
    478         return $this->translated_text[$key];
    479     }
    480    
    481     $cache_key = $this->site_language . $this->language_code . $key;
    482     $cached_translation = $this->fluentc_cache->get($cache_key);
    483    
    484     if ($cached_translation) {
    485         $json_cache = json_decode($cached_translation);
    486         if (isset($json_cache->data->translateSite->body->translatedText)) {
    487             $translated_text = $json_cache->data->translateSite->body->translatedText;
    488             $translated_key = hash('md5', $translated_text);
    489             $this->translated_text[$key] = $translated_text;
    490             $this->translated_text[$translated_key] = $translated_text;
    491            
     279     /**
     280     * Filter title
     281     */
     282    public function fluentcFilterTitle($title, $id = null)
     283    {
     284        do_action('qm/info', 'Starting fluentcFilterTitle');
     285       
     286        if (!$this->language_code) {
     287            return $title;
     288        }
     289
     290        $key = hash('md5', $title . ($id ? "_$id" : ''));
     291
     292        if (isset($this->translated_text[$key])) {
     293            return $this->translated_text[$key];
     294        }
     295
     296        $translated_text = $this->get_cached_translation($key);
     297        if ($translated_text) {
    492298            return $translated_text;
    493299        }
    494     }
    495        
    496 
    497         // If language code is set and title hasn't been translated yet, get the translation
    498         $translated_data = $this->fluentc_connenct->get_translation_text(
    499             $widgetapikey,
    500             $this->site_language,
    501             $language_code,
    502             $title,
    503             $id
    504         );
    505        
    506         if (isset($translated_data->data->translateSite->body)) {
    507            
    508             $translated_text = $translated_data->data->translateSite->body[0]->translatedText;
    509             $this->translated_text[$key] = $translated_text ;
    510             $cache_key = $this->site_language . $language_code . $key;
    511             $this->fluentc_cache->set($cache_key, json_encode([
    512                 'data' => ['translateSite' => ['body' => ['sourceLanguage' => $this->site_language, 'targetLanguage' => $language_code, 'translatedText' => $translated_text, 'originalText' => $title ]]]
    513             ]));
     300
     301        $translated_data = $this->fluentc_connect->get_translation_text(
     302            $this->widgetapikey,
     303            $this->site_language,
     304            $this->language_code,
     305            $title,
     306            $id
     307        );
     308
     309        if (isset($translated_data->data->translateSite->body)) {
     310            $translated_text = $translated_data->data->translateSite->body[0]->translatedText;
     311            $this->update_translation_cache($title, $translated_text, $this->language_code);
    514312            return $translated_text;
    515 
    516         } else {
    517             // If translation failed, store the original title to prevent repeated translation attempts
    518             $this->translated_text[$key] = $title;
    519            
    520             do_action('qm/error', 'Translation failed for title: ' . $title);
    521             return $title;
    522         }
    523     }
     313        } else {
     314            $this->translated_text[$key] = $title;
     315            do_action('qm/error', 'Translation failed for title: ' . $title);
     316            return $title;
     317        }
     318    }
    524319
    525320   
     
    532327     */
    533328    public function fluentcFilterWidgetText( $text, $instance ) {
    534         // if Language is set, translate description if not return description.
    535         $language_code = $this->fluentc_language->get_fluentc_language();
    536         $widgetapikey  = get_option( 'fluentc_api_key' );
    537        
    538         if ( !$widgetapikey ) {
    539             return $text;
    540         }
    541        
    542         if (!$language_code || is_null($text) || $text === '') {
    543             return $text;
    544         }
    545 
    546         if ( function_exists( 'wc_get_page_id' ) ) {
    547             if ( is_page( wc_get_page_id( 'checkout' ) ) || is_page( wc_get_page_id( 'cart' ) ) ) {
     329        {
     330            do_action('qm/info', 'Starting filter_block');
     331           
     332            if (!$this->should_process_content($text)) {
    548333                return $text;
    549334            }
     335   
     336            $dom = $this->load_dom($text);
     337            $texts_to_translate = $entry_map = $entry_skip_map = [];
     338   
     339            $this->process_dom_elements($dom, $texts_to_translate, $entry_map, $entry_skip_map);
     340   
     341            if (!empty($texts_to_translate)) {
     342                $this->process_translations($texts_to_translate, $entry_map, $entry_skip_map);
     343            }
     344   
     345            $html = $this->get_processed_html($dom);
     346           
     347            do_action('qm/info', 'Finished filter_block');
     348            return $html ?: $text;
    550349        }
    551 
    552         $html = html_entity_decode($text, ENT_QUOTES | ENT_HTML5, 'UTF-8');
    553    
    554         if (empty($html)) {
    555             return $text;
    556         }
    557    
    558         $options = new Options();
    559         $options->setCleanupInput(false);
    560         $options->setWhitespaceTextNode(false);
    561    
    562         $dom = new Dom;
    563         $dom->loadStr($html, $options);
    564    
    565         $texts_to_translate = [];
    566         $entry_map = [];
    567         $entry_skip_map = [];
    568    
    569         $elements = $dom->find('*:not(script):not(style):not(code):not(doctype):not(figure):not(pre):not(noscript):not(iframe):not(object):not(embed):not(svg):not(math):not(canvas)');
    570         foreach ($elements as $element) {
    571             $nodes = ($element instanceof \PHPHtmlParser\Dom\Node\HtmlNode) ? $element->getChildren() : [$element];
    572             foreach ($nodes as $node) {
    573                 $this->processNode($node, $texts_to_translate, $entry_map, $entry_skip_map);
    574             }
    575         }
    576    
    577         if (!empty($texts_to_translate)) {
    578             $uncached_texts = [];
    579             $cached_translations = [];
    580    
    581             foreach ($texts_to_translate as $node_text) {
    582                 $key = hash('md5', $node_text);
    583                 $cache_key = $this->site_language . $language_code . $key;
    584                 $cached_translation = $this->fluentc_cache->get($cache_key);
    585    
    586                 if ($cached_translation) {
    587                     $json_cache = json_decode($cached_translation);
    588                     if (isset($json_cache->data->translateSite->body)) {
    589                         $cached_translations[] = $json_cache->data->translateSite->body;
    590                     }
    591                 } else {
    592                     $uncached_texts[] = $node_text;
    593                 }
    594             }
    595    
    596             if (!empty($uncached_texts)) {
    597                 $text_labels = $this->process_text_labels($uncached_texts);
    598    
    599                 $translated_texts = $this->fluentc_connenct->get_translation_content(
    600                     $this->widgetapikey,
    601                     $this->site_language,
    602                     $language_code,
    603                     $text_labels
    604                 );
    605    
    606                 if (isset($translated_texts->data->translateSite->body) && !empty($translated_texts->data->translateSite->body)) {
    607                     $cached_translations = array_merge($cached_translations, $translated_texts->data->translateSite->body);
    608                 } else {
    609                     do_action('qm/debug', 'Translation error: Data not found in response.');
    610                 }
    611             }
    612    
    613             $this->applyTranslations($entry_map, $cached_translations, $language_code);
    614         } else {
    615            // do_action('qm/info', 'No translation needed.');
    616         }
    617    
    618         $this->applySkippedTranslations($entry_skip_map);
    619    
    620         $root = $dom->root;
    621         if ($root && method_exists($root, 'innerHtml')) {
    622             try {
    623                 $html = $root->innerHtml();
    624                 if ($html !== null && $html !== '') {
    625                     // Additional check to ensure $html is a valid string
    626                     if (is_string($html) && strlen(trim($html)) > 0) {
    627                         $html = $this->fluentc_html->find_and_replace($html, null, $language_code, $this->fluentc_connenct->get_language_list_string($this->widgetapikey));
    628                         return $html;
    629                     }
    630                 }
    631             } catch (\Exception $e) {
    632                 // Log the error for debugging
    633                 error_log('Error in filter_block: ' . $e->getMessage());
    634             }
    635         }return $text;
    636350    }
    637351
     
    643357     * @param  mixed $attr HTML Content.
    644358     */
    645     public function fluentc_woocommerce_checkout_shortcode_filter( $output, $tag, $attr ) {
    646         // if Language is set, translate description if not return description.
    647         $language_code = $this->language_code;
    648     if (!$language_code || is_null($output) || $output === '') {
    649         return $output;
    650     }
    651     if ( function_exists( 'wc_get_page_id' ) ) {
    652         if ( is_page( wc_get_page_id( 'checkout' ) ) || is_page( wc_get_page_id( 'cart' ) ) ) {
    653             return $output;
     359    public function fluentc_woocommerce_checkout_shortcode_filter( $output, $tag, $attr ){
     360        {
     361            do_action('qm/info', 'Starting filter_block');
     362           
     363            if (!$this->should_process_content($output)) {
     364                return $output;
     365            }
     366   
     367            $dom = $this->load_dom($output);
     368            $texts_to_translate = $entry_map = $entry_skip_map = [];
     369   
     370            $this->process_dom_elements($dom, $texts_to_translate, $entry_map, $entry_skip_map);
     371   
     372            if (!empty($texts_to_translate)) {
     373                $this->process_translations($texts_to_translate, $entry_map, $entry_skip_map);
     374            }
     375   
     376            $html = $this->get_processed_html($dom);
     377           
     378            do_action('qm/info', 'Finished filter_block');
     379            return $html ?: $output;
    654380        }
    655     }
    656     $html = html_entity_decode($output, ENT_QUOTES | ENT_HTML5, 'UTF-8');
    657 
    658     if (empty($html)) {
    659         return $output;
    660     }
    661 
    662     $options = new Options();
    663     $options->setCleanupInput(false);
    664     $options->setWhitespaceTextNode(false);
    665 
    666     $dom = new Dom;
    667     $dom->loadStr($html, $options);
    668 
    669     $texts_to_translate = [];
    670     $entry_map = [];
    671     $entry_skip_map = [];
    672 
    673     $elements = $dom->find(selector: '*:not(script):not(style):not(code):not(doctype):not(figure):not(pre):not(noscript):not(iframe):not(object):not(embed):not(svg):not(math):not(canvas)');
    674     foreach ($elements as $element) {
    675         $nodes = ($element instanceof \PHPHtmlParser\Dom\Node\HtmlNode) ? $element->getChildren() : [$element];
    676         foreach ($nodes as $node) {
    677             $this->processNode($node, $texts_to_translate, $entry_map, $entry_skip_map);
    678         }
    679     }
    680 
    681     if (!empty($texts_to_translate)) {
    682         $uncached_texts = [];
    683         $cached_translations = [];
    684 
    685         foreach ($texts_to_translate as $text) {
    686             $key = hash('md5', $text);
    687             $cache_key = $this->site_language . $language_code . $key;
    688             $cached_translation = $this->fluentc_cache->get($cache_key);
    689 
    690             if ($cached_translation) {
    691                 $json_cache = json_decode($cached_translation);
    692                 if (isset($json_cache->data->translateSite->body)) {
    693                     $cached_translations[] = $json_cache->data->translateSite->body;
    694                 }
    695             } else {
    696                 $uncached_texts[] = $text;
    697             }
    698         }
    699 
    700         if (!empty($uncached_texts)) {
    701             $text_labels = $this->process_text_labels($uncached_texts);
    702 
    703             $translated_texts = $this->fluentc_connenct->get_translation_content(
    704                 $this->widgetapikey,
    705                 $this->site_language,
    706                 $language_code,
    707                 $text_labels
    708             );
    709 
    710             if (isset($translated_texts->data->translateSite->body) && !empty($translated_texts->data->translateSite->body)) {
    711                 $cached_translations = array_merge($cached_translations, $translated_texts->data->translateSite->body);
    712             } else {
    713                 do_action('qm/debug', 'Translation error: Data not found in response.');
    714             }
    715         }
    716 
    717         $this->applyTranslations($entry_map, $cached_translations, $language_code);
    718     } else {
    719        // do_action('qm/info', 'No translation needed.');
    720     }
    721 
    722     $this->applySkippedTranslations($entry_skip_map);
    723 
    724     $root = $dom->root;
    725     if ($root && method_exists($root, 'innerHtml')) {
    726         try {
    727             $html = $root->innerHtml();
    728             if ($html !== null && $html !== '') {
    729                 // Additional check to ensure $html is a valid string
    730                 if (is_string($html) && strlen(trim($html)) > 0) {
    731                     $html = $this->fluentc_html->find_and_replace($html, null, $language_code, $this->fluentc_connenct->get_language_list_string($this->widgetapikey));
    732                     return $html;
    733                 }
    734             }
    735         } catch (\Exception $e) {
    736             // Log the error for debugging
    737             error_log('Error in filter_block: ' . $e->getMessage());
    738         }
    739     }
    740 
    741 // If we reach here, it means there was no valid innerHTML
    742 return $output;
    743381    }
    744382
     
    759397 * @return string Formatted string of unique text labels.
    760398 */
    761 public function process_text_labels($texts) {
    762     $unique_texts = array_unique(array_filter( $texts ));
    763     return implode(', ', array_map(function($text) {
    764         return '"' . str_replace('"', '"', $text) . '"';
    765     }, $unique_texts));
     399    public function process_text_labels($texts)
     400    {
     401        $unique_texts = array_unique(array_filter($texts));
     402        return implode(', ', array_map(function($text) {
     403            return '"' . str_replace('"', '"', $text) . '"';
     404        }, $unique_texts));
     405    }
     406
     407   
     408
     409    /**
     410     * Helper function to check if content should be processed
     411     */
     412    private function should_process_content($content)
     413    {
     414        return $this->language_code && !is_null($content) && $content !== '';
     415    }
     416
     417    /**
     418     * Helper function to load DOM
     419     */
     420    private function load_dom($content)
     421    {
     422        $html = html_entity_decode($content, ENT_QUOTES | ENT_HTML5, 'UTF-8');
     423        $options = new Options();
     424        $options->setCleanupInput(false);
     425        $options->setWhitespaceTextNode(false);
     426        $options->setRemoveStyles(false);
     427        $options->setPreserveLineBreaks(true);
     428        $dom = new Dom;
     429        $dom->loadStr($html, $options);
     430        return $dom;
     431    }
     432
     433    /**
     434     * Helper function to process DOM elements
     435     */
     436    private function process_dom_elements($dom, &$texts_to_translate, &$entry_map, &$entry_skip_map)
     437    {
     438        $elements = $dom->find('*:not(script):not(style):not(doctype):not(code):not(figure):not(pre):not(noscript):not(iframe):not(object):not(embed):not(svg):not(math):not(canvas)');
     439        foreach ($elements as $element) {
     440            $nodes = ($element instanceof \PHPHtmlParser\Dom\Node\HtmlNode) ? $element->getChildren() : [$element];
     441            foreach ($nodes as $node) {
     442                $this->processNode($node, $texts_to_translate, $entry_map, $entry_skip_map);
     443            }
     444        }
     445    }
     446
     447    /**
     448     * Helper function to process translations
     449     */
     450    private function process_translations(&$texts_to_translate, &$entry_map, &$entry_skip_map)
     451    {
     452        $uncached_texts = [];
     453        $cached_translations = [];
     454
     455        foreach ($texts_to_translate as $text) {
     456            $cached_translation = $this->get_cached_translation(hash('md5', $text));
     457            if ($cached_translation) {
     458                $cached_translations[] = $cached_translation;
     459            } else {
     460                $uncached_texts[] = $text;
     461            }
     462        }
     463
     464        if (!empty($uncached_texts)) {
     465            $text_labels = $this->process_text_labels($uncached_texts);
     466            $translated_texts = $this->fluentc_connect->get_translation_content(
     467                $this->widgetapikey,
     468                $this->site_language,
     469                $this->language_code,
     470                $text_labels
     471            );
     472
     473            if (isset($translated_texts->data->translateSite->body) && !empty($translated_texts->data->translateSite->body)) {
     474                $cached_translations = array_merge($cached_translations, $translated_texts->data->translateSite->body);
     475            } else {
     476                do_action('qm/debug', 'Translation error: Data not found in response.');
     477            }
     478        }
     479
     480        $this->applyTranslations($entry_map, $cached_translations, $this->language_code);
     481    }
     482
     483    /**
     484     * Helper function to get processed HTML
     485     */
     486    private function get_processed_html($dom)
     487{
     488    if ($dom->root && method_exists($dom->root, 'outerHtml')) {
     489        try {
     490            $html = $dom->root->outerHtml();
     491           
     492            // Remove the fluentc-root tag if it exists
     493            $html = preg_replace('/<root>|<\/root>/', '', $html);
     494           
     495            do_action('qm/info', 'Raw processed HTML: ' . substr($html, 0, 100) . '...');
     496           
     497            if ($html !== null && $html !== '' && is_string($html) && strlen(trim($html)) > 0) {
     498                // Temporarily replace comments to prevent processing
     499                $html = preg_replace_callback('/<!--(.*?)-->/s', function($matches) {
     500                    return '###COMMENT' . base64_encode($matches[0]) . '###';
     501                }, $html);
     502
     503                $processed_html = $this->fluentc_html->find_and_replace($html, null, $this->language_code, $this->fluentc_connect->get_language_list_string($this->widgetapikey));
     504
     505                // Restore comments
     506                $processed_html = preg_replace_callback('/###COMMENT(.*?)###/', function($matches) {
     507                    return base64_decode($matches[1]);
     508                }, $processed_html);
     509
     510                do_action('qm/info', 'Final processed HTML: ' . substr($processed_html, 0, 100) . '...');
     511                return $processed_html;
     512            } else {
     513                do_action('qm/info', 'Invalid HTML after processing');
     514            }
     515        } catch (\Exception $e) {
     516            do_action('qm/error', 'Error in get_processed_html: ' . $e->getMessage());
     517        }
     518    } else {
     519        do_action('qm/info', 'Root or outerHtml method not found');
     520    }
     521    return null;
    766522}
     523
     524    /**
     525     * Helper function to check if node should be skipped
     526     */
     527    private function should_skip_node($node)
     528    {
     529        $parent = $node->getParent();
     530        while ($parent !== null) {
     531            if ($parent instanceof \PHPHtmlParser\Dom\Node\HtmlNode) {
     532                $tag_name = strtolower($parent->tag->name());
     533                if (in_array($tag_name, ['style', 'svg'])) {
     534                    return true;
     535                }
     536            }
     537            $parent = $parent->getParent();
     538        }
     539        return false;
     540    }
     541
     542    /**
     543     * Helper function to check if text is empty or numeric
     544     */
     545    private function is_empty_or_numeric($text)
     546    {
     547        return preg_match($this->fluentc_htmltags->regex_only_whitespace, $text) ||
     548               preg_match($this->fluentc_htmltags->regex_only_digits_whitespace_punctuation, $text);
     549    }
     550
     551    /**
     552     * Helper function to process node text
     553     */
     554    private function process_node_text($node, $text, &$texts_to_translate, &$entry_map, &$entry_skip_map)
     555    {
     556        $key = hash('md5', $text);
     557        $dataAttributes = $node->getDataAttributes();
     558
     559        if (array_key_exists($key, $this->translated_text)) {
     560            $this->applyTranslationToNode($node, $this->translated_text[$key], $dataAttributes);
     561            $entry_skip_map[] = $node;
     562            return;
     563        }
     564
     565        $cached_translation = $this->get_cached_translation($key);
     566        if ($cached_translation) {
     567            $this->apply_cached_translation($node, $cached_translation, $dataAttributes, $key, $entry_skip_map);
     568            return;
     569        }
     570
     571        if (!in_array($text, $texts_to_translate)) {
     572            $texts_to_translate[] = $text;
     573        }
     574
     575        if (!isset($entry_map[$text])) {
     576            $entry_map[$text] = [];
     577        }
     578        $entry_map[$text][] = $node;
     579    }
     580
     581    /**
     582     * Helper function to get cached translation
     583     */
     584    private function get_cached_translation($key)
     585    {
     586        $cache_key = $this->site_language . $this->language_code . $key;
     587        $cached_translation = $this->fluentc_cache->get($cache_key);
     588        if ($cached_translation) {
     589            $json_cache = json_decode($cached_translation);
     590            if (isset($json_cache->data->translateSite->body->translatedText)) {
     591                return $json_cache->data->translateSite->body->translatedText;
     592            }
     593        }
     594        return null;
     595    }
     596
     597    /**
     598     * Helper function to apply cached translation
     599     */
     600    private function apply_cached_translation($node, $translated_text, $dataAttributes, $key, &$entry_skip_map)
     601    {
     602        $node->setText($translated_text);
     603        foreach ($dataAttributes as $dataKey => $dataValue) {
     604            $node->tag->setAttribute($dataKey, $dataValue);
     605        }
     606        $translated_key = hash('md5', $translated_text);
     607        $this->translated_text[$key] = $translated_text;
     608        $this->translated_text[$translated_key] = $translated_text;
     609        $entry_skip_map[] = $node;
     610    }
     611
     612    /**
     613     * Helper function to update translation cache
     614     */
     615    private function update_translation_cache($original_text, $translated_text, $language_code)
     616    {
     617        $key = hash('md5', $original_text);
     618        $translated_key = hash('md5', $translated_text);
     619        $this->translated_text[$key] = $translated_text;
     620        $this->translated_text[$translated_key] = $translated_text;
     621        $cache_key = $this->site_language . $language_code . $key;
     622        $this->fluentc_cache->set($cache_key, json_encode([
     623            'data' => ['translateSite' => ['body' => [
     624                'sourceLanguage' => $this->site_language,
     625                'targetLanguage' => $language_code,
     626                'translatedText' => $translated_text,
     627                'originalText' => $original_text
     628            ]]]
     629        ]));
     630    }
    767631
    768632
     
    787651
    788652    // Get the list of available languages
    789     $available_languages = $this->fluentc_connenct->get_display_language_list($widgetapikey);
     653    $available_languages = $this->fluentc_connect->get_display_language_list($widgetapikey);
    790654
    791655    // Check if the user's language matches any available language
  • fluentc-translation/trunk/src/actions/class-yoast.php

    r3153653 r3155849  
    104104        if (isset($translated_data->data->translateSite->body)) {
    105105           
    106             $translated_text = $translated_data->data->translateSite->body[0]->translatedText;
     106            $translated_text = $translated_data->data->translateSite->body->translatedText;
    107107           
    108108            $cache_key = $site_language . $language_code . $key;
  • fluentc-translation/trunk/src/services/class-html.php

    r3153653 r3155849  
    1818use PHPHtmlParser\Dom;
    1919use PHPHtmlParser\Options;
     20use PHPHtmlParser\Dom\Node\HtmlNode;
     21use PHPHtmlParser\Dom\Node\TextNode;
    2022
    2123if ( ! defined( 'ABSPATH' ) ) {
     
    244246 */
    245247public function find_and_replace($html, $json, $language_code, $regex_lang) {
    246     // Create Options object and set the necessary options.
    247     $options = new Options();
     248   
     249    //do_action('qm/debug', 'Raw processed HTML: ' . substr($html, 0, 200) . '...');
     250    $dom = new Dom();
     251    $options = new Options();
    248252    $options->setCleanupInput(false);
    249253    $options->setWhitespaceTextNode(false);
    250 
    251     $dom = new Dom();
     254    $options->setRemoveStyles(false);
     255    $options->setPreserveLineBreaks(true);
    252256    $dom->loadStr($html, $options);
    253257
     258    // Process links
    254259    $links = $dom->find('a');
    255 
    256260    foreach ($links as $link) {
    257         $url = $link->getAttribute('href');
    258 
    259         // Check if the URL is already correct or should not be modified.
    260         $current_language_code = $this->get_fluentc_language_from_url($url, $regex_lang);
    261         $parsed_url = wp_parse_url($url);
    262         $is_relative_path = empty($parsed_url['host']);
    263         $root_url = home_url();
    264        
    265         // Conditions to skip modification.
    266         if (!empty($current_language_code) ||
    267             $is_relative_path ||
    268             (isset($parsed_url['host']) && wp_parse_url($root_url, PHP_URL_HOST) !== $parsed_url['host']) ||
    269             substr($url, -3, 1) === '/' && in_array(substr($url, -2), array($regex_lang, strtoupper($regex_lang))) ||
    270             strpos($url, '/wp-admin/') !== false) { // New condition to skip wp-admin links
    271             // Do nothing
    272             continue;
    273         }
    274 
    275         // If the URL is missing a language code, add the language code.
    276         if (empty($current_language_code)) {
    277             $new_url = $this->htmltag->add_language_code_to_link($language_code, $url);
    278             $link->setAttribute('href', $new_url); // Update the href attribute with the new URL.
    279         }
     261        $this->process_link($link, $language_code, $regex_lang);
    280262    }
    281263
    282     $html = $dom->outerHtml;
    283     return $html;
    284 }
     264    return $dom->root->innerHtml();
     265}
     266
     267private function process_link($link, $language_code, $regex_lang) {
     268    $url = $link->getAttribute('href');
     269    // Check if the URL is already correct or should not be modified.
     270    $current_language_code = $this->get_fluentc_language_from_url($url, $regex_lang);
     271    $parsed_url = wp_parse_url($url);
     272    $is_relative_path = empty($parsed_url['host']);
     273    $root_url = home_url();
     274   
     275    // Conditions to skip modification.
     276    if (!empty($current_language_code) ||
     277        $is_relative_path ||
     278        (isset($parsed_url['host']) && wp_parse_url($root_url, PHP_URL_HOST) !== $parsed_url['host']) ||
     279        substr($url, -3, 1) === '/' && in_array(substr($url, -2), array($regex_lang, strtoupper($regex_lang))) ||
     280        strpos($url, '/wp-admin/') !== false) { // New condition to skip wp-admin links
     281        // Do nothing
     282        return;
     283    }
     284
     285    // If the URL is missing a language code, add the language code.
     286    if (empty($current_language_code)) {
     287        $new_url = $this->htmltag->add_language_code_to_link($language_code, $url);
     288        $link->setAttribute('href', $new_url); // Update the href attribute with the new URL.
     289    }
     290}
     291
    285292
    286293    /**
  • fluentc-translation/trunk/vendor/composer/autoload_psr4.php

    r3129167 r3155849  
    99    'Psr\\Http\\Message\\' => array($vendorDir . '/psr/http-message/src'),
    1010    'Psr\\Http\\Client\\' => array($vendorDir . '/psr/http-client/src'),
    11     'PHPHtmlParser\\' => array($vendorDir . '/paquettg/php-html-parser/src/PHPHtmlParser'),
     11    'PHPHtmlParser\\' => array($vendorDir . '/fluentc/php-html-parser/src/PHPHtmlParser'),
    1212    'PHPCSStandards\\Composer\\Plugin\\Installers\\PHPCodeSniffer\\' => array($vendorDir . '/dealerdirect/phpcodesniffer-composer-installer/src'),
    1313    'MyCLabs\\Enum\\' => array($vendorDir . '/myclabs/php-enum/src'),
  • fluentc-translation/trunk/vendor/composer/autoload_static.php

    r3130179 r3155849  
    5959        'PHPHtmlParser\\' =>
    6060        array (
    61             0 => __DIR__ . '/..' . '/paquettg/php-html-parser/src/PHPHtmlParser',
     61            0 => __DIR__ . '/..' . '/fluentc/php-html-parser/src/PHPHtmlParser',
    6262        ),
    6363        'PHPCSStandards\\Composer\\Plugin\\Installers\\PHPCodeSniffer\\' =>
  • fluentc-translation/trunk/vendor/composer/installed.json

    r3130179 r3155849  
    3434                "class": "PHPCSStandards\\Composer\\Plugin\\Installers\\PHPCodeSniffer\\Plugin"
    3535            },
    36             "installation-source": "dist",
     36            "installation-source": "source",
    3737            "autoload": {
    3838                "psr-4": {
     
    8383        },
    8484        {
     85            "name": "fluentc/php-html-parser",
     86            "version": "3.1.4",
     87            "version_normalized": "3.1.4.0",
     88            "source": {
     89                "type": "git",
     90                "url": "https://github.com/FluentC/php-html-parser.git",
     91                "reference": "9e14514b532211afce53405ae6eb15236d2b4952"
     92            },
     93            "dist": {
     94                "type": "zip",
     95                "url": "https://api.github.com/repos/FluentC/php-html-parser/zipball/9e14514b532211afce53405ae6eb15236d2b4952",
     96                "reference": "9e14514b532211afce53405ae6eb15236d2b4952",
     97                "shasum": ""
     98            },
     99            "require": {
     100                "ext-curl": "*",
     101                "ext-mbstring": "*",
     102                "ext-zlib": "*",
     103                "guzzlehttp/guzzle": "^7.0",
     104                "guzzlehttp/psr7": "^1.6",
     105                "myclabs/php-enum": "^1.7",
     106                "paquettg/string-encode": "~1.0.0",
     107                "php": ">=7.2",
     108                "php-http/httplug": "^2.1"
     109            },
     110            "require-dev": {
     111                "friendsofphp/php-cs-fixer": "^2.16",
     112                "infection/infection": "^0.13.4",
     113                "mockery/mockery": "^1.2",
     114                "phan/phan": "^2.4",
     115                "phpunit/phpunit": "^7.5.1"
     116            },
     117            "time": "2024-09-21T22:25:23+00:00",
     118            "type": "library",
     119            "installation-source": "source",
     120            "autoload": {
     121                "psr-4": {
     122                    "PHPHtmlParser\\": "src/PHPHtmlParser"
     123                }
     124            },
     125            "notification-url": "https://packagist.org/downloads/",
     126            "license": [
     127                "MIT"
     128            ],
     129            "authors": [
     130                {
     131                    "name": "FluentC",
     132                    "email": "mvp@fluentc.ai",
     133                    "homepage": "https://www.fluentc.ai"
     134                }
     135            ],
     136            "description": "An HTML DOM parser. It allows you to manipulate HTML. Find tags on an HTML page with selectors just like jQuery.",
     137            "homepage": "https://github.com/fluentc/php-html-parser",
     138            "keywords": [
     139                "dom",
     140                "html",
     141                "parser"
     142            ],
     143            "support": {
     144                "source": "https://github.com/FluentC/php-html-parser/tree/3.1.4"
     145            },
     146            "funding": [
     147                {
     148                    "url": "https://tidelift.com/funding/github/packagist/paquettg/php-html-parser",
     149                    "type": "tidelift"
     150                }
     151            ],
     152            "install-path": "../fluentc/php-html-parser"
     153        },
     154        {
    85155            "name": "guzzlehttp/guzzle",
    86156            "version": "7.8.2",
     
    468538        },
    469539        {
    470             "name": "paquettg/php-html-parser",
    471             "version": "3.1.1",
    472             "version_normalized": "3.1.1.0",
    473             "source": {
    474                 "type": "git",
    475                 "url": "https://github.com/paquettg/php-html-parser.git",
    476                 "reference": "4e01a438ad5961cc2d7427eb9798d213c8a12629"
    477             },
    478             "dist": {
    479                 "type": "zip",
    480                 "url": "https://api.github.com/repos/paquettg/php-html-parser/zipball/4e01a438ad5961cc2d7427eb9798d213c8a12629",
    481                 "reference": "4e01a438ad5961cc2d7427eb9798d213c8a12629",
    482                 "shasum": ""
    483             },
    484             "require": {
    485                 "ext-curl": "*",
    486                 "ext-mbstring": "*",
    487                 "ext-zlib": "*",
    488                 "guzzlehttp/guzzle": "^7.0",
    489                 "guzzlehttp/psr7": "^1.6",
    490                 "myclabs/php-enum": "^1.7",
    491                 "paquettg/string-encode": "~1.0.0",
    492                 "php": ">=7.2",
    493                 "php-http/httplug": "^2.1"
    494             },
    495             "require-dev": {
    496                 "friendsofphp/php-cs-fixer": "^2.16",
    497                 "infection/infection": "^0.13.4",
    498                 "mockery/mockery": "^1.2",
    499                 "phan/phan": "^2.4",
    500                 "phpunit/phpunit": "^7.5.1"
    501             },
    502             "time": "2020-11-01T20:34:43+00:00",
    503             "type": "library",
    504             "installation-source": "dist",
    505             "autoload": {
    506                 "psr-4": {
    507                     "PHPHtmlParser\\": "src/PHPHtmlParser"
    508                 }
    509             },
    510             "notification-url": "https://packagist.org/downloads/",
    511             "license": [
    512                 "MIT"
    513             ],
    514             "authors": [
    515                 {
    516                     "name": "Gilles Paquette",
    517                     "email": "paquettg@gmail.com",
    518                     "homepage": "http://gillespaquette.ca"
    519                 }
    520             ],
    521             "description": "An HTML DOM parser. It allows you to manipulate HTML. Find tags on an HTML page with selectors just like jQuery.",
    522             "homepage": "https://github.com/paquettg/php-html-parser",
    523             "keywords": [
    524                 "dom",
    525                 "html",
    526                 "parser"
    527             ],
    528             "support": {
    529                 "issues": "https://github.com/paquettg/php-html-parser/issues",
    530                 "source": "https://github.com/paquettg/php-html-parser/tree/3.1.1"
    531             },
    532             "funding": [
    533                 {
    534                     "url": "https://tidelift.com/funding/github/packagist/paquettg/php-html-parser",
    535                     "type": "tidelift"
    536                 }
    537             ],
    538             "install-path": "../paquettg/php-html-parser"
    539         },
    540         {
    541540            "name": "paquettg/string-encode",
    542541            "version": "1.0.1",
     
    741740                }
    742741            },
    743             "installation-source": "dist",
     742            "installation-source": "source",
    744743            "notification-url": "https://packagist.org/downloads/",
    745744            "license": [
     
    822821                }
    823822            },
    824             "installation-source": "dist",
     823            "installation-source": "source",
    825824            "autoload": {
    826825                "classmap": [
     
    10381037        {
    10391038            "name": "squizlabs/php_codesniffer",
    1040             "version": "3.10.2",
    1041             "version_normalized": "3.10.2.0",
     1039            "version": "3.10.3",
     1040            "version_normalized": "3.10.3.0",
    10421041            "source": {
    10431042                "type": "git",
    10441043                "url": "https://github.com/PHPCSStandards/PHP_CodeSniffer.git",
    1045                 "reference": "86e5f5dd9a840c46810ebe5ff1885581c42a3017"
    1046             },
    1047             "dist": {
    1048                 "type": "zip",
    1049                 "url": "https://api.github.com/repos/PHPCSStandards/PHP_CodeSniffer/zipball/86e5f5dd9a840c46810ebe5ff1885581c42a3017",
    1050                 "reference": "86e5f5dd9a840c46810ebe5ff1885581c42a3017",
     1044                "reference": "62d32998e820bddc40f99f8251958aed187a5c9c"
     1045            },
     1046            "dist": {
     1047                "type": "zip",
     1048                "url": "https://api.github.com/repos/PHPCSStandards/PHP_CodeSniffer/zipball/62d32998e820bddc40f99f8251958aed187a5c9c",
     1049                "reference": "62d32998e820bddc40f99f8251958aed187a5c9c",
    10511050                "shasum": ""
    10521051            },
     
    10601059                "phpunit/phpunit": "^4.0 || ^5.0 || ^6.0 || ^7.0 || ^8.0 || ^9.3.4"
    10611060            },
    1062             "time": "2024-07-21T23:26:44+00:00",
     1061            "time": "2024-09-18T10:38:58+00:00",
    10631062            "bin": [
    10641063                "bin/phpcbf",
     
    10711070                }
    10721071            },
    1073             "installation-source": "dist",
     1072            "installation-source": "source",
    10741073            "notification-url": "https://packagist.org/downloads/",
    10751074            "license": [
     
    12271226            "time": "2024-03-25T16:39:00+00:00",
    12281227            "type": "phpcodesniffer-standard",
    1229             "installation-source": "dist",
     1228            "installation-source": "source",
    12301229            "notification-url": "https://packagist.org/downloads/",
    12311230            "license": [
  • fluentc-translation/trunk/vendor/composer/installed.php

    r3130179 r3155849  
    44        'pretty_version' => 'dev-main',
    55        'version' => 'dev-main',
    6         'reference' => '339a53f9cf72277741074188046f8521f026d550',
     6        'reference' => 'cf45b01c58ff2892b642f122caecf86f2d8b0873',
    77        'type' => 'library',
    88        'install_path' => __DIR__ . '/../../',
     
    1414            'pretty_version' => 'dev-main',
    1515            'version' => 'dev-main',
    16             'reference' => '339a53f9cf72277741074188046f8521f026d550',
     16            'reference' => 'cf45b01c58ff2892b642f122caecf86f2d8b0873',
    1717            'type' => 'library',
    1818            'install_path' => __DIR__ . '/../../',
     
    2828            'aliases' => array(),
    2929            'dev_requirement' => true,
     30        ),
     31        'fluentc/php-html-parser' => array(
     32            'pretty_version' => '3.1.4',
     33            'version' => '3.1.4.0',
     34            'reference' => '9e14514b532211afce53405ae6eb15236d2b4952',
     35            'type' => 'library',
     36            'install_path' => __DIR__ . '/../fluentc/php-html-parser',
     37            'aliases' => array(),
     38            'dev_requirement' => false,
    3039        ),
    3140        'guzzlehttp/guzzle' => array(
     
    6271            'type' => 'library',
    6372            'install_path' => __DIR__ . '/../myclabs/php-enum',
    64             'aliases' => array(),
    65             'dev_requirement' => false,
    66         ),
    67         'paquettg/php-html-parser' => array(
    68             'pretty_version' => '3.1.1',
    69             'version' => '3.1.1.0',
    70             'reference' => '4e01a438ad5961cc2d7427eb9798d213c8a12629',
    71             'type' => 'library',
    72             'install_path' => __DIR__ . '/../paquettg/php-html-parser',
    7373            'aliases' => array(),
    7474            'dev_requirement' => false,
     
    159159        ),
    160160        'squizlabs/php_codesniffer' => array(
    161             'pretty_version' => '3.10.2',
    162             'version' => '3.10.2.0',
    163             'reference' => '86e5f5dd9a840c46810ebe5ff1885581c42a3017',
     161            'pretty_version' => '3.10.3',
     162            'version' => '3.10.3.0',
     163            'reference' => '62d32998e820bddc40f99f8251958aed187a5c9c',
    164164            'type' => 'library',
    165165            'install_path' => __DIR__ . '/../squizlabs/php_codesniffer',
Note: See TracChangeset for help on using the changeset viewer.