Yes. We start with Step 1 only: create a safe MU plugin skeleton.
The purpose of Step 1 is not yet concurrency. It is to create a stable place where all future code will live, confirm WordPress loads it, and avoid breaking FluentSupport while we are still experimenting.
WordPress MU plugins are automatically enabled from `wp-content/mu-plugins`, cannot be disabled from the normal plugin screen, and WordPress only auto-loads PHP files directly inside that folder, not files hidden inside subfolders. So we use one root loader file, then load our organized module files from a subfolder. ([WordPress Developer Resources]1)
FluentSupport also officially exposes action hooks, filter hooks, helper classes, utility functions, and REST/API-related extension points, so this is the correct direction for extending it without editing the plugin itself. ([Fluent Support Developers]2)
- Step 1 — Create the MU plugin skeleton
- 1. Create this folder structure
Inside your WordPress site:
```text
wp-content/
mu-plugins/
ydb-fluentsupport-tools.php
ydb-fluentsupport-tools/
includes/
admin-page.php
helpers.php
config.php
```
Important: the file directly inside `mu-plugins` is:
```text
ydb-fluentsupport-tools.php
```
That is the file WordPress will auto-load.
- 2. Create the main MU plugin loader
Create this file:
```text
wp-content/mu-plugins/ydb-fluentsupport-tools.php
```
Put this inside:
```php
/**
* Plugin Name: YDB FluentSupport Tools
* Description: Custom site-specific tools for FluentSupport, including ticket concurrency handling.
* Author: YDB
* Version: 0.1.0
*
* This is a Must-Use plugin.
*
* Important MU plugin notes:
* - It is loaded automatically by WordPress.
* - It cannot be activated/deactivated from the normal Plugins screen.
* - WordPress only auto-loads PHP files directly inside wp-content/mu-plugins.
* - For that reason, this file acts as a loader for the real files inside the folder.
*/
if (!defined('ABSPATH')) {
exit;
}
/**
* Main plugin constants.
*
* We use constants so every module can safely refer to the same paths.
*/
define('YDB_FS_TOOLS_VERSION', '0.1.0');
define('YDB_FS_TOOLS_FILE', FILE);
define('YDB_FS_TOOLS_DIR', DIR . '/ydb-fluentsupport-tools');
define('YDB_FS_TOOLS_URL', content_url('mu-plugins/ydb-fluentsupport-tools'));
/**
* Safety check.
*
* If the plugin folder is missing, we stop quietly.
* This prevents fatal errors if files are uploaded in the wrong order.
*/
if (!is_dir(YDB_FS_TOOLS_DIR)) {
return;
}
/**
* Load configuration first.
*
* Feature flags will live here.
* This lets us enable/disable modules without deleting code.
*/
require_once YDB_FS_TOOLS_DIR . '/includes/config.php';
/**
* Load helper functions.
*
* Helpers should contain small reusable functions only.
* No heavy logic here.
*/
require_once YDB_FS_TOOLS_DIR . '/includes/helpers.php';
/**
* Load admin diagnostic page.
*
* This gives us a visible confirmation that the MU plugin is working.
*/
require_once YDB_FS_TOOLS_DIR . '/includes/admin-page.php';
```
- 3. Create the config file
Create this file:
```text
wp-content/mu-plugins/ydb-fluentsupport-tools/includes/config.php
```
Put this inside:
```php
/**
* YDB FluentSupport Tools - Configuration
*
* This file contains feature flags.
* We keep them here so we can safely turn features on/off during development.
*/
if (!defined('ABSPATH')) {
exit;
}
/**
* Enable admin diagnostic page.
*
* Keep this true while developing.
* Later we can disable it if you do not want this page visible.
*/
define('YDB_FS_TOOLS_ENABLE_ADMIN_PAGE', true);
/**
* Enable ticket concurrency module.
*
* Not used yet.
* We will enable this only after the skeleton is confirmed working.
*/
define('YDB_FS_TOOLS_ENABLE_CONCURRENCY', false);
/**
* Enable debug logging.
*
* When true, our plugin can write messages to the WordPress debug log.
* Only useful if WP_DEBUG_LOG is enabled in wp-config.php.
*/
define('YDB_FS_TOOLS_ENABLE_DEBUG_LOG', true);
```
- 4. Create the helpers file
Create this file:
```text
wp-content/mu-plugins/ydb-fluentsupport-tools/includes/helpers.php
```
Put this inside:
```php
/**
* YDB FluentSupport Tools - Helpers
*
* This file contains small reusable helper functions.
* No feature-specific logic should live here.
*/
if (!defined('ABSPATH')) {
exit;
}
/**
* Write a debug message to the WordPress debug log.
*
* This only writes if:
* - our debug flag is enabled
* - WP_DEBUG is enabled
*
* Usage:
* ydb_fs_tools_log('Something happened');
*/
function ydb_fs_tools_log($message, array $context = array()) {
if (!defined('YDB_FS_TOOLS_ENABLE_DEBUG_LOG') || !YDB_FS_TOOLS_ENABLE_DEBUG_LOG) {
return;
}
if (!defined('WP_DEBUG') || !WP_DEBUG) {
return;
}
if (!empty($context)) {
$message .= ' | Context: ' . wp_json_encode($context);
}
error_log('[YDB FluentSupport Tools] ' . $message);
}
/**
* Check whether FluentSupport appears to be active.
*
* We keep this deliberately simple for now.
* Later, if needed, we can replace this with a deeper FluentSupport-specific check.
*/
function ydb_fs_tools_is_fluentsupport_active() {
if (!function_exists('is_plugin_active')) {
require_once ABSPATH . 'wp-admin/includes/plugin.php';
}
return is_plugin_active('fluent-support/fluent-support.php');
}
/**
* Get a readable yes/no value for admin display.
*/
function ydb_fs_tools_yes_no($value) {
return $value ? 'Yes' : 'No';
}
```
- 5. Create the admin diagnostic page
Create this file:
```text
wp-content/mu-plugins/ydb-fluentsupport-tools/includes/admin-page.php
```
Put this inside:
```php
/**
* YDB FluentSupport Tools - Admin Diagnostic Page
*
* This page confirms that:
* - the MU plugin is loaded
* - our helper files are loaded
* - FluentSupport appears active
* - debug constants are visible
*/
if (!defined('ABSPATH')) {
exit;
}
if (!defined('YDB_FS_TOOLS_ENABLE_ADMIN_PAGE') || !YDB_FS_TOOLS_ENABLE_ADMIN_PAGE) {
return;
}
/**
* Add a simple admin page under Tools.
*
* We use manage_options so only administrators can see it.
*/
add_action('admin_menu', function () {
add_management_page(
'YDB FluentSupport Tools',
'YDB FluentSupport Tools',
'manage_options',
'ydb-fluentsupport-tools',
'ydb_fs_tools_render_admin_page'
);
});
/**
* Render the admin diagnostic page.
*/
function ydb_fs_tools_render_admin_page() {
if (!current_user_can('manage_options')) {
wp_die('You do not have permission to access this page.');
}
$fluent_active = ydb_fs_tools_is_fluentsupport_active();
?>
<div class="wrap">
<h1>YDB FluentSupport Tools</h1>
<p>
This page confirms that the custom MU plugin is loaded correctly.
</p>
<table class="widefat striped" style="max-width: 900px;">
<tbody>
<tr>
<th scope="row">Plugin version</th>
<td><?php echo esc_html(YDB_FS_TOOLS_VERSION); ?></td>
</tr>
<tr>
<th scope="row">Plugin directory</th>
<td><?php echo esc_html(YDB_FS_TOOLS_DIR); ?></td>
</tr>
<tr>
<th scope="row">FluentSupport active</th>
<td>
<?php echo esc_html(ydb_fs_tools_yes_no($fluent_active)); ?>
<?php if (!$fluent_active): ?>
<p style="color:#b32d2e;">
FluentSupport does not appear active using the standard plugin path check.
If FluentSupport is active but this says No, we will adjust the detection method later.
</p>
<?php endif; ?>
</td>
</tr>
<tr>
<th scope="row">Concurrency module enabled</th>
<td><?php echo esc_html(ydb_fs_tools_yes_no(YDB_FS_TOOLS_ENABLE_CONCURRENCY)); ?></td>
</tr>
<tr>
<th scope="row">Debug logging enabled in our plugin</th>
<td><?php echo esc_html(ydb_fs_tools_yes_no(YDB_FS_TOOLS_ENABLE_DEBUG_LOG)); ?></td>
</tr>
<tr>
<th scope="row">WP_DEBUG</th>
<td><?php echo esc_html(ydb_fs_tools_yes_no(defined('WP_DEBUG') && WP_DEBUG)); ?></td>
</tr>
<tr>
<th scope="row">WP_DEBUG_LOG</th>
<td><?php echo esc_html(ydb_fs_tools_yes_no(defined('WP_DEBUG_LOG') && WP_DEBUG_LOG)); ?></td>
</tr>
</tbody>
</table>
<h2>Next planned modules</h2>
<ol>
<li>Ticket view heartbeat: detect which agent is viewing a ticket.</li>
<li>Ticket reply lock: warn if another agent is already replying.</li>
<li>Optional assignment helper: assign ticket to current agent from the ticket screen.</li>
<li>Audit log: record who opened, replied, assigned, or changed a ticket.</li>
</ol>
</div>
<?php
}
```
- 6. Check that it loaded
Go to:
```text
WordPress Admin → Tools → YDB FluentSupport Tools
```
You should see a diagnostic table.
Also check:
```text
WordPress Admin → Plugins → Must-Use
```
You should see:
```text
YDB FluentSupport Tools
```
- 7. What this step gives us
At this point we have:
```text
A safe MU plugin
A clean file structure
Feature flags
A debug helper
A diagnostic admin page
A place to add concurrency code next
```
We have not touched FluentSupport behavior yet.
That is intentional.
For ticket concurrency, the next step will be to add a module like:
```text
wp-content/mu-plugins/ydb-fluentsupport-tools/includes/concurrency.php
```
But first confirm that the diagnostic page appears correctly.
[1]: https://developer.wordpress.org/advanced-administration/plugins/mu-plugins/ "Must Use Plugins – Advanced Administration Handbook | Developer.WordPress.org"
[2]: https://developers.fluentsupport.com/ "Fluent Support Developers"