PHP code example of fiachehr / laravel-eav

1. Go to this page and download the library: Download fiachehr/laravel-eav library. Choose the download type require.

2. Extract the ZIP file and open the index.php.

3. Add this code to the index.php.
    
        
<?php
require_once('vendor/autoload.php');

/* Start to develop here. Best regards https://php-download.com/ */

    

fiachehr / laravel-eav example snippets


use Fiachehr\LaravelEav\Domain\Shared\Traits\HasAttributes;
use Illuminate\Database\Eloquent\Model;

class Product extends Model
{
    use HasAttributes;
    
    // Your model code...
}

// Get all attributes with their values
$product->eavAttributes; // Returns collection with pivot values

// Get attribute value by ID or slug
$value = $product->getEavAttributeValue(1); // by ID
$value = $product->getEavAttributeValue('color'); // by slug
$value = $product->getEavAttributeValueBySlug('color');

// Get all attribute values as key-value pairs
// Keys can be 'id', 'slug', or 'logical_id'
$values = $product->getEavAttributeValues('slug'); 
// Returns: ['color' => 'red', 'size' => 'large', 'price' => 100]

$values = $product->getEavAttributeValues('id'); 
// Returns: [1 => 'red', 2 => 'large', 3 => 100]

// Get all attribute values as Eloquent models
$attributeValues = $product->eavAttributeValues; 
// Returns collection of EloquentAttributeValue models

// Set attribute values (by ID or slug)
$product->setEavAttributeValues([
    1 => 'Value 1',           // by ID
    'color' => 'red',         // by slug
    'size' => 'large',        // by slug
    'price' => 100.50,        // number
    'is_active' => true,      // boolean
    'created_at' => '2024-01-01', // date
]);

// Set a single attribute value
$product->setEavAttributeValue('color', 'blue');
$product->setEavAttributeValue(1, 'new value');

// Sync attribute values (removes old ones not in the array)
$product->syncEavAttributeValues([
    'color' => 'red',
    'size' => 'medium',
]);

// Remove a specific attribute
$product->removeEavAttributeValue('color');
$product->removeEavAttributeValue(1);

// Clear all attribute values
$product->clearEavAttributeValues();

use Fiachehr\LaravelEav\Domain\Enums\AttributeType;
use Fiachehr\LaravelEav\Domain\Enums\ValidationType;

// Create an attribute with email validation
$attribute = Attribute::create([
    'title' => 'Email Address',
    'type' => AttributeType::TEXT,
    'validations' => [
        ValidationType::REQUIRED->value,
        ValidationType::EMAIL->value,
    ],
]);

// Create an attribute with image file validation
$attribute = Attribute::create([
    'title' => 'Profile Image',
    'type' => AttributeType::FILE,
    'validations' => [
        ValidationType::REQUIRED->value,
        ValidationType::IMAGE->value,
        ['type' => ValidationType::MAX_FILE_SIZE->value, 'parameter' => 2048], // 2MB
    ],
]);

// Create an attribute with min/max length validation
$attribute = Attribute::create([
    'title' => 'Description',
    'type' => AttributeType::TEXTAREA,
    'validations' => [
        ValidationType::REQUIRED->value,
        ['type' => ValidationType::MIN_LENGTH->value, 'parameter' => 10],
        ['type' => ValidationType::MAX_LENGTH->value, 'parameter' => 500],
    ],
]);

use Fiachehr\LaravelEav\Domain\Services\AttributeValidator;

$validator = new AttributeValidator();

try {
    // Validate a value against attribute validations
    $validator->validate(
        AttributeType::TEXT,
        '[email protected]',
        [ValidationType::EMAIL->value]
    );
    
    // Value is valid
} catch (\Illuminate\Validation\ValidationException $e) {
    // Handle validation errors
    $errors = $e->validator->errors();
}

use Fiachehr\LaravelEav\Domain\Services\AttributeValidator;

$validator = new AttributeValidator();

// Get Laravel validation rules for an attribute
$rules = $validator->getValidationRules(
    AttributeType::TEXT,
    [
        ValidationType::REQUIRED->value,
        ValidationType::EMAIL->value,
        ['type' => ValidationType::MAX_LENGTH->value, 'parameter' => 255],
    ]
);

// Use in Laravel Form Request
$request->validate([
    'email' => $rules,
]);

