installed plugin Easy Digital Downloads version 3.1.0.3

This commit is contained in:
2022-11-27 15:03:07 +00:00
committed by Gitium
parent 555673545b
commit c5dce2cec6
1200 changed files with 238970 additions and 0 deletions
wp-content/plugins/easy-digital-downloads
assets
css
images
js
admin
alpine.min.jsedd-admin-customers.jsedd-admin-dashboard.jsedd-admin-discounts.jsedd-admin-downloads.jsedd-admin-email-tags.jsedd-admin-extension-manager.jsedd-admin-notes.jsedd-admin-notices.jsedd-admin-orders.jsedd-admin-orders.js.mapedd-admin-payments.jsedd-admin-reports.jsedd-admin-settings.jsedd-admin-tax-rates.jsedd-admin-tax-rates.js.mapedd-admin-tools-export.jsedd-admin-tools-import.jsedd-admin-tools.jsedd-admin-upgrades.jsedd-admin.jsedd-ajax.jsedd-checkout-global.js
frontend
checkout
components
agree-to-terms
index.jsutils.js
edd-ajax.js
gateways
jquery.validate.min.js
packages
paypal-checkout.js
utils
vendor
wp-polyfill.min.js
sample-products-import.xml
easy-digital-downloads.php
includes
EDD_SL_Plugin_Updater.phpactions.php
adjustments
admin
add-ons.php
adjustments
admin-actions.phpadmin-bar.phpadmin-deprecated-functions.phpadmin-footer.phpadmin-pages.phpclass-api-keys-table.phpclass-edd-heartbeat.phpclass-edd-notices.phpclass-list-table.phpclass-pass-manager.phpclass-sections.php
customers
dashboard-widgets.php
discounts
downloads
emails
extensions
import
installers
notes
payments
plugins.php
promos
reporting
settings
thickbox.phptools.php
tools
tracking.php
upgrades
upload-functions.php
views
ajax-functions.php
api
blocks
assets
build
edd-blocks.php
includes
readme.md
views
cart
checkout
class-base-object.phpclass-component.phpclass-easy-digital-downloads.phpclass-edd-cache-helper.phpclass-edd-cli.phpclass-edd-cron.phpclass-edd-customer-query.phpclass-edd-customer.phpclass-edd-db-customer-meta.phpclass-edd-db-customers.phpclass-edd-db.phpclass-edd-discount.phpclass-edd-download.phpclass-edd-fees.phpclass-edd-html-elements.phpclass-edd-license-handler.phpclass-edd-logging.phpclass-edd-register-meta.phpclass-edd-roles.phpclass-edd-session.phpclass-edd-stats.phpclass-stats.phpclass-structured-data.phpclass-utilities.phpcompat-functions.php
compat
component-functions.phpcountry-functions.php
currency
customer-functions.php
customers
database
NotificationsDB.phpREADME.md
engine
queries
rows
schemas
tables
date-functions.phpdeprecated-functions.phpdeprecated-hooks.phpdiscount-functions.phpdownload-functions.php
downloads
emails
error-tracking.php
extensions
formatting.php
gateways
actions.phpamazon-payments.phpfunctions.php
libs
manual.phppaypal-standard.php
paypal
stripe
apple-developer-merchantid-domain-association
assets
edd-stripe.php
includes
vendor
autoload.php
composer
stripe
stripe-php
CHANGELOG.mdCODE_OF_CONDUCT.mdLICENSEMakefileREADME.mdVERSIONbuild.phpcomposer.json
data
init.php
lib
Account.phpAccountLink.phpAlipayAccount.php
ApiOperations
ApiRequestor.phpApiResource.phpApiResponse.phpApplePayDomain.phpApplicationFee.phpApplicationFeeRefund.phpBalance.phpBalanceTransaction.phpBankAccount.phpBaseStripeClient.php
BillingPortal
BitcoinReceiver.phpBitcoinTransaction.phpCapability.phpCard.phpCharge.php
Checkout
Collection.phpCountrySpec.phpCoupon.phpCreditNote.phpCreditNoteLineItem.phpCustomer.phpCustomerBalanceTransaction.phpDiscount.phpDispute.phpEphemeralKey.phpErrorObject.phpEvent.php
Exception
ExchangeRate.phpFile.phpFileLink.php
HttpClient
Invoice.phpInvoiceItem.phpInvoiceLineItem.php
Issuing
LineItem.phpLoginLink.phpMandate.phpOAuth.phpOAuthErrorObject.phpOrder.phpOrderItem.phpOrderReturn.phpPaymentIntent.phpPaymentMethod.phpPayout.phpPerson.phpPlan.phpPrice.phpProduct.phpPromotionCode.php
Radar
Recipient.phpRecipientTransfer.phpRefund.php
Reporting
RequestTelemetry.phpReview.phpSKU.php
Service
AbstractService.phpAbstractServiceFactory.phpAccountLinkService.phpAccountService.phpApplePayDomainService.phpApplicationFeeService.phpBalanceService.phpBalanceTransactionService.php
BillingPortal
ChargeService.php
Checkout
CoreServiceFactory.phpCountrySpecService.phpCouponService.phpCreditNoteService.phpCustomerService.phpDisputeService.phpEphemeralKeyService.phpEventService.phpExchangeRateService.phpFileLinkService.phpFileService.phpInvoiceItemService.phpInvoiceService.php
Issuing
MandateService.phpOAuthService.phpOrderReturnService.phpOrderService.phpPaymentIntentService.phpPaymentMethodService.phpPayoutService.phpPlanService.phpPriceService.phpProductService.phpPromotionCodeService.php
Radar
RefundService.php
Reporting
ReviewService.phpSetupIntentService.php
Sigma
SkuService.phpSourceService.phpSubscriptionItemService.phpSubscriptionScheduleService.phpSubscriptionService.phpTaxRateService.php
Terminal
TokenService.phpTopupService.phpTransferService.phpWebhookEndpointService.php
SetupIntent.php
Sigma
SingletonApiResource.phpSource.phpSourceTransaction.phpStripe.phpStripeClient.phpStripeClientInterface.phpStripeObject.phpSubscription.phpSubscriptionItem.phpSubscriptionSchedule.phpTaxId.phpTaxRate.php
Terminal
ThreeDSecure.phpToken.phpTopup.phpTransfer.phpTransferReversal.phpUsageRecord.phpUsageRecordSummary.php
Util
Webhook.phpWebhookEndpoint.phpWebhookSignature.php
phpdoc.dist.xmlphpstan-baseline.neonphpstan.neon.distupdate_certs.php
install.phpinterface-edd-exception.php
libraries
logs
mime-types.phpmisc-functions.php
models
notes
orders
payments
plugin-compatibility.phppost-types.phpprivacy-functions.phpprocess-download.phpprocess-purchase.phpquery-filters.phprefund-functions.php
reports
scripts.phpshortcodes.phptax-functions.phptemplate-actions.phptemplate-functions.phptheme-compatibility.php
traits
user-functions.php
users
utils
widgets.php
languages
license.txtreadme.txt
templates
uninstall.php

