LESSON 1 โฑ๏ธ 12 min read

Introduction & Plugin Architecture

Welcome to Modern Plugin Development

WordPress plugins extend and modify WordPress functionality without touching core files. In this tutorial, you'll build a complete Task Manager plugin using modern object-oriented PHP patterns.

By the end, you'll have a fully-functional plugin that:

  • Uses proper OOP architecture with namespaces
  • Has its own admin interface with settings
  • Stores data in a custom database table
  • Exposes a REST API for AJAX operations
  • Follows WordPress coding standards and security best practices

The Plugin Header

Every WordPress plugin starts with a header comment in the main PHP file:

<?php
/**
 * Plugin Name:       Task Manager
 * Plugin URI:        https://example.com/task-manager
 * Description:       A modern task management plugin built with OOP.
 * Version:           1.0.0
 * Requires at least: 6.0
 * Requires PHP:      8.0
 * Author:            Your Name
 * Author URI:        https://example.com
 * License:           GPL v2 or later
 * License URI:       https://www.gnu.org/licenses/gpl-2.0.html
 * Text Domain:       task-manager
 * Domain Path:       /languages
 */
Required Fields: Only Plugin Name is truly required, but including Version, Description, Author, and Text Domain is standard practice.

Modern Plugin File Structure

We'll use this organized structure for our Task Manager plugin:

task-manager/
โ”œโ”€โ”€ task-manager.php          # Main plugin file (bootstrap)
โ”œโ”€โ”€ composer.json             # Autoloading configuration
โ”œโ”€โ”€ uninstall.php             # Cleanup on uninstall
โ”œโ”€โ”€ readme.txt                # WordPress.org readme
โ”œโ”€โ”€ assets/
โ”‚   โ”œโ”€โ”€ css/
โ”‚   โ”‚   โ””โ”€โ”€ admin.css         # Admin styles
โ”‚   โ””โ”€โ”€ js/
โ”‚       โ””โ”€โ”€ admin.js          # Admin scripts
โ”œโ”€โ”€ languages/
โ”‚   โ””โ”€โ”€ task-manager.pot      # Translation template
โ”œโ”€โ”€ src/                      # PHP source files
โ”‚   โ”œโ”€โ”€ Plugin.php            # Main plugin class
โ”‚   โ”œโ”€โ”€ Activator.php         # Activation logic
โ”‚   โ”œโ”€โ”€ Deactivator.php       # Deactivation logic
โ”‚   โ”œโ”€โ”€ Admin/
โ”‚   โ”‚   โ”œโ”€โ”€ AdminMenu.php     # Admin menu registration
โ”‚   โ”‚   โ”œโ”€โ”€ Settings.php      # Settings page
โ”‚   โ”‚   โ””โ”€โ”€ TasksPage.php     # Tasks management page
โ”‚   โ”œโ”€โ”€ Database/
โ”‚   โ”‚   โ””โ”€โ”€ TasksTable.php    # Database operations
โ”‚   โ”œโ”€โ”€ REST/
โ”‚   โ”‚   โ””โ”€โ”€ TasksController.php  # REST API endpoints
โ”‚   โ””โ”€โ”€ Models/
โ”‚       โ””โ”€โ”€ Task.php          # Task data model
โ””โ”€โ”€ vendor/                   # Composer autoloader (gitignored)

Why Object-Oriented PHP?

Traditional WordPress plugins often use procedural code with prefixed functions:

// โŒ Procedural approach - harder to maintain
function tm_create_task( $title ) { /* ... */ }
function tm_get_tasks() { /* ... */ }
function tm_delete_task( $id ) { /* ... */ }
function tm_admin_menu() { /* ... */ }
function tm_enqueue_scripts() { /* ... */ }

OOP provides better organization, reusability, and testability:

// โœ… OOP approach - clean and maintainable
namespace TaskManagerDatabase;

class TasksTable {
    public function create( array $data ): int { /* ... */ }
    public function find( int $id ): ?Task { /* ... */ }
    public function delete( int $id ): bool { /* ... */ }
}

Benefits of OOP in Plugins

  1. Encapsulation โ€“ Related code grouped in classes
  2. Namespaces โ€“ No function name collisions
  3. Autoloading โ€“ No manual require statements
  4. Testability โ€“ Classes can be unit tested
  5. Reusability โ€“ Extend and compose classes

The Main Plugin File

Our bootstrap file will be minimal โ€“ just constants and initialization:

<?php
/**
 * Plugin Name: Task Manager
 * ...header fields...
 */

// Prevent direct access
if ( ! defined( 'ABSPATH' ) ) {
    exit;
}

// Plugin constants
define( 'TM_VERSION', '1.0.0' );
define( 'TM_PLUGIN_FILE', __FILE__ );
define( 'TM_PLUGIN_DIR', plugin_dir_path( __FILE__ ) );
define( 'TM_PLUGIN_URL', plugin_dir_url( __FILE__ ) );

// Composer autoloader
if ( file_exists( TM_PLUGIN_DIR . 'vendor/autoload.php' ) ) {
    require_once TM_PLUGIN_DIR . 'vendor/autoload.php';
}

// Initialize plugin
function tm_init() {
    return TaskManagerPlugin::get_instance();
}
add_action( 'plugins_loaded', 'tm_init' );

// Activation & Deactivation
register_activation_hook( __FILE__, [ TaskManagerActivator::class, 'activate' ] );
register_deactivation_hook( __FILE__, [ TaskManagerDeactivator::class, 'deactivate' ] );
Security First: Always include the if ( ! defined( 'ABSPATH' ) ) exit; check to prevent direct file access.

What We'll Build: Task Manager

Throughout this tutorial, we'll build these features:

FeatureTechniques
Admin dashboardadd_menu_page(), custom templates
Settings pageSettings API, options storage
Task CRUDCustom database table, $wpdb
REST APIregister_rest_route(), controllers
AJAX interfacewp_ajax_*, JavaScript fetch
SecurityNonces, capabilities, sanitization

Setting Up Your Development Environment

Before we start coding, ensure you have:

  1. Local WordPress โ€“ LocalWP, DDEV, or Docker
  2. Composer โ€“ For autoloading (composer init)
  3. Code editor โ€“ VS Code with PHP Intelephense
  4. Debug mode โ€“ Enable WP_DEBUG in wp-config.php
// wp-config.php - Development settings
define( 'WP_DEBUG', true );
define( 'WP_DEBUG_LOG', true );
define( 'WP_DEBUG_DISPLAY', true );
define( 'SCRIPT_DEBUG', true );

Next Steps

In the next lesson, we'll set up Composer, configure PSR-4 autoloading, and create our main Plugin class using the singleton pattern.

๐ŸŽฏ Lesson Complete! You now understand the structure and architecture of a modern WordPress plugin.