Jake Vanderwerf
2026-09-04 32ce5c542c90be348895328078e392dde2052957
inc/managers/SEO/render/SchemaOutput.php
@@ -6,10 +6,18 @@
use JVBase\Instance;
use JVBase\managers\Cache;
use JVBase\managers\SEO\BreadcrumbManager;
use JVBase\managers\SEO\render\Thing\CreativeWork\Menu;
use JVBase\managers\SEO\render\Thing\CreativeWork\MenuSection;
use JVBase\managers\SEO\render\Thing\Intangible\MenuItem;
use JVBase\managers\SEO\render\Thing\Intangible\Offer;
use JVBase\managers\SEO\render\Thing\Intangible\Service;
use JVBase\managers\SEO\render\Thing\Organization\LocalBusiness\LocalBusiness;
use JVBase\managers\SEO\render\Thing\Thing;
use JVBase\meta\Meta;
use JVBase\registrar\config\seo\Resolver;
use JVBase\registrar\Registrar;
use WP_Query;
if (!defined('ABSPATH')) {
   exit;
}
@@ -30,12 +38,13 @@
      $registrar = false;
      if (is_front_page()) {
         $schema[] = $this->buildWebsiteSchema(true);
         $schema[] = $this->buildWebsiteSchema();
         $test = $this->buildOrganizationSchema();
         if (!empty($test)) {
            $schema[] = $test;
         }
      }
      if (is_singular($this->types)) {
         $type = get_post_type();
         $registrar = Registrar::getInstance($type);
@@ -66,6 +75,8 @@
//          error_log('SEO: '.print_r($seo->schema(), true));
            $schema[] = $seo->schema()->outputArchiveSchema();
         }
      } elseif (is_post_type_archive('product')) {
         $schema[] = $this->buildProductSchema();
      }
      $isContent = array_values(array_filter(array_map(function($item) {
         return intval(get_option(BASE.$item.'_archive', false));
@@ -144,7 +155,7 @@
      }
//    $encoded =  wp_json_encode($schema, JSON_UNESCAPED_SLASHES | JSON_PRETTY_PRINT);
//    $encoded =  wp_json_encode($schema, JSON_UNESCAPED_SLASHES | JSON_PRETTY_PRINT, 1024);
      $encoded = wp_json_encode($schema, JSON_UNESCAPED_SLASHES, 1024);
      $encoded = wp_json_encode($schema, JSON_UNESCAPED_SLASHES, 2048);
      if ($encoded === false) {
         error_log('wp_json_encode failed: ' . json_last_error_msg());
         return;
@@ -362,5 +373,113 @@
      $class = SchemaHelper::getInstance()::classFromConfig($config);
      return ($class)? $class->outputSchema() : [];
   }
   public function buildProductSchema():array
   {
      $sections = aneb_menu_sections();
      if (empty($sections)) {
         $sections = [];
      }
      $menuSections = [];
      foreach ($sections as $s) {
         if (empty($s['id'])) {
            continue;
         }
         $items = new WP_Query([
            'post_type'         => 'product',
            'order'             => 'ASC',
            'posts_per_page'    => -1,
            'post_status'       => 'publish',
            'tax_query'         => [
               [
                  'taxonomy'  => 'product_cat',
                  'terms'     => (int)$s['id']
               ]
            ],
            'fields'            => 'ids',
         ]);
         if (!$items->have_posts())  {
            continue;
         }
         $section = new MenuSection();
         $section->setName($s['name']);
         $section->setId(get_post_type_archive_link('product').'#'.sanitize_title($s['name']));
         if (!empty($s['description'])) {
            $section->setDescription($s['description']);
         }
         $menuItems = [];
         foreach ($items->posts as $ID) {
            $meta = Meta::forPost($ID);
            $fields = $meta->getAll();
            if (empty($fields['variations'])) {
               $item = $this->buildMenuItem($ID, $fields);
               if ($item) {
                  $menuItems[] = $item;
               }
            } else {
               foreach ($fields['variations'] as $variation) {
                  $item = $this->buildMenuItem($ID, $variation);
                  if ($item) {
                     $menuItems[] = $item;
                  }
               }
            }
         }
         if (!empty($menuItems)) {
            $section->setHasMenuItem($menuItems);
            $menuSections[] = $section;
         }
      }
      if (!empty($menuSections)) {
         $schema = new Menu();
         $schema->setName(get_bloginfo('name') . ' | Alberta\'s Best Food Truck Menu');
         $schema->setId(get_post_type_archive_link('product').'#menu');
         $schema->setDescription('Southern style barbeque with Northern flair from Meeting Creek, Alberta');
         $schema->setUrl(get_post_type_archive_link('product'));
         $schema->setHasMenuSection($menuSections);
         return $schema->outputSchema();
      }
      return [];
   }
      protected function buildMenuItem(int $ID, array $fields):MenuItem|false
      {
         $item = new MenuItem();
         $item->setUrl(get_the_permalink($ID));
         $base = get_post_type_archive_link('product').'#'.$ID.'-'.sanitize_title($fields['post_title']);
         $item->setId($base);
         $doit = false;
         if (!empty($fields['post_thumbnail']??'')) {
            $doit = true;
            $item->setImage(Thing::createImageFromID($fields['post_thumbnail']));
         }
         if (!empty($fields['post_excerpt']??'')) {
            $doit = true;
            $item->setDescription(wp_strip_all_tags($fields['post_excerpt']));
         }
         if (!empty($fields['price']??'')) {
            $doit = true;
            $offer = new Offer();
            $offer->setId($base.'-price');
            $offer->setPrice($fields['price']);
            $offer->setPriceCurrency('CAD');
            $item->setOffers($offer);
         }
         return $doit ? $item : false;
      }
}