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

Sulu Media Extra Bundle Laravel Package

alengo/sulu-media-extra-bundle

Sulu CMS media utilities: sync @2x crops to base formats automatically, generate image-formats.xml entries from YAML, backfill existing @2x format options, and rename media with dry-run support.

View on GitHub
Deep Wiki
Context7

Getting Started

Minimal Steps

  1. Check version compatibility first (added in 1.1.0):

    • 1.1.0 targets Sulu 3.1+ / Symfony 8.1+.
    • On Sulu 3.0 or Symfony ≤ 8.0, pin the previous line instead:
      composer require "alengo/sulu-media-extra-bundle:^1.0"
      
    • Verify what your project can actually resolve:
      composer why-not alengo/sulu-media-extra-bundle 1.1.0
      
  2. Installation:

    composer require alengo/sulu-media-extra-bundle
    

    Register the bundle in config/bundles.php:

    Alengo\SuluMediaExtraBundle\AlengoMediaExtraBundle::class => ['all' => true],
    
  3. First Use Case:

    • Enable @2x crop sync (automatic): No action required—it activates immediately after installation.
    • Generate image formats (one-time setup):
      bin/adminconsole alengo:media:image-formats:generate
      
      Create a YAML file at config/app/image-formats.yaml (see README for format).

1.1.0 is a compatibility release: no new commands, options, or public API changes were announced. Everything below applies to ^1.0 and ^1.1 alike—only the framework floor moved.


Implementation Patterns

1. @2x Crop Synchronization

  • Workflow:
    • Define @2x formats in image-formats.xml (e.g., 800x@2x).
    • Save crops for @2x formats in the Sulu admin panel.
    • The bundle automatically mirrors crop coordinates to the base format (e.g., 800x).
  • Integration:
    • Useful for responsive designs where @1x and @2x crops must align.
    • Example: Add 800x@2x to your image-formats.xml and let the bundle handle the rest.
    • On Sulu 3.1, the crop-modified event flow is unchanged, so existing subscribers keep working after the upgrade.

2. Image Format Generation

  • Workflow:
    • Define formats in config/app/image-formats.yaml (e.g., 400x300, 800x).
    • Run the command to generate XML entries:
      bin/adminconsole alengo:media:image-formats:generate --source=config/app/image-formats.yaml
      
    • The command appends entries to config/image-formats.xml (avoids overwriting existing configs).
  • Best Practice:
    • Use this for new projects or when adding standardized formats.
    • Combine with image-format-options:duplicate if migrating existing crops.

3. Backfilling Existing Crops

  • Workflow:
    • If @2x crops exist but base formats lack crops, run:
      bin/adminconsole alengo:media:image-format-options:duplicate
      
    • Requires a YAML source file listing format keys (e.g., 800x, 400x300).
  • Use Case:
    • Post-installation cleanup for projects with pre-existing media.
    • A good first step after upgrading to 1.1.0, to confirm the crop-sync listener still writes to the expected formats on Sulu 3.1.

4. Media Renaming

  • Workflow:
    • Rename a media file (updates DB + storage):
      bin/adminconsole alengo:media:rename <mediaId> "new-name" --locale=en
      
    • Dry-run for safety:
      bin/adminconsole alengo:media:rename <mediaId> "new-name" --dry-run
      
  • Integration:
    • Useful for batch updates (e.g., correcting filenames post-upload).
    • Preserves file extensions and increments subVersion to invalidate caches.

Gotchas and Tips

Pitfalls

  1. Upgrading to 1.1.0 on an older stack:

    • The release raises the framework floor. composer update on a Sulu 3.0 / Symfony 8.0 project will either fail resolution or (worse, with loose constraints elsewhere) drag other packages forward.
    • Fix: Upgrade Sulu/Symfony first, or constrain the bundle to ^1.0. Run bin/adminconsole cache:clear and a migration check after the bump.
    • Smoke test: after upgrading, re-save one @2x crop in the admin UI and confirm the base format is still mirrored.
  2. XML Overwrite Risk:

    • The image-formats:generate command appends to image-formats.xml. If you manually edit the file, conflicts may arise.
    • Fix: Back up image-formats.xml before running the command.
  3. Locale Handling in Renaming:

    • The rename command uses --locale to normalize filenames (e.g., Ümlaut → Umlaut).
    • Tip: Always specify --locale explicitly to avoid unexpected behavior.
  4. Dry-Run Limitations:

    • The --dry-run flag shows what would change but doesn’t validate storage permissions.
    • Test: Run dry-run first, then verify storage paths manually.
  5. Circular Dependencies in Crops:

    • If base and @2x formats have conflicting crops, the bundle prioritizes @2x as the source.
    • Debug: Check me_format_options table for orphaned entries after sync.

