Skip to content

v3.0.0

Choose a tag to compare

@gfazioli gfazioli released this 06 Oct 15:06
· 3 commits to master since this release

WP Bones 3.0 changes what the framework does when a plugin says nothing. The changes are breaking, and php bones migrate:to-v3 converts what it can and lists the rest. Read the upgrade guide before you update: https://wpbones.com/docs/migrating-to-v3

PHP stays 8.1+, React stays 18 (from @wordpress/element), and the build does not change.

💥 Migrations run once per site (#40, #119, #121)

  • When a migration runs:
    • each migration runs once per site, in file-name order, and its name is recorded in an option;
    • the pending ones run on activation, on the first request after the plugin's Version changes (however the update arrived: dashboard, ZIP, FTP, git, Composer), and with php bones migrate;
    • a lock keeps concurrent requests from running them twice;
    • a failure stops the run and shows administrators a notice until it runs.
  • What 2.x did instead: it re-ran every migration and every seeder on each activation and dashboard update, inside the update request, with the old code still loaded.
  • Seeders do not run any more: seed data is a migration. migrate:to-v3 converts the seeders, and one with $runOnce seeds only an empty table, as before.
  • The base class is WPBones\Database\Migration. Its constructor has no side effects. The old class still loads, deprecated.
  • New commands: php bones migrate and php bones migrate:status. migrate:create <table> creates the table it is given.
  • plugin/updated.php runs on the first request after an update, in the new code, with $previousVersion.

💥 What declares nothing is for administrators (#125)

  • Pages and menus: a page of config/routes.php or pages/, or a menu of config/menus.php, without a capability now needs manage_options. It was read (2.1.2), and before that nothing. To keep the old behaviour, declare 'capability' => 'read'.
  • REST routes: a route without a permission_callback refuses every request with WordPress's rest_forbidden. It was public. To keep it public, declare 'permission_callback' => '__return_true'.

💥 Requests that change something carry a nonce (#129)

  • Admin pages: every request to a WP Bones admin page that is not a GET or a HEAD carries the plugin's nonce. The form prints it with $plugin->csrfField(); it can also travel in the query string or in an X-WPBones-Nonce header. The check runs before any load callback or controller method. Up to 2.x, a form on another site could post to these pages with an administrator's cookies.
  • Opting out: a page that checks its own nonce says 'csrf' => false.
  • Ajax: a logged action of a provider without $nonceHash refuses every request. make:ajax now sets $nonceHash for you.
  • useHTTPPost() returns unslashed values.

💥 Generated files leave the plugin folder (#128)

  • Where they go: compiled Blade views and single/daily logs go to wp-content/uploads/wpbones/<plugin folder>/, with an index.php at every level and a deny-all .htaccess.
  • Log names carry a hash keyed with AUTH_SALT, so they cannot be guessed where nginx ignores the .htaccess.
  • Blade compiles only when a Blade view renders.
  • No fallback: when uploads cannot be written, a Blade view throws a RuntimeException that says so, and the logs fall back to error_log().
  • Storage::delete() is there for an uninstall.php.

✨ php bones migrate:to-v3

Run it in your plugin's source folder after the update. It converts the migrations and the seeders, then lists for you to review:

  • every page, menu and REST route that declares nothing;
  • every POST form without csrfField();
  • every Ajax provider without a nonce;
  • every second unslash of a useHTTPPost() value.

It rewrites nothing in that list.

Update

composer require "wpbones/wpbones:^3.0"
php bones migrate:to-v3

The 14 boilerplates and their Playground demos are on 3.0. Plugins on ^2.x stay on 2.1.3 until they change their constraint.

Full Changelog: v2.1.3...v3.0.0