Jake Vanderwerf
2026-08-29 f859e64a57c624ff2daa2b21355f65a49fd4807d
inc/blocks/MenuBlock.php
@@ -4,11 +4,10 @@
use JVBase\base\Options;
use JVBase\base\Site;
use JVBase\managers\Cache;
use JVBase\forms\TaxonomySelector;
use JVBase\meta\Form;
use JVBase\meta\Meta;
use JVBase\meta\Render;
use JVBase\registrar\Registrar;
use WP_Block;
use WP_Post;
use WP_Query;
if (!defined('ABSPATH')) {
@@ -32,15 +31,29 @@
    public function __construct()
    {
        $this->cache = Cache::for('menu', WEEK_IN_SECONDS)->connect('post');
        $this->cache = Cache::for('menu', 'post', WEEK_IN_SECONDS);
      $this->cache->flush();
      if (Site::hasIntegration('square')) {
         $this->base = '_square_';
      } else if (Site::hasIntegration('helcim')) {
         $this->base = '_helcim_';
      }
        add_action('init', [ $this, 'registerBlock' ]);
      add_action('save_post', [$this, 'flushCache'], 10, 2);
    }
   public function flushCache(int $postID, WP_Post $post):void
   {
      if (defined('DOING_AUTOSAVE') && DOING_AUTOSAVE) return;
      if (wp_is_post_revision($postID) || wp_is_post_autosave($postID)) return;
      $postType = $post->post_type;
      if ($postType !== 'product' && !in_array($postType, Registrar::getFoodMenuTypes())) {
         return;
      }
      error_log('Flushing food menu block cache');
      $this->cache->flush();
   }
    public function registerBlock():void
    {
        register_block_type($this->path, [
@@ -50,9 +63,12 @@
   protected function buildParams():void
   {
      if (is_post_type_archive(BASE.'menu_item')) {
//    if (is_post_type_archive(BASE.'menu_item') ||
      if (is_post_type_archive('product') ||
         (function_exists('is_shop') && is_shop())) {
         $this->params = ['all'];
      } elseif (is_tax(BASE.'section')) {
//    } elseif (is_tax(BASE.'section')) {
      } elseif (is_tax('product_cat')) {
         $this->params = [];
      } else {
         $this->params = [];
@@ -66,10 +82,8 @@
         return '';
      }
      jvbInlineStyles('forms');
      $key = $this->cache->generateKey($this->params);
      $this->cache->flush();
      return $this->cache->remember(
         $key,
         $this->params,
         function() {
            ob_start();
            $this->renderBlock();
@@ -85,6 +99,23 @@
        $this->renderOnThisPage();
    }
   protected function termHasPosts(int $termID):bool
   {
      $query = new WP_Query([
         'post_type' => 'product',
         'post_status'  => 'publish',
         'posts_per_page'  => 1,
         'fields' => 'ids',
         'tax_query' => [
            [
               'taxonomy' => 'product_cat',
               'terms'  => $termID
            ]
         ]
      ]);
      return $query->have_posts();
   }
    protected function renderHeader():void
    {
      $title = 'Our Menu';
@@ -99,7 +130,8 @@
            <?php
            $sections = $this->getSections();
            foreach ($sections as $section) {
               if (!jvbTermHasPosts($section['id'], BASE.'section')) {
//             if (!jvbTermHasPosts($section['id'], BASE.'section')) {
               if (!$this->termHasPosts($section['id'])) {
                  continue;
               }
               ?>
@@ -129,13 +161,18 @@
    {
      $sections = $this->getSections();
      foreach ($sections as $section) {
         if($section['name'] === 'Uncategorized') {
            continue;
         }
         $items = new WP_Query([
            'post_type' => BASE.'menu_item',
            'post_type' => 'product',
//          'post_type' => BASE.'menu_item',
            'order' => 'ASC',
            'posts_per_page' => -1,
            'tax_query' => [
               [
                  'taxonomy' => BASE.'section',
                  'taxonomy' => 'product_cat',
//                'taxonomy' => BASE.'section',
                  'terms' => (int) $section['id'],
               ]
            ],
@@ -162,7 +199,136 @@
      }
    }
   protected function renderMenuItem(int $ID, string $slug, string $postType = 'menu_item') {
   /**
    * Renders from WooCommerce product
    * @param int $ID
    * @param string $slug
    * @param string $postType
    * @return void
    */
   protected function renderMenuItem(int $ID, string $slug, string $postType = 'product'):void {
      $meta = Meta::forPost($ID);
      $fields = $meta->getAll();
      $excerpt = get_the_excerpt($ID);
      $isVariable = !empty($fields['variations']??[]);
      $variations = $isVariable ? array_map('floatval', array_column($fields['variations'], 'price')) : [];
      $priceRange = $isVariable ?
         (jvbCurrency(min($variations)).' - '.jvbCurrency(max($variations))) :
         jvbCurrency($fields['_price']??'');
//    if (!$isVariable) {
//       jvbDump($fields, 'Fields');
//    }
      $out = sprintf(
   '<div id="%s" class="menu-item%s" data-section="%s" data-label="%s" data-id="%s">
            <div class="header row x-btw">
               <h3>%s</h3>
               <p class="price">%s</p>
            </div>
            <div class="description">%s</div>
            <div class="info col right">',
         sanitize_title($fields['post_title']),
         $isVariable ? ' variable' : '',
         $slug,
         $fields['post_title'],
         $ID,
         $fields['post_title'],
         $priceRange,
         $excerpt
      );
      if (!empty($fields['variations']??[])) {
         foreach ($fields['variations'] as $index => $row) {
            $out .= sprintf(
            '<div class="row right nowrap">
                  <div>
                     <h4>%s — %s</h4>
                     %s
                  </div><a href="?add-to-cart=%d&variation_id=%d"
   data-quantity="1"
   data-product_id="%d"
   data-variation_id="%d"
   class="btn chip add_to_cart_button ajax_add_to_cart add-to-cart">
   %s
   <span>Add to Cart</span>
</a>', //Note: we had 3 %s%s%s before the last </div> last time. This was to add optional ingredients or preparation time duration, not default in WooCommerce
                  $row['title'],
                  jvbCurrency($row['price']),
                  empty($row['description']) ? '' : wpautop($row['description']),
                  $ID,
                  $row['id'],
                  $ID,
                  $row['id'],
                  jvbIcon('plus-square')
            );
//          $out .= Form::render(
//             $row['id'],
//             '',
//             [
//                'type'   => 'quantity',
//                'label'  => $row['title'],
//                'min' => 0,
//                'max' => 30,
//                'data'   => [
//                   'price'  => $row['price'],
//                   'id'  => $row['id'],
//                   'sku' => $row['sku'],
//                   'name'   => $row['title'],
//                   'add-to-cart'  => ''
//                ],
//                'add' => 'Add 1 '.$row['title'].' to cart',
//                'remove' => 'Remove 1 '.$row['title']. ' from cart',
//             ]
//          );
            $out .= '</div>';
         }
      } else {
         $out .= sprintf(
            '<a href="?add-to-cart=%d"
               data-quantity="1"
               data-product_id="%d"
               class="btn chip add_to_cart_button ajax_add_to_cart add-to-cart">
               %s
                  <span>Add to Cart</span>
            </a>',
            $ID,
            $ID,
            jvbIcon('plus-square')
         );
//       $out .= Form::render(
//          $ID,
//          '',
//          [
//             'type'   => 'quantity',
//             'label'  => 'Add to Order',
//             'min' => 0,
//             'max' => 30,
//             'step'   => 1,
//             'data'   => [
//                'price'  => $fields['_price'],
//                'id'  => $ID,
//                'name'   => $fields['post_title'],
//                'step'   => 1,
//                'add-to-cart'  => '',
//             ],
//             'add' => 'Add 1 '.$fields['post_title'].' to cart',
//             'remove' => 'Remove 1 '.$fields['title']. ' from cart',
//          ]
//       );
      }
      $out .= '</div></div>';
      echo $out;
   }
   /**
   protected function renderMenuItemOLD(int $ID, string $slug, string $postType = 'menu_item') {
      $meta = Meta::forPost($ID);
      $fields = $meta->getAll();
      $values = $meta->getAll([
@@ -278,7 +444,8 @@
      </div>
      <?php
   }
   } **/
    protected function renderOnThisPage():void