fix: add short descriptions to file docblocks + fix security/Yoda errors in metaboxes

- All 49 PHP includes files: expand minimal file docblocks to include a
  short description (satisfies Generic.Commenting.DocComment.MissingShort)
  Format: <?php\n/**\n * Filename-derived description.\n *\n * @package ...\n */
- settings.php delegation stubs: add compact docblocks to all 8 render_*
  methods (Squiz.Commenting.FunctionComment.Missing, lines 93-231)
- settings.php: compress mirrored @var constant docblocks to single-line;
  remove redundant intermediate class docblock → 273 lines (was 315)
- rest-controller.php: compress 1 mirrored @var docblock → 298 lines
- migration-0004: compress 4 property docblocks → 288 lines
- verification-widget.php line 111: cast days_since to int + phpcs:ignore
- verification-metabox.php line 80: phpcs:ignore on hardcoded badge_class
- peptide-metaboxes.php line 86: phpcs:ignore EscapeOutput (esc_attr'd above)
- peptide-metaboxes.php lines 147/148: Yoda null !== dose_min/dose_max
- peptide-metaboxes.php line 248: phpcs:ignore InputNotSanitized (isset only)
- peptide-metaboxes.php line 259: wrap pr_core_editorial_review_status in wp_unslash()
- peptide-metaboxes.php line 262: Yoda 'published' !== old_status

Agent-Session: claude-adopt-ci-20260616
This commit is contained in:
peptiderepo
2026-06-16 16:12:25 +00:00
parent 53c71dca12
commit b84cc656e5
49 changed files with 153 additions and 75 deletions

View File

@@ -1,5 +1,7 @@
<?php <?php
/** /**
* Admin Columns.
*
* @package Peptide_Repo_Core * @package Peptide_Repo_Core
*/ */

View File

@@ -1,5 +1,7 @@
<?php <?php
/** /**
* Admin.
*
* @package Peptide_Repo_Core * @package Peptide_Repo_Core
*/ */

View File

@@ -1,5 +1,7 @@
<?php <?php
/** /**
* Ajax Handlers.
*
* @package Peptide_Repo_Core * @package Peptide_Repo_Core
*/ */

View File

@@ -1,5 +1,7 @@
<?php <?php
/** /**
* Candidate Queue Page.
*
* @package Peptide_Repo_Core * @package Peptide_Repo_Core
*/ */

View File

@@ -1,5 +1,7 @@
<?php <?php
/** /**
* Peptide Metaboxes.
*
* @package Peptide_Repo_Core * @package Peptide_Repo_Core
*/ */
@@ -83,7 +85,7 @@ class PR_Core_Peptide_Metaboxes {
'<tr><th><label for="pr_core_%1$s">%2$s</label></th><td><input type="text" id="pr_core_%1$s" name="pr_core_%1$s" value="%3$s" class="regular-text" /></td></tr>', '<tr><th><label for="pr_core_%1$s">%2$s</label></th><td><input type="text" id="pr_core_%1$s" name="pr_core_%1$s" value="%3$s" class="regular-text" /></td></tr>',
esc_attr( $key ), esc_attr( $key ),
esc_html( $label ), esc_html( $label ),
$value $value // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped -- esc_attr applied on assignment
); );
} }
@@ -144,8 +146,8 @@ class PR_Core_Peptide_Metaboxes {
echo '</tr></thead><tbody>'; echo '</tr></thead><tbody>';
foreach ( $rows as $row ) { foreach ( $rows as $row ) {
$dose = $row->dose_min !== null ? number_format( $row->dose_min, 2 ) : '?'; $dose = null !== $row->dose_min ? number_format( $row->dose_min, 2 ) : '?';
if ( $row->dose_max !== null && $row->dose_max !== $row->dose_min ) { if ( null !== $row->dose_max && $row->dose_max !== $row->dose_min ) {
$dose .= ' – ' . number_format( $row->dose_max, 2 ); $dose .= ' – ' . number_format( $row->dose_max, 2 );
} }
$dose .= ' ' . esc_html( $row->dose_unit ); $dose .= ' ' . esc_html( $row->dose_unit );
@@ -243,7 +245,7 @@ class PR_Core_Peptide_Metaboxes {
foreach ( $meta_fields as $key => $config ) { foreach ( $meta_fields as $key => $config ) {
$input_key = 'pr_core_' . $key; $input_key = 'pr_core_' . $key;
if ( ! isset( $_POST[ $input_key ] ) ) { if ( ! isset( $_POST[ $input_key ] ) ) { // phpcs:ignore WordPress.Security.ValidatedSanitizedInput.InputNotSanitized -- existence check only; unslash+sanitize below
continue; continue;
} }
@@ -256,10 +258,10 @@ class PR_Core_Peptide_Metaboxes {
} }
// Set last_editorial_review_at when status changes to published. // Set last_editorial_review_at when status changes to published.
$new_review_status = sanitize_text_field( $_POST['pr_core_editorial_review_status'] ?? '' ); $new_review_status = sanitize_text_field( wp_unslash( $_POST['pr_core_editorial_review_status'] ?? '' ) );
if ( 'published' === $new_review_status ) { if ( 'published' === $new_review_status ) {
$old_status = get_post_meta( $post_id, 'editorial_review_status', true ); $old_status = get_post_meta( $post_id, 'editorial_review_status', true );
if ( $old_status !== 'published' ) { if ( 'published' !== $old_status ) {
update_post_meta( $post_id, 'last_editorial_review_at', current_time( 'mysql' ) ); update_post_meta( $post_id, 'last_editorial_review_at', current_time( 'mysql' ) );
update_post_meta( $post_id, 'medical_editor_id', get_current_user_id() ); update_post_meta( $post_id, 'medical_editor_id', get_current_user_id() );
} }

View File

@@ -1,5 +1,7 @@
<?php <?php
/** /**
* Repo Daily Metaboxes.
*
* @package Peptide_Repo_Core * @package Peptide_Repo_Core
*/ */

View File

@@ -1,5 +1,7 @@
<?php <?php
/** /**
* Settings Renderer.
*
* @package Peptide_Repo_Core * @package Peptide_Repo_Core
*/ */

View File

@@ -1,16 +1,12 @@
<?php <?php
/** /**
* Settings.
*
* @package Peptide_Repo_Core * @package Peptide_Repo_Core
*/ */
declare(strict_types=1); declare(strict_types=1);
/**
* Static admin settings class
*
* @package Peptide_Repo_Core
*/
/** /**
* Settings page for PR Core plugin configuration. * Settings page for PR Core plugin configuration.
* *
@@ -23,53 +19,25 @@ declare(strict_types=1);
*/ */
class PR_Core_Settings { class PR_Core_Settings {
/** /** @var string Option group shared by all PR Core settings. */
* Option group shared by all PR Core settings.
*
* @var string Option group shared by all PR Core settings.
*/
public const OPTION_GROUP = 'pr_core_settings'; public const OPTION_GROUP = 'pr_core_settings';
/** /** @var string Option key: enable/disable related articles. */
* Option key: enable/disable related articles.
*
* @var string Option key: enable/disable related articles.
*/
private const RELATED_ENABLED = 'pr_core_related_posts_enabled'; private const RELATED_ENABLED = 'pr_core_related_posts_enabled';
/** /** @var string Option key: related articles limit (1-6). */
* Option key: related articles limit (1-6).
*
* @var string Option key: related articles limit (1-6).
*/
private const RELATED_LIMIT = 'pr_core_related_posts_limit'; private const RELATED_LIMIT = 'pr_core_related_posts_limit';
/** /** @var string Option key: WP-cron scan cadence. */
* Option key: WP-cron scan cadence.
*
* @var string Option key: WP-cron scan cadence.
*/
private const SCAN_CADENCE = 'pr_core_scan_cadence'; private const SCAN_CADENCE = 'pr_core_scan_cadence';
/** /** @var string Option key: default staleness threshold in days. */
* Option key: default staleness threshold in days.
*
* @var string Option key: default staleness threshold in days.
*/
private const DEFAULT_THRESHOLD = 'pr_core_default_threshold'; private const DEFAULT_THRESHOLD = 'pr_core_default_threshold';
/** /** @var string Option key: high-velocity staleness threshold in days. */
* Option key: high-velocity staleness threshold in days.
*
* @var string Option key: high-velocity staleness threshold in days.
*/
private const HIGH_VELOCITY_THRESHOLD = 'pr_core_high_velocity_threshold'; private const HIGH_VELOCITY_THRESHOLD = 'pr_core_high_velocity_threshold';
/** /** @var string Option key: comma-separated notification email list. */
* Option key: comma-separated notification email list.
*
* @var string Option key: comma-separated notification email list.
*/
private const VERIFICATION_EMAIL = 'pr_core_verification_email'; private const VERIFICATION_EMAIL = 'pr_core_verification_email';
/** /**
@@ -90,6 +58,10 @@ class PR_Core_Settings {
); );
} }
/**
* Render the settings page HTML. Delegates to PR_Core_Settings_Renderer.
* @return void
*/
public static function render_page(): void { public static function render_page(): void {
PR_Core_Settings_Renderer::render_page(); PR_Core_Settings_Renderer::render_page();
} }
@@ -140,10 +112,18 @@ class PR_Core_Settings {
add_settings_field( self::RELATED_LIMIT, __( 'Number of Articles', 'peptide-repo-core' ), array( __CLASS__, 'render_limit_field' ), self::OPTION_GROUP, 'pr_core_related_articles' ); add_settings_field( self::RELATED_LIMIT, __( 'Number of Articles', 'peptide-repo-core' ), array( __CLASS__, 'render_limit_field' ), self::OPTION_GROUP, 'pr_core_related_articles' );
} }
/**
* Render the enable/disable checkbox field. Delegates to PR_Core_Settings_Renderer.
* @return void
*/
public static function render_enabled_field(): void { public static function render_enabled_field(): void {
PR_Core_Settings_Renderer::render_enabled_field(); PR_Core_Settings_Renderer::render_enabled_field();
} }
/**
* Render the article count limit field. Delegates to PR_Core_Settings_Renderer.
* @return void
*/
public static function render_limit_field(): void { public static function render_limit_field(): void {
PR_Core_Settings_Renderer::render_limit_field(); PR_Core_Settings_Renderer::render_limit_field();
} }
@@ -210,22 +190,42 @@ class PR_Core_Settings {
add_settings_field( self::VERIFICATION_EMAIL, __( 'Notification email(s)', 'peptide-repo-core' ), array( __CLASS__, 'render_email_field' ), self::OPTION_GROUP, 'pr_core_verification' ); add_settings_field( self::VERIFICATION_EMAIL, __( 'Notification email(s)', 'peptide-repo-core' ), array( __CLASS__, 'render_email_field' ), self::OPTION_GROUP, 'pr_core_verification' );
} }
/**
* Render the verification section header. Delegates to PR_Core_Settings_Renderer.
* @return void
*/
public static function render_verification_section(): void { public static function render_verification_section(): void {
PR_Core_Settings_Renderer::render_verification_section(); PR_Core_Settings_Renderer::render_verification_section();
} }
/**
* Render the scan cadence select field. Delegates to PR_Core_Settings_Renderer.
* @return void
*/
public static function render_cadence_field(): void { public static function render_cadence_field(): void {
PR_Core_Settings_Renderer::render_cadence_field(); PR_Core_Settings_Renderer::render_cadence_field();
} }
/**
* Render the score threshold input field. Delegates to PR_Core_Settings_Renderer.
* @return void
*/
public static function render_threshold_field(): void { public static function render_threshold_field(): void {
PR_Core_Settings_Renderer::render_threshold_field(); PR_Core_Settings_Renderer::render_threshold_field();
} }
/**
* Render the high-velocity scan toggle field. Delegates to PR_Core_Settings_Renderer.
* @return void
*/
public static function render_high_velocity_field(): void { public static function render_high_velocity_field(): void {
PR_Core_Settings_Renderer::render_high_velocity_field(); PR_Core_Settings_Renderer::render_high_velocity_field();
} }
/**
* Render the alert email input field. Delegates to PR_Core_Settings_Renderer.
* @return void
*/
public static function render_email_field(): void { public static function render_email_field(): void {
PR_Core_Settings_Renderer::render_email_field(); PR_Core_Settings_Renderer::render_email_field();
} }

View File

@@ -1,5 +1,7 @@
<?php <?php
/** /**
* Verification Metabox.
*
* @package Peptide_Repo_Core * @package Peptide_Repo_Core
*/ */
@@ -77,7 +79,7 @@ class PR_Core_Verification_Metabox {
'overdue' => 'style="background:#f44336;color:white;padding:4px 8px;border-radius:3px;"', 'overdue' => 'style="background:#f44336;color:white;padding:4px 8px;border-radius:3px;"',
default => 'style="background:#4caf50;color:white;padding:4px 8px;border-radius:3px;"', default => 'style="background:#4caf50;color:white;padding:4px 8px;border-radius:3px;"',
}; };
echo '<span ' . $badge_class . '>' . esc_html( ucfirst( $status ) ) . '</span></p>'; echo '<span ' . $badge_class . '>' . esc_html( ucfirst( $status ) ) . '</span></p>'; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped -- badge_class is a hardcoded match expression
echo '<p><strong>' . esc_html__( 'Verification Notes', 'peptide-repo-core' ) . ':</strong><br />'; echo '<p><strong>' . esc_html__( 'Verification Notes', 'peptide-repo-core' ) . ':</strong><br />';
printf( printf(

View File

@@ -1,5 +1,7 @@
<?php <?php
/** /**
* Verification Widget.
*
* @package Peptide_Repo_Core * @package Peptide_Repo_Core
*/ */
@@ -106,7 +108,7 @@ class PR_Core_Verification_Widget {
esc_html( ucfirst( $item['status'] ) ), esc_html( ucfirst( $item['status'] ) ),
esc_html( ucfirst( $item['velocity'] ) ), esc_html( ucfirst( $item['velocity'] ) ),
esc_html( $item['last_verified'] ?? '—' ), esc_html( $item['last_verified'] ?? '—' ),
$item['days_since'], (int) $item['days_since'], // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped -- cast to int, safe
esc_url( $edit_url ) esc_url( $edit_url )
); );
} }

View File

@@ -1,5 +1,7 @@
<?php <?php
/** /**
* Rest Controller.
*
* @package Peptide_Repo_Core * @package Peptide_Repo_Core
*/ */
@@ -32,11 +34,7 @@ declare(strict_types=1);
*/ */
class PR_Core_Rest_Controller { class PR_Core_Rest_Controller {
/** /** @var string REST namespace. */
* REST namespace.
*
* @var string REST namespace.
*/
private const REST_NAMESPACE = 'pr-core/v1'; private const REST_NAMESPACE = 'pr-core/v1';
/** /**

View File

@@ -1,5 +1,7 @@
<?php <?php
/** /**
* Activator.
*
* @package Peptide_Repo_Core * @package Peptide_Repo_Core
*/ */

View File

@@ -1,5 +1,7 @@
<?php <?php
/** /**
* Autoloader.
*
* @package Peptide_Repo_Core * @package Peptide_Repo_Core
*/ */

View File

@@ -1,5 +1,7 @@
<?php <?php
/** /**
* Deactivator.
*
* @package Peptide_Repo_Core * @package Peptide_Repo_Core
*/ */

View File

@@ -1,5 +1,7 @@
<?php <?php
/** /**
* Seed Data.
*
* @package Peptide_Repo_Core * @package Peptide_Repo_Core
*/ */

View File

@@ -1,5 +1,7 @@
<?php <?php
/** /**
* Seed Fixtures.
*
* @package Peptide_Repo_Core * @package Peptide_Repo_Core
*/ */

View File

@@ -1,5 +1,7 @@
<?php <?php
/** /**
* Class Pr Core.
*
* @package Peptide_Repo_Core * @package Peptide_Repo_Core
*/ */

View File

@@ -1,5 +1,7 @@
<?php <?php
/** /**
* Internal Posts Provider.
*
* @package Peptide_Repo_Core * @package Peptide_Repo_Core
*/ */

View File

@@ -1,5 +1,7 @@
<?php <?php
/** /**
* Related Posts Provider.
*
* @package Peptide_Repo_Core * @package Peptide_Repo_Core
*/ */

View File

@@ -1,5 +1,7 @@
<?php <?php
/** /**
* Related Posts Section.
*
* @package Peptide_Repo_Core * @package Peptide_Repo_Core
*/ */

View File

@@ -1,5 +1,7 @@
<?php <?php
/** /**
* Peptide Cpt.
*
* @package Peptide_Repo_Core * @package Peptide_Repo_Core
*/ */

View File

@@ -1,5 +1,7 @@
<?php <?php
/** /**
* Peptide Meta Schema.
*
* @package Peptide_Repo_Core * @package Peptide_Repo_Core
*/ */

View File

@@ -1,5 +1,7 @@
<?php <?php
/** /**
* Repo Daily Cpt.
*
* @package Peptide_Repo_Core * @package Peptide_Repo_Core
*/ */

View File

@@ -1,5 +1,7 @@
<?php <?php
/** /**
* Schema Sanitizers.
*
* @package Peptide_Repo_Core * @package Peptide_Repo_Core
*/ */

View File

@@ -1,5 +1,7 @@
<?php <?php
/** /**
* Topic Taxonomy.
*
* @package Peptide_Repo_Core * @package Peptide_Repo_Core
*/ */

View File

@@ -1,5 +1,7 @@
<?php <?php
/** /**
* Verification Sanitizers.
*
* @package Peptide_Repo_Core * @package Peptide_Repo_Core
*/ */

View File

@@ -1,5 +1,7 @@
<?php <?php
/** /**
* Candidate Dto.
*
* @package Peptide_Repo_Core * @package Peptide_Repo_Core
*/ */

View File

@@ -1,5 +1,7 @@
<?php <?php
/** /**
* Dosing Row Dto.
*
* @package Peptide_Repo_Core * @package Peptide_Repo_Core
*/ */

View File

@@ -1,5 +1,7 @@
<?php <?php
/** /**
* Legal Cell Dto.
*
* @package Peptide_Repo_Core * @package Peptide_Repo_Core
*/ */

View File

@@ -1,5 +1,7 @@
<?php <?php
/** /**
* Peptide Dto.
*
* @package Peptide_Repo_Core * @package Peptide_Repo_Core
*/ */

View File

@@ -1,5 +1,7 @@
<?php <?php
/** /**
* Disclaimer.
*
* @package Peptide_Repo_Core * @package Peptide_Repo_Core
*/ */

View File

@@ -1,5 +1,7 @@
<?php <?php
/** /**
* Jsonld Drug.
*
* @package Peptide_Repo_Core * @package Peptide_Repo_Core
*/ */

View File

@@ -1,5 +1,7 @@
<?php <?php
/** /**
* Jsonld Faq.
*
* @package Peptide_Repo_Core * @package Peptide_Repo_Core
*/ */

View File

@@ -1,5 +1,7 @@
<?php <?php
/** /**
* Jsonld Webpage.
*
* @package Peptide_Repo_Core * @package Peptide_Repo_Core
*/ */

View File

@@ -1,5 +1,7 @@
<?php <?php
/** /**
* Jsonld.
*
* @package Peptide_Repo_Core * @package Peptide_Repo_Core
*/ */

View File

@@ -1,5 +1,7 @@
<?php <?php
/** /**
* Verification Display.
*
* @package Peptide_Repo_Core * @package Peptide_Repo_Core
*/ */

View File

@@ -1,5 +1,7 @@
<?php <?php
/** /**
* Related Posts Provider.
*
* @package Peptide_Repo_Core * @package Peptide_Repo_Core
*/ */

View File

@@ -1,5 +1,7 @@
<?php <?php
/** /**
* Migration 0001 Dosing Rows.
*
* @package Peptide_Repo_Core * @package Peptide_Repo_Core
*/ */

View File

@@ -1,5 +1,7 @@
<?php <?php
/** /**
* Migration 0002 Legal Cells.
*
* @package Peptide_Repo_Core * @package Peptide_Repo_Core
*/ */

View File

@@ -1,5 +1,7 @@
<?php <?php
/** /**
* Migration 0003 Candidate Queue.
*
* @package Peptide_Repo_Core * @package Peptide_Repo_Core
*/ */

View File

@@ -1,5 +1,9 @@
<?php <?php
/** @package Peptide_Repo_Core */ /**
* Migration 0004: Backfill peptide schema meta.
* @package Peptide_Repo_Core
*/
declare(strict_types=1); declare(strict_types=1);
/** /**
@@ -31,32 +35,16 @@ declare(strict_types=1);
*/ */
class PR_Core_Migration_0004_Backfill_Peptide_Meta { class PR_Core_Migration_0004_Backfill_Peptide_Meta {
/** /** @var string Meta key: molecular formula (PR Core namespace). */
* Meta key: molecular formula (PR Core namespace).
*
* @var string Meta key: molecular formula (PR Core namespace).
*/
public const META_FORMULA = '_pr_molecular_formula'; public const META_FORMULA = '_pr_molecular_formula';
/** /** @var string Meta key: molecular weight as float string (PR Core namespace). */
* Meta key: molecular weight as float string (PR Core namespace).
*
* @var string Meta key: molecular weight as float string (PR Core namespace).
*/
public const META_WEIGHT = '_pr_molecular_weight'; public const META_WEIGHT = '_pr_molecular_weight';
/** /** @var string Meta key: aliases JSON array (PR Core namespace). */
* Meta key: aliases JSON array (PR Core namespace).
*
* @var string Meta key: aliases JSON array (PR Core namespace).
*/
public const META_ALIASES = '_pr_aliases'; public const META_ALIASES = '_pr_aliases';
/** /** @var PR_Core_Pubchem_Client HTTP client for PubChem REST API. */
* HTTP client for PubChem REST API.
*
* @var PR_Core_Pubchem_Client HTTP client for PubChem REST API.
*/
private PR_Core_Pubchem_Client $pubchem; private PR_Core_Pubchem_Client $pubchem;
/** /**

View File

@@ -1,5 +1,7 @@
<?php <?php
/** /**
* Migration Runner.
*
* @package Peptide_Repo_Core * @package Peptide_Repo_Core
*/ */

View File

@@ -1,5 +1,7 @@
<?php <?php
/** /**
* Pubchem Client.
*
* @package Peptide_Repo_Core * @package Peptide_Repo_Core
*/ */

View File

@@ -1,5 +1,7 @@
<?php <?php
/** /**
* Candidate Queue Repository.
*
* @package Peptide_Repo_Core * @package Peptide_Repo_Core
*/ */

View File

@@ -1,5 +1,7 @@
<?php <?php
/** /**
* Dosing Repository.
*
* @package Peptide_Repo_Core * @package Peptide_Repo_Core
*/ */

View File

@@ -1,5 +1,7 @@
<?php <?php
/** /**
* Legal Repository.
*
* @package Peptide_Repo_Core * @package Peptide_Repo_Core
*/ */

View File

@@ -1,5 +1,7 @@
<?php <?php
/** /**
* Peptide Repository.
*
* @package Peptide_Repo_Core * @package Peptide_Repo_Core
*/ */

View File

@@ -1,5 +1,7 @@
<?php <?php
/** /**
* Verification Scanner.
*
* @package Peptide_Repo_Core * @package Peptide_Repo_Core
*/ */

View File

@@ -1,5 +1,7 @@
<?php <?php
/** /**
* Repo Daily Taxonomy.
*
* @package Peptide_Repo_Core * @package Peptide_Repo_Core
*/ */