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

Glide Bundle Laravel Package

ashleydawson/glide-bundle

View on GitHub
Deep Wiki
Context7

Getting Started

Minimal Setup

  1. Installation:

    composer require ashleydawson/glide-bundle
    

    Register the bundle in config/bundles.php (Symfony 4+) or app/AppKernel.php (Symfony 2/3):

    AshleyDawson\GlideBundle\AshleyDawsonGlideBundle::class => ['all' => true],
    
  2. Configure Filesystems: Define source (original images) and cache (processed images) filesystems in config/packages/ashley_dawson_glide.yaml:

    ashley_dawson_glide:
        source_filesystem: 'oneup_flysystem.local_filesystem.source'
        cache_filesystem: 'oneup_flysystem.local_filesystem.cache'
    

    Use OneupFlysystemBundle for filesystem management.

  3. First Use Case: Create a controller to serve processed images:

    use Symfony\Component\HttpFoundation\Request;
    use Symfony\Component\Routing\Annotation\Route;
    
    class ImageController extends AbstractController
    {
        #[Route('/images/{filename}', name: 'glide_image')]
        public function show(Request $request, string $filename): Response
        {
            return $this->get('ashleydawson.glide.server_factory')
                ->create($this->get('oneup_flysystem.local_filesystem.source'))
                ->getImageResponse($filename, $request->query->all());
        }
    }
    

    Access images via URL: /images/photo.jpg?w=300&h=200.


Implementation Patterns

Core Workflow

  1. Request Handling: Use query parameters to define transformations (e.g., ?w=300&h=200&fit=crop). GlideBundle automatically parses these into manipulators.

  2. Filesystem Integration:

    • Source: Store originals in a filesystem (e.g., local, s3).
    • Cache: Configure a dedicated filesystem for processed images (e.g., Symfony’s cache dir or local filesystem).
    • Example with S3:
      ashley_dawson_glide:
          source_filesystem: 'aws_s3.source'
          cache_filesystem: 'aws_s3.cache'
      
  3. Controller Abstraction: Reuse the GlideServerFactory service to avoid repetition:

    $glideServer = $this->get('ashleydawson.glide.server_factory')
        ->create($sourceFs, $cacheFs);
    return $glideServer->getImageResponse($filename, $queryParams);
    
  4. Dynamic Routes: Use Symfony’s routing to handle dynamic filenames:

    # config/routes.yaml
    glide_images:
        path: /images/{filename}
        controller: App\Controller\ImageController::show
        defaults:
            filename: null
    

Advanced Patterns

  1. Custom Manipulators: Extend functionality by creating custom manipulators (e.g., watermarks, filters):

    // src/Glide/Manipulator/WatermarkManipulator.php
    class WatermarkManipulator implements ManipulatorInterface
    {
        public function run(Request $request, Image $image)
        {
            if ($request->query->has('watermark')) {
                $watermark = $this->getWatermarkImage();
                $image->insert($watermark, 'bottom-right', 10, 10);
            }
            return $image;
        }
    }
    

    Register in services.yaml:

    services:
        App\Glide\Manipulator\WatermarkManipulator:
            tags:
                - { name: ashleydawson.glide.manipulators }
    
  2. Middleware for Security: Validate filenames and query parameters to prevent path traversal:

    #[Route('/images/{filename}', name: 'glide_image')]
    public function show(Request $request, string $filename): Response
    {
        if (!preg_match('/^[a-z0-9\-_]+$/i', $filename)) {
            throw $this->createAccessDeniedException();
        }
        // Proceed with Glide processing
    }
    
  3. Caching Strategies:

    • Cache Filesystem: Use a fast filesystem (e.g., local or memory) for cache.
    • HTTP Caching: Leverage Symfony’s HttpCache or Varnish for edge caching:
      framework:
          http_cache:
              cache_control:
                  rules:
                      - path: ^/images/
                        headers:
                            Cache-Control: 'public, max-age=31536000'
      
  4. Batch Processing: Pre-generate thumbnails for performance:

    $glideServer = $this->get('ashleydawson.glide.server_factory')
        ->create($sourceFs, $cacheFs);
    $glideServer->getImageResponse('photo.jpg', ['w' => 800, 'h' => 600]); // Pre-cache
    

Gotchas and Tips

Common Pitfalls

  1. Filesystem Permissions:

    • Ensure the cache filesystem is writable by the web server user.
    • For local filesystems, set permissions:
      chmod -R 775 var/cache/glide
      
  2. Query Parameter Conflicts:

    • Glide uses ?w, ?h, ?fit, etc. Avoid naming your routes or query params similarly to prevent conflicts.
    • Example: Use ?thumbnail=true instead of ?w=100 if you want to trigger a custom manipulator.
  3. Deprecated Symfony Versions:

    • The bundle supports Symfony 3/4 but may have edge cases with older versions (e.g., app/cache vs. var/cache).
    • For Symfony 5+, consider using league/glide-symfony directly.
  4. Memory Limits:

    • Large images may hit PHP’s memory_limit. Increase it temporarily:
      ini_set('memory_limit', '512M');
      
    • Use ?fit=crop or ?resize to reduce memory usage.
  5. Cache Invalidation:

    • Deleting files from the source filesystem won’t invalidate cached versions. Manually clear the cache:
      php bin/console cache:clear
      
    • Or implement a custom cache invalidation listener.

Debugging Tips

  1. Check Filesystem Contents: Verify files exist in the source and cache directories:

    ls var/cache/glide/
    ls path/to/source/
    
  2. Enable Glide Debugging: Temporarily disable caching to test live processing:

    ashley_dawson_glide:
        cache_filesystem: null # Disables caching
    
  3. Log Manipulator Execution: Add debug logs to custom manipulators:

    public function run(Request $request, Image $image)
    {
        $this->container->get('logger')->debug('Running custom manipulator', [
            'query' => $request->query->all(),
        ]);
        // ...
    }
    
  4. Validate Query Parameters: Use Glide’s built-in validation or add your own:

    $query = $request->query->all();
    if (!isset($query['w']) || !is_numeric($query['w'])) {
        throw new \InvalidArgumentException('Width must be a number');
    }
    

Extension Points

  1. Custom Server Factories: Extend the GlideServerFactory to add default manipulators or configurations:

    class CustomGlideServerFactory extends GlideServerFactory
    {
        public function create(Filesystem $sourceFs, Filesystem $cacheFs = null)
        {
            $server = parent::create($sourceFs, $cacheFs);
            $server->addManipulator(new MyCustomManipulator());
            return $server;
        }
    }
    

    Register in services.yaml:

    services:
        ashleydawson.glide.server_factory:
            class: App\Glide\CustomGlideServerFactory
    
  2. Event Listeners: Hook into Glide events (e.g., glide.image.processed) to log or analyze processed images:

    use League\Glide\Events\ImageProcessed;
    
    class GlideListener
    {
        public function onImageProcessed(ImageProcessed $event)
        {
            $this->logger->info('Image processed', [
                'path' => $event->getPath(),
                'query' => $event->getQuery(),
            ]);
        }
    }
    

    Register as a service with the kernel.event_listener tag.

  3. Dynamic Filesystem Configuration: Use environment variables or config files to switch filesystems dynamically

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.
terminal42/code-quality-tools
codifyo/ts-generator-bundle
andydefer/laravel-cluster
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