Files
WebForm-mw/civi-extension/webform-mw/xml/Menu/webform_mw.xml
T
Joel Brock 325615576a Upload: route through Civi extension multipart endpoint
Every JSON-based upload path on this Civi stores the `content` field
verbatim on disk — confirmed against both APIv4 File.create AND APIv3
Attachment.create (both came back as base64 text in hex dumps). The
multipart `file` part to /civicrm/ajax/rest is also a dead end: APIv3
Attachment.create on this install doesn't see $_FILES (rejected with
"Mandatory key(s) missing: id or content or options.move-file").

The one path Civi honors is APIv3 Attachment.create + options.move-file
— pointing at a filesystem path the Civi server can read. So expose a
tiny multipart endpoint in the WebForm-mw Civi extension that copies
PHP's $_FILES['file']['tmp_name'] into the API call, then return the
new file id as JSON. PHP's $_FILES preserves binary natively.

Civi extension (requires admin deploy):
- CRM/WebformMw/Page/Upload.php  : multipart POST handler. Validates
  the upload, requires `access CiviCRM`, whitelists entity_table to
  civicrm_contact|civicrm_activity, calls Attachment.create with
  move-file pointing at the tmp upload, returns {id, name} JSON.
- xml/Menu/webform_mw.xml        : registers civicrm/webform-mw/upload.

WebForm-mw side:
- lib/civicrm.ts : new civiMultipart() helper. POSTs multipart to an
  arbitrary Civi path (not /civicrm/ajax/rest) with the same AuthX
  headers. Returns the parsed JSON body.
- app/api/upload/route.ts : send the upload's bytes via civiMultipart
  to civicrm/webform-mw/upload. Comment-block now records all four
  upload paths we tried so a future reader doesn't repeat the cycle.

Deploy: admin syncs the updated civi-extension/webform-mw/ directory
and Disable/Re-enables the extension (or runs cv flush) so the new
menu route is registered.
2026-06-10 12:28:43 -07:00

22 lines
732 B
XML

<?xml version="1.0" encoding="iso-8859-1" ?>
<menu>
<item>
<path>civicrm/contact/view/engagement-report</path>
<title>Engagement Report</title>
<page_callback>CRM_WebformMw_Page_Tab</page_callback>
<access_arguments>access CiviCRM</access_arguments>
</item>
<item>
<path>civicrm/webform-mw/file</path>
<title>WebForm-mw file redirect</title>
<page_callback>CRM_WebformMw_Page_File</page_callback>
<access_arguments>access CiviCRM</access_arguments>
</item>
<item>
<path>civicrm/webform-mw/upload</path>
<title>WebForm-mw file upload proxy</title>
<page_callback>CRM_WebformMw_Page_Upload</page_callback>
<access_arguments>access CiviCRM</access_arguments>
</item>
</menu>