PHP code example of solution-forest / laravel-dynamic-properties

1. Go to this page and download the library: Download solution-forest/laravel-dynamic-properties 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/ */

    

solution-forest / laravel-dynamic-properties example snippets




namespace App\Models;

use Illuminate\Database\Eloquent\Model;
use SolutionForest\LaravelDynamicProperties\Traits\HasProperties;

class User extends Model
{
    use HasProperties;
    
    // Your existing model code...
}

use SolutionForest\LaravelDynamicProperties\Models\Property;

// Create a text property
Property::create([
    'name' => 'phone',
    'label' => 'Phone Number',
    'type' => 'text',
    'e,
    'validation' => ['min' => 0, 'max' => 120]
]);

// Create a select property
Property::create([
    'name' => 'status',
    'label' => 'User Status',
    'type' => 'select',
    '

$user = User::find(1);

// ✅ This works - property 'phone' was defined above
$user->setDynamicProperty('phone', '+1234567890');
$user->setDynamicProperty('age', 25);
$user->setDynamicProperty('status', 'active');

// ❌ This will throw PropertyNotFoundException
$user->setDynamicProperty('undefined_property', 'value');

// Or use magic methods
$user->prop_phone = '+1234567890';
$user->prop_age = 25;

// Get properties
$phone = $user->getDynamicProperty('phone');
$age = $user->prop_age; // Magic method
$allProperties = $user->properties; // All properties as array

// Set multiple properties at once
$user->setProperties([
    'phone' => '+1234567890',
    'age' => 25,
    'status' => 'active'
]);

// ✅ RECOMMENDED: Search with defined properties (uses correct column types)
$activeUsers = User::whereProperty('status', 'active')->get();
$youngUsers = User::whereProperty('age', '<', 30)->get();

// ⚠️ FALLBACK: Search undefined properties (uses value-based type detection)
$results = User::whereProperty('undefined_prop', 'some_value')->get();

// Find users by multiple properties
$users = User::whereProperties([
    'status' => 'active',
    'age' => 25
])->get();

// ❌ WRONG - Will throw PropertyNotFoundException
$user->setDynamicProperty('new_field', 'value'); // Property 'new_field' doesn't exist

// ✅ CORRECT - Create property definition first
Property::create([
    'name' => 'new_field',
    'label' => 'New Field',
    'type' => 'text'
]);
$user->setDynamicProperty('new_field', 'value'); // Now it works

// ✅ With property definition - Type safe
Property::create(['name' => 'score', 'type' => 'number']);
$users = User::whereProperty('score', '>', 80); // Uses number_value column correctly

// ⚠️ Without property definition - Fallback behavior
$users = User::whereProperty('undefined_score', '>', 80); // Uses value-based type detection

// ✅ With validation rules
Property::create([
    'name' => 'email',
    'type' => 'text',
    'validation' => ['email', 'inition - No validation possible
// (Would throw PropertyNotFoundException before validation could occur)

// ✅ FAST - Uses correct column and indexes
Property::create(['name' => 'department', 'type' => 'text']);
$users = User::whereProperty('department', 'engineering'); // Optimized query

// ⚠️ SLOWER - Uses fallback type detection
$users = User::whereProperty('undefined_dept', 'engineering'); // Less optimal

Property::create([
    'name' => 'bio',
    'label' => 'Biography',
    'type' => 'text',
    'validation' => [
        'min' => 10,        // Minimum length
        'max' => 500,       // Maximum length
        '

Property::create([
    'name' => 'salary',
    'label' => 'Annual Salary',
    'type' => 'number',
    'validation' => [
        'min' => 0,
        'max' => 1000000,
        'decimal_places' => 2
    ]
]);

Property::create([
    'name' => 'hire_date',
    'label' => 'Hire Date',
    'type' => 'date',
    'validation' => [
        'after' => '2020-01-01',
        'before' => 'today'
    ]
]);

Property::create([
    'name' => 'newsletter_subscribed',
    'label' => 'Newsletter Subscription',
    'type' => 'boolean',
    '

Property::create([
    'name' => 'department',
    'label' => 'Department',
    'type' => 'select',
    'options' => ['engineering', 'marketing', 'sales', 'hr'],
    '

// In a migration
Schema::table('users', function (Blueprint $table) {
    $table->json('dynamic_properties')->nullable();
});

Schema::table('companies', function (Blueprint $table) {
    $table->json('dynamic_properties')->nullable();
});

use YourVendor\DynamicProperties\Services\PropertyService;

$propertyService = app(PropertyService::class);

// Advanced search with operators
$results = $propertyService->search('App\\Models\\User', [
    'age' => ['value' => 25, 'operator' => '>='],
    'salary' => ['value' => 50000, 'operator' => '>'],
    'status' => 'active'
]);

// Full-text search on text properties
$users = User::whereRaw(
    "EXISTS (SELECT 1 FROM entity_properties ep WHERE ep.entity_id = users.id 
     AND ep.entity_type = ? AND MATCH(ep.string_value) AGAINST(? IN BOOLEAN MODE))",
    ['App\\Models\\User', '+marketing +manager']
)->get();

use YourVendor\DynamicProperties\Exceptions\PropertyNotFoundException;
use YourVendor\DynamicProperties\Exceptions\PropertyValidationException;

try {
    $user->setDynamicProperty('nonexistent_property', 'value');
} catch (PropertyNotFoundException $e) {
    // Handle property not found
    echo "Property not found: " . $e->getMessage();
}

try {
    $user->setDynamicProperty('age', 'invalid_number');
} catch (PropertyValidationException $e) {
    // Handle validation error
    echo "Validation failed: " . $e->getMessage();
}

// config/dynamic-properties.php
return [
    // Default property validation rules
    'default_validation' => [
        'text' => ['max' => 1000],
        'number' => ['min' => -999999, 'max' => 999999],
    ],
    
    // Enable/disable JSON caching
    'json_cache_enabled' => true,
    
    // Cache sync strategy
    'cache_sync_strategy' => 'immediate', // 'immediate', 'deferred', 'manual'
    
    // Database-specific optimizations
    'database_optimizations' => [
        'mysql' => [
            'use_json_functions' => true,
            'enable_fulltext_search' => true,
        ],
        'sqlite' => [
            'use_json1_extension' => true,
        ],
    ],
];

// Error: "Property 'phone' not found"
$user->setDynamicProperty('phone', '+1234567890');

Property::create(['name' => 'phone', 'type' => 'text']);
$user->setDynamicProperty('phone', '+1234567890'); // Now works

// Error: "Validation failed for property 'age'"
$user->setDynamicProperty('age', -5);

$property = Property::where('name', 'age')->first();
var_dump($property->validation); // See what rules are defined
$user->setDynamicProperty('age', 25); // Use valid value

// Getting different results for the same logical query
$users1 = User::whereProperty('level', '>', 5)->get();   // 10 results
$users2 = User::whereProperty('level', '>', '5')->get(); // 3 results

Property::create(['name' => 'level', 'type' => 'number']);
// Now both queries will return the same results
bash
php artisan vendor:publish --provider="SolutionForest\LaravelDynamicProperties\DynamicPropertyServiceProvider" --tag="migrations"
php artisan migrate
bash
php artisan vendor:publish --provider="SolutionForest\LaravelDynamicProperties\DynamicPropertyServiceProvider" --tag="config"
bash
> php artisan dynamic-properties:create
>