queue ?? [];
// foreach ($queue as $handle) {
// $src = $wp_scripts->registered[$handle]->src ?? 'unknown';
// error_log("Enqueued: $handle => $src");
// }
// }, 999);
//}, 999);
/**
* 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');
//}
const JVB_DIR = WP_PLUGIN_DIR . '/jvb';
define('JVB_URL', plugin_dir_url(__FILE__));
// Session Security
const JVB_SESSION_FINGERPRINT = true;
// Login Security
const JVB_MAX_LOGIN_ATTEMPTS = 5;
const JVB_LOCKOUT_DURATION = 15 * MINUTE_IN_SECONDS;
require(JVB_DIR.'/inc/Instance.php');
require(JVB_DIR.'/base/_setup.php');
require(JVB_DIR.'/inc/utility/setup.php');
require(JVB_DIR.'/checks.php');
require(JVB_DIR . '/inc/integrations/ServiceMap.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');
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' => MONTH_IN_SECONDS,
'display' => __('Once Monthly', 'jvb')
];
return $schedules;
}
register_activation_hook(JVB_DIR.'/jvb.php', 'jvbActivatePlugin');
register_deactivation_hook(JVB_DIR.'/jvb.php', 'jvbDeactivatePlugin');
//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');
/**
* After moving to the Registrar::based registration, we need to carefully time
* when Site gets defined, as well as Registrar initial definitions, field definitions,
* and integration config
* These custom actions should simplify the timing for us.
*/
add_action('plugins_loaded', 'jvb_site_definitions',1);
add_action('plugins_loaded', 'jvb_registrar_definitions',2);
add_action('plugins_loaded', 'jvb_field_definitions', 3);
add_action('plugins_loaded', 'jvb_options_definitions',3);
add_action('init', 'jvbLoadBase', 2);
add_action('init', 'jvb_integration_definitions',3);
add_action('init', 'jvb_field_section_definitions', 5);
/**
* Can define the Site settings
* @return void
*/
function jvb_site_definitions():void
{
do_action('jvb_define_site');
}
function jvb_registrar_definitions():void
{
do_action('jvb_define_registrar');
}
function jvb_field_definitions():void
{
do_action('jvb_define_fields');
}
function jvb_options_definitions():void
{
do_action('jvb_define_options');
}
function jvbLoadBase():void
{
do_action('jvbloaded');
Emails::getInstance();
Queue::getInstance();
Roles::getInstance();
Login::getInstance();
SEOAdmin::getInstance();
SchemaOutput::getInstance();
SchemaHelper::getInstance();
CustomBlocks::getInstance();
AdminPages::getInstance();
if (Site::has('magic_link')) {
MagicLinks::getInstance();
}
if (Site::has('dashboard')) {
Dashboard::getInstance();
}
if (Site::has('referrals')) {
Referrals::getInstance();
}
if (Site::has('is_directory')) {
DirectoryManager::getInstance();
}
if (Site::has('feed_block')) {
TaxonomyRelationships::getInstance();
}
if (Site::hasAll(['dashboard', 'membership', 'feed_block'])) {
UserTermsManager::getInstance();
}
if (Site::has('favourites')) {
Favourites::getInstance();
}
if (!empty(Registrar::withFeature('has_responses'))) {
Responses::getInstance();
}
$membership = Site::membership();
if ($membership && $membership->has('notifications')) {
NotificationManager::getInstance();
}
if ($membership && $membership->has('invitable')) {
InvitationsManager::getInstance();
}
if (!empty(Registrar::withFeature('approve_new'))) {
Approvals::getInstance();
}
jvbLoadRoutes();
}
function jvb_integration_definitions():void
{
do_action('jvb_define_integrations');
}
function jvb_field_section_definitions():void
{
do_action('jvb_define_field_sections');
Registrar::maybeBuildSections();
}
add_action('wp_footer', 'jvbAdditionalActions');
function jvbAdditionalActions():void
{
if (Login::isLogin()) {
return;
}
$extras = apply_filters('jvbAdditionalActions', []);
$extras = array_filter($extras, function ($extra) {
return is_array($extra) && array_key_exists('button', $extra) && array_key_exists('content', $extra);
});
if (empty ($extras)) {
return;
}
$buttons = array_map(function ($extra) {
return $extra['button'];
}, $extras);
$contents = array_map(function($extra) {
return $extra['content'];
}, $extras);
if (!empty ($buttons)) {
?>