Weave Code
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

Laravel Files Laravel Package

sextanet/laravel-files

View on GitHub
Deep Wiki
Context7

Getting Started

Minimal Setup

  1. Installation:

    composer require sextanet/laravel-files
    php artisan vendor:publish --tag="files-migrations"
    php artisan migrate
    
    • Publishes migrations and config files for the files table and relationships.
  2. Define a Model: Add HasFiles trait to your model (e.g., Post):

    use Sextanet\Files\HasFiles;
    
    class Post extends Model
    {
        use HasFiles;
    }
    
  3. First Use Case: Upload a file via a form:

    $post = Post::create(['title' => 'My Post']);
    $post->addFile($request->file('file_input'), 'path/to/store'); // Stores on default disk
    
    • Automatically creates a record in the files table with metadata (disk, path, model ID).

Implementation Patterns

Core Workflows

  1. File Uploads with Metadata:

    // Upload with custom disk and metadata
    $user = User::find(1);
    $user->addFile($request->file('avatar'), 'avatars', [
        'disk' => 's3',
        'mime_type' => 'image/jpeg',
        'visibility' => 'public',
    ]);
    
  2. Scoped Disks: Leverage Laravel’s scoped disks (e.g., s3:private) for access control:

    $file = $post->addFile($request->file('document'), 'documents', [
        'disk' => 's3:private',
    ]);
    
  3. Temporary URLs: Generate time-limited URLs for local files (e.g., for email attachments):

    $url = $file->temporaryUrl(60); // Valid for 60 seconds
    
  4. File Retrieval:

    // Get file path (resolves disk automatically)
    $path = $file->path;
    
    // Stream file directly (e.g., for responses)
    return response()->streamDownload($file->stream(), $file->name);
    
  5. Bulk Operations:

    // Delete all files for a model
    $post->files()->delete();
    
    // Sync files (e.g., after manual uploads)
    $post->syncFiles([$newFileId, $existingFileId]);
    

Integration Tips

  • Validation: Use Laravel’s validation rules to restrict file types/sizes before upload:

    $request->validate([
        'file' => 'required|file|mimes:pdf,jpeg|max:2048',
    ]);
    
  • Events: Listen for file operations (e.g., FileCreated, FileDeleted) via Laravel’s event system:

    // In EventServiceProvider
    protected $listen = [
        'Sextanet\Files\Events\FileCreated' => [
            'App\Listeners\LogFileUpload',
        ],
    ];
    
  • Policy Authorization: Restrict file access in policies:

    public function delete(User $user, File $file)
    {
        return $user->id === $file->model_id;
    }
    
  • Storage Optimization: Use optionalDisk() to handle missing disks gracefully:

    $file->optionalDisk('fallback-disk')->path;
    

Gotchas and Tips

Pitfalls

  1. Disk Configuration:

    • Ensure disks are properly configured in config/filesystems.php. Missing disks will cause silent failures.
    • Fix: Validate disk existence before upload:
      if (!Storage::disk($disk)->exists($path)) {
          Storage::disk($disk)->makeDirectory($path);
      }
      
  2. Temporary URLs:

    • Local temporary URLs require symlink permissions. On shared hosting, this may fail.
    • Fix: Use S3 or other cloud storage for temporary URLs if local fails.
  3. Model Deletion:

    • Deleting a model does not automatically delete its files unless you:
      $post->delete(); // Files remain
      $post->files()->delete(); // Then delete files
      
    • Tip: Override delete() in your model:
      public function delete()
      {
          $this->files()->delete();
          parent::delete();
      }
      
  4. Path Collisions:

    • Custom paths must be unique per model. Reusing paths without IDs (e.g., documents/) will overwrite files.
    • Fix: Use model-specific paths:
      $post->addFile($file, "documents/{$post->id}/");
      
  5. Large Files:

    • Uploading large files (>100MB) may hit PHP’s post_max_size or memory limits.
    • Fix: Use chunked uploads (e.g., laravel-upload).

Debugging

  1. Missing Files:

    • Check files table for orphaned records (where model_id doesn’t exist).
    • Query:
      SELECT * FROM files WHERE model_id NOT IN (SELECT id FROM posts);
      
  2. Disk Permissions:

    • Verify storage permissions:
      chmod -R 775 storage/app
      chmod -R 775 public/storage
      
  3. Log File Operations:

    • Enable debug mode to log file operations:
      config(['files.debug' => true]);
      

Extension Points

  1. Custom File Model: Extend the File model to add fields (e.g., size, checksum):

    php artisan make:model FileExtension --extend=Sextanet\Files\Models\File
    
  2. File Events: Publish event classes and listen for custom logic:

    php artisan vendor:publish --tag="files-events"
    
  3. Disk Fallbacks: Implement a fallback disk strategy in app/Providers/AppServiceProvider:

    File::macro('fallbackDisk', function ($primary, $fallback) {
        return Storage::disk($primary)->exists($this->path)
            ? $primary
            : $fallback;
    });
    
  4. Presigned URLs: For S3, generate presigned URLs instead of temporary URLs:

    $url = $file->disk->url($file->path, 3600); // 1-hour URL
    
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.
jayeshmepani/jpl-moshier-ephemeris-php
elnasnato/laraliveui
labrodev/rest-sdk
sampaui/sampaui
babelqueue/php-sdk
facebook/capi-param-builder-php
babelqueue/symfony
hamzi/corewatch
minionfactory/raw-hydrator
hexters/coinpayment
rjcodes/rjcms
act-training/laravel-permissions-manager
alimarchal/laravel-chart-of-accounts
babenkoivan/elastic-scout-driver
mkwebdesign/filament-watchdog-v5
renatomarinho/laravel-page-speed
zedmagdy/filament-business-hours
renatovdemoura/blade-elements-ui
devgeek/beacon-admin
benjamin-rqt/data-watcher-bundle