wpdesk / wp-persistence
Requires
- php: >=7.0
- psr/container: ~1.0.0
Requires (Dev)
- phpunit/phpunit: ^6
- squizlabs/php_codesniffer: ^3.0.2
- wimg/php-compatibility: ^8
- wp-coding-standards/wpcs: ^0.14.1
- wpdesk/wp-wpdesk-composer: ^2.6
This package is auto-updated.
Last update: 2026-06-19 10:19:08 UTC
README
The WP Desk Persistence Library is a robust, lightweight PHP utility designed for WordPress and WooCommerce environments. It abstracts and unifies access to different persistence layers under a clean, consistent interface. By extending the PSR-11 container standards, it enables seamless reading, writing, and deletion of data across arrays, databases, post meta, transients, and WooCommerce sessions.
The library also provides decorators to optimize performance through deferred writes (batch saving) and automatic serialization.
Key Features
- PSR-11 Compliance: Extends
psr/containerto ensure standards compatibility and ease of dependency injection. - Unified Interface: Write and delete values using a single, clear API regardless of whether the backend is an option, transient, post metadata, or WooCommerce session.
- Multiple Adapters: Out-of-the-box support for:
- In-memory arrays and references.
- WordPress Options, Transients, and Post Meta.
- WooCommerce Sessions, Settings APIs, and Shipping Methods.
- Performance-Oriented Decorators:
- Delayed writes to queue database updates in memory before applying them in a single batch operation.
- Serialization wrappers to safely store complex structures like arrays or objects in simple scalar database options.
- Robust Exception Handling: Transparently maps lookup failures to PSR-compliant exceptions and supports fallback values.
Requirements
The minimum system requirements read from composer.json are:
- PHP Version:
7.0or higher - Key Libraries:
psr/container:~1.0.0
- WordPress Environment: Recommended when using WordPress adapters.
- WooCommerce Environment: Required when using WooCommerce-specific session or settings adapters.
Installation
Install the library using Composer:
composer require wpdesk/wp-persistence
Autoloader Compatibility
To ensure that the correct version of the library is loaded in WordPress environments where multiple plugins might bundle different versions of the same dependency, it is highly recommended to use wpdesk/wp-autoloader.
// Standard Composer autoloader initialization
require_once 'vendor/autoload.php';
Usage
Below are examples demonstrating how to use the different containers and decorators in this package.
Basic CRUD Operations
You can use WordpressOptionsContainer to store basic configuration values.
use WPDesk\Persistence\Adapter\WordPress\WordpressOptionsContainer;
// Initialize the option-backed container with an optional namespace prefix
$container = new WordpressOptionsContainer('my_plugin_');
// Save a scalar value
$container->set('api_key', 'xyz123abc');
// Check if a value exists
if ($container->has('api_key')) {
// Retrieve the value
$apiKey = $container->get('api_key');
}
// Safely get a value with a fallback default without throwing exceptions
$timeout = $container->get_fallback('request_timeout', 30);
// Delete a key
$container->delete('api_key');
// Setting a value to null also deletes it
$container->set('api_key', null);
Transparent Serialization
Standard WordPress options cannot store complex structures natively without manual serialization. The SerializedPersistentContainer automates this process.
use WPDesk\Persistence\Adapter\WordPress\WordpressOptionsContainer;
use WPDesk\Persistence\Decorator\SerializedPersistentContainer;
$baseContainer = new WordpressOptionsContainer('plugin_settings_');
$serializedContainer = new SerializedPersistentContainer($baseContainer);
$settings = [
'notifications' => true,
'retry_limit' => 5,
'allowed_types' => ['post', 'page']
];
// Stores serialized data under option 'plugin_settings_config'
$serializedContainer->set('config', $settings);
// Automatically unserializes to a PHP array on retrieval
$retrievedSettings = $serializedContainer->get('config');
Deferred Writes (Delaying DB Queries)
To avoid executing a database query on every set or delete call, wrap your container in DelayPersistentContainer. This implements the DeferredPersistentContainer interface.
use WPDesk\Persistence\Adapter\WordPress\WordpressOptionsContainer;
use WPDesk\Persistence\Decorator\DelayPersistentContainer;
$options = new WordpressOptionsContainer('user_pref_');
$deferred = new DelayPersistentContainer($options);
// Changes are kept in memory and do not query the database yet
$deferred->set('theme', 'dark');
$deferred->set('sidebar_collapsed', true);
$deferred->delete('old_temporary_flag');
if ($deferred->is_changed()) {
// Persist all queued memory modifications to the database at once
$deferred->save();
}
// Discard all unsaved memory adjustments
$deferred->reset();
Delayed Persistence to a Single Unified Value
To store multiple distinct settings keys as key-value pairs inside a single database field, use DelaySinglePersistentContainer. It implements AllDataAccessContainer.
use WPDesk\Persistence\Adapter\WordPress\WordpressOptionsContainer;
use WPDesk\Persistence\Decorator\DelaySinglePersistentContainer;
$options = new WordpressOptionsContainer();
// All keys manipulated here will end up in a single serialized option named 'my_plugin_unified_settings'
$singleOptionContainer = new DelaySinglePersistentContainer($options, 'my_plugin_unified_settings');
$singleOptionContainer->set('enabled', true);
$singleOptionContainer->set('debug_mode', false);
// Writes a single serialized array containing all values to the option
$singleOptionContainer->save();
// Read all key-value pairs
$allSettings = $singleOptionContainer->get_all();
Reference Array Persistence
You can bind a container to a referenced PHP array via ReferenceArrayContainer. Manipulating the container alters the reference target directly.
use WPDesk\Persistence\Adapter\ReferenceArrayContainer;
$settingsArray = [];
$container = new ReferenceArrayContainer($settingsArray);
$container->set('option_a', 'value_a');
// $settingsArray now contains ['option_a' => 'value_a']
WooCommerce Session Container
Store values directly inside the WooCommerce customer session using WooCommerceSessionContainer.
use WPDesk\Persistence\Adapter\WooCommerce\WooCommerceSessionContainer;
if (null !== WC()->session) {
$sessionContainer = new WooCommerceSessionContainer(WC()->session);
// Save temporary state for the user's cart or session
$sessionContainer->set('selected_delivery_window', 'morning');
$window = $sessionContainer->get('selected_delivery_window');
}
Value Resolution Table
This table illustrates the responses of has() and get() for various types of values stored in the containers.
| Stored Value | Get Result | Has Result |
|---|---|---|
'test' | 'test' | true |
[] | [] | true |
'' | '' | true |
99 | 99 (or string '99') | true |
0 | 0 (or string '0') | true |
true | true (or string '1') | true |
false | false (or empty string '') | true |
| not set | Throws ElementNotExistsException | false |
null | Throws ElementNotExistsException | false |
Backward Compatibility / Legacy APIs
When upgrading the library, please note the following legacy changes and structural updates:
Upgrading to 3.0.0
- Null Handling: Historically, setting a key to
nullstored the literal valuenull. Since version 3.0.0, passingnulltoset()is treated as a removal operation, invokingdelete(). Callingget()orhas()on a key that was set tonullwill throw an ElementNotExistsException and returnfalse, respectively. - Interface Methods: The PersistentContainer interface now requires the
get_fallbackmethod. Custom implementations of this interface must define this method or consume FallbackFromGetTrait.
Upgrading to 2.0.0
- Namespace Standardization: The root namespace path was standardized. The segment
Wordpresswas renamed toWordPress. Ensure your class use-statements and configuration namespaces are updated to utilizeWPDesk\Persistence\Adapter\WordPress\. - Class Renaming: The class
MemoryContainerwas deprecated and renamed to ArrayContainer. Change all references ofMemoryContainerto ArrayContainer.
Running Tests
Unit and integration tests are configured using PHPUnit. The test suites are defined in phpunit-unit.xml and phpunit-integration.xml.
You can execute the test suites using the following Composer commands:
Unit Tests
# Run unit tests with coverage reporting
composer phpunit-unit
# Run unit tests quickly without code coverage
composer phpunit-unit-fast
Integration Tests
# Run integration tests with coverage reporting
composer phpunit-integration
# Run integration tests quickly without code coverage
composer phpunit-integration-fast
License
This library is licensed under the MIT License. See LICENSE.md for details.