feat(cpt): consolidate peptide CPT with PSA; drop pr_peptide (v0.2.0)
Resolves the rewrite slug collision that was 404'ing all 89 production peptide detail pages. PR Core v0.1.1 registered an empty pr_peptide CPT claiming /peptides/%postname%/; WP's rewrite resolver picked it over PSA's populated peptide CPT. This release consolidates both registrations onto a single peptide CPT owned by PR Core. PSA v4.5.0 drops its registration in favor of this one. ## Contract (per CTO msg 02) - POST_TYPE: pr_peptide -> peptide - TAX_CATEGORY: pr_peptide_category -> peptide_category - TAX_FAMILY const removed (pr_peptide_family was never populated) - CPT + taxonomy registration guarded with post_type_exists() / taxonomy_exists() so deploy order between PR Core and PSA is forgiving - Args harmonized as superset of PSA + prior PR Core (thumbnail added to supports; capability_type + map_meta_cap preserved) - Activator: flush_rewrite_rules(false) on activation; new maybe_flush_on_version_change() handler hooked at init:999 for in-place updates that bypass the activation hook (e.g. SCP deploys) - uninstall.php: blanket DELETE replaced with JOIN on _pr_core_authored so PSA-authored peptide posts (the 89 canonical monographs) are never destroyed; peptide_category terms preserved (shared ownership) - Scrub scope: narrow — CPT-slug-derived identifiers only; class names, file names, PR_CORE_* constants, pr_core_* options, and pr-core/v1 REST namespace remain ## Docs - ARCHITECTURE.md: new Key Decision #7 (v0.2.0 consolidation) and §2.9 Uninstall specification - CONVENTIONS.md: CPT Ownership rule + _pr_core_authored flag contract ## Tests - Lightweight harness (tests/bootstrap.php) that stubs the handful of WP functions exercised by the CPT class - tests/unit/test-peptide-cpt.php asserts: constants match contract, TAX_FAMILY is removed, guard no-ops when post_type_exists/taxonomy_exists returns true, args payload shape (thumbnail in supports, rewrite slug, REST namespace), hooks wired - CI: new 'Unit tests (lightweight, no PHPUnit)' step in lint-php job, runs across PHP 8.1/8.2/8.3. Full PHPUnit + wp-env harness is a follow-up Refs: convo/prcore/threads/2026-04-peptides-cpt-collision/02-cto-correction.md
This commit is contained in:
@@ -1,11 +1,13 @@
|
||||
<?php
|
||||
/**
|
||||
* Peptide Repo Core — Full data teardown on uninstall.
|
||||
* Peptide Repo Core — Selective data teardown on uninstall.
|
||||
*
|
||||
* Removes ALL plugin data: custom tables, CPT posts + meta, taxonomy terms,
|
||||
* options, and capabilities. No orphaned data left behind.
|
||||
* Removes plugin-owned data only: custom tables, PR Core-authored peptide
|
||||
* posts, pr_core_ options, and the manage_peptide_content capability.
|
||||
* Shared data (the 89 canonical peptide posts authored by PSA, and the
|
||||
* peptide_category taxonomy terms) is preserved.
|
||||
*
|
||||
* @see ARCHITECTURE.md — Section 2.9 Uninstall specification.
|
||||
* @see ARCHITECTURE.md — §2.9 Uninstall specification.
|
||||
*/
|
||||
|
||||
if ( ! defined( 'WP_UNINSTALL_PLUGIN' ) ) {
|
||||
@@ -27,33 +29,45 @@ foreach ( $tables as $table ) {
|
||||
$wpdb->query( "DROP TABLE IF EXISTS {$table}" );
|
||||
}
|
||||
|
||||
/* ── 2. Delete all pr_peptide posts (cascade deletes meta) ────────────── */
|
||||
/* ── 2. Delete only peptide posts authored through PR Core's UI ───────── */
|
||||
|
||||
/*
|
||||
* As of v0.2.0, PR Core shares the `peptide` CPT with Peptide Search AI.
|
||||
* PSA authored the 89 canonical peptide posts on peptiderepo.com; those
|
||||
* predate PR Core and do NOT carry the `_pr_core_authored` flag. A blanket
|
||||
* DELETE here would destroy site-owned content, not plugin-owned content.
|
||||
*
|
||||
* This loop only deletes posts that PR Core itself created (flagged with
|
||||
* post-meta `_pr_core_authored = '1'`). If no post carries the flag, the
|
||||
* loop no-ops and shared content is preserved.
|
||||
*/
|
||||
// phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery
|
||||
$post_ids = $wpdb->get_col(
|
||||
"SELECT ID FROM {$wpdb->posts} WHERE post_type = 'pr_peptide'"
|
||||
$wpdb->prepare(
|
||||
"SELECT p.ID FROM {$wpdb->posts} p
|
||||
INNER JOIN {$wpdb->postmeta} pm
|
||||
ON p.ID = pm.post_id AND pm.meta_key = %s AND pm.meta_value = %s
|
||||
WHERE p.post_type = %s",
|
||||
'_pr_core_authored',
|
||||
'1',
|
||||
'peptide'
|
||||
)
|
||||
);
|
||||
|
||||
foreach ( $post_ids as $post_id ) {
|
||||
wp_delete_post( (int) $post_id, true );
|
||||
}
|
||||
|
||||
/* ── 3. Delete taxonomy terms ─────────────────────────────────────────── */
|
||||
/* ── 3. Preserve taxonomy terms (shared ownership post-v0.2.0) ────────── */
|
||||
|
||||
$taxonomies = [ 'pr_peptide_category', 'pr_peptide_family' ];
|
||||
|
||||
foreach ( $taxonomies as $taxonomy ) {
|
||||
$terms = get_terms( [
|
||||
'taxonomy' => $taxonomy,
|
||||
'hide_empty' => false,
|
||||
'fields' => 'ids',
|
||||
] );
|
||||
|
||||
if ( is_array( $terms ) ) {
|
||||
foreach ( $terms as $term_id ) {
|
||||
wp_delete_term( (int) $term_id, $taxonomy );
|
||||
}
|
||||
}
|
||||
}
|
||||
/*
|
||||
* `peptide_category` is shared between PR Core and PSA. Term metadata
|
||||
* (descriptions, parent relationships, counts) is data the site owns —
|
||||
* removing it on PR Core uninstall would strip categorization from the
|
||||
* peptide posts that remain. So we intentionally do NOT enumerate or
|
||||
* delete terms here. `pr_peptide_family` is gone in v0.2.0 so no cleanup
|
||||
* is needed for it either.
|
||||
*/
|
||||
|
||||
/* ── 4. Delete all pr_core_ prefixed options ──────────────────────────── */
|
||||
|
||||
@@ -62,7 +76,7 @@ $wpdb->query(
|
||||
"DELETE FROM {$wpdb->options} WHERE option_name LIKE 'pr\_core\_%'"
|
||||
);
|
||||
|
||||
/* ── 5. Remove manage_peptide_content capability from all roles ────────── */
|
||||
/* ── 5. Remove manage_peptide_content capability from all roles ───────── */
|
||||
|
||||
$editable_roles = wp_roles()->roles;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user