Skip to content

fix(editor): map XOOPS locale to TinyMCE 7 pack code (#76)#78

Merged
mambax7 merged 2 commits into
XOOPS:masterfrom
mambax7:fix/issue-76-tinymce7-locale
May 17, 2026
Merged

fix(editor): map XOOPS locale to TinyMCE 7 pack code (#76)#78
mambax7 merged 2 commits into
XOOPS:masterfrom
mambax7:fix/issue-76-tinymce7-locale

Conversation

@mambax7
Copy link
Copy Markdown
Contributor

@mambax7 mambax7 commented May 17, 2026

Closes #76.

Problem

XoopsFormTinymce7::getLanguage()'s fallback (no _XOOPS_EDITOR_TINYMCE7_LANGUAGE defined) produced TinyMCE 3-style codes — str_replace('_','-', strtolower(_LANGCODE)) + a _utf8 suffix (e.g. zh-tw_utf8, and even enen_utf8). TinyMCE 7 packs are <lang> or <lang>_<REGION> (fr_FR.js, zh_TW.js, …) with no _utf8, so every non-English site without the constant silently fell back to English. #72 fixed only the explicit-constant path; this is the fallback.

Fix

  • New normalizeLanguageCode() (pure, static): trims, strips the legacy _utf8, maps known XOOPS codes to the canonical TinyMCE 7 pack name (frfr_FR, svsv_SE, zh-tw/zh_TW/zh-hkzh_TW, pt-brpt_BR, …), otherwise normalises to <lang>_<REGION>; bare languages whose TinyMCE pack is already bare (de, ru, it, …) pass through; empty/invalid → en. Unknown codes degrade to TinyMCE's English default (never worse than today).
  • getLanguage() fallback uses it; the explicit-constant path is unchanged (fix: preserve TinyMCE 7 language locale casing #72 semantics preserved).
  • Corrected the stale TinyMCE 3 comment (dead moxiecode URL / jscripts/langs path) in the english & french editor language files; set french to the valid fr_FR pack name.

No new language define() (only a comment + value change) → no lang_diff.txt entry required.

Tests

Data-provider unit tests in XoopsFormTinymce7Test assert the documented contract (enen, frfr_FR, zh_TW/zh-tw/zh-tw_utf8zh_TW, pt_BRpt_BR, svsv_SE, es-mxes_MX, ''en). These are real executable unit tests of a pure method (not static-source) — they also give genuine patch coverage.

Verification: lint clean on all 5 files; every data-provider case + extra robustness probes (trimming, de passthrough, zh-HK, en-US) verified deterministically against the implementation locally. I could not run the PHPUnit suite in this environment — CI is the final word.

Note

The bundled TinyMCE 7 still ships no language packs (js/tinymce/langs/ is just a README). This fix makes the editor request the correct pack code; sites must still add the desired <code>.js pack for a non-English UI. That packaging decision is out of scope here.

Test plan

  • CI green (PHP 8.2–8.5 run the new data-provider tests)
  • Manual: on a site whose _LANGCODE is e.g. fr/zh-TW with no editor-language constant, confirm TinyMCE requests fr_FR/zh_TW

Summary by CodeRabbit

  • Bug Fixes
    • Fixed TinyMCE 7 language code handling to properly use language-pack filename formats (e.g., zh_TW, fr_FR, pt_BR).
    • Removed invalid legacy suffix from language codes.
    • Enhanced language fallback mechanism for improved TinyMCE 7 compatibility.

Review Change Stack

The getLanguage() fallback emitted TinyMCE 3-style codes
(strtolower + '-' + '_utf8', e.g. zh-tw_utf8) that match no TinyMCE 7
language pack, so non-English sites without _XOOPS_EDITOR_TINYMCE7_LANGUAGE
silently fell back to English.

- Add XoopsFormTinymce7::normalizeLanguageCode(): strips the legacy
  _utf8 suffix, maps known XOOPS codes to TinyMCE 7 pack filenames
  (fr -> fr_FR, sv -> sv_SE, zh-tw -> zh_TW, ...), and otherwise
  normalises to <lang>_<REGION>; empty -> 'en'.
- getLanguage() fallback uses it; explicit-constant path unchanged.
- Correct the stale TinyMCE 3 comment in the english/french editor
  language files (dead moxiecode URL) and set french to the valid
  TinyMCE 7 pack name 'fr_FR'.
- Data-provider unit tests cover the documented contract.

Closes XOOPS#76.
Copilot AI review requested due to automatic review settings May 17, 2026 09:27
@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented May 17, 2026

Warning

Rate limit exceeded

@mambax7 has exceeded the limit for the number of commits that can be reviewed per hour. Please wait 45 minutes and 37 seconds before requesting another review.

You’ve run out of usage credits. Purchase more in the billing tab.

⌛ How to resolve this issue?

After the wait time has elapsed, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

We recommend that you space out your commits to avoid hitting the rate limit.

🚦 How do rate limits work?

CodeRabbit enforces hourly rate limits for each developer per organization.

Our paid plans have higher rate limits than the trial, open-source and free plans. In all cases, we re-allow further reviews after a brief timeout.

Please see our FAQ for further information.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Pro

Run ID: b689d1f8-06ec-482f-b6ab-fa75cfa7752a

📥 Commits

Reviewing files that changed from the base of the PR and between 7dc57d1 and 8715539.

📒 Files selected for processing (2)
  • htdocs/class/xoopseditor/tinymce7/formtinymce.php
  • tests/unit/htdocs/class/xoopseditor/tinymce7/XoopsFormTinymce7Test.php

Walkthrough

This PR refactors TinyMCE 7 language-code fallback handling in XOOPS Core 2.7.0 to emit locale pack filename codes (zh_TW, fr_FR, etc.) instead of lowercased variants with invalid _utf8 suffixes. A mapping table normalizes XOOPS/legacy language codes, and comprehensive unit tests validate the new normalization logic.

Changes

Language Code Normalization

Layer / File(s) Summary
Language normalization implementation and mapping table
htdocs/class/xoopseditor/tinymce7/formtinymce.php
TINYMCE7_LANGUAGE_MAP lookup table maps XOOPS/legacy language variants (e.g., fr-frfr_FR, zh-hanszh_CN) to TinyMCE 7 pack filenames. normalizeLanguageCode() trims input, strips legacy utf8 suffixes case-insensitively, applies the map, and converts dash-separated language-region codes to underscore format. getLanguage() now derives and normalizes codes from _LANGCODE instead of appending the _utf8 suffix.
Language configuration and test coverage
htdocs/class/xoopseditor/tinymce7/language/french.php, tests/unit/htdocs/class/xoopseditor/tinymce7/XoopsFormTinymce7Test.php, docs/changelog.270.txt
French language constant updated from fr to fr_FR locale format. Unit tests import DataProvider attribute and introduce fallbackLanguageCodeProvider() data provider with language-code mappings and testFallbackLanguageCodesUseTinymce7LocaleFormat() to validate normalization output. Changelog documents locale-format emission and _utf8 suffix removal (issue #76).

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Possibly related issues

  • XOOPS/XoopsCore27#76: This PR directly implements the requested normalization and removal of the _utf8 fallback by introducing normalizeLanguageCode() and updating getLanguage() to emit correct TinyMCE 7 locale pack codes.

Possibly related PRs

  • XOOPS/XoopsCore27#75: Both PRs extend XoopsFormTinymce7Test.php and refine language handling coverage; #75 isolates locale-case tests while this PR adds comprehensive fallback-mapping assertions.
  • XOOPS/XoopsCore27#72: Both PRs modify TinyMCE 7 language-code formatting in formtinymce.php and language files to ensure correct locale filenames like zh_TW and fr_FR, with overlapping changes to getLanguage() and corresponding test coverage.
🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 57.14% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately and concisely describes the main fix: mapping XOOPS locale codes to TinyMCE 7 pack code format, addressing issue #76.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@codecov
Copy link
Copy Markdown

codecov Bot commented May 17, 2026

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 18.12%. Comparing base (62d52ff) to head (8715539).
⚠️ Report is 3 commits behind head on master.

Additional details and impacted files
@@             Coverage Diff              @@
##             master      #78      +/-   ##
============================================
- Coverage     18.13%   18.12%   -0.02%     
  Complexity     7854     7854              
============================================
  Files           666      666              
  Lines         43208    43240      +32     
============================================
  Hits           7837     7837              
- Misses        35371    35403      +32     

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@htdocs/class/xoopseditor/tinymce7/formtinymce.php`:
- Around line 189-199: This helper currently splits $key into $parts and returns
pack codes even for malformed tokens; update the fallback-normalization logic
that works on $key/$parts to validate tokens strictly: ensure $parts[0] matches
a two-letter lowercase language code and, if $parts[1] exists, ensure it matches
a two-letter alphabetic region code before returning $parts[0] or $parts[0] .
'_' . strtoupper($parts[1]); if validation fails at any point return 'en'. Use
the existing $key and $parts variables and preserve the existing uppercase
conversion for the region.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Pro

Run ID: 03902892-bc57-46c9-9a80-d58fcbb385d9

📥 Commits

Reviewing files that changed from the base of the PR and between 463aa31 and 7dc57d1.

📒 Files selected for processing (5)
  • docs/changelog.270.txt
  • htdocs/class/xoopseditor/tinymce7/formtinymce.php
  • htdocs/class/xoopseditor/tinymce7/language/english.php
  • htdocs/class/xoopseditor/tinymce7/language/french.php
  • tests/unit/htdocs/class/xoopseditor/tinymce7/XoopsFormTinymce7Test.php

Comment thread htdocs/class/xoopseditor/tinymce7/formtinymce.php Outdated
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR updates the TinyMCE 7 editor adapter so XOOPS fallback locale codes resolve to TinyMCE 7 language-pack filenames instead of legacy TinyMCE 3-style codes.

Changes:

  • Adds locale normalization and mapping for TinyMCE 7 language codes.
  • Updates English/French editor language metadata and French pack code.
  • Adds unit coverage for representative fallback normalization cases and documents the fix in the 2.7.0 changelog.

Reviewed changes

Copilot reviewed 5 out of 5 changed files in this pull request and generated 2 comments.

Show a summary per file
File Description
htdocs/class/xoopseditor/tinymce7/formtinymce.php Adds TinyMCE 7 language-code mapping and fallback normalization.
htdocs/class/xoopseditor/tinymce7/language/english.php Updates the language-pack comment.
htdocs/class/xoopseditor/tinymce7/language/french.php Updates the language-pack comment and changes French to fr_FR.
tests/unit/htdocs/class/xoopseditor/tinymce7/XoopsFormTinymce7Test.php Adds data-provider tests for fallback locale normalization.
docs/changelog.270.txt Records the TinyMCE 7 fallback language handling fix.

Comment on lines +194 to +198
if (!isset($parts[1]) || $parts[1] === '') {
return $parts[0];
}

return $parts[0] . '_' . strtoupper($parts[1]);
Comment on lines +82 to +88
public function normalizeForTest(string $langcode): string
{
return self::normalizeLanguageCode($langcode);
}
};

self::assertSame($expected, $editor->normalizeForTest($langcode));
…S#78 review)

- CodeRabbit (blocking, valid): normalizeLanguageCode() could turn a
  malformed _LANGCODE into a junk pack code. Validate the split tokens
  (language ^[a-z]{2,3}$, region ^[a-z]{2}$); anything else degrades to
  the built-in 'en'. Contract preserved (mapped/empty cases bypass it;
  es-mx -> es_MX still works).
- Copilot (valid): de_DE/es_ES (and it/ja/nl/pl/ru/tr/uk/vi country
  variants) fell through to non-existent pack names. Add explicit map
  aliases that collapse them to the bare TinyMCE 7 pack. Done via the
  map (not a generic collapse) so a real regional pack like es_MX is
  intentionally NOT collapsed and still resolves.
- Copilot (valid coverage gap): add a separate-process end-to-end test
  proving getLanguage() runs _LANGCODE through the normalizer when
  _XOOPS_EDITOR_TINYMCE7_LANGUAGE is absent; plus data-provider cases
  for de_DE, es_ES, malformed and bad-region inputs.

Not contorting for Sonar S1142 (too-many-returns): the gate passes and
guard clauses are clearer here than a forced single-exit. Constant S115
is a XOOPS language-constant-convention false positive (do not rename).
@sonarqubecloud
Copy link
Copy Markdown

Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 5 out of 5 changed files in this pull request and generated no new comments.

@mambax7 mambax7 merged commit 4bfdc69 into XOOPS:master May 17, 2026
11 of 12 checks passed
@mambax7 mambax7 deleted the fix/issue-76-tinymce7-locale branch May 17, 2026 12:12
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

TinyMCE 7: getLanguage() fallback emits TinyMCE 3-style locale codes (e.g. zh-tw_utf8)

2 participants