Download the PHP package yaml-ns/wpp-framework without Composer
On this page you can find all versions of the php package yaml-ns/wpp-framework. It is possible to download/install these versions without Composer. Possible dependencies are resolved automatically.
Download yaml-ns/wpp-framework
More information about yaml-ns/wpp-framework
Files in yaml-ns/wpp-framework
Package wpp-framework
Short Description Reusable WordPress plugin framework base.
License MIT
Informations about the package wpp-framework
WPP Framework
Reusable PHP framework for building application-style WordPress plugins: REST APIs, admin screens, business services, assets, cron, permissions, modules and PHP views.
License: MIT.
Namespace:
Goal
WPP Framework is a shared Composer library installed inside each consumer plugin. It avoids rewriting the same infrastructure for every plugin:
- plugin bootstrap;
- dependency injection container;
- service providers;
- REST routes and middleware;
- security helpers;
- custom post types and taxonomies;
- metaboxes and meta fields;
- admin pages and admin forms;
- admin CRUD screens;
- asset enqueueing;
- WordPress settings;
- cron jobs;
- AJAX actions;
- modules;
- PHP view rendering.
The framework supports multiple active plugins in the same WordPress installation. Each plugin gets its own PluginContext, container and provider list.
Installation
Inside a consumer plugin:
Then run:
The framework package is a Composer library, not a wordpress-plugin.
Public Bootstrap
The main file of a consumer plugin can stay small:
Wpp::activate() registers declarative structures that affect rewrite rules, such as custom post types, runs lifecycle migrations, then flushes rewrite rules.
Wpp::boot() creates the PluginContext, retrieves the isolated framework instance for this plugin, registers configured providers, then boots the plugin.
Wpp::deactivate() clears declared cron jobs and flushes rewrite rules.
For full cleanup when the plugin is deleted, add an uninstall.php file in the consumer plugin:
Configuration
Example config/plugin.php:
Each plugin must explicitly declare a unique slug and rest_namespace. Wpp::boot() and Wpp::activate() reject application configs that do not provide them.
For standard needs, Wpp::boot() can read post_types, taxonomies, meta_boxes, shortcodes, assets, admin, admin_forms, admin_crud, routes, rest_controllers, settings, cron, ajax, i18n, capabilities, lifecycle, logger and uninstall directly from config.
The config is validated before boot and activation so common mistakes fail early.
Recommended Plugin Structure
The framework stays in vendor/. The plugin's application code stays in app/.
Create A Plugin From Scratch
Minimal flow for a product-catalog plugin:
-
Create the WordPress plugin and install the framework:
-
Add the main
product-catalog.phpfile withWpp::activate(),Wpp::boot()andWpp::deactivate(). -
Create
config/plugin.phpwith the plugin identity: -
Generate the common pieces:
-
Adapt fields in the repository, requests and
config/admin-crud.php. - Add a view or shortcode when the plugin needs frontend output.
The examples/product-catalog-plugin/ directory shows this flow with a product CPT, taxonomy, meta fields, settings, admin CRUD, REST API and shortcode.
Architecture Guidelines
Use config for stable declarative parts: CPTs, taxonomies, assets, routes, metaboxes, admin CRUD, cron and settings.
Use routes/*.php to connect REST URLs to controllers. Controllers should handle HTTP use cases, not route registration.
Use a repository to isolate WordPress access (WP_Query, post meta, terms). Controllers, shortcodes and admin CRUD screens can then share the same data access logic.
Use a FormRequest when a REST or admin action needs explicit validation. Use a Policy when authorization depends on the action or resource.
Create a custom ServiceProvider only when you need to register business services, wire an external integration, add container bindings or boot behavior that does not belong in declarative config.
Views
Plugin PHP views live in resources/views/ and can be rendered with ViewRenderer:
View data is extracted with extract(..., EXTR_SKIP), so a view receives $books, $query, $context, etc. directly. The context variable is reserved by the framework.
The view renderer is intentionally native PHP, but it supports layouts, includes, sections and stacks:
In resources/views/layouts/admin.php:
Container
The container centralizes plugin services: repositories, external API clients, import services, policies and similar application objects. For simple plugins, automatic autowiring is enough. Create a custom provider when a specific implementation must be configured.
tagged('importers') returns all tagged implementations. Contextual bindings are useful when two services need the same interface but different implementations.
Modules
Modules can be enabled from config:
A module is simply a group of providers. This keeps the core small and lets each plugin choose its own boundaries.
Included Providers
AdminPageServiceProvider
Registers admin pages from config:
AdminPageServiceProvider is the declarative API for consumer plugin admin pages. AdminServiceProvider is only the internal/debug framework admin page.
AdminFormServiceProvider
Handles admin forms through admin-post.php, checks capability, validates nonce, sanitizes fields and stores an option when no custom handler is provided.
AssetServiceProvider
Enqueues admin and frontend assets. Admin assets can be limited to specific screens with only, and scripts can receive data with localize.
LifecycleServiceProvider
Stores the installed version and runs pending migrations during Wpp::activate(), not during every request.
Logger
The framework depends on psr/log and binds Psr\Log\LoggerInterface to its default Logger. A consumer plugin can replace this binding in a custom provider, including with Monolog.
BaseRepository
BaseRepository provides a base for CPT repositories:
Available methods: query(), all(), latest(), paginate(), where(), find(), findAny(), findOrFail(), create(), update(), delete(), toArray().
create() and update() accept aliases such as title, content, excerpt, status and slug, plus WordPress fields declared by writableFields(). Meta and taxonomy values are synchronized only when declared in metaFields() / taxonomyFields().
MetaBoxServiceProvider
Declares metaboxes and meta fields from config. The provider handles nonce, register_post_meta(), simple HTML rendering and saving.
Checkbox fields are stored as postmeta strings '1' / '0'. Their default REST type is therefore string. If you need a real REST boolean, set meta_type and provide suitable sanitization.
Field sanitization goes through FieldSanitizer, shared by metaboxes and admin CRUD, to keep number, integer, float, select_multiple and checkboxes behavior consistent.
AdminCrudServiceProvider
Declares a simple admin CRUD interface for a CPT repository. The provider adds an admin page, renders index / form views, checks capability and nonce, then calls create(), update() and delete() on the repository.
Admin-post actions are derived from the slug: books_store, books_update, books_delete, books_bulk.
Index views receive $filters, $activeFilters, $currentPage and $totalPages, so they can build search, filters, pagination and bulk actions.
When admin validation fails, the provider redirects back to the form with message=validation_failed, stores errors and old input in a short transient, then injects $errors and $values into the view.
ShortcodeServiceProvider
Declares shortcodes and lets the container resolve class callbacks:
Shortcode tags must match a-z, 0-9, _ and -.
REST
The framework registers a public health endpoint:
Recommended REST route declaration:
Then register the file in config/plugin.php:
The controller stays focused on HTTP use cases and does not need to know RestRouter.
BaseRestController provides paginated(), notFound(), forbidden(), deleted() and handle(). handle() converts a ValidationException into a WP_Error wpp_validation_failed with status 422, and other exceptions into 400 errors.
Form Requests
REST controllers can type a request class that extends FormRequest. The container builds it from WP_REST_Request, and validated() throws ValidationException when data is invalid.
Available rules: required, nullable, sometimes, required_if, required_with, string, numeric, integer, email, boolean, array, min, max, size, in, not_in, same, different, confirmed, url, date, alpha_dash, slug, json, regex, exists:post,post_type, exists:term,taxonomy, exists:user.
The validator also accepts custom injected rules:
Resource Routing
RestRouter can declare standard REST resource routes:
For non-numeric identifiers:
Generated routes:
Policies
Controllers can use an injected policy through the protected $policy property and call authorize().
ResourcePolicy uses WordPress read for reads by default, edit_posts for create, edit_post for update and delete_post for delete. If a resource should be publicly readable, override viewAnyCapability() and viewCapability() to return null.
CLI
The package exposes a Composer binary named wpp:
Useful options:
make:resource generates a CPT, repository, read-only REST controller and routes file. make:crud generates the full REST CRUD stack. make:admin-crud generates config/admin-crud.php and admin index/form views.
The generator creates application files only. You still declare the post type, route file and/or admin_crud in config/plugin.php, keeping configuration explicit.
Tests
The project contains unit tests for the container, REST router, validation, views, CLI generator and the most sensitive providers using local WordPress stubs.
Local PHP/Composer:
Docker:
Quality checks:
CI definitions are provided for GitHub Actions and GitLab CI:
Pipelines run Composer validation, PHP CS Fixer, PHPStan and PHPUnit.
Releases
The project follows SemVer. Public versions should be created with Git tags (v0.9.0, v1.0.0, etc.) rather than a version field in composer.json.
Changes are tracked in CHANGELOG.md, and the release process is documented in RELEASE.md.
Stability target:
0.9.x: pilot production use in internal plugins;1.0.0: public API freeze for the main framework surface.
Uninstall
Deletion cleanup is declarative:
Example
A concrete example is available in:
It creates a product custom post type, product_category taxonomy, settings page, admin CRUD, metaboxes, REST routes and displays products with:
Example REST routes: