$request->get_route(), 'method' => $request->get_method(), 'params' => $request->get_params(), 'time' => microtime(true), ]; // Set up error handler for this request set_error_handler(function($errno, $errstr, $errfile, $errline) { if (!(error_reporting() & $errno)) { return false; } $context = array_merge($GLOBALS['jvb_rest_request'] ?? [], [ 'error_type' => $errno, 'error_message' => $errstr, 'file' => $errfile, 'line' => $errline, 'user_id' => get_current_user_id(), ]); error_log('JVB REST Error: ' . json_encode($context)); return false; // Let PHP handle it normally too }); return $result; }, 10, 3); add_filter('rest_post_dispatch', function($result, $server, $request) { // Restore default error handler restore_error_handler(); // Check for fatal errors that occurred during request $error = error_get_last(); if ($error && in_array($error['type'], [E_ERROR, E_USER_ERROR, E_PARSE, E_COMPILE_ERROR])) { $context = array_merge($GLOBALS['jvb_rest_request'] ?? [], [ 'fatal_error' => $error, 'user_id' => get_current_user_id(), ]); error_log('JVB REST Fatal: ' . json_encode($context)); } // Clean up unset($GLOBALS['jvb_rest_request']); return $result; }, 10, 3); const JVB_LOCAL = 'northeh.test'; function jvbIgnoredPostTypes():array { return [BASE.'directory', BASE.'dash', 'attachment', 'revision', 'nav_menu_item']; } add_filter('show_admin_bar', '__return_false'); const JVB_TESTING = true; const JVB_DIR = WP_PLUGIN_DIR . '/jvb'; define('JVB_URL', plugin_dir_url(__FILE__)); // Session Security define('JVB_SESSION_FINGERPRINT', true); // Login Security define('JVB_MAX_LOGIN_ATTEMPTS', 5); define('JVB_LOCKOUT_DURATION', 15 * MINUTE_IN_SECONDS); require(JVB_DIR.'/base/_setup.php'); //error_log('###############################################'); //error_log('Registered Base'); //error_log('###############################################'); //error_log('BASE: '.print_r(BASE, true)); //error_log('JVB_SITE: '.print_r(JVB_SITE, true)); //error_log('JVB_OPTIONS: '.print_r(JVB_OPTIONS, true)); //error_log('JVB_CONTENT: '.print_r(JVB_CONTENT, true)); //error_log('JVB_TAXONOMY: '.print_r(JVB_TAXONOMY, true)); //error_log('JVB_LOGIN: '.print_r(JVB_LOGIN, true)); //error_log('JVB_MEMBERSHIP: '.print_r(JVB_MEMBERSHIP, true)); //error_log('JVB_USER: '.print_r(JVB_USER, true)); if (empty(JVB_SITE)) { return; } require(JVB_DIR.'/inc/utility/setup.php'); require(JVB_DIR.'/checks.php'); require(JVB_DIR.'/globals.php'); $jvb_feed = jvbGlobalFeedContent(); $jvb_taxonomy_for= jvbGlobalTaxonomyFor(); $jvb_responses = jvbGlobalResponses(); global $jvb_everything; $jvb_everything = array_merge(JVB_CONTENT, JVB_TAXONOMY); require(JVB_DIR . '/inc/registry/_setup.php'); require(JVB_DIR . '/activate.php'); require(JVB_DIR . '/inc/helpers/all.php'); require(JVB_DIR . '/inc/meta/_setup.php'); require(JVB_DIR . '/inc/managers/_setup.php'); function jvbIcon($name, $options = []) { return IconsManager::getInstance()->getIcon($name, $options); } function jvbCSSIcon($name, $options = []) { $style = array_key_exists('style', $options) ? $options['style'] : null; return IconsManager::getInstance()->getCSSIcon($name, $style); } require(JVB_DIR . '/inc/integrations/_setup.php'); require(JVB_DIR . '/inc/rest/_setup.php'); add_filter( 'cron_schedules', 'jvbCronSchedules'); function jvbCronSchedules($schedules) { $schedules[ 'every-5-minutes' ] = [ 'interval' => 5 * 60, 'display' => __('Every 5 minutes', 'jvb') ]; $schedules[ 'every-minute' ] = [ 'interval' => 60, 'display' => __('Every minute', 'jvb') ]; $schedules[ 'monthly' ] = [ 'interval' => 604800 * 4, 'display' => __('Once Monthly', 'jvb') ]; return $schedules; } register_activation_hook(JVB_DIR.'/jvb.php', 'jvbActivatePlugin'); register_deactivation_hook(JVB_DIR.'/jvb.php', 'jvbDeactivatePlugin'); add_action('init', 'jvbUserCheck'); function jvbUserCheck():void { if (is_admin() && isOurPeople()) { wp_redirect(get_home_url(null, '/dash')); exit; } } require(JVB_DIR . '/inc/users/UserSettings.php'); require(JVB_DIR . '/inc/templates.php'); /** * Utilities */ require(JVB_DIR . '/cleanup.php'); require(JVB_DIR . '/inc/admin/_setup.php'); require(JVB_DIR . '/JVBase.php'); add_action('init', 'jvbLoadBase', 1); function jvbLoadBase():void { JVB::getInstance(); } function JVB(): JVB { return JVB::getInstance(); } function checkIf(): Checker { return JVBase\utility\Checker::getInstance(); } require(JVB_DIR . '/inc/blocks/_setup.php'); add_filter('upload_mimes', function ($mimes) { $mimes['webp'] = 'image/webp'; $mimes['avif'] = 'image/avif'; return $mimes; }); // And this to ensure WebP is treated as an image add_filter('file_is_displayable_image', function ($result, $path) { if (preg_match('/\.webp$/i', $path)) { return true; } return $result; }, 10, 2); function jvbDump(mixed $array, string $name = 'var'):void { highlight_string(""); } /** * Scripts */ add_action('wp_enqueue_scripts', 'jvbScripts', 10); function jvbScripts():void { /** * Register Scripts */ //Helper functions used by other classes wp_register_script( 'jvb-utility', JVB_URL.'assets/js/min/utility.min.js', [], '1.0.1', [ 'strategy' => 'defer', 'in_footer' => true, ] ); wp_register_script( 'jvb-favourites', JVB_URL.'assets/js/min/favourites.min.js', [ 'jvb-queue', 'jvb-data-store' ], '1.0.1', [ 'strategy' => 'defer', 'in_footer' => true, ] ); wp_register_script( 'jvb-votes', JVB_URL.'assets/js/min/votes.min.js', [ 'jvb-queue', 'jvb-data-store' ], '1.0.1', [ 'strategy' => 'defer', 'in_footer' => true, ] ); wp_register_script( 'jvb-settings', JVB_URL.'assets/js/min/settings.min.js', [ // 'jvb-queue', 'jvb-utility', 'jvb-data-store' ], '1.0.1', [ 'strategy' => 'defer', 'in_footer' => true, ] ); wp_register_script( 'jvb-popup', JVB_URL.'assets/js/min/popup.min.js', [ 'jvb-a11y' ], '1.0.1', [ 'strategy' => 'defer', 'in_footer' => true ] ); //Main js image resizing, and gallery //TODO: lots of overlap between modals and this, utilize a11y for trapFocus, wp_register_script( 'jvb-media', JVB_URL.'assets/js/min/media.min.js', [], '1.0.1', [ 'strategy' => 'defer', 'in_footer' => true, ] ); wp_register_script( 'jvb-copy-hours', JVB_URL.'assets/js/min/hours.min.js', [ 'jvb-form', 'jvb-utility', 'jvb-modal', 'jvb-a11y' ], '1.0.1', [ 'strategy' => 'defer', 'in_footer' => true, ] ); //Includes the escape and outside click listeners and intersection observers //TODO: make the Modals class use this? // wp_register_script( // 'jvb-ui', // JVB_URL.'assets/js/min/ui.min.js', // [], // '1.0.0', // [ // 'strategy' => 'defer', // 'in_footer' => true, // ] // ); wp_register_script( 'jvb-gallery', JVB_URL.'assets/js/min/gallery.min.js', [ 'jvb-utility', // 'jvb-queue', 'jvb-modal', // 'jvb-swiper', ], '1.0.1', [ 'strategy' => 'defer', 'in_footer' => true, ] ); wp_register_script( 'jvb-swiper', JVB_URL.'assets/js/min/swiper.min.js', [ 'jvb-utility', ], '1.0.1', [ 'strategy' => 'defer', 'in_footer' => true, ] ); wp_register_script( 'jvb-integrations', JVB_URL.'assets/js/min/integrations.min.js', [], '1.0.1', [ 'strategy' => 'defer', 'in_footer' => true ] ); $integration_nonces = [ 'jvb_square_sync' => wp_create_nonce('jvb_square_sync'), 'jvb_gmb_sync_reviews' => wp_create_nonce('jvb_gmb_sync'), 'jvb_gmb_test_api' => wp_create_nonce('jvb_gmb_test'), 'jvb_bluesky_test_post' => wp_create_nonce('jvb_bluesky_test'), 'jvb_facebook_test_post' => wp_create_nonce('jvb_facebook_test'), 'jvb_instagram_test_post' => wp_create_nonce('jvb_instagram_test'), 'jvb_instagram_sync_media' => wp_create_nonce('jvb_instagram_sync'), 'jvb_umami_refresh_data' => wp_create_nonce('jvb_umami_refresh'), 'jvb_export_integration_settings' => wp_create_nonce('jvb_integration_export'), ]; $data = [ 'ajaxUrl' => admin_url('admin-ajax.php'), 'nonce' => wp_create_nonce('jvb_integrations'), 'nonces' => $integration_nonces, // 'services' => array_keys(jvbConnect()->getAvailableServices()), 'userId' => get_current_user_id(), 'baseUrl' => admin_url('admin.php?page=' . BASE) ]; wp_localize_script( 'jvb-integrations', 'jvbIntegrationsConfig', $data ); //The On-This-Page menu. TODO: just include in ui? wp_register_script( 'jvb-page-nav', JVB_URL.'assets/js/min/page-nav.min.js', [], '1.0.1', [ 'strategy' => 'defer', 'in_footer' => true, ] ); //A11y accessibility wp_register_script( 'jvb-a11y', JVB_URL.'assets/js/min/a11y.min.js', [], '1.0.1', [ 'strategy' => 'defer', 'in_footer' => true, ] ); //Central Error Management wp_register_script( 'jvb-error', JVB_URL.'assets/js/min/error.min.js', [ ], '1.0.1', [ 'strategy' => 'defer', 'in_footer' => true, ] ); //Cache Management wp_register_script( 'jvb-cache', JVB_URL.'assets/js/min/cache.min.js', [], '1.0.1', [ 'strategy' => 'defer', 'in_footer' => true, ] ); wp_register_Script( 'jvb-data-store', JVB_URL.'assets/js/min/dataStore.min.js', [], '1.0.1', [ 'strategy' => 'defer', 'in_footer' => true, ] ); //Tabs functionality wp_register_script( 'jvb-tabs', JVB_URL.'assets/js/min/tabs.min.js', [ 'jvb-a11y' ], '1.0.1', [ 'strategy' => 'defer', 'in_footer' => true, ] ); //Modal functionality wp_register_script( 'jvb-modal', JVB_URL.'assets/js/min/modal.min.js', [ 'jvb-a11y' ], '1.0.1', [ 'strategy' => 'defer', 'in_footer' => true, ] ); //Central Queue Management wp_register_script( 'jvb-queue', JVB_URL.'assets/js/min/queue.min.js', [ 'jvb-a11y', 'jvb-error', 'jvb-data-store', 'jvb-utility', 'jvb-popup' ], '1.0.1', [ 'strategy' => 'defer', 'in_footer' => true, ] ); //TaxonomySelector.js wp_register_script( 'jvb-selector', JVB_URL.'assets/js/min/selector.min.js', [ 'jvb-utility', 'jvb-a11y', 'jvb-error', 'jvb-data-store', 'jvb-modal', // 'jvb-loading' ], '1.0.1', [ 'strategy' => 'defer', 'in_footer' => true, ] ); wp_register_script( 'jvb-creator', JVB_URL.'assets/js/min/creator.min.js', ['jvb-selector'], '1.0.1', [ 'strategy' => 'defer', 'in_footer' => true ] ); //PostSelector.js wp_register_script( 'jvb-post-selector', JVB_URL.'assets/js/min/postSelector.min.js', [ 'jvb-selector' ], '1.0.1', [ 'strategy' => 'defer', 'in_footer' => true, ] ); // //Central Loading Manager // wp_register_script( // 'jvb-loading', // JVB_URL.'assets/js/min/loading.min.js', // [], // '1.0.0', // [ // 'strategy' => 'defer', // 'in_footer' => true, // ] // ); // wp_localize_script( // 'jvb-loading', // 'loadingQuips', // [ // 'quips' => json_encode(apply_filters( // 'jvbLoadingQuips', // [] // )) // ] // ); //Upload Manager wp_register_script( 'jvb-handle-selection', JVB_URL.'assets/js/min/handleSelection.min.js', [ 'jvb-a11y', 'jvb-utility', ], '1.0.1', [ 'strategy' => 'defer', 'in_footer' => true, ] ); wp_register_script( 'jvb-drag-handler', JVB_URL.'assets/js/min/dragHandler.min.js', [ 'jvb-a11y', 'jvb-utility', ], '1.0.1', [ 'strategy' => 'defer', 'in_footer' => true, ] ); //Upload Manager wp_register_script( 'jvb-uploader', JVB_URL.'assets/js/min/uploader.min.js', [ 'sortable-js', 'jvb-cache', 'jvb-a11y', 'jvb-utility', 'jvb-handle-selection', 'jvb-modal', 'jvb-drag-handler', // 'jvb-loading', 'jvb-queue', 'jvb-notifications' ], '1.0.1', [ 'strategy' => 'defer', 'in_footer' => true, ] ); wp_register_script( 'quill-js', 'https://cdn.jsdelivr.net/npm/quill@2.0.3/dist/quill.js', [], null, true ); wp_register_script( 'sortable-js', 'https://cdn.jsdelivr.net/npm/sortablejs@latest/Sortable.min.js', array(), null, true ); //Custom Dashboard Navigator // wp_register_script( // 'jvb-dashboard-navigator', // JVB_URL.'assets/js/min/DashboardNavigator.min.js', // [ // 'jvb-a11y', // 'jvb-loading', // 'jvb-content', // 'jvb-crud', // 'jvb-tabs' // ], // '1.0.0', // [ // 'strategy' => 'defer', // 'in_footer' => true, // ] // ); //Notifications wp_register_script( 'jvb-notifications', JVB_URL.'assets/js/min/notifications.min.js', [ 'jvb-utility', ], '1.0.1', [ 'strategy' => 'defer', 'in_footer' => true, ] ); //Base Form Handler wp_register_script( 'jvb-form', JVB_URL.'assets/js/min/form.min.js', [ 'jvb-utility', 'jvb-tabs', 'jvb-selector', 'jvb-uploader', 'sortable-js', 'jvb-populate-form', 'jvb-quill', ], '1.0.1', [ 'strategy' => 'defer', 'in_footer' => true, ] ); wp_register_script( 'jvb-populate-form', JVB_URL.'assets/js/min/populate.min.js', [], '1.0.1', [ 'strategy' => 'defer', 'in_footer' => true, ] ); wp_register_script( 'jvb-quill', JVB_URL.'assets/js/min/quill.min.js', [ 'quill-js' ], '1.0.1', [ 'strategy' => 'defer', 'in_footer' => true, ] ); //CRUD Base Manager wp_register_script( 'jvb-crud', JVB_URL.'assets/js/min/crud.min.js', [ 'jvb-selector', 'jvb-settings', 'jvb-a11y', 'jvb-error', 'jvb-data-store', 'jvb-populate-form', 'jvb-queue', 'jvb-utility', 'jvb-quill', 'jvb-form', 'jvb-view', 'jvb-modal' ], '1.0.1', [ 'strategy' => 'defer', 'in_footer' => true, ] ); wp_register_script( 'jvb-view', JVB_URL.'assets/js/min/view.min.js', [ 'jvb-settings', 'jvb-a11y', 'jvb-utility', 'jvb-data-store', 'jvb-error', 'jvb-populate-form' ], '1.0.1', [ 'strategy' => 'defer', 'in_footer' => true, ] ); //Bio Manager TODO: Replace with Form Handler wp_register_script( 'jvb-bio', JVB_URL.'assets/js/min/bioManager.min.js', [ 'jvb-tabs', 'jvb-form', 'jvb-queue' ], '1.0.1', [ 'strategy' => 'defer', 'in_footer' => true, ] ); //Shop Manager TODO: Replace with Form Handler wp_register_script( 'jvb-shop', JVB_URL.'assets/js/min/shopManager.min.js', [ 'jvb-tabs', 'jvb-form', 'jvb-queue' ], '1.0.1', [ 'strategy' => 'defer', 'in_footer' => true, ] ); //Content Manager TODO: Replace with CRUD.js wp_register_script( 'jvb-content', JVB_URL.'assets/js/min/ContentManager.min.js', [ 'jvb-queue', 'jvb-cache', 'jvb-error', 'jvb-uploader', 'jvb-utility', 'jvb-modal', 'jvb-selector', 'jvb-post-selector', ], '1.0.1', [ 'strategy' => 'defer', 'in_footer' => true, ] ); //Favourites Manager TODO: Replace with CRUD.js wp_register_script( 'jvb-favourites', JVB_URL.'assets/js/min/favouritesManager.min.js', [ 'jvb-a11y', 'jvb-queue', 'jvb-cache', 'jvb-error', 'jvb-utility', 'jvb-tabs', 'jvb-selector', 'jvb-notifications', ], '1.0.1', [ 'strategy' => 'defer', 'in_footer' => true, ] ); //News Manager TODO: Replace with CRUD.js wp_register_script( 'jvb-news', JVB_URL.'assets/js/min/news.min.js', [ 'jvb-a11y', 'jvb-queue', 'jvb-cache', 'jvb-error', 'jvb-utility', 'jvb-modal', 'jvb-selector', 'jvb-tabs', ], '1.0.1', [ 'strategy' => 'defer', 'in_footer' => true, ] ); //Notification Manager TODO: Replace with CRUD? Not quite... wp_register_script( 'jvb-notification-manager', JVB_URL.'assets/js/min/notificationManager.min.js', [ 'jvb-a11y', 'jvb-tabs', ] ); wp_register_script( 'jvb-navigation', JVB_URL.'assets/js/min/navigation.min.js', ); add_action('wp_head', 'jvbInlineNavStyles'); if (Features::forSite()->has('dashboard')) { wp_enqueue_script('jvb-queue'); } wp_enqueue_script('jvb-settings'); wp_enqueue_script('jvb-navigation'); // wp_enqueue_script('jvb-ui'); wp_enqueue_script('jvb-media'); wp_enqueue_script('jvb-gallery'); wp_enqueue_script('jvb-cache'); $userID = get_current_user_id(); $queue = (is_user_logged_in()) ? [ 'api' => rest_url('jvb/v1/'), 'currentUser' => $userID, 'nonce' => wp_create_nonce('wp_rest'), 'dash' => wp_create_nonce('dash-'.$userID), 'favourites' => wp_create_nonce('favourites-'.$userID), 'notifications' => wp_create_nonce('notifications-'.$userID), 'labels' => jvbGetLabels(), ] : [ 'api' => rest_url('jvb/v1/'), 'nonce' => wp_create_nonce('wp_rest'), 'currentUser' => false, 'redirect' => wp_login_url(home_url(add_query_arg(null, null))), // Current URL as redirect 'labels' => jvbGetLabels(), ]; wp_localize_script('jvb-utility', 'jvbSettings', $queue); $initUserSettings = 'async function initUserItems() { if (!jvbSettings.currentUser) return; window.userFavourites = {}; window.userVotes = {}; '; if (Features::forSite()->has('favourites')) { wp_enqueue_script('jvb-favourites'); $initUserSettings .= ' //Fetch user favourites try { const result = await window.jvbCache.fetchWithCache( `${jvbSettings.api}favourites?all=true`, { method: \'GET\', headers: {\'X-WP-Nonce\': jvbSettings.nonce} } ); if (result && result.favourites) { for (const key in result.favourites) { window.userFavourites[key] = new Set(); result.favourites[key].forEach(id => { window.userFavourites[key].add(parseInt(id)); }); } } } catch (error) { console.error(\'Failed to fetch user favourites:\', error); }'; } if (Features::anyContentHas('karma') || Features::anyTaxonomyHas('karma') || Features::anyUserHas('karma')) { wp_enqueue_script('jvb-votes'); $initUserSettings .= '// Fetch user votes try { const result = await window.jvbCache.fetchWithCache( `${jvbSettings.api}vote?user=${jvbSettings.currentUser}`, { method: \'GET\', headers: {\'X-WP-Nonce\': jvbSettings.nonce} }, {forceRefresh: true} ); window.userVotes = {}; if (result) { for (const key in result) { window.userVotes[key] = new Map(); for (const [id, vote] of Object.entries(result[key])) { window.userVotes[key].set(parseInt(id), vote); } } } } catch (error) { console.error(\'Failed to fetch user votes:\', error); }'; } $initUserSettings .= '} initUserItems();'; // wp_add_inline_script('jvb-queue', $initUserSettings, 'after'); if (is_search() || is_tax(BASE.'shop') || is_singular(BASE.'artist') || jvbIsDirectory() ) { wp_enqueue_script('jvb-page-nav'); } // Only load on single shop pages or other relevant pages if (is_tax(BASE.'shop') || is_singular(BASE.'partner')) { $ID = get_queried_object_id(); if (is_tax()) { $check = get_term_meta($ID, BASE.'has_map', true); } else { $check = get_post_meta($ID, BASE.'has_map', true); } // if ($check && $check !== '') { //// wp_enqueue_script( //// 'google-maps-frontend', //// 'https://maps.googleapis.com/maps/api/js?key=' . GOOGLE_API . '&callback=googleMapsLoaded', //// [], //// null, //// ['strategy' => 'async', //// 'in_footer' => true] //// ); // // // Add the callback function // wp_add_inline_script('google-maps-frontend', ' // function googleMapsLoaded() { // if (window.googleMapsCallbacks && window.googleMapsCallbacks.length) { // window.googleMapsCallbacks.forEach(callback => callback()); // } // } // '); // } } if (is_user_logged_in() && Features::forSite()->has('notifications')) { wp_enqueue_script('jvb-notifications'); wp_localize_script('jvb-notifications', 'notificationSettings', array( 'homeUrl' => home_url(), 'strings' => array( 'loading' => 'Loading...', 'error' => 'Failed to load notifications', 'noNotifications' => 'No new notifications', 'viewAll' => 'View All Notifications', 'markRead' => 'Mark as read', 'review' => 'Review' ) )); } jvbAddScriptDependency('jvb-feed-view-script', 'jvb-queue'); jvbAddScriptDependency('jvb-feed-view-script', 'jvb-selector'); jvbAddScriptDependency('jvb-feed-view-script', 'jvb-data-store'); jvbAddScriptDependency('jvb-feed-view-script', 'jvb-cache'); jvbAddScriptDependency('jvb-feed-view-script', 'jvb-a11y'); jvbAddScriptDependency('jvb-feed-view-script', 'jvb-utility'); jvbAddScriptDependency('jvb-feed-view-script', 'jvb-gallery'); // jvbAddScriptDependency('jvb-feed-view-script', 'jvb-loading'); jvbAddScriptDependency('jvb-forms-view-script', 'jvb-queue'); jvbAddScriptDependency('jvb-forms-view-script', 'jvb-quill'); jvbAddScriptDependency('jvb-forms-view-script', 'jvb-form'); jvbAddScriptDependency('jvb-forms-view-script', 'jvb-tabs'); } function jvbAdminMap():void { // wp_enqueue_script( // 'google-maps', // 'https://maps.googleapis.com/maps/api/js?key=' . GOOGLE_API . '&libraries=places&callback=googleMapsLoaded', // [], // null, // [ // 'strategy' => 'async', // 'in_footer' => true // ] // ); // // // Add the callback function // wp_add_inline_script('google-maps', ' // function googleMapsLoaded() { // if (window.googleMapsCallbacks && window.googleMapsCallbacks.length) { // window.googleMapsCallbacks.forEach(callback => callback()); // } // } // '); } function jvbAddScriptDependency(string $handle, string $dep):bool { global $wp_scripts; $script = $wp_scripts->query($handle); if (!$script) { return false; } if (!in_array($dep, $script->deps)) { $script->deps[] = $dep; } return true; } add_action('wp_body_open', 'jvbAccessibility'); function jvbAccessibility():void { echo '
'; } //add_action('wp_head', 'jvbDumpIt'); function jvbDumpIt() { } add_action('after_setup_theme', 'jvbImageSize'); function jvbImageSize():void { add_theme_support('post-thumbnails'); add_image_size( 'tiny', 50, 50, false ); } // //add_action('rest_api_init', function() { // error_log('User ' . get_current_user_id() . ' can edit pages: ' . (current_user_can('edit_pages') ? 'yes' : 'no')); // error_log('User roles: ' . print_r(wp_get_current_user()->roles, true)); //}); // //add_filter('rest_pre_dispatch', function($result, $server, $request) { // if (strpos($request->get_route(), '/wp/v2/pages') !== false) { // error_log('Pages request - User: ' . get_current_user_id()); // error_log('Can edit pages: ' . (current_user_can('edit_pages') ? 'yes' : 'no')); // error_log('Nonce: ' . $request->get_header('X-WP-Nonce')); // } // return $result; //}, 10, 3);