carlxaeron / general
A Laravel package providing general mapping and meta functionality for flexible model relationships and metadata management
Requires
- php: ^8.1
- illuminate/database: ^10.0|^11.0|^12.0
- illuminate/support: ^10.0|^11.0|^12.0
- laravel/framework: ^10.0|^11.0|^12.0
Requires (Dev)
- orchestra/testbench: ^8.0|^9.0|^10.0
- phpunit/phpunit: ^10.0
README
A Laravel package providing general mapping and meta functionality for flexible model relationships and metadata management.
Features
- General Maps: Create flexible, polymorphic relationships between any models
- General Meta: Add custom metadata to any model
- Helper Functions: Global helper functions for easy access
- Traits: Easy-to-use traits for models
- Configurable: Customizable table names and settings
- Laravel 10/11/12 Compatible: Works with modern Laravel versions
Installation
Via Composer
composer require carlxaeron/general
Manual Installation
- Clone or download this package to your project
- Add the package to your
composer.json
:
{ "require": { "carlxaeron/general": "*" } }
- Run
composer install
Setup
1. Publish Configuration (Optional)
php artisan vendor:publish --tag=general-config
This will publish the configuration file to config/general.php
.
2. Publish Migrations (Optional)
php artisan vendor:publish --tag=general-migrations
This will publish the migrations to your database/migrations
folder.
3. Run Migrations
php artisan migrate
Usage
Using Traits
HasGeneralMaps Trait
Add the HasGeneralMaps
trait to any model you want to have relationships with other models:
<?php namespace App\Models; use Illuminate\Database\Eloquent\Model; use Carlxaeron\General\Traits\HasGeneralMaps; class User extends Model { use HasGeneralMaps; // ... your model code }
HasGeneralMeta Trait
Add the HasGeneralMeta
trait to any model you want to have metadata:
<?php namespace App\Models; use Illuminate\Database\Eloquent\Model; use Carlxaeron\General\Traits\HasGeneralMeta; class User extends Model { use HasGeneralMeta; // ... your model code }
Helper Functions
The package provides global helper functions for easy access to functionality:
General Maps Functions
// Get related models $relatedUsers = get_related_models($user, User::class, 'friend'); // Get a specific related model $friend = get_related_model($user, User::class, $friendId, 'friend'); // Add a relationship add_related_model($user, $friend, 'friend', 'best_friend', ['since' => '2020']); // Remove a relationship remove_related_model($user, $friend, 'friend'); // Check if relationship exists if (has_related_model($user, $friend, 'friend')) { // Relationship exists } // Get relationship metadata $metadata = get_relationship_metadata($user, $friend, 'friend'); // Set relationship metadata set_relationship_metadata($user, $friend, ['since' => '2020'], 'friend'); // Toggle relationship toggle_relationship($user, $friend, 'friend'); // Get all relationship types $types = get_relationship_types($user); // Get all relationship keys for a type $keys = get_relationship_keys($user, 'friend'); // Find models by relationship $users = find_by_relationship(User::class, User::class, $friendId, 'friend'); // Find models that have relationships with a specific model $users = find_by_mappable(User::class, User::class, $friendId, 'friend');
General Meta Functions
// Get meta value $value = get_meta($user, 'preference', 'default_value'); // Set meta value set_meta($user, 'preference', 'dark_theme', 'string'); // Check if meta exists if (has_meta($user, 'preference')) { // Meta exists } // Delete meta delete_meta($user, 'preference'); // Get all meta $allMeta = get_all_meta($user); // Find models by meta $users = find_by_meta(User::class, 'theme', 'dark');
Direct Model Methods
When using the traits, you can also call methods directly on your models:
// General Maps $user->getRelatedModels(User::class, 'friend'); $user->addRelatedModel($friend, 'friend'); $user->hasRelatedModel($friend, 'friend'); // General Meta $user->getGeneralMeta('theme'); $user->setGeneralMeta('theme', 'dark'); $user->hasGeneralMeta('theme');
Configuration
The package configuration file (config/general.php
) allows you to customize:
- Table names
- Default relationship types
- Default sort orders
- Default active status
- Maximum string lengths for database columns
- Cache settings
return [ 'tables' => [ 'general_maps' => 'general_maps', 'general_meta' => 'general_meta', ], 'default_relationship_type' => 'general', 'default_sort_order' => 0, 'default_is_active' => true, 'max_lengths' => [ 'mappable_type' => 100, 'related_type' => 100, 'relationship_type' => 100, 'relationship_key' => 100, ], 'cache' => [ 'enabled' => env('GENERAL_CACHE_ENABLED', false), 'ttl' => env('GENERAL_CACHE_TTL', 3600), ], ];
Database Schema
General Maps Table
CREATE TABLE general_maps ( id BIGINT UNSIGNED AUTO_INCREMENT PRIMARY KEY, mappable_type VARCHAR(100) NOT NULL, mappable_id BIGINT UNSIGNED NOT NULL, related_type VARCHAR(100) NOT NULL, related_id BIGINT UNSIGNED NOT NULL, relationship_type VARCHAR(100) DEFAULT 'general', relationship_key VARCHAR(100) NULL, metadata JSON NULL, sort_order INT DEFAULT 0, is_active BOOLEAN DEFAULT TRUE, created_at TIMESTAMP NULL, updated_at TIMESTAMP NULL, UNIQUE KEY unique_general_map ( mappable_type, mappable_id, related_type, related_id, relationship_type, relationship_key ), INDEX idx_mappable (mappable_type, mappable_id, relationship_type), INDEX idx_related (related_type, related_id, relationship_type), INDEX idx_relationship (relationship_type, is_active) );
General Meta Table
CREATE TABLE general_meta ( id BIGINT UNSIGNED AUTO_INCREMENT PRIMARY KEY, metable_type VARCHAR(255) NOT NULL, metable_id BIGINT UNSIGNED NOT NULL, `key` VARCHAR(255) NOT NULL, value TEXT NULL, type VARCHAR(255) DEFAULT 'string', created_at TIMESTAMP NULL, updated_at TIMESTAMP NULL, UNIQUE KEY unique_meta (metable_type, metable_id, `key`) );
Examples
User Friends System
class User extends Model { use HasGeneralMaps, HasGeneralMeta; } // Add a friend $user->addRelatedModel($friend, 'friend', 'best_friend', ['since' => '2020']); // Get all friends $friends = $user->getRelatedModels(User::class, 'friend'); // Get best friends $bestFriends = $user->getRelatedModels(User::class, 'friend', 'best_friend'); // Check if someone is a friend if ($user->hasRelatedModel($friend, 'friend')) { echo "They are friends!"; }
Product Categories with Metadata
class Product extends Model { use HasGeneralMaps, HasGeneralMeta; } class Category extends Model { use HasGeneralMaps; } // Add product to category $product->addRelatedModel($category, 'category', 'main'); // Add metadata to product $product->setGeneralMeta('weight', 500, 'integer'); $product->setGeneralMeta('dimensions', ['width' => 10, 'height' => 20], 'array'); // Get products in category $products = $category->getMappableModels(Product::class, 'category', 'main'); // Get product metadata $weight = $product->getGeneralMeta('weight'); $dimensions = $product->getGeneralMeta('dimensions');
Testing
composer test
Contributing
- Fork the repository
- Create your feature branch (
git checkout -b feature/amazing-feature
) - Commit your changes (
git commit -m 'Add some amazing feature'
) - Push to the branch (
git push origin feature/amazing-feature
) - Open a Pull Request
License
This package is open-sourced software licensed under the MIT license.
Support
If you have any questions or need help, please open an issue on GitHub or contact the maintainer.
Changelog
1.0.0
- Initial release
- General Maps functionality
- General Meta functionality
- Helper functions
- Laravel 10/11 compatibility