定制 onstage2426/wp-plugin-updater 二次开发

按需修改功能、优化性能、对接业务系统,提供一站式技术支持

邮箱:yvsm@zunyunkeji.com | QQ:316430983 | 微信:yvsm316

onstage2426/wp-plugin-updater

最新稳定版本:v0.1.8

Composer 安装命令:

composer require onstage2426/wp-plugin-updater

包简介

README 文档

README

Source: github.com/onstage2426/wp-updater

Delivers WordPress plugin and theme updates from a private GitHub repository. Hooks into the standard WordPress update system so your plugin or theme appears in the Updates screen and can be installed with a single click.

Requirements

  • PHP 8.3+
  • WordPress 6.6+
  • Plugin or theme hosted on GitHub (public or private)

Installation

composer require onstage2426/wp-updater

Quick start

Plugin:

use Onstage2426\WpUpdater\Plugin\PluginUpdater;

$updater = PluginUpdater::build(
    'https://github.com/your-org/your-repo',
    __FILE__
);

Theme:

use Onstage2426\WpUpdater\Theme\ThemeUpdater;

$updater = ThemeUpdater::build(
    'https://github.com/your-org/your-theme',
    'your-theme'   // theme directory name / slug
);

Call this at plugin/theme load time — at the top level of your main file, or in a very early action. The updater registers all its WP hooks internally.

PluginUpdater::build() — factory method

PluginUpdater::build(
    string $repositoryUrl,
    string $pluginFile,
    string $slug        = "",
    int    $checkPeriod = 12,
    string $optionName  = "",
): static
Parameter Type Default Description
$repositoryUrl string Full GitHub URL, e.g. https://github.com/owner/repo
$pluginFile string Absolute path to the plugin's main PHP file. Pass __FILE__ from your plugin's main file
$slug string "" Unique identifier. Defaults to the filename without .php. Must be unique across all active updater instances
$checkPeriod int 12 How often to check for updates, in hours. Set to 0 to disable automatic checks entirely
$optionName string "" WP site option name used to persist check state. Defaults to external_updates-{slug}

ThemeUpdater::build() — factory method

ThemeUpdater::build(
    string $repositoryUrl,
    string $themeSlug,
    int    $checkPeriod = 12,
    string $optionName  = "",
): static
Parameter Type Default Description
$repositoryUrl string Full GitHub URL
$themeSlug string Theme directory name, e.g. my-theme. This is also used as the update checker slug
$checkPeriod int 12 How often to check for updates, in hours
$optionName string "" WP site option name used to persist check state

Public properties

Shared (both PluginUpdater and ThemeUpdater):

Property Type Description
$updater->slug string Unique slug for this updater instance
$updater->updateState UpdateState Persisted check state. See UpdateState

Plugin-only (PluginUpdater):

Property Type Description
$updater->pluginFile string Plugin basename as returned by plugin_basename(), e.g. my-plugin/my-plugin.php
$updater->directoryName string Plugin directory name, e.g. my-plugin
$updater->muPluginFile string MU-plugin filename; empty string for regular plugins

Theme-only (ThemeUpdater):

Property Type Description
$updater->directoryName string Theme directory name (same as slug)

Configuration methods

All methods are defined on the shared base class and return static for chaining. They apply to both PluginUpdater and ThemeUpdater unless noted otherwise.

setMuPluginFile(string $muPluginFile): static (plugin only)

Only needed for MU-plugins. Sets the relative filename of the MU-plugin as it appears in wp-content/mu-plugins/. See MU-plugins.

$updater->setMuPluginFile('my-mu-plugin.php');

setBranch(string $branch): static

Sets which branch to use as the update source. Default is "master".

When the branch is "master" or "main", the updater tries strategies in order:

  1. Latest GitHub release
  2. Latest version tag
  3. Branch HEAD

For any other branch name, only the branch HEAD is used. The branch strategy carries no version number (null), so the update checker cannot determine a newer version from the branch alone. Use releases or tags on master/main for version-based updates.

$updater->setBranch('main');

setAccessToken(string $token): static

Sets the GitHub personal access token used to authenticate API requests and ZIP downloads. Required for private repositories.

$updater->setAccessToken('ghp_xxxx');

The token is injected as an Authorization: token … header on every GitHub API call and on the ZIP download request WordPress makes during upgrade. It is held in memory only — never written to any WordPress option or transient.

Public repositories work without a token and are unaffected when this method is not called.

