Create CRUD Plugin in wordpress

August 31, 20181166
Share Tweet Pin it

In this post you will clearly learn how we are creating custom plugins for CRUD operations in Wordpress. This is an example based. Here we will create company CRUD. This plugin faciliate the user to create, Edit, Delete and list for companies.

For this we require a table as follows

CREATE TABLE '.$table_name.' (
      id int(11) NOT NULL AUTO_INCREMENT,
      company_name VARCHAR (255) NOT NULL,
      website VARCHAR (255) NOT NULL,
      email VARCHAR(100) NOT NULL,
      phone int(12) NULL,
      address VARCHAR (250) NULL,
      notes VARCHAR (250) NULL,
      PRIMARY KEY  (id)
    );

Step 1

Create your plugin folder inside here we are creating companies/companies.php

wp-content/plugins/compaies/companies.php

Step 2

Now Put the following code into the file which are you can understand step by step. Put the following code into the companies.php file which will use to notify the plugin information.

/*
* Plugin Name: Companies
* Description: This plugin to create custom contact list-tables from database using WP_List_Table class.
* Version:     1.0.1
* Author:      Tailwebs
* Author URI:  https://labarta.es/
* License:     GPL2
* License URI: https://www.gnu.org/licenses/gpl-2.0.html
* Text Domain: company
* Domain Path: /languages
*/

Step 3

To load the plugin add the foloowing code

add_action('plugins_loaded', 'company_plugin_load_textdomain');
function company_plugin_load_textdomain()
{
    load_plugin_textdomain('company', false, basename(dirname(__FILE__)).'/languages');
}

Step 4

Declar the DB version of the plugin

global $company_db_version;
$company_db_version = '1.0.1';

Step 5

Declare the table structure to be create for our plugin. Here we are using as per our example. you can change it as per your table requirement.

function company_install()
{
    global $wpdb;
    global $company_db_version;

    $table_name = $wpdb->prefix.'companies';

    $sql = 'CREATE TABLE '.$table_name.' (
      id int(11) NOT NULL AUTO_INCREMENT,
      company_name VARCHAR (255) NOT NULL,
      website VARCHAR (255) NOT NULL,
      email VARCHAR(100) NOT NULL,
      phone int(12) NULL,
      address VARCHAR (250) NULL,
      notes VARCHAR (250) NULL,
      PRIMARY KEY  (id)
    );';

    require_once ABSPATH.'wp-admin/includes/upgrade.php';
    dbDelta($sql);

    add_option('company_db_version', $company_db_version);

    $installed_ver = get_option('company_db_version');
    if ($installed_ver != $company_db_version) {
        $sql = 'CREATE TABLE '.$table_name.' (
          id int(11) NOT NULL AUTO_INCREMENT,
          company_name VARCHAR (255) NOT NULL,
          website VARCHAR (100) NOT NULL,
          email VARCHAR(100) NOT NULL,
          phone int(12) NULL,
          address VARCHAR (250) NULL,
          notes VARCHAR (250) NULL,
          PRIMARY KEY  (id)
        );';

        require_once ABSPATH.'wp-admin/includes/upgrade.php';
        dbDelta($sql);

        update_option('company_db_version', $company_db_version);
    }
}

Step 6

Now its the time to load the plugin and check the corresponded tables has been create in the db or not. Here in this step we have use the WP default table listing function and plugins_loaded function for action call.

register_activation_hook(__FILE__, 'company_install');

function company_install_data()
{
    global $wpdb;

    $table_name = $wpdb->prefix.'companies';
}

register_activation_hook(__FILE__, 'company_install_data');

function company_update_db_check()
{
    global $company_db_version;
    if (get_site_option('company_db_version') != $company_db_version) {
        company_install();
    }
}

add_action('plugins_loaded', 'company_update_db_check');

if (!class_exists('WP_List_Table')) {
    require_once ABSPATH.'wp-admin/includes/class-wp-list-table.php';
}

Step 7

Let us create the CRUD operation in admin area for the table we have created inside this plugin. The following functions are responsible for the CRUD operation in admin area.

class Company_Tables extends WP_List_Table
{
    public function __construct()
    {
        global $status, $page;

        parent::__construct(array(
            'singular' => 'company',
            'plural' => 'companies',
        ));
    }

    public function column_default($item, $column_name)
    {
        return $item[$column_name];
    }

    public function column_phone($item)
    {
        return ''.$item['phone'].'';
    }

    public function column_name($item)
    {
        $actions = array(
            'edit' => sprintf('%s', $item['id'], __('Edit', 'company')),
            'delete' => sprintf('%s', $_REQUEST['page'], $item['id'], __('Delete', 'company')),
        );

        return sprintf('%s %s',
            $item['company_name'],
            $this->row_actions($actions)
        );
    }

    public function column_cb($item)
    {
        return sprintf(
            '',
            $item['id']
        );
    }

    public function get_columns()
    {
        $columns = array(
            'cb' => '',
            'company_name' => __('Company Name', 'company'),
            'website' => __('Website', 'company'),
            'email' => __('E-Mail', 'company'),
            'phone' => __('Phone', 'company'),
            'address' => __('Address', 'company'),
            'notes' => __('Notes', 'company'),
        );

        return $columns;
    }

    public function get_sortable_columns()
    {
        $sortable_columns = array(
            'company_name' => array('company_name', true),
            'website' => array('website', true),
            'email' => array('email', false),
            'phone' => array('phone', false),
            'address' => array('address', false),
            'notes' => array('notes', false),
        );

        return $sortable_columns;
    }

