<?php
|
|
use JVBase\integrations\Umami;
|
use JVBase\managers\Cache;
|
use JVBase\managers\ReferralManager;
|
use JVBase\managers\SEO\SEOAdminPage;
|
use JVBase\utility\Features;
|
|
if (!defined('ABSPATH')) {
|
exit; // Exit if accessed directly
|
}
|
|
function jvbActivatePlugin():void
|
{
|
ob_start();
|
$validator = new JVBase\utility\Validator();
|
$validation = $validator->validateAll();
|
error_log('Validation result: '.print_r($validation, true));
|
$checker = JVBase\utility\Checker::getInstance();
|
error_log('Doing our activation action...');
|
// Get ContentRegistry instance early
|
$registry = new JVBase\registry\ContentRegistry();
|
// Initialize content types
|
$registry->onActivation();
|
$checker->invalidateContentCache();
|
$checker->invalidateTaxonomyCache();
|
do_action(BASE.'activation');
|
error_log('Action done!');
|
error_log('Checking custom tables...');
|
(new JVBase\registry\CheckCustomTables())->maybeCreateTables();
|
error_log('Tables created!');
|
|
// Store schema version
|
update_option('jvb_db_version', '1.0.0');
|
error_log('Starting schedules...');
|
jvbSchedules();
|
error_log('Schedules done!');
|
error_log('checking Admin capabilities...');
|
jvbAddAdminCaps();
|
error_log('Admin caps done!');
|
error_log('Removing unneeded roles...');
|
remove_role('contributor');
|
remove_role('author');
|
remove_role('editor');
|
error_log('Roles removed!');
|
error_log('New Roles done!');
|
jvbRegisterAdminPages();
|
if (array_key_exists('integrations', JVB_SITE) && array_key_exists('umami', JVB_SITE['integrations']) && JVB_SITE['integrations']['umami']=== true) {
|
error_log('Adding Umami tables');
|
Umami::createTables();
|
}
|
error_log('Activation done! Huzzah!');
|
|
$output = ob_get_clean();
|
if ( $output ) {
|
// Grab a backtrace to see what caused the output
|
$trace = debug_backtrace( DEBUG_BACKTRACE_IGNORE_ARGS );
|
$formatted = [];
|
foreach ( $trace as $step ) {
|
if ( isset( $step['file'], $step['line'] ) ) {
|
$formatted[] = $step['file'] . ':' . $step['line'];
|
}
|
}
|
|
error_log( "⚠️ Plugin activation produced unexpected output (" . strlen( $output ) . " chars)" );
|
error_log( "Output: " . trim( $output ) );
|
error_log( "Backtrace: " . implode( ' <- ', $formatted ) );
|
}
|
}
|
|
function jvbAddAdminCaps()
|
{
|
$roleManager = new \JVBase\managers\RoleManager();
|
|
$role = get_role('administrator');
|
$users = get_users(['role' => 'administrator']);
|
foreach (JVB_CONTENT as $slug => $config) {
|
|
$plural = strtolower($config['plural']);
|
$capabilities = [
|
'edit_' . $plural,
|
'edit_published_' . $plural,
|
'publish_' . $plural,
|
'delete_' . $plural,
|
'delete_published_' . $plural,
|
'edit_others_' . $plural,
|
'delete_others_' . $plural,
|
'read_private_' . $plural,
|
'edit_private_' . $plural,
|
'delete_private_' . $plural,
|
];
|
|
foreach ($capabilities as $cap) {
|
$role->add_cap($cap, true);
|
}
|
|
foreach ($users as $user) {
|
$roleManager->grantContent($user, $slug);
|
$roleManager->grantOthersContent($user, $slug);
|
}
|
}
|
add_action('init', 'jvbGrantAdminUserCaps', 99);
|
}
|
/**
|
* Grant capabilities to admin users after post types are registered
|
* This runs on init with high priority to ensure post types exist
|
*/
|
function jvbGrantAdminUserCaps()
|
{
|
// Only run once after activation
|
if (get_option('jvb_admin_caps_granted') === '1') {
|
return;
|
}
|
|
$roleManager = new \JVBase\managers\RoleManager();
|
$users = get_users(['role' => 'administrator']);
|
|
foreach (JVB_CONTENT as $slug => $config) {
|
foreach ($users as $user) {
|
// These methods should check if post type exists before adding caps
|
$roleManager->grantContent($user, $slug);
|
$roleManager->grantOthersContent($user, $slug);
|
}
|
}
|
|
// Mark as complete to prevent running again
|
update_option('jvb_admin_caps_granted', '1');
|
remove_action('init', 'jvbGrantAdminUserCaps', 99);
|
}
|
function jvbScheduledHooks()
|
{
|
return [
|
'jvb_daily_reset' => [
|
'time' => '00:01',
|
'recurrence' => 'daily'
|
],
|
'jvb_process_queue' =>
|
[
|
'recurrence' => 'every-minute',
|
],
|
'jvb_queue_maintenance' => [
|
'time' => '1:05am',
|
'recurrence' => 'hourly'
|
],
|
'jvbEmailDailyMetricsReport' =>
|
[
|
'time' => '4:15am tomorrow'
|
],
|
'jvb_generate_daily_report' =>
|
[
|
'time' => '1:20am tomorrow',
|
],
|
'jvb_daily_error_summary' =>
|
[
|
'time' => '7:01am tomorrow',
|
],
|
'jvb_cleanup_expired_approvals' => [],
|
'jvb_cleanupOrphanedFavourites' => [],
|
'jvb_daily_maintenance' => [
|
'time' => '12:03am tomorrow',
|
],
|
//NotificationManager.php
|
'jvb_notification_digest_daily' =>
|
[
|
'time' => '8:08am tomorrow',
|
],
|
'jvb_notification_digest_weekly' =>
|
[
|
'time' => 'monday 6:07am',
|
'recurrence' => 'weekly',
|
],
|
'jvb_notification_digest_monthly' =>
|
[
|
'time' => '2025-05-05 9:00am',
|
'recurrence' => 'monthly',
|
],
|
|
];
|
}
|
|
function jvbSchedules()
|
{
|
$hooks = jvbScheduledHooks();
|
//TODO: ensure we actually need these
|
foreach ($hooks as $hook => $options) {
|
$time = (array_key_exists('time', $options)) ? strtotime($options['time']) : time();
|
|
$recurrence = (array_key_exists('recurrence', $options)) ? $options['recurrence'] : 'daily';
|
|
if (!wp_next_scheduled($hook)) {
|
$result = wp_schedule_event($time, $recurrence, $hook);
|
if (!$result) {
|
error_log('Did not schedule '.$hook.' successfully...'.print_r($result, true));
|
error_log('Time: '.print_r($time, true));
|
error_log('Recurrence: '.print_r($recurrence, true));
|
}
|
}
|
}
|
}
|
|
function jvbDeactivatePlugin()
|
{
|
jvbClearSchedules();
|
jvbDeleteOptions();
|
jvbDeleteDashboard();
|
jvbDeleteDirectories();
|
Cache::flushAll();
|
do_action('jvbDeactivate');
|
}
|
|
function jvbDeleteOptions():void
|
{
|
$options = array_filter(
|
wp_load_alloptions(),
|
fn ($key) => str_starts_with($key, BASE) ||
|
str_starts_with($key, '_transient_'.BASE) ||
|
str_starts_with($key, '_transient_timeout_'.BASE),
|
ARRAY_FILTER_USE_KEY
|
);
|
foreach ($options as $key => $value) {
|
delete_option($key);
|
}
|
}
|
function jvbDeleteDashboard()
|
{
|
$pages = new WP_Query([
|
'post_type' => BASE.'dash',
|
'posts_per_page' => -1,
|
'post_status' => 'any',
|
'fields' => 'ids'
|
]);
|
if ($pages->have_posts()) {
|
foreach ($pages->posts as $ID) {
|
wp_delete_post($ID, true);
|
}
|
}
|
}
|
function jvbDeleteDirectories()
|
{
|
$pages = new WP_Query([
|
'post_type' => BASE.'directory',
|
'posts_per_page' => -1,
|
'post_status' => 'any',
|
'fields' => 'ids'
|
]);
|
if ($pages->have_posts()) {
|
foreach ($pages->posts as $ID) {
|
wp_delete_post($ID, true);
|
}
|
}
|
}
|
function jvbClearSchedules()
|
{
|
$hooks = array_keys(jvbScheduledHooks());
|
foreach ($hooks as $hook) {
|
wp_clear_scheduled_hook($hook);
|
}
|
}
|
|
// Optional: Add upgrade routine
|
function jvbMaybeUpgrade():void
|
{
|
$current_version = get_option('jvb_db_version', '0');
|
if (version_compare($current_version, '1.0.0', '<')) {
|
jvbActivatePlugin();
|
}
|
}
|
add_action('plugins_loaded', 'jvbMaybeUpgrade');
|
|
|
add_action('jvb_daily_reset', 'jvbDailyResetAction');
|
function jvbDailyResetAction(): void
|
{
|
do_action('jvbDailyReset');
|
error_log('Daily options reset completed at ' . current_time('Y-m-d H:i:s'));
|
}
|
|
|
function jvbRegisterAdminPages():void
|
{
|
if (Features::forSite()->has('referrals')){
|
ReferralManager::addSubpage();
|
}
|
SEOAdminPage::addSubpage();
|
}
|