To generate a token: GitHub → Settings → Developer settings → Personal access tokens. For a private repository the token needs at minimum the repo scope (classic token) or Contents: Read permission (fine-grained token).

setReleaseFilter(callable $callback, int $releaseTypes, int $maxReleases): static

Applies a custom filter when picking the latest release. The updater fetches up to $maxReleases releases and calls $callback for each one to decide whether to use it.

setReleaseFilter(
    callable $callback,
    int      $releaseTypes = PluginUpdater::RELEASE_FILTER_SKIP_PRERELEASE,
    int      $maxReleases  = 20,
): static
Parameter Type Default Description
$callback callable Called as fn(string $version, object $release): bool. Return true to accept the release, false to skip it. $release is the raw GitHub API release object
$releaseTypes int RELEASE_FILTER_SKIP_PRERELEASE ::RELEASE_FILTER_ALL to include pre-releases, ::RELEASE_FILTER_SKIP_PRERELEASE to exclude them
$maxReleases int 20 How many recent releases to fetch and examine. Min 1, max 100
// Accept only releases whose version contains "-stable"
$updater->setReleaseFilter(
    fn(string $version) => str_contains($version, '-stable'),
    PluginUpdater::RELEASE_FILTER_ALL,
    50
);

Constants (available on both PluginUpdater and ThemeUpdater):

Constant Value Description
::RELEASE_FILTER_ALL 3 Examine both stable releases and pre-releases
::RELEASE_FILTER_SKIP_PRERELEASE 1 Skip releases marked as pre-release on GitHub

setReleaseVersionFilter(string $regex, int $releaseTypes, int $maxReleasesToExamine): static

Convenience wrapper around setReleaseFilter() for filtering by version number using a regular expression.

// Only pick up releases whose version starts with "2."
$updater->setReleaseVersionFilter('/^2\./');

// Include pre-releases, look back up to 30 releases
$updater->setReleaseVersionFilter('/^2\./', PluginUpdater::RELEASE_FILTER_ALL, 30);

setAssetFilter(string $pattern): static

When a release has multiple assets, selects the first asset whose name contains $pattern as a substring. Falls back to the first asset when no match is found. Without this call the first asset is always used.

// Pick the production ZIP, not the debug build
$updater->setAssetFilter('my-plugin-');

throttleRedundantChecks(bool $enable, int $hours): static

When enabled, the updater skips scheduled checks if an update is already sitting in the queue waiting to be installed. This avoids hammering the GitHub API when nothing has changed.

$updater->throttleRedundantChecks();             // enable with default 72 hours
$updater->throttleRedundantChecks(hours: 48);    // enable with custom period
$updater->throttleRedundantChecks(false);        // disable

setCooldown(int $hours = 24): static

Sets how many hours must pass after a release is published before the update is surfaced to WordPress. Defaults to 24. Set to 0 to disable.

This creates a window to catch and yank a bad release before it reaches any site — useful protection against supply-chain compromises, broken builds, or accidental publishes.

$updater->setCooldown();        // 24-hour cooldown (default)
$updater->setCooldown(48);      // 48-hour cooldown
$updater->setCooldown(0);       // disabled — surface updates immediately

The cooldown is based on the release's created_at timestamp from GitHub. It has no effect on branch-based update sources (those carry no release timestamp).

enableAutoUpdates(bool $enable): static

Opts this plugin or theme into WordPress automatic background updates by writing to the same site option the admin UI toggle uses (auto_update_plugins / auto_update_themes). The toggle on the Plugins or Themes screen immediately reflects the change.

$updater->enableAutoUpdates();        // enable
$updater->enableAutoUpdates(false);   // disable

The admin can still override this at any time using the toggle in the WordPress UI — calling this method does not lock the preference or fight the admin's choice.

enableDebugMode(bool $enable): static

Controls whether errors and warnings are sent to the PHP error log. Defaults to the value of the WP_DEBUG constant.

$updater->enableDebugMode();        // enable
$updater->enableDebugMode(false);   // disable

setMaxRetries(int $maxRetries, int $initialDelayMs): static

Controls how many times a failed GitHub API request is retried before giving up.

setMaxRetries(
    int $maxRetries    = 2,
    int $initialDelayMs = 500,
): static
Parameter Type Default Description
$maxRetries int 2 Maximum number of extra attempts after the first request fails
$initialDelayMs int 500 Delay before the first retry, in milliseconds. Doubles with each subsequent retry (exponential backoff), capped at 5 seconds

Retries apply only to transient failures: network errors (WP_Error) and server-side errors (500, 502, 503, 504). Rate-limit responses, auth failures, and 404s are not retried.