use Fiachehr\LaravelEav\Domain\Entities\Attribute;
use Fiachehr\LaravelEav\Domain\Enums\AttributeType;
use Fiachehr\LaravelEav\Domain\Repositories\AttributeRepositoryInterface;

// Create attribute in English
$attributeEn = new Attribute(
    id: null,
    logicalId: 'color-en',
    title: 'Color',
    slug: 'color',
    type: AttributeType::TEXT,
    description: 'Product color',
    values: [],
    validations: [],
    isActive: true,
    language: 'en'
);

// Create attribute in Persian
$attributeFa = new Attribute(
    id: null,
    logicalId: 'color-fa',
    title: 'رنگ',
    slug: 'color-fa',
    type: AttributeType::TEXT,
    description: 'رنگ محصول',
    values: [],
    validations: [],
    isActive: true,
    language: 'fa'
);

$repository = app(AttributeRepositoryInterface::class);
$repository->create($attributeEn);
$repository->create($attributeFa);

use Fiachehr\LaravelEav\Infrastructure\Persistence\Eloquent\EloquentAttribute;

// Get attributes for a specific language
$englishAttributes = EloquentAttribute::forLanguage('en')->get();
$persianAttributes = EloquentAttribute::forLanguage('fa')->get();

// Get attributes for current locale
$currentLanguageAttributes = EloquentAttribute::forCurrentLanguage()->get();

// Get attributes for multiple languages
$multiLanguageAttributes = EloquentAttribute::forLanguages(['en', 'fa', 'de'])->get();

// Exclude a specific language
$nonEnglishAttributes = EloquentAttribute::excludeLanguage('en')->get();

// Combine with other scopes
$activeEnglishAttributes = EloquentAttribute::forLanguage('en')
    ->where('is_active', true)
    ->get();

use Fiachehr\LaravelEav\Domain\Repositories\AttributeRepositoryInterface;
use Fiachehr\LaravelEav\Domain\Repositories\AttributeGroupRepositoryInterface;

$attributeRepository = app(AttributeRepositoryInterface::class);
$groupRepository = app(AttributeGroupRepositoryInterface::class);

// Get attributes by language
$englishAttributes = $attributeRepository->findByLanguage('en');
$currentLanguageAttributes = $attributeRepository->findByCurrentLanguage();
$multiLanguageAttributes = $attributeRepository->findByLanguages(['en', 'fa']);

// Same for attribute groups
$englishGroups = $groupRepository->findByLanguage('en');
$currentLanguageGroups = $groupRepository->findByCurrentLanguage();

use Fiachehr\LaravelEav\Domain\Shared\Traits\HasTranslations;
use Fiachehr\LaravelEav\Infrastructure\Persistence\Eloquent\EloquentAttribute;

class Attribute extends EloquentAttribute
{
    use HasTranslations;
    
    // Define which fields are translatable
    protected $translatable = [
        'title',
        'description',
    ];
}

use Fiachehr\LaravelEav\Infrastructure\Persistence\Eloquent\EloquentAttribute;

$attribute = EloquentAttribute::with('translations')->find(1);

// Get translation for a specific field and locale
$translatedTitle = $attribute->getTranslation('title', 'fa');
// Returns: 'رنگ' or null if not found

// Get all translations grouped by locale
$allTranslations = $attribute->getAllTranslations();
// Returns: ['en' => ['title' => 'Color', 'description' => '...'], 'fa' => ['title' => 'رنگ', ...]]

// Get translations for a specific locale
$persianTranslations = $attribute->getTranslationsForLocale('fa');
// Returns: ['title' => 'رنگ', 'description' => '...']

// Get translations for a specific key across all locales
$titleTranslations = $attribute->getTranslationsForKey('title');
// Returns: ['en' => 'Color', 'fa' => 'رنگ', 'de' => 'Farbe']

// Check if translation exists for a locale
if ($attribute->hasTranslation('fa')) {
    // Translation exists for Persian
}

// Check if translation exists for a specific key and locale
if ($attribute->hasTranslationForKey('title', 'fa')) {
    // Title translation exists for Persian
}

// Access translations relationship directly
$translations = $attribute->translations;
// Returns: Collection of EloquentTranslation models

// Set a single translation
$attribute->setTranslation('title', 'fa', 'رنگ');
$attribute->setTranslation('description', 'fa', 'رنگ محصول');

