Weave Code
Weaver
Helps Laravel developers discover, compare, and choose open-source packages. See popularity, security, maintainers, and scores at a glance to make better decisions.
Feedback
Share your thoughts, report bugs, or suggest improvements.
Subject
Message

Orm File Field Laravel Package

mindy/orm-file-field

Provides a file field type for Mindy ORM models, letting you attach, store, and retrieve uploaded files through model attributes. It simplifies file handling in Laravel/PHP applications by treating files as ORM-managed fields with less manual upload and storage code.

View on GitHub
Deep Wiki
Context7

Getting Started

mindy/orm-file-field adds FileField and ImageField column types to the Mindy ORM, so an entity can own an uploaded file, persist its path in the database, and expose helpers for reading/deleting it. With 1 star and zero dependents, treat the source as the documentation: read src/ and composer.json before wiring it in.

1. Install and pin

composer require mindy/orm-file-field

Check the constraint against your Mindy core version — this is a low-traffic package, so verify the mindy/orm requirement is compatible with what your app already uses rather than letting Composer resolve blindly.

2. Find the bootstrap point. Mindy ORM field packages are usually registered implicitly via PSR-4 autoloading (no service provider). Confirm by locating the field classes in the package and referencing them by FQCN in your model. If the package ships a config file or a FileField::$storagePath-style static, publish or set that first — path configuration is where most surprises live.

3. Declare the field on a model

use Mindy\Orm\Model;
use Mindy\Orm\Fields\FileField;
use Mindy\Orm\Fields\ImageField;

class Product extends Model
{
    public static function getFields()
    {
        return [
            'manual' => [
                'class'  => FileField::class,
                'null'   => true,
                'verboseName' => 'PDF manual',
            ],
            'cover' => [
                'class'  => ImageField::class,
                'null'   => true,
            ],
        ];
    }
}

4. First use case: a single image on a content model. The canonical day-one task is uploading a product/user avatar, storing it on disk, and rendering it. Create the field, handle the upload in the controller (or in a Mindy form class if the package ships form widgets), save the model, then render:

$product->cover = $uploadedFile; // or the temp path the field expects
$product->save();
echo $product->cover->getUrl();

Where to look first, in order: the field classes themselves (what properties they expose — path, url, name, size, delete/remove method), any trait or behavior they pull in for upload handling, and the package's tests/examples if present. Do not assume ImageField includes resizing; verify whether it delegates to GD, Imagick, or nothing at all.

Implementation Patterns

Upload-then-assign. The reliable pattern is to let the framework's upload object or temp path reach the field, then save. Keep file movement inside a service or controller action so the ORM stays free of $_FILES assumptions:

public function actionCreate(Request $request)
{
    $product = new Product();
    if ($request->isPost && $product->load($request->post())->isValid()) {
        $product->cover = $request->file('cover');
        $product->save();
    }
}

Separate write path from render path. Store a relative path in the DB and resolve it through the field at render time. This is what keeps deployments portable between local, staging, and CDN-backed storage. Never persist an absolute filesystem path.

Deterministic filenames. If the package does not enforce a naming strategy, wrap the field with your own: hash or slug plus the original extension. This prevents collisions and stops user-supplied names leaking into URLs.

$product->cover = $file;          // field stores path
$product->cover->setName(sprintf('%s-%s.%s', $product->slug, uniqid(), $ext));

Validate before you save, not after. File and image validation belongs in the model's rules() or a form class: MIME type, extension whitelist, max byte size, and for images, dimensions. ImageField may validate dimensions itself — check first, then layer your own rules.

Cleanup on update and delete. The most common production bug in file-field packages is orphaned files. On replacement, delete the previous file before or after the new write, and hook entity deletion:

public function beforeSave()
{
    if ($this->getIsNewRecord() === false) {
        $old = $this->getOldAttribute('cover');
        // delete $old if changed
    }
}

public function afterDelete()
{
    if ($this->cover) {
        $this->cover->delete();
    }
}