During interactive page loads (not WP-Cron), retries are automatically capped at 1 regardless of $maxRetries, to avoid stalling the page response.

$updater->setMaxRetries(3, 250);   // up to 3 retries, starting at 250 ms
$updater->setMaxRetries(0);        // disable retries entirely

removeHooks(): void

Removes all WordPress hooks registered by this updater instance. Called automatically on plugin uninstall. Call manually if you need to tear down the updater at runtime.

$updater->removeHooks();

Reading state

checkForUpdates(): ?Update

Forces an immediate update check against the GitHub API, regardless of the normal schedule. Updates updateState with the result. Returns an Update object if a newer version is available, null otherwise.

$update = $updater->checkForUpdates();
if ($update) {
    error_log("New version available: " . $update->version);
}

getUpdate(): ?Update

Reads the last known update from updateState without making any API calls. Returns an Update object only if the stored version is newer than what is currently installed. Returns null if up to date or if no check has been run yet.

$update = $updater->getUpdate();

getLastRequestApiErrors(): array

Returns API errors collected during the most recent checkForUpdates() call. Each entry is an associative array with keys error (WP_Error), httpResponse (raw WP HTTP response or null), and url (string|null).

$updater->checkForUpdates();

foreach ($updater->getLastRequestApiErrors() as $item) {
    $wpError = $item['error'];
    error_log($wpError->get_error_message() . ' [' . $item['url'] . ']');
}

getStatus(): array

Returns a flat associative array of the current update state, suitable for display. Does not make any API calls.

$status = $updater->getStatus();
// [
//   'slug'              => 'my-plugin',
//   'type'              => 'plugin',
//   'installed_version' => '1.3.0',
//   'last_check'        => '2026-06-09 10:34:21 UTC',
//   'available_version' => '1.4.2',
//   'update_available'  => 'yes',
//   'cooldown_active'   => 'no',
// ]

available_version reflects the raw stored version (ignoring cooldown). update_available is 'yes' only when the update would actually be surfaced to WordPress (cooldown has passed). cooldown_active is 'yes' when an update exists in state but is currently suppressed by the cooldown window.

getEntityTitle(): string

Returns the entity's human-readable display name — from the plugin file header for plugins, from wp_get_theme() for themes. Returns an empty string if the header cannot be read.

echo $updater->getEntityTitle();  // e.g. "My Plugin" or "My Theme"

getUniqueName(string $baseTag): string

Generates a scoped hook name: pu_{baseTag}-{slug}. Used to namespace all filters and actions to this specific instance.

$filterName = $updater->getUniqueName('request_info_result');
// returns e.g. "pu_request_info_result-my-plugin"

triggerError(string $message, int $errorType): void

Fires trigger_error() if debug mode is active. Use E_USER_WARNING or E_USER_ERROR as $errorType.

$updater->triggerError('Something went wrong.', E_USER_WARNING);

WordPress filters

All filter tags are scoped with $updater->getUniqueName('tag')pu_{tag}-{slug}.

pu_request_info_result-{slug}

Fired after the GitHub API is called to build the info shown in the "View details" popup. Receives the populated info object (PluginInfo or ThemeInfo, or null on failure). Return a modified info object or null to suppress the popup.

use Onstage2426\WpUpdater\Plugin\PluginInfo;

add_filter($updater->getUniqueName('request_info_result'), function (?PluginInfo $info): ?PluginInfo {
    if ($info) {
        $info->sections['changelog'] = '<p>See GitHub releases for changelog.</p>';
    }
    return $info;
});

pu_request_update_result-{slug}

Fired after the GitHub API is called during a scheduled or manual check, before the result is written to state. Receives the Update object (or null). Return a modified Update or null to suppress the update.

add_filter($updater->getUniqueName('request_update_result'), function (?Update $update): ?Update {
    return $update;
});

pu_pre_inject_info-{slug}

Fired just before entity info is returned to WordPress for the popup. Last chance to modify or suppress the info.

pu_pre_inject_update-{slug}

Fired just before an update is written into the update transient. Last chance to modify the Update object before WordPress sees it.

add_filter($updater->getUniqueName('pre_inject_update'), function (Update $update): Update {
    // e.g. override the download URL
    $update->download_url = 'https://example.com/my-plugin.zip';
    return $update;
});

pu_check_now-{slug}

Controls whether the scheduler should run a check right now. Receives bool $shouldCheck, the timestamp of the last check as int, and the configured check period in hours as int.