@ -0,0 +1,346 @@
<?php
namespace EDD\Admin\Extensions;
use \EDD\Admin\Pass_Manager;
abstract class Extension {
/**
* The product ID. This only needs to be set if the extending class is
* for a single product.
*
* @since 2.11.4
* @var int
*/
protected $item_id;
/**
* The settings tab where this item will show.
*
* @since 2.11.4
* @var string
*/
protected $settings_tab = '';
/**
* The required AA pass level.
*/
const PASS_LEVEL = Pass_Manager::PERSONAL_PASS_ID;
/**
* The Extension Manager
*
* @var \EDD\Admin\Extensions\Extension_Manager
*/
protected $manager;
/**
* The settings section for this item.
*
* @since 2.11.5
* @var string
*/
protected $settings_section = 'general';
public function __construct() {
$this->manager = new \EDD\Admin\Extensions\Extension_Manager( static::PASS_LEVEL );
}
/**
* Whether the extension is activated.
*
* @since 2.11.4
* @return bool
*/
abstract protected function is_activated();
/**
* Output the settings field (installation helper).
*
* @return void
*/
public function settings_field() {
if ( $this->is_activated() ) {
return;
}
$this->do_single_extension_card();
}
/**
* Outputs a single extension card.
*
* @since 2.11.4
* @param false|int $item_id Optional: the individual extension product ID.
* @return void
*/
public function do_single_extension_card( $item_id = false ) {
if ( empty( $item_id ) && empty( $this->item_id ) ) {
return;
}
$product_data = $this->get_product_data( $item_id );
if ( ! $product_data || empty( $product_data->title ) ) {
return;
}
$this->manager->do_extension_card(
$product_data,
$this->get_button_parameters( $product_data, $item_id ),
$this->get_link_parameters( $product_data ),
$this->get_configuration( $product_data )
);
}
/**
* Gets the product data for a specific extension.
*
* @param false|int $item_id
* @return bool|ProductData|array False if there is no data; product data object if there is, or possibly an array of arrays.
*/
public function get_product_data( $item_id = false ) {
require_once EDD_PLUGIN_DIR . 'includes/admin/extensions/class-extensions-api.php';
$api = new ExtensionsAPI();
$body = $this->get_api_body();
$api_item_id = $item_id ?: $this->item_id;
$product_data = $api->get_product_data( $body, $api_item_id );
if ( ! $product_data ) {
return false;
}
if ( $api_item_id ) {
return $product_data;
}
if ( $item_id && ! empty( $product_data[ $item_id ] ) ) {
return $product_data[ $item_id ];
}
return $product_data;
}
/**
* Gets the custom configuration for the extension.
*
* @since 2.11.4
* @param ProductData $product_data Optionally allows the product data to be parsed in the configuration.
* @return array
*/
protected function get_configuration( ProductData $product_data ) {
return array();
}
/**
* Formats a custom description array by running wpautop and converting it to a string.
*
* @since 2.11.4
* @param array $description The custom product description.
* @return string
*/
protected function format_description( array $description ) {
return implode( '', array_map( 'wpautop', $description ) );
}
/**
* Whether the current screen is an EDD setings screen.
*
* @since 2.11.4
* @return bool
*/
protected function is_edd_settings_screen() {
return edd_is_admin_page( 'settings', $this->settings_tab );
}
/**
* Whether the current screen is a download new/edit screen.
*
* @since 2.11.4
* @return bool
*/
protected function is_download_edit_screen() {
return edd_is_admin_page( 'download', 'edit' ) || edd_is_admin_page( 'download', 'new' );
}
/**
* Whether the section for an individual product can be registered/shown.
*
* @since 2.11.4
* @return bool
*/
protected function can_show_product_section() {
if ( ! $this->is_edd_settings_screen() ) {
return false;
}
if ( $this->is_activated() ) {
return false;
}
if ( ! $this->get_product_data() ) {
return false;
}
return true;
}
/**
* Gets the array for the body of the API request.
* Classes may need to override this (for example, to query a specific tag).
* Note that the first array key/value pair are used to create the option name.
*
* @return array
*/
protected function get_api_body() {
return array();
}
/**
* Gets the type for the button data-type attribute.
* This is intended to sync with the Products API request.
* Default is product.
*
* Really a shim for array_key_first.
*
* @param array $array
* @return string
*/
private function get_type( array $array ) {
$type = 'product';
if ( empty( $array ) ) {
return $type;
}
if ( function_exists( 'array_key_first' ) ) {
return array_key_first( $array );
}
foreach ( $array as $key => $unused ) {
return $key;
}
return $type;
}
/**
* Gets the button parameters.
* Classes should not need to replace this method.
*
* @param ProductData $product_data The extension data returned from the Products API.
* @param int|false $item_id Optional: the item ID.
* @return array
*/
protected function get_button_parameters( ProductData $product_data, $item_id = false ) {
if ( empty( $item_id ) ) {
$item_id = $this->item_id;
}
$body = $this->get_api_body();
$type = $this->get_type( $body );
$id = ! empty( $body[ $type ] ) ? $body[ $type ] : $this->item_id;
$button = array(
'type' => $type,
'id' => $id,
'product' => $item_id,
);
// If the extension is not installed, the button will prompt to install and activate it.
if ( ! $this->manager->is_plugin_installed( $product_data->basename ) ) {
if ( $this->manager->pass_can_download() ) {
$button = array(
/* translators: The extension name. */
'button_text' => sprintf( __( 'Log In to Your Account to Download %s', 'easy-digital-downloads' ), $product_data->title ),
'href' => $this->get_upgrade_url( $product_data, $item_id, true ),
'new_tab' => true,
'type' => $type,
);
} else {
$button = array(
/* translators: The extension name. */
'button_text' => sprintf( __( 'Upgrade Today to Access %s!', 'easy-digital-downloads' ), $product_data->title ),
'href' => $this->get_upgrade_url( $product_data, $item_id ),
'new_tab' => true,
'type' => $type,
);
}
} elseif ( ! empty( $product_data->basename ) && ! $this->manager->is_plugin_active( $product_data->basename ) ) {
// If the extension is installed, but not activated, the button will prompt to activate it.
$button['plugin'] = $product_data->basename;
$button['action'] = 'activate';
/* translators: The extension name. */
$button['button_text'] = sprintf( __( 'Activate %s', 'easy-digital-downloads' ), $product_data->title );
}
return $button;
}
/**
* Gets the upgrade URL for the button.
*
* @since 2.11.4
* @param ProductData $product_data The product data object.
* @param int $item_id The item/product ID.
* @param bool $has_access Whether the user already has access to the extension (based on pass level).
* @return string
*/
private function get_upgrade_url( ProductData $product_data, $item_id, $has_access = false ) {
if ( $has_access ) {
$url = 'https://easydigitaldownloads.com/your-account/your-downloads/';
} else {
$url = 'https://easydigitaldownloads.com/lite-upgrade';
}
$utm_parameters = array(
'utm_medium' => $this->settings_section,
'utm_content' => $product_data->slug,
);
return edd_link_helper(
$url,
$utm_parameters
);
}
/**
* Gets the array of parameters for the link to configure the extension.
*
* @since 2.11.4
* @param ProductData $product_data The product data object.
* @return array
*/
protected function get_link_parameters( ProductData $product_data ) {
$configuration = $this->get_configuration( $product_data );
$tab = ! empty( $configuration['tab'] ) ? $configuration['tab'] : $product_data->tab;
$section = ! empty( $configuration['section'] ) ? $configuration['section'] : $product_data->section;
if ( empty( $tab ) && empty( $section ) ) {
return array(
/* translators: the plural Downloads label. */
'button_text' => sprintf( __( 'View %s', 'easy-digital-downloads' ), edd_get_label_plural() ),
'href' => add_query_arg(
array(
'post_type' => 'download',
),
admin_url( 'edit.php' )
),
);
}
return array(
/* translators: The extension name. */
'button_text' => sprintf( __( 'Configure %s', 'easy-digital-downloads' ), $product_data->title ),
'href' => edd_get_admin_url(
array(
'page' => 'edd-settings',
'tab' => urlencode( $tab ),
'section' => urlencode( $section ),
)
),
);
}
/**
* Optionally hides the submit button on screens where it's not needed.
*
* @since 2.11.4
* @return void
*/
public function hide_submit_button() {
if ( ! $this->can_show_product_section() ) {
return;
}
?>
<style>p.submit{display:none;}</style>
<?php
}
}

@ -0,0 +1,483 @@
<?php
namespace EDD\Admin\Extensions;
use \EDD\Admin\Pass_Manager;
class Extension_Manager {
/**
* All of the installed plugins on the site.
*
* @since 2.11.4
* @var array
*/
public $all_plugins;
/**
* The minimum pass ID required to install the extension.
*
* @since 2.11.4
* @var int
*/
private $required_pass_id;
/**
* Pass Manager class
*
* @var Pass_Manager
*/
protected $pass_manager;
public function __construct( $required_pass_id = null ) {
if ( $required_pass_id ) {
$this->required_pass_id = $required_pass_id;
}
$this->pass_manager = new Pass_Manager();
add_action( 'wp_ajax_edd_activate_extension', array( $this, 'activate' ) );
add_action( 'wp_ajax_edd_install_extension', array( $this, 'install' ) );
add_action( 'admin_enqueue_scripts', array( $this, 'register_assets' ) );
}
/**
* Registers the extension manager script and style.
*
* @since 2.11.4
* @return void
*/
public function register_assets() {
if ( wp_script_is( 'edd-extension-manager', 'registered' ) ) {
return;
}
$minify = defined( 'SCRIPT_DEBUG' ) && SCRIPT_DEBUG ? '' : '.min';
wp_register_style( 'edd-extension-manager', EDD_PLUGIN_URL . "assets/css/edd-admin-extension-manager.min.css", array(), EDD_VERSION );
wp_register_script( 'edd-extension-manager', EDD_PLUGIN_URL . "assets/js/edd-admin-extension-manager.js", array( 'jquery' ), EDD_VERSION, true );
wp_localize_script(
'edd-extension-manager',
'EDDExtensionManager',
array(
'activating' => __( 'Activating', 'easy-digital-downloads' ),
'installing' => __( 'Installing', 'easy-digital-downloads' ),
'plugin_install_failed' => __( 'Could not install the plugin. Please download and install it manually via Plugins > Add New.', 'easy-digital-downloads' ),
'extension_install_failed' => sprintf(
/* translators: 1. opening anchor tag, do not translate; 2. closing anchor tag, do not translate */
__( 'Could not install the extension. Please %1$sdownload it from your account%2$s and install it manually.', 'easy-digital-downloads' ),
'<a href="https://easydigitaldownloads.com/your-account/" target="_blank" rel="noopener noreferrer">',
'</a>'
),
'extension_manager_nonce' => wp_create_nonce( 'edd_extensionmanager' ),
)
);
}
/**
* Enqueues the extension manager script/style.
*
* @since 2.11.4
* @return void
*/
public function enqueue() {
wp_enqueue_style( 'edd-extension-manager' );
wp_enqueue_script( 'edd-extension-manager' );
}
/**
* Outputs a standard extension card.
*
* @since 2.11.4
* @param ProductData $product The product data object.
* @param array $inactive_parameters The array of information to build the button for an inactive/not installed plugin.
* @param array $active_parameters The array of information needed to build the link to configure an active plugin.
* @param array $configuration The optional array of data to override the product data retrieved from the API.
* @return void
*/
public function do_extension_card( ProductData $product, $inactive_parameters, $active_parameters, $configuration = array() ) {
$this->enqueue();
if ( ! empty( $configuration ) ) {
$product = $product->mergeConfig( $configuration );
}
?>
<div class="<?php echo esc_attr( implode( ' ', array_map( 'sanitize_html_class', $this->get_card_classes( $product ) ) ) ); ?>">
<h3 class="edd-extension-manager__title"><?php echo esc_html( $product->title ); ?></h3>
<div class="edd-extension-manager__body">
<?php if ( ! empty( $product->image ) ) : ?>
<div class="edd-extension-manager__image">
<img alt="" src="<?php echo esc_url( $product->image ); ?>" />
</div>
<?php endif; ?>
<?php if ( ! empty( $product->description ) ) : ?>
<div class="edd-extension-manager__description"><?php echo wp_kses_post( wpautop( $product->description ) ); ?></div>
<?php endif; ?>
<?php if ( ! empty( $product->features ) && is_array( $product->features ) ) : ?>
<div class="edd-extension-manager__features">
<ul>
<?php foreach ( $product->features as $feature ) : ?>
<li><span class="dashicons dashicons-yes"></span><?php echo esc_html( $feature ); ?></li>
<?php endforeach; ?>
</ul>
</div>
<?php endif; ?>
<div class="edd-extension-manager__group">
<?php
if ( ! empty( $product->basename ) && ! $this->is_plugin_active( $product->basename ) ) {
?>
<div class="edd-extension-manager__step">
<?php $this->button( $inactive_parameters ); ?>
</div>
<?php
}
?>
<div class="edd-extension-manager__step">
<?php $this->link( $active_parameters ); ?>
</div>
</div>
</div>
</div>
<?php
}
/**
* Gets the CSS classes for the single extension card.
*
* @since 2.11.4
* @param ProductData $product The product data object.
* @return array The array of CSS classes.
*/
private function get_card_classes( $product ) {
$base_class = 'edd-extension-manager__card';
$card_classes = array(
$base_class,
);
$variation = 'stacked';
if ( ! empty( $product->style ) ) {
$variation = $product->style;
}
if ( 'detailed-2col' === $variation && ( empty( $product->features ) || ! is_array( $product->features ) ) ) {
$variation = 'detailed';
}
$card_classes[] = "{$base_class}--{$variation}";
return $card_classes;
}
/**
* Outputs the button to activate/install a plugin/extension.
* If a link is passed in the args, create a button style link instead (@uses $this->link()).
*
* @since 2.11.4
* @param array $args The array of parameters for the button.
* @return void
*/
public function button( $args ) {
if ( ! empty( $args['href'] ) ) {
$this->link( $args );
return;
}
$defaults = array(
'button_class' => 'button-primary',
'plugin' => '',
'action' => '',
'button_text' => '',
'type' => 'plugin',
'id' => '',
'product' => '',
'pass' => $this->required_pass_id,
);
$args = wp_parse_args( $args, $defaults );
if ( empty( $args['button_text'] ) ) {
return;
}
?>
<button
class="button <?php echo esc_attr( $args['button_class'] ); ?> edd-extension-manager__action"
<?php
foreach ( $args as $key => $attribute ) {
if ( empty( $attribute ) || in_array( $key, array( 'button_class', 'button_text' ), true ) ) {
continue;
}
printf(
' data-%s="%s"',
esc_attr( $key ),
esc_attr( $attribute )
);
}
?>
>
<?php echo esc_html( $args['button_text'] ); ?>
</button>
<?php
}
/**
* Outputs the link, if it should be a link.
*
* @param array $args
* @return void
*/
public function link( $args ) {
$defaults = array(
'button_class' => 'button-primary',
'button_text' => '',
);
$args = wp_parse_args( $args, $defaults );
if ( empty( $args['button_text'] ) ) {
return;
}
?>
<a
class="button <?php echo esc_attr( $args['button_class'] ); ?>"
href="<?php echo esc_url( $args['href'] ); ?>"
<?php echo ! empty( $args['new_tab'] ) ? ' target="_blank" rel="noopener noreferrer"' : ''; ?>
>
<?php echo esc_html( $args['button_text'] ); ?>
</a>
<?php
}
/**
* Installs and maybe activates a plugin or extension.
*
* @since 2.11.4
*/
public function install() {
// Run a security check.
check_ajax_referer( 'edd_extensionmanager', 'nonce', true );
$generic_error = esc_html__( 'There was an error while performing your request.', 'easy-digital-downloads' );
$type = ! empty( $_POST['type'] ) ? sanitize_text_field( $_POST['type'] ) : '';
$required_pass = ! empty( $_POST['pass'] ) ? sanitize_text_field( $_POST['pass'] ) : '';
$result = array(
'message' => $generic_error,
'is_activated' => false,
);
if ( ! $type ) {
wp_send_json_error( $result );
}
// Check if new installations are allowed.
if ( ! $this->can_install( $type, $required_pass ) ) {
wp_send_json_error( $result );
}
$result['message'] = 'plugin' === $type
? __( 'Could not install the plugin. Please download and install it manually via Plugins > Add New.', 'easy-digital-downloads' )
: sprintf(
/* translators: 1. opening anchor tag, do not translate; 2. closing anchor tag, do not translate */
__( 'Could not install the extension. Please %1$sdownload it from your account%2$s and install it manually.', 'easy-digital-downloads' ),
'<a href="https://easydigitaldownloads.com/your-account/" target="_blank" rel="noopener noreferrer">',
'</a>'
);
$plugin = ! empty( $_POST['plugin'] ) ? sanitize_text_field( $_POST['plugin'] ) : '';
if ( empty( $plugin ) ) {
wp_send_json_error( $result );
}
// Set the current screen to avoid undefined notices.
set_current_screen( 'download_page_edd-settings' );
// Prepare variables.
$url = esc_url_raw(
edd_get_admin_url(
array(
'page' => 'edd-addons',
)
)
);
ob_start();
$creds = request_filesystem_credentials( $url, '', false, false, null );
// Hide the filesystem credentials form.
ob_end_clean();
// Check for file system permissions.
if ( ! $creds ) {
wp_send_json_error( $result );
}
if ( ! WP_Filesystem( $creds ) ) {
wp_send_json_error( $result );
}
/*
* We do not need any extra credentials if we have gotten this far, so let's install the plugin.
*/
require_once EDD_PLUGIN_DIR . 'includes/admin/installers/class-plugin-silent-upgrader.php';
require_once EDD_PLUGIN_DIR . 'includes/admin/installers/class-plugin-silent-upgrader-skin.php';
require_once EDD_PLUGIN_DIR . 'includes/admin/installers/class-install-skin.php';
// Do not allow WordPress to search/download translations, as this will break JS output.
remove_action( 'upgrader_process_complete', array( 'Language_Pack_Upgrader', 'async_upgrade' ), 20 );
// Create the plugin upgrader with our custom skin.
$installer = new \EDD\Admin\Installers\PluginSilentUpgrader( new \EDD\Admin\Installers\Install_Skin() );
// Error check.
if ( ! method_exists( $installer, 'install' ) || empty( $plugin ) ) {
wp_send_json_error( $result );
}
$installer->install( $plugin ); // phpcs:ignore
// Flush the cache and return the newly installed plugin basename.
wp_cache_flush();
$plugin_basename = $installer->plugin_info();
// Check for permissions.
if ( ! current_user_can( 'activate_plugins' ) ) {
$result['message'] = 'plugin' === $type ? esc_html__( 'Plugin installed.', 'easy-digital-downloads' ) : esc_html__( 'Extension installed.', 'easy-digital-downloads' );
wp_send_json_error( $result );
}
$this->activate( $plugin_basename );
}
/**
* Activates an existing extension.
*
* @since 2.11.4
* @param string $plugin_basename Optional: the plugin basename.
*/
public function activate( $plugin_basename = '' ) {
$result = array(
'message' => __( 'There was an error while performing your request.', 'easy-digital-downloads' ),
'is_activated' => false,
);
// Check for permissions.
if ( ! check_ajax_referer( 'edd_extensionmanager', 'nonce', false ) || ! current_user_can( 'activate_plugins' ) ) {
$result['message'] = __( 'Plugin activation is not available for you on this site.', 'easy-digital-downloads' );
wp_send_json_error( $result );
}
$already_installed = false;
if ( empty( $plugin_basename ) ) {
$plugin_basename = ! empty( $_POST['plugin'] ) ? sanitize_text_field( $_POST['plugin'] ) : '';
$already_installed = true;
}
$plugin_basename = sanitize_text_field( wp_unslash( $plugin_basename ) );
$type = ! empty( $_POST['type'] ) ? sanitize_text_field( $_POST['type'] ) : '';
if ( 'plugin' !== $type ) {
$type = 'extension';
}
$result = array(
/* translators: "extension" or "plugin" as defined by $type */
'message' => sprintf( __( 'Could not activate the %s.', 'easy-digital-downloads' ), esc_html( $type ) ),
'is_activated' => false,
);
if ( empty( $plugin_basename ) || empty( $type ) ) {
wp_send_json_error( $result );
}
$result['basename'] = $plugin_basename;
// Activate the plugin silently.
$activated = activate_plugin( $plugin_basename );
if ( ! is_wp_error( $activated ) ) {
if ( $already_installed ) {
$message = 'plugin' === $type ? esc_html__( 'Plugin activated.', 'easy-digital-downloads' ) : esc_html__( 'Extension activated.', 'easy-digital-downloads' );
} else {
$message = 'plugin' === $type ? esc_html__( 'Plugin installed & activated.', 'easy-digital-downloads' ) : esc_html__( 'Extension installed & activated.', 'easy-digital-downloads' );
}
$result['is_activated'] = true;
$result['message'] = $message;
wp_send_json_success( $result );
}
// Fallback error just in case.
wp_send_json_error( $result );
}
/**
* Determine if the plugin/extension installations are allowed.
*
* @since 2.11.4
*
* @param string $type Should be `plugin` or `extension`.
*
* @return bool
*/
public function can_install( $type, $required_pass_id = false ) {
if ( ! current_user_can( 'install_plugins' ) ) {
return false;
}
// Determine whether file modifications are allowed.
if ( ! wp_is_file_mod_allowed( 'edd_can_install' ) ) {
return false;
}
// All plugin checks are done.
if ( 'plugin' === $type ) {
return true;
}
return $this->pass_can_download( $required_pass_id );
}
/**
* Checks if a user's pass can download an extension.
*
* @since 2.11.4
* @return bool Returns true if the current site has an active pass and it is greater than or equal to the extension's minimum pass.
*/
public function pass_can_download( $required_pass_id = false ) {
$highest_pass_id = $this->pass_manager->highest_pass_id;
if ( ! $required_pass_id ) {
$required_pass_id = $this->required_pass_id;
}
return ! empty( $highest_pass_id ) && ! empty( $required_pass_id ) && $this->pass_manager->pass_compare( $highest_pass_id, $required_pass_id, '>=' );
}
/**
* Get all installed plugins.
*
* @since 2.11.4
* @return array
*/
public function get_plugins() {
if ( $this->all_plugins ) {
return $this->all_plugins;
}
$this->all_plugins = get_plugins();
return $this->all_plugins;
}
/**
* Check if a plugin is installed.
*
* @since 2.11.4
* @param string $plugin The path to the main plugin file, eg 'my-plugin/my-plugin.php'.
* @return boolean
*/
public function is_plugin_installed( $plugin ) {
return array_key_exists( $plugin, $this->get_plugins() );
}
/**
* Whether a given plugin is active or not.
*
* @since 2.11.4
* @param string|ProductData $basename_or_data The path to the main plugin file, eg 'my-plugin/my-plugin.php', or the product data object.
* @return boolean
*/
public function is_plugin_active( $basename_or_data ) {
$basename = ! empty( $basename_or_data->basename ) ? $basename_or_data->basename : $basename_or_data;
return ! empty( $basename ) && is_plugin_active( $basename );
}
}

