plugin install

This commit is contained in:
Tony Volpe
2024-06-18 17:29:05 -04:00
parent e1aaedd1ae
commit 41f50eacc4
5880 changed files with 1057631 additions and 39681 deletions

View File

@@ -0,0 +1,220 @@
<?php
namespace Gravity_Forms\Gravity_Forms\License;
use GFCommon;
use WP_Error;
use Gravity_Forms\Gravity_Forms\External_API\GF_API_Connector;
use Gravity_Forms\Gravity_Forms\External_API\GF_API_Response;
use Gravity_Forms\Gravity_Forms\External_API\GF_API_Response_Factory;
/**
* Class GF_License_API_Connector
*
* Connector providing methods to communicate with the License API.
*
* @since 2.5.11
*
* @package Gravity_Forms\Gravity_Forms\License
*/
class GF_License_API_Connector extends GF_API_Connector {
/**
* @var \Gravity_Api $strategy
*/
protected $strategy;
/**
* @var \GFCache $cache
*/
protected $cache;
/**
* @var GF_API_Response_Factory $response_factory
*/
protected $response_factory;
public function __construct( $strategy, $cache, GF_API_Response_Factory $response_factory ) {
$this->response_factory = $response_factory;
parent::__construct( $strategy, $cache );
}
/**
* Check if cache debug is enabled.
*
* @since 2.5.11
*
* @return bool
*/
public function is_debug() {
return defined( 'GF_CACHE_DEBUG' ) && GF_CACHE_DEBUG;
}
/**
* If the site was registered with the legacy process.
*
* @since 2.5.11
*
* @return bool
*/
public function is_legacy_registration() {
return $this->strategy->is_legacy_registration();
}
/**
* Clear the cache for a given key.
*
* @since 2.5.11
*
* @param string $key
*/
public function clear_cache_for_key( $key ) {
$this->cache->delete( 'rg_gforms_license_info_' . $key );
}
/**
* Get the license info.
*
* @since 2.5.11
*
* @param string $key
* @param bool $cache
*
* @return GF_API_Response
*/
public function check_license( $key = false, $cache = true ) {
$license_info = false;
$key = $key ? trim( $key ) : $this->strategy->get_key();
$license_info_data = $this->cache->get( 'rg_gforms_license_info_' . $key );
if ( $this->is_debug() ) {
$cache = false;
}
if ( $license_info_data && $cache ) {
$license_info = GFCommon::safe_unserialize( $license_info_data, GF_API_Response::class );
if ( $license_info ) {
return $license_info;
} else {
$this->clear_cache_for_key( $key );
}
}
$license_info = $this->response_factory->create(
$this->strategy->check_license( $key ),
false
);
if ( $license_info->can_be_used() ) {
$this->cache->set( 'rg_gforms_license_info_' . $key, serialize( $license_info ), true, DAY_IN_SECONDS );
}
return $license_info;
}
/**
* Check if the saved license key is valid.
*
* @since 2.5.11
*
* @return true|WP_Error
*/
public function is_valid_license() {
$license_info = $this->check_license();
return $license_info->is_valid();
}
/**
* Registers a site to the specified key, or if $new_key is blank, unlinks a key from an existing site.
* Requires that the $new_key is saved in options before calling this function
*
* @since 2.5.11 Implement the license enforcement process.
*
* @param string $new_key Unhashed Gravity Forms license key.
*
* @return GF_License_API_Response
*/
public function update_site_registration( $new_key, $is_md5 = false ) {
// Get new license key information.
$version_info = GFCommon::get_version_info( false );
if ( $version_info['is_valid_key'] ) {
$data = $this->strategy->check_license( $new_key );
$result = $this->response_factory->create( $data );
} else {
// Invalid key, do not change site registration.
$error = new WP_Error( GF_License_Statuses::INVALID_LICENSE_KEY, GF_License_Statuses::get_message_for_code( GF_License_Statuses::INVALID_LICENSE_KEY ) );
GFCommon::log_error( 'Invalid license. Site cannot be registered' );
$result = $this->response_factory->create( $error );
}
if ( ! $result->can_be_used() ) {
GFCommon::log_error( 'Failed to update site registration with Gravity Manager. ' . print_r( $result->get_error_message(), true ) );
}
return $result;
}
/**
* Purge site credentials if the license info contains certain errors.
*
* @since 2.5.11
*
* @return void
*/
public function maybe_purge_site_credentials() {
// Check if the license info contains the revoke site error.
$license_info = $this->check_license();
$errors = array(
'gravityapi_site_revoked',
'gravityapi_fail_authentication',
'gravityapi_site_url_changed',
);
if ( is_wp_error( $license_info ) && in_array( $license_info->get_error_code(), $errors, true ) ) {
GFCommon::log_debug( __METHOD__ . '(): purging the site credentials because of the following license error: ' . $license_info->get_error_message() );
// Purge site data to ensure we can get a fresh start.
$this->strategy->purge_site_credentials();
}
}
/**
* Retrieve a list of plugins from the API.
*
* @since 2.5.11
*
* @param bool $cache Whether to respect the cached data.
*
* @return mixed
*/
public function get_plugins( $cache = true ) {
$plugins = $this->cache->get( 'rg_gforms_plugins', $found_in_cache );
if ( $this->is_debug() ) {
$cache = false;
}
if ( $found_in_cache && $cache ) {
return $plugins;
}
$plugins = $this->strategy->get_plugins_info();
$this->cache->set( 'rg_gforms_plugins', $plugins, true, DAY_IN_SECONDS );
return $plugins;
}
}