add_filter($updater->getUniqueName('check_now'), function (bool $should, int $lastCheck, int $period): bool {
    return (time() - $lastCheck) > DAY_IN_SECONDS;
}, 10, 3);

pu_first_check_time-{slug}

Controls the timestamp of the first scheduled cron event. Defaults to a random offset within the first checkPeriod window to spread load across installations.

add_filter($updater->getUniqueName('first_check_time'), function (int $timestamp): int {
    return time();  // check immediately on the next cron run
});

pu_vcs_update_detection_strategies-{slug}

Lets you reorder, replace, or extend the array of detection strategies passed to GitHubClient::chooseReference().

use Onstage2426\WpUpdater\GitHubClient;

add_filter($updater->getUniqueName('vcs_update_detection_strategies'), function (array $strategies): array {
    // Remove the tag strategy, only use releases
    unset($strategies[GitHubClient::STRATEGY_LATEST_TAG]);
    return $strategies;
});

Available strategy keys: GitHubClient::STRATEGY_LATEST_RELEASE, GitHubClient::STRATEGY_LATEST_TAG, GitHubClient::STRATEGY_BRANCH.

pu_remove_from_default_update_checks-{slug}

By default this entity is excluded from the WP.org update payload (it has no WP.org entry). Return false to include it in the payload anyway.

add_filter($updater->getUniqueName('remove_from_default_update_checks'), '__return_false');

Tip (plugins only): If your plugin header includes Update URI: https://github.com/your-org/your-repo, WordPress 5.8+ natively excludes it from the WP.org check and the library skips registering the exclusion filter entirely. No additional code is required — just adding the header is enough.

pu_retain_fields-{slug}

Controls which fields are copied from the info object into an Update during checkForUpdates(). This filter fires only during update detection — not when stored state is reloaded on the next page.

add_filter('pu_retain_fields-my-plugin', function (array $fields): array {
    $fields[] = 'my_custom_field';
    return $fields;
});

The custom field must also exist as a public property on Update or it will be silently skipped.

pu_api_error (action)

Fired whenever the GitHub API returns an error (network failure, rate limit, or non-200 response). Receives WP_Error $error, the raw HTTP response, the request URL, and the entity slug.

Notable error codes:

Code Meaning
pu-github-http-error Non-200 response that is not a rate limit
pu-github-rate-limited 429 or 403 with x-ratelimit-remaining: 0. The WP_Error data array includes reset_time (Unix timestamp or null). Follow-on requests are automatically blocked until the reset time
pu-no-update-source All detection strategies returned null
pu-no-plugin-version Source found but carried no version number
add_action('pu_api_error', function (WP_Error $error, mixed $response, ?string $url, ?string $slug): void {
    if ($slug === 'my-plugin') {
        error_log('[my-plugin updater] ' . $error->get_error_message());
    }
}, 10, 4);

Data classes

Update

The minimal record written to the update transient.

Property Type Source
$slug ?string Entity slug
$version ?string Version string from the GitHub release/tag, e.g. "1.4.2"
$download_url ?string ZIP download URL
$homepage ?string URI from the plugin/theme header
$icons array Icon URLs loaded from the local assets/ directory (plugins only)
$filename ?string Plugin basename, set at injection time (plugins only)
$last_updated ?string Release created_at timestamp from GitHub; null for branch-based sources

PluginInfo

The full metadata object shown in the "View details" popup for plugins.

Property Type Source
$name ?string Plugin Name header
$slug ?string Plugin slug
$version ?string Version from GitHub release/tag
$homepage ?string Plugin URI header
$sections array Keyed sections shown in the popup. description from plugin header; changelog from GitHub release body or local changelog file
$download_url ?string ZIP download URL
$banners mixed Banner images loaded from the local assets/ directory
$icons array Icon images loaded from the local assets/ directory
$author ?string Author header
$author_homepage ?string Author URI header
$downloaded ?int Download count from the selected GitHub release asset
$last_updated ?string Release creation timestamp (created_at from GitHub)
$filename ?string Plugin basename

ThemeInfo

The full metadata object shown in the theme info popup.

Property Type Source
$name ?string Theme Name header
$slug ?string Theme slug
$version ?string Version from GitHub release/tag
$homepage ?string Theme URI header
$sections array Keyed sections shown in the popup. description from theme header; changelog from GitHub release body or local changelog file
$download_url ?string ZIP download URL
$screenshot_url ?string Screenshot URL from wp_get_theme()->get_screenshot()
$author ?string Author header
$author_homepage ?string Author URI header
$downloaded ?int Download count from the selected GitHub release asset
$last_updated ?string Release creation timestamp (created_at from GitHub)

