From 1aa7c404dae63c9518468fe9b579fad819f8d871 Mon Sep 17 00:00:00 2001
From: Jake Vanderwerf <get@jakevanderwerf.ca>
Date: Sun, 13 Sep 2026 18:32:43 +0000
Subject: [PATCH] =Single Event page setup done through the new Event block. Currently working on the Simple Calendar block setup

---
 inc/blocks/SimpleCalendarBlock.php |  280 +++++++++++++++++++++++++++++++++++++++++++++++++------
 1 files changed, 247 insertions(+), 33 deletions(-)

diff --git a/inc/blocks/SimpleCalendarBlock.php b/inc/blocks/SimpleCalendarBlock.php
index e294792..c83d0a3 100644
--- a/inc/blocks/SimpleCalendarBlock.php
+++ b/inc/blocks/SimpleCalendarBlock.php
@@ -1,6 +1,7 @@
 <?php
 namespace JVBase\blocks;
 
+use DateTime;
 use JVBase\managers\Cache;
 use JVBase\meta\Meta;
 use JVBase\registrar\Registrar;
@@ -31,6 +32,7 @@
     public function __construct()
     {
         $this->cache = Cache::for('calendar', 'post',  DAY_IN_SECONDS);
+		$this->cache->flush();
         add_action('init', [ $this, 'registerBlock' ]);
     }
 
@@ -73,6 +75,14 @@
 		} else {
 			$this->params = [];
 		}
+
+		foreach (['eyear', 'emonth', 'eday'] as $key) {
+			$val = get_query_var($key);
+			if (!empty($val)) {
+				$this->params[$key] = $val;
+			}
+		}
+
 	}
 
     public function render(array $attributes, string $content, WP_Block $block)
@@ -95,19 +105,20 @@
 
     protected function renderBlock():void
     {
+		echo '<section class="simple-calendar">';
         $this->renderHeader();
         $this->renderCalendar();
         $this->renderOnThisPage();
+		echo '</section>';
     }
 
     protected function renderHeader():void
     {
-		$title = 'Events';
-		if(!in_array('all', $this->params)) {
-			$title = '<small>'.$title.'</small>';
-		}
+		$title = $this->determineTitle();
+
 
         ?>
+
         <header id="top">
             <h1><?=$title?></h1>
 			<?php $this->buildNav(); ?>
@@ -118,6 +129,50 @@
 		</section>
         <?php
     }
+		protected function determineTitle():string
+		{
+			if (is_tax(BASE.'event_category')) {
+				$title = sprintf(
+					'%s Events',
+					get_queried_object()->name,
+				);
+			} else {
+				$title = 'Events';
+			}
+
+
+			if(!in_array('all', $this->params)) {
+				$title = '<small>'.$title.'</small>';
+			}
+			if (is_tax(BASE.'city')) {
+				$title .= sprintf(
+					' in %s',
+					get_queried_object()->name,
+				);
+			}
+			if ($this->has('emonth')) {
+				$title .= sprintf(
+					' %s %s',
+					is_tax() ? 'happening on' : 'in',
+					$this->getMonthName((int)$this->has('emonth')),
+				);
+			}
+			if ($this->has('eday')) {
+				$title .= sprintf(
+					' %s,',
+					(int)$this->has('eday')
+				);
+			}
+			if ($this->has('eyear')) {
+				$title.= sprintf(
+					' %s%s',
+					!$this->has('emonth') ? 'in ' : '',
+					$this->has('eyear')
+				);
+			}
+
+			return $title;
+		}
 		protected function buildNav():void
 		{
 			$content = $taxonomies = '';
@@ -159,7 +214,7 @@
 					}
 					if (!empty($out)) {
 						$taxonomies .= sprintf(
-							'<ul class="term-list %s"><li class="label">%s</li>%s</ul>',
+							'<ul class="term-list row start %s"><li class="label">%s</li>%s</ul>',
 							$slug,
 							$title,
 							implode('', $out)
@@ -168,14 +223,109 @@
 				}
 			}
 