// Set multiple translations at once
$attribute->setTranslations([
    'title' => [
        'en' => 'Color',
        'fa' => 'رنگ',
        'de' => 'Farbe',
    ],
    'description' => [
        'en' => 'Product color',
        'fa' => 'رنگ محصول',
        'de' => 'Produktfarbe',
    ],
]);

// Or using locale-first format
$attribute->setTranslations([
    'en' => [
        'title' => 'Color',
        'description' => 'Product color',
    ],
    'fa' => [
        'title' => 'رنگ',
        'description' => 'رنگ محصول',
    ],
]);

// Delete a specific translation
$attribute->deleteTranslation('title', 'fa');

// Delete all translations for a specific locale
$attribute->deleteTranslationsForLocale('fa');

// Delete all translations for a specific key across all locales
$attribute->deleteTranslationsForKey('title');

// Delete all translations for this model
$attribute->deleteAllTranslations();

use Fiachehr\LaravelEav\Infrastructure\Persistence\Eloquent\EloquentAttribute as BaseEloquentAttribute;
use Fiachehr\LaravelEav\Domain\Shared\Traits\HasTranslations;

class Attribute extends BaseEloquentAttribute
{
    use HasTranslations;
    
    protected $translatable = ['title', 'description'];
}

// The translations relation will automatically work with existing data
// that uses the base class name (EloquentAttribute)
$attribute = Attribute::with('translations')->find(1);
$translations = $attribute->translations; // Works correctly!

use Fiachehr\LaravelEav\Domain\Shared\Traits\HasAttributes;

class Product extends Model
{
    use HasAttributes;
}

// Get attributes for current language
$product = Product::find(1);
$currentLanguageAttributes = $product->eavAttributes()
    ->where('language', app()->getLocale())
    ->get();

// Or filter by specific language
$englishAttributes = $product->eavAttributes()
    ->where('language', 'en')
    ->get();

// config/app.php
'locale' => 'en',
'supported_locales' => ['en', 'fa', 'de', 'es'],

// Search products by attribute value (exact match)
$products = Product::whereEavAttribute('color', 'red')->get();

// Search with LIKE (partial match)
$products = Product::whereEavAttributeLike('title', 'laptop')->get();

// Search by number range
$products = Product::whereEavAttributeBetween('price', 100, 500)->get();

// Search by date range
$products = Product::whereEavAttributeDateBetween('created_at', '2024-01-01', '2024-12-31')->get();

// Search where value is IN array
$products = Product::whereEavAttributeIn('color', ['red', 'blue', 'green'])->get();

// Search where value is NOT IN array
$products = Product::whereEavAttributeNotIn('status', ['deleted', 'archived'])->get();

// Search where value is NULL
$products = Product::whereEavAttributeNull('notes')->get();

// Search where value is NOT NULL
$products = Product::whereEavAttributeNotNull('description')->get();

// Multiple conditions (AND - all must match)
$products = Product::whereEavAttributes([
    ['attribute' => 'color', 'value' => 'red'],
    ['attribute' => 'size', 'value' => 'large', 'operator' => '='],
    ['attribute' => 'price', 'value' => 100, 'operator' => '>='],
])->get();

// Combine with other Laravel query methods
$products = Product::whereEavAttribute('color', 'red')
    ->where('status', 'active')
    ->orderBy('created_at', 'desc')
    ->paginate(20);

use Fiachehr\LaravelEav\Infrastructure\Query\EavQueryBuilder;

// Basic usage - get product IDs matching criteria
$query = Product::eavQuery();
$query->whereText('color', 'red')
      ->whereNumber('price', '>', 100)
      ->whereBoolean('in_stock', true);

$productIds = $query->getAttributableIds();
$products = Product::whereIn('id', $productIds)->get();

// Or use the helper method
$products = Product::findByEav(function ($query) {
    $query->whereText('color', 'red')
          ->whereNumberBetween('price', 100, 500)
          ->whereDateBetween('created_at', '2024-01-01', '2024-12-31');
});

$query = Product::eavQuery();

// Exact match
$query->whereText('title', 'Laptop');

// LIKE search (contains)
$query->whereTextLike('description', 'gaming');

// IN array
$query->whereTextIn('color', ['red', 'blue', 'green']);

// NOT IN array
$query->whereTextNotIn('status', ['deleted', 'archived']);

