Part 2 of 13 · Elite Limo Booking

How I Structured a Big WordPress Plugin Without It Becoming a Mess

Developer workspace showing WordPress plugin code and an architecture diagram with separate plugin modules

A plugin with a dozen features can collapse into chaos shockingly fast. One file grows to thousands of lines, every function touches every other, and fixing payments somehow breaks bookings. Before that could happen to the limo plugin, I forced a structure on it, and the structure is simple enough to say in one sentence: one class per job, and the main file is only a conductor.

Concretely, the main plugin file does almost nothing itself. It defines constants, loads the pieces, and wires them up:

define('ELITE_LIMO_PLUGIN_URL',  plugin_dir_url(__FILE__));
define('ELITE_LIMO_PLUGIN_PATH', plugin_dir_path(__FILE__));
define('ELITE_LIMO_VERSION',     '1.0.0');

private function load_dependencies() {
    require_once ELITE_LIMO_PLUGIN_PATH . 'includes/class-database.php';
    require_once ELITE_LIMO_PLUGIN_PATH . 'includes/class-firebase-otp.php';
    require_once ELITE_LIMO_PLUGIN_PATH . 'includes/class-stripe-payment.php';
    require_once ELITE_LIMO_PLUGIN_PATH . 'includes/class-driver-assignment.php';
    require_once ELITE_LIMO_PLUGIN_PATH . 'includes/class-notifications.php';
}

Look at the file names, they are the feature list. Database work in one class, phone verification in another, payments in another, driver assignment in another, notifications in another. Every class owns one job completely, and no class reaches into another’s internals. When a payment bug appears, there is exactly one file to open. When I added a feature, it arrived as a new class and one require_once line, not as another two hundred lines braided into an existing tangle.

Two practical details carry this structure. First, the constants. plugin_dir_path(__FILE__) gives the plugin’s absolute folder on disk, for requiring PHP files, and plugin_dir_url(__FILE__) gives its web address, for loading scripts and styles. Mixing those two up is a classic WordPress beginner break, paths are for the server, URLs are for the browser, and each function exists because the other’s value is wrong for its job.

Second, the conductor idea in practice. The main class holds references to the pieces and passes work to them, the booking flow asks the OTP class to verify, then the payment class to charge, then the assignment class to dispatch. Each specialist stays ignorant of the others’ insides. That ignorance is the feature, it is what lets one part change without the others noticing.

A few things people ask me about this

How big should a plugin be before splitting into classes? Sooner than feels necessary. The moment a second distinct job appears, payments alongside bookings, split. Restructuring at three thousand lines hurts far more than starting structured.

What is the difference between plugin_dir_path and plugin_dir_url? Path is the server filesystem location, used with require_once. URL is the public web address, used with wp_enqueue_script and styles. Never swap them.

Next

Structure is skeleton, but a plugin is not alive until WordPress calls it. Wiring into WordPress properly, activation hooks, shortcodes, and AJAX, is the next post.

Leave a Reply

Your email address will not be published. Required fields are marked *