PluginProbe
Charitable – Donation & Fundraising Platform (Donation Forms, Recurring Donations & Fundraising Campaigns) / 1.8.11.3
Charitable – Donation & Fundraising Platform (Donation Forms, Recurring Donations & Fundraising Campaigns) v1.8.11.3
1.8.13.1 1.8.13 1.8.12.3 1.8.12.2 1.8.12.1 1.8.12 1.8.11.3 1.8.11.2 1.8.11.1 1.8.11 1.6.6 1.6.60 1.6.7 1.6.8 1.6.9 1.7.0 1.7.0.1 1.7.0.11 1.7.0.12 1.7.0.14 1.7.0.2 1.7.0.3 1.7.0.5 1.7.0.6 1.7.0.7 All 212 releases
charitable / includes / admin / growth-tools / class-charitable-growth-tools.php

class-charitable-growth-tools.php in Charitable – Donation & Fundraising Platform (Donation Forms, Recurring Donations & Fundraising Campaigns) 1.8.11.3, at includes/admin/growth-tools/class-charitable-growth-tools.php

556 lines 15.3 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2 /**
3 * Charitable Growth Tools.
4 *
5 * @package Charitable/Classes/Charitable_Guide_Tools
6 * @author David Bisset
7 * @copyright Copyright (c) 2023, WP Charitable LLC
8 * @license http://opensource.org/licenses/gpl-2.0.php GNU Public License
9 * @since 1.8.1.6
10 * @version 1.8.1.6
11 */
12
13 // Exit if accessed directly.
14 if ( ! defined( 'ABSPATH' ) ) {
15 exit;
16 }
17
18 if ( ! class_exists( 'Charitable_Guide_Tools' ) ) :
19
20 /**
21 * Charitable_Guide_Tools
22 *
23 * @final
24 * @since 1.8.1.6
25 */
26 class Charitable_Guide_Tools {
27
28 /**
29 * The single instance of this class.
30 *
31 * @var Charitable_Guide_Tools|null
32 */
33 private static $instance = null;
34
35
36 /**
37 * The installed plugins.
38 *
39 * @var array
40 */
41 public $installed_plugins = array();
42
43 /**
44 * The growth tools.
45 *
46 * @var array
47 */
48 public $growth_tools = array();
49
50 /**
51 * Create object instance.
52 *
53 * @since 1.8.1.6
54 */
55 public function __construct() {
56 }
57
58 /**
59 * Run things upon init.
60 *
61 * @since 1.8.1.6
62 *
63 * @return void
64 */
65 public function init() {
66 }
67
68 /**
69 * Get the tools, grabbing the information actually from the Charitable_Admin_Plugins_Third_Party library.
70 *
71 * @since 1.8.1.6
72 *
73 * @return array
74 */
75 public function get_growth_tools() {
76
77 if ( empty( $this->growth_tools ) ) {
78 $growth_tools = array();
79 $growth_tools = Charitable_Admin_Plugins_Third_Party::get_instance()->get_plugins( false );
80 $this->growth_tools = $growth_tools;
81 }
82
83 return apply_filters( 'charitable_growth_tools', $this->growth_tools );
84 }
85
86 /**
87 * Get the installed plugins.
88 *
89 * @since 1.8.1.6
90 *
91 * @return array
92 */
93 public function get_installed_plugins() {
94
95 if ( empty( $this->installed_plugins ) ) {
96 $installed_plugins = array();
97 $installed_plugins = get_plugins();
98 $this->installed_plugins = $installed_plugins;
99 }
100
101 return $this->installed_plugins;
102 }
103
104 /**
105 * Enqueue assets.
106 *
107 * @since 1.8.1.6
108 */
109 public function enqueue_scripts() {
110
111 $min = charitable_get_min_suffix();
112 $version = charitable()->get_version();
113 $assets_dir = charitable()->get_path( 'assets', false );
114
115 /* The following styles are only loaded on Charitable screens. */
116 $screen = get_current_screen();
117
118 if ( ( ! empty( $_GET['page'] ) && 'charitable-growth-tools' === $_GET['page'] ) ) { // phpcs:ignore
119
120 wp_enqueue_style(
121 'charitable-growth-tools',
122 $assets_dir . 'css/growth-tools/growth-tools' . $min . '.css',
123 array(),
124 $version
125 );
126
127 }
128 }
129
130 /**
131 * Get a single guide tool suggestion. This is what is called usually by another outside function.
132 *
133 * @param string $type The type of suggestion to get.
134 * @param bool $has_donations Whether the site has donations or not.
135 *
136 * @since 1.8.1.6
137 *
138 * @return array
139 */
140 public function get_suggestion( $type = false, $has_donations = true ) {
141
142 $suggestions = $this->generate_suggestions( $type );
143
144 // get unique keys from $suggestions and pick a random one.
145 $plugin_categories = array_keys( $suggestions );
146 $plugin_category = $plugin_categories[ array_rand( $plugin_categories ) ];
147
148 // get a random array element in the $suggestions array with the key of $plugin_category.
149 $plugin_suggestions = (array) $suggestions[ $plugin_category ];
150 if ( count( $plugin_suggestions ) > 1 ) {
151 $plugin_suggestion = $plugin_suggestions[ array_rand( $plugin_suggestions ) ];
152 } else {
153 $plugin_suggestion = $plugin_suggestions[0];
154 }
155
156 // get headline - if there has never been a donation, then offer a different text.
157 if ( $has_donations ) {
158 $plugin_suggestion['headline'] = esc_html__( 'Ready to grow your donations? Let Charitable help!', 'charitable' ) . ' 🚀';
159 } else {
160 $plugin_suggestion['headline'] = esc_html__( 'Excited to make your first donation? Let Charitable help!', 'charitable' ) . ' 🚀';
161 }
162
163 return $plugin_suggestion;
164 }
165
166
167 /**
168 * Generate a list of possible guide tool suggestions, seperated by category.
169 *
170 * @since 1.8.1.6.
171 *
172 * @param string $type The type of suggestion to generate.
173 *
174 * @return array
175 */
176 public function generate_suggestions( $type = false ) {
177
178 $suggestions = array();
179 $growth_tools = $this->get_growth_tools();
180
181 if ( ! $type ) {
182 return false;
183 }
184
185 // limit tool section to those assigned to a guide tools section.
186 $growth_tools = array_filter(
187 $growth_tools,
188 function ( $tool ) {
189 return isset( $tool['gt_section'] );
190 }
191 );
192
193 // get the list of installed plugins.
194 $installed_plugins = $this->get_installed_plugins();
195
196 // determine what to suggest based on what plugin they might not have installed.
197
198 // form plugins.
199 if ( ! $this->does_have_form_plugins( $installed_plugins ) ) {
200 $suggestions['form'] = $this->get_plugin_suggestion( 'form' );
201 }
202 if ( ! $this->does_have_seo_plugins( $installed_plugins ) ) {
203 $suggestions['seo'] = $this->get_plugin_suggestion( 'seo' );
204 }
205 if ( ! $this->does_have_email_plugins( $installed_plugins ) ) {
206 $suggestions['email'] = $this->get_plugin_suggestion( 'email' );
207 }
208 if ( ! $this->does_have_page_builder_plugins( $installed_plugins ) ) {
209 $suggestions['email'] = $this->get_plugin_suggestion( 'page-builder' );
210 }
211
212 $suggestions['marketing'] = $this->get_plugin_suggestion( 'marketing' );
213
214 return $suggestions;
215 }
216
217 /**
218 * Get a suggestion for a particular plugin.
219 *
220 * @since 1.8.1.6
221 *
222 * @param string $suggestion_type The type of suggestion to get.
223 *
224 * @return array
225 */
226 public function get_plugin_suggestion( $suggestion_type = 'form' ) {
227 $suggestions = array();
228
229 switch ( $suggestion_type ) {
230 case 'form':
231 $recommendations = array( 'wpforms', 'formidable' );
232 $plugin_list = array( 'tablepress', 'custom-post-type-ui', 'query-monitor', 'wpdatatables' );
233 $random_number = wp_rand( 1, 100 );
234
235 $has_plugin_list = false;
236 foreach ( $plugin_list as $plugin ) {
237 if ( isset( $this->installed_plugins[ $plugin ] ) ) {
238 $has_plugin_list = true;
239 break;
240 }
241 }
242 if ( $has_plugin_list ) {
243 // get random number.
244 $slug = $random_number > 75 ? 'formidable' : 'wpforms-lite';
245 } else {
246 $slug = $random_number > 50 ? 'formidable' : 'wpforms-lite';
247 }
248
249 $suggestions[] = $this->get_suggestion_from_growth_tools( $slug );
250 break;
251
252 case 'seo':
253 $suggestions[] = $this->get_suggestion_from_growth_tools( 'aioseo' );
254 break;
255 case 'email':
256 $suggestions[] = $this->get_suggestion_from_growth_tools( 'wp-mail-smtp' );
257 break;
258 case 'marketing':
259 $suggestions[] = $this->get_suggestion_from_growth_tools( 'rafflepress' );
260 $suggestions[] = $this->get_suggestion_from_growth_tools( 'pushengage' );
261 $suggestions[] = $this->get_suggestion_from_growth_tools( 'optinmonster' );
262 break;
263 case 'page-builder':
264 $suggestions[] = $this->get_suggestion_from_growth_tools( 'coming-soon' );
265 break;
266 }
267
268 return $suggestions;
269 }
270
271 /**
272 * Get a suggestion title, content, etc. from the guide tools.
273 *
274 * @param string $slug The slug of the guide tool to get.
275 *
276 * @since 1.8.1.6
277 *
278 * @return array
279 */
280 public function get_suggestion_from_growth_tools( $slug = false ) {
281 if ( ! $slug ) {
282 return false;
283 }
284
285 if ( empty( $this->growth_tools[ $slug ]['title'] ) || empty( $this->growth_tools[ $slug ]['excerpt'] ) || empty( $this->growth_tools[ $slug ]['why'] ) ) {
286 return false;
287 }
288
289 $tool = array(
290 'name' => isset( $this->growth_tools[ $slug ]['title'] ) ? esc_html( $this->growth_tools[ $slug ]['title'] ) : false,
291 'description' => isset( $this->growth_tools[ $slug ]['excerpt'] ) ? esc_html( $this->growth_tools[ $slug ]['excerpt'] ) : false,
292 'tip' => isset( $this->growth_tools[ $slug ]['why'] ) ? esc_html( $this->growth_tools[ $slug ]['why'] ) : false,
293 'id' => $slug,
294 'content' => $this->generate_content( $slug ),
295 );
296
297 return $tool;
298 }
299
300 /**
301 * Generate the content for a particular guide tool.
302 *
303 * @param string $slug The slug of the guide tool to generate content for.
304 *
305 * @since 1.8.1.6
306 *
307 * @return string
308 */
309 public function generate_content( $slug ) {
310
311 $growth_tools = $this->get_growth_tools();
312
313 // translators: Placeholder for the missing plugin name.
314 $content = '<p>' . sprintf( __( '%1$s We suggest %2$s.', 'charitable' ), ! empty( $this->growth_tools[ $slug ]['what'] ) ? 'We noticed you may not have ' . esc_html( $this->growth_tools[ $slug ]['what'] ) . '.' : false, '<a target="_blank" href="' . admin_url( 'admin.php?page=charitable-growth-tools#' . $this->growth_tools[ $slug ]['id'] ) . '" class="tool-suggestion">' . $this->growth_tools[ $slug ]['title'] . '</a>' ) . '</p>';
315
316 return $content;
317 }
318
319 /**
320 * Check if the site has a form plugin installed.
321 *
322 * @since 1.8.1.6
323 *
324 * @param array $installed_plugins The list of installed plugins.
325 *
326 * @return boolean
327 */
328 public function does_have_form_plugins( $installed_plugins = array() ) {
329
330 if ( empty( $installed_plugins ) ) {
331 $installed_plugins = get_plugins();
332 }
333
334 if ( empty( $installed_plugins ) ) {
335 return false;
336 }
337
338 $form_plugins = array(
339 'contact-form-7' => 'Contact Form 7',
340 'ninja-forms' => 'Ninja Forms',
341 'gravity-forms' => 'Gravity Forms',
342 );
343
344 foreach ( $form_plugins as $slug => $name ) {
345 if ( isset( $installed_plugins[ $slug ] ) ) {
346 return true;
347 }
348 }
349
350 return false;
351 }
352
353
354 /**
355 * Check if the site has a known SEO plugin installed.
356 *
357 * @since 1.8.1.6
358 *
359 * @param array $installed_plugins The list of installed plugins.
360 *
361 * @return boolean
362 */
363 public function does_have_seo_plugins( $installed_plugins = array() ) {
364
365 if ( empty( $installed_plugins ) ) {
366 $installed_plugins = get_plugins();
367 }
368
369 if ( empty( $installed_plugins ) ) {
370 return false;
371 }
372
373 $seo_plugins = array(
374 'yoast' => 'Yoast SEO',
375 );
376
377 foreach ( $seo_plugins as $slug => $name ) {
378 if ( isset( $installed_plugins[ $slug ] ) ) {
379 return true;
380 }
381 }
382
383 return false;
384 }
385
386 /**
387 * Check if the site has a known SEO plugin installed.
388 *
389 * @since 1.8.1.6
390 *
391 * @param array $installed_plugins The list of installed plugins.
392 *
393 * @return boolean
394 */
395 public function does_have_email_plugins( $installed_plugins = array() ) {
396
397 if ( empty( $installed_plugins ) ) {
398 $installed_plugins = get_plugins();
399 }
400
401 if ( empty( $installed_plugins ) ) {
402 return false;
403 }
404
405 $email_plugins = array(
406 'wp-mail-smtp' => 'WP Mail SMTP',
407 'smtp-mailer' => 'SMTP Mailer',
408 );
409
410 foreach ( $email_plugins as $slug => $name ) {
411 if ( isset( $installed_plugins[ $slug ] ) ) {
412 return true;
413 }
414 }
415
416 return false;
417 }
418
419 /**
420 * Check if the site has a known page builder plugin installed.
421 *
422 * @since 1.8.1.6
423 *
424 * @param array $installed_plugins The list of installed plugins.
425 *
426 * @return boolean
427 */
428 public function does_have_page_builder_plugins( $installed_plugins = array() ) {
429
430 if ( empty( $installed_plugins ) ) {
431 $installed_plugins = get_plugins();
432 }
433
434 if ( empty( $installed_plugins ) ) {
435 return false;
436 }
437
438 $plugin_list = array( '', '', '' );
439
440 $email_plugins = array(
441 'elementor' => 'Elementor',
442 'beaver-builder-lite-version' => 'Beaver Builder',
443 'wpbakery' => 'WPBakery',
444 );
445
446 foreach ( $email_plugins as $slug => $name ) {
447 if ( isset( $installed_plugins[ $slug ] ) ) {
448 return true;
449 }
450 }
451
452 return false;
453 }
454
455 /**
456 * Get the HTML for the dashboard notice.
457 *
458 * @since 1.8.1.6
459 *
460 * @param array $suggestion The suggestion to display.
461 * @param string $show_gt_chart_notice_headline The headline to display.
462 *
463 * @return string
464 */
465 public function get_dashboard_notice_html( $suggestion = array(), $show_gt_chart_notice_headline = '' ) {
466
467 if ( empty( $suggestion ) ) {
468 return false;
469 }
470
471 ob_start();
472
473 ?>
474
475 <?php if ( ! empty( $show_gt_chart_notice_headline ) ) : ?>
476 <h2 class=""><?php echo $show_gt_chart_notice_headline; // phpcs:ignore ?></h2>
477 <?php endif; ?>
478
479 <?php if ( ! empty( $suggestion['content'] ) ) : ?>
480 <?php echo $suggestion['content']; // phpcs:ignore ?>
481 <?php endif; ?>
482
483 <?php if ( ! empty( $suggestion['tip'] ) ) : ?>
484 <p class="charitable-notice-why"><strong><?php echo esc_html__( 'Tip:', 'charitable' ); ?></strong><br/><?php echo esc_html( $suggestion['tip'] ); ?></p>
485 <?php endif; ?>
486
487 <p class="more-recommendations"><?php echo esc_html__( 'More recommendations:', 'charitable' ); ?> <a target="_blank" href="<?php echo esc_url( admin_url( 'admin.php?page=charitable-growth-tools' ) ); ?>"><?php echo esc_html__( 'Growth Tools', 'charitable' ); ?></a> - <a target="_blank" href="<?php echo esc_url( admin_url( 'admin.php?page=charitable-addons' ) ); ?>"><?php echo esc_html__( 'Charitable Addons', 'charitable' ); ?></a></p>
488 <p class="charitable-dashboard-notice-another-suggestion"><a href="#"><strong><?php echo esc_html__( 'Get another suggestion.', 'charitable' ); ?></a></p>
489
490 <a href="#" class="charitable-remove-growth-tools" title="<?php echo esc_html__( 'Close this notice.', 'charitable' ); ?>"></a>
491
492 <?php
493
494 $notice_html = ob_get_clean();
495
496 return $notice_html;
497 }
498
499 /**
500 * Get the HTML for the dashboard notice via AJAX.
501 *
502 * @since 1.8.1.6
503 *
504 * @return void
505 */
506 public function ajax_get_dashboard_notice_html() {
507
508 // check for ajax.
509 if ( ! isset( $_POST['nonce'] ) || ! wp_verify_nonce( sanitize_text_field( wp_unslash( $_POST['nonce'] ) ), 'charitable-admin' ) ) { // phpcs:ignore
510 wp_send_json_error( esc_html__( 'No suggestions are available at this time.', 'charitable' ) );
511 }
512
513 $suggestion = ! empty( $_POST['suggestion'] ) ? esc_html( $_POST['suggestion'] ) : false; // phpcs:ignore
514 $headline = ! empty( $_POST['headline'] ) ? esc_html( $_POST['headline'] ) : false; // phpcs:ignore
515 $html = false;
516
517 if ( empty( $suggestion ) || empty( $headline ) ) {
518
519 $total_donations_array = (array) wp_count_posts( 'donation' ); // the function caches this, so we shouldn't have to.
520 $total_donations = ! empty( $total_donations_array ) ? array_sum( $total_donations_array ) : 0;
521 $headline = ( false !== $total_donations_array && is_array( $total_donations_array ) && $total_donations > 0 ) ? esc_html__( 'No donations recently? Let Charitable help!', 'charitable' ) . ' 🚀' : esc_html__( 'Excited to make your first donation? Let Charitable help!', 'charitable' ) . ' 🚀';
522 $suggestion = self::get_instance()->get_suggestion( 'dashboard', $total_donations );
523
524 $html = $this->get_dashboard_notice_html( $suggestion, $headline );
525
526 } else {
527
528 $html = $this->get_dashboard_notice_html( $suggestion, $headline );
529
530 }
531
532 if ( $html ) {
533 wp_send_json_success( $html );
534 } else {
535 wp_send_json_error( esc_html__( 'Error generating dashboard notice.', 'charitable' ) );
536 }
537 }
538
539 /**
540 * Returns and/or create the single instance of this class.
541 *
542 * @since 1.8.1.6
543 *
544 * @return Charitable_Guide_Tools
545 */
546 public static function get_instance() {
547 if ( is_null( self::$instance ) ) {
548 self::$instance = new self();
549 }
550
551 return self::$instance;
552 }
553 }
554
555 endif;
556