/

File & Image Uploads

change_type() field types for file and image uploads, plus gallery() for a multi-image, drag-to-reorder field.

Plain file uploads

public function change_type(string $field, string $type, string $length = '', array $extra = []): self

change_type($field, 'file', '', $extra) turns a field into a file dropzone. Its $extra options:

OptionTypeDefaultDescription
not_renameboolfalseKeep the uploaded file's original name instead of a generated safe one. The name is still sanitized (path separators/traversal stripped) even with this on - it just isn't randomized.
previewfalse|true|'download'|'modal'|'edit'falseWhat clicking the file name does. false/'download' - a plain download link. true/'modal' - opens an in-app preview modal (an iframe onto the file) with a Download button alongside. 'edit' - opens that row's own edit form instead, useful when the field's real purpose is "the record this file is attached to".
$xcrud->change_type('simple_upload', 'file', '', ['not_rename' => true, 'preview' => 'modal']);

Image uploads

change_type($field, 'image', '', $extra) adds resize/crop/watermark/thumbnail processing on top of a plain upload:

OptionTypeDefaultDescription
width / heightint-Auto resize target. Both + crop=true fills the exact box (aspect ratio preserved, excess cropped); either alone, or both without crop, fits within the box (aspect ratio preserved, no cropping).
cropboolfalseSee above - fills the box instead of just fitting within it.
manual_cropboolfalseShows an interactive drag-to-crop UI (Cropper.js) right after picking a file, before it's saved. Combines with width/height/crop rather than replacing them - manual_crop controls what gets kept, the others still apply to the cropped result afterward.
ratiofloat-With manual_crop, locks the crop box to this width/height ratio (e.g. 0.5 = always twice as tall as wide) instead of letting the visitor pick any rectangle.
watermarkstring-Path to a PNG, relative to the project root, overlaid onto the saved image.
watermark_position[x%, y%][95, 95]Where the watermark's top-left corner lands, as a percentage of the image's own width/height.
thumbsarray[]Named additional derived images saved alongside the main one - each item: width/height/crop/marker (filename suffix)/folder/watermark. Each thumb is independently resized from the original, not chained off each other.
// Fits within 200x200, no cropping
$xcrud->change_type('auto_resize', 'image', '', ['width' => 200, 'height' => 200]);

// Fills 200x200 exactly, excess cropped
$xcrud->change_type('auto_crop', 'image', '', ['width' => 200, 'height' => 200, 'crop' => true]);

// Interactive drag-to-crop, then resized to 200x200
$xcrud->change_type('manual_crop_2', 'image', '', ['width' => 200, 'height' => 200, 'manual_crop' => true]);

// Two derived thumbnails, one watermarked, one cropped into a subfolder
$xcrud->change_type('image_with_thumbs', 'image', '', [
    'thumbs' => [
        ['width' => 300, 'marker' => '_th', 'watermark' => 'assets/watermark.png'],
        ['width' => 100, 'height' => 100, 'crop' => true, 'folder' => 'thumbs'],
    ],
]);

Upload storage configuration

These live in XcrudConfig, not per-field:

SettingTypeDefaultDescription
$uploadDirstring'media/'Where uploaded files are actually written.
$uploadMaxSizeint10 MB (10 * 1024 * 1024)Max upload size in bytes, enforced application-side on top of PHP's own upload_max_filesize.
$uploadAllowedImageExtarray['jpg', 'jpeg', 'png', 'gif', 'webp']Allowed extensions for image fields.
$uploadAllowedFileExtarraya curated list of common document/archive typesAllowed extensions for plain file fields. Add to this list only for genuinely safe types you actually need.

See the XcrudConfig Reference for every other setting.

public function gallery(string $field, string $childTable, array $options = []): self

Unlike change_type('image'), gallery() is a drag-drop field for many images at once, each saved as its own row in $childTable - not a column on the current table. $field here is a virtual name, so it does not go in ->columns(). $childTable must itself be a real, reachable table with at minimum an auto-increment id, the foreign-key column named in fk, a filename column, a name column (a per-image caption), a size column, and a sort_order column that drag-to-reorder persists into.

OptionTypeDefaultDescription
fkstringrequiredThe child table's own foreign-key column referencing this table's primary key.
folderstringfield nameSubdirectory of $uploadDir this gallery's images are saved into.
layout'grid'|'list''grid''grid' - a wrapping grid of square thumbnails. 'list' - one row per image with a thumbnail, editable caption, file size, and Preview/Remove buttons. Drag-to-reorder works identically either way.
width / height / crop / watermark / watermark_position / thumbs--Same meaning as change_type('image')'s own options, applied to every image uploaded into this gallery independently.
max_filesint-Caps how many images this gallery can hold in total; further uploads are rejected once reached.
$xcrud->gallery('gallery', 'uploads_gallery', [
    'fk'     => 'upload_id',
    'width'  => 1600,
    'height' => 1600,
]);

A brand new, never-saved row has no id yet for gallery images to reference - the field shows a disabled "save this record first" placeholder until the row actually exists.