BuddyPress for SportsPress

Today, we’re pleased to announce that BuddyPress for SportsPress is now an official @ThemeBoy extension! tboy.co/buddypress

So what is BuddyPress?

 

If you’ve been building websites using WordPress, most likely you have  heard of BuddyPress  .

BuddyPress is a powerful community plugin for WordPress that takes your site beyond the blog. It includes all of the features you’ve come to expect from any online community, like user profiles, groups, activity streams, notifications, and more.

Some fantastic uses we’ve seen are:

  • A campus wide social-network for your university, school or college
  • An internal communication tool for your company
  • Niche social-networks for very specific interest groups
  • Focused communities for products & services
  • Integrated with bbPress to enhance community forums

Further read: https://buddypress.org/about/

 

What does the BuddyPress for SportsPress extension do?

The BuddyPress for SportsPress  coordinates these two modules by associating your SportsPress player profiles to enrolled clients on your site, as a BuddyPress Profile.

When you have connected a player profile to an enlisted client, the BuddyPress expansion will make a part profile where you can see an action stream of any progressions that client made on the site, their SportsPress player profile points of interest, warnings for any updates to the site including that client, and a rundown of occasions they are playing.

 

 

Similar to a Facebook wall, members can write post updates on their profile page. You can use the “@” symbol to mention other members in posts so other teammates can chime in and comment on the post. These post updates are visible to your network, and are useful for starting up a team wide discussion.

Obviously there will likewise be circumstances where clients might want to send private messages to at least one individuals, and BuddyPress represents this too.

If you’re a site administrator, I know you’ll appreciate the public activity stream where any updates made by members will be displayed chronologically. This is a great way to keep track of any new changes that are made on the site.

 

At whatever point a SportsPress occasion is refreshed, a warning will show up in the WordPress dashboard to advise the site administrator and to any client who is associated with that specific refresh.

If you have been wanting to create an online community for your sports team or keep team discussions within your website, the BuddyPress for SportsPress extension will save you time by introducing the social network features BuddyPress users love.

Using Eloquent in WordPress Plugin Development

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.

Download code

Newsletter

Want to receive weekly updates? Sign up to the newsletter and never miss new article.