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

Filesystem Laravel Package

joomla/filesystem

Joomla Framework filesystem utilities for common file operations. Includes helpers for safe filenames, uploads, and path handling, with a patcher component for applying file patches. Install via Composer and use in PHP apps needing lightweight filesystem tooling.

View on GitHub
Deep Wiki
Context7

Getting Started

Minimal Steps

  1. Installation:

    composer require joomla/filesystem "^3.0"
    

    For PHP 8.3+ projects (v4.x), use "^4.0".

  2. First Use Case: Upload a file with validation:

    use Joomla\Filesystem\File;
    
    $file = request()->file('file');
    $path = storage_path('app/uploads/' . File::makeSafe($file->getClientOriginalName()));
    
    File::upload($file->getPathname(), $path);
    
  3. Key Classes to Explore:

    • Joomla\Filesystem\File (file operations)
    • Joomla\Filesystem\Folder (directory operations)
    • Joomla\Filesystem\Path (path utilities)

Where to Look First


Implementation Patterns

Core Workflows

1. File Uploads with Validation

use Joomla\Filesystem\File;

// Validate file
$allowedExtensions = ['jpg', 'png', 'pdf'];
$maxSize = 5 * 1024 * 1024; // 5MB

$file = request()->file('file');
$ext = strtolower(File::getExt($file->getClientOriginalName()));

if (!in_array($ext, $allowedExtensions)) {
    throw new \InvalidArgumentException("Invalid file type.");
}

if ($file->getSize() > $maxSize) {
    throw new \RuntimeException("File too large.");
}

// Upload
$safeName = File::makeSafe($file->getClientOriginalName());
$path = storage_path("app/uploads/{$safeName}");
File::upload($file->getPathname(), $path);

2. Directory Operations

use Joomla\Filesystem\Folder;

// Create directory (recursive)
Folder::create(storage_path('app/cache'), 0755, true);

// List files (sorted)
$files = Folder::files(storage_path('app/uploads'), '.*\.jpg$', true, 'natsort');

3. File Content Handling

use Joomla\Filesystem\File;

// Read/write text
$content = File::read(storage_path('app/config.php'));
File::write(storage_path('app/config.php'), $content . "\n// Updated");

// Read binary (e.g., images)
$imageData = File::read(storage_path('app/uploads/image.jpg'), null, null, true);

4. Path Utilities

use Joomla\Filesystem\Path;

// Normalize and resolve paths
$absolutePath = Path::resolve(storage_path('..') . '/public');
$relativePath = Path::makeRelative($absolutePath, base_path());

Laravel Integration Tips

  1. Use with Laravel’s Storage Facade:

    use Illuminate\Support\Facades\Storage;
    use Joomla\Filesystem\File;
    
    $file = request()->file('file');
    $disk = Storage::disk('local');
    $path = $disk->path('uploads/' . File::makeSafe($file->getClientOriginalName()));
    
    File::upload($file->getPathname(), $path);
    
  2. Custom Validation Rules:

    use Joomla\Filesystem\File;
    use Illuminate\Validation\Rule;
    
    $validator = Validator::make($request->all(), [
        'file' => [
            'required',
            'file',
            Rule::function('ext', function ($attribute, $value) {
                $ext = strtolower(File::getExt($value->getClientOriginalName()));
                return in_array($ext, ['jpg', 'png']);
            }),
        ],
    ]);
    
  3. Service Provider Binding (for dependency injection):

    // app/Providers/AppServiceProvider.php
    public function register()
    {
        $this->app->bind('joomla.filesystem', function () {
            return new \Joomla\Filesystem\File();
        });
    }
    
  4. Artisan Commands:

    use Joomla\Filesystem\Folder;
    use Illuminate\Console\Command;
    
    class CleanCacheCommand extends Command
    {
        protected $signature = 'cache:clean';
        public function handle()
        {
            Folder::delete(storage_path('app/cache'));
            $this->info('Cache cleared!');
        }
    }
    

