Adopt reusable CI standard + PHPUnit conversion (#22)
Squash-merge of PR #22: adopt shared reusable CI workflow, convert PHPUnit to stubs, update branch-protection contexts.
QA-approved at 05d8094a1d. All required CI checks green.
Agent-Session: 2026-06-17-prcore-ci-deploy
This commit is contained in:
@@ -1,6 +1,18 @@
|
||||
<?php
|
||||
/**
|
||||
* Disclaimer.
|
||||
*
|
||||
* @package Peptide_Repo_Core
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
/**
|
||||
* Provides shortcode [pr_disclaimer surface="dosing"] and function
|
||||
*
|
||||
* @package Peptide_Repo_Core
|
||||
*/
|
||||
|
||||
/**
|
||||
* Shared disclaimer component for all peptide data surfaces.
|
||||
*
|
||||
@@ -17,10 +29,18 @@ declare(strict_types=1);
|
||||
*/
|
||||
class PR_Core_Disclaimer {
|
||||
|
||||
/** @var string Option key for disclaimer copy (JSON). */
|
||||
/**
|
||||
* Option key for disclaimer copy (JSON).
|
||||
*
|
||||
* @var string Option key for disclaimer copy (JSON).
|
||||
*/
|
||||
private const COPY_OPTION = 'pr_core_disclaimer_copy';
|
||||
|
||||
/** @var string Option key for disclaimer version. */
|
||||
/**
|
||||
* Option key for disclaimer version.
|
||||
*
|
||||
* @var string Option key for disclaimer version.
|
||||
*/
|
||||
private const VERSION_OPTION = 'pr_core_disclaimer_version';
|
||||
|
||||
/**
|
||||
@@ -28,13 +48,13 @@ class PR_Core_Disclaimer {
|
||||
*
|
||||
* @var array<string, string>
|
||||
*/
|
||||
private const DEFAULTS = [
|
||||
'dosing' => 'The dosing information presented here is compiled from published peer-reviewed literature and is provided for educational and research purposes only. It does not constitute medical advice, diagnosis, or treatment recommendations. Always consult a licensed healthcare professional before making any decisions based on this information.',
|
||||
'legal' => 'Legal status information is compiled from publicly available regulatory texts and is current as of the last-verified date shown. Regulatory frameworks change frequently. This information does not constitute legal advice. Verify current regulations with the relevant regulatory authority in your jurisdiction before taking any action.',
|
||||
'reconstitution' => 'This calculator is provided for educational purposes only. Always verify your calculations independently and consult a licensed healthcare professional. The results are based on the inputs you provide and standard reconstitution mathematics.',
|
||||
'ai-answer' => 'This response was generated by an AI system and may contain errors or omissions. All claims are grounded in the Peptide Repo corpus and cited sources where possible. This is not medical advice. Always verify information with primary sources and consult a licensed healthcare professional.',
|
||||
'general' => 'The information on this site is for educational and research purposes only. It is not intended as medical advice, diagnosis, or treatment. Always consult a licensed healthcare professional.',
|
||||
];
|
||||
private const DEFAULTS = array(
|
||||
'dosing' => 'The dosing information presented here is compiled from published peer-reviewed literature and is provided for educational and research purposes only. It does not constitute medical advice, diagnosis, or treatment recommendations. Always consult a licensed healthcare professional before making any decisions based on this information.',
|
||||
'legal' => 'Legal status information is compiled from publicly available regulatory texts and is current as of the last-verified date shown. Regulatory frameworks change frequently. This information does not constitute legal advice. Verify current regulations with the relevant regulatory authority in your jurisdiction before taking any action.',
|
||||
'reconstitution' => 'This calculator is provided for educational purposes only. Always verify your calculations independently and consult a licensed healthcare professional. The results are based on the inputs you provide and standard reconstitution mathematics.',
|
||||
'ai-answer' => 'This response was generated by an AI system and may contain errors or omissions. All claims are grounded in the Peptide Repo corpus and cited sources where possible. This is not medical advice. Always verify information with primary sources and consult a licensed healthcare professional.',
|
||||
'general' => 'The information on this site is for educational and research purposes only. It is not intended as medical advice, diagnosis, or treatment. Always consult a licensed healthcare professional.',
|
||||
);
|
||||
|
||||
/**
|
||||
* Register shortcode and any frontend hooks.
|
||||
@@ -42,7 +62,7 @@ class PR_Core_Disclaimer {
|
||||
* @return void
|
||||
*/
|
||||
public function register_hooks(): void {
|
||||
add_shortcode( 'pr_disclaimer', [ $this, 'shortcode_handler' ] );
|
||||
add_shortcode( 'pr_disclaimer', array( $this, 'shortcode_handler' ) );
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -52,7 +72,7 @@ class PR_Core_Disclaimer {
|
||||
* @return string Disclaimer HTML.
|
||||
*/
|
||||
public function shortcode_handler( $atts ): string {
|
||||
$atts = shortcode_atts( [ 'surface' => 'general' ], $atts, 'pr_disclaimer' );
|
||||
$atts = shortcode_atts( array( 'surface' => 'general' ), $atts, 'pr_disclaimer' );
|
||||
return self::render( sanitize_text_field( $atts['surface'] ) );
|
||||
}
|
||||
|
||||
@@ -81,7 +101,7 @@ class PR_Core_Disclaimer {
|
||||
*/
|
||||
public static function get_disclaimer_text( string $surface ): string {
|
||||
$custom = get_option( self::COPY_OPTION, '{}' );
|
||||
$copy = json_decode( $custom, true ) ?: [];
|
||||
$copy = json_decode( $custom, true ) ?: array(); // phpcs:ignore Universal.Operators.DisallowShortTernary.Found
|
||||
|
||||
if ( ! empty( $copy[ $surface ] ) ) {
|
||||
return (string) $copy[ $surface ];
|
||||
@@ -110,7 +130,7 @@ class PR_Core_Disclaimer {
|
||||
*/
|
||||
public static function update_disclaimer( string $surface, string $text ): void {
|
||||
$custom = get_option( self::COPY_OPTION, '{}' );
|
||||
$copy = json_decode( $custom, true ) ?: [];
|
||||
$copy = json_decode( $custom, true ) ?: array(); // phpcs:ignore Universal.Operators.DisallowShortTernary.Found
|
||||
|
||||
$copy[ sanitize_text_field( $surface ) ] = sanitize_textarea_field( $text );
|
||||
|
||||
|
||||
@@ -1,6 +1,18 @@
|
||||
<?php
|
||||
/**
|
||||
* Jsonld Drug.
|
||||
*
|
||||
* @package Peptide_Repo_Core
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
/**
|
||||
* Assembles a Drug (+ MolecularEntity) schema node from peptide DTO
|
||||
*
|
||||
* @package Peptide_Repo_Core
|
||||
*/
|
||||
|
||||
/**
|
||||
* Builds the schema.org Drug graph piece for a peptide page.
|
||||
*
|
||||
@@ -17,17 +29,33 @@ declare(strict_types=1);
|
||||
*/
|
||||
class PR_Core_Jsonld_Drug {
|
||||
|
||||
/** @var string Meta key: molecular formula sourced by migration 0004. */
|
||||
private const META_FORMULA = '_pr_molecular_formula';
|
||||
/**
|
||||
* Meta key: molecular formula sourced by migration 0004.
|
||||
*
|
||||
* @var string Meta key: molecular formula sourced by migration 0004.
|
||||
*/
|
||||
private const META_FORMULA = '_pr_molecular_formula';
|
||||
|
||||
/** @var string Meta key: molecular weight (float string) sourced by migration 0004. */
|
||||
private const META_WEIGHT = '_pr_molecular_weight';
|
||||
/**
|
||||
* Meta key: molecular weight (float string) sourced by migration 0004.
|
||||
*
|
||||
* @var string Meta key: molecular weight (float string) sourced by migration 0004.
|
||||
*/
|
||||
private const META_WEIGHT = '_pr_molecular_weight';
|
||||
|
||||
/** @var string Meta key: aliases JSON array sourced by migration 0004. */
|
||||
private const META_ALIASES = '_pr_aliases';
|
||||
/**
|
||||
* Meta key: aliases JSON array sourced by migration 0004.
|
||||
*
|
||||
* @var string Meta key: aliases JSON array sourced by migration 0004.
|
||||
*/
|
||||
private const META_ALIASES = '_pr_aliases';
|
||||
|
||||
/** @var string Unit text for molecularWeight QuantitativeValue. */
|
||||
private const UNIT_TEXT = 'g/mol';
|
||||
/**
|
||||
* Unit text for molecularWeight QuantitativeValue.
|
||||
*
|
||||
* @var string Unit text for molecularWeight QuantitativeValue.
|
||||
*/
|
||||
private const UNIT_TEXT = 'g/mol';
|
||||
|
||||
/**
|
||||
* Build a schema.org Drug piece array for a peptide.
|
||||
@@ -38,12 +66,12 @@ class PR_Core_Jsonld_Drug {
|
||||
public function build( PR_Core_Peptide_DTO $peptide ): array {
|
||||
$permalink = get_permalink( $peptide->id );
|
||||
|
||||
$node = [
|
||||
'@type' => [ 'Drug', 'MolecularEntity' ],
|
||||
$node = array(
|
||||
'@type' => array( 'Drug', 'MolecularEntity' ),
|
||||
'@id' => $permalink . '#drug',
|
||||
'name' => $peptide->display_name ?: $peptide->title,
|
||||
'name' => $peptide->display_name ?: $peptide->title, // phpcs:ignore Universal.Operators.DisallowShortTernary.Found
|
||||
'url' => $permalink,
|
||||
];
|
||||
);
|
||||
|
||||
if ( '' !== $peptide->excerpt ) {
|
||||
$node['description'] = $peptide->excerpt;
|
||||
@@ -64,11 +92,11 @@ class PR_Core_Jsonld_Drug {
|
||||
// molecularWeight: prefer _pr_molecular_weight, fall back to DTO field.
|
||||
$weight = $this->get_weight( $peptide );
|
||||
if ( $weight > 0.0 ) {
|
||||
$node['molecularWeight'] = [
|
||||
$node['molecularWeight'] = array(
|
||||
'@type' => 'QuantitativeValue',
|
||||
'value' => $weight,
|
||||
'unitText' => self::UNIT_TEXT,
|
||||
];
|
||||
);
|
||||
}
|
||||
|
||||
// External identifiers: CAS and DrugBank omitted in v0.6.0 (no source).
|
||||
@@ -150,9 +178,9 @@ class PR_Core_Jsonld_Drug {
|
||||
* @return array<string, string>|null
|
||||
*/
|
||||
private function build_legal_status(): ?array {
|
||||
return [
|
||||
return array(
|
||||
'@type' => 'DrugLegalStatus',
|
||||
'description' => esc_html__( 'Not approved for human therapeutic use; supplied for laboratory research purposes only.', 'peptide-repo-core' ),
|
||||
];
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,6 +1,18 @@
|
||||
<?php
|
||||
/**
|
||||
* Jsonld Faq.
|
||||
*
|
||||
* @package Peptide_Repo_Core
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
/**
|
||||
* Reads _pr_faq_items post-meta (JSON array of {question, answer} objects)
|
||||
*
|
||||
* @package Peptide_Repo_Core
|
||||
*/
|
||||
|
||||
/**
|
||||
* Builds the schema.org FAQPage graph piece for a peptide page.
|
||||
*
|
||||
@@ -17,7 +29,11 @@ declare(strict_types=1);
|
||||
*/
|
||||
class PR_Core_Jsonld_Faq {
|
||||
|
||||
/** @var string Meta key holding the FAQ items JSON array. */
|
||||
/**
|
||||
* Meta key holding the FAQ items JSON array.
|
||||
*
|
||||
* @var string Meta key holding the FAQ items JSON array.
|
||||
*/
|
||||
public const META_FAQ_ITEMS = '_pr_faq_items';
|
||||
|
||||
/**
|
||||
@@ -34,11 +50,11 @@ class PR_Core_Jsonld_Faq {
|
||||
return null;
|
||||
}
|
||||
|
||||
return [
|
||||
return array(
|
||||
'@type' => 'FAQPage',
|
||||
'@id' => $permalink . '#faq',
|
||||
'mainEntity' => array_map( [ $this, 'build_question' ], $items ),
|
||||
];
|
||||
'mainEntity' => array_map( array( $this, 'build_question' ), $items ),
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -48,14 +64,14 @@ class PR_Core_Jsonld_Faq {
|
||||
* @return array<string, mixed> Schema.org Question node.
|
||||
*/
|
||||
private function build_question( array $item ): array {
|
||||
return [
|
||||
'@type' => 'Question',
|
||||
'name' => esc_html( $item['question'] ),
|
||||
'acceptedAnswer' => [
|
||||
return array(
|
||||
'@type' => 'Question',
|
||||
'name' => esc_html( $item['question'] ),
|
||||
'acceptedAnswer' => array(
|
||||
'@type' => 'Answer',
|
||||
'text' => esc_html( $item['answer'] ),
|
||||
],
|
||||
];
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -71,16 +87,16 @@ class PR_Core_Jsonld_Faq {
|
||||
$raw = get_post_meta( $post_id, self::META_FAQ_ITEMS, true );
|
||||
|
||||
if ( ! is_string( $raw ) || '' === $raw ) {
|
||||
return [];
|
||||
return array();
|
||||
}
|
||||
|
||||
$decoded = json_decode( $raw, true );
|
||||
|
||||
if ( ! is_array( $decoded ) || empty( $decoded ) ) {
|
||||
return [];
|
||||
return array();
|
||||
}
|
||||
|
||||
$valid = [];
|
||||
$valid = array();
|
||||
foreach ( $decoded as $item ) {
|
||||
if ( ! is_array( $item ) ) {
|
||||
continue;
|
||||
@@ -88,10 +104,10 @@ class PR_Core_Jsonld_Faq {
|
||||
$question = sanitize_text_field( (string) ( $item['question'] ?? '' ) );
|
||||
$answer = sanitize_textarea_field( (string) ( $item['answer'] ?? '' ) );
|
||||
if ( '' !== $question && '' !== $answer ) {
|
||||
$valid[] = [
|
||||
$valid[] = array(
|
||||
'question' => $question,
|
||||
'answer' => $answer,
|
||||
];
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,6 +1,18 @@
|
||||
<?php
|
||||
/**
|
||||
* Jsonld Webpage.
|
||||
*
|
||||
* @package Peptide_Repo_Core
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
/**
|
||||
* Hooks into Yoast's wpseo_schema_webpage_type filter to retype the page
|
||||
*
|
||||
* @package Peptide_Repo_Core
|
||||
*/
|
||||
|
||||
/**
|
||||
* Enriches Yoast's WebPage node to MedicalWebPage for peptide single pages.
|
||||
*
|
||||
@@ -16,10 +28,18 @@ declare(strict_types=1);
|
||||
*/
|
||||
class PR_Core_Jsonld_Webpage {
|
||||
|
||||
/** @var string Meta key for last editorial review date (ISO date string). */
|
||||
/**
|
||||
* Meta key for last editorial review date (ISO date string).
|
||||
*
|
||||
* @var string Meta key for last editorial review date (ISO date string).
|
||||
*/
|
||||
private const META_LAST_REVIEWED = '_pr_last_reviewed';
|
||||
|
||||
/** @var string Meta key for last source verification date (ISO date string). */
|
||||
/**
|
||||
* Meta key for last source verification date (ISO date string).
|
||||
*
|
||||
* @var string Meta key for last source verification date (ISO date string).
|
||||
*/
|
||||
private const META_LAST_VERIFIED = '_pr_last_source_verified';
|
||||
|
||||
/**
|
||||
@@ -77,7 +97,7 @@ class PR_Core_Jsonld_Webpage {
|
||||
// Yoast may set @type as a plain string OR an array of strings.
|
||||
// Normalise to array so in_array() works regardless of shape.
|
||||
$raw_type = $piece['@type'] ?? '';
|
||||
$types = is_array( $raw_type ) ? $raw_type : [ $raw_type ];
|
||||
$types = is_array( $raw_type ) ? $raw_type : array( $raw_type );
|
||||
|
||||
if ( in_array( 'WebPage', $types, true ) || in_array( 'MedicalWebPage', $types, true ) ) {
|
||||
foreach ( $enrichments as $key => $value ) {
|
||||
@@ -97,16 +117,16 @@ class PR_Core_Jsonld_Webpage {
|
||||
* @return array<string, mixed> Enrichment fields to merge into the WebPage node.
|
||||
*/
|
||||
private function build_webpage_enrichments( int $post_id ): array {
|
||||
$enrichments = [];
|
||||
$enrichments = array();
|
||||
|
||||
// lastReviewed: prefer _pr_last_reviewed, fall back to _pr_last_source_verified,
|
||||
// lastReviewed: prefer _pr_last_reviewed, fall back to _pr_last_source_verified,.
|
||||
// then post modified date.
|
||||
$last_reviewed = (string) get_post_meta( $post_id, self::META_LAST_REVIEWED, true );
|
||||
if ( '' === $last_reviewed ) {
|
||||
$last_reviewed = (string) get_post_meta( $post_id, self::META_LAST_VERIFIED, true );
|
||||
}
|
||||
if ( '' === $last_reviewed ) {
|
||||
$last_reviewed = get_post_modified_time( 'Y-m-d', false, $post_id ) ?: '';
|
||||
$last_reviewed = get_post_modified_time( 'Y-m-d', false, $post_id ) ?: ''; // phpcs:ignore Universal.Operators.DisallowShortTernary.Found
|
||||
}
|
||||
|
||||
if ( '' !== $last_reviewed ) {
|
||||
@@ -118,27 +138,27 @@ class PR_Core_Jsonld_Webpage {
|
||||
if ( $editor_id > 0 ) {
|
||||
$editor = get_userdata( $editor_id );
|
||||
if ( $editor ) {
|
||||
$enrichments['reviewedBy'] = [
|
||||
$enrichments['reviewedBy'] = array(
|
||||
'@type' => 'Person',
|
||||
'name' => sanitize_text_field( $editor->display_name ),
|
||||
'url' => get_author_posts_url( $editor_id ),
|
||||
];
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
if ( ! isset( $enrichments['reviewedBy'] ) ) {
|
||||
$enrichments['reviewedBy'] = [
|
||||
$enrichments['reviewedBy'] = array(
|
||||
'@type' => 'Organization',
|
||||
'name' => 'Peptide Repo',
|
||||
'url' => home_url(),
|
||||
];
|
||||
);
|
||||
}
|
||||
|
||||
// audience: MedicalAudience for researchers.
|
||||
$enrichments['audience'] = [
|
||||
$enrichments['audience'] = array(
|
||||
'@type' => 'MedicalAudience',
|
||||
'audienceType' => 'Researcher',
|
||||
];
|
||||
);
|
||||
|
||||
return $enrichments;
|
||||
}
|
||||
|
||||
@@ -1,11 +1,24 @@
|
||||
<?php
|
||||
/**
|
||||
* Jsonld.
|
||||
*
|
||||
* @package Peptide_Repo_Core
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
/**
|
||||
* Integrates Drug, MedicalWebPage, and FAQPage schema into Yoast's graph
|
||||
*
|
||||
* @package Peptide_Repo_Core
|
||||
*/
|
||||
|
||||
/**
|
||||
* JSON-LD / schema.org structured data emission for peptide pages.
|
||||
*
|
||||
* What: Integrates Drug, MedicalWebPage, and FAQPage schema into Yoast's graph
|
||||
* on single peptide pages. When Yoast is inactive, emits a standalone
|
||||
*
|
||||
* @graph block via wp_head as a fallback.
|
||||
*
|
||||
* Who calls it: PR_Core::init() calls register_hooks(). Yoast hooks fire on
|
||||
@@ -34,13 +47,25 @@ declare(strict_types=1);
|
||||
*/
|
||||
class PR_Core_Jsonld {
|
||||
|
||||
/** @var PR_Core_Jsonld_Drug Drug piece builder. */
|
||||
/**
|
||||
* Drug piece builder.
|
||||
*
|
||||
* @var PR_Core_Jsonld_Drug Drug piece builder.
|
||||
*/
|
||||
private PR_Core_Jsonld_Drug $drug_builder;
|
||||
|
||||
/** @var PR_Core_Jsonld_Webpage MedicalWebPage enricher. */
|
||||
/**
|
||||
* MedicalWebPage enricher.
|
||||
*
|
||||
* @var PR_Core_Jsonld_Webpage MedicalWebPage enricher.
|
||||
*/
|
||||
private PR_Core_Jsonld_Webpage $webpage_enricher;
|
||||
|
||||
/** @var PR_Core_Jsonld_Faq FAQ piece builder. */
|
||||
/**
|
||||
* FAQ piece builder.
|
||||
*
|
||||
* @var PR_Core_Jsonld_Faq FAQ piece builder.
|
||||
*/
|
||||
private PR_Core_Jsonld_Faq $faq_builder;
|
||||
|
||||
/**
|
||||
@@ -67,19 +92,19 @@ class PR_Core_Jsonld {
|
||||
*/
|
||||
public function register_hooks(): void {
|
||||
// wpseo_schema_webpage_type: retype WebPage -> MedicalWebPage on peptide singles.
|
||||
add_filter( 'wpseo_schema_webpage_type', [ $this->webpage_enricher, 'retype_to_medical_webpage' ] );
|
||||
add_filter( 'wpseo_schema_webpage_type', array( $this->webpage_enricher, 'retype_to_medical_webpage' ) );
|
||||
|
||||
// wpseo_schema_graph: two callbacks at different priorities.
|
||||
// Priority 11 -- enrich_webpage_piece: merge lastReviewed/reviewedBy/audience into the
|
||||
// existing WebPage node that Yoast already emitted.
|
||||
// Priority 11 -- enrich_webpage_piece: merge lastReviewed/reviewedBy/audience into the.
|
||||
// existing WebPage node that Yoast already emitted.
|
||||
// Priority 12 -- inject_graph_nodes: append Drug + FAQPage arrays to the graph.
|
||||
// Must run after enrich_webpage_piece so the WebPage node is already
|
||||
// enriched before Drug/FAQ are appended.
|
||||
add_filter( 'wpseo_schema_graph', [ $this->webpage_enricher, 'enrich_webpage_piece' ], 11, 2 );
|
||||
add_filter( 'wpseo_schema_graph', [ $this, 'inject_graph_nodes' ], 12, 2 );
|
||||
// Must run after enrich_webpage_piece so the WebPage node is already.
|
||||
// enriched before Drug/FAQ are appended.
|
||||
add_filter( 'wpseo_schema_graph', array( $this->webpage_enricher, 'enrich_webpage_piece' ), 11, 2 );
|
||||
add_filter( 'wpseo_schema_graph', array( $this, 'inject_graph_nodes' ), 12, 2 );
|
||||
|
||||
// Standalone fallback: emits only when Yoast is not producing output.
|
||||
add_action( 'wp_head', [ $this, 'emit_standalone_fallback' ], 99 );
|
||||
add_action( 'wp_head', array( $this, 'emit_standalone_fallback' ), 99 );
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -90,8 +115,8 @@ class PR_Core_Jsonld {
|
||||
* Appending plain Drug/FAQ arrays here is safe -- unlike wpseo_schema_graph_pieces
|
||||
* which calls get_class() and is_needed() on each item expecting objects.
|
||||
*
|
||||
* @param array<int, array<string, mixed>> $graph Assembled Yoast graph.
|
||||
* @param \Yoast\WP\SEO\Context\Meta_Tags_Context|null $context Yoast schema context.
|
||||
* @param array<int, array<string, mixed>> $graph Assembled Yoast graph.
|
||||
* @param \Yoast\WP\SEO\Context\Meta_Tags_Context|null $context Yoast schema context.
|
||||
* @return array<int, array<string, mixed>> Graph with Drug (and optionally FAQ) appended.
|
||||
*/
|
||||
public function inject_graph_nodes( array $graph, $context ): array {
|
||||
@@ -150,7 +175,7 @@ class PR_Core_Jsonld {
|
||||
}
|
||||
|
||||
$permalink = get_permalink( (int) $post_id );
|
||||
$graph = [ $this->drug_builder->build( $peptide ) ];
|
||||
$graph = array( $this->drug_builder->build( $peptide ) );
|
||||
|
||||
$faq_node = $this->faq_builder->build( (int) $post_id, $permalink );
|
||||
if ( null !== $faq_node ) {
|
||||
@@ -160,7 +185,10 @@ class PR_Core_Jsonld {
|
||||
printf(
|
||||
'<script type="application/ld+json">%s</script>' . "\n",
|
||||
wp_json_encode(
|
||||
[ '@context' => 'https://schema.org', '@graph' => $graph ],
|
||||
array(
|
||||
'@context' => 'https://schema.org',
|
||||
'@graph' => $graph,
|
||||
),
|
||||
JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE | JSON_PRETTY_PRINT
|
||||
)
|
||||
);
|
||||
|
||||
@@ -1,6 +1,18 @@
|
||||
<?php
|
||||
/**
|
||||
* Verification Display.
|
||||
*
|
||||
* @package Peptide_Repo_Core
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
/**
|
||||
* Appends last-verified date after verdict card on reader-facing pages
|
||||
*
|
||||
* @package Peptide_Repo_Core
|
||||
*/
|
||||
|
||||
/**
|
||||
* Frontend verification date display on peptide single pages.
|
||||
*
|
||||
@@ -20,7 +32,7 @@ class PR_Core_Verification_Display {
|
||||
* @return void
|
||||
*/
|
||||
public static function init(): void {
|
||||
add_filter( 'the_content', [ __CLASS__, 'append_verification_display' ], 20 );
|
||||
add_filter( 'the_content', array( __CLASS__, 'append_verification_display' ), 20 );
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -63,10 +75,10 @@ class PR_Core_Verification_Display {
|
||||
* @return string HTML block.
|
||||
*/
|
||||
private static function render_verification_block( string $last_verified ): string {
|
||||
$date_obj = new \DateTime( $last_verified );
|
||||
$date_obj = new \DateTime( $last_verified );
|
||||
$formatted_date = $date_obj->format( get_option( 'date_format' ) );
|
||||
|
||||
$html = '<p class="pr-verification-date">';
|
||||
$html = '<p class="pr-verification-date">';
|
||||
$html .= esc_html__( 'Last verified: ', 'peptide-repo-core' );
|
||||
$html .= sprintf(
|
||||
'<time datetime="%s">%s</time>',
|
||||
|
||||
Reference in New Issue
Block a user