Watchful LogoWatchful Logo
  • Features
  • Premium Pricing
  • GDPR
  • Login
  • Create a free account

Getting Started

7
  • Add your sites
    • Add a website to Watchful
    • Add a WordPress site to Watchful
    • Add a Joomla! site to Watchful
  • Set up your dashboard
    • How to edit site details in Watchful
    • Add site tags in Watchful
    • How to validate account emails
    • Customizing the Watchful interface

Backing Up Your Sites

1
  • Backup monitoring
    • Monitor stale backups

Securing Your Sites

1
  • Vulnerability Scanner
    • Vulnerability Scanner checks

Reports & Insights

2
  • Reports & activity logs
    • Activity Logs and data retention
  • SEO & audits
    • Monitoring website quality with Lighthouse

Site Management

1
  • Managing your sites
    • Deleting and restoring sites

Apps, Integrations & API

6
  • Developer guides
    • Creating custom apps for Joomla!
    • Creating custom apps
    • Creating custom apps for WordPress
  • Using Watchful Apps
    • Install and configure Watchful Apps
    • Legacy custom apps
  • API
    • Use the Watchful REST API

Account & Billing

14
  • Account settings
    • Beta-testing new Watchful features
    • Personalizing account preferences
    • Changing your username or password
    • How to validate account emails
  • Billing & payments
    • Adding funds to your account
    • View and download invoices
    • What is Watchful’s refund policy?
    • Update your billing information
    • How do I change my PayPal account?
  • Plans & subscriptions
    • Changing your Watchful plan
    • Cancel your subscription or delete your account
  • Account lifecycle
    • Understanding the account clean-up process
  • Account security
    • Authenticating with Social Sign-in
    • Enabling two-factor authentication
View Categories
  • Documentation
  • Apps, Integrations & API
  • Developer guides

Creating custom apps for Joomla!

Watchful allows Joomla! developers to extend its monitoring capabilities through custom app adapters.

These adapters collect application-specific information from your extensions and generate alerts that Watchful processes during site validation.

A Joomla! custom app uses an enabled plugin in the watchfulliApps group. The Watchful component discovers these plugins and invokes their appMainProgram method to collect monitoring information.

This guide explains the adapter structure, provides a legacy-style implementation example, and describes how Watchful handles stored values and alerts.

For a general introduction, see Creating custom apps.

Before you begin

You will need:

  • A Joomla! site connected to Watchful.
  • An installed and active Watchful component.
  • A Joomla! extension that you want to monitor.
  • Familiarity with PHP and Joomla! plugin development.

You can package the adapter alongside your existing Joomla! extension.

Joomla! version compatibility

The example in this article illustrates the legacy-style Watchful adapter contract.

The Watchful client uses triggerEvent on Joomla! 3 and the event dispatcher on later Joomla! versions.

Joomla! 4, 5, and 6 use newer plugin registration and event-dispatching mechanisms. Modern service providers or subscribers must register the required event and return the adapter result in the format expected by the dispatcher.

Consequently, the example is not a universal installation template for every Joomla! version. Verify event registration and compatibility with your target Joomla! release.

Step 1: Create the adapter plugin

Create a PHP file named:

acmemonitor.php

Add the following code:

<?php
defined('_JEXEC') || exit;

// The Watchful component defines this before importing its adapter plugins.
// Avoid loading its guarded base class in unrelated CMS requests.
$base = JPATH_ADMINISTRATOR . '/components/com_watchfulli/classes/apps.php';
if (!defined('WATCHFULLI_PATH') || !is_file($base)) {
    return;
}
require_once $base;

class PlgWatchfulliAppsAcmemonitor extends WatchfulliApps
{
    public function appMainProgram($oldValuesSerialized = null)
    {
        $name = 'acmeMonitor';
        $this->setName($name);
        $this->setDescription('Acme custom monitor');
        $this->alerts = [];
        $this->values = [];

        // Replace this configuration read with your own extension service.
        $status = (string) $this->params->get('status', 'healthy');
        $current = json_encode(['status' => $status]);
        if (!is_string($current)) {
            return $this;
        }

        // The legacy reader expects a serialized string, not null.
        $previous = null;
        if (is_string($oldValuesSerialized) && $oldValuesSerialized !== '') {
            $previous = $this->readExAppValue($oldValuesSerialized);
        }

        if ($previous === null) {
            $this->createAppValue($name, $current);
        } elseif ($previous !== $current) {
            $this->updateAppValue($name, $current);
            $this->createAppAlert(1, 'Acme monitor status changed to: ' . $status);
        }
        return $this;
    }
}

This adapter performs several functions:

  1. Checks that the Watchful component is available.
  2. Loads the required Watchful adapter class.
  3. Assigns a unique name and description to the integration.
  4. Retrieves the current monitor status.
  5. Compares it with the previously stored value.
  6. Creates an alert when the status changes.
  7. Returns the adapter result to Watchful.

The first successful collection establishes a baseline without generating an alert.

Replace the example status lookup with logic that retrieves information from your own Joomla! extension.

Step 2: Create the plugin manifest

Create a file named:

acmemonitor.xml

Add the following XML:

<?xml version="1.0" encoding="utf-8"?>
<extension type="plugin" group="watchfulliApps" method="upgrade" version="3.0">
    <name>Acme Watchful monitor adapter</name>
    <version>1.0.0</version>
    <description>Custom notifications supplied by Acme.</description>
    <files>
        <filename plugin="acmemonitor">acmemonitor.php</filename>
    </files>
    <config>
        <fields name="params">
            <fieldset name="basic">
                <field name="status" type="text" default="healthy"
                       label="Monitor status"/>
            </fieldset>
        </fields>
    </config>