@ -0,0 +1,111 @@
<?php
namespace EDD\Admin\Extensions;
class ProductData {
/**
* The product name.
*
* @since 2.11.4
* @var string
*/
public $title;
/**
* The product slug.
*
* @since 2.11.4
* @var string
*/
public $slug = '';
/**
* The URL for the product featured image.
*
* @since 2.11.4
* @var string
*/
public $image;
/**
* The product description.
*
* @since 2.11.4
* @var string
*/
public $description;
/**
* The extension basename.
*
* @since 2.11.4
* @var string
*/
public $basename;
/**
* The settings tab where the extension settings will show.
*
* @since 2.11.4
* @var string
*/
public $tab;
/**
* The settings section for the extension.
*
* @since 2.11.4
* @var string
*/
public $section;
/**
* The product features.
*
* @since 2.11.4
* @var array
*/
public $features = array();
/**
* Take array and return object.
*
* @since 2.11.4
* @param array $array
* @return ProductData
* @throws \InvalidArgumentException
*/
public function fromArray( $array ) {
$expected_keys = array( 'title', 'slug', 'description', 'basename' );
$array_to_check = array_intersect_key( $array, array_flip( $expected_keys ) );
if ( empty( $array_to_check ) ) {
throw new \InvalidArgumentException(
'Invalid ProductData object, must have the exact following keys: ' . implode( ', ', $expected_keys )
);
}
$product_data = new self();
foreach ( $array as $key => $value ) {
$product_data->$key = $value;
}
return $product_data;
}
/**
* Merge an array of data into an object.
*
* @since 2.11.4
* @param array $configuration The custom configuration data.
* @return ProductData
*/
public function mergeConfig( array $configuration ) {
foreach ( $configuration as $key => $value ) {
$this->{$key} = $value;
}
return $this;
}
}