UpdateState

Persists the update check state to a WP site option. Accessible as $updater->updateState.

Method Returns Description
getUpdate() ?Update The last stored update record, or null
getLastCheck() int Unix timestamp of the last check, or 0 if never checked
timeSinceLastCheck() int Seconds since the last check
reset() void Zeroes all state fields (last-check timestamp, checked version, stored update) and persists the result

Reliability features

The following behaviours are active out of the box with no configuration required.

Concurrent check lock — if two requests (e.g. a cron job and an admin page load) try to run checkForUpdates() at the same time, one of them acquires a short-lived lock and performs the API call while the other immediately returns the last-known stored update. The lock expires automatically after 60 seconds, so a crashed process can never block future checks indefinitely.

Transient-failure retries — failed API requests (network errors, 500/502/503/504) are automatically retried with exponential backoff. See setMaxRetries() to change the defaults.

Automatic rollback on upgrade failure — before each upgrade starts, the updater captures the download URL of the currently-installed version and passes it to the WordPress upgrader as rollback data. If the upgrade fails partway through, WordPress uses that URL to restore the previous version automatically.

ETag cache integrity — the ETag cache (used to avoid redownloading unchanged API responses) is validated every time it is loaded from the database and again before each request. Corrupt or partially-written entries are discarded automatically.

Local assets (plugins only)

Place assets in an assets/ subdirectory inside your plugin directory. The updater loads them automatically for the update popup.

Icons (shown on the Plugins screen and in the popup):

Filename Size slot
assets/icon.svg SVG (preferred)
assets/icon-256x256.png or .jpg
assets/icon-128x128.png or .jpg

Banners (shown at the top of the "View details" popup):

Filename Size slot
assets/banner-772x250.png or .jpg Standard
assets/banner-1544x500.png or .jpg High-DPI

Themes use the screenshot file already present in the theme directory — no assets/ directory is needed.

Distribution — Composer, assets, and built files

The updater downloads whichever ZIP GitHub provides for a release. How you handle dependencies and build artifacts depends on your workflow.

Option A — Commit built files (simple): run composer install --no-dev and commit the vendor/ directory, commit compiled CSS/JS, and never commit node_modules/. The source ZIP GitHub generates will include everything.

Option B — GitHub Actions release pipeline (recommended): keep vendor/, node_modules/, and build output out of git. On each tag push, a workflow installs dependencies, runs the build, stamps the version header, creates a clean ZIP, and uploads it as a release asset. The updater automatically prefers the first release asset over GitHub's source ZIP when one is present.

Why the workflow must create the release as a draft first

When a GitHub release is published, the release asset (your ZIP) is uploaded by the workflow job after the release becomes publicly visible. During that gap — typically around two minutes — the updater falls back to GitHub's auto-generated source ZIP, which does not contain vendor/ or any built output. Any site that updates during this window will get a broken install.

The fix is to publish the release as a draft, upload the asset, then remove the draft flag in a final step. GitHub's /releases/latest endpoint only returns non-draft releases, so the updater cannot see the release until the asset is fully attached.

Version stamping

The tag name is used as the authoritative version. The workflow stamps the Version: header in your main PHP file from the tag before zipping, so the installed plugin's header always matches the GitHub release version.

Complete workflow (.github/workflows/release.yml)

Push a tag (git tag v1.2.0 && git push --tags) to trigger it.

on:
  push:
    tags: ["v*"]

jobs:
  release:
    runs-on: ubuntu-latest
    permissions:
      contents: write
    steps:
      - uses: actions/checkout@v6

      - name: Stamp version from tag
        run: |
          sed -i "s/^ \* Version:.*/ * Version: ${GITHUB_REF_NAME#v}/" your-plugin.php

      - uses: shivammathur/setup-php@v2
        with:
          php-version: "8.3"

      - run: composer install --no-dev --optimize-autoloader

      # Remove the next two steps if you have no JS build
      - uses: actions/setup-node@v4
        with:
          node-version: "20"
      - run: npm ci && npm run build

      - name: Create plugin ZIP
        run: |
          zip -r your-plugin.zip . \
            --exclude=".git/*" --exclude=".github/*" \
            --exclude="node_modules/*" --exclude="*.config.js" \
            --exclude="package*.json"

      - name: Create draft release with asset
        run: |
          gh release create "$GITHUB_REF_NAME" your-plugin.zip \
            --draft \
            --generate-notes \
            --title "$GITHUB_REF_NAME"
        env:
          GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}

      - name: Publish release
        run: gh release edit "$GITHUB_REF_NAME" --draft=false
        env:
          GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}

