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

552 lines 16.3 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', __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 'inbox' => self::view_args_inbox(),
88 'entries' => array(
89 'widget-heading' => __( 'Latest Entries', 'formidable' ),
90 'cta' => array(
91 'label' => __( 'View All Entries', 'formidable' ),
92 'link' => admin_url( 'admin.php?page=formidable-entries' ),
93 ),
94 'show-placeholder' => 0 >= (int) $counters_value['entries'],
95 'count' => $counters_value['entries'],
96 'placeholder' => self::view_args_entries_placeholder( $counters_value['forms'] ),
97 ),
98 'payments' => array(
99 'show-placeholder' => empty( $total_payments ),
100 'placeholder' => array(
101 'copy' => __( 'You don\'t have a payment form setup yet.', 'formidable' ),
102 'cta' => array(
103 'link' => admin_url( 'admin.php?page=formidable-form-templates' ),
104 'label' => esc_html__( 'Create a Payment Form', 'formidable' ),
105 ),
106 ),
107 'counters' => array(
108 array(
109 'heading' => __( 'Total Earnings', 'formidable' ),
110 'type' => 'currency',
111 'items' => $total_payments,
112 ),
113 ),
114 ),
115 'video' => array( 'id' => self::get_youtube_embed_video( $counters_value['entries'] ) ),
116 )
117 );
118 }
119
120 /**
121 * Init dashboard page.
122 *
123 * @return void
124 */
125 public static function route() {
126 $dashboard_view = self::get_dashboard_helper();
127
128 $should_display_videos = is_callable( 'FrmProDashboardHelper::should_display_videos' ) ? FrmProDashboardHelper::should_display_videos() : true;
129
130 require FrmAppHelper::plugin_path() . '/classes/views/dashboard/dashboard.php';
131 }
132
133 /**
134 * Init top counters widgets view args used to construct FrmDashboardHelper.
135 *
136 * @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.
137 * @param array $counters_value The counter values for "Total Forms" & "Total Entries".
138 *
139 * @return array
140 */
141 private static function view_args_counters( $latest_available_form, $counters_value ) {
142 $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 ) : '';
143
144 $lite_counters = array(
145 self::view_args_build_counter( __( 'Total Forms', 'formidable' ), array(), $counters_value['forms'] ),
146 self::view_args_build_counter(
147 __( 'Total Entries', 'formidable' ),
148 self::view_args_build_cta(
149 __( 'Add Entry', 'formidable' ),
150 $add_entry_cta_link,
151 self::display_counter_cta( 'entries', $counters_value['entries'], $latest_available_form )
152 ),
153 $counters_value['entries']
154 ),
155 );
156
157 $pro_counters_placeholder = array(
158 self::view_args_build_counter(
159 __( 'All Views', 'formidable' ),
160 self::view_args_build_cta(
161 __( 'Learn More', 'formidable' ),
162 admin_url( 'admin.php?page=formidable-views' )
163 )
164 ),
165 self::view_args_build_counter(
166 __( 'Installed Apps', 'formidable' ),
167 self::view_args_build_cta(
168 __( 'Learn More', 'formidable' ),
169 admin_url( 'admin.php?page=formidable-applications' )
170 )
171 ),
172 );
173
174 if ( class_exists( 'FrmProDashboardController' ) ) {
175 $pro_counters = FrmProDashboardController::get_counters();
176 return array_merge( $lite_counters, $pro_counters );
177 }
178
179 return array_merge( $lite_counters, $pro_counters_placeholder );
180 }
181
182 /**
183 * Build view args for counter widget.
184 *
185 * @param string $heading
186 * @param array $cta
187 * @param int $value
188 * @param string $type
189 *
190 * @return array
191 */
192 public static function view_args_build_counter( $heading, $cta = array(), $value = 0, $type = 'default' ) {
193
194 $counter_args = array(
195 'heading' => $heading,
196 'counter' => $value,
197 'type' => 'default',
198 );
199 if ( ! empty( $cta ) ) {
200 $counter_args['cta'] = $cta;
201 }
202
203 return $counter_args;
204 }
205
206 /**
207 * Build view args for cta.
208 *
209 * @param string $title
210 * @param string $link
211 * @param bool $display
212 *
213 * @return array
214 */
215 public static function view_args_build_cta( $title, $link = '#', $display = true ) {
216 return array(
217 'title' => $title,
218 'link' => $link,
219 'display' => $display,
220 );
221 }
222
223 /**
224 * Init total earnings widget view args to FrmDashboardHelper.
225 *
226 * @return array
227 */
228 private static function view_args_payments() {
229
230 $prepared_data = array();
231
232 $model_payments = new FrmTransLitePayment();
233 $payments = $model_payments->get_payments_stats();
234 foreach ( $payments['total'] as $currency => $total_payments ) {
235 if ( 0 < (int) $total_payments ) {
236 $prepared_data[] = array(
237 'counter_label' => FrmCurrencyHelper::get_currency( $currency ),
238 'counter' => (int) $total_payments,
239 );
240 }
241 }
242
243 return $prepared_data;
244 }
245
246 /**
247 * Init view args for entries placeholder.
248 *
249 * @param array $forms_count The total forms count. If there are no any forms yet, we'll have CTA pointing to creating a form.
250 * @return array
251 */
252 private static function view_args_entries_placeholder( $forms_count ) {
253
254 if ( ! $forms_count ) {
255 $copy = sprintf(
256 /* translators: %1$s: HTML start of a tag, %2$s: HTML close a tag */
257 __( 'See the %1$sform documentation%2$s for instructions on publishing your form', 'formidable' ),
258 '<a target="_blank" href="' . FrmAppHelper::admin_upgrade_link( '', 'knowledgebase/publish-a-form/' ) . '">',
259 '</a>'
260 );
261 return array(
262 'background' => 'entries-placeholder',
263 'heading' => __( 'You Have No Entries Yet', 'formidable' ),
264 'copy' => $copy,
265 'button' => array(
266 'label' => esc_html__( 'Add New Form', 'formidable' ),
267 'link' => admin_url( 'admin.php?page=' . FrmFormTemplatesController::PAGE_SLUG ),
268 ),
269 );
270 }
271
272 $copy = sprintf(
273 /* translators: %1$s: HTML start of a tag, %2$s: HTML close a tag */
274 __( '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' ),
275 '<a target="_blank" href="' . FrmAppHelper::admin_upgrade_link( '', 'knowledgebase/publish-a-form/' ) . '">',
276 '</a>'
277 );
278 return array(
279 'background' => 'entries-placeholder',
280 'heading' => __( 'You Have No Entries Yet', 'formidable' ),
281 'copy' => $copy,
282 'button' => null,
283 );
284 }
285
286 /**
287 * A function to handle the counters cta from the top: Total Forms, Total Entries, All Views, Installed Apps.
288 *
289 * @param string $counter_type
290 * @param int $counter_value
291 * @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.
292 * @return array
293 */
294 public static function display_counter_cta( $counter_type, $counter_value, $latest_available_form = false ) {
295 if ( $counter_value > 0 || ( 'entries' === $counter_type && false === $latest_available_form ) ) {
296 return false;
297 }
298
299 return true;
300 }
301
302 /**
303 * Hide 3rd party notifications from dashboard
304 *
305 * @return void
306 */
307 public static function remove_admin_notices_on_dashboard() {
308 if ( false === self::is_dashboard_page() ) {
309 return;
310 }
311
312 global $wp_filter;
313 if ( isset( $wp_filter['admin_notices'] ) ) {
314 unset( $wp_filter['admin_notices'] );
315 }
316 }
317
318 /**
319 * Handle dashboard AJAX requests. Used in FrmHooksController
320 * Action name: dashboard_ajax_action.
321 *
322 * @return void
323 */
324 public static function ajax_requests() {
325 $dashboard_action = FrmAppHelper::get_post_param( 'dashboard_action', '', 'sanitize_text_field' );
326
327 switch ( $dashboard_action ) {
328
329 case 'welcome-banner-has-closed':
330 self::add_welcome_closed_banner_user_id();
331 wp_send_json_success();
332 break;
333
334 case 'save-subscribed-email':
335 $email = FrmAppHelper::get_post_param( 'email', '', 'sanitize_email' );
336 self::save_subscribed_email( $email );
337 wp_send_json_success();
338 break;
339 }
340 }
341
342 /**
343 * Handle the entries list. Called via add_filter.
344 * Hook name: manage_formidable_page_formidable-dashboard_columns.
345 *
346 * @param array $columns An associative array of column headings.
347 * @return array
348 */
349 public static function entries_columns( $columns = array() ) {
350 $columns['0_form_id'] = esc_html__( 'Form', 'formidable' );
351 $columns['0_name'] = esc_html__( 'Name', 'formidable' );
352 $columns['0_user_id'] = esc_html__( 'Author', 'formidable' );
353 $columns['0_created_at'] = esc_html__( 'Created on', 'formidable' );
354 return $columns;
355 }
356
357 /**
358 * Check if user has closed the welcome banner. The status of banner is saved in db options.
359 *
360 * @return bool
361 */
362 public static function welcome_banner_has_closed() {
363 $user_id = get_current_user_id();
364 $banner_closed_by_users = self::get_closed_welcome_banner_user_ids();
365
366 if ( ! empty( $banner_closed_by_users ) && in_array( $user_id, $banner_closed_by_users, true ) ) {
367 return true;
368 }
369 return false;
370 }
371
372 /**
373 * Check if is dashboard page.
374 *
375 * @return bool
376 */
377 public static function is_dashboard_page() {
378 return FrmAppHelper::is_admin_page( 'formidable-dashboard' );
379 }
380
381 /**
382 * Detect if the logged user's email is subscribed. Used for inbox email subscribe.
383 *
384 * @param string $email The logged user's email.
385 * @return bool
386 */
387 public static function email_is_subscribed( $email ) {
388 $subscribed_emails = self::get_subscribed_emails();
389 return in_array( $email, $subscribed_emails, true );
390 }
391
392 /**
393 * Register controller assets.
394 *
395 * @return void
396 */
397 public static function register_assets() {
398 wp_register_script( self::PAGE_SLUG, FrmAppHelper::plugin_url() . '/js/formidable_dashboard.js', array( 'formidable_admin' ), FrmAppHelper::plugin_version(), true );
399 wp_register_style( self::PAGE_SLUG, FrmAppHelper::plugin_url() . '/css/admin/dashboard.css', array(), FrmAppHelper::plugin_version() );
400 }
401
402 /**
403 * Enqueue controller assets.
404 *
405 * @return void
406 */
407 public static function enqueue_assets() {
408
409 if ( ! self::is_dashboard_page() ) {
410 return;
411 }
412
413 wp_enqueue_style( 'formidable-animations' );
414 wp_enqueue_style( self::PAGE_SLUG );
415 wp_enqueue_script( self::PAGE_SLUG );
416 }
417
418 /**
419 * Init the view args for Inbox widget.
420 *
421 * @return array
422 */
423 private static function view_args_inbox() {
424 return self::inbox_prepare_messages( FrmInboxController::get_inbox_messages() );
425 }
426
427 /**
428 * Prepare inbox messages data.
429 *
430 * @return array
431 */
432 private static function inbox_prepare_messages( $data ) {
433 foreach ( $data as $key => $messages ) {
434 if ( in_array( $key, array( 'unread', 'dismissed' ), true ) ) {
435 foreach ( $messages as $key_msg => $message ) {
436 $data[ $key ][ $key_msg ]['cta'] = self::inbox_clean_messages_cta( $message['cta'] );
437 }
438 }
439 }
440 return $data;
441 }
442
443 private static function inbox_clean_messages_cta( $cta ) {
444
445 // remove dismiss button
446 $pattern = '/<a[^>]*class="[^"]*frm_inbox_dismiss[^"]*"[^>]*>.*?<\/a>/is';
447 return preg_replace( $pattern, ' ', $cta );
448 }
449
450 /**
451 * 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.
452 *
453 * @param int $entries_count The total entries available.
454 * @return string|null The YouTube video ID.
455 */
456 private static function get_youtube_embed_video( $entries_count ) {
457 $youtube_api = new FrmYoutubeFeedApi();
458 $welcome_video = $youtube_api->get_video();
459 $featured_video = $youtube_api->get_video( 'featured' );
460
461 if ( 0 === (int) $entries_count && false === $welcome_video && false === $featured_video ) {
462 return null;
463 }
464 if ( 0 === (int) $entries_count && false !== $welcome_video ) {
465 return isset( $welcome_video['video-id'] ) ? $welcome_video['video-id'] : null;
466 }
467 // We might receive the most recent video feed as the featured selection.
468 if ( isset( $featured_video[0] ) ) {
469 return $featured_video[0]['video-id'];
470 }
471 return isset( $featured_video['video-id'] ) ? $featured_video['video-id'] : null;
472 }
473
474 /**
475 * Save subscribed user's email to dashboard options.
476 * Used for Inbox widget - email subscribe.
477 *
478 * @param string $email The user email address.
479 * @return void
480 */
481 private static function save_subscribed_email( $email ) {
482 $subscribed_emails = self::get_subscribed_emails();
483 if ( ! in_array( $email, $subscribed_emails, true ) ) {
484 $subscribed_emails[] = $email;
485 self::update_dashboard_options( $subscribed_emails, 'inbox-subscribed-emails' );
486 }
487 }
488
489 /**
490 * Get list of users' ids that have closed the welcome banner.
491 *
492 * @return array
493 */
494 private static function get_closed_welcome_banner_user_ids() {
495 return self::get_dashboard_options( 'closed-welcome-banner-user-ids' );
496 }
497
498 /**
499 * Get list of subscribed emails. The list will contain all emails subscribed via Inbox widget.
500 *
501 * @return array
502 */
503 private static function get_subscribed_emails() {
504 return self::get_dashboard_options( 'inbox-subscribed-emails' );
505 }
506
507 /**
508 * Get the dashboard options from db.
509 *
510 * @param string|null $option_name The dashboard option name. If null it will return all dashboard options.
511 * @return array
512 */
513 private static function get_dashboard_options( $option_name = null ) {
514 $options = get_option( self::OPTION_META_NAME, array() );
515 if ( null !== $option_name && ! isset( $options[ $option_name ] ) ) {
516 return array();
517 }
518 if ( null !== $option_name ) {
519 return $options[ $option_name ];
520 }
521 return $options;
522 }
523
524 /**
525 * Update the dashboard options to db.
526 *
527 * @param array $data
528 * @param string $option_name
529 *
530 * @return void
531 */
532 private static function update_dashboard_options( $data, $option_name ) {
533 $options = self::get_dashboard_options();
534 $options[ $option_name ] = $data;
535 update_option( self::OPTION_META_NAME, $options, 'no' );
536 }
537
538 /**
539 * Save user id to closed banner list.
540 *
541 * @return void
542 */
543 private static function add_welcome_closed_banner_user_id() {
544 $users_list = self::get_closed_welcome_banner_user_ids();
545 $user_id = get_current_user_id();
546 if ( ! in_array( $user_id, $users_list, true ) ) {
547 $users_list[] = $user_id;
548 self::update_dashboard_options( $users_list, 'closed-welcome-banner-user-ids' );
549 }
550 }
551 }
552