Repository navigation
v4.7.0
Added
-
A settings table can keep each row in its own database row (#25).
WP_Settings_Tablestored every row in one option, and every mutation read the whole array, changed one key and wrote the whole array back — the right shape for a table an admin edits one row at a time through the modal, and the wrong shape for a table something else writes. A webhook mirroring records into WordPress fires once per record, so two requests arriving together each read the same array, each add their own row, and the second write drops the first; nothing errors, and nothing short of counting rows against the source notices. Rows now sit behind aWP_Settings_Table_Storageadapter.'storage' => 'table'gives each row its own database row, where a save is oneINSERT ... ON DUPLICATE KEY UPDATEand a delete is oneDELETE, so concurrent writes to different rows cannot lose each other — and a lookup by id becomes oneSELECTinstead of loading every row into PHP. The schema is created on first use and can be installed up front from an activation hook withinstall_storage().storagealso takes any object implementing the interface, for rows that belong somewhere else entirely.Consumer note: the default is unchanged. A table with no
storageargument keeps the same option array under the same name. Switching an existing table to'storage' => 'table'does not migrate the option — read the old option and feed the rows in yourself.
Fixed
- Two settings table rows created in the same second under the same name are both kept. The generated row id was
sanitize_title($name) . '-' . time(), so the second row took the id the first already held and silently overwrote it. Generated ids are checked against storage and take a numeric suffix when the id is already stored. - A settings table bulk action no longer rewrites rows outside the selection. Bulk delete and bulk status changes wrote the whole row set back, so a row another request had just added between the read and the write was lost even though the admin had not selected it.