// IS NULL
$query->whereTextNull('notes');

// IS NOT NULL
$query->whereTextNotNull('description');

$query = Product::eavQuery();

// Exact match
$query->whereNumber('price', 100);

// Comparison operators
$query->whereNumber('price', '>', 100);
$query->whereNumber('price', '>=', 100);
$query->whereNumber('price', '<', 1000);
$query->whereNumber('price', '<=', 1000);
$query->whereNumber('price', '!=', 0);

// Range
$query->whereNumberBetween('price', 100, 500);

// IN array
$query->whereNumberIn('category_id', [1, 2, 3, 5, 8]);

// NOT IN array
$query->whereNumberNotIn('category_id', [4, 6, 7]);

// IS NULL
$query->whereNumberNull('discount');

// IS NOT NULL
$query->whereNumberNotNull('price');

$query = Product::eavQuery();

// Exact match
$query->whereDecimal('price', 99.99);

// Comparison
$query->whereDecimal('price', '>', 50.00);
$query->whereDecimal('price', '<=', 200.00);

$query = Product::eavQuery();

// Date exact match
$query->whereDate('created_at', '2024-01-01');

// Date comparison
$query->whereDate('created_at', '>=', '2024-01-01');
$query->whereDate('created_at', '<', '2024-12-31');

// Date range
$query->whereDateBetween('created_at', '2024-01-01', '2024-12-31');

// DateTime exact match
$query->whereDateTime('published_at', '2024-01-01 10:00:00');

// DateTime comparison
$query->whereDateTime('published_at', '>=', '2024-01-01 00:00:00');

$query = Product::eavQuery();

// Boolean value
$query->whereBoolean('is_active', true);
$query->whereBoolean('is_featured', false);

// Shortcuts
$query->whereTrue('is_active');
$query->whereFalse('is_deleted');

$query = Product::eavQuery();

// JSON contains key-value
$query->whereJsonContains('metadata', 'tags', 'electronics');
$query->whereJsonContains('specifications', 'ram', '8GB');

$query = Product::eavQuery();

// AND conditions (all must match)
$query->whereText('color', 'red')
      ->whereNumber('price', '>', 100)
      ->whereBoolean('in_stock', true);

// OR conditions (any can match)
$query->whereAny([
    ['attribute' => 'color', 'value' => 'red'],
    ['attribute' => 'color', 'value' => 'blue'],
    ['attribute' => 'color', 'value' => 'green'],
]);

// Complex: (color = red AND price > 100) OR (color = blue AND price < 50)
$query->where(function ($q) {
    $q->whereText('color', 'red')
      ->whereNumber('price', '>', 100);
})->orWhere(function ($q) {
    $q->whereText('color', 'blue')
      ->whereNumber('price', '<', 50);
});

// Very complex: (color IN ['red','blue'] AND price > 100) OR (size = 'large' AND price < 200)
$query->where(function ($q) {
    $q->whereTextIn('color', ['red', 'blue'])
      ->whereNumber('price', '>', 100);
})->orWhere(function ($q) {
    $q->whereText('size', 'large')
      ->whereNumber('price', '<', 200);
});

$query = Product::eavQuery();

// Order by text value
$query->orderByText('title', 'asc');
$query->orderByText('name', 'desc');

// Order by number value
$query->orderByNumber('price', 'asc');
$query->orderByNumber('rating', 'desc');

// Order by date
$query->orderByDate('created_at', 'desc');
$query->orderByDateTime('published_at', 'asc');

// Multiple ordering
$query->orderByNumber('price', 'asc')
      ->orderByText('title', 'asc');

$query = Product::eavQuery();

// Limit results
$query->limit(10);

// Offset
$query->offset(20);

// Get count
$count = $query->count();

// Get distinct attribute values
$colors = $query->getDistinctAttributeValues('color');
// Returns: ['red', 'blue', 'green', 'yellow']

$query = Product::eavQuery();
$query->whereText('color', 'red')
      ->whereNumber('price', '>', 100);

// Get matching entity IDs
$productIds = $query->getAttributableIds();
$products = Product::whereIn('id', $productIds)->get();

// Get count
$count = $query->count();

// Get all attribute values for matching entities
$colors = $query->getAttributeValues('color');

// Get distinct attribute values
$uniqueColors = $query->getDistinctAttributeValues('color');

