Back to all posts

WordPress Must-Use Plugin with a helpers.php File


What is a Must-Use Plugin?

Must-use plugins, or MU plugins, are plugins that WordPress automatically loads. They are placed in the wp-content/mu-plugins directory and do not require manual activation through the WordPress admin dashboard. This makes them ideal for crucial functionality that should always be active on your site.

Why Use a helpers.php File?

When building complex plugins, your code can become unwieldy if everything is placed in a single file. The helpers.php file allows you to store common functions separately, making your code more modular, readable, and easier to maintain. It’s especially useful for:

  • Data sanitization and validation
  • Formatting responses
  • Logging events
  • Handling authentication and permissions

Setting Up Your Plugin Structure

Here’s how to structure your must-use plugin:

wp-content/
└── mu-plugins/
    └── custom-rest-api.php
        ├── endpoints/
        │   ├── example-endpoint.php
        │   └── another-endpoint.php
        └── inc/
            └── helpers.php

Main Plugin File

set up your main plugin file to include the helpers.php file and your endpoint files:

<?php
// custom-rest-api.php

/*
Plugin Name: Custom REST API
Description: A must-use plugin to add custom REST API routes.
Author: Your Name
Version: 1.0
*/

// Include helper and endpoint files
require_once __DIR__ . '/inc/helpers.php';
require_once __DIR__ . '/endpoints/example-endpoint.php';
require_once __DIR__ . '/endpoints/another-endpoint.php';
?>

Creating the helpers.php File

<?php
// inc/helpers.php

function custom_sanitize_input($input) {
    return sanitize_text_field($input);
}

function custom_validate_string($input) {
    return is_string($input) && !empty($input);
}

function custom_format_response($data) {
    return [
        'status' => 'success',
        'data' => $data,
    ];
}

function custom_log_event($message) {
    if (defined('WP_DEBUG') && WP_DEBUG) {
        error_log($message);
    }
}

function custom_check_permissions() {
    if (!is_user_logged_in()) {
        return new WP_Error('rest_forbidden', 'You cannot access this route', ['status' => 403]);
    }

    if (!current_user_can('manage_options')) {
        return new WP_Error('rest_forbidden', 'You do not have sufficient permissions to access this route', ['status' => 403]);
    }

    return true;
}
?>

Example Endpoint Files

Now, let’s create the endpoint files using the helper functions.

endpoints/example-endpoint.php

<?php
// endpoints/example-endpoint.php

add_action('rest_api_init', function() {
    register_rest_route('custom/v1', '/example', [
        'methods' => 'GET',
        'callback' => 'custom_example_route_callback',
        'permission_callback' => 'custom_check_permissions'
    ]);
});

function custom_example_route_callback(WP_REST_Request $request) {
    custom_log_event('Example endpoint accessed');
    return new WP_REST_Response(custom_format_response(['message' => 'Hello, World!']), 200);
}
?>

endpoints/another-endpoint.php

<?php
// endpoints/another-endpoint.php

add_action('rest_api_init', function() {
    register_rest_route('custom/v1', '/another', [
        'methods' => 'POST',
        'callback' => 'custom_another_route_callback',
        'permission_callback' => 'custom_check_permissions',
        'args' => [
            'example_param' => [
                'required' => true,
                'validate_callback' => 'custom_validate_string',
                'sanitize_callback' => 'custom_sanitize_input'
            ],
        ],
    ]);
});

function custom_another_route_callback(WP_REST_Request $request) {
    $param = $request->get_param('example_param');
    custom_log_event('Another endpoint accessed with param: ' . $param);
    return new WP_REST_Response(custom_format_response(['message' => 'Received: ' . esc_html($param)]), 200);
}
?>

Benefits of Using a helpers.php File

  • Code Reusability: By centralizing common functions, you can reuse them across multiple endpoints, reducing code duplication.
  • Improved Readability: Separating helper functions from endpoint logic makes your code easier to read and understand.
  • Easier Maintenance: If you need to update a common function, you only need to do it in one place, simplifying maintenance.
  • Modularity: Keeping your code modular allows you to add new features and endpoints without affecting existing functionality.

By modularizing your code and using helper functions, you can build more robust and scalable plugins. This approach is particularly beneficial when working with custom REST API routes, where clean and efficient code can significantly improve your development workflow and overall site performance.

Read More