Corcel
Use WordPress backend with Laravel or any PHP application
Install / Use
/learn @corcel/CorcelREADME
A collection of Model classes that allows you to get data directly from a WordPress database.
Corcel is a collection of PHP classes built on top of Eloquent ORM (from Laravel framework), that provides a fluent interface to connect and get data directly from a WordPress database.
You can use WordPress as the backend (administration panel) or CMS, for inserting posts, custom types, etc, and any other PHP app in the other side querying those data (as a Model layer). It's easier to use Corcel with Laravel, but you're free to use it with any PHP project that uses Composer.
<a href="https://ko-fi.com/A36513JF" target="_blank">Buy me a Coffee</a> | <a href="https://twitter.com/corcelphp" target="_blank">Follow Corcel on Twitter</a>
Table of Contents
<a id="install"></a> Installing Corcel
Version Compatibility
Laravel | Corcel
:---------|:----------
5.1.x | ~2.1.0
5.2.x | ~2.2.0
5.3.x | ~2.3.0
5.4.x | ~2.4.0
5.5.x | ~2.5.0
5.6.x | ~2.6.0
5.7.x | ~2.7.0
5.8.x | ~2.8.0
6.0.x | ^3.0.0
7.0.x | ^4.0.0
8.0.x | ^5.0.0
9.0.x | ^6.0.0
10.0.x | ^7.0.0
11.0.x | ^8.0.0
12.0.x | ^9.0.0
<a id="installing-corcel"></a> Installing Corcel
You need to use Composer to install Corcel into your project:
composer require jgrossi/corcel
Configuring (Laravel)
<a name="config-auto-discovery"></a> Laravel 5.5 and newer
Corcel wil register itself using Laravel's Auto Discovery.
<a name="config-service-loader"></a> Laravel 5.4 and older
You'll have to include CorcelServiceProvider in your config/app.php:
'providers' => [
/*
* Package Service Providers...
*/
Corcel\Laravel\CorcelServiceProvider::class,
]
<a name="config-publish"></a> Publishing the configuration file
Now configure our config file to make sure your database is set correctly and to allow you to register custom post types and shortcodes in a very easy way:
Run the following Artisan command in your terminal:
php artisan vendor:publish --provider="Corcel\Laravel\CorcelServiceProvider"
Now you have a config/corcel.php config file, where you can set the database connection with WordPress tables and much more.
<a id="database-setup"></a> Database Setup
Laravel Setup
Just set the database connection you want to be used by Corcel in config/corcel.php.
Let' suppose you have those following database connections in your config/database.php file:
// File: /config/database.php
'connections' => [
'mysql' => [ // for Laravel database
'driver' => 'mysql',
'host' => 'localhost',
'database' => 'mydatabase',
'username' => 'admin'
'password' => 'secret',
'charset' => 'utf8',
'collation' => 'utf8_unicode_ci',
'prefix' => '',
'strict' => false,
'engine' => null,
],
'wordpress' => [ // for WordPress database (used by Corcel)
'driver' => 'mysql',
'host' => 'localhost',
'database' => 'mydatabase',
'username' => 'admin',
'password' => 'secret',
'charset' => 'utf8',
'collation' => 'utf8_unicode_ci',
'prefix' => 'wp_',
'strict' => false,
'engine' => null,
],
],
In this case you should want to use the wordpress connection for Corcel, so just set it into the Corcel config file config/corcel.php:
'connection' => 'wordpress',
Other PHP Framework (not Laravel) Setup
Here you have to configure the database to fit the Corcel requirements. First, you should include the Composer autoload file if not already loaded:
require __DIR__ . '/vendor/autoload.php';
Now you must set your WordPress database params:
$params = [
'database' => 'database_name',
'username' => 'username',
'password' => 'pa$$word',
'prefix' => 'wp_' // default prefix is 'wp_', you can change to your own prefix
];
Corcel\Database::connect($params);
You can specify all Eloquent params, but some are default (but you can override them).
'driver' => 'mysql',
'host' => 'localhost',
'charset' => 'utf8',
'collation' => 'utf8_unicode_ci',
'prefix' => 'wp_', // Specify the prefix for WordPress tables, default prefix is 'wp_'
<a id="usage"></a> Usage
<a id="posts"></a> Posts
Every time you see
Post::method(), if you're using your own Post class (where you set the connection name), likeApp\Postyou should useApp\Post::method()and notPost::method(). All the examples are assuming you already know this difference.
In the examples, every time you see
Post::method()assumeCorcel\Model\Post::method().
// All published posts
$posts = Post::published()->get();
$posts = Post::status('publish')->get();
// A specific post
$post = Post::find(31);
echo $post->post_title;
Creating your own model classes
Optionally you can create your own Post model (or Page, or whatever) which extends Corcel\Post. Then set the connection name (if you want to override the Corcel's default one) you're using, in this case foo-bar:
Extending
Corcel\Model\Postclass can add flexibility to your project, once you can add custom methods and logic, according what you need to use from your WordPress database.
<?php // File: app/Post.php
namespace App;
use Corcel\Model\Post as Corcel;
class Post extends Corcel
{
protected $connection = 'foo-bar';
public function customMethod() {
//
}
}
So, now you can fetch WP database data using your own class:
$posts = App\Post::all(); // using the 'foo-bar' connection
Just remember you don't have to extends our
Postclass, you can useCorcel\Model\Postand all others model without any problem.
Meta Data (Custom Fields)
NOTE: In Corcel v1 you could save meta data using the
Post::save()method. That's not allowed anymore. UsesaveMeta()orcreateMeta()(see below) methods to save post meta.
You can retrieve meta data from posts too.
// Get a custom meta value (like 'link' or whatever) from a post (any type)
$post = Post::find(31);
echo $post->meta->link; // OR
echo $post->fields->link;
echo $post->link; // OR
To create or update meta data form a User just use the saveMeta() or saveField() methods. They return bool like the Eloquent save() method.
$post = Post::find(1);
$post->saveMeta('username', 'jgrossi');
You can save many meta data at the same time too:
$post = Post::find(1);
$post->saveMeta([
'username' => 'jgrossi',
'url' => 'http://jgrossi.com',
]);
You also have the createMeta() and createField() methods, that work like the saveX() methods, but they are used only for creation and return the PostMeta created instance, instead of bool.
$post = Post::find(1);
$postMeta = $post->createMeta('foo', 'bar'); // instance of PostMeta class
$trueOrFalse = $post->saveMeta('foo', 'baz'); // boolean
Querying Posts by Custom Fields (Meta)
There are multiples possibilities to query posts by their custom fields (meta) by using scopes on a Post (or another other model which uses the HasMetaFields trait) class:
To check if a meta key exists, use the hasMeta() scope:
// Finds a published post with a meta flag.
$post = Post::published()->hasMeta('featured_article')->first();
If you want to precisely match a meta-field, you can use the hasMeta() scope with a value.
// Find a published post which matches both meta_key and meta_value.
$post = Post::published()->hasMeta('username', 'jgrossi')->first();
If you need to match multiple meta-fields, you can also use the hasMeta() scope passing an array as parameter:
$post = Post::hasMeta(['username' => 'jgrossi'])->first();
$post = Post::hasMeta(['username' => 'jgrossi', 'url' => 'jgrossi.com'])->first();
// Or just passing the keys
$post = Post::hasMeta(['username', 'url'])->first();
If you need to match a case-insensitive string, or match with wildcards, you can use the hasMetaLike() scope with a value. This uses an SQL LIKE operator, so use '%' as a wildcard operator.
// Will match: 'J Grossi', 'J GROSSI', and 'j grossi'.
$post = Post::published()->hasMetaLike('author', 'J GROSSI')->first()
