Download the PHP package devuri/wp-adapter without Composer

On this page you can find all versions of the php package devuri/wp-adapter. It is possible to download/install these versions without Composer. Possible dependencies are resolved automatically.

FAQ

After the download, you have to make one include require_once('vendor/autoload.php');. After that you have to import the classes with use statements.

Example:
If you use only one package a project is not needed. But if you use more then one package, without a project it is not possible to import the classes with use statements.

In general, it is recommended to use always a project to download your libraries. In an application normally there is more than one library needed.
Some PHP packages are not free to download and because of that hosted in private repositories. In this case some credentials are needed to access such packages. Please use the auth.json textarea to insert credentials, if a package is coming from a private repository. You can look here for more information.

  • Some hosting areas are not accessible by a terminal or SSH. Then it is not possible to use Composer.
  • To use Composer is sometimes complicated. Especially for beginners.
  • Composer needs much resources. Sometimes they are not available on a simple webspace.
  • If you are using private repositories you don't need to share your credentials. You can set up everything on our site and then you provide a simple download link to your team member.
  • Simplify your Composer build process. Use our own command line tool to download the vendor folder as binary. This makes your build process faster and you don't need to expose your credentials for private repositories.
Please rate this library. Is it a good library?

Informations about the package wp-adapter

WP Adapter

WordPress contracts, production adapters, and ready-made testing adapters for clean, testable plugin development.

Advanced usage

Quick start

This is the shortest path from installation to a service that runs with WordPress in production and without WordPress in unit tests.

1. Install for development

Composer makes the contracts, production adapters, testing adapters, and psr/log available during development.

2. Write plugin logic against a contract

myplugin_settings is the WordPress option name. The array is simply the value this service chooses to store. update() accepts any value supported by WordPress options. See Option storage contract for the full behavior.

3. Use the WordPress adapter in production

Create concrete adapters in the plugin bootstrap, then pass them into services:

Pass $settings to the plugin class or controller that needs it. The service never calls get_option() or update_option() directly.

4. Use the testing adapter in a unit test

The same service runs without loading WordPress. The package supplies the testing adapter, so the test does not need a custom mock.

5. Build a distributable plugin

Run this from the plugin root:

Load the copied bundle from the plugin's main file:

Ship lib/wp-adapter/ in the plugin ZIP and remove vendor/. See Direct-load distribution for build safety and conflict handling.

How it works

WP Adapter creates one boundary between plugin business logic and common WordPress APIs.

Layer Main namespaces Purpose
Contracts AdapterKit\Core\Contracts\ Interfaces used by plugin business logic
WordPress adapters Storage, Http, Hooks, and Environment under AdapterKit\Core\ Production implementations that call WordPress
Testing adapters AdapterKit\Core\Testing\, plus Time\FrozenClock Controlled implementations used in unit tests

A service depends only on a contract. The plugin bootstrap chooses the production implementation, while the unit test chooses the testing implementation. All three layers are maintained as versioned package API.

The production adapters are intentionally thin wrappers around WordPress. The testing adapters provide controlled state, configured responses, and recorded calls for service-level tests. They are not intended to reproduce every WordPress runtime edge case. Use integration tests when exact WordPress behavior is what the test needs to prove.

What this solves

WordPress plugins often call get_option(), add_action(), and wp_remote_post() directly inside business logic. That couples the logic to a running WordPress installation and makes isolated tests difficult.

WP Adapter keeps WordPress at the edge. Services receive small interfaces through their constructors and remain plain PHP. In production they receive WordPress adapters. In unit tests they receive the supplied testing adapters. No custom mocks and no WordPress bootstrap are needed for those service tests.

The boundary rule

WordPress function calls belong only in the production adapter classes and the plugin bootstrap edge.

Business logic must call contracts instead of calling WordPress directly:

The package cannot isolate a service that still calls get_option(), wp_remote_post(), add_action(), or another WordPress function internally.

PluginContext::fromPluginFile() is the documented bootstrap-edge exception. It calls WordPress path helpers to construct immutable plugin metadata. Use PluginContext::fromValues() when WordPress is not loaded.

A useful boundary check is simple: instantiate the service from a plain PHP process that loads only Composer. If that triggers a missing WordPress function, WordPress has leaked past the edge.

See docs/testing-guide.md for a complete wrong-versus-right example and checklist.

Production wiring

A real plugin usually creates several adapters in one bootstrap location and passes them into the main plugin object:

Run this from the main plugin file, or pass the main plugin file path explicitly. PluginContext::fromPluginFile() uses that path to calculate the plugin basename, directory path, and directory URL.

This bootstrap is the composition root: the place that selects concrete implementations and passes them into the plugin. Business logic should continue to type-hint contracts, not these concrete classes.

Complete service example

The following service combines option storage, HTTP, logging, and Result while remaining independent of WordPress:

The HTTP contract returns a normalized array with is_error, error_message, code, and body. The body is a string, so the service decodes JSON itself. A 400 or 500 response is not a transport error, which is why the example checks the status code separately.

The option value is an array because this service stores two related fields. The storage contract does not require arrays. See the contract reference below for accepted values and WordPress return semantics.