View File

@@ -0,0 +1,47 @@
<?php
namespace Gravity_Forms\Gravity_Forms\License;
use Gravity_Forms\Gravity_Forms\External_API\GF_API_Response_Factory;
/**
* Class GF_License_API_Response_Factory
*
* Concrete response factory used to return a License API Response
*
* @since 2.5.11
*
* @package Gravity_Forms\Gravity_Forms\License
*/
class GF_License_API_Response_Factory implements GF_API_Response_Factory {
private $transient_strategy;
/**
* GF_License_API_Response_Factory constructor
*
* @since 2.5.11
*
* @param $transient_strategy
*/
public function __construct( $transient_strategy ) {
$this->transient_strategy = $transient_strategy;
}
/**
* Create a new License API Response from the given data.
*
* @since 2.5.11
*
* @param mixed ...$args
*
* @return GF_License_API_Response
*/
public function create( ...$args ) {
$data = $args[0];
$validate = isset( $args[1] ) ? $args[1] : true;
return new GF_License_API_Response( $data, $validate, $this->transient_strategy );
}
}

View File

@@ -0,0 +1,381 @@
<?php
namespace Gravity_Forms\Gravity_Forms\License;
use Gravity_Forms\Gravity_Forms\External_API\GF_API_Response;
use Gravity_Forms\Gravity_Forms\Transients\GF_Transient_Strategy;
/**
* Class GF_License_API_Response
*
* Concrete Response class for the GF License API.
*
* @since 2.5.11
*
* @package Gravity_Forms\Gravity_Forms\License
*/
class GF_License_API_Response extends GF_API_Response {
/**
* @var GF_Transient_Strategy
*/
private $transient_strategy;
/**
* GF_License_API_Response constructor.
*
* @since 2.5.11
*
* @param mixed $data The data from the API connector.
* @param bool $validate Whether to validate the data passed.
* @param GF_Transient_Strategy $transient_strategy The Transient Strategy used to store things in transients.
*/
public function __construct( $data, $validate, GF_Transient_Strategy $transient_strategy ) {
$this->transient_strategy = $transient_strategy;
// Data is a wp_error, parse it to get the correct code and message.
if ( is_wp_error( $data ) ) {
/**
* @var \WP_Error $data
*/
if ( $data->get_error_code() == 'rest_invalid_param' ) {
$this->set_status( GF_License_Statuses::INVALID_LICENSE_KEY );
$this->add_error( __( 'The license is invalid.', 'gravityforms' ) );
} else {
$this->set_status( $data->get_error_code() );
$this->add_error( $data->get_error_message() );
}
if ( empty( $data->get_error_data() ) ) {
return;
}
$error_data = $data->get_error_data();
if ( rgar( $error_data, 'license' ) ) {
$error_data = rgar( $error_data, 'license' );
}
$this->add_data_item( $error_data );
return;
}
// Data is somehow broken; set a status for Invalid license keys and bail.
if ( ! is_array( $data ) ) {
$this->set_status( GF_License_Statuses::INVALID_LICENSE_KEY );
$this->add_error( GF_License_Statuses::get_message_for_code( GF_License_Statuses::INVALID_LICENSE_KEY ) );
return;
}
// Set is_valid to true since we are bypassing validation.
if ( ! $validate ) {
$data['is_valid'] = true;
}
// Data is formatted properly, but the `is_valid` param is false. Return an invalid license key error.
if ( isset( $data['is_valid'] ) && ! $data['is_valid'] ) {
$this->set_status( GF_License_Statuses::INVALID_LICENSE_KEY );
$this->add_error( GF_License_Statuses::get_message_for_code( GF_License_Statuses::INVALID_LICENSE_KEY ) );
return;
}
// Finally, the data is correct, so store it and set our status to valid.
$this->add_data_item( $data );
$this->set_status( GF_License_Statuses::VALID_KEY );
}
/**
* Get the stored error for this site license.
*
* @since 2.5.11
*
* @return \WP_Error|false
*/
private function get_stored_error() {
return $this->transient_strategy->get( 'rg_gforms_registration_error' );
}
/**
* Whether this license key is valid.
*
* @since 2.5.11
*
* @return bool
*/
public function is_valid() {
if ( empty( $this->data ) || $this->get_status() === GF_License_Statuses::NO_DATA ) {
return false;
}
if ( ! $this->has_errors() ) {
return (bool) $this->get_data_value( 'is_valid' );
}
return $this->get_status() !== GF_License_Statuses::INVALID_LICENSE_KEY;
}
/**
* Get the error message for the response, either the first one by default, or at a specific index.
*
* @since 2.5.11
*
* @param int $index The array index to use if mulitple errors exist.
*
* @return mixed|string
*/
public function get_error_message( $index = 0 ) {
if ( ! $this->has_errors() ) {
return '';
}
return $this->errors[ $index ];
}
/**
* Get the human-readable display status for the response.
*
* @since 2.5.11
*
* @return string|void
*/
public function get_display_status() {
if ( $this->max_seats_exceeded() ) {
return __( 'Sites Exceeded', 'gravityforms' );
}
switch ( $this->get_status() ) {
case GF_License_Statuses::INVALID_LICENSE_KEY:
return __( 'Invalid', 'gravityforms' );
case GF_License_Statuses::EXPIRED_LICENSE_KEY:
return __( 'Expired', 'gravityforms' );
case GF_License_Statuses::VALID_KEY:
default:
return __( 'Active', 'gravityforms' );
}
}
/**
* Licenses can be valid and usable, technically-invalid but still usable, or invalid and unusable.
* This will return the correct usability value for this license key.
*
* @since 2.5.11
*
* @return string
*/
public function get_usability() {
if ( $this->get_status() === GF_License_Statuses::VALID_KEY || $this->get_status() === GF_License_Statuses::NO_DATA ) {
return GF_License_Statuses::USABILITY_VALID;
}
if ( $this->get_status() === GF_License_Statuses::INVALID_LICENSE_KEY || $this->get_status() === GF_License_Statuses::SITE_REVOKED ) {
return GF_License_Statuses::USABILITY_NOT_ALLOWED;
}
return GF_License_Statuses::USABILITY_ALLOWED;
}
//----------------------------------------
//---------- Helpers/Utils ---------------
//----------------------------------------
/**
* Whether this response has any errors stored as a transient.
*
* @since 2.5.11
*
* @return bool
*/
private function has_stored_error() {
return (bool) $this->get_stored_error();
}
/**
* Get a properly-formatted link to the Upgrade page for this license key.
*
* @since 2.5.11
*
* @return string
*/
public function get_upgrade_link() {
$key = $this->get_data_value( 'license_key_md5' );
$type = $this->get_data_value( 'product_code' );
return sprintf( 'https://www.gravityforms.com/my-account/licenses/?action=upgrade&license_key=%s&license_code=%s&utm_source=gf-admin&utm_medium=upgrade-button&utm_campaign=license-enforcement', $key, $type );
}
/**
* Get the CTA information for this license key, if applicable.
*
* @since 2.5.11
*
* @return mixed
*/
public function get_cta() {
if ( $this->get_status() == GF_License_Statuses::EXPIRED_LICENSE_KEY ) {
return array(
'type' => 'button',
'label' => __( 'Manage', 'gravityforms' ),
'link' => 'https://www.gravityforms.com/my-account/licenses/?utm_source=gf-admin&utm_medium=manage-button&utm_campaign=license-enforcement',
'class' => 'cog',
);
} elseif ( $this->max_seats_exceeded() ) {
return array(
'type' => 'button',
'label' => __( 'Upgrade', 'gravityforms' ),
'link' => $this->get_upgrade_link(),
'class' => 'product',
);
} else if ( $this->has_expiration() ) {
return array(
'type' => 'text',
'content' => $this->get_data_value( 'days_to_expire' ),
);
} else {
return array(
'type' => 'blank',
);
}
}
/**
* Some statuses are invalid, but get treated as usable. This determines if they should be displayed as
* though they are valid.
*
* @since 2.5.11
*
* @return bool
*/
public function display_as_valid() {
if ( $this->max_seats_exceeded() ) {
return false;
}
switch ( $this->get_status() ) {
case GF_License_Statuses::INVALID_LICENSE_KEY:
case GF_License_Statuses::EXPIRED_LICENSE_KEY:
return false;
case GF_License_Statuses::VALID_KEY:
default:
return true;
}
}
/**
* Whether the license key can be used.
*
* @since 2.5.11
*
* @return bool
*/
public function can_be_used() {
return $this->get_usability() !== GF_License_Statuses::USABILITY_NOT_ALLOWED;
}
/**
* Determine if the contained License Key has an expiration date.
*
* @since 2.5.11
*
* @return bool
*/
public function has_expiration() {
return $this->get_data_value( 'date_expires' ) && ! $this->get_data_value( 'renewal_date' ) && ! $this->get_data_value( 'is_perpetual' );
}
/**
* Get the text for the renewal message.
*
* @since 2.5.11
*
* @return string
*/
public function renewal_text() {
if ( $this->get_status() === GF_License_Statuses::EXPIRED_LICENSE_KEY ) {
return __( 'Expired On', 'gravityforms' );
}
$has_subscription = (bool) $this->get_data_value( 'renewal_date' );
$cancelled = (bool) $this->get_data_value( 'is_subscription_canceled' );
if ( $has_subscription && ! $cancelled ) {
return __( 'Renews On', 'gravityforms' );
}
return __( 'Expires On', 'gravityforms' );
}
/**
* Returns the license renewal or expiry date or the doesn't expire message.
*
* @since 2.6.2
*
* @return string|void
*/
public function renewal_date() {
if ( $this->get_data_value( 'is_perpetual' ) ) {
return __( 'Does not expire', 'gravityforms' );
}
$date = $this->get_data_value( 'renewal_date' );
if ( empty( $date ) ) {
$date = $this->get_data_value( 'date_expires' );
}
return gmdate( 'M d, Y', strtotime( $date ) );
}
/**
* Whether the license has max seats exceeded.
*
* @since 2.5.11
*
* @return bool
*/
public function max_seats_exceeded() {
return $this->get_status() === GF_License_Statuses::MAX_SITES_EXCEEDED || $this->get_data_value( 'remaining_seats' ) < 0;
}
//----------------------------------------
//---------- Serialization ---------------
//----------------------------------------
/**
* Prepares the object for serializing.
*
* @since 2.6.2
*
* @return array
*/
public function __serialize() {
return array(
'data' => $this->data,
'errors' => $this->errors,
'status' => $this->status,
'meta' => $this->meta,
'strat' => $this->transient_strategy,
);
}
/**
* Hydrates the object when unserializing.
*
* @since 2.6.2
*
* @param array $data The unserialized data.
*
* @return void
*/
public function __unserialize( $data ) {
$this->data = $data['data'];
$this->errors = $data['errors'];
$this->status = $data['status'];
$this->meta = $data['meta'];
$this->transient_strategy = $data['strat'];
}
}

