PluginProbe
WPFunnels – Funnel Builder for WooCommerce with Checkout & One Click Upsell / 3.13.3
WPFunnels – Funnel Builder for WooCommerce with Checkout & One Click Upsell v3.13.3
3.13.3 3.13.2 3.13.1 3.13.0 3.12.13 3.12.12 3.12.11 3.12.10 3.12.9 3.12.8 3.12.7 3.12.6 3.12.5 3.12.4 3.12.3 3.12.1 3.12.2 3.12.0 3.11.1 3.11.0 3.10.9 3.10.8 3.10.7 3.10.6 2.8.16 All 261 releases
wpfunnels / admin / modules / automations / class-wpfnl-automations.php

class-wpfnl-automations.php in WPFunnels – Funnel Builder for WooCommerce with Checkout & One Click Upsell 3.13.3, at admin/modules/automations/class-wpfnl-automations.php

272 lines 10.3 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2 /**
3 * Automations module
4 *
5 * @package
6 */
7
8 namespace WPFunnels\Modules\Admin\Automations;
9
10 use WPFunnels\Admin\Module\Wpfnl_Admin_Module;
11 use WPFunnels\Traits\SingletonTrait;
12 use WPFunnels\Wpfnl_functions;
13
14 class Module extends Wpfnl_Admin_Module
15 {
16 use SingletonTrait;
17
18 public function __construct()
19 {
20 // Enqueue automation-canvas scripts
21 add_action('admin_enqueue_scripts', [$this, 'enqueue_automation_scripts']);
22
23 // The whole screen lives in the React admin now.
24 add_action('admin_init', [$this, 'maybe_redirect_to_react_admin']);
25
26 // Initialize REST API
27 require_once WPFNL_DIR . '/admin/modules/automations/class-wpfnl-automation-rest-api.php';
28 }
29
30 /**
31 * Send this screen to the React admin route.
32 *
33 * Both halves of this module's view — the promo for installs that are not
34 * licensed yet, and the automation list for the ones that are — now live at
35 * `?page=wpfunnels#/automation` (see src/admin/pages/Automation). The view
36 * is left in place as the fallback for anything that filters the redirect
37 * off.
38 *
39 * @return void
40 * @since 3.13.3
41 */
42 public function maybe_redirect_to_react_admin()
43 {
44 if (wp_doing_ajax() || wp_doing_cron()) {
45 return;
46 }
47
48 $page = isset($_GET['page']) ? sanitize_text_field(wp_unslash($_GET['page'])) : ''; // phpcs:ignore WordPress.Security.NonceVerification.Recommended
49
50 if (WPFNL_AUTOMATIONS_SLUG !== $page) {
51 return;
52 }
53
54 /**
55 * Filters whether the unlicensed automations screen redirects to the
56 * React admin route.
57 *
58 * @param bool $redirect Whether to redirect. Default true.
59 *
60 * @since 3.13.3
61 */
62 if (!apply_filters('wpfunnels/redirect_automations_to_react_admin', true)) {
63 return;
64 }
65
66 $url = admin_url('admin.php?page=' . WPFNL_MAIN_PAGE_SLUG) . '#/automation';
67
68 if (wp_safe_redirect($url)) {
69 exit;
70 }
71 }
72
73
74 /**
75 * Whether the React admin is being loaded by an install that can open the
76 * canvas editor.
77 *
78 * The editor ships inside the React bundle as a lazily loaded chunk, so the
79 * screen needs none of its own scripts — only the globals the editor reads
80 * and the WordPress editor pieces it embeds.
81 *
82 * @param string $hook Current admin screen hook suffix.
83 * @return bool
84 * @since 3.13.3
85 */
86 private function is_react_admin_screen($hook)
87 {
88 $react_admin_hooks = [
89 'toplevel_page_' . WPFNL_MAIN_PAGE_SLUG,
90 'wpfunnels_page_' . WPFNL_REACT_ADMIN_SLUG,
91 ];
92
93 if (!in_array($hook, $react_admin_hooks, true)) {
94 return false;
95 }
96
97 return Wpfnl_functions::is_mail_mint_pro_license_active()
98 && Wpfnl_functions::is_mail_mint_free_active()
99 && Wpfnl_functions::is_pro_license_activated();
100 }
101
102
103 /**
104 * Give the React admin what the canvas editor needs.
105 *
106 * The editor itself travels inside the React bundle as a lazily loaded
107 * chunk, so nothing is enqueued for it here — only the WordPress editor
108 * pieces it embeds and the two globals it reads.
109 *
110 * @param string $hook Current admin page hook
111 * @since 3.9.5
112 */
113 public function enqueue_automation_scripts($hook)
114 {
115 if (!$this->is_react_admin_screen($hook)) {
116 return;
117 }
118
119 // Enqueue wp-tinymce for WYSIWYG editor support
120 wp_tinymce_inline_scripts();
121 wp_enqueue_editor();
122
123 // The editor's full-screen overlay (.wpfnl-automation-modal) sits at
124 // z-index: 999999, higher than WP core's default .media-modal z-index —
125 // pushing the media library modal behind the editor chrome. Force it
126 // back on top.
127 wp_add_inline_style(
128 'media-views',
129 '.media-modal { z-index: 9999999999 !important; } .media-modal-backdrop { z-index: 999999998 !important; }'
130 );
131
132 wp_localize_script(
133 'wpfnl-react-admin',
134 'wpfnlAutomationVars',
135 [
136 'ajaxUrl' => admin_url('admin-ajax.php'),
137 'nonce' => wp_create_nonce('wpfnl_automation_nonce'),
138 'restUrl' => rest_url(),
139 'restNonce' => wp_create_nonce('wp_rest'),
140 ]
141 );
142
143 // Provide MRM_Vars global that automation-canvas components depend on.
144 $current_user = wp_get_current_user();
145 $email_settings = get_option( '_mrm_email_settings', array() );
146 $is_pro_active = defined( 'MAIL_MINT_PRO_VERSION' );
147 $is_pro_lic_active = $is_pro_active && class_exists( 'MRM\\Common\\MrmCommon' ) && \MRM\Common\MrmCommon::is_mailmint_pro_license_active();
148 $mint_trans = class_exists( 'Mint\\MRM\\Utilities\\Helper\\TranslationString\\TransStrings' )
149 ? \Mint\MRM\Utilities\Helper\TranslationString\TransStrings::getStrings()
150 : array();
151 $lists = class_exists( 'Mint\\MRM\\DataBase\\Models\\ContactGroupModel' )
152 ? \Mint\MRM\DataBase\Models\ContactGroupModel::get_all_to_custom_select( 'lists' )
153 : array();
154 $tags = class_exists( 'Mint\\MRM\\DataBase\\Models\\ContactGroupModel' )
155 ? \Mint\MRM\DataBase\Models\ContactGroupModel::get_all_to_custom_select( 'tags' )
156 : array();
157
158 wp_localize_script(
159 'wpfnl-react-admin',
160 'MRM_Vars',
161 array(
162 'ajaxurl' => admin_url( 'admin-ajax.php' ),
163 'api_base_url' => get_rest_url(),
164 'nonce' => wp_create_nonce( 'wp_rest' ),
165 'current_userID' => get_current_user_id(),
166 'admin_url' => get_admin_url(),
167 'date_format' => get_option( 'date_format', 'F j, Y' ),
168 'time_format' => get_option( 'time_format', 'H:i' ),
169 'gmt_offset' => get_option( 'gmt_offset' ),
170 'local_time' => date_i18n( 'Y-m-d H:i:s' ),
171 'current_user_email' => $current_user->user_email,
172 'email_settings' => $email_settings,
173 'lists' => $lists,
174 'tags' => $tags,
175 'is_wc_active' => class_exists( 'WooCommerce' ),
176 'is_edd_active' => defined( 'EDD_VERSION' ),
177 'is_mailmint_pro_active' => $is_pro_active,
178 'is_mailmint_pro_license_active' => $is_pro_lic_active,
179 'is_tutor_active' => defined( 'TUTOR_VERSION' ),
180 'is_gform_active' => class_exists( 'GFCommon' ),
181 'is_jetform_active' => class_exists( 'Jet_Form_Builder\\Plugin' ),
182 'is_fluentform_active' => defined( 'FLUENTFORM' ),
183 'is_learndash_active' => defined( 'LEARNDASH_VERSION' ),
184 'is_memberpress_active' => defined( 'MEPR_VERSION' ),
185 'is_contact_form_active' => defined( 'WPCF7_VERSION' ),
186 'is_lifterlms_active' => defined( 'LLMS_VERSION' ),
187 'is_fluent_booking_active' => defined( 'FLUENT_BOOKING_VERSION' ),
188 'is_wp_form_active' => class_exists( 'WPForms' ),
189 'is_bricks_active' => defined( 'BRICKS_VERSION' ),
190 'is_wcs_active' => class_exists( 'WC_Subscriptions' ),
191 'is_wcm_active' => class_exists( 'WC_Memberships' ),
192 'is_wcw_active' => class_exists( 'TInvWishlist' ),
193 'mint_trans' => $mint_trans,
194 'mint_page' => 'automation',
195 'open_ai_key' => array(),
196 'twilio_settings' => array(),
197 'post_types' => array(),
198 'contact_general_fields' => array(),
199 'contact_custom_fields' => array(),
200 'editor_data_source' => $this->get_editor_data_source(),
201 )
202 );
203 }
204
205 /**
206 * Provide the product/post category options the email builder's custom
207 * block panels (e.g. ProductBlock) read from MRM_Vars.editor_data_source.
208 * Without this key present, `options={undefined}` is passed to a Select
209 * field, which throws "Cannot read properties of undefined (reading 'map')"
210 * the moment that panel renders.
211 *
212 * @return array
213 * @since 3.12.10
214 */
215 private function get_editor_data_source()
216 {
217 return array(
218 'product_categories' => $this->get_formatted_categories( 'product_cat' ),
219 'post_categories' => $this->get_formatted_categories( 'category' ),
220 'placeholder_image' => '',
221 );
222 }
223
224 /**
225 * Fetch terms for a taxonomy formatted as {value, label} pairs.
226 *
227 * @param string $taxonomy Taxonomy name.
228 * @return array
229 * @since 3.12.10
230 */
231 private function get_formatted_categories( $taxonomy )
232 {
233 if ( ! taxonomy_exists( $taxonomy ) ) {
234 return array();
235 }
236
237 $terms = get_categories(
238 array(
239 'taxonomy' => $taxonomy,
240 'orderby' => 'name',
241 'hide_empty' => false,
242 )
243 );
244
245 $formatted = array();
246 foreach ( $terms as $term ) {
247 $formatted[] = array(
248 'value' => $term->term_id,
249 'label' => $term->name,
250 );
251 }
252
253 return $formatted;
254 }
255
256 public function get_view()
257 {
258 require_once WPFNL_DIR . '/admin/modules/automations/views/view.php';
259 }
260
261 public function get_name()
262 {
263 return __('automations','wpfnl');
264 }
265
266 public function init_ajax()
267 {
268
269 }
270 }
271
272