Replace your-plugin.php and your-plugin.zip with your actual filenames.

If your plugin or theme is PHP-only with no Composer dependencies and no JS build, the source ZIP is fine and no workflow is required.

Changelog

If the GitHub release has a body, it is used as the changelog in the popup. If not, the updater looks for a changelog file in the plugin/theme directory:

  • CHANGELOG.md
  • CHANGES.md
  • changelog.md
  • changes.md

If Parsedown is installed, Markdown is rendered to HTML. Otherwise the raw text is shown.

MU-plugins

MU-plugins that live directly in wp-content/mu-plugins/ (not in a subdirectory) must call setMuPluginFile() so WordPress can match the plugin correctly:

$updater = PluginUpdater::build(
    'https://github.com/your-org/your-repo',
    __FILE__,
)->setMuPluginFile('my-mu-plugin.php');

MU-plugins installed in a subdirectory (e.g. mu-plugins/my-plugin/my-plugin.php) are detected automatically — no call needed.

Debugging

$updater->enableDebugMode();

This sends warnings to error_log() when the plugin/theme file cannot be read, the version header is missing, or the API returns no usable version.

You can also inspect errors from the last check directly:

$update = $updater->checkForUpdates();

foreach ($updater->getLastRequestApiErrors() as $item) {
    error_log($item['error']->get_error_message() . '' . $item['url']);
}

WP-CLI

When WP-CLI is active, the updater automatically registers a command group for each configured updater instance. No extra setup is required — calling build() is sufficient.

Command namespace: wp pu <slug>

wp pu <slug> check

Triggers an immediate update check against the GitHub API and prints the result. API warnings (rate limits, network errors) are printed before the final status line.

$ wp pu my-plugin check
Checking for updates...
Success: Update available: 1.4.2

wp pu <slug> status

Displays the current update state without making any API calls — equivalent to reading getStatus() from PHP.

$ wp pu my-plugin status
slug:                  my-plugin
type:                  plugin
installed version:     1.3.0
last check:            2026-06-09 10:34:21 UTC
available version:     1.4.2
update available:      yes
cooldown active:       no

wp pu <slug> clear

Resets the stored state — clears the last-check timestamp and any stored update record. Useful when testing, or after a manual install that bypassed the update system.

$ wp pu my-plugin clear
Success: Update state cleared.

wp pu <slug> enable-auto-updates / disable-auto-updates

Opts the entity in or out of WordPress automatic background updates. Equivalent to the toggle in the Plugins or Themes screen.

$ wp pu my-plugin enable-auto-updates
Success: Automatic updates enabled.

$ wp pu my-plugin disable-auto-updates
Success: Automatic updates disabled.

To actually install a pending update, use the standard WP-CLI command after check confirms one is available:

$ wp plugin update my-plugin   # or: wp theme update my-theme

Full example

use Onstage2426\WpUpdater\Plugin\PluginUpdater;
use Onstage2426\WpUpdater\Plugin\PluginInfo;

$updater = PluginUpdater::build(
    'https://github.com/acme/my-plugin',
    __FILE__,
    'my-plugin',
    24   // check every 24 hours
);

// Only ship stable 2.x releases
$updater
    ->setReleaseVersionFilter('/^2\./')
    ->throttleRedundantChecks(hours: 72)
    ->enableDebugMode();

// Append a note to the changelog in the popup
add_filter($updater->getUniqueName('request_info_result'), function (?PluginInfo $info): ?PluginInfo {
    if ($info && !empty($info->sections['changelog'])) {
        $info->sections['changelog'] .= '<p><a href="https://github.com/acme/my-plugin/releases">Full release history on GitHub</a></p>';
    }
    return $info;
});

统计信息

  • 总下载量: 28
  • 月度下载量: 0
  • 日度下载量: 0
  • 收藏数: 0
  • 点击次数: 1
  • 依赖项目数: 0
  • 推荐数: 0

GitHub 信息

  • Stars: 0
  • Watchers: 0
  • Forks: 0
  • 开发语言: PHP

其他信息

  • 授权协议: MIT
  • 更新时间: 2026-06-06

承接程序开发

PHP开发

VUE

Vue开发

前端开发

小程序开发

公众号开发

系统定制

数据库设计

云部署

网站建设

安全加固