View File

@@ -0,0 +1,52 @@
<?php
namespace Gravity_Forms\Gravity_Forms\License;
use Gravity_Forms\Gravity_Forms\External_API\GF_API_Debug;
use Gravity_Forms\Gravity_Forms\GF_Service_Container;
use Gravity_Forms\Gravity_Forms\GF_Service_Provider;
use Gravity_Forms\Gravity_Forms\Transients\GF_WP_Transient_Strategy;
use Gravity_Forms\Gravity_Forms\Util\GF_Util_Service_Provider;
/**
* Class GF_License_Service_Provider
*
* Service provider for the License Service.
*
* @package Gravity_Forms\Gravity_Forms\License
*/
class GF_License_Service_Provider extends GF_Service_Provider {
const GRAVITY_API = 'gravity_api';
const RESPONSE_FACTORY = 'gf_license_response_factory';
const LICENSE_API_CONNECTOR = 'license_api_connector';
/**
* Register the various classes for this service.
*
* @since 2.5.11
*
* @param GF_Service_Container $container
*/
public function register( GF_Service_Container $container ) {
\GFForms::include_gravity_api();
require_once( plugin_dir_path( __FILE__ ) . 'class-gf-license-api-connector.php' );
require_once( plugin_dir_path( __FILE__ ) . 'class-gf-license-api-connector.php' );
require_once( plugin_dir_path( __FILE__ ) . 'class-gf-license-statuses.php' );
require_once( plugin_dir_path( __FILE__ ) . 'class-gf-license-api-response.php' );
require_once( plugin_dir_path( __FILE__ ) . 'class-gf-license-api-response-factory.php' );
$container->add( self::GRAVITY_API, function () {
return \Gravity_Api::get_instance();
} );
$container->add( self::RESPONSE_FACTORY, function () use ( $container ) {
return new GF_License_API_Response_Factory( $container->get( GF_Util_Service_Provider::TRANSIENT_STRAT ) );
} );
$container->add( self::LICENSE_API_CONNECTOR, function () use ( $container ) {
return new GF_License_API_Connector( $container->get( self::GRAVITY_API ), $container->get( GF_Util_Service_Provider::GF_CACHE ), $container->get( self::RESPONSE_FACTORY ) );
} );
}
}