Verify the field exposes delete() or remove() and what it returns — some implementations only clear the DB value.

Thumbnails and derivatives. Treat derived images as a separate concern. Either the field supports on-the-fly resizing (check for width/height options), or generate derivatives in an afterSave hook into a parallel directory (cover/thumbs/). Cache the derivative path in a computed getter rather than adding extra database columns for every size.

Eager-loading and N+1. If files are stored via a related model rather than a plain column, use Mindy's with()/select_related-equivalent when listing records, otherwise each row triggers a filesystem stat in the template.

Integration with forms. If the package ships form field types, prefer them over raw <input type="file"> — they usually handle the "keep existing file when no new upload is sent" case, which is trivial to get wrong by hand:

// In an edit form, only overwrite when a new file is present
if ($request->file('cover')) {
    $product->cover = $request->file('cover');
}

Testing. Point the storage root at a temp directory or vfsStream in your test bootstrap so tests do not litter the repo, and assert both the DB value and the existence of the file after save().

Gotchas and Tips

This package is effectively undocumented. One star and no dependents means no blog posts, no Stack Overflow answers, and possibly stale examples. Budget an hour to read the field classes before designing around them; the API surface is small, and guessing at getUrl() semantics will cost more time than reading.

Version pinning is not optional. With a single-maintainer, low-activity package, a composer update can change behavior silently. Pin to a commit or exact version in composer.json and review diffs when bumping.

Filesystem/DB non-atomicity. The file is written before the row commits, so a failed save() leaves an orphan; a deleted row leaves a file. Mitigate with an afterDelete cleanup hook and a periodic sweeper for orphans. Wrap upload work in a try/catch that removes the temp file on exception.

Path configuration is the usual failure point. Relative paths resolve against the process working directory, which differs between web, CLI, and queue workers. Set an absolute storage root in config and derive web URLs separately. Check whether the package respects open_basedir and whether the web root is expected to be a sibling of the storage directory.

Permissions and ownership. The PHP process must be able to write the storage directory; in Docker, that user is usually www-data, not your local user. A silent upload failure that only appears in staging is almost always a permissions or SELinux issue.

Filename sanitization. If the original filename is trusted anywhere, you have a path-traversal vector (../../). Whitelist extensions and strip path separators even if the package claims to handle it.

GD/Imagick dependency. ImageField may call image functions that require an extension. Confirm php -m | grep -E 'gd|imagick' on every environment; a missing extension tends to surface as a fatal error mid-upload rather than a validation failure.

Deletion semantics differ. Some field implementations delete the file when the attribute is set to null, others leave it on disk. Read the delete()/remove() implementations and write your cleanup explicitly rather than relying on implicit behavior.

Extension points. Subclass FileField/ImageField to change the naming strategy, storage adapter, or URL generation; override the relevant method rather than patching vendor code. If the package exposes static configuration (storage path, public URL prefix), set it once in bootstrap, not per model.

Debugging tip. When an upload "succeeds" but the value is empty, log the value the field receives before save(), the resolved absolute path it computed, and the resulting column value. That three-line trace distinguishes a form/plumbing bug from a path-resolution bug from a field bug in about ninety seconds.

Have an exit plan. For production work, weigh this package against a thinner approach — a plain CharField for the path plus a small upload service. Two hundred lines of your own code you understand will often beat a one-star dependency you have to reverse-engineer, especially given the zero-dependents signal.

Weaver

How can I help you explore Laravel packages today?

Conversation history is not saved when not logged in.
Prompt
Add packages to context
No packages found.
coleus/frame
thtg88/journalism
filagora/filagora-ai-forums
rlacerda83/query-parser
socialdept/atp-orm
cboxdk/laravel-assistant-client
socialdept/atp-resolver
socialdept/tenant-domains
tautvydasr/blade-class-names
socialdept/color-scales
maherelgamil/controller
coleus/widgets
coleus/table
coleus/users
coleus/music
coleus/health
coleus/calendar
coleus/notes
coleus/support
coleus/settings