Jake Vanderwerf
2025-11-25 2a2303d1dccc120dd7aa5f6b6ade0f89e0064850
jvb.php
@@ -10,6 +10,7 @@
*/
use JVBase\JVB;
use JVBase\managers\IconsManager;
use JVBase\utility\Checker;
use JVBase\utility\Features;
@@ -18,14 +19,82 @@
    exit;
}
/**
 * Track REST API errors by wrapping request execution
 */
add_filter('rest_pre_dispatch', function($result, $server, $request) {
   // Store request details globally for error logging
   $GLOBALS['jvb_rest_request'] = [
      'route' => $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 = 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');
@@ -54,15 +123,26 @@
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/importers/_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');
require(JVB_DIR . '/inc/meta/_setup.php');
add_filter( 'cron_schedules', 'jvbCronSchedules');
function jvbCronSchedules($schedules)
@@ -161,7 +241,7 @@
/**
 * Scripts
 */
add_action('wp_enqueue_scripts', 'jvbScripts', 999);
add_action('wp_enqueue_scripts', 'jvbScripts', 10);
function jvbScripts():void
{
@@ -173,7 +253,7 @@
        'jvb-utility',
        JVB_URL.'assets/js/min/utility.min.js',
        [],
        '1.0.0',
        '1.0.1',
        [
            'strategy'    => 'defer',
            'in_footer'    => true,
@@ -187,7 +267,7 @@
         'jvb-queue',
         'jvb-data-store'
      ],
      '1.0.0',
      '1.0.1',
      [
         'strategy'    => 'defer',
         'in_footer'    => true,
@@ -200,7 +280,22 @@
         'jvb-queue',
         'jvb-data-store'
      ],
      '1.0.0',
      '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,
@@ -213,7 +308,7 @@
      [
         'jvb-a11y'
      ],
      '1.0.0',
      '1.0.1',
      [
         'strategy'  => 'defer',
         'in_footer' => true
@@ -226,7 +321,7 @@
        'jvb-media',
        JVB_URL.'assets/js/min/media.min.js',
        [],
        '1.0.0',
        '1.0.1',
        [
            'strategy'    => 'defer',
            'in_footer' => true,
@@ -242,7 +337,7 @@
         'jvb-modal',
         'jvb-a11y'
      ],
      '1.0.0',
      '1.0.1',
      [
         'strategy'  => 'defer',
         'in_footer' => true,
@@ -267,9 +362,11 @@
        JVB_URL.'assets/js/min/gallery.min.js',
        [
         'jvb-utility',
         'jvb-queue'
//       'jvb-queue',
         'jvb-modal',
//       'jvb-swiper',
      ],
        '1.0.0',
        '1.0.1',
        [
            'strategy'    => 'defer',
            'in_footer'    => true,
@@ -277,10 +374,23 @@
    );
   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.0',
      '1.0.1',
      [
         'strategy'  => 'defer',
         'in_footer' => true
@@ -318,7 +428,7 @@
        'jvb-page-nav',
        JVB_URL.'assets/js/min/page-nav.min.js',
        [],
        '1.0.0',
        '1.0.1',
        [
            'strategy'    => 'defer',
            'in_footer'    => true,
@@ -330,7 +440,7 @@
        'jvb-a11y',
        JVB_URL.'assets/js/min/a11y.min.js',
        [],
        '1.0.0',
        '1.0.1',
        [
            'strategy'    => 'defer',
            'in_footer'    => true,
@@ -344,7 +454,7 @@
        [
        ],
        '1.0.0',
        '1.0.1',
        [
            'strategy'    => 'defer',
            'in_footer'    => true,
@@ -356,7 +466,7 @@
        'jvb-cache',
        JVB_URL.'assets/js/min/cache.min.js',
        [],
        '1.0.0',
        '1.0.1',
        [
            'strategy'    => 'defer',
            'in_footer'    => true,
@@ -367,7 +477,7 @@
      'jvb-data-store',
      JVB_URL.'assets/js/min/dataStore.min.js',
      [],
      '1.0.0',
      '1.0.1',
      [
         'strategy'  => 'defer',
         'in_footer' => true,
@@ -381,7 +491,7 @@
        [
            'jvb-a11y'
        ],
        '1.0.0',
        '1.0.1',
        [
            'strategy'    => 'defer',
            'in_footer'    => true,
@@ -395,7 +505,7 @@
        [
            'jvb-a11y'
        ],
        '1.0.0',
        '1.0.1',
        [
            'strategy'    => 'defer',
            'in_footer'    => true,
@@ -413,7 +523,7 @@
            'jvb-utility',
         'jvb-popup'
        ],
        '1.0.0',
        '1.0.1',
        [
            'strategy'    => 'defer',
            'in_footer'    => true,
@@ -432,7 +542,7 @@
            'jvb-modal',
//            'jvb-loading'
        ],
        '1.0.0',
        '1.0.1',
        [
            'strategy'    => 'defer',
            'in_footer'    => true,
@@ -443,7 +553,7 @@
      'jvb-creator',
      JVB_URL.'assets/js/min/creator.min.js',
      ['jvb-selector'],
      '1.0.0',
      '1.0.1',
      [
         'strategy'    => 'defer',
         'in_footer'    => true
@@ -457,7 +567,7 @@
        [
            'jvb-selector'
        ],
        '1.0.0',
        '1.0.1',
        [
            'strategy'    => 'defer',
            'in_footer'    => true,
@@ -494,7 +604,7 @@
         'jvb-a11y',
            'jvb-utility',
        ],
        '1.0.0',
        '1.0.1',
        [
            'strategy'    => 'defer',
            'in_footer'    => true,
@@ -507,7 +617,7 @@
         'jvb-a11y',
            'jvb-utility',
        ],
        '1.0.0',
        '1.0.1',
        [
            'strategy'    => 'defer',
            'in_footer'    => true,
@@ -519,17 +629,18 @@
        'jvb-uploader',
        JVB_URL.'assets/js/min/uploader.min.js',
        [
         'sortable-multidrag',
         'jvb-cache',
         'jvb-a11y',
            'jvb-utility',
         'jvb-handle-selection',
         'jvb-modal',
         'jvb-drag-handler',
//       'jvb-drag-handler',
//            'jvb-loading',
            'jvb-queue',
            'jvb-notifications'
        ],
        '1.0.0',
        '1.0.1',
        [
            'strategy'    => 'defer',
            'in_footer'    => true,
@@ -552,6 +663,15 @@
      true
   );
   // Load MultiDrag plugin
   wp_register_script(
      'sortable-multidrag',
      'https://cdn.jsdelivr.net/npm/sortablejs@latest/plugins/MultiDrag.min.js',
      array('sortable-js'),
null,
      true
   );
    //Custom Dashboard Navigator
//    wp_register_script(
//        'jvb-dashboard-navigator',
@@ -577,7 +697,7 @@
        [
            'jvb-utility',
        ],
        '1.0.0',
        '1.0.1',
        [
            'strategy'    => 'defer',
            'in_footer' => true,
@@ -593,9 +713,11 @@
            'jvb-tabs',
            'jvb-selector',
            'jvb-uploader',
         'sortable-js'
         'sortable-js',
         'jvb-populate-form',
         'jvb-quill',
        ],
        '1.0.0',
        '1.0.1',
        [
            'strategy'    => 'defer',
            'in_footer'    => true,
@@ -606,7 +728,7 @@
      'jvb-populate-form',
      JVB_URL.'assets/js/min/populate.min.js',
      [],
      '1.0.0',
      '1.0.1',
      [
         'strategy'  => 'defer',
         'in_footer' => true,
@@ -618,7 +740,7 @@
      [
         'quill-js'
      ],
      '1.0.0',
      '1.0.1',
      [
         'strategy'  => 'defer',
         'in_footer' => true,
@@ -630,6 +752,7 @@
        JVB_URL.'assets/js/min/crud.min.js',
        [
         'jvb-selector',
         'jvb-settings',
            'jvb-a11y',
            'jvb-error',
            'jvb-data-store',
@@ -641,7 +764,7 @@
         'jvb-view',
         'jvb-modal'
        ],
        '1.0.0',
        '1.0.1',
        [
            'strategy'    => 'defer',
            'in_footer'    => true,
@@ -652,13 +775,14 @@
      '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.0',
      '1.0.1',
      [
         'strategy'  => 'defer',
         'in_footer' => true,
@@ -674,7 +798,7 @@
            'jvb-form',
            'jvb-queue'
        ],
        '1.0.0',
        '1.0.1',
        [
            'strategy'    => 'defer',
            'in_footer'    => true,
@@ -690,7 +814,7 @@
            'jvb-form',
            'jvb-queue'
        ],
        '1.0.0',
        '1.0.1',
        [
            'strategy'    => 'defer',
            'in_footer'    => true,
@@ -711,7 +835,7 @@
            'jvb-selector',
            'jvb-post-selector',
        ],
        '1.0.0',
        '1.0.1',
        [
            'strategy'    => 'defer',
            'in_footer'    => true,
@@ -732,7 +856,7 @@
            'jvb-selector',
            'jvb-notifications',
        ],
        '1.0.0',
        '1.0.1',
        [
            'strategy'    => 'defer',
            'in_footer'    => true,
@@ -753,7 +877,7 @@
            'jvb-selector',
            'jvb-tabs',
        ],
        '1.0.0',
        '1.0.1',
        [
            'strategy'    => 'defer',
            'in_footer'    => true,
@@ -775,27 +899,22 @@
      JVB_URL.'assets/js/min/navigation.min.js',
   );
    add_action('wp_head', 'jvbInlineNavStyles');
    wp_enqueue_script('jvb-queue');
   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');
    wp_localize_script(
        'jvb-cache',
        'cacheJVB',
        [
            'cache' => json_encode(jvbGetCache())
        ]
    );
    $userID = get_current_user_id();
   $icons = new \JVBase\JVBIcons();
    $queue = (is_user_logged_in()) ?
        [
            'api'             => rest_url('jvb/v1/'),
@@ -804,7 +923,6 @@
            'dash'            => wp_create_nonce('dash-'.$userID),
            'favourites'    => wp_create_nonce('favourites-'.$userID),
            'notifications'    => wp_create_nonce('notifications-'.$userID),
            'icons'            => $icons->localizeIcons(),
         'labels'       => jvbGetLabels(),
        ] :
        [
@@ -812,11 +930,12 @@
            'nonce'       => wp_create_nonce('wp_rest'),
            'currentUser' => false,
            'redirect'    => wp_login_url(home_url(add_query_arg(null, null))), // Current URL as redirect
            'icons'       => $icons->localizeIcons(),
         'labels'       => jvbGetLabels(),
        ];
    wp_localize_script('jvb-queue', 'jvbSettings', $queue);
    wp_localize_script('jvb-utility', 'jvbSettings', $queue);
   $initUserSettings = 'async function initUserItems() {
   if (!jvbSettings.currentUser) return;
@@ -920,7 +1039,7 @@
//        ');
//        }
    }
    if (is_user_logged_in()) {
    if (is_user_logged_in() && Features::forSite()->has('notifications')) {
        wp_enqueue_script('jvb-notifications');
        wp_localize_script('jvb-notifications', 'notificationSettings', array(
@@ -938,6 +1057,10 @@
    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');
@@ -996,21 +1119,27 @@
//add_action('wp_head', 'jvbDumpIt');
function jvbDumpIt()
{
}
//add_filter('map_meta_cap', function($caps, $cap, $user_id, $args) {
// error_log('Caps: '.print_r($caps, true));
// error_log('Cap: '.print_r($cap, true));
// error_log('User ID: '.print_r($user_id, true));
// error_log('Args: '.print_r($args, true));
// return $caps;
//}, 10, 4);
add_action('after_setup_theme', 'jvbImageSize');
function jvbImageSize():void
{
   add_theme_support('post-thumbnails');
   add_image_size( 'tiny', 50, 50, false );
}
add_action( 'doing_it_wrong_run', function( $function, $message, $version ) {
   if ( 'map_meta_cap' === $function ) {
      error_log( "Map Meta Cap Wrong: $message" );
      error_log( print_r( wp_debug_backtrace_summary( null, 0, false ), true ) );
   }
}, 10, 3 );
//
//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);