How to structure a plugin into multiple files using classes?

I am writing my first simple plugin from scratch so I’m looking for a bit of advice on structuring the classes within the plugin. I encapsulated some basic functions in a class in the main plugin file but I guess it will become quite ungainly with a lot of functions in a single file.

The structure of my plugin directory so far looks like this:

inc
  -core.php
  -plugin-settings.php
css
  -style.css
lang
plugin-file.php

One thing that I have struggled with is structuring plugin into multiple files using classes.

The code of main plugin file is:

<?php
/**
* Plugin Name: Plugin name
* Plugin URI: http://someurl.com
* Description: Some description
* Version: 1.0
* Author: Me
* Author URI: http://someurl.com
*/
define( 'SBP_DIR', plugin_dir_path( __FILE__ ) );   // Defining plugin dir path.
/*----------------------------------------------
    Including Files
----------------------------------------------*/
include(SBP_DIR_DIR . 'inc/core.php');              // main plugin functions
include(SBP_DIR_DIR . 'inc/plugin-settings.php');   // the plugin options page HTML
/*----------------------------------------------
    Class Dummy_Class
----------------------------------------------*/
global $sbp_class;
if ( !class_exists("Dummy_Class") ) {
    class Dumy_Class {
/*----------------------------------------------
    Function Construct
----------------------------------------------*/
        function __construct() {
            $this->path = plugin_basename(__FILE__);
            add_action( 'init', array( $this, 'init' ) );
            add_action('admin_enqueue_scripts',  array( $this, 'enqueue' ) );
            add_filter("plugin_action_links_$this->path", array( $this, 'sbp_settings_link' ) );
        }
/*----------------------------------------------
    Function init
----------------------------------------------*/
        function init() {
            load_plugin_textdomain( 'sb-pack', false, basename( dirname( __FILE__ ) ) . '/lang' );  // load plugin textdomain
        }
/*----------------------------------------------
    CSS style of the plugin options page
----------------------------------------------*/
        function enqueue($hook) {
            global $sbp_settings_page;
            if ( $hook != $sbp_settings_page )  // load stylesheet only on plugin option page
                return;
            wp_enqueue_style('styles', plugin_dir_url( __FILE__ ) . 'css/styles.css');
        }
/*----------------------------------------------
    Add settings link on plugins page
----------------------------------------------*/
        function sbp_settings_link($links) {
            $settings_link = '<a href="https://wordpress.stackexchange.com/questions/144003/options-general.php?page=sbp-options">Settings</a>';
            array_unshift($links, $settings_link);
            return $links;
        }

    }   //End class Dummy_Class
    $sb_pack = new Dummy_Class; // instantiate the plugin class
}   //End if (!class_exists("Dummy_Class"))

I want to mention that core.php file contains what the plugin does, ie some several functions.

My questions are:

  1. How should be included the core.php and plugin-settings.php files within the main plugin file?
  2. Those files should have unique classes too? How YOU would structure them and why?

I do not have in-depth knowledge of OOP so I need a little bit of step by step instruction.

Any thoughts would be appreciated.

1 Answer
1

Some basic rules for object organization in a plugin.

  • One class declaration per file, no other code in that file. The creation of a new instance – new Dummy_Class – should not be in the same file as the class declaration.

  • Everything that is sending data to the user (presentation) should get its own class: HTML, CSV, XML output or HTTP headers.

  • Every algorithm, every data source should get its own class, so you can change it later. Lets say, you store some data in an option and want change that later to use a custom database table: then you should be able to do that without changing all files.

  • Registration and creation of objects belongs to a separate class (controller).
    add_action( 'something', array( $this, 'callback' ) ) is usually a sign of bad design. Use a separate object instead of $this.

  • Avoid global constants, they clutter up the global namespace. Just pass the path of the current plugin file to the main controller.

Leave a Comment