main_page = [
'page_title' => 'JakeVan Settings',
'menu_title' => 'JakeVan',
'capability' => 'manage_options',
'menu_slug' => BASE . 'settings',
'icon' => jvbCSSIcon('settings'),
'position' => 0
];
$this->subpages = apply_filters('jvbAdminSubpages', []);
// delete_option(BASE.'admin_actions');
// delete_option(BASE.'admin_subpages');
// $this->getSubpages();
$this->getActions();
// Hook into WordPress admin
add_action('admin_menu', [$this, 'registerAdminPages']);
add_action('admin_enqueue_scripts', [$this, 'enqueueAdminAssets']);
}
/**
* Register a subpage to appear under the main settings page
*
* @param string $page_title The text to be displayed in the title tags of the page
* @param string $menu_title The text to be used for the menu
* @param string $capability The capability required to access the page
* @param string $menu_slug The slug name to refer to this menu by
* @param callable $callback The function to be called to output the content for this page
* @param string|null $icon
* @param int|null $position The position in the menu order (optional)
* @return bool Success or failure
*/
public function registerSubpage(
string $page_title,
string $menu_title,
string $capability,
string $menu_slug,
callable $callback,
string|null $icon = null,
int|null $position = null
):bool {
return true;
// if (empty($page_title) ||
// empty($menu_title) ||
// empty($capability) ||
// empty($menu_slug) ||
// !is_callable($callback)) {
// error_log('This wasn\'t registered: '.print_r([
// 'page_title' => $page_title,
// 'menu_title' => $menu_title,
// 'capability' => $capability,
// 'menu_slug' => $menu_slug,
// 'callback' => $callback
// ], true));
// return false;
// }
//
// $this->getSubpages();
//
// $subpage = [
// 'page_title' => $page_title,
// 'menu_title' => $menu_title,
// 'capability' => $capability,
// 'menu_slug' => BASE . $menu_slug,
// 'callback' => $callback,
// 'position' => $position
// ];
//
// if (!is_null($position)) {
// $subpage['position'] = $position;
// }
// if (!is_null($icon)) {
// $subpage['icon'] = $this->getIcon($icon);
// }
//
// $this->subpages[] = $subpage;
//
// $this->setSubpages();
//
// return true;
}
protected function getSubpages()
{
$this->subpages = get_option(BASE.'admin_subpages', []);
}
protected function setSubpages()
{
update_option(BASE.'admin_subpages', $this->subpages);
}
public function registerAction(
string $label,
string $slug,
string $capability,
string|null $icon = null
):bool {
$this->getActions();
$action = [
'label' => $label,
'slug' => sanitize_title($slug),
'capability'=> $capability,
];
if (!is_null($icon)) {
$action['icon'] = $icon;
}
$this->actions[sanitize_title($slug)] = $action;
$this->setActions();
return true;
}
protected function getActions()
{
$this->actions = get_option(BASE.'admin_actions', []);
}
protected function setActions()
{
update_option(BASE.'admin_actions', $this->actions);
}
/**
* Register admin pages with WordPress
*/
public function registerAdminPages():void
{
// Add main settings page
$this->page_hook = add_menu_page(
$this->main_page['page_title'],
$this->main_page['menu_title'],
$this->main_page['capability'],
$this->main_page['menu_slug'],
[$this, 'renderMainPage'],
$this->main_page['icon'],
$this->main_page['position']
);
// Add main page as a subpage to make it appear in submenu
add_submenu_page(
$this->main_page['menu_slug'],
$this->main_page['page_title'],
'Overview',
$this->main_page['capability'],
$this->main_page['menu_slug']
);
add_submenu_page(
$this->main_page['menu_slug'],
'Cache',
'Cache',
'manage_options',
BASE.'cache',
[$this, 'renderCachePage']
);
// $this->getSubpages();
// Add registered subpages
foreach ($this->subpages as $page) {
if (!array_key_exists('page_title', $page) ||
!array_key_exists('menu_title', $page) ||
!array_key_exists('capability', $page) ||
!array_key_exists('menu_slug', $page) ||
!array_key_exists('callback', $page)) {
error_log('Invalid admin page config for '.print_r($page, true));
continue;
}
add_submenu_page(
$this->main_page['menu_slug'],
$page['page_title'],
$page['menu_title'],
$page['capability'],
$page['menu_slug'],
$page['callback']
);
}
}
/**
* Render the main settings page
*/
public function renderMainPage():void
{
?>
= esc_html($this->main_page['page_title']); ?>
renderDashboard(); ?>
Active Users
renderUserStats(); ?>
Recent Content
renderRecentContent(); ?>
Quick Actions
renderActions(); ?>
Quick Links
renderQuickLinks(); ?>
queue()->getQueueStatus();
error_log('Queue Status: '.print_r($queue_status, true));
// Other system checks
$memory_usage = memory_get_usage(true) / 1024 / 1024;
// Display status items
?>
Queue Status:
= (isset($queue_status['pending']) ? esc_html($queue_status['pending']) : '0'); ?> pending,
= (isset($queue_status['processing']) ?
esc_html($queue_status['processing']) :
'0'); ?> processing
Memory Usage:
= round($memory_usage, 2); ?> MB
Plugin Version:
1.0.0
Content Types:
= count(JVB_CONTENT); ?> registered
Taxonomies:
= count(JVB_TAXONOMY); ?> registered
$config) {
$count = count_users()['avail_roles'][$role]??0;
?>
= esc_html($count); ?>
=$config['name']?>
$config) {
$content_types[jvbCheckBase($content)] = $config['plural'];
}
?>
| Content Type |
Last 7 Days |
Total |
$label) : ?>
get_var($wpdb->prepare(
"SELECT COUNT(*) FROM {$wpdb->posts}
WHERE post_type = %s
AND post_date > %s
AND post_status = 'publish'",
$type,
$week_ago
));
$total_count = $wpdb->get_var($wpdb->prepare(
"SELECT COUNT(*) FROM {$wpdb->posts} WHERE post_type = %s AND post_status = 'publish'",
$type
));
?>
| = esc_html($label); ?> |
= esc_html($recent_count); ?> |
= esc_html($total_count); ?> |
'Moderate Artist Requests',
'url' => admin_url('admin.php?page=' . BASE . 'artist_approval'),
'icon' => 'dashicons-id'
],
[
'title' => 'Manage Shops',
'url' => admin_url('edit-tags.php?taxonomy=' . BASE . 'shop'),
'icon' => 'dashicons-store'
],
[
'title' => 'Queue Status',
'url' => admin_url('admin.php?page=' . BASE . 'queue_status'),
'icon' => 'dashicons-list-view'
],
[
'title' => 'Manage Styles',
'url' => admin_url('edit-tags.php?taxonomy=' . BASE . 'style'),
'icon' => 'dashicons-admin-customizer'
]
];
foreach ($links as $link) {
?>
= esc_html($link['title']); ?>
actions as $action) {
if (current_user_can($action['capability'])) {
?>
= jvbIcon($action['icon']); ?>
= esc_html($action['label'])?>
=jvbIcon('refresh')?>=jvbIcon('check')?>
rest_url('jvb/v1/admin-action'),
'nonce' => wp_create_nonce('wp_rest'),
'action' => wp_create_nonce('itsme'),
]
);
}
/**
* Create a custom SVG icon for the admin menu
* @param string $icon Icon name
* @param bool $css Whether to convert to CSS
* @return string Base64 encoded SVG icon
*/
protected function getIcon(string $icon = 'logo', bool $css = false): string
{
$svg = jvbIcon($icon, ['wrap' => false]);
if ($css) {
// For CSS, replace currentColor with brand color
$svg = str_replace('currentColor', '#FF0080', $svg);
// Clean and prepare the SVG for CSS
$svg = preg_replace('/[\r\n\t]+/', ' ', $svg); // Remove newlines and tabs
$svg = preg_replace('/\s{2,}/', ' ', $svg); // Minimize spaces
$svg = trim($svg); // Trim whitespace
// Base64 encoding is the most reliable approach for CSS background images
return 'url(data:image/svg+xml;base64,' . base64_encode($svg) . ')';
}
// Convert the SVG to a data URI
return 'data:image/svg+xml;base64,' . base64_encode($svg);
}
public function renderCachePage()
{
$groups = get_option(BASE.'all_cache_groups', []);
?>
Manage Cache
$caches) {
?>
=$group?>