Jake Vanderwerf
2026-02-04 2127b1bdd73ecd2423e443992da4b442f5a3c1a3
inc/managers/SEO/SchemaOutputManager.php
@@ -1,8 +1,8 @@
<?php
namespace JVBase\managers\SEO;
use JVBase\managers\CacheManager;
use JVBase\meta\MetaManager;
use JVBase\managers\Cache;
use JVBase\meta\Meta;
use WP_Term;
use WP_User;
@@ -16,14 +16,14 @@
 * Integrates with The SEO Framework, letting it handle defaults
 * while we override with our configured templates.
 *
 * Now with integrated caching via CacheManager for performance.
 * Now with integrated caching via Cache for performance.
 */
class SchemaOutputManager
{
   private ConfigManager $config;
   private SchemaBuilder $registry;
   private ?TemplateResolver $resolver = null;
   private CacheManager $cache;
   private Cache $cache;
   private array $pseudoTypes = [
      'BeforeAfter',
   ];
@@ -31,12 +31,10 @@
   public function __construct()
   {
      $this->registry = SchemaBuilder::getInstance();
      $this->cache = CacheManager::for('schema');
      // Register cache connections
      $this->cache->connectTo('post', 'id');
      $this->cache->connectTo('taxonomy', 'id');
      $this->cache->connectTo('user', 'id');
      $this->cache = Cache::for('schema')
         ->connect('post',true)
         ->connect('taxonomy',true)
         ->connect('user',true);
      // Hook into TSF for meta
      add_filter('the_seo_framework_title_from_generation', [$this, 'filterTitle'], 10, 2);
@@ -50,6 +48,69 @@
      // Output our schema
      add_action('wp_head', [$this, 'outputSchema'], 1);
      add_filter('the_seo_framework_sitemap_exclude_ids', [$this, 'excludeHiddenSingles'], 10, 1);
   }
   /**
    * Exclude posts from sitemap based on hide_single and is_timeline flags
    *
    * @param array $ids Array of post IDs to exclude
    * @return array Modified array with hidden posts added
    */
   public function excludeHiddenSingles(array $ids): array
   {
      $hiddenTypes = [];
      $timelineTypes = [];
      // Find post types with hide_single or is_timeline flags
      foreach (JVB_CONTENT as $slug => $config) {
         $postType = BASE . $slug;
         if (!empty($config['hide_single'])) {
            $hiddenTypes[] = $postType;
         }
         if (!empty($config['is_timeline'])) {
            $timelineTypes[] = $postType;
         }
      }
      $hiddenIds = [];
      // Get all posts from hide_single types
      if (!empty($hiddenTypes)) {
         $hiddenIds = $this->cache->remember(
            'hidden_single_posts',
            function() use ($hiddenTypes) {
               return get_posts([
                  'post_type' => $hiddenTypes,
                  'posts_per_page' => -1,
                  'fields' => 'ids',
                  'post_status' => 'publish',
               ]);
            }
         );
      }
      // Get child posts from timeline types
      if (!empty($timelineTypes)) {
         $timelineChildIds = $this->cache->remember(
            'timeline_child_posts',
            function() use ($timelineTypes) {
               return get_posts([
                  'post_type' => $timelineTypes,
                  'posts_per_page' => -1,
                  'fields' => 'ids',
                  'post_status' => 'publish',
                  'post_parent__not_in' => [0], // Only get posts with a parent
               ]);
            }
         );
         $hiddenIds = array_merge($hiddenIds, $timelineChildIds);
      }
      return array_merge($ids, $hiddenIds);
   }
   /**
@@ -459,7 +520,7 @@
   }
   /**
    * Enhanced buildSchemaFromConfig with MetaManager integration
    * Enhanced buildSchemaFromConfig with Meta integration
    */
   private function buildSchemaFromConfig(array $config, string $schemaType, ?string $id = null): ?array
   {
@@ -470,11 +531,11 @@
         $schema['@id'] = $id;
      }
      // Get MetaManager if we have a context
      // Get Meta if we have a context
      $meta = null;
      $context = $this->getCurrentContext();
      if ($context) {
         $meta = new MetaManager($context['objectId'], $context['objectType']);
         $meta = new Meta($context['objectId'], $context['objectType']);
      }
      // Process each field