Back to all posts

Exploring the Bulk Importer Plugin in WordPress


In WordPress, plugins are powerful tools that extend the functionality of a website. One such plugin is the Bulk Importer, which allows you to import data from a CSV file into a custom database table. In this blog post, we will dive into the code of the Bulk Importer plugin, line by line, to understand its structure and how to modify it for future enhancements.

Plugin Setup:

Let’s start by examining the initial section of the code, which defines the plugin name, version, and author. This information is important for plugin identification and management.

/*
  Plugin Name: Bulk Importer
  Version: 1.0
  Author: Chethan S Poojary
*/

Plugin Class:

The core functionality of the Bulk Importer plugin is encapsulated within a class named BraProductImporter. This class contains various methods that handle table creation, data insertion, and CSV import processing.

// Define the BraProductImporter class
class BraProductImporter
{
    // Class properties
    private $table_name;
    private $import_success;
    private $error_message;
    
    // Class constructor
    public function __construct()
    {
        global $wpdb;
        $this->table_name = $wpdb->prefix . 'bra_products';
        $this->import_success = false;
        $this->error_message = '';
    }

The class defines three private properties: $table_name, $import_success, and $error_message. These properties are used to store the table name, import success status, and error messages, respectively.

The constructor method is called when an instance of the class is created. It initializes the class properties, including the $table_name, which is set by appending the WordPress database prefix to 'bra_products'.

Table Creation:

The create_custom_table() method is responsible for creating a custom table in the WordPress database during plugin activation.

// Create the custom table during plugin activation
public function create_custom_table()
{
    global $wpdb;

    $sql = "CREATE TABLE IF NOT EXISTS {$this->table_name} (
        id INT UNSIGNED AUTO_INCREMENT PRIMARY KEY,
        brand VARCHAR(255),
        product VARCHAR(255),
        model VARCHAR(255),
        band INT,
        bust INT,
        fit VARCHAR(255),
        product_band INT,
        product_cup VARCHAR(255)
    );";

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

The SQL query is defined as a string in the $sql variable. It creates a table with columns for id, brand, product, model, band, bust, fit, product_band, and product_cup. The AUTO_INCREMENT keyword ensures that the id column auto-increments for each new row.

The dbDelta() function, provided by WordPress, is used to execute the SQL query and create the table. It also handles database schema updates for existing tables.

Data Insertion:

The insert_product() method inserts a single row into the custom table.

// Insert a single row into the custom table
public function insert_product($data)
{
    global $wpdb;

    // Prepare the data for insertion
    $product_data = array(
        'brand' => $data[0],
        'product' => $data[1],
        'model' => $data[2],
        'band' => $data[3],
        'bust' => $data[4],
        'fit' => $data[5],
        'product_band' => $data[6],
        'product_cup' => $data[7]
    );

    // Insert the data into the table
    $result = $wpdb->insert($this->table_name, $product_data);

    // Check if the data insertion was successful
    if ($result) {
        $insert_id = $wpdb->insert_id;
        return 'Data inserted successfully. Insert ID: ' . $insert_id;
    } else {
        return new WP_Error('insert_failed', 'Error: Failed to insert data into the table.');
    }
}

The method accepts an array of data representing a product. The data is prepared in an associative array format to match the table columns. The $wpdb->insert() function is used to insert the data into the table.

If the insertion is successful, the method returns a success message with the insert ID. If the insertion fails, a WP_Error object is returned with an error message.

CSV Import Processing:

The process_csv_import() method handles the processing of the uploaded CSV file.

