Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 2 additions & 5 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -101,16 +101,13 @@ add_action('init', function(){
'menu_slug' => $client->slug . '-manage-license',
'icon_url' => '',
'position' => null,
'parent_slug' => '',
'activated_redirect' => admin_url( 'admin.php?page=my-plugin-page' ), // should you want to redirect on activation of license.
'deactivated_redirect' => admin_url( 'admin.php?page=my-plugin-deactivation-page' ), // should you want to redirect on detactivation of license.
]
);
});
```

Make sure you call this function directly, never use any action hook to call this function.

> For plugins example code that needs to be used on your main plugin file.
> For themes example code that needs to be used on your themes `functions.php` file.

Expand Down Expand Up @@ -148,9 +145,9 @@ $client->set_textdomain( 'your-project-textdomain' );
```

## Example Plugin
[surecart-plugin-license.zip](https://d.pr/f/6ZyfAS)
[surecart-plugin-license.zip](https://d.pr/f/6MPcya)

## Example Theme
[surecart-theme-license.zip](https://d.pr/f/RK8NFS)
[surecart-theme-license.zip](https://d.pr/f/mYc39R)

For full setup and functionality details, see the official documentation: [Licensing Setup and Functionality](https://surecart.com/docs/licensing-setup-and-functionality/).
2 changes: 1 addition & 1 deletion src/Client.php
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ class Client {
*
* @var string
*/
public $version = '1.2.1';
public $version = '1.2.2';

/**
* Name of the plugin
Expand Down
33 changes: 26 additions & 7 deletions src/License.php
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,9 @@ public function retrieve( $license_key ) {
* @throws \Exception If something goes wrong.
*/
public function activate( $key = '' ) {
$settings = $this->client->settings();
$previous = $settings->get_options(); // restored if this attempt fails.
$activation_id = '';
try {
// validate the license and store it.
$license = $this->validate( $key, true );
Expand All @@ -65,21 +68,30 @@ public function activate( $key = '' ) {
if ( is_wp_error( $activation ) ) {
throw new \Exception( $activation->get_error_message() );
}
$this->client->settings()->activation_id = $activation->id;
$activation_id = $activation->id;
$settings->activation_id = $activation_id;
// validate the release.
$this->validate_release();
} catch ( \Exception $e ) {
// undo activation.
$activation = $this->client->activation()->get();
if ( $activation ) {
$this->client->activation()->delete();
// undo the activation this attempt created.
$undone = $activation_id ? $this->client->activation()->delete( $activation_id ) : true;
if ( is_wp_error( $undone ) && 'not_found' !== $undone->get_error_code() ) {
// keep only its id, so Deactivate License can remove it.
$settings->clear_options();
$settings->activation_id = $activation_id;
$this->client->updater()->clear_cache();
return new \WP_Error( 'error', $e->getMessage() . ' ' . $this->client->__( 'The activation could not be undone. Click Deactivate License to remove it.' ) );
}
// on error, clear options.
$this->client->settings()->clear_options();

// restore the previous options, so a failed or interrupted request never loses a saved key.
$settings->set_options( $previous );

// return \WP_Error.
return new \WP_Error( 'error', $e->getMessage() );
}

$this->client->updater()->clear_cache();

return true;
}

Expand All @@ -101,12 +113,14 @@ public function deactivate( $activation_id = '' ) {
// it has been deleted remotely.
if ( 'not_found' === $deactivated->get_error_code() ) {
$this->client->settings()->clear_options();
$this->client->updater()->clear_cache();
return true;
}
return $deactivated;
}

$this->client->settings()->clear_options();
$this->client->updater()->clear_cache();
return true;
}

Expand Down Expand Up @@ -148,6 +162,11 @@ public function get_current_release( $expires_in = 900 ) {
* @throws \Exception If the license is not valid.
*/
public function validate( $key, $store = false ) {
// without a key, the request would hit the licenses collection.
if ( '' === trim( (string) $key ) ) {
throw new \Exception( $this->client->__( 'Please enter a license key.' ) );
}

// get license.
$license = $this->retrieve( sanitize_text_field( $key ) );
if ( is_wp_error( $license ) ) {
Expand Down
41 changes: 26 additions & 15 deletions src/Settings.php
Original file line number Diff line number Diff line change
Expand Up @@ -165,13 +165,24 @@ public function get_options() {
return (array) get_option( $this->option_key, array() );
}

/**
* Replace all options.
*
* @param array $options The options.
*
* @return bool
*/
public function set_options( $options ) {
return update_option( $this->option_key, (array) $options );
}

/**
* Clear out the options.
*
* @return bool
*/
public function clear_options() {
return update_option( $this->option_key, array() );
return $this->set_options( array() );
}

/**
Expand Down Expand Up @@ -222,27 +233,20 @@ public function settings_output() {
<form method="post" action="<?php echo esc_attr( $this->form_action_url() ); ?>">
<input type="hidden" name="_action" value="<?php echo esc_attr( $action ); ?>">
<input type="hidden" name="_nonce" value="<?php echo esc_attr( wp_create_nonce( $this->client->name ) ); ?>">
<input type="hidden" name="activation_id" value="<?php echo esc_attr( $this->activation_id ); ?>">

<h2><?php echo esc_html( $this->menu_args['page_title'] ); ?></h2>
<label for="license_key">
<?php if ( 'activate' === $action ) : ?>
<?php if ( 'activate' === $action ) : ?>
<?php echo esc_html( sprintf( $this->client->__( 'Enter your license key to activate %s.', 'surecart' ), $this->client->name ) ); ?>
<?php elseif ( ! $this->license_key ) : ?>
<?php echo esc_html( $this->client->__( 'The last activation attempt failed and could not be undone. Click Deactivate License to remove it.' ) ); ?>
<?php else : ?>
<?php echo esc_html( sprintf( $this->client->__( 'Your license is succesfully activated for this site.', 'surecart' ), $this->client->name ) ); ?>
<?php endif; ?>
</label>

<?php if ( 'activate' === $action ) : ?>
<input class="widefat" type="password" autocomplete="off" name="license_key" id="license_key" value="<?php echo esc_attr( $this->license_key ); ?>" autofocus>
<?php endif; ?>

<?php if ( isset( $_GET['debug'] ) ) : // phpcs:ignore ?>
<label for="license_id"><?php echo esc_html( sprintf( $this->client->__( 'License ID', 'surecart' ), $this->client->name ) ); ?></label>
<input class="widefat" type="text" autocomplete="off" name="license_id" id="license_id" value="<?php echo esc_attr( $this->license_id ); ?>" autofocus>

<label for="activation_id"><?php echo esc_html( sprintf( $this->client->__( 'Activation ID', 'surecart' ), $this->client->name ) ); ?></label>
<input class="widefat" type="text" autocomplete="off" name="activation_id" id="activation_id" value="<?php echo esc_attr( $this->activation_id ); ?>" autofocus>
<input class="widefat" type="password" autocomplete="off" name="license_key" id="license_key" value="" placeholder="<?php echo $this->license_key ? esc_attr( $this->client->__( 'Leave blank to use the saved key' ) ) : ''; ?>" autofocus>
<?php endif; ?>

<?php submit_button( 'activate' === $action ? $this->client->__( 'Activate License' ) : $this->client->__( 'Deactivate License' ) ); ?>
Expand Down Expand Up @@ -345,7 +349,12 @@ public function license_form_submit() {

// handle activation.
if ( 'activate' === $_POST['_action'] ) {
$activated = $this->client->license()->activate( sanitize_text_field( $_POST['license_key'] ) );
$license_key = isset( $_POST['license_key'] ) ? sanitize_text_field( wp_unslash( $_POST['license_key'] ) ) : '';
// the form doesn't print the stored key, so an empty field reuses it.
if ( '' === $license_key ) {
$license_key = (string) $this->license_key;
}
$activated = $this->client->license()->activate( $license_key );
if ( is_wp_error( $activated ) ) {
$this->add_error( $activated->get_error_code(), $activated->get_error_message() );
return;
Expand All @@ -361,9 +370,11 @@ public function license_form_submit() {

// handle deactivation.
if ( 'deactivate' === $_POST['_action'] ) {
$deactivated = $this->client->license()->deactivate( sanitize_text_field( $_POST['activation_id'] ) );
// deactivate the stored activation, never one the form posts.
$deactivated = $this->client->license()->deactivate();
if ( is_wp_error( $deactivated ) ) {
$this->add_error( $deactivated->get_error_code(), $deactivated->get_error_message() );
return;
}

if ( ! empty( $this->menu_args['deactivated_redirect'] ) ) {
Expand All @@ -387,7 +398,7 @@ public function redirect( $url ) {
?>
<div class="spinner is-active"></div>
<script>
window.location.assign("<?php echo esc_url( $url ); ?>");
window.location.assign(<?php echo wp_json_encode( esc_url_raw( $url ) ); ?>);
</script>
<?php
}
Expand Down
11 changes: 11 additions & 0 deletions src/Updater.php
Original file line number Diff line number Diff line change
Expand Up @@ -130,6 +130,17 @@ private function set_cached_version_info( $value ) {
set_transient( $this->cache_key, $value, 3 * HOUR_IN_SECONDS );
}

/**
* Clear the cached version info and WordPress' update data, which hold the package link.
* Call it when the license changes.
*
* @return void
*/
public function clear_cache() {
delete_transient( $this->cache_key );
delete_site_transient( 'theme' === $this->client->type ? 'update_themes' : 'update_plugins' );
}

/**
* Get plugin info from SureCart\Licensing
*/
Expand Down
Loading
Loading