PluginProbe
Formidable Forms – WordPress Form Builder for Contact Forms, Calculators, Quizzes & More / 6.26
Formidable Forms – WordPress Form Builder for Contact Forms, Calculators, Quizzes & More v6.26
6.35 6.34 6.33.1 6.33 6.32.1 6.32 6.31 6.25 6.25.1 6.26 6.26.1 6.27 6.28 6.29 6.3 6.3.1 6.3.2 6.30 6.4 6.4.1 6.4.2 6.5 6.5.1 6.5.2 6.5.3 All 141 releases
formidable / classes / controllers / FrmDashboardController.php

FrmDashboardController.php in Formidable Forms – WordPress Form Builder for Contact Forms, Calculators, Quizzes & More 6.26, at classes/controllers/FrmDashboardController.php

579 lines 16.5 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2 if ( ! defined( 'ABSPATH' ) ) {
3 die( 'You are not allowed to call this page directly.' );
4 }
5
6 class FrmDashboardController {
7
8 /**
9 * Handle name used for registering controller scripts and style.
10 */
11 const PAGE_SLUG = 'formidable-dashboard';
12
13 /**
14 * Option name used to store the dashboard options into db options table.
15 */
16 const OPTION_META_NAME = 'frm-dashboard-options';
17
18 /**
19 * Register all of the hooks related to the welcome screen functionality
20 *
21 * @return void
22 */
23 public static function load_admin_hooks() {
24 add_action( 'admin_menu', self::class . '::menu', 9 );
25 }
26
27 /**
28 * Register Dashboard page tp Formidable admin menu.
29 *
30 * @return void
31 */
32 public static function menu() {
33 add_submenu_page( 'formidable', 'Formidable | ' . __( 'Dashboard', 'formidable' ), esc_html__( 'Dashboard', 'formidable' ) . wp_kses_post( FrmInboxController::get_notice_count() ), 'frm_view_forms', 'formidable-dashboard', 'FrmDashboardController::route' );
34 }
35
36 /**
37 * Triggered from FrmAppController::load_page() with admin_init
38 *
39 * @since 6.8
40 *
41 * @return void
42 */
43 public static function load_page() {
44 self::remove_admin_notices_on_dashboard();
45 self::load_assets();
46
47 $unread_count = FrmEntriesHelper::get_visible_unread_inbox_count();
48
49 add_filter( 'manage_' . sanitize_title( FrmAppHelper::get_menu_name() ) . ( $unread_count ? '-' . $unread_count : '' ) . '_page_formidable-dashboard_columns', 'FrmDashboardController::entries_columns' );
50 add_filter( 'frm_show_footer_links', '__return_false' );
51 add_filter( 'screen_options_show_screen', '__return_false' );
52 }
53
54 /**
55 * Register and enqueue dashboard assets.
56 *
57 * @since 6.8
58 *
59 * @return void
60 */
61 public static function load_assets() {
62 self::register_assets();
63 self::enqueue_assets();
64 }
65
66 /**
67 * Gets dashboard helper instance.
68 *
69 * @since 6.17
70 *
71 * @return FrmDashboardHelper
72 */
73 public static function get_dashboard_helper() {
74 $latest_available_form = FrmForm::get_latest_form();
75 $total_payments = self::view_args_payments();
76 $counters_value = array(
77 'forms' => FrmForm::get_forms_count(),
78 'entries' => FrmEntry::get_entries_count(),
79 );
80
81 return new FrmDashboardHelper(
82 array(
83 'counters' => array(
84 'counters' => self::view_args_counters( $latest_available_form, $counters_value ),
85 ),
86 'license' => array(),
87 'get_free_templates' => array(),
88 'inbox' => self::view_args_inbox(),
89 'entries' => array(
90 'widget-heading' => __( 'Latest Entries', 'formidable' ),
91 'cta' => array(
92 'label' => __( 'View All Entries', 'formidable' ),
93 'link' => admin_url( 'admin.php?page=formidable-entries' ),
94 ),
95 'show-placeholder' => 0 >= (int) $counters_value['entries'],
96 'count' => $counters_value['entries'],
97 'placeholder' => self::view_args_entries_placeholder( $counters_value['forms'] ),
98 ),
99 'payments' => array(
100 'show-placeholder' => empty( $total_payments ),
101 'placeholder' => array(
102 'copy' => __( 'You don\'t have a payment form setup yet.', 'formidable' ),
103 'cta' => array(
104 'link' => admin_url( 'admin.php?page=formidable-form-templates' ),
105 'label' => esc_html__( 'Create a Payment Form', 'formidable' ),
106 ),
107 ),
108 'counters' => array(
109 array(
110 'heading' => __( 'Total Earnings', 'formidable' ),
111 'type' => 'currency',
112 'items' => $total_payments,
113 ),
114 ),
115 ),
116 'video' => array( 'id' => self::get_youtube_embed_video( $counters_value['entries'] ) ),
117 )
118 );
119 }
120
121 /**
122 * Init dashboard page.
123 *
124 * @return void
125 */
126 public static function route() {
127 $dashboard_view = self::get_dashboard_helper();
128
129 $should_display_videos = is_callable( 'FrmProDashboardHelper::should_display_videos' ) ? FrmProDashboardHelper::should_display_videos() : true;
130
131 require FrmAppHelper::plugin_path() . '/classes/views/dashboard/dashboard.php';
132 }
133
134 /**
135 * Init top counters widgets view args used to construct FrmDashboardHelper.
136 *
137 * @param false|object $latest_available_form If a form is available, we utilize its ID to direct the 'Create New Entry' link of the entries counter CTA when no entries exist.
138 * @param array $counters_value The counter values for "Total Forms" & "Total Entries".
139 *
140 * @return array
141 */
142 private static function view_args_counters( $latest_available_form, $counters_value ) {
143 $add_entry_cta_link = false !== $latest_available_form && isset( $latest_available_form->id ) ? admin_url( 'admin.php?page=formidable-entries&frm_action=new&form=' . $latest_available_form->id ) : '';
144
145 $lite_counters = array(
146 self::view_args_build_counter( __( 'Total Forms', 'formidable' ), array(), $counters_value['forms'] ),
147 self::view_args_build_counter(
148 __( 'Total Entries', 'formidable' ),
149 self::view_args_build_cta(
150 __( 'Add Entry', 'formidable' ),
151 $add_entry_cta_link,
152 self::display_counter_cta( 'entries', $counters_value['entries'], $latest_available_form )
153 ),
154 $counters_value['entries']
155 ),
156 );
157
158 $pro_counters_placeholder = array(
159 self::view_args_build_counter(
160 __( 'All Views', 'formidable' ),
161 self::view_args_build_cta(
162 __( 'Learn More', 'formidable' ),
163 admin_url( 'admin.php?page=formidable-views' )
164 )
165 ),
166 self::view_args_build_counter(
167 __( 'Installed Apps', 'formidable' ),
168 self::view_args_build_cta(
169 __( 'Learn More', 'formidable' ),
170 admin_url( 'admin.php?page=formidable-applications' )
171 )
172 ),
173 );
174
175 if ( class_exists( 'FrmProDashboardController' ) ) {
176 $pro_counters = FrmProDashboardController::get_counters();
177 return array_merge( $lite_counters, $pro_counters );
178 }
179
180 return array_merge( $lite_counters, $pro_counters_placeholder );
181 }
182
183 /**
184 * Build view args for counter widget.
185 *
186 * @param string $heading
187 * @param array $cta
188 * @param int $value
189 * @param string $type
190 *
191 * @return array
192 */
193 public static function view_args_build_counter( $heading, $cta = array(), $value = 0, $type = 'default' ) {
194
195 $counter_args = array(
196 'heading' => $heading,
197 'counter' => $value,
198 'type' => 'default',
199 );
200
201 if ( ! empty( $cta ) ) {
202 $counter_args['cta'] = $cta;
203 }
204
205 return $counter_args;
206 }
207
208 /**
209 * Build view args for cta.
210 *
211 * @param string $title
212 * @param string $link
213 * @param bool $display
214 *
215 * @return array
216 */
217 public static function view_args_build_cta( $title, $link = '#', $display = true ) {
218 return array(
219 'title' => $title,
220 'link' => $link,
221 'display' => $display,
222 );
223 }
224
225 /**
226 * Init total earnings widget view args to FrmDashboardHelper.
227 *
228 * @return array
229 */
230 private static function view_args_payments() {
231
232 $prepared_data = array();
233
234 $model_payments = new FrmTransLitePayment();
235 $payments = $model_payments->get_payments_stats();
236
237 foreach ( $payments['total'] as $currency => $total_payments ) {
238 if ( 0 < (int) $total_payments ) {
239 $prepared_data[] = array(
240 'counter_label' => FrmCurrencyHelper::get_currency( $currency ),
241 'counter' => (int) $total_payments,
242 );
243 }
244 }
245
246 return $prepared_data;
247 }
248
249 /**
250 * Init view args for entries placeholder.
251 *
252 * @param array $forms_count The total forms count. If there are no any forms yet, we'll have CTA pointing to creating a form.
253 *
254 * @return array
255 */
256 private static function view_args_entries_placeholder( $forms_count ) {
257
258 if ( ! $forms_count ) {
259 $copy = sprintf(
260 /* translators: %1$s: HTML start of a tag, %2$s: HTML close a tag */
261 __( 'See the %1$sform documentation%2$s for instructions on publishing your form', 'formidable' ),
262 '<a target="_blank" href="' . esc_url( FrmAppHelper::admin_upgrade_link( '', 'knowledgebase/publish-a-form/' ) ) . '">',
263 '</a>'
264 );
265 return array(
266 'background' => 'entries-placeholder',
267 'heading' => __( 'You Have No Entries Yet', 'formidable' ),
268 'copy' => $copy,
269 'button' => array(
270 'label' => esc_html__( 'Add New Form', 'formidable' ),
271 'link' => admin_url( 'admin.php?page=' . FrmFormTemplatesController::PAGE_SLUG ),
272 ),
273 );
274 }
275
276 $copy = sprintf(
277 /* translators: %1$s: HTML start of a tag, %2$s: HTML close a tag */
278 __( 'See the %1$sform documentation%2$s for instructions on publishing a form. Once vou have at least one entry you\'ll see it here.', 'formidable' ),
279 '<a target="_blank" href="' . FrmAppHelper::admin_upgrade_link( '', 'knowledgebase/publish-a-form/' ) . '">',
280 '</a>'
281 );
282 return array(
283 'background' => 'entries-placeholder',
284 'heading' => __( 'You Have No Entries Yet', 'formidable' ),
285 'copy' => $copy,
286 'button' => null,
287 );
288 }
289
290 /**
291 * A function to handle the counters cta from the top: Total Forms, Total Entries, All Views, Installed Apps.
292 *
293 * @param string $counter_type
294 * @param int $counter_value
295 * @param false|object $latest_available_form The form object of the latest form available. If there are at least one form available we show "Add Entry" cta for entries counter.
296 *
297 * @return array
298 */
299 public static function display_counter_cta( $counter_type, $counter_value, $latest_available_form = false ) {
300 if ( $counter_value > 0 || ( 'entries' === $counter_type && false === $latest_available_form ) ) {
301 return false;
302 }
303
304 return true;
305 }
306
307 /**
308 * Hide 3rd party notifications from dashboard
309 *
310 * @return void
311 */
312 public static function remove_admin_notices_on_dashboard() {
313 if ( false === self::is_dashboard_page() ) {
314 return;
315 }
316
317 global $wp_filter;
318
319 if ( isset( $wp_filter['admin_notices'] ) ) {
320 unset( $wp_filter['admin_notices'] );
321 }
322 }
323
324 /**
325 * Handle dashboard AJAX requests. Used in FrmHooksController
326 * Action name: dashboard_ajax_action.
327 *
328 * @return void
329 */
330 public static function ajax_requests() {
331 $dashboard_action = FrmAppHelper::get_post_param( 'dashboard_action', '', 'sanitize_text_field' );
332
333 switch ( $dashboard_action ) {
334
335 case 'welcome-banner-has-closed':
336 self::add_welcome_closed_banner_user_id();
337 wp_send_json_success();
338 break;
339
340 case 'save-subscribed-email':
341 $email = FrmAppHelper::get_post_param( 'email', '', 'sanitize_email' );
342 self::save_subscribed_email( $email );
343 wp_send_json_success();
344 break;
345 }
346 }
347
348 /**
349 * Handle the entries list. Called via add_filter.
350 * Hook name: manage_formidable_page_formidable-dashboard_columns.
351 *
352 * @param array $columns An associative array of column headings.
353 *
354 * @return array
355 */
356 public static function entries_columns( $columns = array() ) {
357 $columns['0_form_id'] = esc_html__( 'Form', 'formidable' );
358 $columns['0_name'] = esc_html__( 'Name', 'formidable' );
359 $columns['0_user_id'] = esc_html__( 'Author', 'formidable' );
360 $columns['0_created_at'] = esc_html__( 'Created on', 'formidable' );
361 return $columns;
362 }
363
364 /**
365 * Check if user has closed the welcome banner. The status of banner is saved in db options.
366 *
367 * @return bool
368 */
369 public static function welcome_banner_has_closed() {
370 $user_id = get_current_user_id();
371 $banner_closed_by_users = self::get_closed_welcome_banner_user_ids();
372
373 if ( ! empty( $banner_closed_by_users ) && in_array( $user_id, $banner_closed_by_users, true ) ) {
374 return true;
375 }
376 return false;
377 }
378
379 /**
380 * Check if is dashboard page.
381 *
382 * @return bool
383 */
384 public static function is_dashboard_page() {
385 return FrmAppHelper::is_admin_page( 'formidable-dashboard' );
386 }
387
388 /**
389 * Detect if the logged user's email is subscribed. Used for inbox email subscribe.
390 *
391 * @param string $email The logged user's email.
392 *
393 * @return bool
394 */
395 public static function email_is_subscribed( $email ) {
396 $subscribed_emails = self::get_subscribed_emails();
397 return in_array( $email, $subscribed_emails, true );
398 }
399
400 /**
401 * Register controller assets.
402 *
403 * @return void
404 */
405 public static function register_assets() {
406 wp_register_script( self::PAGE_SLUG, FrmAppHelper::plugin_url() . '/js/formidable_dashboard.js', array( 'formidable_admin' ), FrmAppHelper::plugin_version(), true );
407 wp_register_style( self::PAGE_SLUG, FrmAppHelper::plugin_url() . '/css/admin/dashboard.css', array(), FrmAppHelper::plugin_version() );
408 }
409
410 /**
411 * Enqueue controller assets.
412 *
413 * @return void
414 */
415 public static function enqueue_assets() {
416
417 if ( ! self::is_dashboard_page() ) {
418 return;
419 }
420
421 wp_enqueue_style( 'formidable-animations' );
422 wp_enqueue_style( self::PAGE_SLUG );
423 wp_enqueue_script( self::PAGE_SLUG );
424 }
425
426 /**
427 * Init the view args for Inbox widget.
428 *
429 * @return array
430 */
431 private static function view_args_inbox() {
432 return self::inbox_prepare_messages( FrmInboxController::get_inbox_messages() );
433 }
434
435 /**
436 * Prepare inbox messages data.
437 *
438 * @param array $data
439 *
440 * @return array
441 */
442 private static function inbox_prepare_messages( $data ) {
443 foreach ( $data as $key => $messages ) {
444 if ( in_array( $key, array( 'unread', 'dismissed' ), true ) ) {
445 foreach ( $messages as $key_msg => $message ) {
446 $data[ $key ][ $key_msg ]['cta'] = self::inbox_clean_messages_cta( $message['cta'] );
447 }
448 }
449 }
450 return $data;
451 }
452
453 /**
454 * Clean messages CTA.
455 *
456 * @param string $cta
457 *
458 * @return string
459 */
460 private static function inbox_clean_messages_cta( $cta ) {
461
462 // remove dismiss button
463 $pattern = '/<a[^>]*class="[^"]*frm_inbox_dismiss[^"]*"[^>]*>.*?<\/a>/is';
464 return preg_replace( $pattern, ' ', $cta );
465 }
466
467 /**
468 * Get the embed YouTube video from YouTube feed api. If there are 0 entries we show the welcome video otherwise latest video from FF YouTube channel is displayed.
469 *
470 * @param int|string $entries_count The total entries available.
471 *
472 * @return string|null The YouTube video ID.
473 */
474 private static function get_youtube_embed_video( $entries_count ) {
475 $youtube_api = new FrmYoutubeFeedApi();
476 $welcome_video = $youtube_api->get_video();
477 $featured_video = $youtube_api->get_video( 'featured' );
478
479 if ( 0 === (int) $entries_count && false === $welcome_video && false === $featured_video ) {
480 return null;
481 }
482
483 if ( 0 === (int) $entries_count && false !== $welcome_video ) {
484 return $welcome_video['video-id'] ?? null;
485 }
486
487 // We might receive the most recent video feed as the featured selection.
488 if ( isset( $featured_video[0] ) ) {
489 return $featured_video[0]['video-id'];
490 }
491
492 return $featured_video['video-id'] ?? null;
493 }
494
495 /**
496 * Save subscribed user's email to dashboard options.
497 * Used for Inbox widget - email subscribe.
498 *
499 * @param string $email The user email address.
500 *
501 * @return void
502 */
503 private static function save_subscribed_email( $email ) {
504 $subscribed_emails = self::get_subscribed_emails();
505
506 if ( ! in_array( $email, $subscribed_emails, true ) ) {
507 $subscribed_emails[] = $email;
508 self::update_dashboard_options( $subscribed_emails, 'inbox-subscribed-emails' );
509 }
510 }
511
512 /**
513 * Get list of users' ids that have closed the welcome banner.
514 *
515 * @return array
516 */
517 private static function get_closed_welcome_banner_user_ids() {
518 return self::get_dashboard_options( 'closed-welcome-banner-user-ids' );
519 }
520
521 /**
522 * Get list of subscribed emails. The list will contain all emails subscribed via Inbox widget.
523 *
524 * @return array
525 */
526 private static function get_subscribed_emails() {
527 return self::get_dashboard_options( 'inbox-subscribed-emails' );
528 }
529
530 /**
531 * Get the dashboard options from db.
532 *
533 * @param string|null $option_name The dashboard option name. If null it will return all dashboard options.
534 *
535 * @return array
536 */
537 private static function get_dashboard_options( $option_name = null ) {
538 $options = get_option( self::OPTION_META_NAME, array() );
539
540 if ( null !== $option_name && ! isset( $options[ $option_name ] ) ) {
541 return array();
542 }
543
544 if ( null !== $option_name ) {
545 return $options[ $option_name ];
546 }
547 return $options;
548 }
549
550 /**
551 * Update the dashboard options to db.
552 *
553 * @param array $data
554 * @param string $option_name
555 *
556 * @return void
557 */
558 private static function update_dashboard_options( $data, $option_name ) {
559 $options = self::get_dashboard_options();
560 $options[ $option_name ] = $data;
561 update_option( self::OPTION_META_NAME, $options, 'no' );
562 }
563
564 /**
565 * Save user id to closed banner list.
566 *
567 * @return void
568 */
569 private static function add_welcome_closed_banner_user_id() {
570 $users_list = self::get_closed_welcome_banner_user_ids();
571 $user_id = get_current_user_id();
572
573 if ( ! in_array( $user_id, $users_list, true ) ) {
574 $users_list[] = $user_id;
575 self::update_dashboard_options( $users_list, 'closed-welcome-banner-user-ids' );
576 }
577 }
578 }
579