enqueue_wizard(); } /** * The wizard's script, styles and data. The Lead Funnels page loads them, and so does the dashboard, whose bar opens * the same wizard without leaving the page. */ public function enqueue_wizard() { static $done = false; if ( $done ) { return; } $done = true; $css = ACQUIS_PLUGIN_DIR . 'admin/funnels/acquis-funnels.css'; $js = ACQUIS_PLUGIN_DIR . 'admin/funnels/acquis-funnels.js'; wp_enqueue_style( 'acquis-funnels', ACQUIS_PLUGIN_URL . 'admin/funnels/acquis-funnels.css', array( 'dashicons' ), acquis_asset_ver( $css ) ); wp_enqueue_script( 'acquis-funnels', ACQUIS_PLUGIN_URL . 'admin/funnels/acquis-funnels.js', array( 'jquery' ), acquis_asset_ver( $js ), true ); $templates = array(); foreach ( ACQUIS_Funnel_Templates::all() as $id => $t ) { $templates[] = array( 'id' => $id, 'label' => $t['label'], 'description' => $t['description'] ?? '', 'icon' => $t['icon'] ?? 'dashicons-admin-generic', 'needs_file' => ! empty( $t['needs_file'] ), 'defaults' => $t['defaults'], 'extra' => array_values( (array) ( $t['extra'] ?? array() ) ), 'sections' => wp_parse_args( (array) ( $t['sections'] ?? array() ), array( 'after' => 1, 'email' => 1, 'notify' => 1 ) ), 'prefill_redirect' => (string) ( $t['prefill_redirect'] ?? '' ), 'notify_default' => ! empty( $t['notify_default'] ) ? 1 : 0, 'pro_defaults' => (array) ( $t['pro_defaults'] ?? array() ), 'notes' => (array) ( $t['notes'] ?? array() ), 'no_display' => ! empty( $t['needs_file'] ), // 'resource' puts the template's own questions on the file screen, under the file they depend on. 'extra_screen' => (string) ( $t['extra_screen'] ?? '' ), 'hide_details' => ! empty( $t['hide_details'] ), 'file_sub' => (string) ( $t['file_sub'] ?? '' ), // what the review says about the file, when it is not "reused and not changed" ); } $files = array(); foreach ( (array) ACQUIS_File_Manager::get_all_files() as $f ) { $f = is_object( $f ) ? (array) $f : (array) $f; $fid = (int) ( $f['id'] ?? $f['ID'] ?? 0 ); $title = (string) ( $f['title'] ?? $f['post_title'] ?? '' ); if ( $fid ) { $files[] = array( 'id' => $fid, 'title' => $title ); } } $forms = array(); foreach ( ACQUIS_P3_DB::get_forms() as $f ) { $forms[] = array( 'id' => (int) $f->id, 'title' => $f->title ); } $std = array(); foreach ( ACQUIS_Funnel_Templates::standard_fields() as $k => $def ) { $std[] = array( 'key' => $k, 'label' => $def['label'], 'required' => ! empty( $def['required'] ) && 'email' === $k ); } $config = array( 'ajaxurl' => admin_url( 'admin-ajax.php' ), 'nonce' => wp_create_nonce( self::NONCE ), 'templates' => $templates, 'files' => $files, 'forms' => $forms, 'fields' => $std, 'adminEmail' => (string) get_option( 'admin_email' ), 'pro' => ACQUIS_P3_Admin::is_pro_active(), 'showNote' => ! ACQUIS_P3_Admin::is_pro_active() && ! get_user_meta( get_current_user_id(), self::NOTE, true ), 'addonsUrl' => admin_url( 'admin.php?page=acquis-addons' ), 'listUrl' => admin_url( 'admin.php?page=' . self::PAGE ), 'filesUrl' => admin_url( 'admin.php?page=acquisitionsuite-files' ), 'displays' => array_values( array_intersect( array( 'embedded', 'popup', 'floating', 'slidein' ), (array) apply_filters( 'acquis_form_display_styles', array( 'embedded', 'popup' ) ) ) ), 'i18n' => $this->strings(), ); /** * The data the wizard script gets. Pro adds its own (lists of tags, sequences, pipelines) here. * * @param array $config */ $config = apply_filters( 'acquis_funnel_wizard_config', $config ); wp_localize_script( 'acquis-funnels', 'ACQUIS_FUNNELS', $config ); /** * The wizard's script was enqueued (on the Lead Funnels page or the dashboard). Pro adds its own script here. */ do_action( 'acquis_funnel_wizard_enqueued' ); } private function strings() { return array( 'create' => __( 'Create funnel', 'acquisitionsuite' ), 'save' => __( 'Save changes', 'acquisitionsuite' ), 'cancel' => __( 'Cancel', 'acquisitionsuite' ), 'back' => __( 'Back', 'acquisitionsuite' ), 'continue' => __( 'Continue', 'acquisitionsuite' ), 'close' => __( 'Close', 'acquisitionsuite' ), 'useTemplate' => __( 'Use template', 'acquisitionsuite' ), 'pickTitle' => __( 'Build a lead funnel in a few minutes', 'acquisitionsuite' ), 'pickSub' => __( 'What do you want to achieve?', 'acquisitionsuite' ), 'basicsSub' => __( 'Let\'s get started.', 'acquisitionsuite' ), 'name' => __( 'Funnel name', 'acquisitionsuite' ), 'nameHelp' => __( 'Only you see this. It names the funnel and its form.', 'acquisitionsuite' ), 'headline' => __( 'Headline', 'acquisitionsuite' ), 'headlineHelp' => __( 'Shown above the form.', 'acquisitionsuite' ), 'description' => __( 'Description', 'acquisitionsuite' ), 'resourceTitle' => __( 'Resource and form', 'acquisitionsuite' ), 'resourceSub' => __( 'What do people get, and what do you ask for?', 'acquisitionsuite' ), 'resource' => __( 'Resource to deliver', 'acquisitionsuite' ), 'noFiles' => __( 'You have no uploaded files yet.', 'acquisitionsuite' ), 'uploadFile' => __( 'Upload a file', 'acquisitionsuite' ), 'chooseFile' => __( 'Choose a file…', 'acquisitionsuite' ), 'resourceHelp' => __( 'Delivery follows your delivery settings (instant, email, or both).', 'acquisitionsuite' ), 'form' => __( 'Form', 'acquisitionsuite' ), 'createForm' => __( 'Create a form', 'acquisitionsuite' ), 'createFormSub' => __( 'Built for this funnel', 'acquisitionsuite' ), 'existingForm' => __( 'Use an existing form', 'acquisitionsuite' ), 'existingSub' => __( 'Reused, never changed', 'acquisitionsuite' ), 'chooseForm' => __( 'Choose a form…', 'acquisitionsuite' ), 'fields' => __( 'Fields', 'acquisitionsuite' ), 'emailRequired' => __( 'always asked', 'acquisitionsuite' ), 'addField' => __( 'Add a custom field', 'acquisitionsuite' ), 'fieldLabel' => __( 'Field label', 'acquisitionsuite' ), 'removeField' => __( 'Remove field', 'acquisitionsuite' ), 'how' => __( 'How it appears', 'acquisitionsuite' ), 'embedded' => __( 'Embedded on a page', 'acquisitionsuite' ), 'popup' => __( 'Popup', 'acquisitionsuite' ), 'floating' => __( 'Floating button', 'acquisitionsuite' ), 'slidein' => __( 'Slide-in panel', 'acquisitionsuite' ), 'slideDelay' => __( 'Open by itself after (seconds)', 'acquisitionsuite' ), 'slideHelp' => __( 'A small tab stays on the edge of the page. Use 0 to open it only when it is clicked. Visitors who close it are not shown it again for a week.', 'acquisitionsuite' ), 'sectionsOff' => __( 'This kind of funnel is paid for at checkout, so the message, email and notification come from your payment settings.', 'acquisitionsuite' ), 'details' => __( 'Details', 'acquisitionsuite' ), 'styleNote' => __( 'The form uses the default style from your plugin settings.', 'acquisitionsuite' ), 'refreshForm' => __( 'Reload fields from Form Builder', 'acquisitionsuite' ), 'fieldType' => __( 'Type:', 'acquisitionsuite' ), 'mergeNote' => __( 'Changes made to this form in Form Builder are kept. Only what you change here is applied to it.', 'acquisitionsuite' ), /* translators: %d: number of fields */ 'othersKept' => __( '%d field(s) here are dropdowns, checkboxes or other types made in Form Builder. You can rename or remove them here; their options are edited in Form Builder.', 'acquisitionsuite' ), 'formLocked' => __( 'The form this funnel was built on cannot be changed here. To use a different form, create a new funnel.', 'acquisitionsuite' ), 'afterTitle' => __( 'After submission', 'acquisitionsuite' ), 'afterSub' => __( 'What happens when someone submits?', 'acquisitionsuite' ), 'showMessage' => __( 'Show a message', 'acquisitionsuite' ), 'redirect' => __( 'Redirect to a page', 'acquisitionsuite' ), 'message' => __( 'Message', 'acquisitionsuite' ), 'redirectUrl' => __( 'Address to send people to', 'acquisitionsuite' ), 'redirectNote' => __( 'If a file is delivered instantly, the download starts before the redirect.', 'acquisitionsuite' ), 'emailTitle' => __( 'Delivery email, for this funnel only', 'acquisitionsuite' ), 'emailCustom' => __( 'Write a custom email for this funnel', 'acquisitionsuite' ), 'emailGlobal' => __( 'Off: this funnel uses your global email template from Email Settings.', 'acquisitionsuite' ), 'emailSubject' => __( 'Subject', 'acquisitionsuite' ), 'emailBody' => __( 'Message', 'acquisitionsuite' ), 'emailTags' => __( 'You can use {full_name}, {email}, {file_name} and {site_name}. The download button is added for you when a file is delivered.', 'acquisitionsuite' ), 'notify' => __( 'Email me when someone signs up', 'acquisitionsuite' ), 'notifyTo' => __( 'Send it to', 'acquisitionsuite' ), 'proNote' => __( 'Pro can also tag leads, start email sequences and move them through your pipeline.', 'acquisitionsuite' ), 'dismiss' => __( 'Dismiss', 'acquisitionsuite' ), 'learnMore' => __( 'See what Pro adds', 'acquisitionsuite' ), 'reviewTitle' => __( 'Review', 'acquisitionsuite' ), 'reviewSub' => __( 'Everything is ready. AcquisitionSuite will:', 'acquisitionsuite' ), 'rvForm' => __( 'Create a lead capture form', 'acquisitionsuite' ), 'rvFormNew' => __( 'New. It appears under Form Builder.', 'acquisitionsuite' ), 'rvFormUse' => __( 'Use your existing form', 'acquisitionsuite' ), 'rvFormUseSub' => __( 'Reused and not changed.', 'acquisitionsuite' ), 'rvFile' => __( 'Deliver your resource', 'acquisitionsuite' ), 'rvFileSub' => __( 'Reused and not changed.', 'acquisitionsuite' ), 'rvEmail' => __( 'Send a custom delivery email', 'acquisitionsuite' ), 'rvEmailSub' => __( 'For this funnel only.', 'acquisitionsuite' ), 'rvNotify' => __( 'Notify you of new leads', 'acquisitionsuite' ), 'rvAfter' => __( 'Show a message after submission', 'acquisitionsuite' ), 'rvRedirect' => __( 'Redirect to your page after submission', 'acquisitionsuite' ), 'rvTrack' => __( 'Track leads and analytics', 'acquisitionsuite' ), 'rvTrackSub' => __( 'Filtered to this funnel.', 'acquisitionsuite' ), 'rvPages' => __( 'Nothing on your pages is changed. You will get a shortcode to place where you want the form.', 'acquisitionsuite' ), 'working' => __( 'Creating your funnel…', 'acquisitionsuite' ), 'workingEdit' => __( 'Saving your funnel…', 'acquisitionsuite' ), 'undo' => __( 'If any step fails, everything created so far is undone.', 'acquisitionsuite' ), 'stepForm' => __( 'Creating the form', 'acquisitionsuite' ), 'stepResource' => __( 'Checking your resource', 'acquisitionsuite' ), 'stepPublish' => __( 'Publishing', 'acquisitionsuite' ), 'stepSaving' => __( 'Saving changes', 'acquisitionsuite' ), 'failed' => __( 'Nothing was created. Please try again.', 'acquisitionsuite' ), 'tryAgain' => __( 'Back to review', 'acquisitionsuite' ), 'readyTitle' => __( 'Your funnel is ready', 'acquisitionsuite' ), 'savedTitle' => __( 'Your funnel is saved', 'acquisitionsuite' ), 'shortcode' => __( 'Shortcode', 'acquisitionsuite' ), 'copy' => __( 'Copy', 'acquisitionsuite' ), 'copied' => __( 'Copied', 'acquisitionsuite' ), 'addToPage' => __( 'Add it to a page', 'acquisitionsuite' ), 'how1' => __( 'Copy the shortcode.', 'acquisitionsuite' ), 'how2' => __( 'Edit any page or post.', 'acquisitionsuite' ), 'how3' => __( 'Add a Shortcode block, paste it, and update the page.', 'acquisitionsuite' ), 'howAlt' => __( 'You can also use the AcquisitionSuite form block, the Elementor widget or the Bricks element.', 'acquisitionsuite' ), 'openForm' => __( 'Open the form', 'acquisitionsuite' ), 'viewLeads' => __( 'View leads', 'acquisitionsuite' ), 'viewReport' => __( 'View analytics', 'acquisitionsuite' ), 'editFunnel' => __( 'Edit funnel', 'acquisitionsuite' ), 'allFunnels' => __( 'All funnels', 'acquisitionsuite' ), 'notChanged' => __( 'Your pages were not changed. Add the shortcode where you want the form to appear.', 'acquisitionsuite' ), 'conflictTitle' => __( 'The form was changed outside this funnel', 'acquisitionsuite' ), 'conflictText' => __( 'Someone edited this funnel\'s form in Form Builder. Do you want to replace those changes with the funnel\'s settings, or keep them and only update the funnel?', 'acquisitionsuite' ), 'overwrite' => __( 'Replace the form', 'acquisitionsuite' ), 'keep' => __( 'Keep my form changes', 'acquisitionsuite' ), 'deleteTitle' => __( 'Delete this funnel?', 'acquisitionsuite' ), 'deleteSub' => __( 'Leads and submissions are always kept. Choose what happens to the rest.', 'acquisitionsuite' ), 'deleteForm' => __( 'Delete the form this funnel created', 'acquisitionsuite' ), 'deleteRule' => __( 'Delete the automation rule this funnel created', 'acquisitionsuite' ), 'restorePrice' => __( 'Put the file back as it was (it was priced by this funnel)', 'acquisitionsuite' ), 'formUsed' => __( 'Pages that use its shortcode will stop showing it.', 'acquisitionsuite' ), 'reusedKept' => __( 'is reused, so it is never deleted', 'acquisitionsuite' ), 'deleteFunnel' => __( 'Delete funnel', 'acquisitionsuite' ), 'errName' => __( 'Enter a name for this funnel.', 'acquisitionsuite' ), 'errFill' => __( 'Fill in:', 'acquisitionsuite' ), 'errFile' => __( 'Choose the file people should receive.', 'acquisitionsuite' ), 'errForm' => __( 'Choose one of your existing forms.', 'acquisitionsuite' ), 'errUrl' => __( 'Enter the address people should be sent to, starting with https://.', 'acquisitionsuite' ), 'errEmail' => __( 'Write a subject and a message, or switch the custom email off.', 'acquisitionsuite' ), 'errNotify' => __( 'Enter a valid email address.', 'acquisitionsuite' ), 'error' => __( 'Something went wrong. Please try again.', 'acquisitionsuite' ), 'repaired' => __( 'Repaired', 'acquisitionsuite' ), ); } // ── Pages ────────────────────────────────────────────────────────────── public function render() { if ( ! current_user_can( 'manage_options' ) ) { wp_die( esc_html__( 'Insufficient permissions.', 'acquisitionsuite' ), 403 ); } ACQUIS_Funnels::maybe_install(); // phpcs:disable WordPress.Security.NonceVerification.Recommended -- read-only screen selection $view = isset( $_GET['view'] ) ? sanitize_key( wp_unslash( $_GET['view'] ) ) : ''; $id = isset( $_GET['funnel'] ) ? absint( $_GET['funnel'] ) : 0; $days = isset( $_GET['days'] ) ? absint( $_GET['days'] ) : 30; // phpcs:enable ?>
; ?>)