@ -0,0 +1,222 @@
<?php
namespace EDD\Admin\Extensions;
class ExtensionsAPI {
/**
* Gets the product data from the EDD Products API.
*
* @since 2.11.4
* @param array $body The body for the API request.
* @param int $item_id The product ID, if querying a single product.
* @return false|array|ProductData
*/
public function get_product_data( $body = array(), $item_id = false ) {
if ( empty( $body ) ) {
if ( empty( $item_id ) ) {
return false;
}
$body = $this->get_api_body( $item_id );
}
$key = $this->array_key_first( $body );
// The option name is created from the first key/value pair of the API "body".
$option_name = sanitize_key( "edd_extension_{$key}_{$body[ $key ]}_data" );
$option = get_option( $option_name );
$is_stale = $this->option_has_expired( $option );
// The ProductData class.
$product_data = new ProductData();
// If the data is "fresh" and what we want exists, return it.
if ( $option && ! $is_stale ) {
if ( $item_id && ! empty( $option[ $item_id ] ) ) {
return $product_data->fromArray( $option[ $item_id ] );
} elseif ( ! empty( $option['timeout'] ) ) {
unset( $option['timeout'] );
return $option;
}
}
// Get all of the product data.
$all_product_data = $this->get_all_product_data();
// If no product data was retrieved, let the option sit for an hour.
if ( empty( $all_product_data ) ) {
$data = array(
'timeout' => strtotime( '+1 hour', time() ),
);
if ( $option && $is_stale ) {
$data = array_merge( $option, $data );
}
update_option(
$option_name,
$data,
false
);
if ( $item_id && ! empty( $option[ $item_id ] ) ) {
return $product_data->fromArray( $option[ $item_id ] );
}
unset( $option['timeout'] );
return $option;
}
$value = array(
'timeout' => strtotime( '+1 week', time() ),
);
if ( $item_id && ! empty( $all_product_data->$item_id ) ) {
$item = $all_product_data->$item_id;
$value[ $item_id ] = $this->get_item_data( $item );
} elseif ( in_array( $key, array( 'category', 'tag' ), true ) ) {
$term_id = $body[ $key ];
foreach ( $all_product_data as $item_id => $item ) {
if ( 'category' === $key && ( empty( $item->categories ) || ! in_array( $term_id, $item->categories, true ) ) ) {
continue;
} elseif ( 'tag' === $key && ( empty( $item->tags ) || ! in_array( $term_id, $item->tags, true ) ) ) {
continue;
}
$value[ $item_id ] = $this->get_item_data( $item );
}
}
update_option( $option_name, $value, false );
unset( $value['timeout'] );
return $item_id && ! empty( $value[ $item_id ] ) ? $product_data->fromArray( $value[ $item_id ] ) : $value;
}
/**
* Gets all of the product data, either from an option or an API request.
* If the option exists and has data, it will be an object.
*
* @since 2.11.4
* @return object|false
*/
private function get_all_product_data() {
// Possibly all product data is in an option. If it is, return it.
$all_product_data = get_option( 'edd_all_extension_data' );
if ( $all_product_data && ! $this->option_has_expired( $all_product_data ) ) {
return ! empty( $all_product_data['products'] ) ? $all_product_data['products'] : false;
}
// Otherwise, query the API.
$url = add_query_arg(
array(
'edd_action' => 'extension_data',
),
$this->get_products_url()
);
$request = wp_remote_get(
esc_url_raw( $url ),
array(
'timeout' => 15,
'sslverify' => true,
)
);
// If there was an API error, set option and return false.
if ( is_wp_error( $request ) || ( 200 !== wp_remote_retrieve_response_code( $request ) ) ) {
update_option(
'edd_all_extension_data',
array(
'timeout' => strtotime( '+1 hour', time() ),
),
false
);
return false;
}
// Fresh data has been retrieved, so update the option with a four hour timeout.
$all_product_data = json_decode( wp_remote_retrieve_body( $request ) );
$data = array(
'timeout' => strtotime( '+4 hours', time() ),
'products' => $all_product_data,
);
update_option( 'edd_all_extension_data', $data, false );
return $all_product_data;
}
/**
* Gets the product data as needed for the extension manager.
*
* @since 2.11.4
* @param object $item
* @return array
*/
private function get_item_data( $item ) {
return array(
'title' => ! empty( $item->title ) ? $item->title : '',
'slug' => ! empty( $item->slug ) ? $item->slug : '',
'image' => ! empty( $item->image ) ? $item->image : '',
'description' => ! empty( $item->excerpt ) ? $item->excerpt : '',
'basename' => ! empty( $item->custom_meta->basename ) ? $item->custom_meta->basename : '',
'tab' => ! empty( $item->custom_meta->settings_tab ) ? $item->custom_meta->settings_tab : '',
'section' => ! empty( $item->custom_meta->settings_section ) ? $item->custom_meta->settings_section : '',
);
}
/**
* Gets the base url for the products remote request.
*
* @since 2.11.4
* @return string
*/
private function get_products_url() {
if ( defined( 'EDD_PRODUCTS_URL' ) ) {
return EDD_PRODUCTS_URL;
}
return 'https://easydigitaldownloads.com/';
}
/**
* Gets the default array for the body of the API request.
* A class may override this by setting an array to query a tag or category.
* Note that the first array key/value pair are used to create the option name.
*
* @since 2.11.4
* @param int $item_id The product ID.
* @return array
*/
private function get_api_body( $item_id ) {
return array(
'product' => $item_id,
);
}
/**
* Gets the first key of an array.
* (Shims array_key_first for PHP < 7.3)
*
* @since 2.11.4
* @param array $array
* @return string|null
*/
private function array_key_first( array $array ) {
if ( function_exists( 'array_key_first' ) ) {
return array_key_first( $array );
}
foreach ( $array as $key => $unused ) {
return $key;
}
return null;
}
/**
* Checks whether a given option has "expired".
*
* @since 2.11.4
* @param array|false $option
* @return bool
*/
private function option_has_expired( $option ) {
return empty( $option['timeout'] ) || time() > $option['timeout'];
}
}

