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

Ouzo Goodies Laravel Package

letsdrink/ouzo-goodies

View on GitHub
Deep Wiki
Context7

Getting Started

Minimal Setup

  1. Installation:

    composer require letsdrink/ouzo-goodies
    

    Ensure your project uses PHP 8.4+ (required for full functionality).

  2. First Use Case: Replace verbose array operations with fluent syntax:

    use Ouzo\Goodies\Arrays;
    use Ouzo\Goodies\Functions;
    
    $filteredNames = Arrays::map($users, Functions::extractField('name'))
                           ->filter(Functions::notEmpty())
                           ->toArray();
    
  3. Key Entry Points:

    • Ouzo\Goodies\Arrays for collection operations
    • Ouzo\Goodies\Assert for fluent assertions
    • Ouzo\Goodies\Mock for test mocking

Where to Look First

  • Documentation: Ouzo Goodies Docs (especially the Utilities section)
  • Source: src/Ouzo/Goodies/ for class implementations
  • Test Examples: tests/ directory for practical usage patterns

Implementation Patterns

Core Workflows

1. Data Transformation Pipeline

// Traditional Laravel approach
$processed = collect($items)
    ->filter(fn($item) => $item['active'])
    ->map(fn($item) => $item['name'])
    ->unique()
    ->values()
    ->toArray();

// Ouzo Goodies equivalent
$processed = FluentArray::from($items)
    ->filter(Functions::extractField('active'))
    ->map(Functions::extractField('name'))
    ->unique()
    ->toArray();

2. Test Assertions

// Traditional PHPUnit
$this->assertCount(3, $users);
$this->assertContains('John', $users);
$this->assertStringStartsWith('J', $users[0]);

// Ouzo Goodies
Assert::thatArray($users)
    ->hasSize(3)
    ->contains('John');

Assert::thatString($users[0]['name'])
    ->startsWith('J');

3. Mocking Services

// Traditional mocking
$mock = $this->createMock(UserRepository::class);
$mock->method('find')->willReturn($user);

// Ouzo Goodies
$mock = Mock::create(UserRepository::class);
Mock::when($mock)->find(1)->thenReturn($user);

4. DateTime Operations

// Traditional Carbon
$futureDate = now()->addYears(1)->addMonths(2);

// Ouzo Goodies
$futureDate = Clock::now()
    ->plusYears(1)
    ->plusMonths(2)
    ->format();

Integration Tips

Laravel-Specific Patterns

  1. Service Container Integration:

    // Bind Ouzo utilities as singletons
    $this->app->singleton(FluentArray::class, fn() => new FluentArray([]));
    
  2. Collection Macros:

    // Extend Laravel Collections with Ouzo methods
    collect([])->macro('ouzoMap', function($callback) {
        return FluentArray::from($this->all())
            ->map($callback)
            ->toArray();
    });
    
  3. TestCase Setup:

    use Ouzo\Goodies\Assert;
    use Ouzo\Goodies\Mock;
    
    class TestCase extends \Tests\TestCase {
        protected function setUp(): void {
            Mock::resetAll();
        }
    
        protected function assertArrayContainsKeyValue($array, $key, $value) {
            Assert::thatArray($array)->containsKey($key)->containsValue($value);
        }
    }
    

Performance Considerations

  • Fluent Arrays: Prefer for complex chained operations (readability > micro-optimizations)
  • Native PHP 8.4: Use array_find(), array_any() directly when possible (they delegate to Ouzo under the hood)
  • Mocking: Avoid over-mocking - use for complex dependencies only

Gotchas and Tips

Common Pitfalls

  1. PHP 8.4 Requirements:

    • array_find(), array_any(), array_all() won't work on older PHP versions
    • #[Deprecated] attributes may trigger IDE warnings
  2. Fluent Method Chaining:

    // This won't work - FluentArray methods return self
    FluentArray::from($items)->filter()->map(); // Missing closures!
    
    // Correct:
    FluentArray::from($items)
        ->filter(Functions::extractField('active'))
        ->map(Functions::extractField('name'));
    
  3. Mock Verification:

    // Forgetting to verify calls
    Mock::verify($mock)->method('arg'); // Must be called after test
    
  4. Clock Timezone:

    // Defaults to system timezone - set explicitly if needed
    Clock::setTimezone('UTC');
    

Debugging Tips

  1. Assertion Failures:

    • Ouzo assertions provide detailed failure messages:
    Assert::thatArray($users)->hasSize(3); // Shows actual size if failed
    
  2. Mock Debugging:

    // Inspect mock interactions
    Mock::verify($mock)->method('arg')->times(1);
    Mock::verify($mock)->method('nonexistent')->times(0);
    
  3. FluentArray Inspection:

    // Debug intermediate states
    $fluent = FluentArray::from($items)
        ->filter(/* ... */)
        ->tap(fn($arr) => logger()->debug('Filtered:', $arr));
    

Extension Points

  1. Custom Comparators:

    use Ouzo\Goodies\Comparator;
    
    $customComparator = Comparator::create(function($a, $b) {
        return $a->priority <=> $b->priority;
    });
    
    Arrays::sort($items, $customComparator);
    
  2. Custom Assertions:

    Assert::extend('isValidEmail', function($string) {
        return filter_var($string, FILTER_VALIDATE_EMAIL) !== false;
    });
    
    Assert::thatString($email)->isValidEmail();
    
  3. Fluent Function Composition:

    $transform = FluentFunctions::extractField('name')
        ->removePrefix('user_')
        ->prepend('User: ');
    
    // Reuse across multiple operations
    Arrays::map($users, $transform);
    

Configuration Quirks

  1. Clock Defaults:

    • Uses system timezone by default
    • No global configuration - set per operation or via Clock::setTimezone()
  2. Mock Behavior:

    • By default, unmocked methods return null
    • Configure via Mock::setDefaultReturnValue($value)
  3. Assertion Strictness:

    • Use Assert::that()->strict() for type-sensitive comparisons
    • Default behavior matches PHPUnit's loose comparison

Pro Tips

  1. Function Composition:

    // Create reusable transformations
    $toUpper = FluentFunctions::create(fn($s) => strtoupper($s));
    Arrays::map($strings, $toUpper);
    
  2. Path Operations:

    // Cross-platform path handling
    $normalized = Path::normalize('/var//user/../home');
    // => '/var/home'
    
  3. Cache Utilities:

    // Simple in-memory cache
    Cache::set('key', $value, 3600);
    $value = Cache::get('key');
    
  4. Dynamic Proxies:

    // Create partial mocks
    $partialMock = Mock::create(Service::class, [
        'method1' => fn() => 'hardcoded',
        'method2' => fn() => throw new \RuntimeException()
    ]);
    
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.
milito/query-filter
apiboxsym/user-bundle
apiboxsym/health-check-bundle
jayeshmepani/jpl-moshier-ephemeris-php
elnasnato/laraliveui
labrodev/rest-sdk
sampaui/sampaui
babelqueue/php-sdk
facebook/capi-param-builder-php
babelqueue/symfony
hamzi/corewatch
minionfactory/raw-hydrator
hexters/coinpayment
rjcodes/rjcms
act-training/laravel-permissions-manager
alimarchal/laravel-chart-of-accounts
babenkoivan/elastic-scout-driver
mkwebdesign/filament-watchdog-v5
renatomarinho/laravel-page-speed
zedmagdy/filament-business-hours