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

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