@ -0,0 +1,132 @@
<?php
/**
* Email Marketing
*
* Manages automatic installation/activation for email marketing extensions.
*
* @package EDD
* @subpackage EmailMarketing
* @copyright Copyright (c) 2021, Easy Digital Downloads
* @license https://opensource.org/licenses/gpl-2.0.php GNU Public License
* @since 2.11.4
*/
namespace EDD\Admin\Settings;
use \EDD\Admin\Extensions\Extension;
class EmailMarketing extends Extension {
/**
* The EDD settings tab where this extension should show.
*
* @since 2.11.4
* @var string
*/
protected $settings_tab = 'marketing';
/**
* The settings section for this item.
*
* @since 2.11.5
* @var string
*/
protected $settings_section = 'email_marketing';
public function __construct() {
add_filter( 'edd_settings_sections_marketing', array( $this, 'add_section' ) );
add_action( 'edd_settings_tab_top_marketing_email_marketing', array( $this, 'field' ) );
parent::__construct();
}
/**
* Adds an email marketing section to the Marketing tab.
*
* @since 2.11.4
* @param array $sections
* @return array
*/
public function add_section( $sections ) {
if ( ! $this->is_edd_settings_screen() ) {
return $sections;
}
$product_data = $this->get_product_data();
if ( ! $product_data || ! is_array( $product_data ) ) {
return $sections;
}
$sections[ $this->settings_section ] = __( 'Email Marketing', 'easy-digital-downloads' );
return $sections;
}
/**
* Gets the customized configuration for the extension card.
*
* @since 2.11.4
* @param \EDD\Admin\Extensions\ProductData $product_data The product data object.
* @return array
*/
protected function get_configuration( \EDD\Admin\Extensions\ProductData $product_data ) {
$configuration = array();
if ( ! empty( $product_data->title ) ) {
/* translators: the product name */
$configuration['title'] = sprintf( __( 'Get %s Today!', 'easy-digital-downloads' ), $product_data->title );
}
return $configuration;
}
/**
* Adds the email marketing extensions as cards.
*
* @since 2.11.4
* @return void
*/
public function field() {
$this->hide_submit_button();
if ( $this->is_activated() ) {
printf( '<p>%s</p>', esc_html__( 'Looks like you have an email marketing extension installed, but we support more providers!', 'easy-digital-downloads' ) );
}
?>
<div class="edd-extension-manager__card-group">
<?php
foreach ( $this->get_product_data() as $item_id => $extension ) {
$this->do_single_extension_card( $item_id );
}
?>
</div>
<?php
}
/**
* Overrides the body array sent to the Products API.
*
* @since 2.11.4
* @return array
*/
protected function get_api_body() {
return array(
'tag' => 1578,
);
}
/**
* Whether any email marketing extension is active.
*
* @since 2.11.4
*
* @return bool True if any email marketing extension is active.
*/
protected function is_activated() {
foreach ( $this->get_product_data() as $extension ) {
// The data is stored in the database as an array--at this point it has not been converted to an object.
if ( ! empty( $extension['basename'] ) && $this->manager->is_plugin_active( $extension['basename'] ) ) {
return true;
}
}
return false;
}
}
new EmailMarketing();

@ -0,0 +1,124 @@
<?php
/**
* Invoices
*
* Manages automatic installation/activation for Invoices.
*
* @package EDD
* @subpackage Invoices
* @copyright Copyright (c) 2021, Easy Digital Downloads
* @license https://opensource.org/licenses/gpl-2.0.php GNU Public License
* @since 2.11.4
*/
namespace EDD\Admin\Settings;
use \EDD\Admin\Extensions\Extension;
class Invoices extends Extension {
/**
* The product ID on EDD.
*
* @var integer
*/
protected $item_id = 375153;
/**
* The EDD settings tab where this extension should show.
*
* @since 2.11.4
* @var string
*/
protected $settings_tab = 'gateways';
/**
* The settings section for this item.
*
* @since 2.11.5
* @var string
*/
protected $settings_section = 'invoices';
/**
* The pass level required to access this extension.
*/
const PASS_LEVEL = \EDD\Admin\Pass_Manager::EXTENDED_PASS_ID;
public function __construct() {
add_filter( 'edd_settings_sections_gateways', array( $this, 'add_section' ) );
add_action( 'edd_settings_tab_top_gateways_invoices', array( $this, 'settings_field' ) );
add_action( 'edd_settings_tab_top_gateways_invoices', array( $this, 'hide_submit_button' ) );
parent::__construct();
}
/**
* Gets the custom configuration for Invoices.
*
* @since 2.11.4
* @param \EDD\Admin\Extensions\ProductData $product_data The product data object.
* @return array
*/
protected function get_configuration( \EDD\Admin\Extensions\ProductData $product_data ) {
return array(
'style' => 'detailed-2col',
'title' => 'Attractive Invoices For Your Customers',
'description' => $this->get_custom_description(),
'features' => array(
'Generate Attractive Invoices',
'Build Customer Confidence',
'PDF Download Support',
'Include in Purchase Emails',
'Customizable Templates',
),
);
}
/**
* Gets a custom description for the Invoices extension card.
*
* @since 2.11.4
* @return string
*/
private function get_custom_description() {
$description = array(
'Impress customers and build customer loyalty with attractive invoices. Making it easy to locate, save, and print purchase history builds trust with customers.',
'Provide a professional experience with customizable templates and one-click PDF downloads. ',
);
return $this->format_description( $description );
}
/**
* Adds the Invoices Payments section to the settings.
*
* @param array $sections
* @return array
*/
public function add_section( $sections ) {
if ( ! $this->can_show_product_section() ) {
return $sections;
}
$sections[ $this->settings_section ] = __( 'Invoices', 'easy-digital-downloads' );
return $sections;
}
/**
* Whether EDD Invoices active or not.
*
* @since 2.11.4
*
* @return bool True if Invoices is active.
*/
protected function is_activated() {
if ( $this->manager->is_plugin_active( $this->get_product_data() ) ) {
return true;
}
return class_exists( 'EDDInvoices' );
}
}
new Invoices();

