mallardduck/wp-eloquent-models

A Laravel wrapper for wordpress which turns all Wordpress models into Laravel Eloquent Models.

v0.4.1 2020-02-18 05:14 UTC

This package is auto-updated.

Last update: 2024-09-18 16:16:45 UTC


README

A library that converts converts wordpress tables into Laravel Eloquent Models. This is can be helpful for any wordpress project where maybe you'd rather use the awesome features of Laravel's Eloquent.

Or maybe you're building a project using Laravel and Roots Bedrock/Sage/etc and want to access WordPress data within Laravel. Or maybe you're writing an API with something like Slim or better yet Lumen don't want to increase your load time by loading the entire WP core.

This is a great boiler plate based off Eloquent by Laravel to get you going.

Note: This is documentation for additional functionality on top of Eloquent. For documentation on all of Eloquent's features you visit the documentation.

Overview

Installing WPEloquent

The recommended way to install WPEloquent is through Composer.

composer require mallardduck/wp-eloquent-models

Version Guidance

Setup - Common

require_once('vendor/autoload.php');

\WPEloquent\Core\Laravel::connect([
    'global' => true,

    'config' => [

        'database' => [
            'user'     => 'user',
            'password' => 'password',
            'name'     => 'database',
            'host'     => '127.0.0.1',
            'port'     => '3306'
        ],

        // your wpdb prefix
        'prefix' => 'wp_',
    ],

    // enable events
    'events' => false,

    // enable query log
    'log'    => true
]);

If you wanted to enable this on your entire WP install you could create a file with the above code to drop in the mu-plugins folder.

Setup with Laravel

These directions are for when you want to work with WordPress database using Eloqent inside Laravel. The easiest mehtod is making a new config inside Laravel's config/database.php. For example:

    'wordpress' => [
        'driver' => 'mysql',
        'url' => env('DATABASE_URL'),
        'host' => env('DB_HOST', '127.0.0.1'),
        'port' => env('DB_PORT', '3306'),
        'database' => env('DB_NAME', 'wordpress'),
        'username' => env('DB_USER', 'forge'),
        'password' => env('DB_PASSWORD', ''),
        'unix_socket' => env('DB_SOCKET', ''),
        'charset' => 'utf8mb4',
        'collation' => 'utf8mb4_unicode_ci',
        'prefix' => env('DB_PREFIX', 'wp_'),
        'prefix_indexes' => true,
        'strict' => true,
        'engine' => null,
        'options' => extension_loaded('pdo_mysql') ? array_filter([
            PDO::MYSQL_ATTR_SSL_CA => env('MYSQL_ATTR_SSL_CA'),
        ]) : [],
    ],

Note: In this example the WordPress database and Laravel database can be accessed on the same server by the same MySQL user. The laravel .env of your project may need to be adjusted to match this example.

Then in your AppServiceProvider add the following line:

BaseModel::setDefaultConnection('wordpress');

Supported Models

Posts

use \WPEloquent\Model\Post;

// getting a post
$post = Post::find(1);

// available relationships
$post->author;
$post->comments;
$post->terms;
$post->tags;
$post->categories;
$post->meta;

Statuses

By default, the Post returns posts with all statuses. You can however override this with the local scope published to return only published posts.

Post::published()->get();

Or if you need a specific status you can override with defined status via local scope.

Post::status('draft')->get();

Post Types

By default, the Post returns posts with all post types. You can however override this by defining a post type via local scope.

Post::type('page')->get();

Comments

use \WPEloquent\Model\Comment;

// getting a comment
$comment = Comment::find(12345);

// available relationships
$comment->post;
$comment->author;
$comment->meta

Terms

In this version Term is still accesible as a model but is only leveraged through posts.

$post->terms()->where('taxonomy', 'country');

Users

use \WPEloquent\Model\User;

// getting a comment
$user = User::find(123);

// available relationships
$user->posts;
$user->meta;
$user->comments

Meta

The models Post, User, Comment, Term, all implement the HasMeta. Therefore they meta can easily be retrieved by the getMeta and set by the setMeta helper functions:

$post = Post::find(1);
$post->setMeta('featured_image', 'my-image.jpg');
$post->setMeta('breakfast', ['waffles' => 'blueberry', 'pancakes' => 'banana']);

// or all in one call
$featured_image = Post::find(1)->getMeta('featured_image');
Post::find(1)->setMeta('featured_image', 'image.jpg');

// same applies for all other models

$user = User::find(1)
$facebook = $user->getMeta('facebook');
$user->setMeta('social', ['facebook' => 'facebook.com/me', 'instagram' => 'instagram.com/me']);

$comment = Comment::find(1);
$meta = $comment->getMeta('some_comment_meta');

$term = Term::find(123);
$meta = $term->getMeta('some_term_meta');

// delete meta
$post = Post::find(123)->deleteMeta('some_term_meta');

Options

In wordpress you can use get_option. Alternatively, if you don't want to load the wordpress core you can use helper function getValue.

use \WPEloquent\Model\Post;

$siteurl = Option::getValue('siteurl');

Or of course, the long form:

use \WPEloquent\Model\Options;

$siteurl = Option::where('option_name', 'siteurl')->value('option_value');

Links

use \WPEloquent\Model\Link;

$siteurl = Link::find(1);

Extending your own models

If you want to add your own functionality to a model, for instance a User you can do so like this:

namespace App\Model;

class User extends \WPEloquent\Model\User {

    public function orders() {
        return $this->hasMany('\App\Model\User\Orders');
    }

    public function current() {
        // some functionality to get current user
    }

    public function favorites() {
        return $this->hasMany('Favorites');
    }

}

Another example would be for custom taxonomies on a post, say country

namespace App\Model;

class Post extends \WPEloquent\Model\Post {

    public function countries() {
        return $this->terms()->where('taxonomy', 'country');
    }

}

Post::with(['categories', 'countries'])->find(1);

Or maybe you need to access a custom post type, like:

namespace App\Model;

class CustomPostType extends \WPEloquent\Model\Post {
    protected $post_type  = 'custom_post_type';

    public static function getBySlug(string $slug): self
    {
        return self::where('post_name', $slug)->firstOrfail();
    }
}

CustomPostType::with(['categories', 'countries'])->find(1);

Query Logs

Sometimes it's helpful to see the query logs for debugging. You can enable the logs by passing log is set to true (see setup) on the Laravel::connect method. Logs are retrieved by running.

use \WPEloquent\Core\Laravel;

print_r(Laravel::queryLog());