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

Media Storage Client Bundle Laravel Package

avtonom/media-storage-client-bundle

View on GitHub
Deep Wiki
Context7

Getting Started

Minimal Setup

  1. Installation

    composer require avtonom/media-storage-client-bundle:~1.2
    

    Replace ~1.2 with the latest stable version.

  2. Register the Bundle Add to config/bundles.php (Symfony 4+) or app/AppKernel.php (Symfony 3):

    return [
        // ...
        Avtonom\MediaStorageClientBundle\AvtonomMediaStorageClientBundle::class => ['all' => true],
        Sensio\Bundle\BuzzBundle\SensioBuzzBundle::class => ['all' => true],
    ];
    
  3. Basic Configuration Define remote storage endpoints in config/packages/avtonom_media_storage_client.yaml:

    avtonom_media_storage_client:
        clients:
            sonata_media_client:
                base_url: "https://your-sonata-media-server.com"
                add_media_url: "/api/media/upload"
        urls:
            get_media_by_reference_full_url: "/api/media/referencefull"
    
  4. First Use Case Upload a file via a controller:

    use Symfony\Component\HttpFoundation\File\UploadedFile;
    
    public function uploadFile(UploadedFile $file)
    {
        $proxyMedia = $this->get('avtonom.media_storage_client.manager')
            ->sendFile($file, 'sonata_media_client', 'default_context');
    
        return new JsonResponse(['media' => $proxyMedia->toArray()]);
    }
    

Implementation Patterns

Common Workflows

  1. File Upload via API

    • Use the sendFile() method in controllers or services:
      $proxyMedia = $this->mediaStorageClient->sendFile(
          $uploadedFile,
          'client_name_from_config',
          'optional_context'
      );
      
    • Handle the response (e.g., store the mediaReferenceFull in your entity).
  2. Entity Listeners for Automatic Uploads

    • Configure a Doctrine listener to auto-upload files when entities are persisted/updated:
      services:
          avtonom.media_storage_client.listener:
              class: Avtonom\MediaStorageClientBundle\EventListener\ObjectAddFileListener
              arguments:
                  - '@avtonom.media_storage_client.manager'
                  - '%avtonom.media_storage_client.listener%'
              tags:
                  - { name: doctrine.event_listener, event: prePersist, method: run }
                  - { name: doctrine.event_listener, event: preUpdate, method: run }
      
    • Define listener rules in config/packages/avtonom_media_storage_client.yaml:
      listener:
          interfaces: ['App\Entity\Product', 'App\Entity\Article']
          change_field: 'imageFile'  # Field to trigger upload
          client: 'sonata_media_client'
      
  3. Frontend Integration

    • Use the provided Twig blocks for file upload buttons and references:
      {% include '@AvtonomMediaStorageClient/standard_layout.html.twig' %}
      
    • Customize the upload button:
      <input type="file"
             name="file"
             class="file-upload"
             data-url="{{ path('app.upload', {'client': 'sonata_media_client'}) }}">
      
  4. Fetching Media Metadata

    • Retrieve remote media details using the getMediaByReferenceFull service:
      $media = $this->get('avtonom.media_storage_client.manager')
          ->getMediaByReferenceFull($referenceFullUrl);
      

Integration Tips

  1. Symfony Forms

    • Create a custom form type to handle file uploads:
      use Avtonom\MediaStorageClientBundle\Form\Type\MediaType;
      
      $builder->add('media', MediaType::class, [
          'client' => 'sonata_media_client',
          'context' => 'product_images',
      ]);
      
  2. Validation

    • Validate file types/sizes before upload:
      if (!$file->isValid()) {
          throw new \RuntimeException('Invalid file upload.');
      }
      
  3. Context-Based Uploads

    • Use contexts to route files to different SonataMedia providers:
      clients:
          sonata_media_client:
              base_url: "https://media-server.com"
              contexts:
                  thumbnail: "/api/media/thumbnail"
                  original: "/api/media/original"
      
  4. Error Handling

    • Wrap upload logic in try-catch blocks:
      try {
          $proxyMedia = $this->mediaStorageClient->sendFile($file, 'client_name');
      } catch (\Exception $e) {
          $this->addFlash('error', 'Upload failed: ' . $e->getMessage());
      }
      