@ -0,0 +1,124 @@
<?php
/**
* Recurring Payments
*
* Manages automatic activation for Recurring Payments.
*
* @package EDD
* @subpackage Recurring
* @copyright Copyright (c) 2021, Easy Digital Downloads
* @license https://opensource.org/licenses/gpl-2.0.php GNU Public License
* @since 2.11.4
*/
namespace EDD\Admin\Settings;
use \EDD\Admin\Extensions\Extension;
class Recurring extends Extension {
/**
* The product ID on EDD.
*
* @var integer
*/
protected $item_id = 28530;
/**
* The EDD settings tab where this extension should show.
*
* @since 2.11.4
* @var string
*/
protected $settings_tab = 'gateways';
/**
* The pass level required to access this extension.
*/
const PASS_LEVEL = \EDD\Admin\Pass_Manager::EXTENDED_PASS_ID;
/**
* The settings section for this item.
*
* @since 2.11.5
* @var string
*/
protected $settings_section = 'recurring';
public function __construct() {
add_filter( 'edd_settings_sections_gateways', array( $this, 'add_section' ) );
add_action( 'edd_settings_tab_top_gateways_recurring', array( $this, 'settings_field' ) );
add_action( 'edd_settings_tab_top_gateways_recurring', array( $this, 'hide_submit_button' ) );
parent::__construct();
}
/**
* Gets the custom configuration for Recurring.
*
* @since 2.11.4
* @param \EDD\Admin\Extensions\ProductData $product_data The product data object.
* @return array
*/
protected function get_configuration( \EDD\Admin\Extensions\ProductData $product_data ) {
return array(
'style' => 'detailed-2col',
'title' => 'Increase Revenue By Selling Subscriptions!',
'description' => $this->get_custom_description(),
'features' => array(
'Flexible Recurring Payments',
'Custom Reminder Emails',
'Free Trial Support',
'Signup Fees',
'Recurring Revenue Reports',
),
);
}
/**
* Gets a custom description for the Recurring extension card.
*
* @since 2.11.4
* @return string
*/
private function get_custom_description() {
$description = array(
'Grow stable income by selling subscriptions and make renewals hassle free for your customers.',
'When your customers are automatically billed, you reduce the risk of missed payments and retain more customers.',
);
return $this->format_description( $description );
}
/**
* Adds the Recurring Payments section to the settings.
*
* @param array $sections
* @return array
*/
public function add_section( $sections ) {
if ( ! $this->can_show_product_section() ) {
return $sections;
}
$sections[ $this->settings_section ] = __( 'Recurring Payments', 'easy-digital-downloads' );
return $sections;
}
/**
* Whether EDD Recurring active or not.
*
* @since 2.11.4
*
* @return bool True if Recurring is active.
*/
protected function is_activated() {
if ( $this->manager->is_plugin_active( $this->get_product_data() ) ) {
return true;
}
return class_exists( 'EDD_Recurring' );
}
}
new Recurring();

@ -0,0 +1,152 @@
<?php
/**
* Reviews
*
* Manages automatic activation for Reviews.
*
* @package EDD
* @subpackage Reviews
* @copyright Copyright (c) 2021, Easy Digital Downloads
* @license https://opensource.org/licenses/gpl-2.0.php GNU Public License
* @since 2.11.4
*/
namespace EDD\Admin\Settings;
use \EDD\Admin\Extensions\Extension;
class Reviews extends Extension {
/**
* The product ID on EDD.
*
* @var integer
*/
protected $item_id = 37976;
/**
* The EDD settings tab where this extension should show.
*
* @since 2.11.4
* @var string
*/
protected $settings_tab = 'marketing';
/**
* The settings section for this item.
*
* @since 2.11.5
* @var string
*/
protected $settings_section = 'reviews';
/**
* The pass level required to access this extension.
*/
const PASS_LEVEL = \EDD\Admin\Pass_Manager::EXTENDED_PASS_ID;
public function __construct() {
add_filter( 'edd_settings_sections_marketing', array( $this, 'add_section' ) );
add_action( 'edd_settings_tab_top_marketing_reviews', array( $this, 'settings_field' ) );
add_action( 'edd_settings_tab_top_marketing_reviews', array( $this, 'hide_submit_button' ) );
add_action( 'add_meta_boxes', array( $this, 'maybe_do_metabox' ) );
parent::__construct();
}
/**
* Gets the custom configuration for Reviews.
*
* @since 2.11.4
* @param \EDD\Admin\Extensions\ProductData $product_data The product data object.
* @return array
*/
protected function get_configuration( \EDD\Admin\Extensions\ProductData $product_data ) {
$configuration = array(
'title' => 'Build Trust With Real Customer Reviews',
);
$settings_configuration = array(
'style' => 'detailed-2col',
'description' => $this->get_custom_description(),
'features' => array(
'Request Reviews',
'Incentivize Reviewers',
'Full Schema.org Support',
'Embed Reviews Via Blocks',
'Limit Reviews to Customers',
'Vendor Reviews (with Frontend Submissions)',
),
);
return $this->is_edd_settings_screen() ? array_merge( $configuration, $settings_configuration ) : $configuration;
}
/**
* Gets a custom description for the Reviews extension card.
*
* @since 2.11.4
* @return string
*/
private function get_custom_description() {
$description = array(
'Increase sales on your site with social proof. 70% of online shoppers don\'t purchase before reading reviews.',
'Easily collect, manage, and beautifully display reviews all from your WordPress dashboard.',
);
return $this->format_description( $description );
}
/**
* Adds the Reviews section to the settings.
*
* @param array $sections
* @return array
*/
public function add_section( $sections ) {
if ( ! $this->can_show_product_section() ) {
return $sections;
}
$sections[ $this->settings_section ] = __( 'Reviews', 'easy-digital-downloads' );
return $sections;
}
/**
* If Reviews is not active, registers a metabox on individual download edit screen.
*
* @since 2.11.4
* @return void
*/
public function maybe_do_metabox() {
if ( ! $this->is_download_edit_screen() ) {
return;
}
if ( $this->is_activated() ) {
return;
}
add_meta_box(
'edd-reviews-status',
__( 'Product Reviews', 'easy-digital-downloads' ),
array( $this, 'settings_field' ),
'download',
'side',
'low'
);
}
/**
* Whether EDD Reviews active or not.
*
* @since 2.11.4
*
* @return bool True if Reviews is active.
*/
protected function is_activated() {
if ( $this->manager->is_plugin_active( $this->get_product_data() ) ) {
return true;
}
return function_exists( 'edd_reviews' );
}
}
new Reviews();

