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

Data Uri Laravel Package

1tomany/data-uri

Convert data URIs, base64 strings, files, and HTTP/HTTPS URLs into temporary file value objects. The decoder infers MIME types and filenames, supports custom names and types, and auto-deletes temporary files when destroyed.

View on GitHub
Deep Wiki
Context7

Getting Started

Minimal Setup

  1. Install the package:

    composer require 1tomany/data-uri
    
  2. Basic usage (decode a data URI):

    use OneToMany\DataUri\DataDecoder;
    
    $dataUri = 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAA...';
    $file = DataDecoder::decode($dataUri);
    
    // Access file properties
    echo $file->getName();       // e.g., 'image.png'
    echo $file->getFormat();     // e.g., 'image/png'
    $content = $file->getContent(); // Binary content
    
  3. First use case: Handle base64-encoded images from a frontend API:

    $requestData = $request->json()->all();
    $imageData = $requestData['image']; // Base64 string
    $file = DataDecoder::decodeBase64($imageData, 'image/png', 'user-upload.png');
    Storage::put('uploads/' . $file->getName(), $file->getContent());
    

Where to Look First

  • API Overview: Focus on DataDecoder::decode() for versatility (handles URIs, URLs, and files).
  • Examples: Check decode.php for practical patterns.
  • Interface: Explore DataUriInterface methods (getName(), getContent(), getStream()) for integration.

Implementation Patterns

Core Workflows

1. Data URI Handling in API Responses

// Decode a data URI from an API payload (e.g., Slack message attachments)
$attachment = $response['files'][0];
$dataUri = $attachment['file']['url_private'] ?? $attachment['file']['url'];
$file = DataDecoder::decode($dataUri, null, 'image.jpg');

// Save to Laravel storage
Storage::disk('public')->put('attachments/' . $file->getName(), $file->getContent());

2. Rich Text Editor Integration

// Process pasted data URIs from TinyMCE/CKEditor
$htmlContent = $request->input('content');
preg_match_all('/data:image\/(?<type>\w+);base64,(?<data>[^"]+)/', $htmlContent, $matches);

foreach ($matches['data'] as $index => $base64Data) {
    $file = DataDecoder::decodeBase64($base64Data, 'image/' . $matches['type'][$index]);
    $uploadedPath = Storage::disk('public')->putFileAs(
        'editor-uploads',
        new \Illuminate\Http\File($file->getStream()),
        $file->getName()
    );
    $htmlContent = str_replace($matches[0][$index], asset('storage/' . $uploadedPath), $htmlContent);
}

3. Background Job for Async Processing

// Job: ProcessDataUriJob
public function handle() {
    $dataUri = $this->dataUri;
    $file = DataDecoder::decode($dataUri);

    // Process file (e.g., OCR, thumbnail generation)
    $processed = $this->processFile($file);

    // Save metadata
    Metadata::create([
        'original_name' => $file->getClientName(),
        'mime_type' => $file->getFormat(),
        'processed_data' => $processed,
    ]);
}

4. Streaming Remote Files

// Download and process a remote file without full download
$remoteUrl = 'https://example.com/large-file.zip';
$file = DataDecoder::decode($remoteUrl, null, 'archive.zip');

// Stream to a zip library for extraction
$zip = new \ZipArchive();
$zip->openFromString($file->getContent());

Laravel-Specific Patterns

Wrapping in a Service Class

// app/Services/DataUriService.php
class DataUriService {
    public function decodeAndStore(string $dataUri, string $disk = 'public'): string {
        $file = DataDecoder::decode($dataUri);
        return Storage::disk($disk)->putFileAs(
            'data-uri-uploads',
            new \Illuminate\Http\File($file->getStream()),
            $file->getName()
        );
    }
}

Validation Middleware

// app/Http/Middleware/ValidateDataUri.php
public function handle($request, Closure $next) {
    $dataUri = $request->input('data_uri');
    try {
        $file = DataDecoder::decode($dataUri);
        if (!in_array($file->getFormat(), ['image/jpeg', 'image/png'])) {
            abort(400, 'Unsupported MIME type');
        }
    } catch (\Exception $e) {
        abort(400, 'Invalid data URI');
    }
    return $next($request);
}

