WordPress is great but I really hate it when I have to write SQL queries. Most of the developers I have seen don’t really like writing SQL Queries. WordPress Comes with $wpdb class but you still have to write sql queries. $wpdb is fine when you have small number of queries to make but If you have ever encountered a situation where you have work with lots of custom database tables and have to join them with different tables, you know the pain.
I came across similar situation and instead writing ugly sql queries , I came up with a solution using Eloquent. Eloquent is ORM developed by Laravel framework. This is very easy to work with and you can still write sql queries with Eloquent if you want to. I am not going to talk about features of Eloquent in this article. You can look into official eloquent documentation for more information about Eloquent.
Lets start setting up our plugin.
I assume you have a working WordPress installation and You have composer installed in your machine. If you are not sure what composer is, Composer is dependency manager for php. You can visit composer’s official page for more information and download.
Lets navigate to WordPress plugins directory and create a folder for our plugin, I am going to name my plugin _ “wpdrift-client” _.
I have composer installed globally in my machine, if your composer is not global, you might want to copy composer.phar file into your plugin directory and use “ composer.phar ” instead of “ composer ” when making composer commands. lets require illuminate\database package from composer. Open your terminal window and cd into the plugin folder (i.e. wordpress-installation/wp-content/plugins/wpdrift-client) and type following command:
composer require illuminate/database
Now your plugin folder should look something like this:
Composer has generated vendor directory which includes are package, composer.json file and composer.lock file. Lets open composer.json and setup our namespace. Lets edit it to look something like following code:
{ "require": { "illuminate/database": "^5.4" }, "autoload": { "psr-4": { "Models\\": "app/models", "Controllers\\": "app/controllers" } } }
Run a composer command from your terminal
composer dump-autoload
We have setup namespace for our models and controllers now lets create these folders. We will be creating a folder named _ “app” _ and inside that we will create two folders _ “models” _ and _ “controllers” _ which will store our Models and Controllers respectively. You can name your namespace anything you like.
We have installed Eloquent successfully, lets go ahead and create other files for plugin. We will create a main plugin file “wpdrift-clients.php”, a blank “index.php” file, “assets” folder which will store our css, js, images and fonts, we will also create a folder named views which will store views for our plugin. We will also create a folder called “core” which will be responsible for storing other files like plugin activation hook, connecting eloquent to database and helpers.
After creating these files and folders, your plugin directory should look something like this:
Let me explain what I did here:
We are creating a database table named “clients” (with prefix), core/create_db_tables.php includes code to create database, core/class-enqueue.php is responsible for styles and scripts required for plugin. helpers.php includes helper functions. Pretty much most of the things are included inside core/init.php
Here are the codes for these files:
Main plugin file : wpdrift-client.php
/\* Plugin Name: WpDrift Clients Plugin URI: http://wpdrift.com Description: Custom plugin using Eloquent Version: 1.0 Author: WPDrift Author URI: http://wpdrift.com License: GPL2 License URI: https://www.gnu.org/licenses/gpl-2.0.html Text Domain: wpdrift-clients Domain Path: /languages \*/ if(! defined('ABSPATH')) exit; if( ! defined('WPDRIFT\_CLIENTS\_URl')){ define('WPDRIFT\_CLIENTS\_URl',plugin\_dir\_url(\_\_FILE\_\_)); } if( ! defined('WPDRIFT\_CLIENTS\_PATH')){ define('WPDRIFT\_CLIENTS\_PATH',plugin\_dir\_path(\_\_FILE\_\_)); } require WPDRIFT\_CLIENTS\_PATH.'/core/create\_db\_tables.php'; register\_activation\_hook(\_\_FILE\_\_,'wpdrift\_clients\_custom\_tables'); if(! class\_exists('Wpdrift\_Clients')){ class Wpdrift\_Clients { function \_\_construct(){ add\_action('plugins\_loaded',[$this,'include\_dependencies']); } function include\_dependencies() { include WPDRIFT\_CLIENTS\_PATH.'/core/init.php'; } } } new Wpdrift\_Clients();
core/init.php
require WPDRIFT\_CLIENTS\_PATH.'/vendor/autoload.php'; /\*database connection\*/ $capsule = new Illuminate\Database\Capsule\Manager; $capsule-\>addConnection(['driver' =\> 'mysql', 'host' =\> DB\_HOST, 'database' =\> DB\_NAME, 'username' =\> DB\_USER, 'password' =\> DB\_PASSWORD, 'charset' =\> 'utf8', 'collation' =\> 'utf8\_unicode\_ci', 'prefix' =\> '',]); $capsule-\>setAsGlobal(); $capsule-\>bootEloquent(); // enqueue styles and scripts with class-enqueue.php // helper functions helper.php include\_once WPDRIFT\_CLIENTS\_PATH.'/core/helpers.php'; include\_once WPDRIFT\_CLIENTS\_PATH.'/core/class-enqueue.php'; // add ajax actions $actions = new Controllers\ActionController(); add\_action('wp\_ajax\_create\_client',[$actions,'create']); add\_action('wp\_ajax\_delete\_client',[$actions,'delete']); // shortcode add\_shortcode('wpdrift\_clients',function(){ wpdrift\_clients\_load\_view('clients',['title'=\>'Clients list']); });
core/class-enqueue.php
if(! class\_exists('Wpdrift\_Clients\_Enqueue')){ class Wpdrift\_Clients\_Enqueue { function \_\_construct(){ add\_action('wp\_enqueue\_scripts',array($this,'enqueue')); } function enqueue() { wp\_enqueue\_style('wpdrift-clients',WPDRIFT\_CLIENTS\_URl.'assets/css/wpdrift-clients.css'); wp\_enqueue\_script('jquery'); wp\_enqueue\_script('wpdrift-clients',WPDRIFT\_CLIENTS\_URl.'assets/js/wpdrift-clients.js',array('jquery'),'1.0',true); } } new Wpdrift\_Clients\_Enqueue(); }
core/helpers.php
function wpdrift\_clients\_load\_view($file,$data=[]){ if(! empty($data)){ extract($data); } if(file\_exists(WPDRIFT\_CLIENTS\_PATH.'views/'.$file.'.php')){ include\_once WPDRIFT\_CLIENTS\_PATH.'views/'.$file.'.php'; } else{ echo 'File not found in '.WPDRIFT\_CLIENTS\_PATH.'views/'.$file.'.php'; } } function get\_clients(){ $clients = Models\Client::all(); return $clients; }
Basically, we are just displaying a view with shortcode. Shortcode will trigger a function wpdrift_clients_load_view() (Location: core/helpers.php) , this function will extract array argument and include a view from views folder.
View file includes a table which is displaying dynamic data with a function get_clients() (Location: core/helpers.php), this function gets data from Client Model.
each dynamic data has a delete button which is a form with a ajax action, (Action defined on core/init.php), call back for these actions are stored in app/controllers/ActionController.php, this controller is using app/models/Clinet.php to interact with clients table.
app/controllers/ActionController.php
namespace Controllers; use Models\Client as Client; class ActionController { function create(){ $name = $\_POST['name']; $email = $\_POST['email']; $phone = $\_POST['phone']; $purchased\_service = $\_POST['service']; $client = new Client; $client-\>name = $name; $client-\>email = $email; $client-\>phone = $phone; $client-\>purchased\_service = $purchased\_service; $client-\>save(); $response = ['response\_type' =\> 'success', 'response\_data' =\> [ 'name' =\> $clinet-\>name, 'email' =\> $clinet-\>email, 'phone' =\> $clinet-\>phone, 'service' =\> $clinet-\>purchased\_service,] ]; return $response; die(); } function delete(){ $client\_id = $\_POST['client\_id']; $client = Client::find($client\_id); if($client){ $client-\>delete(); return 'success'; die(); } return false; die(); } }
app/models/Client.php
namespace Models; use Illuminate\Database\Eloquent\Model as Model; class Client extends Model { protected $table; public $timestamps = false; function \_\_construct() { parent::\_\_construct(); $this-\>table = $this-\>get\_table\_name('clients'); } private function get\_table\_name($name) { global $wpdb; return $wpdb-\>prefix.$name; } }
As You can see, we don’t have much code on our model, all we are telling model is to use prefix_clients table, Eloquent by default expects table to have created_at and updated_at column. So, by defining public $timestamps = false; we are disabling that feature. Eloquent assumes you have a primary key table with the name id, if you are thinking of using some other name, you will have to define one more property called $primaryKey . For example, if you are creating a model for WordPress native Users table, it would look something like this:
namespace Models; use Illuminate\Database\Eloquent\Model as Model; class User extends Model { protected $table; public $timestamps = false; protected $primaryKey = 'ID'; function \_\_construct() { parent::\_\_construct(); $this-\>table = 'wp\_users'; $this-\>table = $this-\>get\_table\_name('users'); } private function get\_table\_name($name) { global $wpdb; return $wpdb-\>prefix.$name; } function meta() { return $this-\>hasMany('App\Usermeta'); } function posts() { return $this-\>hasMany('App\Post'); } }
In the above example meta and posts method define relationship with other Models “Usermeta and Post”, which can use usermeta and posts table.
We built a very basic plugin using eloquent orm. But this article is not about how big the plugin is but structuring your plugin to use MVC architecture and using Eloquent orm with your plugin. This article only focused on using MVC and Eloquent, you will have to implement security when you build your real plugin.
Hence, if you are using creating a big custom plugin with lots of custom tables, I believe this approach will be very manageable and easy where as I would not suggest you to use this approach to publish your plugin in wordpress.org as it makes extra database connection and user is using 5 plugins with similar approach, they will have 6 database connections.
The post Using Eloquent in WordPress Plugin Development appeared first on upnrunn® | Build & Deploy Powerful Application.
Top comments (0)