Jake Vanderwerf
4 hours ago 56a9a1ccf764ff7a6af8f8a2292cb07443cb4aa7
jvb.php
@@ -10,59 +10,183 @@
*/
use JVBase\JVB;
use JVBase\utility\Checker;
use JVBase\utility\Features;
use JVBase\managers\IconsManager;
use JVBase\registrar\Registrar;
use JVBase\base\Site;
//security
if (!defined('ABSPATH')) {
    exit;
}
const JVB_LOCAL = 'northeh.test';
add_filter('show_admin_bar', '__return_false');
const JVB_TESTING = false;
/**
 * 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);
function jvbIgnoredPostTypes():array
{
   return [BASE.'directory', BASE.'dash', 'attachment', 'revision', 'nav_menu_item'];
}
define('JVB_TESTING', str_contains(get_home_url(),'.test'));
//const JVB_TESTING = false;
//if (!JVB_TESTING) {
   add_filter('show_admin_bar', '__return_false');
//}
//if (JVB_TESTING) {
// error_log('In testing mode...');
//} else {
// error_log('Not in testing mode...');
//}
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 . '/inc/registrar/_setup.php');
require(JVB_DIR . '/activate.php');
require(JVB_DIR . '/inc/helpers/all.php');
require(JVB_DIR . '/inc/ui/_setup.php');
require(JVB_DIR . '/inc/meta/_setup.php');
require(JVB_DIR . '/inc/importers/_setup.php');
require(JVB_DIR . '/inc/managers/_setup.php');
/**
 * Get an icon element
 *
 * @param string $name Icon name
 * @param array $options Options array:
 *   - 'source' => 'icons'|'dash'|'forms'|etc. (default: 'icons')
 *   - 'style' => 'regular'|'bold'|'fill'|etc.
 *   - 'label' => 'Accessible label'
 *   - 'decorative' => true
 *   - 'class' => 'additional classes'
 *   - 'size' => 24
 * @return string HTML icon element
 */
function jvbIcon(string $name, array $options = []): string
{
   $source = $options['source'] ?? 'icons';
   // Remove source from options before passing to IconsManager
   unset($options['source']);
   return IconsManager::for($source)->get($name, $options);
}
function jvbFullIcon(string $name, array $options = []):string
{
   $source = $options['source'] ?? 'icons';
   unset($options['source']);
   return IconsManager::for($source)->getRawSvg($name, $options['style']??null);
}
/**
 * Get a CSS data URI for an icon
 *
 * @param string $name Icon name
 * @param array $options Options array:
 *   - 'style' => 'regular'|'bold'|'fill'|etc.
 *   - 'source' => 'icons'|'dash'|'forms'|etc. (for tracking purposes)
 * @return string data:image/svg+xml;base64,... URL
 */
function jvbCSSIcon(string $name, array $options = []): string
{
   $style = $options['style'] ?? null;
   $source = $options['source'] ?? 'icons';
   return IconsManager::for($source)->getCSSIcon($name, $style);
}
/**
 * Get a dashboard icon
 */
function jvbDashIcon(string $name, array $options = []): string
{
   $options['source'] = 'dash';
   return jvbIcon($name, $options);
}
/**
 * Get a form editor icon
 */
function jvbFormIcon(string $name, array $options = []): string
{
   $options['source'] = 'forms';
   return jvbIcon($name, $options);
}
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)
@@ -96,12 +220,12 @@
function jvbUserCheck():void
{
    if (is_admin() && isOurPeople()) {
        wp_redirect(get_home_url(2, '/dash'));
        wp_redirect(get_home_url(null, '/dash'));
        exit;
    }
}
require(JVB_DIR . '/inc/users/UserSettings.php');
//require(JVB_DIR . '/inc/users/UserSettings.php');
require(JVB_DIR . '/inc/templates.php');
@@ -124,10 +248,8 @@
}
function checkIf(): Checker
{
   return JVBase\utility\Checker::getInstance();
}
require(JVB_DIR . '/inc/blocks/_setup.php');
@@ -161,615 +283,52 @@
/**
 * Scripts
 */