-			if (!empty($content) || !empty($taxonomies)) {
+			$dates = $this->getDateNavigation();
+
+			if (!is_post_type_archive($this->content[0]) || $this->isDatedArchive()) {
 				echo sprintf(
-					'<nav class="types">%s%s</nav>',
+					'<a href="%s" class="btn chip">All Events</a>',
+					get_post_type_archive_link($this->content[0])
+				);
+			}
+			if (!empty($content) || !empty($taxonomies) || !empty($dates)) {
+				echo sprintf(
+					'<nav class="calendar types">%s%s%s</nav>',
 					$content,
-					$taxonomies
+					$taxonomies,
+					$dates
 				);
 			}
 		}
+			protected function isDatedArchive():bool
+			{
+				foreach (['eyear', 'emonth', 'eday'] as $key) {
+					if (array_key_exists($key, $this->params)) {
+						return true;
+					}
+				}
+				return false;
+			}
+			protected function getDateNavigation():string
+			{
+				$type = get_post_type();
+				if (empty($type)) {
+					return '';
+				}
+
+				return $this->cache->remember(
+					$type.'dateNav',
+					function() use ($type) {
+						$tmp = new WP_Query([
+							'post_type'	=> $type,
+							'post_status' => 'publish',
+							'posts_per_page' => -1,
+							'fields' => 'ids',
+						]);
+						$dates = [];
+						foreach ($tmp->posts as $id) {
+							$meta = Meta::forPost($id);
+							$start = $meta->get('date_start');
+							if (!empty($start)) {
+								$date = new DateTime($start);
+								$year = $date->format('Y');
+								$month = $date->format('m');
+								$day = $date->format('d');
+
+								if (!array_key_exists($year, $dates)) {
+									$dates[$year] = [];
+								}
+								if (!array_key_exists($month, $dates[$year])) {
+									$dates[$year][$month] = [];
+								}
+								if (!in_array($day, $dates[$year][$month])) {
+									$dates[$year][$month][] = $day;
+								}
+							}
+						}
+						if (empty($dates)) {
+							return '';
+						}
+
+						$base = get_post_type_archive_link($type);
+						$out = sprintf(
+						'<details class="dates row start"><summary>%sBy Date</summary>',
+							jvbIcon('calendar')
+						);
+						foreach ($dates as $year => $months) {
+							$out .= sprintf(
+								'<details><summary><a href="%s/%d" title="See all in %d">%d</a></summary><ul>',
+								$base,
+								$year,
+								$year,
+								$year
+							);
+
+							foreach ($months as $month => $days) {
+								$m = intval($month);
+								$monthName = $this->getMonthName($m);
+
+								$out .= sprintf(
+									'<li><a href="%s/%d/%s" title="View all posts in %s, %d">%s</a></li>',
+									$base,
+									$year,
+									$month,
+									$monthName,
+									$year,
+									$monthName
+								);
+							}
+							$out .= '</ul></details>';
+						}
+						$out .= '</details>';
+
+						return $out;
+					}
+				);
+			}
 
     protected function renderCalendar():void
     {
@@ -201,7 +351,7 @@
 		}
 		if (is_tax()) {
 			$tax = get_queried_object();
-			jvbDump($tax);
+			jvbDump($tax, 'taxonomy');
 		}
 		return [];
 	}
@@ -213,27 +363,7 @@
 			return $this->formatSingular();
 		}
 
-		$page = $past
-			? $_GET['jpast']??1
-			: $_GET['jpage']??1;
-
-		$items = new WP_Query([
-			'post_type'	=>$this->getCurrentPostTypes(),
-			'post_status'	=> 'publish',
-			'orderby'		=> 'meta_value',
-			'meta_key'		=> BASE.'date_start',
-			'posts_per_page'=> 30,
-			'fields'		=> 'ids',
-			'paged'			=> $page,
-			'meta_type'		=> 'DATETIME',
-			'meta_query'	=> [
-				[
-					'key'	=> BASE.'past',
-					'value'	=> '1',
-					'compare' => $past ? '=' : '!='
-				]
-			]
-		]);
+		$items = new WP_Query($this->buildArgs($past));
 
 		$events = implode('', array_map([$this, 'formatItem'], $items->posts));
 