   // Process the uploaded CSV file
    public function process_csv_import()
    {
        if (isset($_POST['submit']) && isset($_FILES['csv_file'])) {
    
            if (!wp_verify_nonce($_POST['_wpnonce'], 'csv_import_nonce')) {
                $this->error_message = new WP_Error('nonce_verification_failed', 'Error: Nonce verification failed.');
                return;
            }
    
            if (!current_user_can('administrator')) {
                $this->error_message = new WP_Error('no_permission', 'Error: You do not have permission to upload files.');
                return;
            }
    
            $file_path = $_FILES['csv_file']['tmp_name'];
            if (($handle = fopen($file_path, "r")) !== FALSE) {
                $row_number = 1; // Initialize row number
                while (($data = fgetcsv($handle, 5000, ",")) !== FALSE) {
                    if ($row_number === 1) {
                        $row_number++;
                        continue; // Ignore the first row
                    }
    
                    // Check if all fields are filled
                    if (count($data) === 8 && !in_array('', $data, true)) {
                        $result = $this->insert_product($data);
                        if (is_wp_error($result)) {
                            $this->error_message = new WP_Error('missing_fields', 'Error: Row ' . $row_number . ' has missing fields.');
                            break;
                        }
                    } else {
                        $this->error_message = new WP_Error('missing_fields', 'Error: Row ' . $row_number . ' has missing fields.');
                        break;
                    }
    
                    $row_number++;
                }
                fclose($handle);
            } else {
                $this->error_message = new WP_Error('file_open_failed', 'Error: Failed to open the CSV file.');
            }
    
            if (empty($this->error_message)) {
                $this->import_success = true;
            }
        }
    }

The method is triggered when the form is submitted ($_POST['submit']) and a file is uploaded ($_FILES['csv_file']). The file processing logic is implemented within this conditional block.

The wp_verify_nonce() function is used to verify the security nonce. Nonces are used to protect against cross-site request forgery (CSRF) attacks. If the verification fails, an error message is set.

A permission check is performed to ensure that only administrators can upload files. If the current user doesn’t have administrator capabilities, an error message is set.

The uploaded CSV file is opened using fopen(), and its contents are processed using fgetcsv() line by line. Each line represents a product’s data.

The first row is ignored ($row_number === 1) since it typically contains column headers.

The data is checked to ensure all fields are filled. If any field is missing (''), an error message is set.

The insert_product() method is called to insert the product data into the table. If the insertion fails, an error message is set.

The row number is incremented for each iteration.

After the CSV file is processed, it is closed, and if no error messages are set, the import is considered successful.

Shortcode and Form Display:

The csv_import_form() method generates the HTML form for uploading the CSV file.

<?php
//Design Import Form    
public function csv_import_form()
    {
        ob_start();
        if (current_user_can('administrator')) {
            if ($this->import_success) {
                echo '<p>Data imported successfully!</p>';
            } elseif (is_wp_error($this->error_message)) {
                echo '<p>' . esc_html($this->error_message->get_error_message()) . '</p>';
            }
?>
            <form method="post" enctype="multipart/form-data">
                <?php wp_nonce_field('csv_import_nonce'); ?>
                <input required type="file" name="csv_file" accept=".csv">
                <input type="submit" name="submit" value="Import">
            </form>
<?php
        } else {
            echo '<p>Error: You do not have permission to use this shortcode.</p>';
        }
        // Get the contents of the output buffer and assign it to a variable
        $import_form = ob_get_clean();
        return $import_form;
    }

The method is responsible for displaying the form to upload the CSV file. It checks the user’s permission and displays success/error messages accordingly.

The ob_start() function initiates an output buffer to capture the generated HTML. it generated form HTML is returned.

Plugin Integration:

The following code integrates the plugin by registering hooks and callbacks.

// Create an instance of the BraProductImporter class
$bra_product_importer = new BraProductImporter();

// Register hooks and callbacks
register_activation_hook(__FILE__, array($bra_product_importer, 'create_custom_table'));
add_action('admin_menu', array($bra_product_importer, 'register_product_importer_page'));
add_action('init', array($bra_product_importer, 'process_csv_import'));
add_shortcode('csv_import', array($bra_product_importer, 'csv_import_form'));

BraProductImporter class create an instance class

The create_custom_table() method is registered as the callback for the plugin’s activation hook. It ensures the custom table is created when the plugin is activated.

The register_product_importer_page() method is registered as a callback for the admin_menu action hook. It adds a menu page for the product importer in the WordPress admin dashboard.

The process_csv_import() method is registered as a callback for the init action hook. It handles the CSV file import processing.

The csv_import_form() method is registered as a shortcode callback for the [csv_import] shortcode. It generates and displays the import form.

Conclusion:

In this blog post, we’ve explored the Bulk Importer plugin code, line by line, understanding its structure and functionality. We’ve learned about table creation, data insertion, CSV import processing, and form display. Armed with this knowledge, you can modify the code to suit your specific requirements, such as adding additional fields, customizing error messages, or extending the plugin’s capabilities. WordPress plugins provide endless possibilities for enhancing and extending your website’s functionality, and the Bulk Importer plugin serves as a great starting point for handling CSV imports. Happy coding!


Check out complete code
Download Plugin
Download Sample Data To Upload



<?php
/*
  Plugin Name: Bulk Importer
  Version: 1.0
  Author: Chethan
*/

if (!defined('ABSPATH')) {
    exit; // Exit if accessed directly
}

// Define the BraProductImporter class
class BraProductImporter
{
    private $table_name;
    private $import_success;
    private $error_message;

    public function __construct()
    {
        global $wpdb;
        $this->table_name = $wpdb->prefix . 'bra_products'; // Replace with your table name
        $this->import_success = false;
        $this->error_message = '';
    }