View File

@@ -0,0 +1,70 @@
<?php
namespace Gravity_Forms\Gravity_Forms\License;
/**
* Class GF_License_Statuses
*
* Helper class to provide license statuse codes and messages. Should not be instantiated, but used statically.
*
* @since 2.5.11
*
* @package Gravity_Forms\Gravity_Forms\License
*/
class GF_License_Statuses {
const VALID_KEY = 'valid_key';
const SITE_UNREGISTERED = 'site_unregistered';
const INVALID_LICENSE_KEY = 'gravityapi_invalid_license';
const EXPIRED_LICENSE_KEY = 'gravityapi_expired_license';
const SITE_REVOKED = 'gravityapi_site_revoked';
const URL_CHANGED = 'gravityapi_site_url_changed';
const MAX_SITES_EXCEEDED = 'gravityapi_exceeds_number_of_sites';
const MULTISITE_NOT_ALLOWED = 'gravityapi_multisite_not_allowed';
const NO_DATA = 'rest_no_route';
const USABILITY_VALID = 'success';
const USABILITY_ALLOWED = 'warning';
const USABILITY_NOT_ALLOWED = 'error';
/**
* Get the correct Message for the given code.
*
* @since 2.5.11
*
* @param $code
*
* @return mixed|string|void
*/
public static function get_message_for_code( $code ) {
$general_invalid_message = sprintf(
/* translators: %1s and %2s are link tag markup */
__( 'The license key entered is incorrect; please visit the %1$sGravity Forms website%2$s to verify your license.', 'gravityforms' ),
'<a href="https://www.gravityforms.com/my-account/licenses/?utm_source=gf-admin&utm_medium=purchase-link&utm_campaign=license-enforcement" target="_blank">',
'</a>'
);
$map = array(
self::VALID_KEY => __( 'Your license key has been successfully validated.', 'gravityforms' ),
self::SITE_REVOKED => sprintf(
/* translators: %1s and %2s are link tag markup */
__( 'The license key entered has been revoked; please check its status in your %1$sGravity Forms account.%2$s', 'gravityforms' ),
'<a href="https://www.gravityforms.com/my-account/licenses/?utm_source=gf-admin&utm_medium=account-link-revoked&utm_campaign=license-enforcement" target="_blank">',
'</a>'
),
self::MAX_SITES_EXCEEDED => __( 'This license key has already been activated on its maximum number of sites; please upgrade your license.', 'gravityforms' ),
self::MULTISITE_NOT_ALLOWED => __( 'This license key does not support multisite installations. Please use a different license.', 'gravityforms' ),
self::EXPIRED_LICENSE_KEY => sprintf(
/* translators: %1s and %2s are link tag markup */
__( 'This license key has expired; please visit your %1$sGravity Forms account%2$s to manage your license.', 'gravityforms' ),
'<a href="https://www.gravityforms.com/my-account/licenses/?utm_source=gf-admin&utm_medium=account-link-expired&utm_campaign=license-enforcement" target="_blank">',
'</a>'
),
self::SITE_UNREGISTERED => $general_invalid_message,
self::INVALID_LICENSE_KEY => $general_invalid_message,
self::URL_CHANGED => $general_invalid_message,
);
return isset( $map[ $code ] ) ? $map[ $code ] : $general_invalid_message;
}
}