</extension>

The important setting is:

group="watchfulliApps"

The Watchful component imports enabled plugins in this group.

Adding a class to a component model or registering an ordinary system plugin does not make the adapter discoverable.

Step 3: Install and enable the adapter

To test the legacy-style example on a compatible Joomla! installation:

  1. Place acmemonitor.php and acmemonitor.xml at the root of a ZIP archive.
  2. Install the package using Joomla!’s extension installer.
  3. Enable the new adapter plugin.
  4. Refresh data for the site in Watchful to establish the initial baseline.
  5. Change the adapter’s Monitor status setting.
  6. Refresh data for the site in Watchful again.
  7. Check for the resulting custom-plugin event.

For a production integration, retrieve monitoring information from your extension’s existing services rather than using a manually configured status field.

Handle missing dependencies gracefully and avoid fatal errors that could interrupt site validation.

Do not define WATCHFULLI_PATH yourself or attempt to load the entire Watchful component during unrelated Joomla! requests.

Understanding adapter values

Joomla! adapters can use previously stored values to detect changes in application state.

The inherited WatchfulliApps class provides several methods for managing these values.

MethodPurpose
setName()Assigns a unique identity to the integration.
setDescription()Provides a description of the custom app.
readExAppValue()Retrieves the integration’s previously stored value.
createAppValue()Creates a value for a new integration baseline.
updateAppValue()Updates an existing integration value.
createAppAlert()Adds an informational or error alert.

Using a consistent integration name

Always call setName() before readExAppValue().

The previous value is located using the integration name, so this identity must remain consistent.

Use the same name with:

  • setName()
  • createAppValue()
  • updateAppValue()

Although the underlying class supports multiple values, the Watchful backend currently persists only the value associated with the integration’s name.

Storing multiple measurements

If your integration monitors several measurements, combine them into a single deterministic JSON string.

For example:

{
    "status": "healthy",
    "count": 0,
    "service": "available"
}

Sort collections before encoding them to avoid generating alerts simply because the order of values has changed.

The underlying value implementation rejects empty names and certain false-like values, including 0, false, and empty strings.

The update method also rejects values loosely equal to null.

A nonempty JSON object avoids these limitations.

Generating alerts

Use the inherited createAppAlert() method to add alerts:

$this->createAppAlert(
    1,
    'Acme monitor status changed to: degraded'
);

The method accepts a severity level, a message, and up to three optional parameters.

Use:

  • 1 for informational events.
  • 2 for errors.

For example:

$this->createAppAlert(
    2,
    'Acme service connection failed.'
);

The method creates an AppAlert object and appends it to the adapter result.

Do not copy the class-named constructor patterns found in retired example apps. Use the inherited methods provided by the current adapter class.

Always return $this from appMainProgram(), including when no alert is generated.

Understanding stored values and baseline resets

During validation, Watchful provides previously stored custom-app values through jmpluginsexvalues.

The adapter can use these values to compare the current application state against an earlier validation.

After processing a successful validation response, the Watchful backend replaces the site’s previously stored custom-app values with those returned by the client.

Consequently, the baseline may be reset when:

  • An adapter is disabled or no longer returns its value.
  • An integration is renamed.
  • A previously stored value is omitted from the validation response.

Keep your integration identity stable and return the current value on every successful collection, including when the state has not changed.

The legacy value reader also replaces the sequence 0000000000 with spaces. Avoid storing this sequence in serialized state values.

Do not use readExAppValue() to process arbitrary untrusted serialized input.

Reporting events between validations

Joomla! adapter values are intended for comparing snapshots of application state. They are not a durable event queue.

An event that occurs and disappears between Watchful validations may not be detected through a simple state comparison.

For example, your extension might encounter a temporary API error and recover before Watchful next validates the site.

If the event must be reported, retain an event record in your own extension and expose it during collection.

Your extension should define how events are retained, identified, and replayed because the alert contract does not provide delivery acknowledgements.

Configuring notifications

Watchful processes custom-app alerts through its existing notification system.

Generating an alert does not automatically guarantee that an email or other notification will be delivered.

Review your Watchful notification preferences and enable the relevant notifications for your monitoring requirements.

For more information about the notification workflow, see Creating custom apps.

Joomla! development requirements

When building production adapters:

  1. Register the adapter in the watchfulliApps plugin group.
  2. Verify event-dispatcher compatibility with your target Joomla! version.
  3. Assign a unique and consistent integration name.
  4. Return $this from appMainProgram() even when no alert is generated.
  5. Return the current integration value on every successful collection.
  6. Store multiple measurements in a consistent, nonempty JSON representation when necessary.
  7. Use createAppAlert() for informational and error events.
  8. Handle missing dependencies without interrupting Joomla! or Watchful.
  9. Retain short-lived events locally if they must survive between validations.
  10. Test initial, changed, and unchanged states.

Summary

Joomla! custom apps extend Watchful monitoring through discoverable plugins in the watchfulliApps group.

These adapters collect application-specific information, compare stored values, and generate alerts that Watchful processes during site validation.

For an overview of the custom-app system, see Creating custom apps.

apps developers Joomla!
Creating custom apps for WordPressCreating custom apps

About Watchful

Since 2012 Watchful has been helping digital agencies grow and be successful by providing professional solutions for safely managing websites. Watchful currently supports WordPress and Joomla.

More about Watchful »
  • Features
  • Blog
  • Success Stories
  • Podcast
  • Knowledge base
  • News & Events
  • Brand Assets
  • Status
  • RESTful API
  • Free account
  • How-to
  • Testimonials
  • About Us
  • Contact

  • Privacy Policy
  • Terms of Service
Copyright © 2026 Watchful LLC