// Get the underlying query builder for advanced operations
$dbQuery = $query->getQuery();
$results = $dbQuery->get();

// Get products with only specific attributes loaded
$products = Product::with(['eavAttributes' => function ($query) {
    $query->whereIn('slug', ['color', 'size', 'price']);
}])->get();

// Get attribute values for specific attributes only
$product = Product::find(1);
$specificValues = $product->eavAttributes()
    ->whereIn('slug', ['color', 'size'])
    ->get()
    ->mapWithKeys(function ($attr) {
        return [$attr->slug => $attr->pivot->value_text ?? $attr->pivot->value_number ?? $attr->pivot->value];
    });

// Get products with their attribute values as array
$products = Product::with('eavAttributes')->get()->map(function ($product) {
    return [
        'id' => $product->id,
        'name' => $product->name,
        'attributes' => $product->getEavAttributeValues('slug'),
    ];
});

$query = Product::eavQuery();
$query->whereText('category', 'electronics');

// Get sum of prices
$totalPrice = $query->sum('price');

// Get average price
$avgPrice = $query->avg('price');

// Get minimum price
$minPrice = $query->min('price');

// Get maximum price
$maxPrice = $query->max('price');

// Get count
$count = $query->count();

// Get all attribute groups
$product->eavAttributeGroups;

// Attach groups
$product->attachEavAttributeGroups([1, 2, 3]);

// Sync groups (replaces all existing)
$product->syncEavAttributeGroups([1, 2]);

// Detach groups
$product->detachEavAttributeGroups([1]);

// Get attributes through groups
$attributes = $product->getEavAttributesThroughGroups();

// Find products with specific criteria
$products = Product::findByEav(function ($query) {
    $query->whereTextIn('color', ['red', 'blue', 'green'])
          ->whereNumberBetween('price', 50, 200)
          ->whereBoolean('in_stock', true)
          ->whereDateBetween('created_at', '2024-01-01', '2024-12-31')
          ->orderByNumber('price', 'asc')
          ->limit(20);
});

// Find users with specific attributes
$users = User::findByEav(function ($query) {
    $query->whereText('city', 'Tehran')
          ->whereNumber('age', '>=', 18)
          ->whereNumber('age', '<=', 65)
          ->whereBoolean('is_verified', true)
          ->orderByText('name', 'asc');
});

// Find articles with specific tags and date range
$articles = Article::findByEav(function ($query) {
    $query->whereJsonContains('tags', 'value', 'laravel')
          ->whereDateBetween('published_at', '2024-01-01', '2024-12-31')
          ->whereBoolean('is_published', true)
          ->orderByDateTime('published_at', 'desc');
});

use Fiachehr\LaravelEav\Domain\Repositories\AttributeRepositoryInterface;

$attributeRepository = app(AttributeRepositoryInterface::class);

// Find attribute
$attribute = $attributeRepository->findById(1);
$attribute = $attributeRepository->findBySlug('color');
$attribute = $attributeRepository->findByLogicalId('uuid-here');

// Get all active attributes
$attributes = $attributeRepository->findActive();

use Fiachehr\LaravelEav\Application\UseCases\CreateAttributeUseCase;
use Fiachehr\LaravelEav\Application\DTOs\CreateAttributeDTO;
use Fiachehr\LaravelEav\Domain\Enums\AttributeType;

$useCase = app(CreateAttributeUseCase::class);

$dto = CreateAttributeDTO::fromArray([
    'title' => 'Color',
    'slug' => 'color',
    'type' => AttributeType::COLOR->value,
    'values' => ['red', 'blue', 'green'],
    'validations' => ['

   $products = Product::with('eavAttributes')->get();
   

   $products = Product::with(['eavAttributes' => function ($q) {
       $q->whereIn('slug', ['color', 'price']);
   }])->get();
   

   // Good - Single query
   $products = Product::findByEav(function ($q) {
       $q->whereText('color', 'red')
         ->whereNumber('price', '>', 100);
   });
   
   // Less efficient - Multiple queries
   $products = Product::whereEavAttribute('color', 'red')
       ->whereEavAttribute('price', '>', 100)
       ->get();
   
bash
php artisan migrate
bash
php artisan vendor:publish --tag=laravel-eav-config
bash
php artisan migrate
bash
php artisan migrate