Contracts and implementations

The examples in this section show valid uses, not the only accepted values. For example, an option may be an array, string, number, boolean, object, or another value WordPress can store. Each subsection describes the actual contract and any important differences between the production and testing implementations.

Plugin services depend on six package-owned contracts plus PSR-3 logging.

Concern Contract Production implementation Testing implementation
Hooks and REST routes HooksInterface WordPressHooks RecordingHooks
Options OptionStorageInterface WordPressOptionStorage InMemoryOptionStorage
Transients TransientStorageInterface WordPressTransientStorage InMemoryTransientStorage
URLs, sanitization, escaping, screen state EnvironmentInterface WordPressEnvironment MockEnvironment
HTTP GET and POST HttpClientInterface WordPressHttpClient MockHttpClient
Time ClockInterface SystemClock FrozenClock
Logging Psr\Log\LoggerInterface NullLogger or WordPressDebugLogger RecordingLogger

What thin wrapper means

The production storage and hook adapters mostly pass arguments directly to the equivalent WordPress functions:

Adapter method WordPress function
OptionStorageInterface::get() get_option()
OptionStorageInterface::update() update_option()
OptionStorageInterface::delete() delete_option()
TransientStorageInterface::get() get_transient()
TransientStorageInterface::set() set_transient()
TransientStorageInterface::delete() delete_transient()
HooksInterface::addAction() add_action()
HooksInterface::addFilter() add_filter()
HooksInterface::registerRestRoute() register_rest_route()

The adapter does not turn WordPress storage into an array-only API and it does not hide WordPress return semantics. The contract provides a replaceable boundary, not a new database abstraction.

Option storage contract

The last two differences are intentional. The in-memory adapter is optimized for testing service state, not for reproducing every storage-engine return edge case. Add an integration test when your code depends on exact WordPress return behavior.

Transient storage contract

The value may be any WordPress-compatible transient value. The expiration is a number of seconds. Use 0 for no expiration or a positive integer for a maximum lifetime. Avoid negative expiration values because the in-memory adapter treats every non-positive value as no expiration, while WordPress or an external cache may handle a negative value differently. get() returns false when the transient is missing or expired, so storing boolean false makes those states indistinguishable.

A WordPress transient may disappear before its expiration time. Treat the expiration as a maximum lifetime, not a guarantee that the value will remain available. InMemoryTransientStorage uses an injected ClockInterface and expires an entry when now() is equal to or later than its calculated expiration time. It does not simulate early cache eviction, multisite behavior, external object caches, or transient key length limits.

HTTP contract

Both get() and post() accept a URL and an optional WordPress HTTP arguments array. They return the same shape:

MockHttpClient records every request before resolving a response. Registered URL fragments are checked in registration order. The first fragment contained in the full URL wins. When no fragment matches, it returns is_error => true with code 0 and an explanatory message.

Hooks contract

For actions and filters, the third argument is priority and the fourth argument is the number of callback arguments WordPress should pass. The defaults are priority 10 and one accepted argument. REST route arguments use the same array accepted by register_rest_route(). Call registerRestRoute() from a callback registered on rest_api_init, just as required when calling the WordPress function directly.

RecordingHooks records registrations. It does not execute callbacks or run a WordPress hook lifecycle. hasAction() and hasFilter() check only the tag. hasRestRoute() checks only the route string, not the namespace. Use the corresponding getters when callback, priority, accepted argument count, namespace, or REST arguments matter to the assertion.

Environment contract

WordPressEnvironment forwards URL, current-time, sanitization, escaping, HTML filtering, and current-screen calls to WordPress. currentTime() returns an integer for timestamp or U, and a string for mysql or another PHP date format. It exposes WordPress's default site-time behavior and does not expose the optional GMT argument from current_time().

MockEnvironment provides controlled equivalents suitable for service tests. It returns a fixed timestamp, but formatted time values are produced by PHP's date() and therefore use the test process's default timezone, not the WordPress site timezone. Its sanitization, escaping, URL handling, and allowed HTML behavior are simplified PHP implementations. Do not use it to prove that WordPress sanitizes or escapes a difficult input exactly as expected. Use an integration test for that.

Clock and logging contracts

SystemClock::now() returns time(). FrozenClock returns the timestamp passed to its constructor and can move forward or backward with advance($seconds).

RecordingLogger stores PSR-3 level, message, and context. Helpers such as hasWarning('activation_failed') use substring matching on the message. Use all(), getErrors(), or the other level-specific getters when an exact message or context assertion is required.

Testing adapter reference

InMemoryOptionStorage

Constructor values seed the store. has(), all(), and clear() are testing helpers and are not part of OptionStorageInterface.

InMemoryTransientStorage and FrozenClock

Use an expiration of 0 for an entry that does not expire during the test.

MockHttpClient

addJsonResponse() accepts an array and JSON-encodes it into the response body. Use addRawResponse() when the test needs to control all four response fields directly. addRawResponse() does not fill in missing fields, so provide is_error, error_message, code, and body. clear() removes both request history and configured responses.

RecordingHooks

The getters return the recorded callback, priority, accepted argument count, namespace, route, and REST argument data needed for detailed assertions.

