Skip to content

Custom Fields Exchange Modernized

CI Agent edited this page Sep 13, 2026 · 2 revisions

Custom Fields XML Exchange — Modernized Screen

Modernization of the legacy Custom Fields export/import screens (lib/cfields/cfieldsExport.php + lib/cfields/cfieldsImport.php) — GitHub issue #1411.

The two legacy Smarty screens are replaced by a single standalone Dashio page (gui/templates/cfields/cfieldsExchange.html) backed by a plain-PHP REST BFF API (api/cfieldsx/index.php). The Custom Fields screen (cfieldsView.html) toolbar now has Export and Upload File buttons pointing at the modern screen, and $actions->cfieldsExchange was added in lib/functions/common.php.

  • URL: gui/templates/cfields/cfieldsExchange.html
  • BFF API: GET /api/cfieldsx/ (info) · POST /api/cfieldsx/export (download) · POST /api/cfieldsx/import (multipart upload)
  • Rights: export — cfield_view; import — cfield_management (parity with legacy). Users without a right see the affected card greyed out and receive HTTP 403 from the BFF.

Screen layout

Section Description
Context strip Existing custom field count + export/import rights + max upload size
Export card Filename input (default customFields.xml), Format select (XML only), View File Format Document link, Export button (downloads the XML attachment)
Import card Format select (XML only), file input, max-size hint, Upload File button
Result box Green list of Imported names and red list of Not imported (already-existing) names, plus a totals summary

cfieldsExchange normal state

Export behavior

The BFF mirrors the legacy ADODB_XML output exactly: root <custom_fields>, one <custom_field> row per custom_fields ⋈ cfield_node_types row, columns name, label, type, possible_values, default_value, valid_regexp, length_min, length_max, show_on_design, enable_on_design, show_on_execution, enable_on_execution, show_on_testplan_design, enable_on_testplan_design, node_type_id. Streamed as an attachment, default filename customFields.xml. Right checked: cfield_view.

Import behavior

Rows are parsed XXE-safe (simplexml_load_string after disabling the entity loader, LIBXML_NONET). For each field, if no field with that name exists (cfield_mgr->get_by_name), it is created via cfield_mgr->create(); otherwise it is skipped and reported as not imported. Upload size limited by import_file_max_size_bytes (default 800 KB). Right checked: cfield_management.

cfieldsExchange import result

Error states

Case Client message
Empty export filename Export name can not be empty!
No file selected Please choose a file to import
File over the size limit The file exceeds the maximum allowed size of {kb} KB
Malformed/empty XML Could not load XML content… (+ libxml detail)

Security

Session auth + per-route rights, same-origin proof required on all POSTs (api/_guard.php), XXE protection (entity loader disabled + LIBXML_NONET), export filename sanitized (basename() + [a-zA-Z0-9 _.-] allow-list) before echoing in the Content-Disposition header. #1487 parity fix (2026-09-13): the old [a-zA-Z0-9_.] allow-list silently reverted filenames with spaces or hyphens to the default customFields.xml (legacy honored them); spaces/hyphens are accepted now and CRLF injection attempts still fall back safely.

i18n

32 cfx.* keys added to all 10 locale bundles (en, de, es, fr, it, ja, pt, ro, ru, zh), each validated with python3 -m json.tool.

Test cases

15/15 PASS — see tmp/TLU_Test_Cases.md → Task — Issue #1411. Re-verification 17/17 PASS (2026-09-13, fresh DB) → Task — Issue #1487 (export-filename parity fix recorded in docs/MODERNIZATION-STATUS.md as row #7b / extras entry).

Clone this wiki locally