cache = Cache::for('calendar', 'post', DAY_IN_SECONDS);
$this->cache->flush();
add_action('init', [ $this, 'registerBlock' ]);
}
public function registerBlock():void
{
register_block_type($this->path, [
'render_callback' => [ $this, 'render' ]
]);
}
protected function buildParams():void
{
$registered = Registrar::withFeature('is_calendar', 'post');
$registered = array_map('jvbCheckBase', $registered);
$types = [];
foreach ($registered as $type) {
$registrar = Registrar::getInstance($type);
$types[$type] = $registrar->getPlural();
}
$this->content = $types;
$taxonomies = [];
foreach ($registered as $type) {
$registrar = Registrar::getInstance($type);
$taxonomies = array_merge($taxonomies, $registrar->registrar->taxonomies);
}
$taxonomies = array_map('jvbCheckBase', $taxonomies);
$types = [];
foreach ($taxonomies as $type) {
$registrar = Registrar::getInstance($type);
$types[$type] = $registrar->getPlural();
}
$this->taxonomies = $types;
if (is_post_type_archive($registered)) {
$this->params = ['all'];
} elseif (is_tax($taxonomies)) {
$this->params = ['tax'];
} 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)
{
$this->buildParams();
if (empty($this->params)) {
return '';
}
$this->cache->flush();
return $this->cache->remember(
$this->params,
function() {
ob_start();
$this->renderBlock();
return ob_get_clean();
}
);
}
protected function renderBlock():void
{
echo '';
$this->renderHeader();
$this->renderCalendar();
$this->renderOnThisPage();
echo '';
}
protected function renderHeader():void
{
$title = $this->determineTitle();
?>
We bring southern-style barbeque eats with Northern flair to any event throughout Alberta.
Want to bring us to your event? Let us know, we'd love to come!
name,
);
} else {
$title = 'Events';
}
if(!in_array('all', $this->params)) {
$title = ''.$title.'';
}
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',
Events::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 = '';
if (count($this->content) > 1) {
$out = [];
foreach ($this->content as $slug => $title) {
$out[] = sprintf(
'
%s',
get_post_type_archive_link($slug),
$title,
$title
);
}
if (!empty($out)) {
$content = sprintf(
'%sBy Content
',
jvbIcon('calendar-alt'),
implode('', $out)
);
}
}
if (!empty($this->taxonomies)) {
foreach ($this->taxonomies as $slug => $title) {
$check = get_terms([
'taxonomy' => $slug,
'hide_empty' => true,
'orderby' => 'name',
]);
$out = [];
if ($check && !is_wp_error($check)) {
foreach ($check as $term) {
$out[] = sprintf(
'%s',
get_term_link($term->term_id, $slug),
$term->name,
$term->name
);
}
}
if (!empty($out)) {
$inst = Registrar::getInstance($slug);
$taxonomies .= sprintf(
'%sBy %s
',
$inst->getSlug(),
jvbIcon($inst->getIcon()??'folder'),
$inst->getSingular(),
$slug,
implode('', $out)
);
}
}
}
$dates = $this->getDateNavigation();
if (is_tax() || !is_post_type_archive($this->firstContent()) || $this->isDatedArchive()) {
echo sprintf(
'All Events',
get_post_type_archive_link($this->firstContent())
);
}
if (!empty($content) || !empty($taxonomies) || !empty($dates)) {
echo sprintf(
'',
$content,
$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(
'%sBy Date
',
jvbIcon('calendar')
);
foreach ($dates as $year => $months) {
$out .= sprintf(
'%d
',
$base,
$year,
$year,
$year
);
foreach ($months as $month => $days) {
$m = intval($month);
$monthName = Events::getMonthName($m);
$out .= sprintf(
'- %s
',
$base,
$year,
$month,
$monthName,
$year,
$monthName
);
}
$out .= '
';
}
$out .= ' ';
return $out;
}
);
}
protected function renderCalendar():void
{
?>
Upcoming Events = jvbIcon('calendar-blank')?>
= $this->getEvents() ?>
Past Events = jvbIcon('calendar-check')?>
= $this->getEvents(true) ?>
name];
}
if (is_singular()) {
return [get_queried_object()->post_type];
}
if (is_tax()) {
return [get_post_type()];
}
return [];
}
protected function getEvents(bool $past = false):string
{
$events = '';
if (is_singular()) {
return $this->formatSingular();
}
$items = new WP_Query($this->buildArgs($past));
$events = implode('', array_map([$this, 'formatItem'], $items->posts));
$events = empty($events) ? 'Nothing here yet
' : sprintf(
'',
$events
);
$total = $items->max_num_pages;
if ($total > 1) {
$big = 999999999; // need an unlikely integer
$format = $past ? 'jpast' : 'jpage';
$events .= paginate_links([
'base' => str_replace( $big, '%#%', esc_url( get_pagenum_link( $big ) ) ),
'format' => '?'.$format.'=%#%',
'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',
'order' => 'ASC',
'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));
if (empty($meta->get('date_start'))) {
return '';
}
$date = strtotime($meta->get('date_start'));
$img = empty($meta->get('post_thumbnail')) ? '' : jvbFormatImage($meta->get('post_thumbnail'), 'tiny', 'medium');
$fields = $meta->getAll();
return sprintf(
'
%s
%s
%s
',
$type,
Events::tags($fields),
$img,
Events::calendarDay($fields['date_start']),
get_the_permalink($ID),
$meta->get('post_title'),
Events::formatDay($meta->get('date_start'), $meta->get('time_start'), $meta->get('time_end')),
Events::location($fields),
Events::terms($fields, false),
empty($meta->get('post_excerpt')) ? '' : wpautop($meta->get('post_excerpt'))
);
}
protected function formatSingular():string
{
return '';
}
protected function renderOnThisPage():void
{
if (empty($this->details)) {
return;
}
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 firstContent():string
{
return array_keys($this->content)[0]??'';
}
}