PluginProbe
Formidable Forms – WordPress Form Builder for Contact Forms, Calculators, Quizzes & More / 6.8.2
Formidable Forms – WordPress Form Builder for Contact Forms, Calculators, Quizzes & More v6.8.2
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.8.2, at classes/controllers/FrmDashboardController.php

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