RecordingLogger

The has*() helpers search for a message substring at a specific level. They do not compare the context array.

MockEnvironment

The constructor arguments are the base home URL, base admin URL, and fixed timestamp. The class trims trailing slashes from the two base URLs and joins paths with one slash. setCurrentScreenId() is a testing helper and is not part of EnvironmentInterface. Formatted time values use PHP's configured default timezone.

PHPUnit setup

A unit-test bootstrap only needs Composer:

A minimal PHPUnit configuration can make the unit suite the default:

Run the default unit suite:

Integration tests are separate. They need a WordPress test bootstrap and should be run explicitly through the Integration suite. The unit bootstrap shown above does not load WordPress.

Shared value types and helpers

PluginContext

PluginContext stores immutable plugin metadata and is normally created once at bootstrap.

The arguments are, in order: the main plugin file, plugin slug, plugin version, text domain, and option prefix. The option prefix is stored exactly as provided. fromPluginFile() calls plugin_basename(), plugin_dir_path(), and plugin_dir_url(), so use it only after WordPress is loaded.

Use PluginContext::fromValues() in tests or another environment where WordPress path helpers are unavailable. It accepts all eight stored values directly and does not validate or normalize them.

Result

Result provides one success-or-failure return shape for service methods.

Result data is always an array. Successful results always use code success and an empty message. Failed results use the code, message, and optional data supplied by the caller.

KeyBuilder

KeyBuilder keeps option, transient, cache, and hook names consistent.

Pass the prefix without a trailing underscore or slash. KeyBuilder only concatenates strings. It does not sanitize the prefix or name and it does not prevent a caller from supplying separators. Use stable, already-sanitized identifiers.

Direct-load distribution

Most WordPress plugins ship as ZIP files without a Composer runtime. WP Adapter supports that workflow.

Build workflow

Load the generated bundle from the plugin's main file:

What the copy command does

wp-adapter-copy:

  1. Verifies that the package source and psr/log source exist.
  2. Rejects a source and target path overlap.
  3. Copies WP Adapter and psr/log into a temporary sibling directory.
  4. Generates a deterministic .build-id from the staged files.
  5. Moves the existing bundle to a temporary backup.
  6. Installs the complete staged bundle.
  7. Restores the previous bundle if the final install fails.
  8. Removes the temporary backup after a successful install.

A failed preflight or staging copy leaves the existing lib/wp-adapter/ untouched. The fresh staged copy also prevents removed source files from surviving as stale files in a later build.

The generated .build-id is required runtime metadata and must ship with the plugin.

Build conflict guard

Always load init.php. Do not hide it behind a class_exists() check.

Runtime behavior:

The guard prevents mixed WP Adapter builds from silently serving different classes in one request. It is not namespace isolation. Different builds still cannot coexist, and the guard cannot resolve collisions with an older unguarded copy or an unrelated Composer package.

Namespace-per-plugin scoping remains the long-term coexistence solution.

Advanced usage

Supply a custom adapter

The contracts are the extension points. A plugin can provide its own implementation when the built-in WordPress adapter is not the right fit.

Examples include:

Services do not change because they already depend on OptionStorageInterface.

Choose logging behavior at bootstrap

Use NullLogger when logs should be discarded, WordPressDebugLogger when logs should use PHP's error_log(), or another PSR-3 logger supplied by the plugin. WordPressDebugLogger writes only when WP_DEBUG_LOG is defined and truthy. Its constructor accepts a minimum PSR-3 level and defaults to debug.

Business logic should depend only on Psr\Log\LoggerInterface.

Test time-dependent code

Inject ClockInterface rather than calling time() inside business logic.

Production uses SystemClock. Tests use FrozenClock and advance it without sleeping.

Keep unit and integration tests separate

Unit tests should exercise business logic with testing adapters and no WordPress bootstrap.

Integration tests should verify the thin WordPress adapters against a real WordPress test environment. Examples include unchanged-option return values, scalar option type conversion, transient cache behavior, exact sanitizer output, hook registration details, and HTTP normalization.

Most plugin behavior should remain in the unit-tested service layer. Integration tests cover the WordPress-specific details that the controlled testing adapters intentionally do not emulate.

Keep constructors focused

If a service needs many unrelated adapters, split the service by responsibility. The contracts make dependencies visible, but they do not remove the need for cohesive class design.

Requirements

PHP 7.4, 8.0, 8.1, 8.2
WordPress No minimum enforced
Runtime dependency psr/log ^1.1

The package is deliberately PHP 7.4 compatible. PHP 8-only syntax such as mixed type declarations, constructor property promotion, and union types is not used in src/.

Further reading

License

This project is licensed under the MIT License. See LICENSE for details.


All versions of wp-adapter with dependencies

PHP Build Version
Package Version
Requires php Version ^7.4 || ^8.0 || ^8.1 || ^8.2
psr/log Version ^1.1
Composer command for our command line client (download client) This client runs in each environment. You don't need a specific PHP version etc. The first 20 API calls are free. Standard composer command

The package devuri/wp-adapter contains the following files

Loading the files please wait ...