    // Create the custom table during plugin activation
    public function create_custom_table()
    {
        global $wpdb;

        $sql = "CREATE TABLE IF NOT EXISTS {$this->table_name} (
          id INT UNSIGNED AUTO_INCREMENT PRIMARY KEY,
          brand VARCHAR(255),
          product VARCHAR(255),
          model VARCHAR(255),
          band INT,
          bust INT,
          fit VARCHAR(255),
          product_band INT,
          product_cup VARCHAR(255)
      );";

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

    // Insert a single row into the custom table
    public function insert_product($data)
    {
        global $wpdb;

        // Prepare the data for insertion
        $product_data = array(
            'brand' => $data[0],
            'product' => $data[1],
            'model' => $data[2],
            'band' => $data[3],
            'bust' => $data[4],
            'fit' => $data[5],
            'product_band' => $data[6],
            'product_cup' => $data[7]
        );

        // Insert the data into the table
        $result = $wpdb->insert($this->table_name, $product_data);

        // Check if the data insertion was successful
        if ($result) {
            $insert_id = $wpdb->insert_id;
            return 'Data inserted successfully. Insert ID: ' . $insert_id;
        } else {
            return new WP_Error('insert_failed', 'Error: Failed to insert data into the table.');
        }
    }

    // Process the uploaded CSV file
    public function process_csv_import()
    {
        if (isset($_POST['submit']) && isset($_FILES['csv_file'])) {
    
            if (!wp_verify_nonce($_POST['_wpnonce'], 'csv_import_nonce')) {
                $this->error_message = new WP_Error('nonce_verification_failed', 'Error: Nonce verification failed.');
                return;
            }
    
            if (!current_user_can('administrator')) {
                $this->error_message = new WP_Error('no_permission', 'Error: You do not have permission to upload files.');
                return;
            }
    
            $file_path = $_FILES['csv_file']['tmp_name'];
            if (($handle = fopen($file_path, "r")) !== FALSE) {
                $row_number = 1; // Initialize row number
                while (($data = fgetcsv($handle, 5000, ",")) !== FALSE) {
                    if ($row_number === 1) {
                        $row_number++;
                        continue; // Ignore the first row
                    }
    
                    // Check if all fields are filled
                    if (count($data) === 8 && !in_array('', $data, true)) {
                        $result = $this->insert_product($data);
                        if (is_wp_error($result)) {
                            $this->error_message = new WP_Error('missing_fields', 'Error: Row ' . $row_number . ' has missing fields.');
                            break;
                        }
                    } else {
                        $this->error_message = new WP_Error('missing_fields', 'Error: Row ' . $row_number . ' has missing fields.');
                        break;
                    }
    
                    $row_number++;
                }
                fclose($handle);
            } else {
                $this->error_message = new WP_Error('file_open_failed', 'Error: Failed to open the CSV file.');
            }
    
            if (empty($this->error_message)) {
                $this->import_success = true;
            }
        }
    }
    
    

    public function csv_import_form()
    {
        ob_start();
        if (current_user_can('administrator')) {
            if ($this->import_success) {
                echo '<p>Data imported successfully!</p>';
            } elseif (is_wp_error($this->error_message)) {
                echo '<p>' . esc_html($this->error_message->get_error_message()) . '</p>';
            }
?>
            <form method="post" enctype="multipart/form-data">
                <?php wp_nonce_field('csv_import_nonce'); ?>
                <input required type="file" name="csv_file" accept=".csv">
                <input type="submit" name="submit" value="Import">
            </form>
<?php
        } else {
            echo '<p>Error: You do not have permission to use this shortcode.</p>';
        }
        // Get the contents of the output buffer and assign it to a variable
        $import_form = ob_get_clean();
        return $import_form;
    }

    // Register the Product Importer page in the WordPress backend
    public function register_product_importer_page()
    {
        add_menu_page(
            'Product Importer',
            'Product Importer',
            'administrator',
            'product-importer',
            array($this, 'display_product_importer_page')
        );
    }

    // Display the Product Importer page content
    public function display_product_importer_page()
    {
        echo '<h1>Product Importer</h1>';
        echo do_shortcode('[csv_import]');
    }
}

// Create an instance of the BraProductImporter class
$bra_product_importer = new BraProductImporter();

// Register hooks and callbacks
register_activation_hook(__FILE__, array($bra_product_importer, 'create_custom_table'));
add_action('admin_menu', array($bra_product_importer, 'register_product_importer_page'));
add_action('init', array($bra_product_importer, 'process_csv_import'));
add_shortcode('csv_import', array($bra_product_importer, 'csv_import_form'));