Installation
composer require axstrad/content
Publish the migration and config:
php artisan vendor:publish --provider="Axstrad\Content\ContentServiceProvider" --tag="migrations"
php artisan vendor:publish --provider="Axstrad\Content\ContentServiceProvider" --tag="config"
Run migrations:
php artisan migrate
Basic Usage
Define a content type (e.g., BlogPost) in a migration:
Schema::create('blog_posts', function (Blueprint $table) {
$table->id();
$table->string('title');
$table->text('content');
$table->timestamps();
$table->softDeletes();
});
Register the content type in config/content.php:
'types' => [
'blog_post' => [
'table' => 'blog_posts',
'model' => \App\Models\BlogPost::class,
],
],
First Query Fetch a content item:
use Axstrad\Content\Facades\Content;
$post = Content::find('blog_post', 1); // Returns BlogPost model
CRUD Operations Use the facade for type-agnostic operations:
// Create
$post = Content::create('blog_post', ['title' => 'Hello', 'content' => 'World']);
// Update
$post->update(['title' => 'Updated Title']);
// Delete
Content::delete('blog_post', $post->id);
Querying Chain Eloquent queries with the facade:
$posts = Content::type('blog_post')
->where('published', true)
->orderBy('created_at', 'desc')
->get();
Content Types as Services Dynamically register content types via config or database:
// Dynamic registration (e.g., in a service provider)
Content::registerType('dynamic_post', [
'table' => 'dynamic_posts',
'model' => \App\Models\DynamicPost::class,
]);
Events and Observers Attach observers to content types:
// In AppServiceProvider@boot()
Content::type('blog_post')->observe(\App\Observers\BlogPostObserver::class);
API Resources Use Laravel’s API resources with the facade:
Content::type('blog_post')->find(1)->toArray(); // Returns array
Form Requests Validate content creation/updates:
use Axstrad\Content\Requests\StoreContentRequest;
public function store(StoreContentRequest $request) {
$post = Content::create('blog_post', $request->validated());
}
Policy Integration Apply policies to content types:
// In AuthServiceProvider
Content::type('blog_post')->policy(\App\Policies\BlogPostPolicy::class);
Caching Cache content types or queries:
$posts = Cache::remember("blog_posts_{$user->id}", now()->addHours(1), function () {
return Content::type('blog_post')->where('user_id', $user->id)->get();
});
Model Binding Conflicts Avoid naming conflicts between content models and routes:
// Bad: Route `blog/{post}` conflicts with `BlogPost` model binding.
// Solution: Use explicit binding or rename the model.
Mass Assignment Risks
Ensure fillable is set on models to prevent mass assignment vulnerabilities:
class BlogPost extends Model {
protected $fillable = ['title', 'content']; // Explicitly define
}
Soft Deletes Soft-deleted items may still appear in queries unless explicitly excluded:
// Explicitly exclude soft-deleted
Content::type('blog_post')->withTrashed()->get();
Type Registration Overrides Config values override dynamic registrations. Ensure consistency:
// Config takes precedence over dynamic registration.
Query Logging Enable Laravel’s query logging to inspect generated queries:
DB::enableQueryLog();
$posts = Content::type('blog_post')->get();
dd(DB::getQueryLog());
Facade Debugging Check registered types:
dd(Content::getTypes()); // Returns all registered content types
Model Events Debug observers with Laravel’s event system:
// Temporarily log events
Content::type('blog_post')->created(function ($model) {
\Log::debug("Post created: {$model->title}");
});
Custom Query Scopes Add scopes to content types:
class BlogPost extends Model {
public function scopePublished($query) {
return $query->where('published', true);
}
}
// Usage:
Content::type('blog_post')->published()->get();
Content Type Metadata Extend the config to include metadata (e.g., labels, icons):
'types' => [
'blog_post' => [
'label' => 'Blog Post',
'icon' => 'fa-blog',
],
],
Custom Facade Methods Extend the facade in a service provider:
Content::macro('publishedPosts', function () {
return $this->type('blog_post')->published()->get();
});
// Usage:
Content::publishedPosts();
Database Events Listen for content type migrations or schema changes:
Schema::defaultStringLength(191); // Example: Set default string length
How can I help you explore Laravel packages today?