Filesystem Adapter Integration

// app/Providers/AppServiceProvider.php
public function register() {
    $this->app->bind(\League\Flysystem\Filesystem::class, function () {
        $adapter = new \League\Flysystem\Local\LocalFilesystemAdapter(
            storage_path('app/data-uri-cache')
        );
        return new \League\Flysystem\Filesystem($adapter);
    });
}

// Usage in a controller
$filesystem = app(\League\Flysystem\Filesystem::class);
$file = DataDecoder::decode($dataUri);
$filesystem->writeStream($file->getName(), $file->getStream());

Gotchas and Tips

Pitfalls

  1. Auto-Deletion Behavior:

    • Files are automatically deleted when the DataUriInterface object is destroyed or garbage collected.
    • Workaround: Clone the object or store the content separately if you need the file longer than the current request.
      $file = DataDecoder::decode($dataUri);
      $content = $file->getContent(); // Store this if you need persistence
      
  2. MIME Type Auto-Detection:

    • mime_content_type() may return generic types (e.g., text/plain for .md files).
    • Tip: Always specify the type parameter when possible for accuracy.
      $file = DataDecoder::decode($dataUri, null, 'document.md', 'text/markdown');
      
  3. Large File Handling:

    • Streaming is efficient, but memory limits (memory_limit) may still be hit for very large data URIs.
    • Tip: Use decodeBase64() for large base64 strings and process in chunks if needed.
  4. URL Validation:

    • The package does not validate remote URLs (e.g., HTTPS, rate limiting).
    • Tip: Pre-validate URLs with Guzzle or Laravel’s Http client before passing to DataDecoder.
      use Illuminate\Support\Facades\Http;
      
      $response = Http::get($url);
      if ($response->successful()) {
          $file = DataDecoder::decode($response->body());
      }
      
  5. Filename Preservation:

    • The name parameter is optional and may fall back to a random name.
    • Tip: Extract filenames from URLs or data URIs explicitly:
      $name = parse_url($dataUri, PHP_URL_HOST) ? basename(parse_url($dataUri, PHP_URL_PATH)) : null;
      $file = DataDecoder::decode($dataUri, $name);
      
  6. Stringable Objects:

    • The package may fail on objects implementing \Stringable (e.g., Laravel’s HtmlString).
    • Tip: Convert to string explicitly:
      $stringableObj = new \Illuminate\Support\HtmlString('<div>...</div>');
      $file = DataDecoder::decode((string) $stringableObj);
      

Debugging Tips

  1. Check File Content:

    • Verify the decoded content matches expectations:
      $file = DataDecoder::decode($dataUri);
      file_put_contents('debug-' . $file->getName(), $file->getContent());
      
  2. Log MIME Types:

    • Log detected MIME types to debug auto-detection issues:
      $file = DataDecoder::decode($dataUri);
      logger()->debug('Detected MIME type', ['type' => $file->getFormat()]);
      
  3. Handle Exceptions:

    • Wrap calls in try-catch blocks to handle malformed URIs:
      try {
          $file = DataDecoder::decode($dataUri);
      } catch (\InvalidArgumentException $e) {
          logger()->error('Invalid data URI', ['uri' => $dataUri, 'error' => $e->getMessage()]);
          abort(400, 'Invalid data URI');
      }
      

Extension Points

  1. Custom MIME Types:
    • Extend the FileType enum (if needed) or override M
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.
htinlynn/genius-helper
maco-studios/hephaestus
elmogy/larafast
xeviant/laravel-paystack
gorilladash/laravel-website-sdk
martialbe/flysystem-oss
chondal/3312client
jeroen-g/flickr
opscale-co/nova-genbi
itsjustvita/laravel-retention
tequilarapido/trackit
gregsphotography/site-builder-filament
cabaoctavio/laravel-query-log
gregsphotography/site-builder-components
io-digital/clickatell
snowsoft/laravel-admin
oxygen/auth
relicsoftware/barakah-payment-gateway
tobya/work-with-composer
equipc/laravel-email-validator