@ -0,0 +1,232 @@
<?php
/**
* WP Mail SMTP
*
* Manages automatic installation/activation for WP Mail SMTP.
*
* @package EDD
* @subpackage WP_SMTP
* @copyright Copyright (c) 2021, Easy Digital Downloads
* @license https://opensource.org/licenses/gpl-2.0.php GNU Public License
* @since 2.11.4
*/
namespace EDD\Admin\Settings;
class WP_SMTP {
/**
* Array of configuration data for WP Mail SMTP.
*
* @var array
*/
private $config = array(
'lite_plugin' => 'wp-mail-smtp/wp_mail_smtp.php',
'lite_wporg_url' => 'https://wordpress.org/plugins/wp-mail-smtp/',
'lite_download_url' => 'https://downloads.wordpress.org/plugin/wp-mail-smtp.zip',
'pro_plugin' => 'wp-mail-smtp-pro/wp_mail_smtp.php',
'smtp_settings' => 'admin.php?page=wp-mail-smtp',
'smtp_wizard' => 'admin.php?page=wp-mail-smtp-setup-wizard',
);
/**
* The Extension Manager
*
* @var \EDD\Admin\Extensions\Extension_Manager
*/
private $manager;
public function __construct() {
add_filter( 'edd_settings_emails', array( $this, 'register_setting' ) );
add_action( 'edd_wpsmtp', array( $this, 'settings_field' ) );
$this->manager = new \EDD\Admin\Extensions\Extension_Manager();
}
/**
* Register the setting to show the WP SMTP installer if it isn't active.
*
* @param array $settings
* @return array
*/
public function register_setting( $settings ) {
if ( $this->is_smtp_configured() ) {
return $settings;
}
$settings['main']['wpsmtp'] = array(
'id' => 'wpsmtp',
'name' => __( 'Improve Email Deliverability', 'easy-digital-downloads' ),
'desc' => '',
'type' => 'hook',
);
return $settings;
}
/**
* Output the settings field (installation helper).
*
* @param array $args
* @return void
*/
public function settings_field( $args ) {
$this->manager->enqueue();
?>
<div class="edd-extension-manager__body">
<p class="edd-extension-manager__description">
<?php esc_html_e( 'WP Mail SMTP allows you to easily set up WordPress to use a trusted provider to reliably send emails, including sales notifications.', 'easy-digital-downloads' ); ?>
</p>
<div class="edd-extension-manager__group">
<div class="edd-extension-manager__step">
<?php $this->manager->button( $this->get_button_parameters() ); ?>
</div>
<?php
if ( $this->is_smtp_activated() ) {
return;
}
?>
<div class="edd-extension-manager__step" style="display:none;">
<?php $this->manager->link( $this->get_link_parameters() ); ?>
</div>
</div>
</div>
<?php
}
/**
* Gets the button parameters.
*
* @return array
*/
private function get_button_parameters() {
$button = array();
// If neither the lite nor pro plugin is installed, the button will prompt to install and activate the lite plugin.
if ( ! $this->manager->is_plugin_installed( $this->config['lite_plugin'] ) && ! $this->manager->is_plugin_installed( $this->config['pro_plugin'] ) ) {
$button['plugin'] = $this->config['lite_download_url'];
$button['action'] = 'install';
$button['button_text'] = __( 'Install & Activate WP Mail SMTP', 'easy-digital-downloads' );
} elseif ( ! $this->is_smtp_activated() ) {
// If one of the SMTP plugins is installed, but not activated, the button will prompt to activate it.
$button['plugin'] = $this->config['lite_plugin'];
$button['action'] = 'activate';
$button['button_text'] = __( 'Activate WP Mail SMTP', 'easy-digital-downloads' );
} elseif ( ! $this->is_smtp_configured() ) {
// If the plugin is active, but not configured, the button will send them to the setup wizard.
$button = $this->get_link_parameters();
}
return $button;
}
/**
* Gets the array of parameters for the link to configure WP Mail SMTP.
*
* @since 2.11.4
* @return array
*/
private function get_link_parameters() {
return $this->is_smtp_configured() ?
array(
'button_text' => __( 'Configure WP Mail SMTP', 'easy-digital-downloads' ),
'href' => admin_url( $this->config['smtp_settings'] ),
) :
array(
'button_text' => __( 'Run the WP Mail SMTP Setup Wizard', 'easy-digital-downloads' ),
'href' => admin_url( $this->config['smtp_wizard'] ),
);
}
/**
* Whether WP Mail SMTP plugin configured or not.
*
* @since 2.11.4
*
* @return bool True if some mailer is selected and configured properly.
*/
protected function is_smtp_configured() {
if ( ! $this->is_smtp_activated() || ! class_exists( '\\WPMailSMTP\\Options' ) ) {
return false;
}
$phpmailer = $this->get_phpmailer();
$mailer = \WPMailSMTP\Options::init()->get( 'mail', 'mailer' );
$is_mailer_complete = ! empty( $mailer ) && wp_mail_smtp()->get_providers()->get_mailer( $mailer, $phpmailer )->is_mailer_complete();
return 'mail' !== $mailer && $is_mailer_complete;
}
/**
* Whether WP Mail SMTP plugin active or not.
*
* @since 2.11.4
*
* @return bool True if SMTP plugin is active.
*/
protected function is_smtp_activated() {
return function_exists( 'wp_mail_smtp' ) && ( is_plugin_active( $this->config['lite_plugin'] ) || is_plugin_active( $this->config['pro_plugin'] ) );
}
/**
* Get $phpmailer instance.
*
* @since 2.11.4
*
* @return \PHPMailer|\PHPMailer\PHPMailer\PHPMailer Instance of PHPMailer.
*/
protected function get_phpmailer() {
if ( version_compare( get_bloginfo( 'version' ), '5.5-alpha', '<' ) ) {
$phpmailer = $this->get_phpmailer_v5();
} else {
$phpmailer = $this->get_phpmailer_v6();
}
return $phpmailer;
}
/**
* Get $phpmailer v5 instance.
*
* @since 2.11.4
*
* @return \PHPMailer Instance of PHPMailer.
*/
private function get_phpmailer_v5() {
global $phpmailer;
if ( ! ( $phpmailer instanceof \PHPMailer ) ) {
require_once ABSPATH . WPINC . '/class-phpmailer.php';
require_once ABSPATH . WPINC . '/class-smtp.php';
$phpmailer = new \PHPMailer( true ); // phpcs:ignore WordPress.WP.GlobalVariablesOverride.Prohibited
}
return $phpmailer;
}
/**
* Get $phpmailer v6 instance.
*
* @since 2.11.4
*
* @return \PHPMailer\PHPMailer\PHPMailer Instance of PHPMailer.
*/
private function get_phpmailer_v6() {
global $phpmailer;
if ( ! ( $phpmailer instanceof \PHPMailer\PHPMailer\PHPMailer ) ) {
require_once ABSPATH . WPINC . '/PHPMailer/PHPMailer.php';
require_once ABSPATH . WPINC . '/PHPMailer/SMTP.php';
require_once ABSPATH . WPINC . '/PHPMailer/Exception.php';
$phpmailer = new \PHPMailer\PHPMailer\PHPMailer( true ); // phpcs:ignore WordPress.WP.GlobalVariablesOverride.Prohibited
}
return $phpmailer;
}
}
new WP_SMTP();