add_action('wp_enqueue_scripts', 'jvbScripts', 999);
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.0',
        [
            '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.0',
      [
         '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.0',
      [
         '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.0',
        [
            '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.0',
      [
         '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'
      ],
        '1.0.0',
        [
            'strategy'    => 'defer',
            'in_footer'    => true,
        ]
    );
   wp_register_script(
      'jvb-integrations',
      JVB_URL.'assets/js/min/integrations.min.js',
      [],
      '1.0.0',
      [
         '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.0',
        [
            'strategy'    => 'defer',
            'in_footer'    => true,
        ]
    );
    //A11y accessibility
    wp_register_script(
        'jvb-a11y',
        JVB_URL.'assets/js/min/a11y.min.js',
        [],
        '1.0.0',
        [
            'strategy'    => 'defer',
            'in_footer'    => true,
        ]
    );
    //Central Error Management
    wp_register_script(
        'jvb-error',
        JVB_URL.'assets/js/min/error.min.js',
        [
        ],
        '1.0.0',
        [
            'strategy'    => 'defer',
            'in_footer'    => true,
        ]
    );
    //Cache Management
    wp_register_script(
        'jvb-cache',
        JVB_URL.'assets/js/min/cache.min.js',
        [],
        '1.0.0',
        [
            'strategy'    => 'defer',
            'in_footer'    => true,
        ]
    );
   wp_register_Script(
      'jvb-data-store',
      JVB_URL.'assets/js/min/dataStore.min.js',
      [],
      '1.0.0',
      [
         'strategy'  => 'defer',
         'in_footer' => true,
      ]
   );
    //Tabs functionality
    wp_register_script(
        'jvb-tabs',
        JVB_URL.'assets/js/min/tabs.min.js',
        [
            'jvb-a11y'
        ],
        '1.0.0',
        [
            'strategy'    => 'defer',
            'in_footer'    => true,
        ]
    );
    //Modal functionality
    wp_register_script(
        'jvb-modal',
        JVB_URL.'assets/js/min/modal.min.js',
        [
            'jvb-a11y'
        ],
        '1.0.0',
        [
            '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',
        ],
        '1.0.0',
        [
            '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.0',
        [
            'strategy'    => 'defer',
            'in_footer'    => true,
        ]
    );
   wp_register_script(
      'jvb-creator',
      JVB_URL.'assets/js/min/creator.min.js',
      ['jvb-selector'],
      '1.0.0',
      [
         '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.0',
        [
            '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-uploader',
        JVB_URL.'assets/js/min/uploader.min.js',
        [
         'jvb-cache',
         'jvb-a11y',
            'jvb-utility',
//            'jvb-loading',
            'jvb-queue',
            'jvb-notifications'
        ],
        '1.0.0',
        [
            '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.0',
        [
            'strategy'    => 'defer',
            'in_footer' => true,
        ]
    );
    //Base Form Handler
    wp_register_script(
        'jvb-form',
        JVB_URL.'assets/js/min/form.min.js',
        [
            'jvb-utility',
            'jvb-selector',
            'jvb-uploader',
         'sortable-js'
        ],
        '1.0.0',
        [
            'strategy'    => 'defer',
            'in_footer'    => true,
        ]
    );
   wp_register_script(
      'jvb-populate-form',
      JVB_URL.'assets/js/min/populate.min.js',
      [],
      '1.0.0',
      [
         'strategy'  => 'defer',
         'in_footer' => true,
      ]
   );
   wp_register_script(
      'jvb-quill',
      JVB_URL.'assets/js/min/quill.min.js',
      [
         'quill-js'
      ],
      '1.0.0',
      [
         'strategy'  => 'defer',
         'in_footer' => true,
      ]
   );
    //CRUD Base Manager
    wp_register_script(
        'jvb-crud',
        JVB_URL.'assets/js/min/crud.min.js',
        [
         'jvb-selector',
            'jvb-a11y',
            'jvb-error',
            'jvb-data-store',
         'jvb-populate-form',
            'jvb-queue',
            'jvb-utility',
         'jvb-quill',
            'jvb-form',
         'jvb-view',
         'jvb-modal'
        ],
        '1.0.0',
        [
            'strategy'    => 'defer',
            'in_footer'    => true,
        ]
    );
   wp_register_script(
      'jvb-view',
      JVB_URL.'assets/js/min/view.min.js',
      [
         'jvb-a11y',
         'jvb-utility',
         'jvb-data-store',
         'jvb-error'
      ],
      '1.0.0',
      [
         '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.0',
        [
            '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.0',
        [
            '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.0',
        [
            '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.0',
        [
            '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.0',
        [
            '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');
    wp_enqueue_script('jvb-queue');
   if (Site::has('dashboard')) {
      wp_enqueue_script('jvb-queue');
   }
   wp_enqueue_script('jvb-auth');
   wp_enqueue_script('jvb-settings');
    wp_enqueue_script('jvb-navigation');
//    wp_enqueue_script('jvb-ui');
    wp_enqueue_script('jvb-media');
//    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())
        ]
    );
   $interactions = [];
   if (Site::has('favourites')) {
      $interactions[] = 'favourites';
   }
   if (!empty(Registrar::getFeatured('karma'))) {
      $interactions[] = 'karma';
   }
   if (Site::has('notifications')) {
      $interactions[] = 'notifications';
   }
    $userID = get_current_user_id();
   $icons = new \JVBase\JVBIcons();
    $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),
            'icons'            => $icons->localizeIcons(),
         '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
            'icons'       => $icons->localizeIcons(),
         'labels'       => jvbGetLabels(),
        ];
   if (!empty($interactions)) {
      wp_enqueue_script('jvb-interactions');
      foreach($interactions as $interaction) {
         wp_enqueue_script('jvb-'.$interaction);
      }
   }
    wp_localize_script('jvb-queue', 'jvbSettings', $queue);
   $queue = [
      'api' => rest_url('jvb/v1/'),
      'redirect' => get_home_url(null, '/login/'),
      'labels' => Registrar::getLabels(),
   ];
    wp_localize_script('jvb-auth', 'jvbSettings', $queue);
   $initUserSettings = 'async function initUserItems() {
   if (!jvbSettings.currentUser) return;
@@ -777,7 +336,7 @@
   window.userFavourites = {};
   window.userVotes = {};
   ';
   if (Features::forSite()->has('favourites')) {
   if (Site::has('favourites')) {
      wp_enqueue_script('jvb-favourites');
      $initUserSettings .= '
      //Fetch user favourites
@@ -803,7 +362,7 @@
      }';
   }
   if (Features::anyContentHas('karma') || Features::anyTaxonomyHas('karma') || Features::anyUserHas('karma')) {
   if (!empty(Registrar::getFeatured('karma'))) {
      wp_enqueue_script('jvb-votes');
      $initUserSettings .= '// Fetch user votes
        try {
@@ -843,6 +402,10 @@
        wp_enqueue_script('jvb-page-nav');
    }
   if (has_block('jvb/summaryBlock')) {
      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')) {
@@ -873,7 +436,7 @@
//        ');
//        }
    }
    if (is_user_logged_in()) {
    if (is_user_logged_in() && Site::has('notifications')) {
        wp_enqueue_script('jvb-notifications');
        wp_localize_script('jvb-notifications', 'notificationSettings', array(
@@ -891,6 +454,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');
@@ -945,6 +512,13 @@
    echo '<div class="screen-reader-text live-region" aria-live="polite" role="status"></div>';
}
add_action('wp_head', 'jvbFrontendBase',1);
function jvbFrontendBase():void
{
   ?>
   <script type="text/javascript">window.jvbBase = '<?= BASE ?>';</script>
   <?php
}
//add_action('wp_head', 'jvbDumpIt');
function jvbDumpIt()
@@ -952,18 +526,60 @@
}
//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_image_size( 'directory-preview', 100, 100, 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 ) );
//
//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);
add_filter('rest_authentication_errors', function($result) {
   // Don't override existing authentication
   if (is_wp_error($result) || $result === true) {
      return $result;
   }
}, 10, 3 );
   // Try to authenticate from cookie
   $cookie_user = wp_validate_auth_cookie('', 'logged_in');
   if ($cookie_user) {
      wp_set_current_user($cookie_user);
      return true;
   }
   return $result;
}, 99);
add_action('wp_footer', 'jvb_back_to_top');
function jvb_back_to_top():void
{
   echo sprintf(
      '<a id="back-to-top" class="btn sticky" href="#">%s<span>Back to Top</span></a>',
      jvbIcon('caret-double-up')
   );
}
add_action( 'doing_it_wrong_run', function ( $function_name ) {
   if ( '_load_textdomain_just_in_time' === $function_name ) {
      // This will print the full execution path to your screen or log
      debug_print_backtrace();
   }
} );