Gotchas and Tips

Pitfalls

  1. CORS Issues

    • If the frontend and backend are on different domains, ensure the SonataMedia server has CORS headers configured:
      Access-Control-Allow-Origin: *
      Access-Control-Allow-Methods: POST, GET, OPTIONS
      
  2. File Size Limits

    • The bundle relies on Symfony’s max_file_size (php.ini) and client_max_body_size (Nginx/Apache). Adjust these if uploads fail silently.
  3. Listener Overhead

    • Doctrine listeners trigger on every prePersist/preUpdate. For large datasets, this can impact performance. Use selectively.
  4. Reference Full URL Mismatch

    • If mediaReferenceFull doesn’t match the remote server’s expected format, uploads will fail. Verify the get_media_by_reference_full_url endpoint returns the correct structure.
  5. Deprecated BuzzBundle

    • The bundle depends on sensio/buzz-bundle (v1.x), which is unmaintained. Monitor for HTTP client deprecation warnings.

Debugging

  1. Enable Logging

    • Set logging_level to DEBUG (100) in config to trace HTTP requests:
      logging_level: 100
      
    • Check logs for errors like:
      [Buzz\Exception\CurlException] cURL error 6: Could not resolve host (see http://curl.haxx.se/libcurl/c/libcurl-errors.html)
      
  2. Validate Endpoints

    • Test the remote API endpoints manually (e.g., curl -X POST -F file=@test.jpg http://sonata-media-server/api/media/upload).
  3. ProxyMediaInterface Issues

    • If media_get() returns ERROR: file not found, verify:
      • The mediaReferenceFull URL is correct.
      • The remote server’s getMediaByReferenceFull endpoint is accessible.

Extension Points

  1. Custom HTTP Client

    • Override the default Buzz client by binding your own service:
      services:
          avtonom.media_storage_client.http_client:
              class: Symfony\Contracts\HttpClient\HttpClientInterface
              factory: ['Symfony\Component\HttpClient\HttpClient', 'create']
              tags: ['avtonom.media_storage_client.http_client']
      
  2. Pre/Post Upload Hooks

    • Extend the ObjectAddFileListener to add logic before/after uploads:
      class CustomAddFileListener extends ObjectAddFileListener
      {
          public function run($entity, $eventName)
          {
              // Pre-upload logic
              $result = parent::run($entity, $eventName);
      
              // Post-upload logic
              return $result;
          }
      }
      
  3. Custom Media Metadata

    • Extend the ProxyMediaInterface to include additional fields (e.g., altText, copyright):
      class CustomProxyMedia implements ProxyMediaInterface
      {
          private $altText;
      
          public function setAltText(string $altText): void
          {
              $this->altText = $altText;
          }
      
          public function getAltText(): ?string
          {
              return $this->altText;
          }
      }
      
  4. Multi-Part Uploads

    • For large files, implement chunked uploads by extending the sendFile method:
      public function sendFileInChunks(UploadedFile $file, string $clientName, string $context = null)
      {
          $chunkSize = 5 * 1024 * 1024; // 5MB
          $stream = $file->openFile();
          $offset = 0;
      
          while (!$stream->eof()) {
              $chunk = $stream->read($chunkSize);
              $this->sendChunk($chunk, $clientName, $context, $offset);
              $offset += strlen($chunk);
          }
      }
      
  5. Fallback for Offline Mode

    • Implement a local storage fallback when the remote server is unavailable:
      try {
          $proxyMedia = $this->mediaStorageClient->sendFile($file, 'sonata_media_client');
      } catch (\Exception $e) {
          $proxyMedia = $this->localStorage->store($file);
      }
      
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.
comsave/common
alecsammon/php-raml-parser
chrome-php/wrench
lendable/composer-license-checker
typhoon/reflection
mesilov/moneyphp-percentage
mike42/gfx-php
bookdown/themes
aura/view
aura/html
aura/cli
povils/phpmnd
nayjest/manipulator
omnipay/tests
psr-mock/http-message-implementation
psr-mock/http-factory-implementation
psr-mock/http-client-implementation
voku/email-check
voku/urlify
rtheunissen/guzzle-log-middleware