Gotchas and Tips

Pitfalls

  1. PHP Version Mismatch:

    • v3.x: Requires PHP 8.1+.
    • v4.x: Requires PHP 8.3+.
    • Laravel 10 supports PHP 8.2, so use ^3.2 for compatibility.
    • Workaround: Use a PHP version manager or pin to ^3.2.
  2. Path Handling Quirks:

    • File::makeSafe() transliterates filenames (e.g., köln.jpgkoln.jpg).
    • Always use Path::resolve() for absolute paths to avoid issues with ../ or ./.
    • Gotcha: Folder::create() fails silently if the parent directory doesn’t exist (use recursive: true).
  3. Error Messages:

    • Avoid exposing raw paths in errors (fixed in v2.0.1+ for CVE-2022-23794).
    • Wrap filesystem operations in try-catch:
      try {
          File::copy($source, $dest);
      } catch (\Exception $e) {
          Log::error("Copy failed: " . $e->getMessage());
          throw new \RuntimeException("Failed to copy file.");
      }
      
  4. File Permissions:

    • Folder::create() defaults to 0755. Use 0777 for writable directories (not recommended for production).
    • Tip: Set permissions after creation:
      Folder::create($path, 0755);
      chmod($path, 0777); // Only if absolutely necessary
      
  5. Large File Handling:

    • File::read() loads entire files into memory. For large files (>100MB), use streams:
      $handle = fopen($path, 'r');
      while (!feof($handle)) {
          $buffer = fread($handle, 8192);
          // Process buffer
      }
      fclose($handle);
      
  6. Windows Path Issues:

    • Use DIRECTORY_SEPARATOR or Path::normalize() for cross-platform paths:
      $path = Path::normalize('folder' . DIRECTORY_SEPARATOR . 'file.txt');
      

Debugging Tips

  1. Enable Debug Mode:

    \Joomla\Filesystem\File::setDebug(true); // Logs operations to error log
    
  2. Check File Existence:

    • Use File::exists() (v3.2+) or Folder::exists():
      if (!File::exists($path)) {
          throw new \RuntimeException("File not found: {$path}");
      }
      
  3. Common Issues:

    • "Permission denied": Verify storage and bootstrap/cache permissions (chmod -R 775 storage bootstrap/cache).
    • "File not found": Use Path::resolve() to get absolute paths and debug with realpath().
    • "Invalid argument": Sanitize filenames with File::makeSafe() before operations.

Extension Points

  1. Custom File Validator:

    class CustomFileValidator
    {
        public static function validate(array $file, array $rules): bool
        {
            $ext = strtolower(File::getExt($file['name']));
            return in_array($ext, $rules['extensions']) &&
                   $file['size'] <= $rules['max_size'];
        }
    }
    
  2. Event Listeners for File Operations:

    // app/Providers/EventServiceProvider.php
    protected $listen = [
        'joomla.filesystem.file.created' => [
           \App\Listeners\LogFileUpload::class,
        ],
    ];
    

    Trigger events manually:

    event(new \Joomla\Filesystem\Event\FileCreated($path));
    
  3. Override Default Behavior:

    • Extend core classes (e.g., File or Folder) and bind them in Laravel’s service container:
      $this->app->bind(\Joomla\Filesystem\File::class, function ()
      
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.
nexmo/api-specification
capell-app/block-library
axium/identity
cetria/laravel-dummy-models
cetria/reflection-helper
agropredict/sso-auth-bundle
evolvestudio/spam-protection
datacore/hub-sdk
develia/commons
cuci/prototurk-sdk
cuci/prototurk-sdk-symfony
develia/geo-bundle
dreamzy/livewire-charts
touchestate-sdk/php-sdk
22h/doctrine-garbage-collection-bundle
agtp/agtp-php
agtp/mod-php
splash/sonata-admin
splash/metadata
splash/openapi