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\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();
// 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();
// 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();
$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 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' => ['