| 1 |
<?php |
| 2 |
/** |
| 3 |
* This class is responsible for interactions (downloading/installing) addons and third-party addons, and recommendations. |
| 4 |
* |
| 5 |
* @package Charitable/Classes/Charitable_Admin_Plugins_Third_Party |
| 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 |
| 10 |
*/ |
| 11 |
|
| 12 |
// Exit if accessed directly. |
| 13 |
if ( ! defined( 'ABSPATH' ) ) { |
| 14 |
exit; |
| 15 |
} |
| 16 |
|
| 17 |
if ( ! class_exists( 'Charitable_Admin_Plugins_Third_Party' ) ) : |
| 18 |
|
| 19 |
/** |
| 20 |
* Charitable_Admin_Analytics |
| 21 |
* |
| 22 |
* @since 1.8.1 |
| 23 |
*/ |
| 24 |
final class Charitable_Admin_Plugins_Third_Party { |
| 25 |
|
| 26 |
/** |
| 27 |
* The name of our database table |
| 28 |
* |
| 29 |
* @since 1.8.1 |
| 30 |
* |
| 31 |
* @var string |
| 32 |
*/ |
| 33 |
public $table_name; |
| 34 |
|
| 35 |
/** |
| 36 |
* General storage for analytic data |
| 37 |
* |
| 38 |
* @since 1.8.1 |
| 39 |
* |
| 40 |
* @var array |
| 41 |
*/ |
| 42 |
public $analytics; |
| 43 |
|
| 44 |
/** |
| 45 |
* The single instance of this class. |
| 46 |
* |
| 47 |
* @var Charitable_Admin_Plugins_Third_Party|null |
| 48 |
*/ |
| 49 |
private static $instance = null; |
| 50 |
|
| 51 |
|
| 52 |
/** |
| 53 |
* Create class object. |
| 54 |
* |
| 55 |
* @since 1.8.1 |
| 56 |
*/ |
| 57 |
public function __construct() { |
| 58 |
|
| 59 |
$this->init(); |
| 60 |
} |
| 61 |
|
| 62 |
/** |
| 63 |
* Init class. |
| 64 |
* |
| 65 |
* @since 1.8.1 |
| 66 |
*/ |
| 67 |
public function init() { |
| 68 |
|
| 69 |
add_action( 'wp_ajax_charitable_dismiss_suggestion', array( $this, 'charitable_dismiss_suggestion' ) ); |
| 70 |
} |
| 71 |
|
| 72 |
/** |
| 73 |
* Dismiss a suggestion via AJAX. |
| 74 |
* |
| 75 |
* @since 1.8.1.5 |
| 76 |
* |
| 77 |
* @return void |
| 78 |
*/ |
| 79 |
public function charitable_dismiss_suggestion() { |
| 80 |
|
| 81 |
check_ajax_referer( 'charitable-admin', 'nonce' ); |
| 82 |
|
| 83 |
$post_data = sanitize_post( $_POST, 'raw' ); |
| 84 |
|
| 85 |
$slug = isset( $post_data['slug'] ) ? sanitize_text_field( wp_unslash( $post_data['slug'] ) ) : false; |
| 86 |
$type = isset( $post_data['type'] ) ? sanitize_text_field( wp_unslash( $post_data['type'] ) ) : false; |
| 87 |
|
| 88 |
if ( ! $slug ) { |
| 89 |
wp_send_json( |
| 90 |
array( |
| 91 |
'message' => esc_html__( 'Missing plugin name for dismiss.', 'charitable' ), |
| 92 |
) |
| 93 |
); |
| 94 |
} |
| 95 |
|
| 96 |
if ( ! $type ) { |
| 97 |
wp_send_json( |
| 98 |
array( |
| 99 |
'message' => esc_html__( 'Missing plugin type for dismiss.', 'charitable' ), |
| 100 |
) |
| 101 |
); |
| 102 |
} |
| 103 |
|
| 104 |
if ( 'addon' === $type ) { |
| 105 |
|
| 106 |
$user_meta_key = 'charitable_dismissed_addons'; |
| 107 |
|
| 108 |
} elseif ( 'partner' === $type ) { |
| 109 |
|
| 110 |
$user_meta_key = 'charitable_dismissed_partners'; |
| 111 |
|
| 112 |
} else { |
| 113 |
wp_send_json( |
| 114 |
array( |
| 115 |
'message' => esc_html__( 'Invalid plugin type for dismiss.', 'charitable' ), |
| 116 |
) |
| 117 |
); |
| 118 |
} |
| 119 |
|
| 120 |
$dismissed = (array) get_user_meta( get_current_user_id(), $user_meta_key, true ); |
| 121 |
|
| 122 |
if ( ! in_array( $slug, $dismissed, true ) ) { |
| 123 |
$dismissed[] = $slug; |
| 124 |
} |
| 125 |
|
| 126 |
// remove blank values. |
| 127 |
$dismissed = array_filter( $dismissed ); |
| 128 |
|
| 129 |
// update user meta. |
| 130 |
update_user_meta( get_current_user_id(), $user_meta_key, $dismissed ); |
| 131 |
|
| 132 |
wp_send_json_success( |
| 133 |
array( |
| 134 |
'dismissed' => $dismissed, |
| 135 |
), |
| 136 |
200 |
| 137 |
); |
| 138 |
|
| 139 |
wp_die(); |
| 140 |
} |
| 141 |
|
| 142 |
/** |
| 143 |
* Install plugins which are not Charitable addons. |
| 144 |
* |
| 145 |
* @since 1.8.1 |
| 146 |
* |
| 147 |
* @return void |
| 148 |
*/ |
| 149 |
public function install_plugin() { |
| 150 |
|
| 151 |
check_admin_referer( 'charitable-admin', 'nonce' ); |
| 152 |
|
| 153 |
$post_data = sanitize_post( $_POST, 'raw' ); |
| 154 |
|
| 155 |
// Permission check. |
| 156 |
if ( ! current_user_can( 'install_plugins' ) ) { |
| 157 |
wp_send_json( |
| 158 |
array( |
| 159 |
'error' => esc_html__( 'Plugin install is disabled for you on this site.', 'charitable' ), |
| 160 |
) |
| 161 |
); |
| 162 |
|
| 163 |
wp_send_json_error( esc_html__( 'Install error', 'charitable' ) ); |
| 164 |
} |
| 165 |
|
| 166 |
$slug = isset( $post_data['slug'] ) ? sanitize_text_field( wp_unslash( $post_data['slug'] ) ) : false; |
| 167 |
|
| 168 |
|
| 169 |
if ( ! $slug ) { |
| 170 |
wp_send_json( |
| 171 |
array( |
| 172 |
'message' => esc_html__( 'Missing plugin name for install.', 'charitable' ), |
| 173 |
) |
| 174 |
); |
| 175 |
} |
| 176 |
|
| 177 |
include_once ABSPATH . 'wp-admin/includes/plugin-install.php'; |
| 178 |
$api = plugins_api( |
| 179 |
'plugin_information', |
| 180 |
array( |
| 181 |
'slug' => $slug, |
| 182 |
'fields' => array( |
| 183 |
'short_description' => false, |
| 184 |
'sections' => false, |
| 185 |
'requires' => false, |
| 186 |
'rating' => false, |
| 187 |
'ratings' => false, |
| 188 |
'downloaded' => false, |
| 189 |
'last_updated' => false, |
| 190 |
'added' => false, |
| 191 |
'tags' => false, |
| 192 |
'compatibility' => false, |
| 193 |
'homepage' => false, |
| 194 |
'donate_link' => false, |
| 195 |
), |
| 196 |
) |
| 197 |
); |
| 198 |
|
| 199 |
if ( is_wp_error( $api ) ) { |
| 200 |
wp_send_json( |
| 201 |
array( |
| 202 |
'error' => $api->get_error_message(), |
| 203 |
) |
| 204 |
); |
| 205 |
if ( charitable_is_debug() ) : |
| 206 |
error_log( print_r( $api->get_error_message(), true ) ); // phpcs:ignore |
| 207 |
endif; |
| 208 |
die(); |
| 209 |
} |
| 210 |
|
| 211 |
$download_url = $api->download_link; |
| 212 |
|
| 213 |
$method = ''; |
| 214 |
$url = add_query_arg( |
| 215 |
array( |
| 216 |
'page' => 'charitable_settings', |
| 217 |
), |
| 218 |
admin_url( 'admin.php' ) |
| 219 |
); |
| 220 |
$url = esc_url( $url ); |
| 221 |
|
| 222 |
ob_start(); |
| 223 |
if ( false === ( $creds = request_filesystem_credentials( $url, $method, false, false, null ) ) ) { // phpcs:ignore |
| 224 |
$form = ob_get_clean(); |
| 225 |
|
| 226 |
wp_send_json( array( 'form' => $form ) ); |
| 227 |
} |
| 228 |
|
| 229 |
// If we are not authenticated, make it happen now. |
| 230 |
if ( ! WP_Filesystem( $creds ) ) { |
| 231 |
ob_start(); |
| 232 |
request_filesystem_credentials( $url, $method, true, false, null ); |
| 233 |
$form = ob_get_clean(); |
| 234 |
wp_send_json( array( 'form' => $form ) ); |
| 235 |
die(); |
| 236 |
} |
| 237 |
|
| 238 |
// Prevent language upgrade in ajax calls. |
| 239 |
remove_action( 'upgrader_process_complete', array( 'Language_Pack_Upgrader', 'async_upgrade' ), 20 ); |
| 240 |
|
| 241 |
// We do not need any extra credentials if we have gotten this far, so let's install the plugin. |
| 242 |
require_once ABSPATH . 'wp-admin/includes/class-wp-upgrader.php'; |
| 243 |
require_once plugin_dir_path( CHARITABLE_DIRECTORY_PATH ) . 'charitable/includes/utilities/Skin.php'; |
| 244 |
|
| 245 |
// Create the plugin upgrader with our custom skin. |
| 246 |
$skin = new Charitable_Skin(); |
| 247 |
$installer = new Plugin_Upgrader( $skin ); |
| 248 |
$installer->install( $download_url ); |
| 249 |
|
| 250 |
// Flush the cache and return the newly installed plugin basename. |
| 251 |
wp_cache_flush(); |
| 252 |
|
| 253 |
// send json success with array. |
| 254 |
$basename = $this->get_basename_from_slug( $slug ); |
| 255 |
|
| 256 |
wp_send_json_success( |
| 257 |
array( |
| 258 |
'basename' => $basename, |
| 259 |
), |
| 260 |
200 |
| 261 |
); |
| 262 |
|
| 263 |
wp_die(); |
| 264 |
} |
| 265 |
|
| 266 |
/** |
| 267 |
* Get plugin basename from slug. |
| 268 |
* |
| 269 |
* @param string $slug The plugin slug. |
| 270 |
*/ |
| 271 |
public function get_basename_from_slug( $slug = false ) { |
| 272 |
|
| 273 |
if ( false === $slug ) { |
| 274 |
return; |
| 275 |
} |
| 276 |
|
| 277 |
$basename = ''; |
| 278 |
$plugins = $this->get_plugins( false ); |
| 279 |
if ( charitable_is_debug() ) : |
| 280 |
error_log( print_r( $plugins, true ) ); // phpcs:ignore |
| 281 |
endif; |
| 282 |
if ( ! empty( $plugins ) ) : |
| 283 |
foreach ( $plugins as $nice_name => $plugin ) { |
| 284 |
if ( charitable_is_debug() ) : |
| 285 |
error_log( print_r( $plugin, true ) ); // phpcs:ignore |
| 286 |
endif; |
| 287 |
if ( ! empty( $plugin['slug'] ) && ( $slug === $plugin['slug'] || $slug === $nice_name ) && isset( $plugin['basename'] ) ) { |
| 288 |
$basename = $plugin['basename']; |
| 289 |
} |
| 290 |
} |
| 291 |
endif; |
| 292 |
|
| 293 |
return $basename; |
| 294 |
} |
| 295 |
|
| 296 |
/** |
| 297 |
* Activate plugin. |
| 298 |
* |
| 299 |
* @since 1.8.1 |
| 300 |
* @version 1.8.4 |
| 301 |
* |
| 302 |
* @return void |
| 303 |
*/ |
| 304 |
public function activate_plugin() { |
| 305 |
|
| 306 |
check_ajax_referer( 'charitable-admin', 'nonce' ); |
| 307 |
|
| 308 |
$post_data = sanitize_post( $_POST, 'raw' ); |
| 309 |
|
| 310 |
if ( ! current_user_can( 'install_plugins' ) ) { |
| 311 |
wp_send_json( |
| 312 |
array( |
| 313 |
'error' => esc_html__( 'You are not allowed to install plugins', 'charitable' ), |
| 314 |
) |
| 315 |
); |
| 316 |
} |
| 317 |
|
| 318 |
$basename = isset( $post_data['basename'] ) ? sanitize_text_field( wp_unslash( $post_data['basename'] ) ) : false; |
| 319 |
|
| 320 |
if ( ! $basename ) { |
| 321 |
wp_send_json( |
| 322 |
array( |
| 323 |
'message' => esc_html__( 'Missing plugin basename.', 'charitable' ), |
| 324 |
) |
| 325 |
); |
| 326 |
} |
| 327 |
|
| 328 |
$success = activate_plugin( $basename, '', false ); |
| 329 |
|
| 330 |
// Disable MonsterInsights redirect. |
| 331 |
if ( strstr( $basename, 'google-analytics-for-wordpress' ) ) { |
| 332 |
if ( charitable_is_debug() ) : |
| 333 |
error_log( print_r( 'MonsterInsights activated, deleting transient/updating option to prevent redirect.', true ) ); // phpcs:ignore |
| 334 |
endif; |
| 335 |
delete_transient( '_monsterinsights_activation_redirect' ); |
| 336 |
} |
| 337 |
// Disable Exactmetrics redirect. |
| 338 |
if ( strstr( $basename, 'google-analytics-dashboard-for-wp' ) ) { |
| 339 |
if ( charitable_is_debug() ) : |
| 340 |
error_log( print_r( 'Exactmetrics activated, deleting transient/updating option to prevent redirect.', true ) ); // phpcs:ignore |
| 341 |
endif; |
| 342 |
delete_transient( '_exactmetrics_activation_redirect' ); |
| 343 |
} |
| 344 |
// Disable WP Mail SMTP redirect. |
| 345 |
if ( strstr( $basename, 'wp-mail-smtp' ) ) { |
| 346 |
if ( charitable_is_debug() ) : |
| 347 |
error_log( print_r( 'WP Mail SMTP activated, deleting transient/updating option to prevent redirect.', true ) ); // phpcs:ignore |
| 348 |
endif; |
| 349 |
delete_transient( 'wp_mail_smtp_activation_redirect' ); |
| 350 |
} |
| 351 |
// Disable Rafflepress redirect. |
| 352 |
if ( strstr( $basename, 'rafflepress' ) ) { |
| 353 |
if ( charitable_is_debug() ) : |
| 354 |
error_log( print_r( 'Rafflepress activated, deleting transient/updating option to prevent redirect.', true ) ); // phpcs:ignore |
| 355 |
endif; |
| 356 |
delete_transient( '_rafflepress_welcome_screen_activation_redirect' ); |
| 357 |
} |
| 358 |
// Disable seedprod redirect. |
| 359 |
if ( strstr( $basename, 'seedprod' ) ) { |
| 360 |
if ( charitable_is_debug() ) : |
| 361 |
error_log( print_r( 'SeedProd activated, deleting transient/updating option to prevent redirect.', true ) ); // phpcs:ignore |
| 362 |
endif; |
| 363 |
delete_transient( '_seedprod_welcome_screen_activation_redirect' ); |
| 364 |
} |
| 365 |
// Disable instagram-feed redirect. |
| 366 |
if ( strstr( $basename, 'instagram-feed' ) ) { |
| 367 |
if ( charitable_is_debug() ) : |
| 368 |
error_log( print_r( 'Instagram Feed activated, deleting transient/updating option to prevent redirect.', true ) ); // phpcs:ignore |
| 369 |
endif; |
| 370 |
delete_option( 'sbi_plugin_do_activation_redirect' ); |
| 371 |
} |
| 372 |
// Disable facebook-feed redirect. |
| 373 |
if ( strstr( $basename, 'facebook-feed' ) ) { |
| 374 |
if ( charitable_is_debug() ) : |
| 375 |
error_log( print_r( 'Facebook Feed activated, deleting transient/updating option to prevent redirect.', true ) ); // phpcs:ignore |
| 376 |
endif; |
| 377 |
delete_option( 'cff_plugin_do_activation_redirect' ); |
| 378 |
} |
| 379 |
// Disable trustpulse redirect. |
| 380 |
if ( strstr( $basename, 'trustpulse' ) ) { |
| 381 |
if ( charitable_is_debug() ) : |
| 382 |
error_log( print_r( 'TrustPulse activated, deleting transient/updating option to prevent redirect.', true ) ); // phpcs:ignore |
| 383 |
endif; |
| 384 |
delete_option( 'trustpulse_api_plugin_do_activation_redirect' ); |
| 385 |
} |
| 386 |
// Disable searchwp-live-ajax-search redirect. |
| 387 |
if ( strstr( $basename, 'searchwp-live-ajax-search' ) ) { |
| 388 |
if ( charitable_is_debug() ) : |
| 389 |
error_log( print_r( 'SearchWP Live Search activated, deleting transient/updating option to prevent redirect.', true ) ); // phpcs:ignore |
| 390 |
endif; |
| 391 |
delete_transient( 'searchwp_live_search_activation_redirect' ); |
| 392 |
} |
| 393 |
// Disable duplicator redirect. |
| 394 |
if ( strstr( $basename, 'duplicator' ) ) { |
| 395 |
if ( charitable_is_debug() ) : |
| 396 |
error_log( print_r( 'Duplicator activated, deleting transient/updating option to prevent redirect.', true ) ); // phpcs:ignore |
| 397 |
endif; |
| 398 |
update_option( 'duplicator_redirect_to_welcome', false ); |
| 399 |
} |
| 400 |
// Disable pushengage redirect. |
| 401 |
if ( strstr( $basename, 'pushengage' ) ) { |
| 402 |
if ( charitable_is_debug() ) : |
| 403 |
error_log( print_r( 'PushEngage activated, deleting transient/updating option to prevent redirect.', true ) ); // phpcs:ignore |
| 404 |
endif; |
| 405 |
delete_transient( 'pushengage_activation_redirect' ); |
| 406 |
} |
| 407 |
|
| 408 |
/* |
| 409 |
* Record that Charitable drove this WPVibe install, for cross-brand |
| 410 |
* attribution. The option pair is UNPREFIXED on purpose: whichever |
| 411 |
* Awesome Motive plugin installs the promoted plugin writes its own |
| 412 |
* name into `<plugin>_source`, and each brand's own check-in claims |
| 413 |
* only the installs whose source names IT. The key is `wpvibe_source`, |
| 414 |
* the plugin's published `vibe-ai` slug notwithstanding, because that |
| 415 |
* is the key every brand agrees to read - WPForms uses the identical |
| 416 |
* pair for the same plugin. Guarded so a value another AM plugin |
| 417 |
* already wrote is never overwritten: the option records who FIRST |
| 418 |
* drove the install. This method is reached only through Charitable's |
| 419 |
* own AJAX installer, so the attribution is never claimed for an |
| 420 |
* activation the user made from the Plugins screen directly. |
| 421 |
* |
| 422 |
* Written as a fixed 'Charitable Lite', not a charitable_is_pro() |
| 423 |
* ternary: this file ships in the Lite plugin, so the driver is |
| 424 |
* always Charitable Lite. Pro's own copy of this method (Charitable |
| 425 |
* Pro is a separate, standalone plugin - it never runs alongside |
| 426 |
* Lite) writes 'Charitable Pro'. Both strings contain 'Charitable', |
| 427 |
* which is all a receiving check-in matches on. |
| 428 |
* |
| 429 |
* Autoload explicitly OFF (fix round 2, ITEM 2): Pro's own copy of |
| 430 |
* this method omits the third argument, which defaults an option |
| 431 |
* to autoloaded. Both of these are read only from this one admin |
| 432 |
* screen and from a weekly check-in - never on the front end, never |
| 433 |
* on most admin requests - so there is no reason to load either of |
| 434 |
* them into memory on every request the way autoloaded options are. |
| 435 |
* Deliberately NOT matching Pro here. |
| 436 |
* |
| 437 |
* @since 1.8.13 |
| 438 |
*/ |
| 439 |
if ( strstr( $basename, 'vibe-ai' ) && ! get_option( 'wpvibe_source' ) ) { |
| 440 |
update_option( 'wpvibe_source', 'Charitable Lite', false ); |
| 441 |
update_option( 'wpvibe_date', time(), false ); |
| 442 |
} |
| 443 |
|
| 444 |
if ( is_wp_error( $success ) ) { |
| 445 |
wp_send_json_error( |
| 446 |
array( |
| 447 |
'error' => $success->get_error_message(), |
| 448 |
) |
| 449 |
); |
| 450 |
wp_die(); |
| 451 |
} |
| 452 |
|
| 453 |
$setup = $this->get_setup_screen_for_plugin( $basename ); |
| 454 |
|
| 455 |
if ( $setup ) : |
| 456 |
|
| 457 |
wp_send_json_success( |
| 458 |
array( |
| 459 |
'setup' => $setup, |
| 460 |
), |
| 461 |
200 |
| 462 |
); |
| 463 |
wp_die(); |
| 464 |
|
| 465 |
endif; |
| 466 |
|
| 467 |
$settings = $this->get_settings_screen_for_plugin( $basename ); |
| 468 |
|
| 469 |
if ( $settings ) : |
| 470 |
|
| 471 |
wp_send_json_success( |
| 472 |
array( |
| 473 |
'settings' => $settings, |
| 474 |
), |
| 475 |
200 |
| 476 |
); |
| 477 |
wp_die(); |
| 478 |
|
| 479 |
endif; |
| 480 |
|
| 481 |
wp_die(); |
| 482 |
} |
| 483 |
|
| 484 |
/** |
| 485 |
* Checks if plugin is installed. |
| 486 |
* |
| 487 |
* @param string $plugin The plugin slug. |
| 488 |
*/ |
| 489 |
public function is_plugin_installed( $plugin = '' ) { |
| 490 |
|
| 491 |
if ( empty( $plugin ) ) { |
| 492 |
return false; |
| 493 |
} |
| 494 |
|
| 495 |
$plugins = $this->get_plugins( false ); |
| 496 |
|
| 497 |
if ( ! empty( $plugins[ $plugin ] ) && ! empty( $plugins[ $plugin ]['installed'] ) ) { |
| 498 |
return (bool) $plugins[ $plugin ]['installed']; |
| 499 |
} |
| 500 |
|
| 501 |
return false; |
| 502 |
} |
| 503 |
|
| 504 |
/** |
| 505 |
* Checks if plugin is activated. |
| 506 |
* |
| 507 |
* @param string $plugin The plugin slug. |
| 508 |
*/ |
| 509 |
public function is_plugin_activated( $plugin = '' ) { |
| 510 |
|
| 511 |
if ( empty( $plugin ) ) { |
| 512 |
return false; |
| 513 |
} |
| 514 |
|
| 515 |
$plugins = $this->get_plugins( false ); |
| 516 |
|
| 517 |
if ( ! empty( $plugins[ $plugin ] ) && ! empty( $plugins[ $plugin ]['active'] ) ) { |
| 518 |
return (bool) $plugins[ $plugin ]['active']; |
| 519 |
} |
| 520 |
|
| 521 |
return false; |
| 522 |
} |
| 523 |
|
| 524 |
/** |
| 525 |
* Get plugin basename. |
| 526 |
* |
| 527 |
* @param string $plugin The plugin slug. |
| 528 |
*/ |
| 529 |
public function get_basename( $plugin = '' ) { |
| 530 |
|
| 531 |
if ( empty( $plugin ) ) { |
| 532 |
return false; |
| 533 |
} |
| 534 |
|
| 535 |
$plugins = $this->get_plugins( false ); |
| 536 |
|
| 537 |
if ( ! empty( $plugins[ $plugin ] ) && ! empty( $plugins[ $plugin ]['active'] ) ) { |
| 538 |
return $plugins[ $plugin ]['basename']; |
| 539 |
} |
| 540 |
|
| 541 |
return false; |
| 542 |
} |
| 543 |
|
| 544 |
/** |
| 545 |
* Get plugin setup url. |
| 546 |
* |
| 547 |
* @param string $slug_or_basename The plugin slug. |
| 548 |
*/ |
| 549 |
public function get_setup_screen_for_plugin( $slug_or_basename = false ) { |
| 550 |
|
| 551 |
if ( false === $slug_or_basename ) { |
| 552 |
return; |
| 553 |
} |
| 554 |
|
| 555 |
$setup = ''; |
| 556 |
$plugins = $this->get_plugins( false ); |
| 557 |
if ( ! empty( $plugins ) ) : |
| 558 |
foreach ( $plugins as $plugin_slug => $plugin_info ) { |
| 559 |
if ( ! empty( $plugin_info['setup'] ) && ( $plugin_slug === $slug_or_basename || $plugin_info['basename'] === $slug_or_basename ) ) { |
| 560 |
$setup = $plugin_info['setup']; |
| 561 |
} |
| 562 |
} |
| 563 |
endif; |
| 564 |
|
| 565 |
return $setup; |
| 566 |
} |
| 567 |
|
| 568 |
/** |
| 569 |
* Get plugin settings url. |
| 570 |
* |
| 571 |
* @param string $slug_or_basename The plugin slug. |
| 572 |
*/ |
| 573 |
public function get_settings_screen_for_plugin( $slug_or_basename = false ) { |
| 574 |
|
| 575 |
if ( false === $slug_or_basename ) { |
| 576 |
return; |
| 577 |
} |
| 578 |
|
| 579 |
$setup = ''; |
| 580 |
$plugins = $this->get_plugins( false ); |
| 581 |
if ( ! empty( $plugins ) ) : |
| 582 |
foreach ( $plugins as $plugin_slug => $plugin_info ) { |
| 583 |
if ( ! empty( $plugin_info['settings'] ) && ( $plugin_slug === $slug_or_basename || $plugin_info['basename'] === $slug_or_basename ) ) { |
| 584 |
$setup = $plugin_info['settings']; |
| 585 |
} |
| 586 |
} |
| 587 |
endif; |
| 588 |
|
| 589 |
return $setup; |
| 590 |
} |
| 591 |
|
| 592 |
/** |
| 593 |
* Get plugin learn more button. |
| 594 |
* |
| 595 |
* @param string $plugin_slug The plugin slug. |
| 596 |
* @param string $button_text The button text. |
| 597 |
* @param string $css The button css. |
| 598 |
*/ |
| 599 |
public function get_learn_more_button_html( $plugin_slug = false, $button_text = 'Learn More', $css = '' ) { |
| 600 |
|
| 601 |
if ( false === $plugin_slug ) { |
| 602 |
return; |
| 603 |
} |
| 604 |
|
| 605 |
$plugins = $this->get_plugins( false ); |
| 606 |
|
| 607 |
if ( ! isset( $plugins[ $plugin_slug ] ) ) { |
| 608 |
return; |
| 609 |
} |
| 610 |
|
| 611 |
$plugin = $plugins[ $plugin_slug ]; |
| 612 |
|
| 613 |
if ( ! $plugin || ! isset( $plugin['slug'] ) ) { |
| 614 |
return; |
| 615 |
} |
| 616 |
|
| 617 |
$button_css = 'charitable-button button-link charitable-button-learn-more'; |
| 618 |
|
| 619 |
if ( $css !== '' ) { |
| 620 |
$button_css .= ' ' . $css; |
| 621 |
} |
| 622 |
|
| 623 |
if ( false === $button_text ) { |
| 624 |
$button_text = esc_html__( 'Learn More', 'charitable' ); |
| 625 |
} |
| 626 |
|
| 627 |
$url = ! empty( $plugin['gt_learn'] ) ? esc_url( $plugin['gt_learn'] ) : false; |
| 628 |
|
| 629 |
if ( ! $url ) { |
| 630 |
return; |
| 631 |
} |
| 632 |
|
| 633 |
$button = '<a href="' . $url . '" target=="_blank" class="' . $button_css . '" data-charitable-third-party-plugin="' . esc_attr( $plugin['slug'] ) . '">' . $button_text . '</a>'; |
| 634 |
|
| 635 |
return $button; |
| 636 |
} |
| 637 |
|
| 638 |
/** |
| 639 |
* Get plugin install button. |
| 640 |
* |
| 641 |
* @param string $plugin_slug The plugin slug. |
| 642 |
* @param string $button_text The button text. |
| 643 |
* @param string $css The button css. |
| 644 |
*/ |
| 645 |
public function get_install_button_html( $plugin_slug = false, $button_text = 'Install', $css = '' ) { |
| 646 |
|
| 647 |
if ( false === $plugin_slug ) { |
| 648 |
return; |
| 649 |
} |
| 650 |
|
| 651 |
$plugins = $this->get_plugins( false ); |
| 652 |
|
| 653 |
if ( ! isset( $plugins[ $plugin_slug ] ) ) { |
| 654 |
return; |
| 655 |
} |
| 656 |
|
| 657 |
$plugin = $plugins[ $plugin_slug ]; |
| 658 |
|
| 659 |
if ( ! $plugin || ! isset( $plugin['slug'] ) ) { |
| 660 |
return; |
| 661 |
} |
| 662 |
|
| 663 |
$button_css = 'charitable-button button-link charitable-button-install'; |
| 664 |
|
| 665 |
if ( $css !== '' ) { |
| 666 |
$button_css .= ' ' . $css; |
| 667 |
} |
| 668 |
|
| 669 |
if ( false === $button_text ) { |
| 670 |
$button_text = esc_html__( 'Install', 'charitable' ); |
| 671 |
} |
| 672 |
|
| 673 |
$button = '<a href="#" class="' . $button_css . '" data-charitable-third-party-plugin="' . esc_attr( $plugin['slug'] ) . '">' . $button_text . '</a>'; |
| 674 |
|
| 675 |
return $button; |
| 676 |
} |
| 677 |
|
| 678 |
/** |
| 679 |
* Get plugin activation button. |
| 680 |
* |
| 681 |
* @param string $plugin_slug The plugin slug. |
| 682 |
* @param string $button_text The button text. |
| 683 |
* @param string $css The button css. |
| 684 |
*/ |
| 685 |
public function get_activation_button_html( $plugin_slug = false, $button_text = 'Activate', $css = '' ) { |
| 686 |
|
| 687 |
if ( false === $plugin_slug ) { |
| 688 |
return; |
| 689 |
} |
| 690 |
|
| 691 |
$plugins = $this->get_plugins( false ); |
| 692 |
|
| 693 |
if ( ! isset( $plugins[ $plugin_slug ] ) ) { |
| 694 |
return; |
| 695 |
} |
| 696 |
|
| 697 |
$plugin = $plugins[ $plugin_slug ]; |
| 698 |
|
| 699 |
if ( ! $plugin || ! isset( $plugin['basename'] ) ) { |
| 700 |
return; |
| 701 |
} |
| 702 |
|
| 703 |
$button_css = 'charitable-button button-link charitable-button-activate'; |
| 704 |
|
| 705 |
if ( $css !== '' ) { |
| 706 |
$button_css .= ' ' . $css; |
| 707 |
$button_css = str_replace( 'install', 'activate', $button_css ); |
| 708 |
} |
| 709 |
|
| 710 |
if ( false === $button_text ) { |
| 711 |
$button_text = esc_html__( 'Activate', 'charitable' ); |
| 712 |
} |
| 713 |
|
| 714 |
$button = '<a href="#" class="' . $button_css . '" data-basename="' . $plugin['basename'] . '">' . $button_text . '</a>'; |
| 715 |
|
| 716 |
return $button; |
| 717 |
} |
| 718 |
|
| 719 |
/** |
| 720 |
* Get plugin setup html link/button. |
| 721 |
* |
| 722 |
* @param string $plugin_slug The plugin slug. |
| 723 |
* @param string $button_text The button text. |
| 724 |
* @param string $css The button css. |
| 725 |
* @param string $setup_link The setup link. |
| 726 |
*/ |
| 727 |
public function get_setup_button_html( $plugin_slug = false, $button_text = 'Activate', $css = '', $setup_link = '' ) { |
| 728 |
|
| 729 |
if ( false === $plugin_slug ) { |
| 730 |
return; |
| 731 |
} |
| 732 |
|
| 733 |
$plugins = $this->get_plugins( false ); |
| 734 |
|
| 735 |
if ( ! isset( $plugins[ $plugin_slug ] ) ) { |
| 736 |
return; |
| 737 |
} |
| 738 |
|
| 739 |
$plugin = $plugins[ $plugin_slug ]; |
| 740 |
|
| 741 |
if ( ! $plugin || ! isset( $plugin['basename'] ) || ! isset( $plugin['setup'] ) ) { |
| 742 |
return; |
| 743 |
} |
| 744 |
|
| 745 |
$setup_link = isset( $plugin['setup'] ) ? esc_url( $plugin['setup'] ) : esc_url( admin_url() ); |
| 746 |
|
| 747 |
$button_css = 'charitable-button button-link charitable-button-setup'; |
| 748 |
|
| 749 |
if ( $css !== '' ) { |
| 750 |
$button_css .= ' ' . $css; |
| 751 |
$button_css = str_replace( 'install', 'setup', $button_css ); |
| 752 |
$button_css = str_replace( 'activate', 'setup', $button_css ); |
| 753 |
} |
| 754 |
|
| 755 |
if ( false === $button_text ) { |
| 756 |
$button_text = esc_html__( 'Setup', 'charitable' ); |
| 757 |
} |
| 758 |
|
| 759 |
$button = '<a href="' . esc_url( $setup_link ) . '" class="' . $button_css . '" data-basename="' . $plugin['basename'] . '">' . $button_text . '</a>'; |
| 760 |
|
| 761 |
return $button; |
| 762 |
} |
| 763 |
|
| 764 |
/** |
| 765 |
* Get plugin button html. |
| 766 |
* |
| 767 |
* @since 1.8.1.5 |
| 768 |
* |
| 769 |
* @param string $plugin_slug The plugin slug. |
| 770 |
* @param string $button_text The button text. |
| 771 |
* @param string $css The button css. |
| 772 |
* |
| 773 |
* @return string |
| 774 |
*/ |
| 775 |
public function get_plugin_button_html( $plugin_slug = false, $button_text = false, $css = false ) { |
| 776 |
|
| 777 |
if ( false === $plugin_slug ) { |
| 778 |
return; |
| 779 |
} |
| 780 |
|
| 781 |
if ( $this->is_plugin_learn_more( $plugin_slug ) ) { |
| 782 |
return $this->get_learn_more_button_html( $plugin_slug, false, $css ); |
| 783 |
} |
| 784 |
|
| 785 |
$is_installed = $this->is_plugin_installed( $plugin_slug ); |
| 786 |
$is_active = $this->is_plugin_activated( $plugin_slug ); |
| 787 |
|
| 788 |
if ( ! $is_installed ) { |
| 789 |
return $this->get_install_button_html( $plugin_slug, $button_text, $css ); |
| 790 |
} |
| 791 |
|
| 792 |
if ( ! $is_active ) { |
| 793 |
return $this->get_activation_button_html( $plugin_slug, $button_text, $css ); |
| 794 |
} |
| 795 |
|
| 796 |
return $this->get_setup_button_html( $plugin_slug, $button_text, $css ); |
| 797 |
} |
| 798 |
|
| 799 |
|
| 800 |
/** |
| 801 |
* Check if plugin has a learn more link. |
| 802 |
* |
| 803 |
* @since 1.8.1.6 |
| 804 |
* |
| 805 |
* @param string $plugin_slug The plugin slug. |
| 806 |
* |
| 807 |
* @return boolean |
| 808 |
*/ |
| 809 |
public function is_plugin_learn_more( $plugin_slug = false ) { |
| 810 |
|
| 811 |
if ( false === $plugin_slug ) { |
| 812 |
return; |
| 813 |
} |
| 814 |
|
| 815 |
$plugins = $this->get_plugins( false ); |
| 816 |
|
| 817 |
if ( ! isset( $plugins[ $plugin_slug ] ) ) { |
| 818 |
return; |
| 819 |
} |
| 820 |
|
| 821 |
$plugin = $plugins[ $plugin_slug ]; |
| 822 |
|
| 823 |
if ( ! $plugin || ! isset( $plugin['slug'] ) ) { |
| 824 |
return; |
| 825 |
} |
| 826 |
|
| 827 |
$learn = ! empty( $plugin['gt_learn'] ) ? esc_url( $plugin['gt_learn'] ) : false; |
| 828 |
|
| 829 |
if ( $learn ) { |
| 830 |
return true; |
| 831 |
} |
| 832 |
|
| 833 |
return false; |
| 834 |
} |
| 835 |
|
| 836 |
|
| 837 |
/** |
| 838 |
* Get the recommended plugins. |
| 839 |
* |
| 840 |
* @since 1.8.1 |
| 841 |
* @version 1.8.8 |
| 842 |
* |
| 843 |
* @param boolean $return_json Whether to return the plugins as JSON or an array. |
| 844 |
* |
| 845 |
* @return array |
| 846 |
*/ |
| 847 |
public function get_plugins( $return_json = true ) { |
| 848 |
|
| 849 |
if ( ! function_exists( 'get_plugins' ) ) { |
| 850 |
require_once ABSPATH . 'wp-admin/includes/plugin.php'; |
| 851 |
} |
| 852 |
|
| 853 |
$includes_path = charitable()->get_path( 'includes' ); |
| 854 |
require_once $includes_path . 'utilities/charitable-utility-functions.php'; |
| 855 |
|
| 856 |
$installed_plugins = get_plugins(); |
| 857 |
|
| 858 |
$plugins = array(); |
| 859 |
|
| 860 |
// Monsterinsights. |
| 861 |
$plugins['monsterinsights'] = array( |
| 862 |
'active' => function_exists( 'monsterinsights' ), |
| 863 |
'icon' => charitable()->get_path( 'directory', false ) . 'assets/images/plugins/third-party/mi.png', |
| 864 |
'title' => 'MonsterInsights', |
| 865 |
'excerpt' => __( 'The leading WordPress analytics plugin that shows you how people find and use your website, so you can make data driven decisions to grow your business. Properly set up Google Analytics without writing code.', 'charitable' ), |
| 866 |
'why' => __( 'Analytics plugins can help you determine how people are finding your campaigns, and which of your public campaigns are getting viewed the most.', 'charitable' ), |
| 867 |
'what' => __( 'an analytics plugin', 'charitable' ), |
| 868 |
'installed' => array_key_exists( 'google-analytics-for-wordpress/googleanalytics.php', $installed_plugins ) || array_key_exists( 'google-analytics-premium/googleanalytics-premium.php', $installed_plugins ), |
| 869 |
'basename' => 'google-analytics-for-wordpress/googleanalytics.php', |
| 870 |
'slug' => 'google-analytics-for-wordpress', |
| 871 |
'settings' => admin_url( 'admin.php?page=monsterinsights-settings' ), |
| 872 |
'setup' => admin_url( 'index.php?page=monsterinsights-onboarding' ), |
| 873 |
'id' => 'mi', |
| 874 |
'gt_section' => 'traffic', |
| 875 |
); |
| 876 |
|
| 877 |
// WPForms. |
| 878 |
$plugins['wpforms-lite'] = array( |
| 879 |
'active' => function_exists( 'wpforms' ), |
| 880 |
'icon' => charitable()->get_path( 'directory', false ) . 'assets/images/plugins/third-party/wpforms.png', |
| 881 |
'title' => 'WPForms', |
| 882 |
'excerpt' => __( 'The best drag & drop WordPress form builder. Easily create beautiful contact forms, surveys, payment forms, and more with our 1000+ form templates. Trusted by over 6 million websites as the best forms plugin.', 'charitable' ), |
| 883 |
'why' => __( 'Form plugins can help you get real feedback such as campaign recommendations or ideas for different payment options.', 'charitable' ), |
| 884 |
'what' => __( 'a form plugin', 'charitable' ), |
| 885 |
'installed' => array_key_exists( 'wpforms-lite/wpforms.php', $installed_plugins ), |
| 886 |
'basename' => 'wpforms-lite/wpforms.php', |
| 887 |
'slug' => 'wpforms-lite', |
| 888 |
'settings' => admin_url( 'admin.php?page=wpforms-settings' ), |
| 889 |
'setup' => admin_url( 'admin.php?page=wpforms-settings' ), |
| 890 |
'id' => 'wpforms', |
| 891 |
'gt_section' => 'engagement', |
| 892 |
); |
| 893 |
|
| 894 |
// AIOSEO. |
| 895 |
$plugins['aioseo'] = array( |
| 896 |
'active' => function_exists( 'aioseo' ), |
| 897 |
'icon' => charitable()->get_path( 'directory', false ) . 'assets/images/plugins/third-party/all-in-one-seo.png', |
| 898 |
'title' => 'AIOSEO', |
| 899 |
'excerpt' => __( 'The original WordPress SEO plugin and toolkit that improves your website’s search rankings. Comes with all the SEO features like Local SEO, WooCommerce SEO, sitemaps, SEO optimizer, schema, and more.', 'charitable' ), |
| 900 |
'why' => __( 'Using an SEO plugin helps you make sure your campaigns and causes are findable on the web.', 'charitable' ), |
| 901 |
'what' => __( 'an SEO plugin', 'charitable' ), |
| 902 |
'installed' => array_key_exists( 'all-in-one-seo-pack/all_in_one_seo_pack.php', $installed_plugins ), |
| 903 |
'basename' => ( charitable_is_installed_aioseo_pro() ) ? 'all-in-one-seo-pack-pro/all_in_one_seo_pack.php' : 'all-in-one-seo-pack/all_in_one_seo_pack.php', |
| 904 |
'slug' => 'all-in-one-seo-pack', |
| 905 |
'settings' => admin_url( 'admin.php?page=aioseo' ), |
| 906 |
'setup' => admin_url( 'admin.php?page=aioseo' ), |
| 907 |
'id' => 'aioseo', |
| 908 |
'gt_section' => 'traffic', |
| 909 |
); |
| 910 |
|
| 911 |
// OptinMonster. |
| 912 |
$plugins['optinmonster'] = array( |
| 913 |
'active' => class_exists( 'OMAPI' ), |
| 914 |
'icon' => charitable()->get_path( 'directory', false ) . 'assets/images/plugins/third-party/om.png', |
| 915 |
'title' => 'OptinMonster', |
| 916 |
'excerpt' => __( 'Instantly get more subscribers, leads, and sales with the #1 conversion optimization toolkit. Create high converting popups, announcement bars, spin a wheel, and more with smart targeting and personalization.', 'charitable' ), |
| 917 |
'why' => __( 'Marketing plugins that offer exit-intent technology, page targeting, and A/B testing can help you keep potential donors on your site.', 'charitable' ), |
| 918 |
'what' => __( 'particular marketing plugins', 'charitable' ), |
| 919 |
'installed' => array_key_exists( 'optinmonster/optin-monster-wp-api.php', $installed_plugins ), |
| 920 |
'basename' => 'optinmonster/optin-monster-wp-api.php', |
| 921 |
'slug' => 'optinmonster', |
| 922 |
'settings' => admin_url( 'admin.php?page=optin-monster-dashboard' ), |
| 923 |
'setup' => admin_url( 'admin.php?page=optin-monster-dashboard' ), |
| 924 |
'id' => 'optinmonster', |
| 925 |
'gt_section' => 'engagement', |
| 926 |
); |
| 927 |
|
| 928 |
// RafflePress. |
| 929 |
$plugins['rafflepress'] = array( |
| 930 |
'active' => defined( 'RAFFLEPRESS_VERSION' ), |
| 931 |
'icon' => charitable()->get_path( 'directory', false ) . 'assets/images/plugins/third-party/rafflepress.png', |
| 932 |
'title' => 'RafflePress', |
| 933 |
'excerpt' => __( 'Turn your website visitors into brand ambassadors! Easily grow your email list, website traffic, and social media followers with the most powerful giveaways & contests plugin for WordPress.', 'charitable' ), |
| 934 |
'why' => __( 'Offering giveaways and contests can help strengthen your overall cause and particular campaigns.', 'charitable' ), |
| 935 |
'what' => __( 'particular marketing plugins', 'charitable' ), |
| 936 |
'installed' => array_key_exists( 'rafflepress/rafflepress.php', $installed_plugins ), |
| 937 |
'basename' => 'rafflepress/rafflepress.php', |
| 938 |
'slug' => 'rafflepress', |
| 939 |
'settings' => admin_url( 'admin.php?page=rafflepress_lite' ), |
| 940 |
'setup' => admin_url( 'admin.php?page=rafflepress_lite' ), |
| 941 |
'id' => 'rafflepress', |
| 942 |
'gt_section' => 'traffic', |
| 943 |
); |
| 944 |
|
| 945 |
// SeedProd. |
| 946 |
$plugins['coming-soon'] = array( |
| 947 |
'active' => defined( 'SEEDPROD_VERSION' ), |
| 948 |
'icon' => charitable()->get_path( 'directory', false ) . 'assets/images/plugins/third-party/seedprod.png', |
| 949 |
'title' => 'SeedProd', |
| 950 |
'excerpt' => __( 'Use the best drag-and-drop landing page builder for WordPress to instantly build coming soon pages, sales pages, opt-in pages, webinar pages, maintenance pages, and more. Includes 100+ free templates.', 'charitable' ), |
| 951 |
'why' => __( 'Build landing pages for your general causes while showcasing testimonials form donors and campaign benefactors.', 'charitable' ), |
| 952 |
'what' => __( 'a page builder plugin', 'charitable' ), |
| 953 |
'installed' => array_key_exists( 'coming-soon/coming-soon.php', $installed_plugins ), |
| 954 |
'basename' => 'coming-soon/coming-soon.php', |
| 955 |
'slug' => 'coming-soon', |
| 956 |
'settings' => admin_url( 'admin.php?page=seedprod_lite' ), |
| 957 |
'setup' => admin_url( 'admin.php?page=seedprod_lite' ), |
| 958 |
'id' => 'seedprod', |
| 959 |
'gt_section' => 'revenue', |
| 960 |
); |
| 961 |
|
| 962 |
// WP Mail Smtp. |
| 963 |
$plugins['wp-mail-smtp'] = array( |
| 964 |
'active' => function_exists( 'wp_mail_smtp' ), |
| 965 |
'icon' => charitable()->get_path( 'directory', false ) . 'assets/images/plugins/third-party/smtp.png', |
| 966 |
'title' => 'WP Mail SMTP', |
| 967 |
'excerpt' => __( 'Improve your WordPress email deliverability and make sure that your website emails reach user’s inbox with the #1 SMTP plugin for WordPress. Over 3 million websites use it to fix WordPress email issues.', 'charitable' ), |
| 968 |
'why' => __( 'Sending reliable emails to donors after they have donated is vital, along with making sure admins get email notifications setup in Charitable.', 'charitable' ), |
| 969 |
'what' => __( 'a SMTP / email plugin', 'charitable' ), |
| 970 |
'installed' => array_key_exists( 'wp-mail-smtp/wp_mail_smtp.php', $installed_plugins ), |
| 971 |
'basename' => 'wp-mail-smtp/wp_mail_smtp.php', |
| 972 |
'slug' => 'wp-mail-smtp', |
| 973 |
'settings' => admin_url( 'admin.php?page=wp-mail-smtp' ), |
| 974 |
'setup' => admin_url( 'admin.php?page=wp-mail-smtp' ), |
| 975 |
'id' => 'wpmailsmtp', |
| 976 |
'gt_section' => 'engagement', |
| 977 |
); |
| 978 |
|
| 979 |
// EDD. |
| 980 |
$plugins['easy-digital-downloads'] = array( |
| 981 |
'active' => class_exists( 'Easy_Digital_Downloads' ), |
| 982 |
'icon' => charitable()->get_path( 'directory', false ) . 'assets/images/plugins/third-party/edd.png', |
| 983 |
'title' => 'Easy Digital Downloads', |
| 984 |
'excerpt' => __( 'The best WordPress eCommerce plugin for selling digital downloads. Start selling eBooks, software, music, digital art, and more within minutes. Accept payments, manage subscriptions, advanced access control, and more.', 'charitable' ), |
| 985 |
'installed' => array_key_exists( 'easy-digital-downloads/easy-digital-downloads.php', $installed_plugins ), |
| 986 |
'basename' => 'easy-digital-downloads/easy-digital-downloads.php', |
| 987 |
'slug' => 'easy-digital-downloads', |
| 988 |
'setup' => admin_url( 'edit.php?post_type=download&page=edd-settings' ), |
| 989 |
'settings' => admin_url( 'edit.php?post_type=download&page=edd-settings' ), |
| 990 |
'id' => 'edd', |
| 991 |
'gt_section' => 'revenue', |
| 992 |
); |
| 993 |
|
| 994 |
// PrettyLinks. |
| 995 |
$plugins['pretty-link'] = array( |
| 996 |
'active' => function_exists( 'prli_plugin_info' ), |
| 997 |
'icon' => false, |
| 998 |
'title' => 'Pretty Links', |
| 999 |
'excerpt' => __( 'Automatically monetize your website content with affiliate links added automatically to your content.', 'charitable' ), |
| 1000 |
'installed' => array_key_exists( 'pretty-link/pretty-link.php', $installed_plugins ), |
| 1001 |
'basename' => 'pretty-link/pretty-link.php', |
| 1002 |
'slug' => 'pretty-link', |
| 1003 |
'setup' => admin_url( 'edit.php?post_type=pretty-link' ), |
| 1004 |
'settomgs' => admin_url( 'edit.php?post_type=pretty-link' ), |
| 1005 |
'id' => 'prettylinks', |
| 1006 |
'gt_section' => 'revenue', |
| 1007 |
); |
| 1008 |
|
| 1009 |
// Smash Balloon (Instagram). |
| 1010 |
$plugins['smash-balloon-instagram'] = array( |
| 1011 |
'active' => defined( 'SBIVER' ), |
| 1012 |
'icon' => charitable()->get_path( 'directory', false ) . 'assets/images/plugins/third-party/sb-instagram.png', |
| 1013 |
'title' => 'Smash Balloon Instagram Feeds', |
| 1014 |
'excerpt' => __( 'Easily display Instagram content on your WordPress site without writing any code. Comes with multiple templates, ability to show content from multiple accounts, hashtags, and more. Trusted by 1 million websites.', 'charitable' ), |
| 1015 |
'installed' => array_key_exists( 'instagram-feed/instagram-feed.php', $installed_plugins ), |
| 1016 |
'basename' => 'instagram-feed/instagram-feed.php', |
| 1017 |
'slug' => 'instagram-feed', |
| 1018 |
'setup' => admin_url( 'admin.php?page=sbi-settings' ), |
| 1019 |
'settings' => admin_url( 'admin.php?page=sbi-settings' ), |
| 1020 |
'id' => 'smashballoon', |
| 1021 |
'gt_section' => 'engagement', |
| 1022 |
); |
| 1023 |
|
| 1024 |
// Smash Balloon (Facebook). |
| 1025 |
$plugins['smash-balloon-facebook'] = array( |
| 1026 |
'active' => defined( 'CFFVER' ), |
| 1027 |
'icon' => charitable()->get_path( 'directory', false ) . 'assets/images/plugins/third-party/sb-facebook.png', |
| 1028 |
'title' => 'Smash Balloon Facebook Feeds', |
| 1029 |
'excerpt' => __( 'Easily display Facebook content on your WordPress site without writing any code. Comes with multiple templates, ability to embed albums, group content, reviews, live videos, comments, and reactions.', 'charitable' ), |
| 1030 |
'installed' => array_key_exists( 'custom-facebook-feed/custom-facebook-feed.php', $installed_plugins ), |
| 1031 |
'basename' => 'custom-facebook-feed/custom-facebook-feed.php', |
| 1032 |
'slug' => 'custom-facebook-feed', |
| 1033 |
'setup' => admin_url( 'admin.php?page=cff-setup' ), |
| 1034 |
'settings' => admin_url( 'admin.php?page=cff-setup' ), |
| 1035 |
'id' => 'smashballoon', |
| 1036 |
'gt_section' => 'engagement', |
| 1037 |
); |
| 1038 |
|
| 1039 |
// Smash Balloon (YouTube). |
| 1040 |
$plugins['smash-balloon-youtube'] = array( |
| 1041 |
'active' => defined( 'SBYVER' ), |
| 1042 |
'icon' => charitable()->get_path( 'directory', false ) . 'assets/images/plugins/third-party/sb-youtube.png', |
| 1043 |
'title' => 'Smash Balloon YouTube Feeds', |
| 1044 |
'excerpt' => __( 'Easily display YouTube videos on your WordPress site without writing any code. Comes with multiple layouts, ability to embed live streams, video filtering, ability to combine multiple channel videos, and more.', 'charitable' ), |
| 1045 |
'installed' => array_key_exists( 'feeds-for-youtube/youtube-feed.php', $installed_plugins ), |
| 1046 |
'basename' => 'feeds-for-youtube/youtube-feed.php', |
| 1047 |
'slug' => 'feeds-for-youtube', |
| 1048 |
'setup' => admin_url( 'admin.php?page=sby-feed-builder' ), |
| 1049 |
'settings' => admin_url( 'admin.php?page=sby-feed-builder' ), |
| 1050 |
); |
| 1051 |
|
| 1052 |
// Smash Balloon (Twitter). |
| 1053 |
$plugins['smash-balloon-twitter'] = array( |
| 1054 |
'active' => defined( 'CTF_VERSION' ), |
| 1055 |
'icon' => charitable()->get_path( 'directory', false ) . 'assets/images/plugins/third-party/sb-twitter.png', |
| 1056 |
'title' => 'Smash Balloon Twitter Feeds', |
| 1057 |
'excerpt' => __( 'Easily display Twitter content in WordPress without writing any code. Comes with multiple layouts, ability to combine multiple Twitter feeds, Twitter card support, tweet moderation, and more.', 'charitable' ), |
| 1058 |
'installed' => array_key_exists( 'custom-twitter-feeds/custom-twitter-feed.php', $installed_plugins ), |
| 1059 |
'basename' => 'custom-twitter-feeds/custom-twitter-feed.php', |
| 1060 |
'slug' => 'custom-twitter-feeds', |
| 1061 |
'setup' => admin_url( 'admin.php?page=ctf-feed-builder' ), |
| 1062 |
'settings' => admin_url( 'admin.php?page=ctf-feed-builder' ), |
| 1063 |
); |
| 1064 |
|
| 1065 |
// TrustPulse. |
| 1066 |
$plugins['trustpulse'] = array( |
| 1067 |
'active' => defined( 'TRUSTPULSE_PLUGIN_VERSION' ), |
| 1068 |
'icon' => charitable()->get_path( 'directory', false ) . 'assets/images/plugins/third-party/trustpulse.png', |
| 1069 |
'title' => 'TrustPulse', |
| 1070 |
'excerpt' => __( 'Boost your sales and conversions by up to 15% with real-time social proof notifications. TrustPulse helps you show live user activity and purchases to help convince other users to purchase.', 'charitable' ), |
| 1071 |
'installed' => array_key_exists( 'trustpulse-api/trustpulse.php', $installed_plugins ), |
| 1072 |
'basename' => 'trustpulse-api/trustpulse.php', |
| 1073 |
'slug' => 'trustpulse-api', |
| 1074 |
'setup' => admin_url( 'admin.php?page=trustpulse' ), |
| 1075 |
'settings' => admin_url( 'admin.php?page=trustpulse' ), |
| 1076 |
); |
| 1077 |
|
| 1078 |
// SearchWP. |
| 1079 |
$plugins['searchwp'] = array( |
| 1080 |
'active' => defined( 'SEARCHWP_LIVE_SEARCH_VERSION' ), |
| 1081 |
'icon' => false, |
| 1082 |
'title' => 'SearchWP', |
| 1083 |
'excerpt' => __( 'The most advanced WordPress search plugin. Customize your WordPress search algorithm, reorder search results, track search metrics, and everything you need to leverage search to grow your business.', 'charitable' ), |
| 1084 |
'why' => __( 'Unlock better search results for your website. Perfect for any information or eCommerce store to help users find exactly what content and products they’re looking for.', 'charitable' ), |
| 1085 |
'what' => __( 'a search plugin', 'charitable' ), |
| 1086 |
'installed' => false, |
| 1087 |
'basename' => false, |
| 1088 |
'slug' => 'searchwp-live-ajax-search', |
| 1089 |
'settings' => admin_url( 'admin.php?page=searchwp-live-search' ), |
| 1090 |
'id' => 'searchwp', |
| 1091 |
'gt_section' => 'revenue', |
| 1092 |
'gt_learn' => 'https://www.wpcharitable.com/refer/searchwp?utm_source=charitableplugin&utm_medium=link&utm_campaign=CharitableGrowthTools&utm_content=' . charitable()->get_version(), |
| 1093 |
|
| 1094 |
); |
| 1095 |
|
| 1096 |
// AffiliateWP. |
| 1097 |
$plugins['affiliatewp'] = array( |
| 1098 |
'active' => class_exists( 'AffiliateWP_Requirements_Check' ), |
| 1099 |
'icon' => charitable()->get_path( 'directory', false ) . 'assets/images/plugins/third-party/affiliate-wp.png', |
| 1100 |
'title' => 'AffiliateWP', |
| 1101 |
'excerpt' => __( 'The #1 affiliate management plugin for WordPress. Easily create an affiliate program for your eCommerce store or membership site within minutes and start growing your sales with the power of referral marketing.', 'charitable' ), |
| 1102 |
'installed' => array_key_exists( 'affiliate-wp/affiliate-wp.php', $installed_plugins ), |
| 1103 |
'basename' => 'affiliate-wp/affiliate-wp.php', |
| 1104 |
'slug' => 'affiliate-wp', |
| 1105 |
'setup' => admin_url(), |
| 1106 |
'settings' => admin_url(), |
| 1107 |
'redirect' => 'https://affiliatewp.com', |
| 1108 |
); |
| 1109 |
|
| 1110 |
// WP Simple Pay. |
| 1111 |
$plugins['wpsimplepay'] = array( |
| 1112 |
'active' => defined( 'SIMPLE_PAY_VERSION' ), |
| 1113 |
'icon' => charitable()->get_path( 'directory', false ) . 'assets/images/plugins/third-party/wp-simple-pay.png', |
| 1114 |
'title' => 'WP Simple Pay', |
| 1115 |
'excerpt' => __( 'The #1 Stripe payments plugin for WordPress. Start accepting one-time and recurring payments on your WordPress site without setting up a shopping cart. No code required.', 'charitable' ), |
| 1116 |
'installed' => array_key_exists( 'stripe/stripe-checkout.php', $installed_plugins ), |
| 1117 |
'basename' => 'stripe/stripe-checkout.php', |
| 1118 |
'slug' => 'stripe', |
| 1119 |
'setup' => admin_url( 'edit.php?post_type=simple-pay&page=simpay_settings' ), |
| 1120 |
'settings' => admin_url( 'edit.php?post_type=simple-pay&page=simpay_settings' ), |
| 1121 |
); |
| 1122 |
|
| 1123 |
// Sugar Calendar. |
| 1124 |
$plugins['sugarcalendar'] = array( |
| 1125 |
'active' => class_exists( 'Sugar_Calendar\\Requirements_Check' ), |
| 1126 |
'icon' => charitable()->get_path( 'directory', false ) . 'assets/images/plugins/third-party/sugar-calendar.png', |
| 1127 |
'title' => 'Sugar Calendar', |
| 1128 |
'excerpt' => __( 'A simple & powerful event calendar plugin for WordPress that comes with all the event management features including payments, scheduling, timezones, ticketing, recurring events, and more.', 'charitable' ), |
| 1129 |
'installed' => array_key_exists( 'sugar-calendar-lite/sugar-calendar-lite.php', $installed_plugins ), |
| 1130 |
'basename' => 'sugar-calendar-lite/sugar-calendar-lite.php', |
| 1131 |
'slug' => 'sugar-calendar-lite', |
| 1132 |
'settings' => admin_url( 'admin.php?page=sugar-calendar' ), |
| 1133 |
); |
| 1134 |
|
| 1135 |
// WPCode. |
| 1136 |
$plugins['wpcode'] = array( |
| 1137 |
'active' => function_exists( 'WPCode' ), |
| 1138 |
'icon' => charitable()->get_path( 'directory', false ) . 'assets/images/plugins/third-party/wpcode.png', |
| 1139 |
'title' => 'WPCode', |
| 1140 |
'excerpt' => __( 'Future proof your WordPress customizations with the most popular code snippet management plugin for WordPress. Trusted by over 1,500,000+ websites for easily adding code to WordPress right from the admin area.', 'charitable' ), |
| 1141 |
'installed' => array_key_exists( 'insert-headers-and-footers/ihaf.php', $installed_plugins ), |
| 1142 |
'basename' => 'insert-headers-and-footers/ihaf.php', |
| 1143 |
'slug' => 'insert-headers-and-footers', |
| 1144 |
'settings' => admin_url( 'admin.php?page=wpcode-settings' ), |
| 1145 |
'setup' => admin_url( 'admin.php?page=wpcode-settings' ), |
| 1146 |
); |
| 1147 |
|
| 1148 |
// Duplicator. |
| 1149 |
$plugins['duplicator'] = array( |
| 1150 |
'active' => defined( 'DUPLICATOR_VERSION' ), |
| 1151 |
'icon' => charitable()->get_path( 'directory', false ) . 'assets/images/plugins/third-party/duplicator.png', |
| 1152 |
'title' => 'Duplicator', |
| 1153 |
'excerpt' => __( 'Leading WordPress backup & site migration plugin. Over 1,500,000+ smart website owners use Duplicator to make reliable and secure WordPress backups to protect their websites. It also makes website migration really easy.', 'charitable' ), |
| 1154 |
'installed' => array_key_exists( 'duplicator/duplicator.php', $installed_plugins ), |
| 1155 |
'basename' => 'duplicator/duplicator.php', |
| 1156 |
'slug' => 'duplicator', |
| 1157 |
'settings' => admin_url( 'admin.php?page=duplicator-settings' ), |
| 1158 |
); |
| 1159 |
|
| 1160 |
// PushEngage. |
| 1161 |
$plugins['pushengage'] = array( |
| 1162 |
'active' => defined( 'PUSHENGAGE_VERSION' ), |
| 1163 |
'icon' => charitable()->get_path( 'directory', false ) . 'assets/images/plugins/third-party/pushengage.png', |
| 1164 |
'title' => 'PushEngage', |
| 1165 |
'excerpt' => __( 'Connect with your visitors after they leave your website with the leading web push notification software. Over 10,000+ businesses worldwide use PushEngage to send 15 billion notifications each month.', 'charitable' ), |
| 1166 |
'why' => __( 'Use push notifications to notify donors or potential donors that a campaign is about to end, or that a campaign has not reached it\'s goal yet.', 'charitable' ), |
| 1167 |
'what' => __( 'particular marketing plugins', 'charitable' ), |
| 1168 |
'installed' => array_key_exists( 'pushengage/main.php', $installed_plugins ), |
| 1169 |
'basename' => 'pushengage/main.php', |
| 1170 |
'slug' => 'pushengage', |
| 1171 |
'setup' => admin_url( 'admin.php?page=pushengage#/settings/site-details' ), |
| 1172 |
'settings' => admin_url( 'admin.php?page=pushengage#/settings/site-details' ), |
| 1173 |
'id' => 'pushengage', |
| 1174 |
'gt_section' => 'traffic', |
| 1175 |
); |
| 1176 |
|
| 1177 |
// Uncanny Automator. |
| 1178 |
$plugins['uncanny-automator'] = array( |
| 1179 |
'active' => function_exists( 'automator_get_recipe_id' ), |
| 1180 |
'icon' => charitable()->get_path( 'directory', false ) . 'assets/images/plugins/third-party/uncanny-automator.png', |
| 1181 |
'title' => 'Uncanny Automator', |
| 1182 |
'excerpt' => __( 'Automate everything with the #1 no-code Automation tool for WordPress. Use data from donors, donation submissions, activities and anything else in your campaign.', 'charitable' ), |
| 1183 |
'installed' => array_key_exists( 'uncanny-automator/uncanny-automator.php', $installed_plugins ), |
| 1184 |
'basename' => 'uncanny-automator/uncanny-automator.php', |
| 1185 |
'slug' => 'uncanny-automator', |
| 1186 |
'setup_complete' => (bool) get_option( 'automator_reporting', false ), |
| 1187 |
'setup' => admin_url( 'edit.php?post_type=uo-recipe&page=uncanny-automator-setup-wizard' ), |
| 1188 |
'settings' => admin_url( 'edit.php?post_type=uo-recipe&page=uncanny-automator-setup-wizard' ), |
| 1189 |
'id' => 'uncanny-automator', |
| 1190 |
'gt_section' => 'engagement', |
| 1191 |
); |
| 1192 |
|
| 1193 |
// Envira Gallery. |
| 1194 |
$plugins['envira-gallery'] = array( |
| 1195 |
'active' => class_exists( 'Envira_Gallery_Lite' ), |
| 1196 |
'icon' => charitable()->get_path( 'directory', false ) . 'assets/images/plugins/third-party/envira-gallery.png', |
| 1197 |
'title' => 'Envira Gallery Lite', |
| 1198 |
'excerpt' => __( 'Add a photo gallery to your campaign pages with this fast and powerful gallery plugin.', 'charitable' ), |
| 1199 |
'why' => __( 'Showing photos in an attractive gallery will add more credentiality to your campaigns.', 'charitable' ), |
| 1200 |
'installed' => array_key_exists( 'envira-gallery-lite/envira-gallery-lite.php', $installed_plugins ), |
| 1201 |
'basename' => 'envira-gallery-lite/envira-gallery-lite.php', |
| 1202 |
'slug' => 'envira-gallery-lite', |
| 1203 |
'setup' => admin_url( 'edit.php?post_type=envira&page=envira-gallery-lite-get-started' ), |
| 1204 |
'id' => 'envira', |
| 1205 |
'gt_section' => 'engagement', |
| 1206 |
); |
| 1207 |
|
| 1208 |
// Constant Contact. |
| 1209 |
$plugins['constant-contact'] = array( |
| 1210 |
'active' => class_exists( 'ConstantContact' ), // todo: update. |
| 1211 |
'icon' => charitable()->get_path( 'directory', false ) . 'assets/images/plugins/third-party/constant-contact.png', |
| 1212 |
'title' => 'Constant Contact', |
| 1213 |
'excerpt' => __( 'Create amazing email marketing campaigns with drag and drop simplicity. <span>Exclusive Offer: Save 20%.</span>', 'charitable' ), |
| 1214 |
'why' => false, |
| 1215 |
'slug' => 'constantcontact', |
| 1216 |
'setup' => false, |
| 1217 |
'id' => 'constantcontact', |
| 1218 |
'gt_section' => 'traffic', |
| 1219 |
'gt_learn' => 'https://www.wpcharitable.com/refer/constant-contact/?utm_source=charitableplugin&utm_medium=link&utm_campaign=CharitableGrowthTools&utm_content=' . charitable()->get_version(), |
| 1220 |
); |
| 1221 |
|
| 1222 |
// SEMRUSH. |
| 1223 |
$plugins['semrush'] = array( |
| 1224 |
'active' => class_exists( 'SEMRUSH' ), // todo: update. |
| 1225 |
'icon' => false, |
| 1226 |
'title' => 'SEMRUSH', |
| 1227 |
'excerpt' => __( 'Perform SEO and content marketing research, track keywords, and much more. <span>Special Offer: First 14 Days Free.</span>', 'charitable' ), |
| 1228 |
'why' => false, |
| 1229 |
'slug' => 'semrush', |
| 1230 |
'setup' => false, |
| 1231 |
'id' => 'semrush', |
| 1232 |
'gt_section' => 'traffic', |
| 1233 |
'gt_learn' => 'https://www.wpcharitable.com/refer/semrush?utm_source=charitableplugin&utm_medium=link&utm_campaign=CharitableGrowthTools&utm_content=' . charitable()->get_version(), |
| 1234 |
); |
| 1235 |
|
| 1236 |
// MemberPress. |
| 1237 |
$plugins['memberpress'] = array( |
| 1238 |
'active' => false, |
| 1239 |
'icon' => false, |
| 1240 |
'title' => 'MemberPress', |
| 1241 |
'excerpt' => __( 'Create a membership website.', 'charitable' ), |
| 1242 |
'installed' => false, |
| 1243 |
'basename' => false, |
| 1244 |
'why' => __( 'Creating a community can help boost returning donations. You can offer exclusive content and discussion, especially for donors or campaign creators.', 'charitable' ), |
| 1245 |
'what' => __( 'a membership plugin', 'charitable' ), |
| 1246 |
'slug' => 'memberpress', |
| 1247 |
'setup' => false, |
| 1248 |
'id' => 'memberpress', |
| 1249 |
'gt_section' => 'revenue', |
| 1250 |
'gt_learn' => 'https://www.wpcharitable.com/refer/memberpress/?utm_source=charitableplugin&utm_medium=link&utm_campaign=CharitableGrowthTools&utm_content=' . charitable()->get_version(), |
| 1251 |
); |
| 1252 |
|
| 1253 |
// Easy Affiliate. |
| 1254 |
$plugins['easy-affiliate'] = array( |
| 1255 |
'active' => false, |
| 1256 |
'icon' => false, |
| 1257 |
'title' => 'Easy Affiliate', |
| 1258 |
'excerpt' => __( 'Launch, grow, and manage an affiliate program, all right from your WordPress dashboard.', 'charitable' ), |
| 1259 |
'installed' => false, |
| 1260 |
'basename' => false, |
| 1261 |
'slug' => 'easy-affiliate', |
| 1262 |
'setup' => false, |
| 1263 |
'id' => 'easyaffiliate', |
| 1264 |
'gt_section' => 'revenue', |
| 1265 |
'gt_learn' => 'https://www.wpcharitable.com/refer/easy-affiliate/?utm_source=charitableplugin&utm_medium=link&utm_campaign=CharitableGrowthTools&utm_content=' . charitable()->get_version(), |
| 1266 |
); |
| 1267 |
|
| 1268 |
// Formidable Forms. |
| 1269 |
$plugins['formidable'] = array( |
| 1270 |
'active' => function_exists( 'load_formidable_forms' ), |
| 1271 |
'icon' => false, |
| 1272 |
'title' => 'Formidable Forms', |
| 1273 |
'excerpt' => __( 'Formidable Forms is the best WordPress forms plugin. Over 300,000 professionals use our WordPress form builder to create contact forms, surveys, calculators, and other WP forms.', 'charitable' ), |
| 1274 |
'why' => __( 'Form plugins can help you get real feedback such as campaign recommendations or ideas for different payment options.', 'charitable' ), |
| 1275 |
'what' => __( 'a form plugin', 'charitable' ), |
| 1276 |
'installed' => array_key_exists( 'formidable/formidable.php', $installed_plugins ), |
| 1277 |
'basename' => 'formidable/formidable.php', |
| 1278 |
'slug' => 'formidable', |
| 1279 |
'settings' => admin_url( 'admin.php?page=formidable-dashboard' ), |
| 1280 |
'setup' => admin_url( 'admin.php?page=formidable-dashboard' ), |
| 1281 |
'id' => 'formidableforms', |
| 1282 |
'gt_section' => 'engagement', |
| 1283 |
); |
| 1284 |
|
| 1285 |
// WPConsent. |
| 1286 |
$plugins['wpconsent'] = array( |
| 1287 |
'active' => function_exists( 'wpconsent' ), |
| 1288 |
'icon' => false, |
| 1289 |
'title' => 'WPConsent', |
| 1290 |
'excerpt' => __( 'WPConsent is the best privacy compliance plugin for WordPress. It helps you comply with GDPR, CCPA, and other privacy regulations.', 'charitable' ), |
| 1291 |
'why' => __( 'Privacy compliance plugins can help you comply with GDPR, CCPA, and other privacy regulations.', 'charitable' ), |
| 1292 |
'what' => __( 'a privacy compliance plugin', 'charitable' ), |
| 1293 |
'installed' => array_key_exists( 'wpconsent-cookies-banner-privacy-suite/wpconsent.php', $installed_plugins ), |
| 1294 |
'basename' => 'wpconsent-cookies-banner-privacy-suite/wpconsent.php', |
| 1295 |
'slug' => 'wpconsent-cookies-banner-privacy-suite', |
| 1296 |
'settings' => admin_url( 'admin.php?page=wpconsent-cookies' ), |
| 1297 |
'setup' => admin_url( 'admin.php?page=wpconsent-cookies' ), |
| 1298 |
'id' => 'wpconsent', |
| 1299 |
'gt_section' => 'privacy', |
| 1300 |
'gt_learn' => 'https://wordpress.org/plugins/wpconsent-cookies-banner-privacy-suite/', |
| 1301 |
); |
| 1302 |
|
| 1303 |
$plugins['guide-coming-soon'] = array( |
| 1304 |
'title' => __( 'Dedicated guides and resources will be coming soon.', 'charitable' ), |
| 1305 |
'id' => 'guide', |
| 1306 |
'gt_section' => 'guides', |
| 1307 |
'coming_soon' => true, |
| 1308 |
); |
| 1309 |
|
| 1310 |
if ( $return_json ) { |
| 1311 |
wp_send_json( $plugins ); |
| 1312 |
} else { |
| 1313 |
return $plugins; |
| 1314 |
} |
| 1315 |
} |
| 1316 |
|
| 1317 |
/** |
| 1318 |
* Get the recommended plugins. |
| 1319 |
* |
| 1320 |
* @since 1.8.1 |
| 1321 |
* |
| 1322 |
* @param string $recommendation_type The type of recommendation to get. |
| 1323 |
* @param int $limit The number of recommendations to get. |
| 1324 |
* |
| 1325 |
* @return array |
| 1326 |
*/ |
| 1327 |
public function get_recommendations( $recommendation_type = 'campaign', $limit = 3 ) { |
| 1328 |
|
| 1329 |
$recommended_addons = $this->get_recommended_addons( $recommendation_type, $limit ); |
| 1330 |
$recommended_partners = $this->get_recommended_partners( $recommendation_type, $limit ); |
| 1331 |
|
| 1332 |
// merge the two arrays. |
| 1333 |
$recommended = array_merge( $recommended_addons, $recommended_partners ); |
| 1334 |
|
| 1335 |
if ( count( $recommended_addons ) + count( $recommended_partners ) > $limit ) { |
| 1336 |
$recommended = array_merge( $recommended_addons, $recommended_partners ); |
| 1337 |
|
| 1338 |
if ( ! empty( $recommended ) ) { |
| 1339 |
// randomly remove elements from the array until the total count of the array equals the limit. |
| 1340 |
$recommended_count = count( $recommended ); |
| 1341 |
while ( $recommended_count > $limit ) { |
| 1342 |
$random_key = array_rand( $recommended ); |
| 1343 |
unset( $recommended[ $random_key ] ); |
| 1344 |
$recommended_count = count( $recommended ); |
| 1345 |
} |
| 1346 |
} |
| 1347 |
} |
| 1348 |
|
| 1349 |
return $recommended; |
| 1350 |
} |
| 1351 |
|
| 1352 |
|
| 1353 |
/** |
| 1354 |
* Get the recommended partners / third party items. |
| 1355 |
* |
| 1356 |
* @since 1.8.1.5 |
| 1357 |
* |
| 1358 |
* @param string $recommendation_type The type of recommendation to get. |
| 1359 |
* @param int $limit The number of recommendations to get. |
| 1360 |
* |
| 1361 |
* @return array |
| 1362 |
*/ |
| 1363 |
public function get_recommended_partners( $recommendation_type = 'campaign', $limit = 3 ) { |
| 1364 |
/* |
| 1365 |
Recommend at least one Charitable addon. |
| 1366 |
|
| 1367 |
Rules: |
| 1368 |
- Must be on the list of preferred partners. |
| 1369 |
- Must not be installed. |
| 1370 |
- Must not be dismissed. |
| 1371 |
|
| 1372 |
*/ |
| 1373 |
|
| 1374 |
$partner_list = $this->get_plugins( false ); |
| 1375 |
|
| 1376 |
$preferred_partners = apply_filters( |
| 1377 |
'charitable_recommended_partners_ ' . $recommendation_type, // @codingStandardsIgnoreLine |
| 1378 |
array( |
| 1379 |
'charitable', |
| 1380 |
'optinmonster', |
| 1381 |
'wpforms-lite', |
| 1382 |
) |
| 1383 |
); |
| 1384 |
|
| 1385 |
// Remove any installed plugins from the preferred list. |
| 1386 |
$installed_plugins = get_plugins(); |
| 1387 |
|
| 1388 |
foreach ( $installed_plugins as $file => $plugin ) { |
| 1389 |
// Get the first part of the string before the /. |
| 1390 |
$plugin_slug = explode( '/', $file )[0]; |
| 1391 |
|
| 1392 |
if ( in_array( $plugin_slug, $preferred_partners, true ) ) { |
| 1393 |
unset( $preferred_partners[ array_search( $plugin_slug, $preferred_partners, true ) ] ); |
| 1394 |
} |
| 1395 |
|
| 1396 |
if ( ! empty( $preferred_partners ) ) { |
| 1397 |
foreach ( $partner_list as $partner_list_slug => $partner_list_info ) { |
| 1398 |
if ( ! empty( $partner_list_info ) && isset( $partner_list_info['slug'] ) && $partner_list_info['slug'] === $plugin_slug ) { |
| 1399 |
unset( $preferred_partners[ array_search( $plugin_slug, $preferred_partners, true ) ] ); |
| 1400 |
} |
| 1401 |
} |
| 1402 |
} |
| 1403 |
} |
| 1404 |
// Remove any plugins already dismissed from the logged in user. |
| 1405 |
$dismissed_partners = (array) get_user_meta( get_current_user_id(), 'charitable_dismissed_partners', true ); |
| 1406 |
$dismissed_partners = array_filter( $dismissed_partners ); |
| 1407 |
|
| 1408 |
if ( ! empty( $dismissed_partners ) ) { |
| 1409 |
foreach ( $dismissed_partners as $dismissed_partner ) { |
| 1410 |
if ( '' === $dismissed_partner ) { |
| 1411 |
continue; |
| 1412 |
} |
| 1413 |
if ( in_array( $dismissed_partner, $dismissed_partners, true ) ) { |
| 1414 |
unset( $preferred_partners[ array_search( $dismissed_partner, $preferred_partners, true ) ] ); |
| 1415 |
} |
| 1416 |
} |
| 1417 |
} |
| 1418 |
|
| 1419 |
// Limit the number of addons to return. |
| 1420 |
$preferred_partners = array_slice( $preferred_partners, 0, $limit ); |
| 1421 |
|
| 1422 |
// For each remaining item in $preferred_partners, get the plugin details from $partner_list. |
| 1423 |
foreach ( $preferred_partners as $key => $partner ) { |
| 1424 |
$preferred_partners[ $partner ] = ! empty( $partner_list[ $partner ] ) ? $partner_list[ $partner ] : array(); |
| 1425 |
$preferred_partners[ $partner ]['type'] = 'partner'; |
| 1426 |
unset( $preferred_partners[ $key ] ); |
| 1427 |
} |
| 1428 |
|
| 1429 |
return $preferred_partners; |
| 1430 |
} |
| 1431 |
|
| 1432 |
/** |
| 1433 |
* Get the recommended addons. |
| 1434 |
* |
| 1435 |
* @since 1.8.1.5 |
| 1436 |
* |
| 1437 |
* @param string $recommendation_type The type of recommendation to get. |
| 1438 |
* @param int $limit The number of recommendations to get. |
| 1439 |
* |
| 1440 |
* @return array |
| 1441 |
*/ |
| 1442 |
public function get_recommended_addons( $recommendation_type = 'campaign', $limit = 3 ) { |
| 1443 |
/* |
| 1444 |
Recommend at least one Charitable addon. |
| 1445 |
|
| 1446 |
Rules: |
| 1447 |
- Must be a Charitable addon. |
| 1448 |
- Must not be installed. |
| 1449 |
- Must not be dismissed. |
| 1450 |
|
| 1451 |
*/ |
| 1452 |
|
| 1453 |
$preferred_addons = apply_filters( |
| 1454 |
'charitable_recommended_addons_ ' . $recommendation_type, // @codingStandardsIgnoreLine |
| 1455 |
array( |
| 1456 |
'charitable-recurring', |
| 1457 |
'charitable-ambassadors', |
| 1458 |
'charitable-gift-aid', |
| 1459 |
'charitable-anonymous-donations', |
| 1460 |
'charitable-fee-relief', |
| 1461 |
) |
| 1462 |
); |
| 1463 |
|
| 1464 |
// Remove any installed Charitable addons from the preferred list. |
| 1465 |
$installed_plugins = get_plugins(); |
| 1466 |
|
| 1467 |
foreach ( $installed_plugins as $file => $plugin ) { |
| 1468 |
// Get the first part of the string before the /. |
| 1469 |
$plugin_slug = explode( '/', $file )[0]; |
| 1470 |
|
| 1471 |
if ( in_array( $plugin_slug, $preferred_addons, true ) ) { |
| 1472 |
unset( $preferred_addons[ array_search( $plugin_slug, $preferred_addons, true ) ] ); |
| 1473 |
} |
| 1474 |
} |
| 1475 |
|
| 1476 |
// Remove any addons already dismissed from the logged in user. |
| 1477 |
$dismissed_addons = (array) get_user_meta( get_current_user_id(), 'charitable_dismissed_addons', true ); |
| 1478 |
$dismissed_addons = array_filter( $dismissed_addons ); |
| 1479 |
|
| 1480 |
if ( ! empty( $dismissed_addons ) ) { |
| 1481 |
foreach ( $dismissed_addons as $dismissed_addon ) { |
| 1482 |
if ( in_array( $dismissed_addon, $preferred_addons, true ) ) { |
| 1483 |
unset( $preferred_addons[ array_search( $dismissed_addon, $preferred_addons, true ) ] ); |
| 1484 |
} |
| 1485 |
} |
| 1486 |
} |
| 1487 |
|
| 1488 |
// Limit the number of addons to return. |
| 1489 |
$preferred_addons_to_compare = array_slice( $preferred_addons, 0, $limit ); |
| 1490 |
|
| 1491 |
// check and see if the slug refers to a Charitable addon first. |
| 1492 |
$addons = get_transient( '_charitable_addons' ); // @codingStandardsIgnoreLine - testing. |
| 1493 |
|
| 1494 |
// Get addons data from transient or perform API query if no transient. |
| 1495 |
if ( false === $addons ) { |
| 1496 |
$addons = charitable_get_addons_data_from_server(); |
| 1497 |
} |
| 1498 |
|
| 1499 |
$preferred_addons = array(); |
| 1500 |
|
| 1501 |
if ( ! empty( $addons ) ) { |
| 1502 |
|
| 1503 |
foreach ( $addons as $addon ) { |
| 1504 |
|
| 1505 |
if ( ! isset( $addon['slug'] ) || empty( $addon['slug'] ) ) { |
| 1506 |
continue; |
| 1507 |
} |
| 1508 |
|
| 1509 |
if ( in_array( $addon['slug'], $preferred_addons_to_compare, true ) ) { |
| 1510 |
|
| 1511 |
$sections = ! empty( $addon['sections'] ) ? unserialize( $addon['sections'] ) : array(); |
| 1512 |
|
| 1513 |
$preferred_addons[ $addon['slug'] ]['icon'] = charitable()->get_path( 'directory', false ) . 'assets/images/plugins/charitable/' . $addon['slug'] . '.png'; |
| 1514 |
$preferred_addons[ $addon['slug'] ]['title'] = trim( str_replace( 'Charitable', '', $addon['name'] ) ); |
| 1515 |
$preferred_addons[ $addon['slug'] ]['sections'] = array(); |
| 1516 |
$preferred_addons[ $addon['slug'] ]['description'] = isset( $sections['description'] ) ? wp_strip_all_tags( $sections['description'] ) : ''; |
| 1517 |
$preferred_addons[ $addon['slug'] ]['type'] = 'addon'; |
| 1518 |
|
| 1519 |
} |
| 1520 |
} |
| 1521 |
|
| 1522 |
} |
| 1523 |
|
| 1524 |
return $preferred_addons; |
| 1525 |
} |
| 1526 |
|
| 1527 |
/** |
| 1528 |
* Get a single plugin. |
| 1529 |
* |
| 1530 |
* @since 1.8.1.5 |
| 1531 |
* |
| 1532 |
* @param string $slug The plugin slug. |
| 1533 |
* |
| 1534 |
* @return array|null |
| 1535 |
*/ |
| 1536 |
public function get_plugin( $slug ) { |
| 1537 |
$plugins = $this->get_plugins( false ); |
| 1538 |
|
| 1539 |
if ( ! isset( $plugins[ $slug ] ) ) { |
| 1540 |
return; |
| 1541 |
} |
| 1542 |
|
| 1543 |
return $plugins[ $slug ]; |
| 1544 |
} |
| 1545 |
|
| 1546 |
/** |
| 1547 |
* Returns and/or create the single instance of this class. |
| 1548 |
* |
| 1549 |
* @since 1.8.1 |
| 1550 |
* |
| 1551 |
* @return Charitable_Admin_Plugins_Third_Party |
| 1552 |
*/ |
| 1553 |
public static function get_instance() { |
| 1554 |
if ( is_null( self::$instance ) ) { |
| 1555 |
self::$instance = new self(); |
| 1556 |
} |
| 1557 |
|
| 1558 |
return self::$instance; |
| 1559 |
} |
| 1560 |
} |
| 1561 |
|
| 1562 |
endif; |
| 1563 |
|