    public function get_bulk_actions()
    {
        $actions = array(
            'delete' => 'Delete',
        );

        return $actions;
    }

    public function process_bulk_action()
    {
        global $wpdb;
        $table_name = $wpdb->prefix.'companies';

        if ('delete' === $this->current_action()) {
            $ids = isset($_REQUEST['id']) ? $_REQUEST['id'] : array();
            if (is_array($ids)) {
                $ids = implode(',', $ids);
            }

            if (!empty($ids)) {
                $wpdb->query("DELETE FROM $table_name WHERE id IN($ids)");
            }
        }
    }

    public function prepare_items()
    {
        global $wpdb;
        $table_name = $wpdb->prefix.'companies';

        $per_page = 10;

        $columns = $this->get_columns();
        $hidden = array();
        $sortable = $this->get_sortable_columns();

        $this->_column_headers = array($columns, $hidden, $sortable);

        $this->process_bulk_action();

        $total_items = $wpdb->get_var("SELECT COUNT(id) FROM $table_name");

        $paged = isset($_REQUEST['paged']) ? max(0, intval($_REQUEST['paged']) - 1) : 0;
        $orderby = (isset($_REQUEST['orderby']) && in_array($_REQUEST['orderby'], array_keys($this->get_sortable_columns()))) ? $_REQUEST['orderby'] : 'lastname';
        $order = (isset($_REQUEST['order']) && in_array($_REQUEST['order'], array('asc', 'desc'))) ? $_REQUEST['order'] : 'asc';

        $this->items = $wpdb->get_results($wpdb->prepare("SELECT * FROM $table_name ORDER BY $orderby $order LIMIT %d OFFSET %d", $per_page, $paged), ARRAY_A);

        $this->set_pagination_args(array(
            'total_items' => $total_items,
            'per_page' => $per_page,
            'total_pages' => ceil($total_items / $per_page),
        ));
    }
}

Step 8

In this step we will add menu to the admin area for the new installed plugin which helps user/admin to manage the CRUD

function company_admin_menu()
{
    add_menu_page(__('Company', 'company'), __('Companies', 'company'), 'activate_plugins', 'companies', 'company_companies_page_handler');
    add_submenu_page('companies', __('Companies', 'company'), __('Companies', 'company'), 'activate_plugins', 'companies', 'company_companies_page_handler');

    add_submenu_page('companiess', __('Add new', 'company'), __('Add new', 'company'), 'activate_plugins', 'companies_form', 'company_companies_form_page_handler');
}

add_action('admin_menu', 'company_admin_menu');

Step 9

Let us create the view files to be create here for the plugin CRUD operations in admin area

function company_companies_page_handler()
{
    global $wpdb;

    $table = new Company_Tables();
    $table->prepare_items();

    $message = '';
    if ('delete' === $table->current_action()) {
        $message = '

'.sprintf(__('Items deleted: %d', 'company'), count($_REQUEST['id'])).'

'; } ?>

display(); ?>
prefix.'companies'; $message = ''; $notice = ''; $default = array( 'id' => 0, 'company_name' => '', 'website' => '', 'email' => '', 'phone' => null, 'address' => '', 'notes' => '', ); if (isset($_REQUEST['nonce']) && wp_verify_nonce($_REQUEST['nonce'], basename(__FILE__))) { $item = shortcode_atts($default, $_REQUEST); $item_valid = company_validate_contact($item); if ($item_valid === true) { if ($item['id'] == 0) { $result = $wpdb->insert($table_name, $item); $item['id'] = $wpdb->insert_id; if ($result) { $message = __('Item was successfully saved', 'company'); } else { $notice = __('There was an error while saving item', 'company'); } } else { $result = $wpdb->update($table_name, $item, array('id' => $item['id'])); if ($result) { $message = __('Item was successfully updated', 'company'); } else { $notice = __('There was an error while updating item', 'company'); } } } else { $notice = $item_valid; } } else { $item = $default; if (isset($_REQUEST['id'])) { $item = $wpdb->get_row($wpdb->prepare("SELECT * FROM $table_name WHERE id = %d", $_REQUEST['id']), ARRAY_A); if (!$item) { $item = $default; $notice = __('Item not found', 'company'); } } } add_meta_box('companies_form_meta_box', __('Contact data', 'company'), 'company_companies_form_meta_box_handler', 'contact', 'normal', 'default'); ?>







Step 10

In this step we will Validate the form data submitted by the admin/user

function company_validate_contact($item)
{
    $messages = array();

    if (empty($item['company_name'])) {
        $messages[] = __('Company Name is required', 'company');
    }
    if (empty($item['website'])) {
        $messages[] = __('Website is required', 'company');
    }
    if (!empty($item['email']) && !is_email($item['email'])) {
        $messages[] = __('E-Mail is in wrong format', 'company');
    }
    if (!empty($item['phone']) && !absint(intval($item['phone']))) {
        $messages[] = __('Phone can not be less than zero');
    }
    if (!empty($item['phone']) && !preg_match('/[0-9]+/', $item['phone'])) {
        $messages[] = __('Phone must be number');
    }

    if (empty($messages)) {
        return true;
    }

    return implode('
', $messages); } function company_languages() { load_plugin_textdomain('company', false, dirname(plugin_basename(__FILE__))); } add_action('init', 'company_languages');

Now the plugin is ready to activate in admin area. All the best