Jake Vanderwerf
2026-08-29 f859e64a57c624ff2daa2b21355f65a49fd4807d
=Some more tweaks. Mostly on the MenuBlock and adding the Meta.php to WooCommerce Products
8 files modified
119 ■■■■■ changed files
activate.php 4 ●●●●● patch | view | raw | blame | history
inc/blocks/MenuBlock.php 50 ●●●●● patch | view | raw | blame | history
inc/integrations/SyncToPost.php 2 ●●●●● patch | view | raw | blame | history
inc/managers/CustomTable.php 12 ●●●●● patch | view | raw | blame | history
inc/managers/IconsManager.php 17 ●●●●● patch | view | raw | blame | history
inc/managers/queue/Queue.php 2 ●●●●● patch | view | raw | blame | history
inc/meta/Meta.php 20 ●●●●● patch | view | raw | blame | history
inc/registrar/Registrar.php 12 ●●●●● patch | view | raw | blame | history
activate.php
@@ -34,7 +34,7 @@
    error_log('Tables created!');
    // Store schema version
    update_option('jvb_db_version', '1.0.0');
    update_option(BASE.'db_version', '1.0.0');
    error_log('Starting schedules...');
    jvbSchedules();
    error_log('Schedules done!');
@@ -247,7 +247,7 @@
// Optional: Add upgrade routine
function jvbMaybeUpgrade():void
{
    $current_version = get_option('jvb_db_version', '0');
    $current_version = get_option(BASE.'db_version', '0');
    if (version_compare($current_version, '1.0.0', '<')) {
        jvbActivatePlugin();
    }
inc/blocks/MenuBlock.php
@@ -5,7 +5,9 @@
use JVBase\base\Site;
use JVBase\managers\Cache;
use JVBase\meta\Meta;
use JVBase\registrar\Registrar;
use WP_Block;
use WP_Post;
use WP_Query;
if (!defined('ABSPATH')) {
@@ -30,14 +32,28 @@
    public function __construct()
    {
        $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, [
@@ -66,7 +82,6 @@
            return '';
        }
        jvbInlineStyles('forms');
        $this->cache->flush();
        return $this->cache->remember(
            $this->params,
            function() {
@@ -84,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 +131,7 @@
                $sections = $this->getSections();
                foreach ($sections as $section) {
//                  if (!jvbTermHasPosts($section['id'], BASE.'section')) {
                    if (!jvbTermHasPosts($section['id'], 'product_cat')) {
                    if (!$this->termHasPosts($section['id'])) {
                        continue;
                    }
                    ?>
@@ -179,23 +211,27 @@
        $fields = $meta->getAll();
//      jvbDump($fields, 'Fields');
        $excerpt = get_the_excerpt($ID);
        $isVariable = !empty($fields['variations']??[]);
        $variations = $isVariable ? array_map('floatval', array_column($fields['variations'], 'price')) : [];
        $priceRange = $isVariable ?
            (min($variations).' - '.max($variations)) :
            $fields['_price']??'';
            (jvbCurrency(min($variations)).' - '.jvbCurrency(max($variations))) :
            jvbCurrency($fields['_price']??'');
//      if (!$isVariable) {
//          jvbDump($fields, 'Fields');
//      }
        $out = sprintf(
    '<div class="menu-item%s" data-section="%s" data-label="%s" data-id="%s">
    '<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>
                    <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'],
inc/integrations/SyncToPost.php
@@ -27,7 +27,7 @@
    public function handleSavePost(int $postID, WP_Post $post, bool $update):void
    {
        if (defined('DOING_AUTOSAVE') && DOING_AUTOSAVE) return;
        if (wp_is_post_revision($postID)) return;
        if (wp_is_post_revision($postID) || wp_is_post_autosave($postID)) return;
        error_log('=== ['.$this->service_name.']::handleSavePost called');
inc/managers/CustomTable.php
@@ -24,6 +24,7 @@
    private static ?wpdb $wpdb = null;
    private static string $prefix;
    protected string $tableName;
    protected bool $table_exists = false;
    protected string $definition;
    protected string $fullTableName;
    protected bool $useTransactions;
@@ -59,11 +60,16 @@
    {
        if (!isset(self::$instances[$tableName])) {
            self::$instances[$tableName] = new self($tableName, $user, $auth, $useTransactions);
            self::$instances[$tableName]->setFlags();
        }
        return self::$instances[$tableName];
    }
        protected function setFlags():void
        {
            $this->table_exists = !is_null(self::$wpdb->get_var("SHOW TABLES LIKE '{$this->fullTableName}'"));
        }
    public static function destroyInstance(string $tableName):void
    {
@@ -230,7 +236,7 @@
        require_once(ABSPATH . 'wp-admin/includes/upgrade.php');
        foreach (self::$instances as $instance) {
            if (!$instance->wpdb->get_var("SHOW TABLES LIKE '{$instance->fullTableName}'")) {
            if (!$instance->table_exists) {
                $instance->createTable();
            }
        }
@@ -242,7 +248,7 @@
            error_log('[CustomTable]No definition set for '.$this->tableName);
            return;
        }
        if (self::$wpdb->get_var("SHOW TABLES LIKE '{$this->fullTableName}'")) {
        if ($this->table_exists) {
            return;
        }
        require_once(ABSPATH . 'wp-admin/includes/upgrade.php');
@@ -264,7 +270,7 @@
            $error_msg = "SQL Error creating table {$this->tableName}: " . self::$wpdb->last_error;
            error_log($error_msg);
            error_log("Failed SQL Query: " . $schema);
        } elseif (self::$wpdb->get_var("SHOW TABLES LIKE '{$this->fullTableName}'")) {
        } else {
            error_log("Successfully created table: {$this->fullTableName}");
        }
    }
inc/managers/IconsManager.php
@@ -698,6 +698,18 @@
        foreach ($this->icons as $style => $names) {
            $styleClass = ($style !== $this->style) ? '-'.substr($style, 0, 2) : '';
            foreach ($names as $icon) {
                $css .= $this->generateSingleIconCss($icon, $style, $styleClass);
            }
        }
        update_option($this->timestampKey, time());
        return $this->minifyCss($css);
    }
    public function generateSingleIconCss(string $icon, ?string $style = null, ?string $styleClass = null):string
    {
        $style = $style??$this->style;
        $styleClass = $styleClass??($style !== $this->style) ? '-'.substr($style, 0, 2) : '';
        $css = '';
                $svg = $this->getEncodedSVG($icon, $style);
                if ($svg !== '') {
                    if ($icon === 'caret-down') {
@@ -713,10 +725,7 @@
                    $css .= "--icon:url('data:image/svg+xml;base64,{$svg}');";
                    $css .= "}";
                }
            }
        }
        update_option($this->timestampKey, time());
        return $this->minifyCss($css);
        return $css;
    }
    protected function minifyCSS(string $css): string
inc/managers/queue/Queue.php
@@ -209,7 +209,7 @@
    /**
     * Get a specific value from an operation - backwards compatibility
     */
    public function getOperationValue(string $id, string $column, bool $decodeJson = true): \static|string|int|array|null
    public function getOperationValue(string $id, string $column, bool $decodeJson = true): static|string|int|array|null
    {
        $op = $this->get($id);
        if (!$op) {
inc/meta/Meta.php
@@ -149,7 +149,7 @@
                'type'  => 'text',
                'label' => 'Short Description',
            ];
            $fields['post_id'] = [
            $fields['ID'] = [
                'type'  => 'text',
                'label' => 'ID',
            ];
@@ -178,6 +178,7 @@
            $product = wc_get_product($id);
            $fields['sku'] = [
                'type'  => 'text',
                'label' => 'SKU',
@@ -257,6 +258,23 @@
            $value = '';
            if ($this->type === 'option') {
                $value = get_option(BASE . $fieldName, $config['default'] ?? '');
            } else if ($this->wpObject && $this->wpObject->post_type === 'product') {
                if (property_exists($this->wpObject, $fieldName)) {
                    $value = $this->wpObject->$fieldName;
                } else {
                    $product = wc_get_product($this->wpObject->ID);
                    $value = match ($fieldName) {
                        'sku'   => $product->get_sku(),
                        '_price'    => $product->get_price(),
                        'description'=> $product->get_short_description(),
                        'sale'  => $product->get_sale_price(),
                        'img'   => $product->get_image_id(),
                        '_stock'    => $product->get_stock_quantity(),
                        '_stock_status' => $product->get_stock_status(),
                        default => '',
                    };
                }
            } else if (
                ($this->wpObject && property_exists($this->wpObject, $fieldName))
                || ($type === 'user' && $this->wpObject && property_exists($this->wpObject->data, $fieldName))) {
inc/registrar/Registrar.php
@@ -61,7 +61,7 @@
        //Shared Flags
        'favouritable', 'karma', 'show_feed', 'show_directory', 'approve_new', 'has_responses', 'invitable',
        //Post Flags
        'hide_single', 'redirect_to_author', 'is_calendar', 'single_image', 'is_timeline', 'is_gallery', 'is_faq', 'is_glossary', 'rewrite_taxonomy', 'add_image_column', 'is_profile',
        'hide_single', 'redirect_to_author', 'is_calendar', 'single_image', 'is_timeline', 'is_gallery', 'is_faq', 'is_glossary', 'rewrite_taxonomy', 'add_image_column', 'is_profile', 'is_food_menu',
        //Taxonomy Flags
        'is_content', 'is_ownable', 'verify_entry', 'track_changes', 'associate_user_content', 'prefix_post_type',
        //User Flags
@@ -192,6 +192,7 @@
     */
    public bool $profile_link;
    public bool $is_profile = false;
    public bool $is_food_menu = false;
    /**
     * @var array
     */
@@ -1258,6 +1259,15 @@
        }, $hasProfiles));
    }
    public function setAsFoodMenu():void
    {
        $this->is_food_menu = true;
    }
        public static function getFoodMenuTypes():array
        {
            return array_map('jvbCheckBase', self::withFeature('is_food_menu'));
        }
    public function setUserSubtype(string $type):self
    {
        $this->user_subtype = sanitize_text_field($type);