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

Ez Image Crop Laravel Package

smarter-solutions/ez-image-crop

EZ Image Crop is a Laravel/PHP package that simplifies adding image cropping to your applications. Configure crop behavior, process uploaded images, and save cropped results with minimal setup. Ideal for avatars, thumbnails, and content images.

View on GitHub
Deep Wiki
Context7

Getting Started

Resolve what this package actually is before writing a line of code. The two supplied documents disagree, and the disagreement is the single most important fact about this package:

  • The description says "a tool that improves image cropping in eZ Publish" — that is the primary source, and it matches the package name, the maintainer namespace, and the 2016 release date.
  • description.md advertises a "lightweight Laravel/PHP package" with a chainable crop/resize/save API. That text reads like generated marketing copy and is not corroborated by any file list, composer.json, facade, service provider, or test suite in the supplied input.

Assume eZ Publish extension until proven otherwise. That means it is a legacy-PHP artifact (extension/ directory, INI settings, template operators, ezcImageConverter plumbing), not an illuminate/* package you can composer require. Budget the first hour for verification, not implementation.

Where to look first, in order:

  1. Repository root tree. Look for extension.xml, settings/*.ini.append.php, autoloads/, classes/, design/standard/templates/, bin/php/. Presence of these confirms eZ Publish. Look for composer.json and a src/ PSR-4 tree; absence of both confirms it is not a Laravel package regardless of the description.
  2. Target eZ version. eZ Publish 4.x (legacy, PHP 5.x) versus 5.x legacy versus eZ Platform (Symfony-based) changes every integration detail. extension.xml version constraints and any ezpublish/ezsystems string in the code will tell you.
  3. The actual cropping entry point. Grep for imagecreatefrom, Imagick, crop, offset, and image alias names. That file is the package. Everything else is glue.
  4. The changelog / commit log. Last release 2016-12-21. Read the trailing commits to see whether it was abandoned mid-refactor.

Minimal enabling steps (eZ Publish 4.x/5.x legacy shape):

  1. Drop the repo into extension/ez_image_crop/ (or whatever the extension directory name is in extension.xml).

  2. Register it in settings/override/site.ini.append.php:

    [ExtensionSettings]
    ActiveExtensions[]=ez_image_crop
    
  3. Clear the INI cache: php bin/php/ezcache.php --clear-all (or Setup → Cache → Clear all caches in admin).

  4. Regenerate image aliases — a cache clear alone does not rebuild existing derivative files in var/<site>/storage/images/.

  5. Reload a page that renders a cropped alias and confirm the output file's mtime changed.

First use case worth pursuing: listing pages and card components where the default eZ image alias uses a naive scale/crop filter and decapitates portraits or clips product shots. That is the exact pain this package addresses and the only justification for adopting it.

If you are actually on Laravel: stop here. Do not try to load this into a Laravel app. If you want the cropping math, copy the coordinate calculation into a service class and drive it with Intervention Image or a direct Imagick wrapper — both are maintained, PHP 8-compatible, and testable.

Implementation Patterns

Pattern 1 — alias-level crop (preferred). Keep cropping declarative so designers and template authors get it without touching PHP. Override the alias in settings/override/image.ini.append.php:

[<alias_name>]
Filters[]=geometry/scale=640;480
Filters[]=geometry/crop=600;400;20;40

Ship this file in the consuming site's settings/override/, not inside the extension, so upgrades to the extension (however unlikely) do not clobber site config. The crop filter's last two arguments are the X/Y offsets — this is where the package's "improvement" usually sits.

Pattern 2 — runtime crop from stored metadata. When crop offsets are per-content-object rather than per-alias (focal point chosen in admin, or a user-dragged crop box), the workflow is: read the stored offset/size, hand width/height/X/Y to the package's crop routine, write to a deterministic path under var/<site>/storage/images/, then serve that path from the template. Cache the path in the datatype attribute or a custom table — recomputing per request is the classic performance trap here.

Pattern 3 — chaining and saving. The useful idiom the description hints at is crop → resize → save with an explicit destination:

$image = new <PackageClass>('/path/to/original.jpg');
$image->crop($width, $height, $offsetX, $offsetY)
      ->resize($targetWidth, $targetHeight)
      ->save('/path/to/var/cache/derivative.jpg');

Two non-negotiables: always read from the original stored image, never from a previously generated derivative (crop-of-a-crop compounds rounding error and loses quality), and always write to a var/ path so cache clears can reclaim it.

Pattern 4 — upload pipeline hook. If cropping must happen at upload time, hook the eZImage datatype's post-store path (eZImageManager / datatype onPublish) rather than the controller. Doing it in the controller means imports, API uploads, and admin edits all bypass your crop. Verify the hook fires on multi-upload and on content-object translations.

Pattern 5 — hybrid estates. If a Laravel app reads assets from a legacy eZ site (shared filesystem, S3 bucket, or an internal HTTP endpoint), do not import this extension into the Laravel app. Treat the legacy site as the crop authority: it writes derivatives to the shared store under a versioned path, Laravel just serves URLs. Encode the path convention (/images/<content_id>/<alias>/<hash>.jpg) once and test both sides against it.

Config discipline. Commit every .ini.append.php you write. Keep package keys under a single INI section and namespace, and record the package commit SHA in a comment at the top of the file — with a 2016 package and no changelog, "which version of this code produced this alias" is a question you will ask.

Gotchas and Tips

It is almost certainly abandoned, and that is the headline. Two stars, last release December 2016, no Packagist profile in the supplied input, and no security disclosure channel. Treat it as vendored source you now own: pin by commit SHA, fork into your own namespace, and assume zero upstream fixes. If your PHP runtime is 7.4+ or 8.x, expect each(), create_function, non-nullable-parameter, and dynamic-property breakage in a 2016 codebase — a smoke test that merely instantiates the crop class will catch most of it.

The Laravel claim is the biggest trap. A developer skimming the description will composer require smarter-solutions/ez-image-crop, get a 404 or an unrelated package, and lose an afternoon. Verify the identity first; do not let the marketing copy set your plan.

Alias caching will waste your first day. eZ Publish caches both the parsed INI and the generated image files. Symptom: you edit image.ini.append.php, clear the INI cache, reload, and see the old crop. Causes, in order of likelihood:

  1. The derivative file still exists in var/<site>/storage/images/ — delete it or run alias regeneration.
  2. The override file is in settings/override/ but an image.ini.append.php in settings/siteaccess/<name>/ takes precedence — check precedence order for the active siteaccess.
  3. You changed the alias definition but kept the same alias name, and a template is reading a cached $node.data_map.image.content.<alias> array.

Debug by stat-ing the output file for mtime, not by eyeballing the rendered page.

INI merge semantics bite silently. Key[]=value appends to an array; Key=value replaces a scalar and wipes the default. Replacing a whole Filters[] chain without re-declaring every prior filter drops them without error. Always re-publish the full chain when overriding.

Offsets are relative to the original stored image, not the displayed size. A focal point computed on a 300px preview must be scaled to the original's dimensions before it becomes an offset, or crops land in the wrong place on high-resolution originals. Store offsets as fractions of original width/height, not pixels.

EXIF orientation is the classic hidden bug. Phone uploads carry an orientation tag; GD ignores it, Imagick may or may not auto-orient depending on settings. You get sideways crops that look correct in the file viewer. Normalize orientation at upload, before any crop math runs.

GD vs Imagick is not cosmetic. GD loses PNG transparency under some operations, has different resampling quality, and loads the whole decoded image into memory (memory_limit fatals on large JPEGs). Imagick is heavier but predictable. Whichever the package selects, pin it explicitly rather than relying on auto-detection — the same alias rendering differently on two servers is an impossible-to-reproduce bug report.

Permissions and paths. var/ must be writable by the PHP user; open_basedir and SELinux contexts on storage/images/ fail with an unhelpful blank image. Log the exact destination path and the error_get_last() output when a save fails — the package likely swallows it.

Extension load order matters. If the extension depends on another (custom datatype, image handler), list it after its dependency in ActiveExtensions[]. Wrong order produces "class not found" at runtime only, not at cache clear.

Write your own tests; there are none. A single assertion is enough to protect you: given a known input image and known offsets, the saved output has exactly the expected pixel dimensions and the expected average color in each quadrant. That catches coordinate-inversion (x,y swapped — extremely common), off-by-one offsets, and a silently-skipped crop.

Extension points to prefer if you must modify: override the image alias INI rather than editing extension PHP; subclass the crop class rather than patching it; add a template operator/fetch function rather than editing templates. Every line you patch inside the vendored package is a line you re-merge by hand — with no upstream, "re-merge" means "remember why you did this in 18 months."

Exit criteria. If the repo turns out to be a genuine illuminate/* package after all, stop and re-run the evaluation properly: composer why-not against your Laravel line, a published namespaced config, a facade-versus-contracts decision, and call-site inventory across services. The description alone is not evidence of any of that.

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.
shitoudev/permissionmanager
johannesclimacus/laravel-tui
hocvt/seotools
vitalybaev/sypexgeo
amphibee/themosis-ignition
gito-me/fast-excel
frankyso/laravel-ipaymu
geolize-studio/laravel-chile
boomerangui/chat
jinas/dhivatar
store-doc/laravel-storage-driver
plus-it/laravel-translation-manager
diephp/perhaps
diephp/telegraph
osmaviation/spreadsheet
microsoft/fluentui-system-icons
mmccook/php-json-canonicalization-scheme
middlewares/firewall
qubiqx/montapacking
nyoncode/laravel-package-console