File manager - Edit - /home/palg2351/public_html/wp-content/plugins/jetformbuilder/modules/user-journey/module.php
Back
<?php namespace JFB_Modules\User_Journey; use Jet_Form_Builder\Admin\Tabs_Handlers\Tab_Handler_Manager; use JFB_Components\Module\Base_Module_After_Install_It; use JFB_Components\Module\Base_Module_Dir_It; use JFB_Components\Module\Base_Module_Dir_Trait; use JFB_Components\Module\Base_Module_Handle_It; use JFB_Components\Module\Base_Module_Handle_Trait; use JFB_Components\Module\Base_Module_It; use JFB_Components\Module\Base_Module_Static_Instance_It; use JFB_Components\Module\Base_Module_Static_Instance_Trait; use JFB_Components\Module\Base_Module_Url_It; use JFB_Components\Module\Base_Module_Url_Trait; use JFB_Modules\User_Journey\Admin\Meta_Boxes\Form_Record_User_Journey_Box; use JFB_Modules\User_Journey\Models\User_Journey_Model; use Jet_Form_Builder\Db_Queries\Exceptions\Sql_Exception; use JFB_Modules\User_Journey\User_Journey_Rest_Controller; // If this file is called directly, abort. if ( ! defined( 'WPINC' ) ) { die; } /** * @method static Module instance() * * @package JFB_Modules\User_Journey */ class Module implements Base_Module_Dir_It, Base_Module_It, Base_Module_Handle_It, Base_Module_Url_It, Base_Module_After_Install_It, Base_Module_Static_Instance_It { use Base_Module_Handle_Trait; use Base_Module_Dir_Trait; use Base_Module_Url_Trait; use Base_Module_Static_Instance_Trait; private $rest; private $forms; /** * Returns the instance ID for the module. * * @return string The instance ID. */ public static function get_instance_id(): string { return 'user-journey'; } /** * Checks if the form-record module is available. * * @return bool True if the module is available, false otherwise. */ public function condition(): bool { return jet_form_builder()->has_module( 'form-record' ); } /** * Initializes hooks for the module. */ public function init_hooks() { add_action( 'rest_api_init', array( $this->get_rest(), 'register_routes' ) ); add_filter( 'jet-form-builder/page-containers/jfb-records-single', array( $this, 'add_box_to_single_record' ), 0 ); if ( $this->is_user_journey_enabled() ) { add_action( 'jet-form-builder/form-handler/before-send', array( $this, 'add_query_args' ), 10 ); add_filter( 'jet-form-builder/actions/redirect-to-page/redirect-args', array( $this, 'add_redirect_to_page_action_query_args' ), 10, 2 ); add_filter( 'jet-fb/response-handler/query-args', array( $this, 'add_gateway_query_args' ), 10, 2 ); add_action( 'wp_footer', array( $this, 'enqueue_journey_script' ) ); add_filter( 'jet-form-builder/editor/config', array( $this, 'add_user_journey_settings' ), 10, 1 ); add_action( 'jet-form-builder/form-record/save-record-action', array( $this, 'save_user_journey' ), 10, 2 ); add_action( 'wp_head', array( $this, 'clear_journey_data_on_reload' ), -9999, 2 ); } } /** * Removes hooks for the module. */ public function remove_hooks() { remove_action( 'rest_api_init', array( $this->get_rest(), 'register_routes' ) ); remove_filter( 'jet-form-builder/page-containers/jfb-records-single', array( $this, 'add_box_to_single_record' ), 0 ); if ( $this->is_user_journey_enabled() ) { remove_action( 'wp_footer', array( $this, 'enqueue_journey_script' ) ); remove_filter( 'jet-form-builder/editor/config', array( $this, 'add_user_journey_settings' ) ); remove_action( 'jet-form-builder/form-record/save-record-action', array( $this, 'save_user_journey' ) ); remove_action( 'wp_head', array( $this, 'clear_journey_data_on_reload' ) ); remove_filter( 'jet-form-builder/actions/redirect-to-page/redirect-args', array( $this, 'add_redirect_to_page_action_query_args' ) ); remove_action( 'jet-form-builder/form-handler/before-send', array( $this, 'add_query_args' ) ); } } /** * Handles actions to perform on module installation. */ public function on_install() { $this->rest = new User_Journey_Rest_Controller(); $this->set_forms(); Tab_Handler_Manager::instance()->install( new Tab_Handlers\User_Journey_Handler() ); } /** * Handles actions to perform on module uninstallation. */ public function on_uninstall() { Tab_Handler_Manager::instance()->uninstall( new Tab_Handlers\User_Journey_Handler() ); } public function set_forms() { if ( ! \JFB_Modules\Post_Type\Module::class ) { return array(); } $this->forms = get_posts( array( 'post_type' => \JFB_Modules\Post_Type\Module::SLUG, 'posts_per_page' => -1, ) ); } public function get_forms() { return $this->forms; } public function add_gateway_query_args( $args, $response ) { if ( ! \JFB_Modules\Post_Type\Module::class ) { return $args; } if ( isset( $response->args['form_id'] ) && isset( $response->args['status'] ) ) { if ( false === strpos( $args['status'], '%7C' ) && false === strpos( $args['status'], '|' ) ) { return $args; } else if ( false !== strpos( $args['status'], '%7C' ) ) { $status = explode( '%7C', $args['status'] )[0]; } else { $status = explode( '|', $args['status'] )[0]; } $jet_fb_user_journey_settings = $this->get_journey_settings(); if ( 'success' === $jet_fb_user_journey_settings['clear_after_submit'] ) { if ( 'dsuccess' === $status ) { $args['jfb_clear_journey'] = $response->args['form_id']; } } else if ( 'always' === $jet_fb_user_journey_settings['clear_after_submit'] ) { $args['jfb_clear_journey'] = $response->args['form_id']; } } return $args; } public function add_redirect_to_page_action_query_args( $args, $handler ) { if ( ! \JFB_Modules\Post_Type\Module::class ) { return $args; } $post_type_module = \Jet_Form_Builder\Plugin::instance()->module( \JFB_Modules\Post_Type\Module::class ); $journey_form_ids = $this->get_form_ids_with_save_user_journey(); $forms = $this->get_forms(); foreach ( $forms as $form ) { $actions = $post_type_module->get_actions( $form->ID ); foreach ( $actions as $action ) { if ( ( $action['type'] ?? '' ) === 'redirect_to_page' ) { if ( isset( $handler->_id ) ) { if ( in_array( $form->ID, $journey_form_ids ) && $action['id'] === $handler->_id ) { $args['jfb_clear_journey'] = $form->ID; } } break; } } } return $args; } public function get_form_ids_with_save_user_journey() { $post_type_module = \Jet_Form_Builder\Plugin::instance()->module( \JFB_Modules\Post_Type\Module::class ); $matched_form_ids = array(); $forms = $this->get_forms(); foreach ( $forms as $form ) { $actions = $post_type_module->get_actions( $form->ID ); foreach ( $actions as $action ) { if ( ( $action['type'] ?? '' ) === 'save_record' ) { $save_user_journey = $action['settings']['save_record']['save_user_journey'] ?? false; if ( $save_user_journey && true === $save_user_journey ) { $matched_form_ids[] = $form->ID; } } } } return $matched_form_ids; } public function add_query_args( $instance ) { $form_id = $instance->form_id; $instance->add_response_data( array( 'jfb_clear_journey' => $form_id ) ); } /** * Adds user journey settings to the provided settings array. * * @param array $settings The settings array to modify. * * @return array The modified settings array. */ public function add_user_journey_settings( $settings ) { $user_journey_settings = Tab_Handler_Manager::get_options( 'user-journey-tab' ); $settings['user_journey'] = array( 'enabled' => $user_journey_settings['enable_user_journey'] ?? false, 'storage_type' => $user_journey_settings['storage_type'] ?? 'local', 'clear_after_submit' => $user_journey_settings['clear_after_submit'] ?? 'success', ); return $settings; } /** * Adds a meta box to a single record. * * @param Base_Meta_Container[] $containers The array of meta containers. * * @return array The modified array of meta containers. */ public function add_box_to_single_record( array $containers ): array { $containers[0]->add_meta_box( new Form_Record_User_Journey_Box() ); return $containers; } /** * Checks if user journey tracking is enabled in the settings. * * @return bool True if user journey tracking is enabled, false otherwise. */ public function is_user_journey_enabled() { $options = Tab_Handler_Manager::get_options( 'user-journey-tab' ); return ! empty( $options['enable_user_journey'] ); } /** * Returns the journey tracking settings. * * @return array The journey settings. */ public function get_journey_settings() { $options = Tab_Handler_Manager::get_options( 'user-journey-tab' ); return array( 'enabled' => ! empty( $options['enable_user_journey'] ), 'storage_type' => $options['storage_type'] ?? 'local', 'clear_after_submit' => $options['clear_after_submit'] ?? 'success', 'form_ids_with_save_user_journey' => $this->get_form_ids_with_save_user_journey(), ); } public function clear_journey_data_on_reload() { $jet_fb_user_journey_settings = $this->get_journey_settings(); ?> <script> ( function() { const settings = <?php echo wp_json_encode( $jet_fb_user_journey_settings ); ?>; const storageKey = 'jet_fb_user_journey'; const storage = settings.storage_type === 'local' ? localStorage : sessionStorage; var params = new URLSearchParams( window.location.search ); if ( params.has('jfb_clear_journey') ) { var status = params.get('status') ?? 'unknown', formId = params.get('jfb_clear_journey'); if ( status.includes('|') ) { status = status.split('|')[0]; } params.delete('jfb_clear_journey'); var newSearch = params.toString(); var newUrl = window.location.origin + window.location.pathname + ( newSearch ? '?' + newSearch : '' ) + window.location.hash; window.history.replaceState( null, document.title, newUrl ); if ( ( 'success' === settings.clear_after_submit && ( 'success' === status || 'dsuccess' === status ) ) || 'always' === settings.clear_after_submit || 'unknown' === status ) { const raw = storage.getItem( storageKey ); if ( ! raw ) { return; } let data = JSON.parse( raw ); if ( ! Array.isArray( data ) && data.hasOwnProperty( formId ) ) { delete data[ formId ]; } storage.setItem( storageKey, JSON.stringify( data ) ); } } } )(); </script> <?php } /** * Enqueues JavaScript for tracking the user journey. */ public function enqueue_journey_script() { $jet_fb_user_journey_settings = $this->get_journey_settings(); ?> <script> ( function() { const settings = <?php echo wp_json_encode( $jet_fb_user_journey_settings ); ?>; const storageKey = 'jet_fb_user_journey'; const storage = settings.storage_type === 'local' ? localStorage : sessionStorage; const currentUrl = window.location.pathname; const queryString = decodeURIComponent( window.location.search ); const formIds = new Set( ( settings.form_ids_with_save_user_journey || [] ).map( Number ) ); let journeys; try { journeys = JSON.parse( storage.getItem( storageKey ) ) || {}; } catch { journeys = {}; } Object.keys( journeys ).forEach( id => { if ( ! formIds.has( +id ) ) delete journeys[ id ]; } ); const pageEntry = { url: currentUrl, query: queryString, timestamp: Date.now() }; function addJourney( journeys, formIds, to_form_id = null ) { if ( null !== to_form_id ) { journeys[ to_form_id ] = []; journeys[ to_form_id ].push( pageEntry ); } else { formIds.forEach( formId => { if ( ! journeys[ formId ] ) { journeys[ formId ] = []; } const journey = journeys[ formId ]; const lastEntry = 0 < journey.length ? journey[ journey.length - 1 ] : false; if ( ! lastEntry ) { journey.push( pageEntry ); } else if ( currentUrl !== lastEntry.url || queryString !== lastEntry.query ) { journey.push( pageEntry ); } } ); } storage.setItem( storageKey, JSON.stringify( journeys ) ); } function clearJourney( form, on_success = true ) { const formElement = form instanceof jQuery ? form[0] : form; const formId = formElement.dataset.formId; let can_clear = false; if ( on_success ) { if ( 'success' === settings.clear_after_submit || 'always' === settings.clear_after_submit ) { can_clear = true; } } else { if ( 'always' === settings.clear_after_submit ) { can_clear = true; } } if ( formElement ) { if ( formIds.has( +formId ) ) { if ( can_clear ) { const raw = storage.getItem( storageKey ); if ( ! raw ) { return; } let data = JSON.parse( raw ); if ( ! Array.isArray( data ) && data.hasOwnProperty( formId ) ) { delete data[ formId ]; } storage.setItem( storageKey, JSON.stringify( data ) ); const savedJourneys = storage.getItem( storageKey ); if ( savedJourneys ) { journeys = JSON.parse( savedJourneys ); } addJourney( journeys, formIds, formId ); if ( window?.JetFormBuilderSettings?.devmode ) { /* eslint-disable no-console */ console.group( 'User Journeys' ); console.info( journeys ); console.groupEnd(); /* eslint-enable no-console */ } } } } else { console.error('Form element is not defined or not a valid DOM element.'); } } addJourney( journeys, formIds ); jQuery( document ).ready( function() { if ( window?.JetFormBuilderSettings?.devmode ) { /* eslint-disable no-console */ console.group( 'User Journeys' ); console.info( journeys ); console.groupEnd(); /* eslint-enable no-console */ } JetPlugins.hooks.addFilter( 'jet.fb.submit.ajax.promises', 'user_journey_promise', function ( promises, $form ) { promises.push( new Promise( ( resolve, reject ) => { const formElement = $form instanceof jQuery ? $form[0] : $form; const formId = formElement.dataset.formId; const userJourneyData = storage.getItem( storageKey ); const userJourneyDataParsed = JSON.parse(userJourneyData || '{}'); const formSpecificData = userJourneyDataParsed[formId] || ''; if ( formElement ) { if ( formIds.has( +formId ) ) { if ( userJourneyData ) { let hiddenInput = $form[0].querySelector( 'input[name="_user_journey"]' ); if ( !hiddenInput ) { hiddenInput = document.createElement( 'input' ); hiddenInput.type = 'hidden'; hiddenInput.name = '_user_journey'; $form[0].appendChild( hiddenInput ); } hiddenInput.value = JSON.stringify( formSpecificData ); } } } resolve(); } ) ); return promises; } ); JetPlugins.hooks.addFilter( 'jet.fb.submit.reload.promises', 'user_journey_promise', function( $promises, $context ) { $promises.push( new Promise( ( resolve ) => { const rootNode = $context.target; const userJourneyData = storage.getItem( storageKey ); const formId = rootNode.dataset.formId; const userJourneyDataParsed = JSON.parse(userJourneyData || '{}'); const formSpecificData = userJourneyDataParsed[formId] || ''; if ( formIds.has( +formId ) && userJourneyData ) { let hiddenInput = rootNode.querySelector( 'input[name="_user_journey"]' ); if ( ! hiddenInput ) { hiddenInput = document.createElement( 'input' ); hiddenInput.type = 'hidden'; hiddenInput.name = '_user_journey'; rootNode.appendChild( hiddenInput ); } hiddenInput.value = JSON.stringify( formSpecificData ); } resolve(); } ) ); return $promises; } ); jQuery( document ).on('jet-form-builder/ajax/on-success', function( event, response, form ) { clearJourney( form ); } ); jQuery( document ).on('jet-form-builder/ajax/processing-error', function( event, response, form ) { clearJourney( form, false ); } ); jQuery( document ).on('jet-form-builder/ajax/on-fail', function( event, jqXHR, textStatus, errorThrown, form ) { clearJourney( form, false ); } ); } ); } )(); </script> <?php } /** * Saves the user journey to the database after form submission. * * @param int $record_id The ID of the form record. * @param array $action_request The action request data. */ public function save_user_journey( $record_id, $action_request ) { try { ( new User_Journey_Model() )->create(); } catch ( Sql_Exception $e ) { if ( defined( 'WP_DEBUG' ) && WP_DEBUG ) { error_log( $e->getMessage() ); } } if ( ! $record_id ) { return; } // phpcs:ignore WordPress.Security.NonceVerification.Missing, WordPress.Security.ValidatedSanitizedInput.MissingUnslash $user_journey = isset( $_POST['_user_journey'] ) ? sanitize_text_field( $_POST['_user_journey'] ) : null; if ( ! $user_journey ) { return; } $journey_data = json_decode( wp_unslash( $user_journey ), true ); if ( ! is_array( $journey_data ) ) { return; } foreach ( $journey_data as $step => $item ) { $journey_results[] = array( 'record_id' => $record_id, 'journey_step' => $step, 'journey_url' => sanitize_text_field( $item['url'] ), 'journey_query' => urldecode( $item['query'] ?? '' ), 'timestamp' => $item['timestamp'], ); } ( new User_Journey_Model() )->insert_many( $journey_results ); } /** * Returns the REST controller for the user journey. * * @return User_Journey_Rest_Controller The REST controller instance. */ public function get_rest(): User_Journey_Rest_Controller { return $this->rest; } }
| ver. 1.4 |
Github
|
.
| PHP 8.3.30 | Generation time: 0.09 |
proxy
|
phpinfo
|
Settings