From 275c0d74cd68677622a5431505c5c870c473063d Mon Sep 17 00:00:00 2001
From: Jake Vanderwerf <get@jakevanderwerf.ca>
Date: Sun, 29 Mar 2026 21:40:15 +0000
Subject: [PATCH] =Seems to be working, huzzah! Added some changes for on-this-page nav
---
base/seo.php | 320 +++++++++++++++++++++++++++++++++++++++++++++++------
1 files changed, 282 insertions(+), 38 deletions(-)
diff --git a/base/seo.php b/base/seo.php
index bd248f9..79c66d8 100644
--- a/base/seo.php
+++ b/base/seo.php
@@ -1,4 +1,286 @@
<?php
+namespace JVBase\base;
+use JVBase\meta\Meta;
+use JVBase\registrar\config\seo\Resolver;
+use JVBase\registrar\Registrar;
+
+class SchemaHelper
+{
+ protected static array $allowedTypes;
+ protected static array $allowedFormats = ['schema', 'archive', 'meta', 'reference'];
+ protected static array $schemas = [];
+ protected static array $metas = [];
+ protected static array $archives = [];
+ protected static array $references = [];
+ public function __construct()
+ {
+ self::$allowedTypes = array_merge(['website', 'organization'], Registrar::getRegistered());
+ }
+ public static function checkType(string $type, string $reference = '[SchemaHelper] Invalid type'):string|false
+ {
+ $type = strtolower($type);
+ if (!in_array($type, self::$allowedTypes)) {
+ error_log($reference.': '.$type);
+ return false;
+ }
+ return $type;
+ }
+ public static function checkFormat(string $format, string $reference = '[SchemaHelper] Invalid format'):string|false
+ {
+ $format = strtolower($format);
+ if (!in_array($format, self::$allowedFormats)) {
+ error_log($reference.': '.$format);
+ return false;
+ }
+ return $format;
+ }
+ public static function getConfig(string $type, string $format):array
+ {
+ $reference = '[SchemaHelper]::getConfig';
+ $type = self::checkType($type, $reference);
+ $format = self::checkFormat($format, $reference);
+ if (!$type || !$format) {
+ return [];
+ }
+ return match($format) {
+ 'schema' => self::schema($type),
+ 'archive' => self::archive($type),
+ 'meta' => self::meta($type),
+ 'reference' => self::reference($type),
+ };
+ }
+ public static function schema(string $type): array
+ {
+ $type = self::checkType($type, '[SchemaHelper]::schema');
+ if (!$type) {
+ return [];
+ }
+
+ if (!array_key_exists($type, self::$schemas)) {
+ self::$schemas[$type] = get_option(BASE.ucfirst($type).'Schema', self::getDefault($type, 'schema'));
+ }
+ return self::$schemas[$type];
+ }
+ public static function meta(string $type): array
+ {
+ $type = self::checkType($type, '[SchemaHelper]::meta');
+ if (!$type) {
+ return [];
+ }
+ if (!array_key_exists($type, self::$metas)) {
+ self::$metas[$type] = get_option(BASE.ucfirst($type).'Meta', self::getDefault($type, 'meta'));
+ }
+ return self::$metas[$type];
+ }
+ public static function archive(string $type): array
+ {
+ $type = self::checkType($type, '[SchemaHelper]::archive');
+ error_log('[SchemaHelper]::archive type: '.print_r($type, true));
+ if (!$type) {
+ return [];
+ }
+
+ if (!array_key_exists($type, self::$archives)) {
+ self::$archives[$type] = get_option(BASE.ucfirst($type).'Archive', self::getDefault($type, 'archive'));
+ }
+ return self::$archives[$type];
+ }
+ public static function reference(string $type): array
+ {
+ $type = self::checkType($type, '[SchemaHelper]::reference');
+ if (!$type) {
+ return [];
+ }
+ if (!array_key_exists($type, self::$references)) {
+ self::$references[$type] = get_option(BASE.ucfirst($type).'Reference', self::getDefault($type, 'reference'));
+ }
+ return self::$references[$type];
+ }
+
+ public static function getDefault(string $type, string $format):array
+ {
+ $reference = '[SchemaHelper]::getDefault';
+ $type = self::checkType($type, $reference);
+ $format = self::checkFormat($format, $reference);
+ if (!$type || !$format) {
+ return [];
+ }
+
+ $defaults = match ($format) {
+ 'schema' => match ($type) {
+ 'website' => [
+ 'type' => 'JVBase\managers\SEO\render\Thing\CreativeWork\WebSite',
+ 'name' => get_bloginfo('name'),
+ 'url' => get_home_url(),
+ 'id' => get_home_url() . '#website',
+ 'description' => get_bloginfo('description'),
+ 'inLanguage' => 'en-CA'
+ ],
+ default => []
+ },
+ 'archive' => [
+ 'type' => 'JVBase\managers\SEO\render\Thing\CreativeWork\WebPage\CollectionPage',
+ ],
+ default => [],
+ };
+ return apply_filters(BASE.ucfirst($type).ucfirst($format).'Default', $defaults);
+ }
+
+ public static function updateHistory(string $type, string $format, array $newest):bool
+ {
+ $reference = '[SchemaHelper]::updateHistory';
+ $type = self::checkType($type, $reference);
+ $format = self::checkFormat($format, $reference);
+ if (!$type || !$format) {
+ return false;
+ }
+
+ $historyOption = BASE.ucfirst($type).ucfirst($format).'History';
+ $history = get_option($historyOption, []);
+ array_unshift($history, $newest);
+ if (count($history) > 5) {
+ array_pop($history);
+ }
+ return update_option($historyOption, $history);
+ }
+
+ public static function update(string $type, string $format, array $config, ?Meta $meta = null):bool
+ {
+ $reference = '[SchemaHelper]::update';
+ $type = self::checkType($type, $reference);
+ $format = self::checkFormat($format, $reference);
+ if (!$type || !$format) {
+ return false;
+ }
+ $method = 'update'.ucfirst($type);
+ return self::$method($config, $meta);
+ }
+ public static function updateSchema(string $type, array $config):bool
+ {
+ $reference = '[SchemaHelper]::updateSchema';
+ $type = self::checkType($type, $reference);
+ if (!$type) {
+ return false;
+ }
+ if (!class_exists($config['type'])){
+ error_log('[SchemaHelper]::updateSchema Config must be a valid schema type: '.$config['type']);
+ return false;
+ }
+ if (!in_array($type, self::$allowedTypes)) {
+ error_log('[SchemaHelper]::updateSchema Config must have a schema type');
+ }
+
+ return self::updateClassConfig($type, 'schema', $config);
+ }
+
+ public static function updateClassConfig(string $type, string $format, array $config):bool
+ {
+ $reference = '[SchemaHelper]::updateClassConfig';
+ $type = self::checkType($type, $reference);
+ if (!$type) {
+ return false;
+ }
+ if (!class_exists($config['type'])){
+ error_log($reference.' Config must be a valid schema type: '.$config['type']);
+ return false;
+ }
+ if (!in_array($type, self::$allowedTypes)) {
+ error_log($reference.' Config must have a schema type');
+ }
+ //Merge stored config with updates
+ $stored = self::schema($type);
+ $update = array_merge_recursive($stored, $config);
+
+ //Validate Properties
+ $className = $update['type'];
+ unset($update['type']);
+ foreach ($update as $property => $value) {
+ if (!property_exists($className, $property)) {
+ error_log($reference.' invalid property attempted: '.$property.', with value: '.print_r($value, true).' for class: '.$className);
+ unset($update[$property]);
+ }
+ }
+ $update['type'] = $className;
+
+ //Add changes to history (keeps last 5 changes)
+ self::updateHistory($type, $format, $update);
+ self::$schemas[$type] = $update;
+ return update_option(BASE.ucfirst($type).ucfirst($format), $update);
+ }
+
+ public static function updateMeta(string $type, array $config):bool
+ {
+ $type = self::checkType($type, '[SchemaHelper]::updateMeta');
+ $allowed = array_filter($config, function($key) {
+ $allowed = in_array($key, ['name', 'description']);
+ if (!$allowed) {
+ error_log('[SchemaHelper]::updateMeta invalid property attempted: '.$key);
+ }
+ return $allowed;
+ });
+ if (empty($allowed)) {
+ error_log('[SchemaHelper]::updateMeta Name or Description must be set');
+ return false;
+ }
+ $config = array_map('sanitize_text_field', $config);
+ self::updateHistory($type, 'meta', $config);
+ self::$metas[$type] = $config;
+ return update_option(BASE.ucfirst($type).'Meta', $config);
+ }
+
+ public static function updateArchive(string $type, array $config):bool
+ {
+ $reference = '[SchemaHelper]::updateArchive';
+ $type = self::checkType($type, $reference);
+ if (!$type) {
+ return false;
+ }
+ if (!class_exists($config['type'])){
+ error_log('[SchemaHelper]::updateSchema Config must be a valid schema type: '.$config['type']);
+ return false;
+ }
+ if (!in_array($type, self::$allowedTypes)) {
+ error_log('[SchemaHelper]::updateSchema Config must have a schema type');
+ }
+
+ return self::updateClassConfig($type, 'schema', $config);
+ }
+
+ public static function classFromConfig(array $config, ?Meta $meta = null):mixed
+ {
+ if (!array_key_exists('type', $config)) {
+ error_log('[SchemaHelper]::classFromConfig No class defined in config: '.print_r($config, true));
+ return false;
+ }
+ $className = $config['type'];
+ unset($config['type']);
+ $class = new $className();
+
+ foreach ($config as $property => $value) {
+ if (is_array($value)) {
+ $value = self::classFromConfig($value, $meta);
+ }
+ $method = 'set'.ucfirst($property);
+ if (!method_exists($class, $method)) {
+ error_log('[SchemaHelper]::classFromConfig - method: '.$method.' does not exist in class: '.$className);
+ continue;
+ }
+ if (is_string($value) && str_contains($value, '{{')) {
+ $value = Resolver::resolveForSchema($property, $value, $config, $meta);
+ }
+ if (!empty($value)) {
+ $class->$method($value);
+ }
+ }
+ return $class;
+ }
+}
+
+
+
+
+
+
/**
* JVB_SCHEMA: Site-wide schema configuration
*
@@ -9,44 +291,6 @@
* - attribution: Developer/maintainer info
*/
-use JVBase\managers\SEO\SchemaBuilder;
-
-$schema = apply_filters('jvb_schema', []);
-$registry = SchemaBuilder::getInstance();
-$checked = [];
-foreach ($schema as $key => $config) {
-
- if (array_key_exists('type', $config)) {
- $type = $config['type'];
- } elseif ($key === 'website') {
- $type = 'WebSite';
- }
- $exists = !is_null($registry->getTypeDefinition($type));
- if (!$exists) {
-// error_log('[JVB_SCHEMA] No definitions for: '.print_r($type, true));
- continue;
- }
- $allowed = $registry->getFieldsForType($type);
- $filtered = array_filter($config, function ($item) use ($allowed) {
- return in_array($item, $allowed);
- }, ARRAY_FILTER_USE_KEY);
-
- if (empty($filtered)) {
-// error_log('[JVB_SCHEMA] No valid filters for '.$type.'.');
- continue;
- }
- $removed = array_filter($config, function ($item) use ($allowed) {
- return !in_array($item, $allowed);
- }, ARRAY_FILTER_USE_KEY);
-
- if (!empty($removed)) {
-// error_log('[JVB_SCHEMA] Invalid fields detected for '.$type.': '.print_r($removed, true));
- }
- $checked[$key] = $filtered;
-}
-
-define('JVB_SCHEMA', $checked);
-
/**
JVB_CONTENT['artwork'] = [
--
Gitblit v1.10.0