<?php
|
namespace JVBase\registry;
|
|
use WP_Post;
|
use JVBase\meta\MetaRegistry;
|
use JVBase\managers\CacheManager;
|
if (!defined('ABSPATH')) {
|
exit;
|
}
|
class PostTypeRegistrar
|
{
|
private string $slug;
|
private array $config;
|
protected array $fields;
|
private string $post_type;
|
private FieldRegistry $fieldRegistry;
|
|
public function __construct(string $slug, array $config)
|
{
|
$this->slug = $slug;
|
$this->config = $config;
|
$this->post_type = BASE . $slug;
|
$this->fieldRegistry = FieldRegistry::getInstance();
|
$this->fields = $this->fieldRegistry->getFields($slug, 'post');
|
|
$this->registerHooks();
|
}
|
|
public function register(): void
|
{
|
$singular = $this->config['singular'] ?? ucfirst($this->slug);
|
$plural = $this->config['plural'] ?? $singular . 's';
|
$loweredPlural = strtolower($plural);
|
$args = [
|
'labels' => $this->buildLabels($singular, $plural),
|
'public' => $this->config['public'] ?? true,
|
'publicly_queryable' => $this->config['publicly_queryable'] ?? $this->config['public'] ?? true,
|
'show_ui' => $this->config['show_ui'] ?? true,
|
// 'show_in_menu' => false,
|
'show_in_menu' => $this->config['show_in_menu'] ?? true,
|
'query_var' => $this->config['query_var'] ?? true,
|
'rewrite' => $this->config['rewrite'] ?? ['slug' => $this->slug, 'with_front' => false],
|
'capability_type' => [$this->slug, $loweredPlural],
|
'capabilities' => [
|
'edit_post' => "edit_{$this->slug}",
|
'read_post' => "read_{$this->slug}",
|
'delete_post' => "delete_{$this->slug}",
|
'edit_posts' => "edit_{$loweredPlural}",
|
'edit_others_posts' => "edit_others_{$loweredPlural}",
|
'publish_posts' => "publish_{$loweredPlural}",
|
'read_private_posts' => "read_private_{$loweredPlural}",
|
'create_posts' => "edit_{$loweredPlural}",
|
],
|
'has_archive' => $this->config['has_archive'] ?? true,
|
'hierarchical' => $this->config['hierarchical'] ?? false,
|
'menu_position' => $this->config['menu_position'] ?? null,
|
'supports' => $this->config['supports'] ?? ['title', 'author', 'thumbnail', 'editor', 'revisions', 'custom-fields', 'excerpt', 'content'],
|
'show_in_rest' => $this->config['show_in_rest'] ?? true,
|
];
|
|
if (jvbCheck('is_calendar', $this->config)) {
|
$args['rewrite']['slug'] = $args['rewrite']['slug']??$this->slug.'/%eyear%/%emonth%/%eday%';
|
}
|
if (isset($this->config['icon'])) {
|
$args['menu_icon'] = jvbCSSIcon($this->config['icon']);
|
}
|
|
register_post_type($this->post_type, $args);
|
|
if (!empty($this->fields)) {
|
$meta_registry = new MetaRegistry($this->fields, $this->slug, 'post');
|
$meta_registry->registerMetaFields();
|
}
|
}
|
|
private function buildLabels(string $singular, string $plural): array
|
{
|
return [
|
'name' => $plural,
|
'singular_name' => $singular,
|
'menu_name' => $plural,
|
'name_admin_bar' => $singular,
|
'add_new' => "Add New",
|
'add_new_item' => "Add New {$singular}",
|
'new_item' => "New {$singular}",
|
'edit_item' => "Edit {$singular}",
|
'view_item' => "View {$singular}",
|
'all_items' => "All {$plural}",
|
'search_items' => "Search {$plural}",
|
'parent_item_colon' => "Parent {$plural}:",
|
'not_found' => "No {$plural} found.",
|
'not_found_in_trash' => "No {$plural} found in Trash.",
|
];
|
}
|
|
public function registerHooks() {
|
if ($this->config['hide_single'] ?? false) {
|
add_filter('is_post_type_viewable', [$this, 'hideFromPublic']);
|
if (jvbCheck('redirectToAuthor',$this->config)) {
|
add_filter('post_type_link', [$this, 'redirectSingleToAuthor'], 15, 2);
|
} else {
|
add_filter('post_type_link', [$this, 'redirectSingleToArchive'], 15, 2);
|
}
|
}
|
|
$postType = $this->post_type;
|
add_action("save_post_{$this->post_type}", function($post_id, $post, $update) use ($postType) {
|
if (jvbNoSaveIt($post_id, $post)) {
|
return;
|
}
|
$this->invalidatePostCache($postType, $post, $update ? 'update' : 'create');
|
}, 10, 3);
|
|
add_action("delete_post", function($post_id, $post) use ($postType) {
|
$post = get_post($post_id);
|
if ($post && $post->post_type === $postType) {
|
$this->invalidatePostCache($postType, $post, 'delete');
|
}
|
}, 10, 2);
|
|
add_action("transition_post_status", function($new_status, $old_status, $post) use ($postType) {
|
if ($post->post_type === $postType && $new_status !== $old_status) {
|
$this->invalidatePostCache($postType, $post, 'status_change');
|
}
|
}, 10, 3);
|
}
|
|
protected function invalidatePostCache(string $type, $post, string $action) {
|
error_log('Clearing Cache for '.print_r($type, true));
|
|
$cache = new CacheManager(jvbNoBase($type));
|
$cache->delete($post->ID);
|
|
// Clear specific cache groups
|
CacheManager::invalidateGroup($type);
|
|
CacheManager::invalidateGroup("user_content_{$post->post_author}");
|
|
// Clear related caches (taxonomies attached to this post)
|
$taxonomies = get_object_taxonomies($post->post_type);
|
foreach ($taxonomies as $taxonomy) {
|
$terms = wp_get_post_terms($post->ID, $taxonomy, ['fields' => 'ids']);
|
if (!empty($terms)) {
|
CacheManager::invalidateGroup($taxonomy);
|
}
|
}
|
|
// Trigger custom action for additional handling
|
do_action("jvb_cache_invalidated_{$type}", $post, $action);
|
}
|
|
public function hideFromPublic(bool $is_viewable): bool
|
{
|
if (!is_admin() && is_singular($this->post_type)) {
|
return false;
|
}
|
return $is_viewable;
|
}
|
|
public function redirectSingleToAuthor(string $url, \WP_Post $post): string
|
{
|
if ($post->post_type !== $this->post_type) {
|
return $url;
|
}
|
|
// Redirect to author page or archive
|
$user_link = get_user_meta($post->post_author, BASE . 'link', true);
|
if ($user_link) {
|
$query_var = str_replace(BASE, '', $post->post_type);
|
return add_query_arg($query_var, $post->ID, get_permalink($user_link));
|
}
|
|
return get_post_type_archive_link($post->post_type);
|
}
|
public function redirectSingleToArchive(string $url, \WP_Post $post): string
|
{
|
if ($post->post_type !== $this->post_type) {
|
return $url;
|
}
|
|
return get_post_type_archive_link($post->post_type);
|
}
|
}
|