cache = Cache::for('menu', 'post', WEEK_IN_SECONDS);
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);
add_action('wp_footer', [$this, 'renderGallery']);
}
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, [
'render_callback' => [ $this, 'render' ]
]);
}
protected function buildParams():void
{
// 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('product_cat')) {
$this->params = [];
} else {
$this->params = [];
}
}
public function render(array $attributes, string $content, WP_Block $block)
{
$this->buildParams();
if (empty($this->params)) {
return '';
}
jvbInlineStyles('forms');
return $this->cache->remember(
$this->params,
function() {
ob_start();
$this->renderBlock();
return ob_get_clean();
}
);
}
protected function renderBlock():void
{
$this->renderHeader();
$this->renderMenu();
$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';
if(!in_array('all', $this->params)) {
$title = ''.$title.'';
}
?>
sections) {
$this->sections = aneb_menu_sections();
}
return $this->sections;
}
protected function renderMenu():void
{
$sections = $this->getSections();
foreach ($sections as $section) {
if($section['name'] === 'Uncategorized') {
continue;
}
$items = new WP_Query([
'post_type' => 'product',
// 'post_type' => BASE.'menu_item',
'order' => 'ASC',
'posts_per_page' => -1,
'tax_query' => [
[
'taxonomy' => 'product_cat',
// 'taxonomy' => BASE.'section',
'terms' => (int) $section['id'],
]
],
'fields' => 'ids'
]);
if ($items->have_posts()) {
$slug = sanitize_title($section['name']);
?>
getAll();
$excerpt = get_the_excerpt($ID);
$isVariable = !empty($fields['variations']??[]);
$product = wc_get_product($ID);
$isFeatured = $product->is_featured();
$isOnSale = $product->is_on_sale();
$isPurchasable = $product->is_purchasable() && $product->is_in_stock();
$priceRange = $this->getPrice($fields, $isOnSale, $isPurchasable);
if ($isVariable) {
$prices = array_map('floatval', array_column($fields['variations'], 'price'));
$min = min($prices);
$max = max($prices);
$priceRange = $min===$max ? jvbCurrency($min) : jvbCurrency($min) .' - '.jvbCurrency($max);
}
// if (in_array($fields['post_title'], ['Chopped Brisket Sandwich', 'Breakfast Poutine'])) {
// jvbDump ($fields);
// }
$gallery = '';
if (!empty($fields['gallery_image_ids'])) {
$gallery = implode(array_map(function($id) use ($fields){
$id = absint($id);
$caption = wp_get_attachment_caption($id);
return sprintf(
'%s%s',
jvbFormatImage($id,'tiny','medium',true,'menu'),
empty($caption) ? $fields['post_title'] : $caption
);
}, $fields['gallery_image_ids']));
}
$caption = '';
if (!empty($fields['image_id'])) {
$caption = wp_get_attachment_caption((int)$fields['image_id']);
$caption = empty($caption) ? $fields['post_title'] : $caption;
}
$out = sprintf(
'
';
echo $out;
}
protected function getPrice(array $item, bool $isOnSale, bool $isPurchasable):string
{
$price = jvbCurrency($item['regular_price']);
$price = $isOnSale ? ' '.$price.' '.jvbCurrency($item['sale_price']) : $price;
return $price;
}
protected function getSaleText(array $item, bool $isPurchasable):string
{
if (empty($item['date_on_sale_to']) && $isPurchasable) {
return '';
}
$out = sprintf(
'%sOn sale until .',
jvbIcon('tag-chevron'),
$item['date_on_sale_to']->format('c'),
$item['date_on_sale_to']->format('l, F j, Y')
);
if (!$isPurchasable) {
$out .= sprintf(
'%sTemporarily Out of Stock',
jvbIcon('warning-circle')
);
}
return $out;
}
/**
protected function renderMenuItemOLD(int $ID, string $slug, string $postType = 'menu_item') {
$meta = Meta::forPost($ID);
$fields = $meta->getAll();
$values = $meta->getAll([
'post_title',
$this->base.'item_id',
$this->base.'price',
$this->base.'product_variations',
'max_order',
'min_order',
'step'
]);
$priceRange = jvbCurrency($values[$this->base.'price']);
$variations = $values[$this->base.'product_variations'];
if(!empty($variations) && $variations[0][$this->base.'name'] === '') {
$variations = [];
}
if (!empty($variations)) {
$prices = [];
foreach ($variations as $row) {
if (isset($row[$this->base.'price']) && is_numeric($row[$this->base.'price'])) {
$prices[] = (float) $row[$this->base.'price'];
}
}
if (!empty($prices) && (min($prices) !== max($prices))) {
$priceRange = jvbCurrency(min($prices)).' - '.jvbCurrency(max($prices));
} elseif (!empty($prices)) {
$priceRange = jvbCurrency(max($prices));
}
}
$max = $values['max_order']??'';
$min = $values['min_order']??'';
$step = $values['step']??'';
$max = ($max === '') ? 50 : $max;
$min = ($min === '') ? 0 : $min;
$step = ($step === '') ? 1 : $step;
?>
details)) {
return;
}
echo jvbOnThisPage(array_keys($this->details));
}
public function renderGallery():void
{
jvbRenderGallery();
}
}