Usage
Creating a Plugin Context
Every WPZylos plugin starts by defining its identity through a PluginContext:
use WPZylos\Framework\Core\PluginContext;
$context = PluginContext::create([
'file' => __FILE__,
'slug' => 'my-plugin',
'prefix' => 'myplugin_',
'textDomain' => 'my-plugin',
'version' => '1.0.0',
'namespace' => 'MyPlugin',
]);
All six keys (
file,slug,prefix,textDomain,version,namespace) are required. AnInvalidArgumentExceptionis thrown if any are missing.
Using the Context
Identity Properties
$context->slug(); // 'my-plugin'
$context->prefix(); // 'myplugin_'
$context->textDomain(); // 'my-plugin'
$context->version(); // '1.0.0'
$context->namespace(); // 'MyPlugin'
$context->file(); // '/path/to/my-plugin.php'
Paths & URLs
$context->path(); // /path/to/plugin/
$context->path('config/app.php'); // /path/to/plugin/config/app.php
$context->url('assets/js/app.js'); // https://example.com/wp-content/plugins/my-plugin/assets/js/app.js
Prefixed Keys
$context->hook('settings_saved'); // 'myplugin_settings_saved'
$context->optionKey('version'); // 'myplugin_version'
$context->transientKey('cache_data'); // 'myplugin_cache_data'
$context->cronHook('daily_cleanup'); // 'myplugin_daily_cleanup'
$context->metaKey('order_id'); // '_myplugin_order_id'
$context->assetHandle('admin-js'); // 'my-plugin-admin-js'
$context->tableName('orders'); // 'wp_myplugin_orders'
$context->tableName('orders', 'network'); // 'wp_myplugin_orders' (uses base_prefix)
Creating an Application
use WPZylos\Framework\Core\Application;
$app = new Application($context);
// Register service providers
$app->register(new DatabaseServiceProvider());
$app->register(new RoutingServiceProvider());
// Boot the application
$app->boot();
Resolving Services
// Resolve from container
$service = $app->make(MyService::class);
// Check if bound
if ($app->has(MyService::class)) {
// ...
}
// Access context and paths
$ctx = $app->context();
$paths = $app->paths();
Creating Service Providers
Extend the ServiceProvider base class and implement register(). Always call parent::register($app) to store the $app reference.
use WPZylos\Framework\Core\ServiceProvider;
use WPZylos\Framework\Core\Contracts\ApplicationInterface;
class MyServiceProvider extends ServiceProvider
{
public function register(ApplicationInterface $app): void
{
parent::register($app);
// Use the shortcut methods provided by ServiceProvider
$this->singleton(MyService::class, function () {
return new MyService($this->context());
});
}
public function boot(ApplicationInterface $app): void
{
// Called after ALL providers are registered
$config = $this->make('config');
}
}
ServiceProvider Shortcut Methods
Inside any service provider, you have access to these convenience methods:
$this->bind(Abstract::class, $concrete); // Bind a service
$this->singleton(Abstract::class, $concrete); // Bind a singleton
$this->make(Abstract::class); // Resolve a service
$this->context(); // Get plugin context
Working with Paths
The Paths instance is created automatically by Application and resolves paths using the plugin context.
Basic Usage
$paths = $app->paths();
$paths->path('config/app.php'); // /plugin/root/config/app.php
$paths->url('assets/css/app.css'); // https://example.com/.../my-plugin/assets/css/app.css
Using Aliases
Aliases let you reference directories with @alias syntax:
// Use built-in aliases
$paths->path('@views/welcome.php'); // /plugin/root/resources/views/welcome.php
$paths->path('@config/database.php'); // /plugin/root/config/database.php
$paths->url('@assets/css/app.css'); // https://example.com/.../resources/assets/css/app.css
// Register custom aliases (chainable)
$paths->alias('templates', 'resources/templates')
->alias('emails', 'resources/emails');
$paths->path('@templates/invoice.php'); // /plugin/root/resources/templates/invoice.php
Checking Existence & Uploads
if ($paths->exists('@config/app.php')) {
// file exists
}
// Get plugin upload directory (auto-creates if needed)
$uploadPath = $paths->uploads(); // .../wp-content/uploads/my-plugin/
$filePath = $paths->uploads('invoices/1.pdf'); // .../wp-content/uploads/my-plugin/invoices/1.pdf
Caching with CacheRepository
The CacheRepository provides context-prefixed caching using WordPress object cache with a transient fallback layer.
Setup
use WPZylos\Framework\Core\Cache\CacheRepository;
// Typically registered in a service provider:
$this->singleton(CacheRepository::class, function () {
return new CacheRepository($this->context());
});
// Then resolve it:
$cache = $app->make(CacheRepository::class);
Object Cache Operations
// Store and retrieve
$cache->put('user_count', 150, 3600); // Store for 1 hour
$count = $cache->get('user_count'); // 150
$count = $cache->get('missing', 0); // 0 (default)
// Store only if not already present
$cache->add('lock_key', true, 60);
// Check and remove
$cache->has('user_count'); // true
$cache->forget('user_count');
// Increment / decrement counters
$cache->put('views', 0);
$cache->increment('views'); // 1
$cache->increment('views', 5); // 6
$cache->decrement('views', 2); // 4
Remember Pattern
// Compute value only if not cached
$users = $cache->remember('active_users', 3600, function () {
return get_users(['role' => 'subscriber']);
});
// Cache forever
$settings = $cache->rememberForever('plugin_settings', function () {
return get_option('myplugin_settings', []);
});
Transient Operations (Persistent Fallback)
Transients persist across page loads even without a persistent object cache:
// Store in transients
$cache->transientPut('license_check', $result, DAY_IN_SECONDS);
// Retrieve
$result = $cache->transientGet('license_check');
// Remember pattern with transients
$data = $cache->transientRemember('remote_data', HOUR_IN_SECONDS, function () {
return wp_remote_get('https://api.example.com/data');
});
// Delete
$cache->transientForget('license_check');
Utility Classes
Arr (Array Helpers)
use WPZylos\Framework\Core\Support\Arr;
// Dot-notation access
Arr::get($array, 'user.name', 'Guest'); // Get nested value
Arr::set($array, 'user.email', '[email protected]'); // Set nested value
Arr::has($array, 'user.name'); // Check existence
Arr::forget($array, 'user.temp'); // Remove by key
Arr::forget($array, ['a', 'b.c']); // Remove multiple keys
// Filtering
Arr::only($array, ['name', 'email']); // Keep only these keys
Arr::except($array, ['password']); // Exclude these keys
// Utility
Arr::flatten([[1, 2], [3, [4]]]); // [1, 2, 3, 4]
Arr::flatten([[1, [2]], [3]], 1); // [1, [2], 3]
Arr::first([1, 2, 3]); // 1
Arr::first($users, fn($u) => $u->active); // First active user
Arr::wrap('hello'); // ['hello']
Arr::wrap(['hello']); // ['hello']
Arr::wrap(null); // []
Str (String Helpers)
use WPZylos\Framework\Core\Support\Str;
// Case conversion
Str::studly('hello_world'); // 'HelloWorld'
Str::camel('hello_world'); // 'helloWorld'
Str::snake('HelloWorld'); // 'hello_world'
Str::kebab('HelloWorld'); // 'hello-world'
Str::slug('Hello World!'); // 'hello-world'
// String checks (accept string or array of needles)
Str::contains('foobar', 'oba'); // true
Str::contains('foobar', ['baz', 'bar']); // true
Str::startsWith('foobar', 'foo'); // true
Str::endsWith('foobar', 'bar'); // true
// Manipulation
Str::limit('Long text here', 8); // 'Long tex...'
Str::limit('Long text', 8, '…'); // 'Long tex…'
Str::random(32); // Random 32-char string
Str::replaceFirst('bar', 'qux', 'foobar bar'); // 'fooqux bar'
Str::before('hello@world', '@'); // 'hello'
Str::after('hello@world', '@'); // 'world'