@@ -248,19 +378,78 @@
 			$events .= paginate_links([
 				'base' => str_replace( $big, '%#%', esc_url( get_pagenum_link( $big ) ) ),
 				'format' => '?'.$format.'=%#%',
-				'current' => $page,
+				'current' => $items->query_vars['paged'],
 				'total' => $total
 			]);
 		}
 
+		wp_reset_postdata();
+
 		return $events;
 	}
 
+	protected function buildArgs(bool $past):array
+	{
+		$page = $past
+			? min($_GET['jpast']??1, 1)
+			: min($_GET['jpage']??1, 1);
+		$postTypes = $this->getCurrentPostTypes();
+
+		$args = [
+			'post_type' => $postTypes,
+			'post_status'	=> 'publish',
+			'orderby'		=> 'meta_value',
+			'meta_key'		=> BASE.'date_start',
+			'meta_type'		=> 'DATETIME',
+			'posts_per_page'=> 30,
+			'fields'		=> 'ids',
+			'paged'			=> $page,
+			'meta_query'	=> [
+				[
+					'key'	=> BASE.'past',
+					'value'	=> '1',
+					'compare' => $past ? 'EXISTS' : 'NOT EXISTS'
+				]
+			]
+		];
+
+
+		if ($this->has('eyear')) {
+			$args['meta_query'][] = [
+				'key'	=> BASE.'year',
+				'value'	=> intval($this->has('eyear')),
+			];
+		}
+		if ($this->has('emonth')) {
+			$args['meta_query'][] = [
+				'key'	=> BASE.'month',
+				'value'	=> str_pad($this->has('emonth'), 2, "0", STR_PAD_LEFT),
+			];
+		}
+		if ($this->has('eday')) {
+			$args['meta_query'][] = [
+				'key'	=> BASE.'day',
+				'value'	=> str_pad($this->has('eday'), 2, "0", STR_PAD_LEFT),
+			];
+		}
+		if (is_tax()) {
+			$obj = get_queried_object();
+			$args['tax_query']= [
+				[
+					'taxonomy'	=> $obj->taxonomy,
+					'terms'		=> $obj->term_id,
+				]
+			];
+		}
+		return $args;
+	}
+
 
 	protected function formatItem(int $ID):string
 	{
 		$meta = Meta::forPost($ID);
 		$type = jvbNoBase(get_post_type($ID));
+		$date = strtotime($meta->get('date_start'));
 		return sprintf(
 	'<li class="item %s">
 				%s
@@ -274,8 +463,8 @@
 			empty($meta->get('post_thumbnail')) ? '' : jvbFormatImage($meta->get('post_thumbnail'), 'tiny', 'medium'),
 			get_the_permalink($ID),
 			$meta->get('post_title'),
-			date('c', $meta->get('date_start')),
-			date('F j, Y', $meta->get('date_start')),
+			date('c', $date),
+			date('F j, Y', $date),
 			empty($meta->get('post_excerpt')) ? '' : wpautop($meta->get('post_excerpt'))
 		);
 	}
@@ -293,4 +482,29 @@
         }
         echo jvbOnThisPage(array_keys($this->details));
     }
+
+	protected function has(string $key):false|string
+	{
+		return array_key_exists($key, $this->params) && absint($this->params[$key]) > 0 ?
+			$this->params[$key] :
+			false;
+	}
+
+	protected function getMonthName(int $num):string
+	{
+		return match($num) {
+			1 => 'January',
+			2 => 'February',
+			3 => 'March',
+			4 => 'April',
+			5 => 'May',
+			6 => 'June',
+			7 => 'July',
+			8 => 'August',
+			9 => 'September',
+			10 => 'October',
+			11 => 'November',
+			12 => 'December',
+		};
+	}
 }

--
Gitblit v1.10.0