Debugging

  • Event Listener Issues:

    • If @2x sync fails, verify the MediaCropModifiedEvent is dispatched (Sulu 3.x default, still the case in 3.1).
    • Log: Enable debug:event-dispatcher to confirm event firing.
    • After a framework upgrade, re-check that your own listeners on the same event still have the expected priority ordering relative to the bundle's subscriber.
  • Command Errors:

    • For image-formats:generate, ensure YAML is valid (use symfony/validator for testing).
    • Tip: Use --target=/tmp/test.xml to debug output before committing.
  • Dependency Conflicts:

    • Inspect the resolved set with composer show alengo/sulu-media-extra-bundle and composer why sulu/sulu when the bundle won't install on a mixed-version stack.

Extension Points

  1. Custom Format Keys:

    • The bundle assumes @2x suffixes. To support other variants (e.g., @3x), extend the MediaCropModifiedSubscriber:
      // src/EventSubscriber/CustomCropSubscriber.php
      use Alengo\SuluMediaExtraBundle\EventSubscriber\MediaCropModifiedSubscriber;
      
      class CustomCropSubscriber extends MediaCropModifiedSubscriber {
          protected function getBaseFormatKey(string $formatKey): ?string {
              if (str_ends_with($formatKey, '@3x')) {
                  return str_replace('@3x', '', $formatKey);
              }
              return parent::getBaseFormatKey($formatKey);
          }
      }
      
    • Register the subscriber in services.yaml:
      Alengo\SuluMediaExtraBundle\EventSubscriber\MediaCropModifiedSubscriber:
          tags: [kernel.event_subscriber]
          arguments:
              $subscriber: '@custom_crop_subscriber'
      
  2. Pre-Rename Validation:

    • Override the MediaRenameCommand to add custom logic (e.g., blacklist filenames):
      // src/Command/CustomMediaRenameCommand.php
      use Alengo\SuluMediaExtraBundle\Command\MediaRenameCommand;
      
      class CustomMediaRenameCommand extends MediaRenameCommand {
          protected function execute(InputInterface $input, OutputInterface $output): int {
              $newName = $input->getArgument('newName');
              if (str_contains($newName, 'blocked')) {
                  $output->writeln('<error>Filename blocked!</error>');
                  return Command::FAILURE;
              }
              return parent::execute($input, $output);
          }
      }
      
  3. Storage Path Customization:

    • The rename command uses Sulu’s default storage adapter. To support custom paths (e.g., S3), extend the MediaRenamer service:
      // src/Service/CustomMediaRenamer.php
      use Alengo\SuluMediaExtraBundle\Service\MediaRenamer;
      
      class CustomMediaRenamer extends MediaRenamer {
          public function rename(Media $media, string $newName, string $locale): void {
              // Add custom logic (e.g., S3 path handling)
              parent::rename($media, $newName, $locale);
          }
      }
      
    • Override the service in services.yaml:
      Alengo\SuluMediaExtraBundle\Service\MediaRenamer:
          class: App\Service\CustomMediaRenamer
      
    • If you extend bundle classes, keep an eye on minor-version signature changes—1.1.0 doesn't change them, but the framework major it now targets may change type hints in parent classes. Run PHPStan/Psalm after upgrading.
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.
socialdept/atp-orm
cboxdk/laravel-assistant-client
socialdept/atp-resolver
socialdept/tenant-domains
tautvydasr/blade-class-names
socialdept/color-scales
maherelgamil/controller
coleus/widgets
coleus/table
coleus/users
coleus/music
coleus/health
coleus/calendar
coleus/notes
coleus/support
coleus/settings
coleus/apps
seampact/laravel
emmyconceptng/laravel-ng-postcode
jjsquady/round-robin