wenprise/eloquent
Lightweight extensions for Laravel Eloquent that add helpful query and model utilities, cleaner builder macros, and convenience helpers to speed up common database tasks. Designed to drop into existing apps with minimal setup and familiar Eloquent syntax.
Installation
composer require wenprise/eloquent
Add to config/app.php under providers:
Wenprise\Eloquent\EloquentServiceProvider::class,
Publish the config file:
php artisan vendor:publish --provider="Wenprise\Eloquent\EloquentServiceProvider" --tag="config"
Basic Setup
wp_db.php in config/wenprise-eloquent.php to match your WordPress database.AppServiceProvider (if not auto-loaded):
public function boot()
{
$this->app->register(\Wenprise\Eloquent\EloquentServiceProvider::class);
}
First Query
use Wenprise\Eloquent\Eloquent;
$posts = Eloquent::table('wp_posts')->where('post_status', 'publish')->get();
// Fetch published posts with a limit
$posts = Eloquent::table('wp_posts')
->select('ID', 'post_title', 'post_content')
->where('post_type', 'post')
->where('post_status', 'publish')
->limit(10)
->get();
// Access data like a Laravel collection
foreach ($posts as $post) {
echo $post->post_title;
}
Leverage Laravel’s query builder for WordPress tables:
// Join with wp_postmeta
$posts = Eloquent::table('wp_posts')
->join('wp_postmeta', 'wp_posts.ID', '=', 'wp_postmeta.post_id')
->where('wp_postmeta.meta_key', '_custom_field')
->select('wp_posts.*', 'wp_postmeta.meta_value')
->get();
Extend Laravel’s Model to interact with WordPress tables:
use Wenprise\Eloquent\Eloquent;
use Illuminate\Database\Eloquent\Model;
class WPPost extends Model
{
protected $table = 'wp_posts';
public $timestamps = false; // WordPress uses 'post_date' instead
protected $primaryKey = 'ID';
public $incrementing = false; // Auto-increment may not apply
// Custom accessors
public function getTitleAttribute()
{
return $this->post_title;
}
}
// Usage
$post = WPPost::where('post_status', 'publish')->first();
echo $post->title;
Define relationships like Laravel, but target WordPress tables:
class WPPost extends Model
{
public function comments()
{
return $this->hasMany(WPComment::class, 'comment_post_ID', 'ID');
}
}
class WPComment extends Model
{
protected $table = 'wp_comments';
public $primaryKey = 'comment_ID';
}
WordPress uses meta_key/meta_value for custom fields. Create accessors:
class WPPost extends Model
{
public function getCustomFieldAttribute($key)
{
return $this->meta()->where('meta_key', $key)->value('meta_value');
}
public function meta()
{
return $this->hasMany(WPPostMeta::class, 'post_id', 'ID');
}
}
Use Laravel’s chunking for large WordPress datasets:
WPPost::where('post_status', 'draft')
->chunk(200, function ($posts) {
foreach ($posts as $post) {
$post->update(['post_status' => 'publish']);
}
});
Attach Laravel observers to WordPress models:
// app/Observers/WPPostObserver.php
class WPPostObserver
{
public function saved(WPPost $post)
{
// Log or trigger actions after save
}
}
// Register in AppServiceProvider
WPPost::observe(WPPostObserver::class);
Primary Key Mismatch
WordPress uses ID (not id) as the primary key for most tables. Always set:
public $primaryKey = 'ID';
public $incrementing = false;
Timestamps
WordPress uses post_date (datetime) instead of Laravel’s created_at/updated_at. Disable auto-timestamps:
public $timestamps = false;
Soft Deletes WordPress doesn’t support soft deletes natively. Use a custom scope:
public function scopeActive($query)
{
return $query->where('post_status', '!=', 'trash');
}
Case Sensitivity WordPress table/column names are case-sensitive on some hosts. Stick to lowercase:
protected $table = 'wp_posts'; // Not 'WP_Posts'
Memory Limits
Large queries (e.g., wp_options) may hit PHP memory limits. Use cursors or chunking:
WPOption::cursor()->get();
Query Logging
Enable Laravel’s query logging in config/database.php:
'log' => true,
'log_queries' => true,
Check logs in storage/logs/laravel.log.
DD() for Debugging
Use Laravel’s dd() to inspect query results:
$posts = WPPost::where('post_type', 'page')->get();
dd($posts->toArray());
WP Debug Mode
Temporarily enable WordPress debug in wp-config.php:
define('WP_DEBUG', true);
define('WP_DEBUG_LOG', true); // Logs to /wp-content/debug.log
Custom Query Builder Extensions Extend the query builder for WordPress-specific methods:
// app/Providers/EloquentServiceProvider.php
use Wenprise\Eloquent\Eloquent;
Eloquent::macro('published', function () {
return $this->where('post_status', 'publish');
});
// Usage
$posts = WPPost::published()->get();
Model Events for WordPress Hook into WordPress actions via Laravel events:
// In a service provider
WPPost::saved(function ($post) {
do_action('wp_insert_post', $post->ID, $post->post);
});
Caching Strategies Cache frequent WordPress queries using Laravel’s cache:
$posts = Cache::remember('published_posts', now()->addHours(1), function () {
return WPPost::published()->get();
});
Migrations for WordPress Tables Use Laravel migrations to manage WordPress table structures (caution: risky for core tables):
Schema::table('wp_posts', function (Blueprint $table) {
$table->string('custom_field')->nullable()->after('post_content');
});
Select Specific Columns
Avoid SELECT *:
// Bad
WPPost::all();
// Good
WPPost::select('ID', 'post_title')->get();
Use Indexes
Ensure WordPress tables are indexed (e.g., post_status, post_type). Add indexes via migrations if needed.
Batch Processing
For bulk updates, use Laravel’s update() with chunking:
WPPost::where('post_status', 'draft')
->update(['post_status' => 'publish']);
Avoid N+1 Queries Eager-load relationships:
WPPost::with('comments')->where('post_status', 'publish')->get();
How can I help you explore Laravel packages today?