Weave Code
Code Weaver
Helps Laravel developers discover, compare, and choose open-source packages. See popularity, security, maintainers, and scores at a glance to make better decisions.
Feedback
Share your thoughts, report bugs, or suggest improvements.
Subject
Message

Workshop Unit Conversions Laravel Package

spatie/workshop-unit-conversions

Lightweight PHP package for performing unit conversions in Laravel or any PHP app. Install via Composer and convert values between supported units with a simple API. Includes tests, changelog, and MIT license.

View on GitHub
Deep Wiki
Context7

Getting Started

The spatie/workshop-unit-conversions package simplifies unit conversions in Laravel by providing a clean, fluent API for common measurements (e.g., length, weight, temperature, volume). Start by installing it via Composer:

composer require spatie/workshop-unit-conversions

The package is self-contained—no configuration is required. Begin with basic conversions like:

use Spatie\WorkshopUnitConversions\UnitConverter;

// Convert 10 kilometers to miles
$converter = new UnitConverter();
$result = $converter->convert('10 kilometers', 'miles'); // Returns ~6.21371

For Laravel-specific use, leverage dependency injection:

// In a controller/service
public function __construct(private UnitConverter $converter) {}

public function convertDistance(float $value, string $from, string $to): float
{
    return $this->converter->convert("$value $from", $to);
}

First use case: Validate user-submitted measurements (e.g., product dimensions) by converting them to a standardized unit before storage.


Implementation Patterns

1. Fluent API for Chained Conversions

Leverage the package’s method chaining for multi-step conversions:

$converter->convert('500 grams', 'pounds')
          ->round(2) // Optional: Round to 2 decimal places
          ->toString(); // Returns "1.10231 pounds"

Workflow:

  • Input Validation: Sanitize user input (e.g., trim(), strtolower()) before passing to convert().
  • Caching: Cache frequent conversions (e.g., currency-like rates) using Laravel’s cache:
    $cacheKey = "conversion_{$from}_{$to}_{$value}";
    return Cache::remember($cacheKey, now()->addHours(1), fn() =>
        $converter->convert("$value $from", $to)
    );
    

2. Integration with Eloquent

Store converted values in a database while keeping original units for display:

// Migration
$table->string('dimension_value')->comment('Stored in meters');
$table->string('dimension_unit');

// Model
public function getDisplayDimensionAttribute(): string
{
    return $this->converter->convert(
        "{$this->dimension_value} meters",
        $this->dimension_unit
    )->toString();
}

3. Custom Units

Extend the package by adding custom units via a service provider:

// app/Providers/UnitConversionServiceProvider.php
public function register()
{
    UnitConverter::addUnit('lightyears', 'astronomical_units', 63241.077);
}

Tip: Use this for domain-specific units (e.g., "pages" to "words" for publishing apps).

4. Form Requests

Validate and convert measurements in form requests:

public function rules()
{
    return [
        'weight' => 'required|string',
    ];
}

public function withValidator($validator)
{
    $validator->after(function ($validator) {
        $value = $this->weight;
        $converted = UnitConverter::convert($value, 'kilograms');
        $this->merge([
            'weight_kg' => $converted->toString(),
        ]);
    });
}

Gotchas and Tips

Pitfalls

  1. Case Sensitivity:

    • Units must match exactly (e.g., "kilometers""Kilometers"). Use strtolower() on user input:
      $converter->convert(strtolower($userInput), $targetUnit);
      
  2. Unsupported Units:

    • The package lacks some niche units (e.g., "furlongs"). Extend via UnitConverter::addUnit() or file an issue.
  3. Precision Loss:

    • Floating-point conversions may introduce rounding errors. Use round() or number_format():
      $converter->convert('1 meter', 'feet')->round(4); // 3.28084
      
  4. Laravel Cache Key Collisions:

    • Avoid caching raw user input (e.g., "5'6"" for height). Normalize first:
      Cache::remember("conversion_{$normalizedValue}_{$from}_{$to}", ...);
      

Debugging

  • Check Available Units: Dump the registry:
    dd(UnitConverter::getRegistry());
    
  • Validate Input: Use UnitConverter::isValidUnit($input) to test if a unit is supported.

Extension Points

  1. Custom Conversion Logic: Override the converter’s convert() method in a decorator:

    class CustomUnitConverter extends UnitConverter
    {
        public function convert(string $value, string $to): self
        {
            // Add custom logic (e.g., log conversions)
            return parent::convert($value, $to);
        }
    }
    
  2. Localization: Translate unit names for UI display:

    $units = [
        'kilometers' => __('units.km'),
        'miles' => __('units.miles'),
    ];
    
  3. Testing: Mock the converter in tests:

    $mock = Mockery::mock(UnitConverter::class);
    $mock->shouldReceive('convert')
         ->with('10 kg', 'pounds')
         ->andReturn(new UnitConverter('22.0462'));
    

Performance

  • Avoid Re-instantiation: Store the UnitConverter as a singleton in a service container or app binding:

    $app->singleton(UnitConverter::class, fn() => new UnitConverter());
    
  • Batch Conversions: For bulk operations (e.g., ETL), pre-load the registry:

    $registry = UnitConverter::getRegistry();
    // Process conversions manually for performance-critical paths
    
Weaver

How can I help you explore Laravel packages today?

Conversation history is not saved when not logged in.
Prompt
Add packages to context
No packages found.
davejamesmiller/laravel-breadcrumbs
artisanry/parsedown
christhompsontldr/phpsdk
enqueue/dsn
bunny/bunny
enqueue/test
enqueue/null
enqueue/amqp-tools
milesj/emojibase
bower-asset/punycode
bower-asset/inputmask
bower-asset/jquery
bower-asset/yii2-pjax
laravel/nova
spatie/laravel-mailcoach
spatie/laravel-superseeder
laravel/liferaft
nst/json-test-suite
danielmiessler/sec-lists
jackalope/jackalope-transport