├── src ├── Profile.php ├── Facades │ └── Gravatar.php ├── Enum │ └── PresetKey.php ├── helpers.php ├── ServiceProvider.php ├── Casts │ ├── GravatarProfile.php │ └── GravatarImage.php ├── Gravatar.php └── Image.php ├── LICENSE ├── composer.json ├── docs ├── installation.md ├── configuration.md ├── index.md ├── usage.md ├── casts.md ├── enums.md ├── parameters.md ├── advanced.md └── presets.md ├── README.md ├── config └── gravatar.php ├── CHANGELOG.md └── UPGRADE.md /src/Profile.php: -------------------------------------------------------------------------------- 1 | 26 | */ 27 | public static function values(): array 28 | { 29 | return array_column(self::cases(), 'value'); 30 | } 31 | 32 | /** 33 | * Check if a given key is valid. 34 | * 35 | * @param string $key The key to validate 36 | */ 37 | public static function isValid(string $key): bool 38 | { 39 | return \in_array($key, self::values(), true); 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2017 Vincent Garnier 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /src/helpers.php: -------------------------------------------------------------------------------- 1 | image($email, $presetName); 19 | } 20 | } 21 | 22 | if (! function_exists('gravatar_profile')) { 23 | /** 24 | * Return a new Gravatar Profile instance. 25 | * 26 | * @param string|null $email The email address to generate the profile for 27 | * @param string|null $format Optional format (json, xml, php, vcf, qr) 28 | * @return Profile The configured Gravatar profile instance 29 | */ 30 | function gravatar_profile(?string $email = null, ?string $format = null): Profile 31 | { 32 | return app('gravatar')->profile($email, $format); 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /src/ServiceProvider.php: -------------------------------------------------------------------------------- 1 | mergeConfigFrom(__DIR__.'/../config/gravatar.php', 'gravatar'); 24 | 25 | $this->app->singleton('gravatar', fn ($app): Gravatar => new Gravatar($app['config']['gravatar'])); 26 | } 27 | 28 | /** 29 | * Bootstrap the Gravatar service. 30 | * 31 | * Publishes configuration file when running in console. 32 | */ 33 | public function boot(): void 34 | { 35 | if ($this->app->runningInConsole()) { 36 | $this->publishes([ 37 | __DIR__.'/../config/gravatar.php' => $this->app->configPath('gravatar.php'), 38 | ], 'gravatar-config'); 39 | } 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /composer.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "forxer/laravel-gravatar", 3 | "description": "A library providing easy gravatar integration in a Laravel project.", 4 | "homepage": "https://github.com/forxer/laravel-gravatar", 5 | "keywords": [ 6 | "gravatar", 7 | "laravel" 8 | ], 9 | "type": "library", 10 | "license": "MIT", 11 | "authors": [ 12 | { 13 | "name": "Vincent Garnier", 14 | "email": "forxer@gmail.org" 15 | } 16 | ], 17 | "support": { 18 | "issues": "https://github.com/forxer/laravel-gravatar/issues", 19 | "email": "forxer@gmail.com" 20 | }, 21 | "require": { 22 | "php": "^8.4", 23 | "laravel/framework": "^12.0", 24 | "forxer/gravatar": "^6.0" 25 | }, 26 | "require-dev": { 27 | "laravel/pint": "^1.25.1", 28 | "driftingly/rector-laravel": "^2.1.3", 29 | "rector/rector": "^2.2.8" 30 | }, 31 | "autoload": { 32 | "psr-4": { 33 | "LaravelGravatar\\": "src" 34 | }, 35 | "files": [ 36 | "src/helpers.php" 37 | ] 38 | }, 39 | "config": { 40 | "preferred-install": "dist", 41 | "sort-packages": true 42 | }, 43 | "minimum-stability": "dev", 44 | "prefer-stable": true, 45 | "extra": { 46 | "laravel": { 47 | "providers": [ 48 | "LaravelGravatar\\ServiceProvider" 49 | ], 50 | "aliases": { 51 | "Gravatar": "LaravelGravatar\\Facades\\Gravatar" 52 | } 53 | } 54 | } 55 | } 56 | -------------------------------------------------------------------------------- /src/Casts/GravatarProfile.php: -------------------------------------------------------------------------------- 1 | $attributes All model attributes 26 | * @return Profile The configured Gravatar profile instance 27 | * 28 | * @throws BindingResolutionException When the service container cannot resolve the binding 29 | */ 30 | public function get(Model $model, string $key, mixed $value, array $attributes): Profile 31 | { 32 | return app('gravatar')->profile($value); 33 | } 34 | 35 | /** 36 | * Prepare the value for storage (returns the value unchanged). 37 | * 38 | * @param Model $model The model instance 39 | * @param string $key The attribute key 40 | * @param mixed $value The value to store 41 | * @param array $attributes All model attributes 42 | * @return mixed The value to be stored in the database 43 | */ 44 | public function set(Model $model, string $key, mixed $value, array $attributes): mixed 45 | { 46 | return $value; 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /src/Casts/GravatarImage.php: -------------------------------------------------------------------------------- 1 | $attributes All model attributes 32 | * @return Image The configured Gravatar image instance 33 | */ 34 | public function get(Model $model, string $key, mixed $value, array $attributes): Image 35 | { 36 | return app('gravatar') 37 | ->image($value) 38 | ->setPreset($this->presetName); 39 | } 40 | 41 | /** 42 | * Prepare the value for storage (returns the value unchanged). 43 | * 44 | * @param Model $model The model instance 45 | * @param string $key The attribute key 46 | * @param mixed $value The value to store 47 | * @param array $attributes All model attributes 48 | * @return mixed The value to be stored in the database 49 | */ 50 | public function set(Model $model, string $key, mixed $value, array $attributes): mixed 51 | { 52 | return $value; 53 | } 54 | } 55 | -------------------------------------------------------------------------------- /docs/installation.md: -------------------------------------------------------------------------------- 1 | Installation 2 | ============ 3 | 4 | ## Requirements 5 | 6 | - PHP 8.4 or newer 7 | - Laravel 12.0 or newer 8 | 9 | For older PHP or Laravel versions, please refer to previous package versions: 10 | - [Version 4.x](https://github.com/forxer/laravel-gravatar/tree/4.x) for PHP 8.2+ and Laravel 10-12 11 | - [Version 2.x](https://github.com/forxer/laravel-gravatar/tree/2.x) for PHP 8.0+ and Laravel 8-9 12 | 13 | ## Installation via Composer 14 | 15 | Install the package using Composer: 16 | 17 | ```bash 18 | composer require forxer/laravel-gravatar 19 | ``` 20 | 21 | ## Service Provider Registration 22 | 23 | The package uses Laravel's auto-discovery feature, so the service provider and facade are automatically registered. You don't need to manually add them to your `config/app.php`. 24 | 25 | ## Configuration File (Optional) 26 | 27 | The package works out of the box without any configuration. However, if you want to customize default settings or define presets, you can publish the configuration file: 28 | 29 | ```bash 30 | php artisan vendor:publish --tag="gravatar-config" 31 | ``` 32 | 33 | This will create a `config/gravatar.php` file in your Laravel application. See the [Configuration](configuration.md) documentation for details on available options. 34 | 35 | ## Verify Installation 36 | 37 | To verify the installation is working, you can use the helper in a route or controller: 38 | 39 | ```php 40 | // routes/web.php 41 | Route::get('/test-gravatar', function () { 42 | return gravatar('test@example.com')->size(200)->url(); 43 | }); 44 | ``` 45 | 46 | Or test in Tinker: 47 | 48 | ```bash 49 | php artisan tinker 50 | ``` 51 | 52 | ```php 53 | >>> gravatar('test@example.com')->size(120)->url() 54 | => "//www.gravatar.com/avatar/55502f40dc8b7c769880b10874abc9d0?s=120" 55 | ``` 56 | 57 | ## Next Steps 58 | 59 | - [Learn basic usage](usage.md) - Helpers, facades, and dependency injection 60 | - [Explore parameters](parameters.md) - Customize your Gravatars 61 | - [View type-safe enums](enums.md) - Use enums for better type safety 62 | -------------------------------------------------------------------------------- /docs/configuration.md: -------------------------------------------------------------------------------- 1 | Configuration 2 | ============= 3 | 4 | Laravel Gravatar can be configured through the `config/gravatar.php` file. This is entirely optional - the package works out of the box with sensible defaults. 5 | 6 | ## Publishing the Configuration 7 | 8 | To customize settings, publish the configuration file: 9 | 10 | ```bash 11 | php artisan vendor:publish --tag="gravatar-config" 12 | ``` 13 | 14 | This creates `config/gravatar.php` in your application. 15 | 16 | ## Configuration File Structure 17 | 18 | ```php 19 | null, 23 | 24 | 'presets' => [ 25 | // Your presets here 26 | ], 27 | ]; 28 | ``` 29 | 30 | ## Configuration Options 31 | 32 | ### Default Preset 33 | 34 | You can specify a default preset to be applied to all Gravatars unless overridden: 35 | 36 | ```php 37 | 'default_preset' => 'medium', 38 | ``` 39 | 40 | Set to `null` to disable the default preset. 41 | 42 | ### Presets 43 | 44 | The `presets` array contains named configurations that can be reused throughout your application. 45 | 46 | See the **[Presets documentation](presets.md)** for complete details on: 47 | - Defining presets 48 | - Available preset keys 49 | - Preset validation 50 | - Using presets 51 | - Examples 52 | 53 | ## Example Configuration 54 | 55 | Here's a minimal example configuration file: 56 | 57 | ```php 58 | 'default', 62 | 63 | 'presets' => [ 64 | 'default' => [ 65 | 'size' => 80, 66 | 'default_image' => 'mp', 67 | 'max_rating' => 'g', 68 | 'extension' => 'webp', 69 | ], 70 | 71 | 'thumbnail' => [ 72 | 'size' => 40, 73 | 'extension' => 'jpg', 74 | ], 75 | 76 | 'profile' => [ 77 | 'size' => 200, 78 | 'default_image' => 'identicon', 79 | 'max_rating' => 'pg', 80 | 'extension' => 'webp', 81 | ], 82 | ], 83 | ]; 84 | ``` 85 | 86 | ## Next Steps 87 | 88 | - [Define presets](presets.md) - Complete guide to preset configurations 89 | - [Add Eloquent casts](casts.md) - Seamlessly integrate with your models 90 | - [Explore advanced features](advanced.md) - Base64 conversion, copying instances 91 | -------------------------------------------------------------------------------- /src/Gravatar.php: -------------------------------------------------------------------------------- 1 | $config The Gravatar configuration array 17 | */ 18 | public function __construct( 19 | private readonly array $config, 20 | ) {} 21 | 22 | /** 23 | * Create a new Gravatar instance from the service container. 24 | * 25 | * @return static The Gravatar instance 26 | */ 27 | public static function create(): static 28 | { 29 | return app('gravatar'); 30 | } 31 | 32 | /** 33 | * Return a new Gravatar image instance for the specified email address. 34 | * 35 | * @param string|null $email The email address to generate the Gravatar for 36 | * @param string|null $presetName Optional preset name to apply default settings 37 | * @return Image The configured Gravatar image instance 38 | */ 39 | public function image(?string $email = null, ?string $presetName = null): Image 40 | { 41 | return new Image($this->config, $email, $presetName); 42 | } 43 | 44 | /** 45 | * Alias for the image() method. 46 | * 47 | * @param string|null $email The email address to generate the Gravatar for 48 | * @param string|null $presetName Optional preset name to apply default settings 49 | * @return Image The configured Gravatar image instance 50 | */ 51 | public function avatar(?string $email = null, ?string $presetName = null): Image 52 | { 53 | return $this->image($email, $presetName); 54 | } 55 | 56 | /** 57 | * Return a new Gravatar profile instance for the specified email address. 58 | * 59 | * @param string|null $email The email address to generate the profile for 60 | * @param string|null $format Optional format (json, xml, php, vcf, qr) 61 | * @return Profile The configured Gravatar profile instance 62 | */ 63 | public function profile(?string $email = null, ?string $format = null): Profile 64 | { 65 | return new Profile($email)->format($format); 66 | } 67 | } 68 | -------------------------------------------------------------------------------- /docs/index.md: -------------------------------------------------------------------------------- 1 | Laravel Gravatar Documentation 2 | ============================== 3 | 4 | Welcome to the Laravel Gravatar documentation. This package provides an easy and elegant way to integrate Gravatar into your Laravel applications. 5 | 6 | ## What is Laravel Gravatar? 7 | 8 | Laravel Gravatar is a Laravel package built on top of the [forxer/gravatar](https://github.com/forxer/gravatar) library. It extends the base functionality with Laravel-specific features: 9 | 10 | - **Helper functions** - `gravatar()` and `gravatar_profile()` for quick access 11 | - **Facade support** - `Gravatar::image()` and `Gravatar::profile()` 12 | - **Service Provider** - Automatic registration and configuration 13 | - **Configuration presets** - Define reusable avatar configurations with automatic validation 14 | - **Enum-based validation** - Runtime validation of preset values using type-safe enums 15 | - **Eloquent casts** - Cast model attributes to Gravatar instances 16 | - **Base64 conversion** - Convert avatars to data URLs using Laravel HTTP client 17 | - **PHP 8.4 features** - Full support for property hooks, asymmetric visibility, enums, and modern PHP 18 | 19 | ## Quick Start 20 | 21 | ```php 22 | use Gravatar\Enum\DefaultImage; 23 | 24 | // Simple usage with helper 25 | $avatar = gravatar('user@example.com') 26 | ->size(120) 27 | ->extensionWebp() 28 | ->defaultImageRobohash(); 29 | 30 | echo $avatar; // Outputs the Gravatar URL 31 | ``` 32 | 33 | ```blade 34 | {{-- In Blade templates --}} 35 | Avatar 36 | ``` 37 | 38 | ## Documentation Structure 39 | 40 | - **[Installation](installation.md)** - Install and configure the package 41 | - **[Usage](usage.md)** - Learn how to use helpers, facades, and dependency injection 42 | - **[Parameters](parameters.md)** - Understand all available Gravatar parameters 43 | - **[Enums](enums.md)** - Use type-safe enums and fluent shorthand methods 44 | - **[Configuration](configuration.md)** - Configure the package 45 | - **[Presets](presets.md)** - Complete guide to preset configurations 46 | - **[Casts](casts.md)** - Use Eloquent casts for seamless integration 47 | - **[Advanced Features](advanced.md)** - Explore advanced functionality 48 | 49 | ## Requirements 50 | 51 | - **PHP 8.4** or newer 52 | - **Laravel 12.0** or newer 53 | 54 | For older versions: 55 | - [Version 4.x](https://github.com/forxer/laravel-gravatar/tree/4.x) - PHP 8.2+, Laravel 10-12 56 | - [Version 2.x](https://github.com/forxer/laravel-gravatar/tree/2.x) - PHP 8.0+, Laravel 8-9 57 | 58 | ## Related Resources 59 | 60 | - [Gravatar Official Documentation](https://gravatar.com/site/implement/) 61 | - [forxer/gravatar Library](https://github.com/forxer/gravatar) - The underlying framework-agnostic library 62 | - [Changelog](../CHANGELOG.md) - Version history and changes 63 | - [Upgrade Guide](../UPGRADE.md) - Migration guides between versions 64 | 65 | ## Support 66 | 67 | - **Issues**: [GitHub Issues](https://github.com/forxer/laravel-gravatar/issues) 68 | - **Discussions**: [GitHub Discussions](https://github.com/forxer/laravel-gravatar/discussions) 69 | 70 | ## License 71 | 72 | This package is open-source software licensed under the [MIT license](../LICENSE). 73 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | [![Latest Stable Version](http://poser.pugx.org/forxer/laravel-gravatar/v)](https://packagist.org/packages/forxer/laravel-gravatar) 2 | [![Total Downloads](http://poser.pugx.org/forxer/laravel-gravatar/downloads)](https://packagist.org/packages/forxer/laravel-gravatar) 3 | [![License](http://poser.pugx.org/forxer/laravel-gravatar/license)](https://packagist.org/packages/forxer/laravel-gravatar) 4 | 5 | Gravatar for Laravel 6 | ==================== 7 | 8 | This package provides an easy Gravatar integration in a Laravel project. 9 | 10 | ```php 11 | use Gravatar\Enum\DefaultImage; 12 | use Gravatar\Enum\Extension; 13 | 14 | // Simple usage 15 | $avatar = gravatar('email@example.com') 16 | ->size(120) 17 | ->defaultImage('robohash') 18 | ->extension('jpg'); 19 | echo $avatar; 20 | 21 | // With type-safe enums 22 | $avatar = gravatar('email@example.com') 23 | ->size(120) 24 | ->defaultImage(DefaultImage::ROBOHASH) 25 | ->extension(Extension::JPG); 26 | 27 | // With fluent shorthand methods 28 | $avatar = gravatar('email@example.com') 29 | ->size(120) 30 | ->extensionJpg() 31 | ->defaultImageRobohash(); 32 | ``` 33 | 34 | ## About this package 35 | 36 | This Laravel package is built on top of the framework-agnostic **[forxer/gravatar](https://github.com/forxer/gravatar)** library. It extends the base functionality by adding: 37 | 38 | - **Laravel-specific features**: Service providers, facades, helper functions (`gravatar()` and `gravatar_profile()`), and configuration 39 | - **Extended classes**: `LaravelGravatar\Image` extends `Gravatar\Image`, and `LaravelGravatar\Profile` extends `Gravatar\Profile` 40 | - **Additional Laravel integrations**: Eloquent casts, preset configurations, and base64 conversion with Laravel's HTTP client 41 | - **Full support for PHP 8.4 features**: Property hooks, type-safe enums, and fluent shorthand methods from the parent library 42 | 43 | All the core Gravatar functionality from the parent library is available in this package. 44 | 45 | ## Documentation 46 | 47 | **Complete documentation is available in the [docs](docs/) directory:** 48 | 49 | - **[Overview](docs/index.md)** - Introduction and quick start 50 | - **[Installation](docs/installation.md)** - Install and configure 51 | - **[Usage](docs/usage.md)** - Helpers, facades, and dependency injection 52 | - **[Parameters](docs/parameters.md)** - All available Gravatar parameters 53 | - **[Enums](docs/enums.md)** - Type-safe enums and fluent methods 54 | - **[Configuration](docs/configuration.md)** - Configure the package 55 | - **[Presets](docs/presets.md)** - Complete guide to preset configurations 56 | - **[Casts](docs/casts.md)** - Eloquent model integration 57 | - **[Advanced Features](docs/advanced.md)** - Base64 conversion, copying, and more 58 | 59 | ## Requirements 60 | 61 | - **PHP 8.4+** 62 | - **Laravel 12.0+** 63 | 64 | For earlier versions: 65 | - [Version 4.x](https://github.com/forxer/laravel-gravatar/tree/4.x) - PHP 8.2+ and Laravel 10.0+ 66 | - [Version 2.x](https://github.com/forxer/laravel-gravatar/tree/2.x) - PHP 8.0+ and Laravel 8.0+ 67 | - [Version 1.x](https://github.com/forxer/laravel-gravatar/tree/1.x) - Older versions 68 | 69 | ## Quick Installation 70 | 71 | ```bash 72 | composer require forxer/laravel-gravatar 73 | ``` 74 | 75 | The service provider is automatically registered via package discovery. 76 | 77 | ## Quick Start 78 | 79 | ```php 80 | // Simple usage with helper 81 | Avatar 82 | 83 | // With configuration 84 | $avatar = gravatar('user@example.com') 85 | ->size(120) 86 | ->extensionWebp() 87 | ->defaultImageRobohash(); 88 | 89 | // Using presets 90 | $avatar = gravatar($user->email, 'small'); 91 | 92 | // With Eloquent casts 93 | class User extends Model 94 | { 95 | protected $casts = [ 96 | 'email' => GravatarImage::class.':medium', 97 | ]; 98 | } 99 | 100 | // In Blade 101 | Avatar 102 | ``` 103 | 104 | ## Key Features 105 | 106 | - **Helper functions** - `gravatar()` and `gravatar_profile()` for quick access 107 | - **Facade support** - `Gravatar::image()` and `Gravatar::profile()` 108 | - **Eloquent casts** - Seamless model integration 109 | - **Preset configurations** - Define reusable avatar settings with automatic validation 110 | - **Enum-based validation** - Preset values validated against type-safe enums at runtime 111 | - **Base64 conversion** - Convert avatars to data URLs 112 | - **PHP 8.4 property hooks** - Direct property access with validation 113 | - **Type-safe enums** - `Rating`, `Extension`, `DefaultImage`, `ProfileFormat` 114 | - **Fluent shorthand methods** - `extensionWebp()`, `ratingPg()`, `defaultImageRobohash()` 115 | 116 | ## Version History 117 | 118 | See [CHANGELOG.md](CHANGELOG.md) for all changes. 119 | 120 | ## Upgrading 121 | 122 | See [UPGRADE.md](UPGRADE.md) for upgrade instructions between major versions. 123 | 124 | ## License 125 | 126 | This package is open-source software licensed under the [MIT license](LICENSE). 127 | -------------------------------------------------------------------------------- /docs/usage.md: -------------------------------------------------------------------------------- 1 | Usage 2 | ===== 3 | 4 | Laravel Gravatar provides three main ways to work with Gravatars in your application: 5 | 6 | 1. **Helper functions** - Quick and convenient for most use cases 7 | 2. **Facade** - For static access anywhere in your app 8 | 3. **Dependency injection** - For better testability in classes 9 | 10 | ## Helper Functions 11 | 12 | The package provides two helper functions that are the recommended way to use Gravatars in Laravel. 13 | 14 | ### The `gravatar()` Helper 15 | 16 | The `gravatar()` helper returns a `LaravelGravatar\Image` instance for building avatar URLs: 17 | 18 | ```php 19 | // Simple usage 20 | $avatar = gravatar('user@example.com'); 21 | echo $avatar; // Outputs the Gravatar URL 22 | 23 | // With parameters 24 | $avatar = gravatar('user@example.com') 25 | ->size(120) 26 | ->defaultImage('robohash') 27 | ->extension('webp'); 28 | 29 | echo $avatar->url(); // Get URL as string 30 | ``` 31 | 32 | You can also call it without an email and set it later: 33 | 34 | ```php 35 | $avatar = gravatar(); 36 | $avatar->email = 'user@example.com'; 37 | $avatar->size(120); 38 | ``` 39 | 40 | With a preset (see [Presets](presets.md)): 41 | 42 | ```php 43 | $avatar = gravatar('user@example.com', 'small'); 44 | ``` 45 | 46 | ### The `gravatar_profile()` Helper 47 | 48 | The `gravatar_profile()` helper returns a `LaravelGravatar\Profile` instance for Gravatar profile URLs: 49 | 50 | ```php 51 | // HTML profile URL 52 | $profile = gravatar_profile('user@example.com'); 53 | echo $profile; 54 | 55 | // JSON profile 56 | $profileJson = gravatar_profile('user@example.com', 'json'); 57 | 58 | // Other formats 59 | $profileXml = gravatar_profile('user@example.com', 'xml'); 60 | $profileVcf = gravatar_profile('user@example.com', 'vcf'); 61 | $profileQr = gravatar_profile('user@example.com', 'qr'); 62 | ``` 63 | 64 | ## Facade 65 | 66 | The `Gravatar` facade provides static access to all functionality: 67 | 68 | ```php 69 | use LaravelGravatar\Facades\Gravatar; 70 | 71 | // Create an avatar image 72 | $avatar = Gravatar::image('user@example.com') 73 | ->size(120); 74 | 75 | // Alias: avatar() is the same as image() 76 | $avatar = Gravatar::avatar('user@example.com'); 77 | 78 | // Create a profile 79 | $profile = Gravatar::profile('user@example.com', 'json'); 80 | 81 | // Access the service instance 82 | $service = Gravatar::create(); 83 | ``` 84 | 85 | ## Dependency Injection 86 | 87 | For better testability, you can inject the Gravatar service into your controllers or other classes: 88 | 89 | ```php 90 | use App\Models\User; 91 | use LaravelGravatar\Gravatar; 92 | 93 | class UserController extends Controller 94 | { 95 | public function show(User $user, Gravatar $gravatar) 96 | { 97 | $avatar = $gravatar->image($user->email) 98 | ->size(120) 99 | ->defaultImage('identicon'); 100 | 101 | $profile = $gravatar->profile($user->email, 'json'); 102 | 103 | return view('users.show', [ 104 | 'user' => $user, 105 | 'avatar' => $avatar, 106 | 'profile' => $profile, 107 | ]); 108 | } 109 | } 110 | ``` 111 | 112 | ## Using in Blade Templates 113 | 114 | All Gravatar instances implement `__toString()`, so you can use them directly in Blade: 115 | 116 | ```blade 117 | {{-- Simple avatar --}} 118 | Avatar 119 | 120 | {{-- With chaining --}} 121 | Avatar 122 | 123 | {{-- Profile link --}} 124 | View Profile 125 | 126 | {{-- Profile JSON --}} 127 | Profile Data 128 | 129 | {{-- Using facade --}} 130 | Avatar 131 | ``` 132 | 133 | ## Setting the Email Address 134 | 135 | There are several ways to provide the email address: 136 | 137 | **1. Using helper method:** 138 | 139 | ```php 140 | // As helper argument 141 | $avatar = gravatar('user@example.com'); 142 | 143 | // Or via method call 144 | $avatar = gravatar()->email('user@example.com'); 145 | 146 | // Getter mode 147 | $current = $avatar->email(); // Returns current email 148 | ``` 149 | 150 | **2. Using direct property:** 151 | 152 | ```php 153 | $avatar = gravatar(); 154 | $avatar->email = 'user@example.com'; 155 | 156 | // Reading the property 157 | echo $avatar->email; // 'user@example.com' 158 | ``` 159 | 160 | Choose the approach that best fits your code style. 161 | 162 | ## Building the URL 163 | 164 | There are two ways to get the Gravatar URL: 165 | 166 | ```php 167 | $avatar = gravatar('user@example.com')->size(120); 168 | 169 | // 1. Using the url() method 170 | $url = $avatar->url(); 171 | 172 | // 2. Using string conversion (__toString) 173 | $url = (string) $avatar; 174 | echo $avatar; // Also uses __toString 175 | ``` 176 | 177 | ## Copying Instances 178 | 179 | You can create a copy of an existing Gravatar instance with all its settings: 180 | 181 | ```php 182 | // Create a base configuration 183 | $base = gravatar()->size(120)->defaultImage('robohash'); 184 | 185 | // Create copies with different emails 186 | $avatar1 = $base->copy('user1@example.com'); 187 | $avatar2 = $base->copy('user2@example.com'); 188 | 189 | // Create a copy and modify settings 190 | $largeAvatar = $base->copy('user@example.com')->size(200); 191 | ``` 192 | 193 | This is useful when you need to generate multiple avatars with consistent settings. 194 | 195 | ## Next Steps 196 | 197 | - [Learn about parameters](parameters.md) - Customize size, rating, default image, etc. 198 | - [View type-safe enums](enums.md) - Use enums for better type safety 199 | - [Define presets](presets.md) - Create reusable configurations 200 | -------------------------------------------------------------------------------- /config/gravatar.php: -------------------------------------------------------------------------------- 1 | null, 18 | 19 | /* 20 | |-------------------------------------------------------------------------- 21 | | Avatar Presets 22 | |-------------------------------------------------------------------------- 23 | | 24 | | Here you may configure as many avatar preset as you wish. 25 | | 26 | */ 27 | 28 | 'presets' => [ 29 | 30 | /* 31 | |-------------------------------------------------------------------------- 32 | | Gravatar Defaults 33 | |-------------------------------------------------------------------------- 34 | | 35 | | Here is an example of a preset using Gravatar's default values. 36 | | 37 | */ 38 | 39 | 'gravatar' => [ 40 | 41 | /* 42 | |-------------------------------------------------------------------------- 43 | | Gravatar image size 44 | |-------------------------------------------------------------------------- 45 | | 46 | | By default, images are presented at 80px by 80px if no size 47 | | parameter is supplied. You may request a specific image size, 48 | | which will be dynamically delivered from Gravatar. 49 | | 50 | | You may request images anywhere from 1px up to 2048px, 51 | | however note that many users have lower resolution images, 52 | | so requesting larger sizes may result in pixelation/low-quality images. 53 | | 54 | | An avatar size should be an integer representing the size in pixels. 55 | | 56 | */ 57 | 58 | 'size' => 80, 59 | 60 | /* 61 | |-------------------------------------------------------------------------- 62 | | Default Gravatar image 63 | |-------------------------------------------------------------------------- 64 | | 65 | | Here you can define the default image to be used when an email address 66 | | has no matching Gravatar image or when the gravatar specified exceeds 67 | | your maximum allowed content rating. 68 | | 69 | | If you'd prefer to use your own default image, then you can easily do so 70 | | by supplying the URL to an image. In addition to allowing you to use your 71 | | own image, Gravatar has a number of built in options which you can also 72 | | use as defaults. Most of these work by taking the requested email hash 73 | | and using it to generate a themed image that is unique to that email address. 74 | | 75 | | Possible values: 76 | | - null value to fallback to the default Gravatar 77 | | - a string represanting the URL of your own default image 78 | | - 'initials': uses the profile name as initials, with a generated background and foreground color 79 | | - 'color': a generated color 80 | | - '404': do not load any image if none is associated with the email hash, instead return an HTTP 404 (File Not Found) response 81 | | - 'mp': (mystery-person) a simple, cartoon-style silhouetted outline of a person (does not vary by email hash) 82 | | - 'identicon': a geometric pattern based on an email hash 83 | | - 'monsterid': a generated 'monster' with different colors, faces, etc 84 | | - 'wavatar': generated faces with differing features and backgrounds 85 | | - 'robohash': a generated robot with different colors, faces, etc 86 | | - 'retro': awesome generated, 8-bit arcade-style pixelated faces 87 | | - 'blank': a transparent PNG image 88 | */ 89 | 90 | 'default_image' => null, 91 | 92 | /* 93 | |-------------------------------------------------------------------------- 94 | | Force to always use the default image 95 | |-------------------------------------------------------------------------- 96 | | 97 | | If for some reason you wanted to force the default image 98 | | to always be load, put it to true. 99 | | 100 | */ 101 | 102 | 'force_default' => false, 103 | 104 | /* 105 | |-------------------------------------------------------------------------- 106 | | Gravatar image max rating 107 | |-------------------------------------------------------------------------- 108 | | 109 | | Gravatar allows users to self-rate their images so that they can 110 | | indicate if an image is appropriate for a certain audience. 111 | | By default, only 'g' rated images are displayed unless you indicate 112 | | that you would like to see higher ratings. 113 | | 114 | | You may specify one of the following ratings to request images up to and including that rating: 115 | | 116 | | 'g': suitable for display on all websites with any audience type. 117 | | 'pg': may contain rude gestures, provocatively dressed individuals, the lesser swear words, or mild violence. 118 | | 'r': may contain such things as harsh profanity, intense violence, nudity, or hard drug use. 119 | | 'x': may contain hardcore sexual imagery or extremely disturbing violence. 120 | | 121 | */ 122 | 123 | 'max_rating' => 'g', 124 | 125 | /* 126 | |-------------------------------------------------------------------------- 127 | | Gravatar image file-type extension 128 | |-------------------------------------------------------------------------- 129 | | 130 | | If you require a file-type extension (some places do) then you may also specify it. 131 | | 132 | | Possible values: 'jpg', 'jpeg', 'png', 'gif', 'webp' 133 | | 134 | */ 135 | 136 | 'extension' => null, 137 | ], 138 | 139 | /* 140 | |-------------------------------------------------------------------------- 141 | | Another Presets 142 | |-------------------------------------------------------------------------- 143 | | 144 | | Define here your own presets. 145 | | 146 | */ 147 | 148 | 'small' => [ 149 | 'size' => 40, 150 | 'default_image' => 'mp', 151 | 'extension' => 'jpg', 152 | ], 153 | 154 | 'medium' => [ 155 | 'size' => 120, 156 | 'default_image' => 'mp', 157 | 'extension' => 'jpg', 158 | ], 159 | 160 | 'large' => [ 161 | 'size' => 360, 162 | 'default_image' => 'mp', 163 | 'extension' => 'jpg', 164 | ], 165 | ], 166 | ]; 167 | -------------------------------------------------------------------------------- /docs/casts.md: -------------------------------------------------------------------------------- 1 | Eloquent Casts 2 | ============== 3 | 4 | Laravel Gravatar provides Eloquent casts to seamlessly integrate Gravatar functionality into your models. 5 | 6 | ## Why Use Casts? 7 | 8 | Casts allow you to: 9 | - **Automatically convert** database values to Gravatar instances 10 | - **Work with Gravatars** as if they were native model properties 11 | - **Reduce boilerplate** - No need to manually create instances 12 | - **Clean controllers** - Access Gravatars directly from your models 13 | 14 | ## Available Casts 15 | 16 | ### GravatarImage 17 | 18 | Casts a model attribute to a `LaravelGravatar\Image` instance. 19 | 20 | ### GravatarProfile 21 | 22 | Casts a model attribute to a `LaravelGravatar\Profile` instance. 23 | 24 | ## Basic Usage 25 | 26 | ### Setting Up the Cast 27 | 28 | In your model, add the cast to the `$casts` array: 29 | 30 | ```php 31 | GravatarImage::class, 42 | ]; 43 | } 44 | ``` 45 | 46 | Now the `email` attribute will automatically be cast to a Gravatar Image instance. 47 | 48 | ### Using in Controllers 49 | 50 | ```php 51 | use App\Models\User; 52 | 53 | class UserController extends Controller 54 | { 55 | public function show(User $user) 56 | { 57 | // $user->email is now a LaravelGravatar\Image instance 58 | $avatar = $user->email->size(120)->extensionWebp(); 59 | 60 | return view('users.show', [ 61 | 'user' => $user, 62 | 'avatar' => $avatar, 63 | ]); 64 | } 65 | } 66 | ``` 67 | 68 | ### Using in Blade 69 | 70 | ```blade 71 | {{-- Access directly in views --}} 72 | Avatar 73 | 74 | {{-- Chain methods --}} 75 | Avatar 76 | 77 | {{-- Apply preset --}} 78 | Avatar 79 | ``` 80 | 81 | ## Using with Presets 82 | 83 | You can specify a preset to be automatically applied to the cast: 84 | 85 | ```php 86 | use LaravelGravatar\Casts\GravatarImage; 87 | 88 | class User extends Model 89 | { 90 | protected $casts = [ 91 | 'email' => GravatarImage::class.':small', 92 | // or 93 | 'avatar_email' => GravatarImage::class.':medium', 94 | ]; 95 | } 96 | ``` 97 | 98 | The preset name comes after a colon (`:`) following the class name. 99 | 100 | ## Working with Different Columns 101 | 102 | You don't have to use the `email` column. Any column containing an email address can be cast: 103 | 104 | ```php 105 | class Post extends Model 106 | { 107 | protected $casts = [ 108 | 'author_email' => GravatarImage::class, 109 | 'commenter_email' => GravatarImage::class.':small', 110 | ]; 111 | } 112 | ``` 113 | 114 | Usage: 115 | 116 | ```blade 117 | Author 118 | Commenter 119 | ``` 120 | 121 | ## Profile Casts 122 | 123 | Cast to Gravatar profiles for accessing user profile data: 124 | 125 | ```php 126 | use LaravelGravatar\Casts\GravatarProfile; 127 | 128 | class User extends Model 129 | { 130 | protected $casts = [ 131 | 'email' => GravatarProfile::class, 132 | ]; 133 | } 134 | ``` 135 | 136 | Usage: 137 | 138 | ```php 139 | // Get profile URL 140 | $profileUrl = $user->email->url(); 141 | 142 | // Get JSON profile 143 | $jsonProfile = $user->email->formatJson(); 144 | ``` 145 | 146 | In Blade: 147 | 148 | ```blade 149 | View Gravatar Profile 150 | Profile JSON 151 | ``` 152 | 153 | ## Multiple Casts on Same Model 154 | 155 | You can have multiple casts for different purposes: 156 | 157 | ```php 158 | use LaravelGravatar\Casts\{GravatarImage, GravatarProfile}; 159 | 160 | class User extends Model 161 | { 162 | protected $casts = [ 163 | 'avatar' => GravatarImage::class.':small', 164 | 'profile_link' => GravatarProfile::class, 165 | ]; 166 | 167 | // Both use the same email 168 | protected function avatar(): Attribute 169 | { 170 | return Attribute::get(fn () => $this->email); 171 | } 172 | 173 | protected function profileLink(): Attribute 174 | { 175 | return Attribute::get(fn () => $this->email); 176 | } 177 | } 178 | ``` 179 | 180 | ## Modifying Cast Instances 181 | 182 | Cast instances are independent - modifying one doesn't affect the original value: 183 | 184 | ```php 185 | $user = User::find(1); 186 | 187 | // Create a large avatar 188 | $largeAvatar = $user->email->size(200); 189 | 190 | // Original email attribute unchanged 191 | echo $user->email->size(); // Still uses preset or default size 192 | 193 | // Each access creates a new instance 194 | $avatar1 = $user->email->size(100); 195 | $avatar2 = $user->email->size(200); 196 | // $avatar1 and $avatar2 are independent 197 | ``` 198 | 199 | ## Practical Examples 200 | 201 | ### User Profile Page 202 | 203 | ```php 204 | class User extends Model 205 | { 206 | protected $casts = [ 207 | 'email' => GravatarImage::class.':medium', 208 | ]; 209 | } 210 | ``` 211 | 212 | ```blade 213 | {{-- resources/views/users/show.blade.php --}} 214 | 219 | ``` 220 | 221 | ### Comments List 222 | 223 | ```php 224 | class Comment extends Model 225 | { 226 | protected $casts = [ 227 | 'commenter_email' => GravatarImage::class.':small', 228 | ]; 229 | } 230 | ``` 231 | 232 | ```blade 233 | {{-- resources/views/comments/list.blade.php --}} 234 | @foreach($comments as $comment) 235 |
236 | Commenter 237 |

{{ $comment->body }}

238 |
239 | @endforeach 240 | ``` 241 | 242 | ### Admin Dashboard 243 | 244 | ```php 245 | class Admin extends Model 246 | { 247 | protected $casts = [ 248 | 'email' => GravatarImage::class.':admin', 249 | ]; 250 | } 251 | ``` 252 | 253 | Where `'admin'` is a preset defined in `config/gravatar.php` (see [Presets](presets.md)): 254 | 255 | ```php 256 | 'presets' => [ 257 | 'admin' => [ 258 | 'size' => 120, 259 | 'default_image' => 'robohash', 260 | 'extension' => 'png', 261 | ], 262 | ], 263 | ``` 264 | 265 | ## Accessing the Email String 266 | 267 | When using a cast, you can still access the original email string: 268 | 269 | ```php 270 | // If you need the email string 271 | $emailString = $user->email->email; 272 | 273 | // Or use getRawOriginal() 274 | $emailString = $user->getRawOriginal('email'); 275 | ``` 276 | 277 | ## Best Practices 278 | 279 | 1. **Use presets with casts** - Define common sizes/styles once 280 | 2. **Keep column names semantic** - `author_email`, `commenter_email`, etc. 281 | 3. **Use consistent presets** - `small`, `medium`, `large` across your app 282 | 4. **Cache rendered HTML** - Gravatar URLs don't change, cache the rendered output 283 | 284 | ## Next Steps 285 | 286 | - [Explore advanced features](advanced.md) - Base64 conversion, copying instances, and more 287 | -------------------------------------------------------------------------------- /docs/enums.md: -------------------------------------------------------------------------------- 1 | Type-Safe Enums and Fluent Methods 2 | ==================================== 3 | 4 | Laravel Gravatar v5 (using `forxer/gravatar` v6) introduces type-safe enums and fluent shorthand methods for a better developer experience. 5 | 6 | ## Why Use Enums? 7 | 8 | Enums provide: 9 | - **Type safety** - Catch typos at compile time 10 | - **IDE autocompletion** - See all available options 11 | - **Better refactoring** - Change values safely 12 | - **Self-documenting code** - Clear, explicit values 13 | 14 | ## Available Enums 15 | 16 | All enums are in the `Gravatar\Enum` namespace. 17 | 18 | ### Rating 19 | 20 | ```php 21 | use Gravatar\Enum\Rating; 22 | 23 | Rating::G // Suitable for all audiences 24 | Rating::PG // May contain mild content 25 | Rating::R // May contain harsh content 26 | Rating::X // May contain adult content 27 | ``` 28 | 29 | ### Extension 30 | 31 | ```php 32 | use Gravatar\Enum\Extension; 33 | 34 | Extension::JPG 35 | Extension::JPEG 36 | Extension::PNG 37 | Extension::GIF 38 | Extension::WEBP 39 | ``` 40 | 41 | ### DefaultImage 42 | 43 | ```php 44 | use Gravatar\Enum\DefaultImage; 45 | 46 | DefaultImage::INITIALS // Initials with generated colors 47 | DefaultImage::COLOR // Generated solid color 48 | DefaultImage::NOT_FOUND // 404 - no image 49 | DefaultImage::MYSTERY_PERSON // Simple silhouette (mp) 50 | DefaultImage::IDENTICON // Geometric pattern 51 | DefaultImage::MONSTERID // Generated monster 52 | DefaultImage::WAVATAR // Generated face 53 | DefaultImage::RETRO // 8-bit pixelated face 54 | DefaultImage::ROBOHASH // Generated robot 55 | DefaultImage::BLANK // Transparent PNG 56 | ``` 57 | 58 | ### ProfileFormat 59 | 60 | ```php 61 | use Gravatar\Enum\ProfileFormat; 62 | 63 | ProfileFormat::JSON // JSON format 64 | ProfileFormat::XML // XML format 65 | ProfileFormat::PHP // PHP serialized 66 | ProfileFormat::VCF // vCard format 67 | ProfileFormat::QR // QR code image 68 | ``` 69 | 70 | ## Using Enums 71 | 72 | Enums can be used with helper methods or direct property assignment. Strings are still accepted for backward compatibility. 73 | 74 | **1. With helper methods:** 75 | 76 | ```php 77 | use Gravatar\Enum\Rating; 78 | use Gravatar\Enum\Extension; 79 | use Gravatar\Enum\DefaultImage; 80 | 81 | $avatar = gravatar('user@example.com') 82 | ->maxRating(Rating::PG) 83 | ->extension(Extension::WEBP) 84 | ->defaultImage(DefaultImage::ROBOHASH); 85 | ``` 86 | 87 | **2. With convenience methods (fluent shorthand):** 88 | 89 | Fluent shorthand methods provide the most concise syntax (see section below). 90 | 91 | **3. With direct property assignment:** 92 | 93 | ```php 94 | use Gravatar\Enum\Rating; 95 | use Gravatar\Enum\DefaultImage; 96 | 97 | $avatar = gravatar('user@example.com'); 98 | $avatar->maxRating = Rating::PG; 99 | $avatar->defaultImage = DefaultImage::IDENTICON; 100 | ``` 101 | 102 | ### Mixed Usage 103 | 104 | You can mix enums and strings - both work: 105 | 106 | ```php 107 | use Gravatar\Enum\Rating; 108 | 109 | $avatar = gravatar('user@example.com') 110 | ->maxRating(Rating::PG) // Enum with helper method 111 | ->extension('webp') // String with helper method 112 | ->defaultImage('robohash'); // String with helper method 113 | ``` 114 | 115 | ## Fluent Shorthand Methods 116 | 117 | For even cleaner code, use fluent shorthand methods. These are pre-defined methods that set specific enum values. 118 | 119 | ### Rating Shortcuts 120 | 121 | ```php 122 | $avatar = gravatar('user@example.com') 123 | ->ratingG() // Set rating to G 124 | ->ratingPg() // Set rating to PG 125 | ->ratingR() // Set rating to R 126 | ->ratingX(); // Set rating to X 127 | ``` 128 | 129 | ### Extension Shortcuts 130 | 131 | ```php 132 | $avatar = gravatar('user@example.com') 133 | ->extensionJpg() 134 | ->extensionJpeg() 135 | ->extensionPng() 136 | ->extensionGif() 137 | ->extensionWebp(); 138 | ``` 139 | 140 | ### Default Image Shortcuts 141 | 142 | ```php 143 | $avatar = gravatar('user@example.com') 144 | ->defaultImageInitials() // Initials 145 | ->defaultImageColor() // Color 146 | ->defaultImageNotFound() // 404 147 | ->defaultImageMp() // Mystery person 148 | ->defaultImageIdenticon() // Identicon 149 | ->defaultImageMonsterid() // Monsterid 150 | ->defaultImageWavatar() // Wavatar 151 | ->defaultImageRetro() // Retro 152 | ->defaultImageRobohash() // Robohash 153 | ->defaultImageBlank(); // Blank 154 | ``` 155 | 156 | ### Profile Format Shortcuts 157 | 158 | ```php 159 | $profile = gravatar_profile('user@example.com') 160 | ->formatJson() // JSON format 161 | ->formatXml() // XML format 162 | ->formatPhp() // PHP format 163 | ->formatVcf() // vCard format 164 | ->formatQr(); // QR code 165 | ``` 166 | 167 | ## Combining Fluent Methods 168 | 169 | Chain multiple fluent methods for clean, readable code: 170 | 171 | ```php 172 | $avatar = gravatar('user@example.com') 173 | ->size(120) 174 | ->extensionWebp() 175 | ->ratingPg() 176 | ->defaultImageRobohash(); 177 | ``` 178 | 179 | ## Comparison of Approaches 180 | 181 | All approaches achieve the same result. Choose based on your preference and use case: 182 | 183 | **1. Using helper methods with strings:** 184 | 185 | ```php 186 | $avatar = gravatar('user@example.com') 187 | ->size(120) 188 | ->extension('webp') 189 | ->maxRating('pg') 190 | ->defaultImage('robohash'); 191 | ``` 192 | 193 | **2. Using helper methods with enums (type-safe):** 194 | 195 | ```php 196 | use Gravatar\Enum\{Extension, Rating, DefaultImage}; 197 | 198 | $avatar = gravatar('user@example.com') 199 | ->size(120) 200 | ->extension(Extension::WEBP) 201 | ->maxRating(Rating::PG) 202 | ->defaultImage(DefaultImage::ROBOHASH); 203 | ``` 204 | 205 | **3. Using convenience methods (fluent shortcuts - most concise):** 206 | 207 | ```php 208 | $avatar = gravatar('user@example.com') 209 | ->size(120) 210 | ->extensionWebp() 211 | ->ratingPg() 212 | ->defaultImageRobohash(); 213 | ``` 214 | 215 | **4. Using direct properties:** 216 | 217 | ```php 218 | use Gravatar\Enum\{Extension, Rating, DefaultImage}; 219 | 220 | $avatar = gravatar('user@example.com'); 221 | $avatar->size = 120; 222 | $avatar->extension = Extension::WEBP; 223 | $avatar->maxRating = Rating::PG; 224 | $avatar->defaultImage = DefaultImage::ROBOHASH; 225 | ``` 226 | 227 | ## In Blade Templates 228 | 229 | ```blade 230 | {{-- Using fluent methods --}} 231 | Avatar 232 | 233 | {{-- Using enums --}} 234 | @php 235 | use Gravatar\Enum\DefaultImage; 236 | @endphp 237 | Avatar 238 | 239 | {{-- Mix and match --}} 240 | Avatar 241 | ``` 242 | 243 | ## Best Practices 244 | 245 | 1. **Prefer convenience methods (fluent shortcuts) for inline usage** - Most concise and readable in Blade and simple cases 246 | 2. **Use helper methods with enums for configuration** - When storing values or working with config files for type safety 247 | 3. **Use direct properties sparingly** - Mainly for dynamic property assignment or when readability benefits 248 | 4. **Mix approaches freely** - Choose what's clearest for each situation 249 | 5. **Import enums at the top** - Use `use` statements for cleaner code 250 | 251 | ```php 252 | // Good: Import once at the top 253 | use Gravatar\Enum\{Rating, Extension, DefaultImage}; 254 | 255 | class UserController 256 | { 257 | public function avatar($email) 258 | { 259 | // Option 1: Convenience methods (recommended for inline) 260 | return gravatar($email) 261 | ->extensionWebp() 262 | ->ratingPg(); 263 | 264 | // Option 2: Helper methods with enums (good for config-driven) 265 | return gravatar($email) 266 | ->extension(Extension::WEBP) 267 | ->maxRating(Rating::PG); 268 | } 269 | } 270 | ``` 271 | 272 | ## Next Steps 273 | 274 | - [Configure settings](configuration.md) - Set up global configuration 275 | - [Define presets](presets.md) - Combine settings into reusable presets 276 | - [Add Eloquent casts](casts.md) - Seamlessly integrate with your models 277 | -------------------------------------------------------------------------------- /CHANGELOG.md: -------------------------------------------------------------------------------- 1 | CHANGELOG 2 | ========= 3 | 4 | 5.0.0 (2025-11-17) 5 | ------------------ 6 | 7 | ### Breaking Changes 8 | 9 | - **Minimum PHP version increased to 8.4** 10 | - **Minimum Laravel version increased to 12.0** - dropped support for Laravel 10 and 11 11 | - **Updated to `forxer/gravatar` 6.0** - inherits all breaking changes from the parent library: 12 | - Removed getter methods: `getEmail()`, `getSize()`, `getExtension()`, `getMaxRating()`, `getDefaultImage()`, `getInitials()`, `getName()`, `getForceDefault()` - use direct property access instead (e.g., `$image->size` instead of `$image->getSize()`) 13 | - Removed setter methods: `setEmail()`, `setSize()`, `setExtension()`, `setMaxRating()`, `setDefaultImage()`, `setInitials()`, `setName()`, `setForceDefault()` - use helper methods or direct property assignment instead (e.g., `$image->size(120)` or `$image->size = 120`) 14 | - Renamed property and method: `name` → `initialsName` and `withName()` → `withInitialsName()` for better clarity 15 | - Removed short alias methods: `s()`, `e()`, `r()`, `d()`, `f()` - use full helper method names or new fluent shorthand methods instead 16 | - **Preset configuration keys**: Short aliases (`s`, `e`, `r`, `d`, `f`) are no longer supported in preset configurations - use full key names (`size`, `extension`, `max_rating`, `default_image`, `force_default`) 17 | 18 | ### Improvements 19 | 20 | - **PHP 8.4 Features**: 21 | - Property Hooks: All properties use property hooks with automatic conversion and validation 22 | - Asymmetric Visibility: `presetName` property uses `public private(set)` for read-public, write-private access 23 | - Readonly Properties: `config` property uses `public readonly` for complete immutability after construction 24 | - Strict Types: All files now use `declare(strict_types=1)` 25 | - **Type-safe Enums**: 26 | - Can now use enum classes from parent library (`Rating`, `Extension`, `DefaultImage`, `ProfileFormat`) for better IDE support and type safety 27 | - **New `PresetKey` enum**: Laravel-specific enum for preset configuration keys validation 28 | - **Fluent Shorthand Methods**: Added support for convenient fluent methods (convenience methods): 29 | - Rating: `ratingG()`, `ratingPg()`, `ratingR()`, `ratingX()` 30 | - Extension: `extensionJpg()`, `extensionJpeg()`, `extensionGif()`, `extensionPng()`, `extensionWebp()` 31 | - Default images: `defaultImageInitials()`, `defaultImageColor()`, `defaultImageNotFound()`, `defaultImageMp()`, `defaultImageIdenticon()`, `defaultImageMonsterid()`, `defaultImageWavatar()`, `defaultImageRetro()`, `defaultImageRobohash()`, `defaultImageBlank()` 32 | - Profile formats: `formatJson()`, `formatXml()`, `formatPhp()`, `formatVcf()`, `formatQr()` 33 | - Initials: `withInitials()`, `withInitialsName()` 34 | - Force default: `enableForceDefault()`, `disableForceDefault()`, `forcingDefault()` 35 | - **Direct Property Assignment**: Properties can now be assigned directly with automatic validation through PHP 8.4 property hooks (e.g., `$avatar->size = 120`) 36 | - **Dual-mode helper methods**: All helper methods work in both setter mode (with argument) and getter mode (without argument) for maximum flexibility 37 | - **Improved `gravatar()` helper**: Now always returns an `Image` instance (even when called without parameters), making it more consistent and intuitive 38 | - **New `gravatar_profile()` helper**: Added a dedicated helper function for creating profile instances, following the pattern from the parent library 39 | - **Code Quality Improvements**: 40 | - Replaced `ALLOWED_PRESET_KEYS` constant array with `PresetKey` enum for type-safe preset key validation 41 | - Refactored `toBase64()` with early returns pattern for improved readability 42 | - Simplified `profile()` method from 7 lines to 3 lines 43 | - Modernized with Laravel 12 patterns: replaced `Container::getInstance()` with `app()` helper 44 | - Added comprehensive PHPDoc documentation with array shapes and conditional return types 45 | - Fixed incorrect return type in `GravatarProfile` cast (was `Image`, now `Profile`) 46 | - Enhanced PHPDoc consistency: all constructors, helpers, and facade methods fully documented 47 | - All return types explicitly declared across the entire codebase 48 | - **Enum-based validation**: Added `validatePresetValue()` method using `PresetKey`, `Extension`, `Rating`, and `DefaultImage` enums for complete type-safe validation 49 | - All enums from parent library fully integrated and utilized for consistency 50 | - **Updated internal code**: 51 | - Fixed `Image::toBase64()` to use property access (`$this->email`) instead of removed `getEmail()` method 52 | - Fixed `Gravatar::profile()` to use `format()` method instead of removed `setFormat()` method 53 | - Removed short aliases from preset configuration allowed keys 54 | - Added support for `initials` and `initials_name` keys in preset configurations 55 | - **Profile enhancements**: 56 | - Direct access to `Profile::getData()` method for fetching Gravatar profile data 57 | - Inherited from parent library automatically 58 | - **Comprehensive documentation restructure**: 59 | - Split documentation into dedicated files in `docs/` directory 60 | - Added Laravel-focused documentation for all features 61 | - New `docs/presets.md`: Complete guide to preset configurations consolidating all preset-related documentation 62 | - All properties documented in order: 1) Helper methods, 2) Convenience methods, 3) Direct properties 63 | - Complete migration guide in UPGRADE.md 64 | 65 | 66 | 4.3.0 (2025-11-16) 67 | ------------------ 68 | 69 | - Using `forxer/gravatar` 5.3 70 | - Improved documentation 71 | 72 | 73 | 4.2.1 (2025-11-12) 74 | ------------------ 75 | 76 | - Stricter typings for return values + Facade docblock 77 | 78 | 79 | 4.2.0 (2025-09-16) 80 | ------------------ 81 | 82 | - Added ability to convert the Gravatar image to a base64-encoded data URL 83 | 84 | 85 | 4.1.0 (2025-03-18) 86 | ------------------ 87 | 88 | - Added support for Laravel 12.0 89 | 90 | 91 | 4.0.0 (2024-05-26) 92 | ------------------ 93 | 94 | - Added support for Laravel 11.0 95 | - Removed support for PHP prior to 8.2 96 | - Removed support for Laravel prior to 10.0 97 | - Removed support for `forxer/gravatar` prior to 5.0 98 | 99 | 100 | 3.0.0 (2023-03-22) 101 | ------------------ 102 | 103 | - Moved/renamed facade class from `LaravelGravatar\Facade` to `LaravelGravatar\Facades\Gravatar` 104 | - Added `LaravelGravatar\Casts\GravatarImage` and `LaravelGravatar\Casts\GravatarProfile` casters 105 | - Added methods for programmatic manipulation of image presets 106 | - Integration of our own `LaravelGravatar\Image` and `LaravelGravatar\Profile` classes which respectively extend `Gravatar\Image` and `Gravatar\Profile` from "parent" package 107 | 108 | 109 | 2.0.1 (2023-03-20) 110 | ------------------ 111 | 112 | - Improved preset support 113 | - Added some defaults customs presets 114 | - Rewritten README file 115 | 116 | 117 | 2.0.0 (2023-03-18) 118 | ------------------ 119 | 120 | - Removed support for PHP prior to 8.0 121 | - Removed support for Laravel prior to 8.0 122 | - Removed support for `forxer/gravatar` prior to 4.0 123 | - Renamed `forxer\LaravelGravatar\` namespace to `LaravelGravatar\` 124 | 125 | 126 | 1.9.0 (2023-02-21) 127 | ------------------ 128 | 129 | - Add support for Laravel 10.0 130 | 131 | 132 | 1.8.0 (2022-02-11) 133 | ------------------ 134 | 135 | - Add support for Laravel 9.0 136 | 137 | 138 | 1.7.0 (2020-09-20) 139 | ------------------ 140 | 141 | - Add support for Laravel 8.0 142 | 143 | 144 | 1.6.0 (2020-03-04) 145 | ------------------ 146 | 147 | - Add support for Laravel 7.0 148 | 149 | 150 | 1.5.1 (2019-12-30) 151 | ------------------ 152 | 153 | - Use Illuminate\Support\Str class instead of depreacated camel_case() helper 154 | 155 | 156 | 1.5.0 (2019-09-07) 157 | ------------------ 158 | 159 | - Add support for Laravel 6.0 160 | 161 | 162 | 1.4.0 (2019-03-07) 163 | ------------------ 164 | 165 | - Add support for Laravel 5.8 166 | 167 | 168 | 1.3.0 (2018-09-11) 169 | ------------------ 170 | 171 | - add support for Laravel 5.7 172 | 173 | 174 | 1.2.0 (2018-02-17) 175 | ------------------ 176 | 177 | - number version error: support a new release of Laravel is a new feature 178 | 179 | 180 | 1.1.1 (2018-02-11) 181 | ------------------ 182 | 183 | - add support for Laravel 5.6 184 | 185 | 186 | 1.1.0 (2017-10-01) 187 | ------------------ 188 | 189 | - Add support for Laravel 5.5 190 | 191 | 192 | 1.0.1 (2017-09-02) 193 | ------------------ 194 | 195 | - Fix call to default image via presets 196 | 197 | 198 | 1.0.0 (2017-08-31) 199 | ------------------ 200 | 201 | - First public release 202 | -------------------------------------------------------------------------------- /src/Image.php: -------------------------------------------------------------------------------- 1 | $config Configuration array from Laravel config 37 | * @param string|null $email The email address to generate the Gravatar for 38 | * @param string|null $presetName Optional preset name to apply 39 | */ 40 | public function __construct( 41 | public readonly array $config, 42 | ?string $email = null, 43 | ?string $presetName = null, 44 | ) { 45 | parent::__construct($email); 46 | 47 | if ($presetName !== null) { 48 | $this->setPreset($presetName); 49 | } 50 | } 51 | 52 | /** 53 | * Build the avatar URL based on the provided settings. 54 | * 55 | * Applies preset configuration before building the URL. 56 | * 57 | * @return string The complete Gravatar image URL 58 | */ 59 | public function url(): string 60 | { 61 | $this->applyPreset(); 62 | 63 | return parent::url(); 64 | } 65 | 66 | /** 67 | * Convert the Gravatar image to base64 encoded string. 68 | * 69 | * @param int $timeout HTTP request timeout in seconds 70 | * @return string|null Base64 encoded image data URL or null on failure 71 | */ 72 | public function toBase64(int $timeout = 5): ?string 73 | { 74 | try { 75 | // Apply preset before building URL 76 | $this->applyPreset(); 77 | 78 | // Get the Gravatar URL 79 | $url = parent::url(); 80 | 81 | // Download the image 82 | $response = Http::timeout($timeout)->get($url); 83 | 84 | if (! $response->successful()) { 85 | Log::warning('Gravatar request unsuccessful', [ 86 | 'email' => $this->email, 87 | 'url' => $url, 88 | 'status' => $response->status(), 89 | ]); 90 | 91 | return null; 92 | } 93 | 94 | $imageData = $response->body(); 95 | 96 | // Gravatar always returns PNG images 97 | return 'data:image/png;base64,'.base64_encode($imageData); 98 | } catch (Exception $exception) { 99 | Log::warning('Failed to convert Gravatar to base64', [ 100 | 'email' => $this->email, 101 | 'url' => $url ?? null, 102 | 'error' => $exception->getMessage(), 103 | ]); 104 | 105 | return null; 106 | } 107 | } 108 | 109 | /** 110 | * Get or set the preset name to be used. 111 | * 112 | * When called with a preset name, applies that preset and returns the instance for chaining. 113 | * When called without arguments, returns the current preset name or null if none is set. 114 | * 115 | * @param string|null $presetName The name of the preset to apply 116 | * @return ($presetName is null ? string|null : static) 117 | */ 118 | public function preset(?string $presetName = null): static|string|null 119 | { 120 | if ($presetName === null) { 121 | return $this->getPreset(); 122 | } 123 | 124 | return $this->setPreset($presetName); 125 | } 126 | 127 | /** 128 | * Get the preset name to be used. 129 | */ 130 | public function getPreset(): ?string 131 | { 132 | return $this->presetName; 133 | } 134 | 135 | /** 136 | * Set the preset name to be used. 137 | * 138 | * @param string|null $presetName The name of the preset to apply, or null to clear 139 | * @return static Returns the instance for method chaining 140 | */ 141 | public function setPreset(?string $presetName): static 142 | { 143 | $this->presetName = $presetName; 144 | 145 | return $this; 146 | } 147 | 148 | /** 149 | * Apply preset configuration to Gravatar image. 150 | * 151 | * @return static Returns the instance for method chaining 152 | * 153 | * @throws InvalidArgumentException When preset keys are invalid or preset is not found 154 | */ 155 | private function applyPreset(): static 156 | { 157 | if ($this->presetName === null) { 158 | return $this; 159 | } 160 | 161 | $presetValues = $this->presetValues(); 162 | 163 | if ($presetValues === []) { 164 | return $this; 165 | } 166 | 167 | foreach ($presetValues as $k => $v) { 168 | if (! PresetKey::isValid($k)) { 169 | throw new InvalidArgumentException( 170 | \sprintf('Gravatar image could not find method to use "%s" key', $k). 171 | \sprintf('Allowed preset keys are: "%s".', implode('", "', PresetKey::values())) 172 | ); 173 | } 174 | 175 | // Validate enum values before applying 176 | $this->validatePresetValue($k, $v); 177 | 178 | if (\strlen((string) $k) === 1) { 179 | $this->{$k}($v); 180 | } else { 181 | $this->{Str::camel($k)}($v); 182 | } 183 | } 184 | 185 | return $this; 186 | } 187 | 188 | /** 189 | * Validate preset value using enums for type safety. 190 | * 191 | * @param string $key The preset key 192 | * @param mixed $value The value to validate 193 | * 194 | * @throws InvalidArgumentException When value is invalid for the given key 195 | */ 196 | private function validatePresetValue(string $key, mixed $value): void 197 | { 198 | // Skip validation for null values and non-string values 199 | if ($value === null || ! \is_string($value)) { 200 | return; 201 | } 202 | 203 | $error = match ($key) { 204 | PresetKey::EXTENSION->value => \in_array($value, Extension::values()) 205 | ? null 206 | : \sprintf('Invalid extension "%s". Valid values: %s', $value, implode(', ', Extension::values())), 207 | PresetKey::MAX_RATING->value => \in_array($value, Rating::values()) 208 | ? null 209 | : \sprintf('Invalid rating "%s". Valid values: %s', $value, implode(', ', Rating::values())), 210 | PresetKey::DEFAULT_IMAGE->value => ! \in_array($value, DefaultImage::values()) && ! filter_var($value, FILTER_VALIDATE_URL) 211 | ? \sprintf('Invalid default image "%s". Valid values: %s or a valid URL', $value, implode(', ', DefaultImage::values())) 212 | : null, 213 | default => null, 214 | }; 215 | 216 | if ($error !== null) { 217 | throw new InvalidArgumentException($error); 218 | } 219 | } 220 | 221 | /** 222 | * Return preset values to use from configuration file. 223 | * 224 | * @return array Associative array of preset configuration values 225 | * 226 | * @throws InvalidArgumentException When preset configuration is missing or invalid 227 | */ 228 | private function presetValues(): array 229 | { 230 | // Resolve preset name from default config if not set 231 | if ($this->presetName === null) { 232 | if (empty($this->config['default_preset'])) { 233 | return []; 234 | } 235 | 236 | $this->presetName = $this->config['default_preset']; 237 | } 238 | 239 | // Validate presets configuration exists 240 | if (empty($this->config['presets']) || ! \is_array($this->config['presets'])) { 241 | throw new InvalidArgumentException('Unable to retrieve Gravatar presets array configuration.'); 242 | } 243 | 244 | // Validate preset exists 245 | if (! isset($this->config['presets'][$this->presetName])) { 246 | throw new InvalidArgumentException( 247 | \sprintf('Unable to retrieve Gravatar preset values, "%s" is probably a wrong preset name.', $this->presetName) 248 | ); 249 | } 250 | 251 | $presetValues = $this->config['presets'][$this->presetName]; 252 | 253 | // Validate preset values 254 | if (empty($presetValues) || ! \is_array($presetValues)) { 255 | throw new InvalidArgumentException( 256 | \sprintf('Unable to retrieve Gravatar "%s" preset values.', $this->presetName) 257 | ); 258 | } 259 | 260 | return $presetValues; 261 | } 262 | } 263 | -------------------------------------------------------------------------------- /docs/parameters.md: -------------------------------------------------------------------------------- 1 | Parameters 2 | ========== 3 | 4 | Gravatar images support several optional parameters to customize their appearance. All parameters can be set using helper methods, direct property assignment, or fluent shorthand methods. 5 | 6 | ## Working with Parameters 7 | 8 | All helper methods work in two modes: 9 | 10 | - **Setter mode**: When called with an argument, sets the value and returns `$this` for chaining 11 | - **Getter mode**: When called without arguments, returns the current value 12 | 13 | ```php 14 | $avatar = gravatar('user@example.com'); 15 | $avatar->size(120); // Setter: sets size to 120 16 | $currentSize = $avatar->size(); // Getter: returns 120 17 | ``` 18 | 19 | You can also use direct property assignment (PHP 8.4 property hooks with validation): 20 | 21 | ```php 22 | $avatar->size = 120; // Direct assignment 23 | echo $avatar->size; // Direct reading 24 | ``` 25 | 26 | ## Available Parameters 27 | 28 | ### Size 29 | 30 | Controls the avatar image size in pixels. 31 | 32 | **Range**: 1 to 2048 pixels 33 | **Default**: 80 34 | 35 | **1. Using helper method:** 36 | 37 | ```php 38 | $avatar = gravatar('user@example.com')->size(120); 39 | 40 | // Getter mode 41 | $currentSize = $avatar->size(); // Returns 120 42 | ``` 43 | 44 | **2. Using direct property:** 45 | 46 | ```php 47 | $avatar = gravatar('user@example.com'); 48 | $avatar->size = 200; 49 | 50 | // Reading the property 51 | echo $avatar->size; // 200 52 | ``` 53 | 54 | **Important**: Many users have lower resolution images, so requesting larger sizes may result in pixelation. 55 | 56 | ### Default Image 57 | 58 | Specifies what image to display when the email has no matching Gravatar or exceeds the rating limit. 59 | 60 | **Default**: Gravatar's default image (mystery person) 61 | 62 | #### Built-in Options 63 | 64 | - `'initials'` - Uses profile name as initials with generated colors 65 | - `'color'` - A generated solid color 66 | - `'404'` - Returns HTTP 404 if no gravatar exists 67 | - `'mp'` - Mystery person (simple silhouette) 68 | - `'identicon'` - Geometric pattern based on email hash 69 | - `'monsterid'` - Generated monster with different colors 70 | - `'wavatar'` - Generated face with differing features 71 | - `'retro'` - 8-bit arcade-style pixelated faces 72 | - `'robohash'` - Generated robot 73 | - `'blank'` - Transparent PNG image 74 | 75 | **1. Using helper method:** 76 | 77 | ```php 78 | $avatar = gravatar('user@example.com')->defaultImage('robohash'); 79 | 80 | // With custom URL 81 | $avatar = gravatar('user@example.com') 82 | ->defaultImage('https://example.com/default-avatar.png'); 83 | 84 | // Getter mode 85 | $current = $avatar->defaultImage(); // Returns current default image 86 | ``` 87 | 88 | **2. Using convenience methods (fluent shorthand):** 89 | 90 | ```php 91 | $avatar = gravatar('user@example.com')->defaultImageRobohash(); 92 | $avatar = gravatar('user@example.com')->defaultImageIdenticon(); 93 | $avatar = gravatar('user@example.com')->defaultImageMp(); 94 | $avatar = gravatar('user@example.com')->defaultImageRetro(); 95 | $avatar = gravatar('user@example.com')->defaultImageWavatar(); 96 | $avatar = gravatar('user@example.com')->defaultImageMonsterid(); 97 | $avatar = gravatar('user@example.com')->defaultImageBlank(); 98 | $avatar = gravatar('user@example.com')->defaultImageNotFound(); // 404 99 | ``` 100 | 101 | **3. Using direct property:** 102 | 103 | ```php 104 | $avatar = gravatar('user@example.com'); 105 | $avatar->defaultImage = 'identicon'; 106 | 107 | // Reading the property 108 | echo $avatar->defaultImage; // 'identicon' 109 | ``` 110 | 111 | #### Initials Default Image 112 | 113 | When using `'initials'` as the default image, you can customize which initials are displayed: 114 | 115 | **1. Using helper methods:** 116 | 117 | ```php 118 | $avatar = gravatar('user@example.com') 119 | ->defaultImage('initials') 120 | ->initials('JD'); 121 | 122 | $avatar = gravatar('user@example.com') 123 | ->defaultImage('initials') 124 | ->initialsName('John Doe'); 125 | ``` 126 | 127 | **2. Using convenience methods:** 128 | 129 | ```php 130 | // Automatically sets default to 'initials' 131 | $avatar = gravatar('user@example.com')->withInitials('JD'); 132 | $avatar = gravatar('user@example.com')->withInitialsName('John Doe'); 133 | ``` 134 | 135 | **3. Using direct properties:** 136 | 137 | ```php 138 | $avatar = gravatar('user@example.com'); 139 | $avatar->defaultImage = 'initials'; 140 | $avatar->initials = 'JD'; 141 | // or 142 | $avatar->initialsName = 'John Doe'; 143 | ``` 144 | 145 | ### Maximum Rating 146 | 147 | Gravatar allows users to self-rate their images. You can request images up to a certain rating. 148 | 149 | **Options**: 150 | - `'g'` - Suitable for all audiences (default) 151 | - `'pg'` - May contain rude gestures, provocative dress, mild swearing, or mild violence 152 | - `'r'` - May contain harsh profanity, intense violence, nudity, or hard drug use 153 | - `'x'` - May contain hardcore sexual imagery or extremely disturbing violence 154 | 155 | **1. Using helper method:** 156 | 157 | ```php 158 | $avatar = gravatar('user@example.com')->maxRating('pg'); 159 | 160 | // Getter mode 161 | $current = $avatar->maxRating(); // Returns current rating 162 | ``` 163 | 164 | **2. Using convenience methods (fluent shorthand):** 165 | 166 | ```php 167 | $avatar = gravatar('user@example.com')->ratingG(); 168 | $avatar = gravatar('user@example.com')->ratingPg(); 169 | $avatar = gravatar('user@example.com')->ratingR(); 170 | $avatar = gravatar('user@example.com')->ratingX(); 171 | ``` 172 | 173 | **3. Using direct property:** 174 | 175 | ```php 176 | $avatar = gravatar('user@example.com'); 177 | $avatar->maxRating = 'r'; 178 | 179 | // Reading the property 180 | echo $avatar->maxRating; // 'r' 181 | ``` 182 | 183 | ### File Extension 184 | 185 | Add a file extension to the URL. Some systems require this. 186 | 187 | **Options**: `'jpg'`, `'jpeg'`, `'png'`, `'gif'`, `'webp'` 188 | 189 | **1. Using helper method:** 190 | 191 | ```php 192 | $avatar = gravatar('user@example.com')->extension('webp'); 193 | 194 | // Getter mode 195 | $current = $avatar->extension(); // Returns current extension 196 | ``` 197 | 198 | **2. Using convenience methods (fluent shorthand):** 199 | 200 | ```php 201 | $avatar = gravatar('user@example.com')->extensionJpg(); 202 | $avatar = gravatar('user@example.com')->extensionJpeg(); 203 | $avatar = gravatar('user@example.com')->extensionPng(); 204 | $avatar = gravatar('user@example.com')->extensionGif(); 205 | $avatar = gravatar('user@example.com')->extensionWebp(); 206 | ``` 207 | 208 | **3. Using direct property:** 209 | 210 | ```php 211 | $avatar = gravatar('user@example.com'); 212 | $avatar->extension = 'png'; 213 | 214 | // Reading the property 215 | echo $avatar->extension; // 'png' 216 | ``` 217 | 218 | ### Force Default 219 | 220 | Force the default image to always be loaded, even if the email has a Gravatar. 221 | 222 | **1. Using helper method:** 223 | 224 | ```php 225 | $avatar = gravatar('user@example.com')->forceDefault(true); 226 | 227 | // Getter mode 228 | $isForced = $avatar->forceDefault(); // Returns true/false 229 | ``` 230 | 231 | **2. Using convenience methods:** 232 | 233 | ```php 234 | $avatar = gravatar('user@example.com')->enableForceDefault(); 235 | $avatar = gravatar('user@example.com')->disableForceDefault(); 236 | 237 | // Check if forcing default 238 | if ($avatar->forcingDefault()) { 239 | // Default is forced 240 | } 241 | ``` 242 | 243 | **3. Using direct property:** 244 | 245 | ```php 246 | $avatar = gravatar('user@example.com'); 247 | $avatar->forceDefault = true; 248 | 249 | // Reading the property 250 | echo $avatar->forceDefault ? 'forced' : 'not forced'; 251 | ``` 252 | 253 | ## Combining Parameters 254 | 255 | You can chain multiple parameters together: 256 | 257 | ```php 258 | $avatar = gravatar('user@example.com') 259 | ->size(120) 260 | ->defaultImage('robohash') 261 | ->maxRating('pg') 262 | ->extension('webp'); 263 | ``` 264 | 265 | Or use a mix of different approaches: 266 | 267 | ```php 268 | $avatar = gravatar('user@example.com'); 269 | $avatar->size = 120; // Direct property 270 | $avatar->defaultImage('robohash'); // Helper method 271 | $avatar->extensionWebp(); // Fluent shorthand 272 | ``` 273 | 274 | ## In Blade Templates 275 | 276 | ```blade 277 | Avatar 278 | 279 | Avatar 280 | ``` 281 | 282 | ## Profile Format 283 | 284 | For Gravatar profiles, you can specify the output format: 285 | 286 | **Options**: `'json'`, `'xml'`, `'php'`, `'vcf'`, `'qr'` 287 | 288 | **1. Using helper method:** 289 | 290 | ```php 291 | $profile = gravatar_profile('user@example.com')->format('json'); 292 | 293 | // Or pass format as second argument 294 | $profile = gravatar_profile('user@example.com', 'json'); 295 | 296 | // Getter mode 297 | $current = $profile->format(); // Returns current format 298 | ``` 299 | 300 | **2. Using convenience methods (fluent shorthand):** 301 | 302 | ```php 303 | $profile = gravatar_profile('user@example.com')->formatJson(); 304 | $profile = gravatar_profile('user@example.com')->formatXml(); 305 | $profile = gravatar_profile('user@example.com')->formatPhp(); 306 | $profile = gravatar_profile('user@example.com')->formatVcf(); 307 | $profile = gravatar_profile('user@example.com')->formatQr(); 308 | ``` 309 | 310 | **3. Using direct property:** 311 | 312 | ```php 313 | $profile = gravatar_profile('user@example.com'); 314 | $profile->format = 'xml'; 315 | 316 | // Reading the property 317 | echo $profile->format; // 'xml' 318 | ``` 319 | 320 | ## Next Steps 321 | 322 | - [View type-safe enums](enums.md) - Use enums for better type safety 323 | - [Configure settings](configuration.md) - Set up global configuration 324 | - [Define presets](presets.md) - Create reusable parameter combinations 325 | -------------------------------------------------------------------------------- /UPGRADE.md: -------------------------------------------------------------------------------- 1 | UPGRADE 2 | ======= 3 | 4 | From 4.x to 5.x 5 | --------------- 6 | 7 | This package now requires at least **PHP 8.4** and **Laravel 12**, your project must correspond to these prerequisites. 8 | 9 | ### Breaking changes 10 | 11 | #### 1. PHP and Laravel version requirements 12 | 13 | - **PHP version**: Minimum PHP version raised from 8.2 to 8.4 14 | - **Laravel version**: Support dropped for Laravel 10 and 11, now requires Laravel 12+ 15 | - **Gravatar library**: Updated to `forxer/gravatar` 6.0 16 | 17 | #### 2. Removed getter methods (from parent library) 18 | 19 | All getter methods from the base `Gravatar\Image` and `Gravatar\Profile` classes have been removed. Use direct property access instead: 20 | 21 | ```php 22 | // Before (v4.x) 23 | $email = $image->getEmail(); 24 | $size = $image->getSize(); 25 | $extension = $image->getExtension(); 26 | $maxRating = $image->getMaxRating(); 27 | $defaultImage = $image->getDefaultImage(); 28 | $initials = $image->getInitials(); 29 | $initialsName = $image->getName(); 30 | $forceDefault = $image->getForceDefault(); 31 | 32 | // After (v5.x) 33 | $email = $image->email; 34 | $size = $image->size; 35 | $extension = $image->extension; 36 | $maxRating = $image->maxRating; 37 | $defaultImage = $image->defaultImage; 38 | $initials = $image->initials; 39 | $initialsName = $image->initialsName; 40 | $forceDefault = $image->forceDefault; 41 | ``` 42 | 43 | #### 3. Removed setter methods (from parent library) 44 | 45 | All setter methods from the base library have been removed. Use helper methods or direct property assignment instead: 46 | 47 | ```php 48 | // Before (v4.x) 49 | $image->setEmail('email@example.com'); 50 | $image->setSize(120); 51 | $image->setExtension('jpg'); 52 | $image->setMaxRating('pg'); 53 | $image->setDefaultImage('robohash'); 54 | $image->setForceDefault(true); 55 | $image->setInitials('JD'); 56 | $image->setName('John Doe'); 57 | 58 | // After (v5.x) - use helper methods (recommended) 59 | $image->email('email@example.com'); 60 | $image->size(120); 61 | $image->extension('jpg'); 62 | $image->maxRating('pg'); 63 | $image->defaultImage('robohash'); 64 | $image->forceDefault(true); 65 | $image->initials('JD'); 66 | $image->initialsName('John Doe'); // Note: renamed from setName() 67 | 68 | // Or use direct property assignment 69 | $image->email = 'email@example.com'; 70 | $image->size = 120; 71 | $image->extension = 'jpg'; 72 | ``` 73 | 74 | #### 4. Renamed property and method 75 | 76 | The `name` property and `withName()` method have been renamed to `initialsName` and `withInitialsName()` for better clarity: 77 | 78 | ```php 79 | // Before (v4.x) 80 | $image->withName('John Doe'); 81 | $name = $image->name; 82 | 83 | // After (v5.x) 84 | $image->withInitialsName('John Doe'); 85 | $name = $image->initialsName; 86 | ``` 87 | 88 | #### 5. Removed short alias methods (from parent library) 89 | 90 | The short alias methods (`s()`, `e()`, `r()`, `d()`, `f()`) have been removed: 91 | 92 | ```php 93 | // Before (v4.x) 94 | $image->s(120); // size 95 | $image->e('jpg'); // extension 96 | $image->r('pg'); // rating 97 | $image->d('mp'); // default image 98 | $image->f(true); // force default 99 | 100 | // After (v5.x) - use full method names 101 | $image->size(120); 102 | $image->extension('jpg'); 103 | $image->maxRating('pg'); 104 | $image->defaultImage('mp'); 105 | $image->forceDefault(true); 106 | 107 | // Or use new fluent shorthand methods (recommended) 108 | $image->extensionJpg() 109 | ->ratingPg() 110 | ->defaultImageMp(); 111 | ``` 112 | 113 | #### 6. Preset configuration keys 114 | 115 | If you use custom presets in your `config/gravatar.php` file, ensure you're using full key names (not the short aliases): 116 | 117 | ```php 118 | // Before (v4.x) - short aliases were supported 119 | 'my_preset' => [ 120 | 's' => 120, // size 121 | 'e' => 'jpg', // extension 122 | 'r' => 'pg', // rating 123 | 'd' => 'mp', // default 124 | 'f' => true, // force default 125 | ], 126 | 127 | // After (v5.x) - use full names only 128 | 'my_preset' => [ 129 | 'size' => 120, 130 | 'extension' => 'jpg', 131 | 'max_rating' => 'pg', 132 | 'default_image' => 'mp', 133 | 'force_default' => true, 134 | ], 135 | ``` 136 | 137 | ### New features in v5.x 138 | 139 | #### 1. New `gravatar_profile()` helper 140 | 141 | A dedicated helper function for creating profile instances: 142 | 143 | ```php 144 | // Before (v4.x) - no dedicated helper for profiles 145 | use LaravelGravatar\Facades\Gravatar; 146 | $profile = Gravatar::profile('email@example.com'); 147 | 148 | // After (v5.x) - dedicated helper available 149 | $profile = gravatar_profile('email@example.com'); 150 | $profile = gravatar_profile('email@example.com', 'json'); 151 | ``` 152 | 153 | #### 2. Improved `gravatar()` helper 154 | 155 | The `gravatar()` helper now always returns an `Image` instance for consistency: 156 | 157 | ```php 158 | // Both return Image instances 159 | $avatar = gravatar('email@example.com'); 160 | $avatar = gravatar(); // Email can be set later 161 | $avatar->email = 'email@example.com'; 162 | ``` 163 | 164 | #### 3. Type-safe enums 165 | 166 | You can now use enum classes for better type safety and IDE support: 167 | 168 | ```php 169 | use Gravatar\Enum\Rating; 170 | use Gravatar\Enum\Extension; 171 | use Gravatar\Enum\DefaultImage; 172 | 173 | $image->maxRating(Rating::PG) 174 | ->extension(Extension::WEBP) 175 | ->defaultImage(DefaultImage::ROBOHASH); 176 | ``` 177 | 178 | #### 4. Fluent shorthand methods 179 | 180 | New fluent methods provide cleaner syntax: 181 | 182 | ```php 183 | $image->ratingPg() 184 | ->extensionWebp() 185 | ->defaultImageRobohash(); 186 | ``` 187 | 188 | See the [README](README.md) for complete documentation on enums and fluent methods. 189 | 190 | #### 4. Preset validation with enums 191 | 192 | **New in v5.0:** Preset configurations are now automatically validated using enums at runtime. 193 | 194 | Invalid preset values will throw detailed exceptions: 195 | 196 | ```php 197 | // config/gravatar.php 198 | 'presets' => [ 199 | 'invalid' => [ 200 | 'extension' => 'bmp', // ❌ Will throw InvalidArgumentException 201 | ], 202 | ], 203 | 204 | // Exception message: 205 | // Invalid extension "bmp". Valid values: jpg, jpeg, png, gif, webp 206 | ``` 207 | 208 | **Action required:** Review your preset configurations to ensure all values are valid: 209 | - `extension`: Must be `jpg`, `jpeg`, `png`, `gif`, or `webp` 210 | - `max_rating`: Must be `g`, `pg`, `r`, or `x` 211 | - `default_image`: Must be a valid enum value or a URL 212 | 213 | This validation helps catch configuration errors early, preventing invalid Gravatar URLs from being generated. 214 | 215 | ### Migration steps 216 | 217 | 1. **Update your PHP version to 8.4 or higher** 218 | 219 | 2. **Update your Laravel application to version 12.0 or newer** 220 | 221 | 3. **Update the package:** 222 | ```bash 223 | composer require forxer/laravel-gravatar:^5.0 224 | ``` 225 | 226 | 4. **Replace getter method calls with direct property access:** 227 | - Find: `->getEmail()` → Replace: `->email` 228 | - Find: `->getSize()` → Replace: `->size` 229 | - Find: `->getExtension()` → Replace: `->extension` 230 | - Find: `->getMaxRating()` → Replace: `->maxRating` 231 | - Find: `->getDefaultImage()` → Replace: `->defaultImage` 232 | - Find: `->getInitials()` → Replace: `->initials` 233 | - Find: `->getName()` → Replace: `->initialsName` 234 | - Find: `->getForceDefault()` → Replace: `->forceDefault` 235 | 236 | 5. **Replace setter method calls with helper methods:** 237 | - Find: `->setEmail(` → Replace: `->email(` 238 | - Find: `->setSize(` → Replace: `->size(` 239 | - Find: `->setExtension(` → Replace: `->extension(` 240 | - Find: `->setMaxRating(` → Replace: `->maxRating(` 241 | - Find: `->setDefaultImage(` → Replace: `->defaultImage(` 242 | - Find: `->setInitials(` → Replace: `->initials(` 243 | - Find: `->setName(` → Replace: `->initialsName(` 244 | - Find: `->setForceDefault(` → Replace: `->forceDefault(` 245 | 246 | 6. **Replace short alias methods:** 247 | - Find: `->s(` → Replace: `->size(` 248 | - Find: `->e(` → Replace: `->extension(` 249 | - Find: `->r(` → Replace: `->maxRating(` 250 | - Find: `->d(` → Replace: `->defaultImage(` 251 | - Find: `->f(` → Replace: `->forceDefault(` 252 | 253 | 7. **Update preset configurations** to use full key names (see section 6 above) 254 | 255 | 8. **Test your application thoroughly** to ensure compatibility with PHP 8.4 and Laravel 12 256 | 257 | 258 | From 3.x to 4.x 259 | --------------- 260 | 261 | This package now requires at least **PHP 8.2** and **Laravel 10**, your project must correspond to this prerequisites. 262 | 263 | 264 | From 2.x to 3.x 265 | --------------- 266 | 267 | Facade class moved/renamed from `LaravelGravatar\Facade` to `LaravelGravatar\Facades\Gravatar`, you need to replace calls to this one if you used it. 268 | 269 | For example: 270 | 271 | - Find: `use LaravelGravatar\Facade as Gravatar;` 272 | - Replace: `use LaravelGravatar\Facades\Gravatar;` 273 | 274 | Integration of our own `LaravelGravatar\Image` and `LaravelGravatar\Profile` classes which respectively extend `Gravatar\Image` and `Gravatar\Profile` from "parent" package. You should replace calls to these if you used them. 275 | 276 | For example: 277 | 278 | - Find: `use Gravatar\Image;` 279 | - Replace: `use LaravelGravatar\Image;` 280 | 281 | - Find: `use Gravatar\Profile;` 282 | - Replace: `use LaravelGravatar\Profile;` 283 | 284 | 285 | From 1.x to 2.x 286 | --------------- 287 | 288 | This package now requires at least **PHP 8** and **Laravel 8**, your project must correspond to this prerequisites. 289 | 290 | Namespaces have been renamed from `forxer\LaravelGravatar\` to `LaravelGravatar\` : 291 | 292 | - Find: `use forxer\LaravelGravatar\` 293 | - Replace: `use LaravelGravatar\` 294 | 295 | Since this version, if you use an undefined preset an exception is thrown. You must define presets before you can use them. 296 | Please consult the chapter of the README concerning presets to adjust your settings. 297 | -------------------------------------------------------------------------------- /docs/advanced.md: -------------------------------------------------------------------------------- 1 | Advanced Features 2 | ================= 3 | 4 | This guide covers advanced features and techniques for using Laravel Gravatar. 5 | 6 | ## Copying Instances 7 | 8 | You can create a copy of an existing Gravatar instance with all its settings using the `copy()` method. 9 | 10 | ### Basic Copying 11 | 12 | ```php 13 | // Create a base configuration 14 | $base = gravatar()->size(120)->defaultImageRobohash()->extensionWebp(); 15 | 16 | // Create copies with different emails 17 | $avatar1 = $base->copy('user1@example.com'); 18 | $avatar2 = $base->copy('user2@example.com'); 19 | $avatar3 = $base->copy('user3@example.com'); 20 | ``` 21 | 22 | ### Copying and Modifying 23 | 24 | ```php 25 | $base = gravatar('user@example.com') 26 | ->size(80) 27 | ->extensionWebp() 28 | ->ratingPg(); 29 | 30 | // Copy and change size 31 | $large = $base->copy()->size(200); 32 | 33 | // Copy with new email and different settings 34 | $other = $base->copy('other@example.com')->defaultImageIdenticon(); 35 | ``` 36 | 37 | ### Use Case: Generating Multiple Avatars 38 | 39 | ```php 40 | class UserController extends Controller 41 | { 42 | public function index() 43 | { 44 | $users = User::all(); 45 | 46 | // Define base configuration once 47 | $avatarConfig = gravatar() 48 | ->size(64) 49 | ->extensionWebp() 50 | ->defaultImageIdenticon() 51 | ->ratingPg(); 52 | 53 | // Generate avatar for each user 54 | foreach ($users as $user) { 55 | $user->avatar_url = $avatarConfig->copy($user->email)->url(); 56 | } 57 | 58 | return view('users.index', compact('users')); 59 | } 60 | } 61 | ``` 62 | 63 | ## Base64 Conversion 64 | 65 | Convert Gravatar images to base64-encoded data URLs for embedding directly in HTML or storing in databases. 66 | 67 | ### Basic Usage 68 | 69 | ```php 70 | $avatar = gravatar('user@example.com')->size(80); 71 | $base64 = $avatar->toBase64(); 72 | 73 | // Returns: data:image/png;base64,iVBORw0KGgoAAAANS... 74 | ``` 75 | 76 | ### With Custom Timeout 77 | 78 | ```php 79 | // Default timeout is 5 seconds 80 | $base64 = $avatar->toBase64(); 81 | 82 | // Custom timeout (in seconds) 83 | $base64 = $avatar->toBase64(timeout: 10); 84 | ``` 85 | 86 | ### Handling Failures 87 | 88 | The method returns `null` if the image cannot be fetched: 89 | 90 | ```php 91 | $base64 = $avatar->toBase64(); 92 | 93 | if ($base64 === null) { 94 | // Failed to fetch image 95 | // Use fallback or log error 96 | } 97 | ``` 98 | 99 | ### Use in Blade 100 | 101 | ```blade 102 | @php 103 | $base64Avatar = gravatar($user->email)->size(80)->toBase64(); 104 | @endphp 105 | 106 | @if($base64Avatar) 107 | Avatar 108 | @else 109 | Default Avatar 110 | @endif 111 | ``` 112 | 113 | ### Practical Use Cases 114 | 115 | #### Email Templates 116 | 117 | ```php 118 | // Generate avatar for email 119 | $avatar = gravatar($user->email)->size(100); 120 | $base64 = $avatar->toBase64(); 121 | 122 | Mail::send('emails.welcome', [ 123 | 'avatar' => $base64, 124 | 'user' => $user, 125 | ], function ($message) use ($user) { 126 | $message->to($user->email); 127 | }); 128 | ``` 129 | 130 | ```blade 131 | {{-- emails/welcome.blade.php --}} 132 | Your Avatar 133 | ``` 134 | 135 | #### Offline/PWA Applications 136 | 137 | ```php 138 | // Cache avatars as base64 for offline use 139 | class CacheUserAvatars extends Command 140 | { 141 | public function handle() 142 | { 143 | User::chunk(100, function ($users) { 144 | foreach ($users as $user) { 145 | $base64 = gravatar($user->email)->size(80)->toBase64(); 146 | Cache::put("avatar.{$user->id}", $base64, now()->addDays(7)); 147 | } 148 | }); 149 | } 150 | } 151 | ``` 152 | 153 | ### Important Notes 154 | 155 | - Gravatar always returns PNG images regardless of the extension specified 156 | - Failed fetches are logged automatically for debugging 157 | - Consider caching base64 data as it can be large 158 | - Network timeouts may occur for slow connections 159 | 160 | ## Working with Profiles 161 | 162 | ### Profile Formats 163 | 164 | ```php 165 | // HTML profile page 166 | $profile = gravatar_profile('user@example.com'); 167 | echo $profile; // https://www.gravatar.com/[hash] 168 | 169 | // JSON data 170 | $jsonProfile = gravatar_profile('user@example.com', 'json'); 171 | 172 | // XML data 173 | $xmlProfile = gravatar_profile('user@example.com')->formatXml(); 174 | 175 | // vCard 176 | $vcf = gravatar_profile('user@example.com')->formatVcf(); 177 | 178 | // QR Code 179 | $qr = gravatar_profile('user@example.com')->formatQr(); 180 | ``` 181 | 182 | ### Fetching Profile Data 183 | 184 | You can fetch profile data using Laravel's HTTP client or use the built-in `getData()` method: 185 | 186 | **Method 1: Using getData() (recommended)** 187 | 188 | ```php 189 | $profile = gravatar_profile('user@example.com'); 190 | $data = $profile->getData('user@example.com'); 191 | 192 | if ($data) { 193 | $displayName = $data['entry'][0]['displayName'] ?? null; 194 | $avatar = $data['entry'][0]['thumbnailUrl'] ?? null; 195 | // ... other profile fields 196 | } 197 | ``` 198 | 199 | **Method 2: Using Laravel's HTTP client** 200 | 201 | ```php 202 | use Illuminate\Support\Facades\Http; 203 | 204 | $profile = gravatar_profile('user@example.com', 'json'); 205 | $response = Http::get($profile->url()); 206 | 207 | if ($response->successful()) { 208 | $data = $response->json(); 209 | // Access profile data 210 | $displayName = $data['entry'][0]['displayName'] ?? null; 211 | } 212 | ``` 213 | 214 | ## Property Hooks (PHP 8.4) 215 | 216 | Laravel Gravatar leverages PHP 8.4 property hooks for automatic validation and conversion. 217 | 218 | ### Direct Property Access 219 | 220 | ```php 221 | $avatar = gravatar('user@example.com'); 222 | 223 | // Writing triggers validation 224 | $avatar->size = 120; // Valid 225 | $avatar->size = 5000; // Throws InvalidImageSizeException 226 | 227 | $avatar->extension = 'webp'; // Valid 228 | $avatar->extension = 'invalid'; // Throws InvalidImageExtensionException 229 | ``` 230 | 231 | ### Enum Conversion 232 | 233 | ```php 234 | use Gravatar\Enum\{Rating, Extension}; 235 | 236 | $avatar = gravatar('user@example.com'); 237 | 238 | // Automatic enum to string conversion 239 | $avatar->maxRating = Rating::PG; 240 | echo $avatar->maxRating; // 'pg' 241 | 242 | // Works both ways 243 | $avatar->extension = Extension::WEBP; // Enum 244 | $avatar->extension = 'jpg'; // String 245 | ``` 246 | 247 | ### Reading Properties 248 | 249 | ```php 250 | $avatar = gravatar('user@example.com') 251 | ->size(120) 252 | ->extensionWebp() 253 | ->ratingPg(); 254 | 255 | // Read current values 256 | echo $avatar->size; // 120 257 | echo $avatar->extension; // 'webp' 258 | echo $avatar->maxRating; // 'pg' 259 | echo $avatar->email; // 'user@example.com' 260 | ``` 261 | 262 | ### Asymmetric Visibility (PHP 8.4) 263 | 264 | Laravel Gravatar uses PHP 8.4's asymmetric visibility feature for internal properties that should be readable but not writable from outside: 265 | 266 | ```php 267 | $avatar = gravatar('user@example.com', 'medium'); 268 | 269 | // ✅ Reading is public 270 | echo $avatar->presetName; // 'medium' 271 | echo $avatar->config['default_preset']; // Access config 272 | 273 | // ❌ Writing is private (will cause error) 274 | // $avatar->presetName = 'other'; // Error: Cannot modify private(set) property 275 | // $avatar->config = []; // Error: Cannot modify private(set) property 276 | ``` 277 | 278 | **Protected properties:** 279 | - **`presetName`** - Uses `public private(set)` - The currently applied preset name (read-only from outside, can be modified internally via `setPreset()`) 280 | - **`config`** - Uses `public readonly` - The configuration array from Laravel config (completely immutable after construction) 281 | 282 | **Visibility types explained:** 283 | - `public private(set)` - Anyone can read, only the class can write (used for `presetName` which changes via presets) 284 | - `public readonly` - Anyone can read, no one can write after construction (used for `config` which never changes) 285 | 286 | This ensures configuration integrity while providing transparency about the current state. 287 | 288 | **Use case:** 289 | 290 | ```php 291 | $avatar = gravatar($email, 'large'); 292 | 293 | // Check which preset is applied 294 | if ($avatar->presetName === 'large') { 295 | // Preset is applied 296 | } 297 | 298 | // Access configuration settings 299 | $defaultPreset = $avatar->config['default_preset'] ?? null; 300 | ``` 301 | 302 | ## Customizing with Initials 303 | 304 | ### Using Initials as Default 305 | 306 | **1. Using helper methods:** 307 | 308 | ```php 309 | $avatar = gravatar('user@example.com') 310 | ->defaultImage('initials') 311 | ->initials('AB'); 312 | 313 | $avatar = gravatar('user@example.com') 314 | ->defaultImage('initials') 315 | ->initialsName('John Doe'); 316 | ``` 317 | 318 | **2. Using convenience methods:** 319 | 320 | ```php 321 | // Automatically set default to 'initials' and provide initials 322 | $avatar = gravatar('user@example.com')->withInitials('JD'); 323 | 324 | // Or from name 325 | $avatar = gravatar('user@example.com')->withInitialsName('John Doe'); 326 | ``` 327 | 328 | **3. Using direct properties:** 329 | 330 | ```php 331 | $avatar = gravatar('user@example.com'); 332 | $avatar->defaultImage = 'initials'; 333 | $avatar->initials = 'AB'; 334 | // or 335 | $avatar->initialsName = 'John Doe'; 336 | ``` 337 | 338 | ### In Models 339 | 340 | ```php 341 | class User extends Model 342 | { 343 | public function getAvatarAttribute() 344 | { 345 | return gravatar($this->email) 346 | ->withInitialsName($this->name) 347 | ->size(120); 348 | } 349 | } 350 | ``` 351 | 352 | ```blade 353 | {{ $user->name }} 354 | ``` 355 | 356 | ## Advanced Blade Techniques 357 | 358 | ### Component 359 | 360 | ```php 361 | // app/View/Components/GravatarAvatar.php 362 | namespace App\View\Components; 363 | 364 | use Illuminate\View\Component; 365 | 366 | class GravatarAvatar extends Component 367 | { 368 | public function __construct( 369 | public string $email, 370 | public int $size = 80, 371 | public string $preset = 'default' 372 | ) {} 373 | 374 | public function render() 375 | { 376 | return view('components.gravatar-avatar'); 377 | } 378 | } 379 | ``` 380 | 381 | ```blade 382 | {{-- resources/views/components/gravatar-avatar.blade.php --}} 383 | Avatar 390 | ``` 391 | 392 | Usage: 393 | 394 | ```blade 395 | 396 | ``` 397 | 398 | ### Custom Directive 399 | 400 | ```php 401 | // app/Providers/AppServiceProvider.php 402 | use Illuminate\Support\Facades\Blade; 403 | 404 | public function boot() 405 | { 406 | Blade::directive('gravatar', function ($expression) { 407 | return ""; 408 | }); 409 | } 410 | ``` 411 | 412 | Usage: 413 | 414 | ```blade 415 | Avatar 416 | ``` 417 | 418 | ## Testing 419 | 420 | ### Mocking in Tests 421 | 422 | ```php 423 | use LaravelGravatar\Facades\Gravatar; 424 | use LaravelGravatar\Image; 425 | 426 | public function test_user_has_gravatar() 427 | { 428 | $mock = Mockery::mock(Image::class); 429 | $mock->shouldReceive('url')->andReturn('https://gravatar.com/avatar/test'); 430 | 431 | Gravatar::shouldReceive('image') 432 | ->with('test@example.com') 433 | ->andReturn($mock); 434 | 435 | $response = $this->get('/users/1'); 436 | $response->assertSee('https://gravatar.com/avatar/test'); 437 | } 438 | ``` 439 | 440 | ## Performance Tips 441 | 442 | 1. **Cache Gravatar URLs** - They don't change frequently 443 | 2. **Use presets** - Reduce repetitive configuration 444 | 3. **Lazy load images** - Use `loading="lazy"` attribute 445 | 4. **Optimize sizes** - Don't request larger than displayed 446 | 5. **Use WebP** - Smaller file sizes with `.extensionWebp()` 447 | 448 | ```blade 449 | Avatar 454 | ``` 455 | 456 | ## Further Resources 457 | 458 | - [Gravatar Official Documentation](https://gravatar.com/site/implement/) - Official Gravatar API documentation 459 | - [forxer/gravatar Library](https://github.com/forxer/gravatar) - The parent framework-agnostic library 460 | - [GitHub Repository](https://github.com/forxer/laravel-gravatar) - Source code and issue tracker 461 | -------------------------------------------------------------------------------- /docs/presets.md: -------------------------------------------------------------------------------- 1 | Presets 2 | ======= 3 | 4 | Presets are named configurations that allow you to define reusable Gravatar settings throughout your application. This feature is **Laravel-specific** and not available in the parent `forxer/gravatar` library. 5 | 6 | ## Overview 7 | 8 | Presets provide: 9 | - **Reusability**: Define settings once, use everywhere 10 | - **Consistency**: Ensure all avatars in a context share the same settings 11 | - **Type Safety**: Automatic validation using the `PresetKey` enum 12 | - **Convenience**: Simple to use with helpers, facades, and Eloquent casts 13 | 14 | ## Configuration 15 | 16 | ### Publishing Configuration 17 | 18 | First, publish the configuration file: 19 | 20 | ```bash 21 | php artisan vendor:publish --tag="gravatar-config" 22 | ``` 23 | 24 | This creates `config/gravatar.php` in your application. 25 | 26 | ### Configuration Structure 27 | 28 | ```php 29 | null, 33 | 34 | 'presets' => [ 35 | // Your presets here 36 | ], 37 | ]; 38 | ``` 39 | 40 | ### Default Preset 41 | 42 | You can specify a default preset to be applied to all Gravatars unless overridden: 43 | 44 | ```php 45 | 'default_preset' => 'medium', 46 | ``` 47 | 48 | Set to `null` to disable the default preset. 49 | 50 | ## Defining Presets 51 | 52 | Presets are defined in the `presets` array of your configuration file: 53 | 54 | ```php 55 | 'presets' => [ 56 | 'small' => [ 57 | 'size' => 40, 58 | 'default_image' => 'mp', 59 | 'extension' => 'jpg', 60 | ], 61 | 62 | 'medium' => [ 63 | 'size' => 120, 64 | 'default_image' => 'mp', 65 | 'extension' => 'jpg', 66 | ], 67 | 68 | 'large' => [ 69 | 'size' => 360, 70 | 'default_image' => 'robohash', 71 | 'max_rating' => 'pg', 72 | 'extension' => 'webp', 73 | ], 74 | 75 | 'with_initials' => [ 76 | 'size' => 100, 77 | 'default_image' => 'initials', 78 | 'initials_name' => 'User Name', // Can be overridden 79 | 'extension' => 'webp', 80 | ], 81 | ], 82 | ``` 83 | 84 | ## Available Preset Keys 85 | 86 | Laravel Gravatar provides a `PresetKey` enum that defines all valid keys for preset configurations. 87 | 88 | ### PresetKey Enum 89 | 90 | ```php 91 | use LaravelGravatar\Enum\PresetKey; 92 | 93 | PresetKey::SIZE // 'size' 94 | PresetKey::DEFAULT_IMAGE // 'default_image' 95 | PresetKey::MAX_RATING // 'max_rating' 96 | PresetKey::EXTENSION // 'extension' 97 | PresetKey::FORCE_DEFAULT // 'force_default' 98 | PresetKey::INITIALS // 'initials' 99 | PresetKey::INITIALS_NAME // 'initials_name' 100 | ``` 101 | 102 | ### Key Descriptions 103 | 104 | | Key | Type | Description | Valid Values | 105 | |-----|------|-------------|--------------| 106 | | `size` | int | Avatar size in pixels | 1-2048 | 107 | | `default_image` | string | Default image type or URL | See [Default Images](#default-image-values) | 108 | | `max_rating` | string | Maximum allowed rating | `g`, `pg`, `r`, `x` | 109 | | `extension` | string | File extension | `jpg`, `jpeg`, `png`, `gif`, `webp` | 110 | | `force_default` | bool | Force default image | `true`, `false` | 111 | | `initials` | string | Explicit initials | e.g., `'JD'` | 112 | | `initials_name` | string | Full name for initials | e.g., `'John Doe'` | 113 | 114 | ### Default Image Values 115 | 116 | Valid values for the `default_image` key: 117 | 118 | - `'initials'` - Generated initials 119 | - `'color'` - Colored background 120 | - `'404'` - Return 404 if not found 121 | - `'mp'` - Mystery Person (default Gravatar logo) 122 | - `'identicon'` - Geometric pattern 123 | - `'monsterid'` - Monster avatar 124 | - `'wavatar'` - Generated face 125 | - `'retro'` - 8-bit arcade style 126 | - `'robohash'` - Robot avatar 127 | - `'blank'` - Transparent PNG 128 | - Any valid URL - Custom default image 129 | 130 | ## Using Presets 131 | 132 | ### 1. With Helper Function 133 | 134 | ```php 135 | // Apply preset in second argument 136 | $avatar = gravatar('user@example.com', 'small'); 137 | 138 | // Apply preset with method 139 | $avatar = gravatar('user@example.com')->preset('medium'); 140 | 141 | // Get current preset name 142 | $presetName = $avatar->preset(); // Returns 'medium' or null 143 | ``` 144 | 145 | ### 2. With Facade 146 | 147 | ```php 148 | use LaravelGravatar\Facades\Gravatar; 149 | 150 | $avatar = Gravatar::image('user@example.com', 'large'); 151 | ``` 152 | 153 | ### 3. With Eloquent Casts 154 | 155 | Specify a preset when casting model attributes: 156 | 157 | ```php 158 | use LaravelGravatar\Casts\GravatarImage; 159 | 160 | class User extends Model 161 | { 162 | protected $casts = [ 163 | 'avatar' => GravatarImage::class.':small', 164 | ]; 165 | } 166 | ``` 167 | 168 | Usage in Blade: 169 | 170 | ```blade 171 | {{ $user->name }} 172 | ``` 173 | 174 | ### 4. In Blade Templates 175 | 176 | ```blade 177 | Avatar 178 | 179 | {{-- Override preset values --}} 180 | Avatar 181 | ``` 182 | 183 | ## Preset Inheritance and Overriding 184 | 185 | Presets are applied **before** any other settings, allowing you to override preset values: 186 | 187 | ```php 188 | $avatar = gravatar('user@example.com', 'small') 189 | ->size(60) // Overrides preset size (40 → 60) 190 | ->extensionWebp(); // Overrides preset extension (jpg → webp) 191 | 192 | echo $avatar->size; // 60 193 | echo $avatar->extension; // 'webp' 194 | ``` 195 | 196 | **Order of application:** 197 | 1. Default preset (if configured) 198 | 2. Explicitly specified preset 199 | 3. Individual method calls or property assignments 200 | 201 | ## Preset Validation 202 | 203 | Laravel Gravatar **automatically validates** all preset values using enums for type safety. 204 | 205 | ### Validated Keys 206 | 207 | The following keys are validated at runtime: 208 | 209 | - **`extension`** - Validated against `Gravatar\Enum\Extension` 210 | - **`max_rating`** - Validated against `Gravatar\Enum\Rating` 211 | - **`default_image`** - Validated against `Gravatar\Enum\DefaultImage` or URL 212 | 213 | ### Key Validation 214 | 215 | All preset **keys** are validated against the `PresetKey` enum: 216 | 217 | ```php 218 | // ✅ Valid preset configuration 219 | 'presets' => [ 220 | 'valid' => [ 221 | 'size' => 120, // ✅ Valid key 222 | 'extension' => 'webp', // ✅ Valid key and value 223 | 'max_rating' => 'pg', // ✅ Valid key and value 224 | 'default_image' => 'robohash', // ✅ Valid key and value 225 | ], 226 | ], 227 | 228 | // ❌ Invalid preset configuration 229 | 'presets' => [ 230 | 'invalid' => [ 231 | 'invalid_key' => 'value', // ❌ Not in PresetKey enum 232 | ], 233 | ], 234 | ``` 235 | 236 | ### Value Validation 237 | 238 | Enum-backed values are validated automatically: 239 | 240 | ```php 241 | // ✅ Valid values 242 | 'presets' => [ 243 | 'validated' => [ 244 | 'extension' => 'webp', // ✅ Valid 245 | 'max_rating' => 'pg', // ✅ Valid 246 | 'default_image' => 'robohash', // ✅ Valid 247 | ], 248 | 249 | 'custom_url' => [ 250 | 'default_image' => 'https://example.com/avatar.png', // ✅ Valid (URL) 251 | ], 252 | ], 253 | 254 | // ❌ Invalid values 255 | 'presets' => [ 256 | 'invalid_extension' => [ 257 | 'extension' => 'bmp', // ❌ Invalid 258 | ], 259 | 260 | 'invalid_rating' => [ 261 | 'max_rating' => 'nc17', // ❌ Invalid 262 | ], 263 | ], 264 | ``` 265 | 266 | ### Error Messages 267 | 268 | When validation fails, you'll receive detailed error messages: 269 | 270 | **Invalid key:** 271 | ``` 272 | InvalidArgumentException: Gravatar image could not find method to use "invalid_key" key 273 | Allowed preset keys are: "size", "default_image", "max_rating", "extension", "force_default", "initials", "initials_name". 274 | ``` 275 | 276 | **Invalid extension:** 277 | ``` 278 | InvalidArgumentException: Invalid extension "bmp". Valid values: jpg, jpeg, png, gif, webp 279 | ``` 280 | 281 | **Invalid rating:** 282 | ``` 283 | InvalidArgumentException: Invalid rating "nc17". Valid values: g, pg, r, x 284 | ``` 285 | 286 | **Invalid default image:** 287 | ``` 288 | InvalidArgumentException: Invalid default image "invalid". Valid values: initials, color, 404, mp, identicon, monsterid, wavatar, retro, robohash, blank or a valid URL 289 | ``` 290 | 291 | ## PresetKey Enum Helper Methods 292 | 293 | The `PresetKey` enum provides utility methods: 294 | 295 | ```php 296 | use LaravelGravatar\Enum\PresetKey; 297 | 298 | // Get all valid preset keys as array 299 | $validKeys = PresetKey::values(); 300 | // Returns: ['size', 'default_image', 'max_rating', 'extension', 'force_default', 'initials', 'initials_name'] 301 | 302 | // Check if a key is valid 303 | if (PresetKey::isValid('size')) { 304 | // Key is valid 305 | } 306 | 307 | if (!PresetKey::isValid('invalid_key')) { 308 | // Key is invalid 309 | } 310 | ``` 311 | 312 | ### Benefits 313 | 314 | 1. **Type Safety**: Runtime validation prevents configuration errors 315 | 2. **Auto-completion**: IDE support for available keys 316 | 3. **Documentation**: Self-documenting code 317 | 4. **Error Prevention**: Catches typos and invalid keys/values early 318 | 5. **Consistency**: Single source of truth for valid preset configurations 319 | 320 | ## Example Configuration 321 | 322 | Here's a complete example configuration file: 323 | 324 | ```php 325 | 'default', 329 | 330 | 'presets' => [ 331 | 'default' => [ 332 | 'size' => 80, 333 | 'default_image' => 'mp', 334 | 'max_rating' => 'g', 335 | 'extension' => 'webp', 336 | ], 337 | 338 | 'thumbnail' => [ 339 | 'size' => 40, 340 | 'extension' => 'jpg', 341 | ], 342 | 343 | 'profile' => [ 344 | 'size' => 200, 345 | 'default_image' => 'identicon', 346 | 'max_rating' => 'pg', 347 | 'extension' => 'webp', 348 | ], 349 | 350 | 'admin' => [ 351 | 'size' => 120, 352 | 'default_image' => 'robohash', 353 | 'extension' => 'png', 354 | ], 355 | 356 | 'with_initials' => [ 357 | 'size' => 100, 358 | 'default_image' => 'initials', 359 | 'initials_name' => 'User Name', 360 | 'extension' => 'webp', 361 | ], 362 | 363 | 'high_quality' => [ 364 | 'size' => 512, 365 | 'extension' => 'webp', 366 | 'max_rating' => 'pg', 367 | 'default_image' => 'robohash', 368 | ], 369 | ], 370 | ]; 371 | ``` 372 | 373 | ## Practical Examples 374 | 375 | ### User List with Thumbnails 376 | 377 | ```php 378 | // Controller 379 | public function index() 380 | { 381 | $users = User::all(); 382 | return view('users.index', compact('users')); 383 | } 384 | ``` 385 | 386 | ```blade 387 | {{-- View --}} 388 | @foreach ($users as $user) 389 |
390 | {{ $user->name }} 391 | {{ $user->name }} 392 |
393 | @endforeach 394 | ``` 395 | 396 | ### Different Sizes in Profile 397 | 398 | ```blade 399 | {{-- Profile header --}} 400 | Profile Picture 401 | 402 | {{-- Sidebar --}} 403 | Avatar 404 | 405 | {{-- Comments --}} 406 | Avatar 407 | ``` 408 | 409 | ### API Resources 410 | 411 | ```php 412 | class UserResource extends JsonResource 413 | { 414 | public function toArray($request) 415 | { 416 | return [ 417 | 'id' => $this->id, 418 | 'name' => $this->name, 419 | 'email' => $this->email, 420 | 'avatar' => [ 421 | 'small' => gravatar($this->email, 'thumbnail')->url(), 422 | 'medium' => gravatar($this->email, 'medium')->url(), 423 | 'large' => gravatar($this->email, 'large')->url(), 424 | ], 425 | ]; 426 | } 427 | } 428 | ``` 429 | 430 | ## Comparison with Parent Library 431 | 432 | The preset system is **Laravel-specific** and extends the functionality of the parent `forxer/gravatar` library: 433 | 434 | ### Laravel Gravatar (this package) 435 | - ✅ Preset configurations 436 | - ✅ Configuration file integration 437 | - ✅ `PresetKey` enum for validation 438 | - ✅ Automatic runtime validation 439 | - ✅ Default preset support 440 | - ✅ Integration with helpers and Eloquent casts 441 | 442 | ### forxer/gravatar (parent library) 443 | - ❌ No preset system 444 | - ✅ Core enums (`Extension`, `Rating`, `DefaultImage`) 445 | - ✅ Method chaining 446 | - ✅ Property hooks 447 | 448 | The Laravel package uses the parent library's enums for **validating preset values**, while adding the `PresetKey` enum for **validating preset keys**. 449 | 450 | ## Next Steps 451 | 452 | - [Add Eloquent casts](casts.md) - Seamlessly integrate with your models 453 | - [Explore advanced features](advanced.md) - Base64 conversion, copying instances 454 | --------------------------------------------------------------------------------