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

Data Uri Laravel Package

1tomany/data-uri

Parse data URIs, base64 strings, plain text, URLs, or local files into a temporary file via an immutable value object. Auto-detect or override MIME type, set an optional display name, and the temp file is deleted automatically on destruct.

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.
sentix/ai-chatbot
terminal42/code-quality-tools
codifyo/ts-generator-bundle
testo/fiber
mintobit/jobqueue
a4sex/maintenance-bundle
a4sex/entity-date-update
a4sex/client-identifier
a4sex/base-utilites
a4sex/key-value-storage
a4sex/micro-status
chilldev/dependency-injection-extra
datinglibre/datinglibre-app-api
biberltd/corebundle
bricre/symfony-bundle-test
biberltd/logbundle
dominium/http-adapter-bundle
dominium/google-analytics
a4sex/auto-clean-entity
christhompsontldr/laravel-inky