Skip to content

Commit

Permalink
Merge pull request #279 from ConvertKit/review-request
Browse files Browse the repository at this point in the history
Review Request Notification
  • Loading branch information
n7studios authored Feb 14, 2022
2 parents 3880ad5 + dac33bf commit aa280fe
Show file tree
Hide file tree
Showing 11 changed files with 567 additions and 6 deletions.
4 changes: 2 additions & 2 deletions .github/workflows/test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -214,11 +214,11 @@ jobs:
uses: actions/upload-artifact@v2
with:
name: test-results
path: /home/runner/work/convertkit-wordpress/convertkit-wordpress/wordpress/wp-content/plugins/convertkit/tests/_output/
path: ${{ env.PLUGIN_DIR }}/tests/_output/

- name: Upload Plugin Log File to Artifact
if: always()
uses: actions/upload-artifact@v2
with:
name: log
path: /home/runner/work/convertkit-wordpress/convertkit-wordpress/wordpress/wp-content/plugins/convertkit/log.txt
path: ${{ env.PLUGIN_DIR }}/log.txt
4 changes: 2 additions & 2 deletions .scripts/read-actions-filters.php
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ public function run( $folders, $extract_filters = true, $extract_actions = true,

// Check the target folder exists
if ( ! is_dir( $folder ) ) {
return false;
continue;
}

// Iterate through the folder and subfolders, finding any PHP files
Expand All @@ -61,7 +61,7 @@ public function run( $folders, $extract_filters = true, $extract_actions = true,
}

}

// Check if any PHP files were found
if ( count( $php_files ) == 0 ) {
return false;
Expand Down
10 changes: 9 additions & 1 deletion admin/class-convertkit-admin-post.php
Original file line number Diff line number Diff line change
Expand Up @@ -172,7 +172,15 @@ public function save_post_meta( $post_id ) {

// Save metadata.
$convertkit_post = new ConvertKit_Post( $post_id );
return $convertkit_post->save( $meta );
$convertkit_post->save( $meta );

// If a Form or Landing Page was specified, request a review.
// This can safely be called multiple times, as the review request
// class will ensure once a review request is dismissed by the user,
// it is never displayed again.
if ( $meta['form'] || $meta['landing_page'] ) {
WP_ConvertKit()->get_class( 'review_request' )->request_review();
}

}

Expand Down
9 changes: 9 additions & 0 deletions admin/section/class-convertkit-settings-base.php
Original file line number Diff line number Diff line change
Expand Up @@ -316,6 +316,15 @@ private function get_description( $description ) {
*/
public function sanitize_settings( $settings ) {

// If a Form or Landing Page was specified, request a review.
// This can safely be called multiple times, as the review request
// class will ensure once a review request is dismissed by the user,
// it is never displayed again.
if ( ( isset( $settings['page_form'] ) && $settings['page_form'] ) ||
( isset( $settings['post_form'] ) && $settings['post_form'] ) ) {
WP_ConvertKit()->get_class( 'review_request' )->request_review();
}

return wp_parse_args( $settings, $this->settings->get_defaults() );

}
Expand Down
207 changes: 207 additions & 0 deletions includes/class-convertkit-review-request.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,207 @@
<?php
/**
* ConvertKit Review Request class.
*
* @package ConvertKit
* @author ConvertKit
*/

/**
* Displays a one time review request notification in the WordPress
* Administration interface.
*
* @package ConvertKit
* @author ConvertKit
*/
class ConvertKit_Review_Request {

/**
* Holds the Plugin name.
*
* @since 1.9.6.7
*
* @var string
*/
private $plugin_name;

/**
* Holds the Plugin slug.
*
* @since 1.9.6.7
*
* @var string
*/
private $plugin_slug;

/**
* Holds the number of days after the Plugin requests a review to then
* display the review notification in WordPress' Administration interface.
*
* @since 1.9.6.7
*
* @var int
*/
private $number_of_days_in_future = 3;

/**
* Registers action and filter hooks.
*
* @since 1.9.6.7
*
* @param string $plugin_name Plugin Name (e.g. ConvertKit).
* @param string $plugin_slug Plugin Slug (e.g. convertkit).
*/
public function __construct( $plugin_name, $plugin_slug ) {

// Store the Plugin Name and Slug in the class.
$this->plugin_name = $plugin_name;
$this->plugin_slug = $plugin_slug;

// Register an AJAX action to dismiss the review.
add_action( 'wp_ajax_' . $this->plugin_slug . '_dismiss_review', array( $this, 'dismiss_review' ) );

// Maybe display a review request in the WordPress Admin notices.
add_action( 'admin_notices', array( $this, 'maybe_display_review_request' ) );

}

/**
* Displays a dismissible WordPress Administration notice requesting a review, if requested
* by the main Plugin and the Review Request hasn't been disabled.
*
* @since 1.9.6.7
*/
public function maybe_display_review_request() {

// If we're not an Admin user, bail.
if ( ! function_exists( 'current_user_can' ) ) {
return;
}
if ( ! current_user_can( 'activate_plugins' ) ) {
return;
}

// Don't display a review request on multisite. This is so that existing Plugin
// users who existed prior to this feature don't get bombarded with the same
// notification across 100+ of their sites on a multisite network.
if ( is_multisite() ) {
return;
}

// If the review request was dismissed by the user, bail.
if ( $this->dismissed_review() ) {
return;
}

// If no review request has been set by the plugin, bail.
if ( ! $this->requested_review() ) {
return;
}

// If here, display the request for a review.
include_once CONVERTKIT_PLUGIN_PATH . '/views/backend/review/notice.php';

}

/**
* Sets a flag in the options table requesting a review notification be displayed
* in the WordPress Administration.
*
* @since 1.9.6.7
*/
public function request_review() {

// If a review has already been requested, bail.
$time = get_option( $this->plugin_slug . '-review-request' );
if ( ! empty( $time ) ) {
return;
}

// Request a review notification to be displayed beginning at a future timestamp.
update_option( $this->plugin_slug . '-review-request', time() + ( $this->number_of_days_in_future * DAY_IN_SECONDS ) );

}

/**
* Flag to indicate whether a review has been requested by the Plugin,
* and the minimum time has passed between the Plugin requesting a review
* and now.
*
* @since 1.9.6.7
*
* @return bool Review Requested
*/
public function requested_review() {

// Bail if no review was requested by the Plugin.
$start_displaying_review_at = get_option( $this->plugin_slug . '-review-request' );
if ( empty( $start_displaying_review_at ) ) {
return false;
}

// Bail if a review was requested by the Plugin, but it's too early to display it.
if ( $start_displaying_review_at > time() ) {
return false;
}

// The Plugin requested a review and it's time to display the notification.
return true;

}

/**
* Dismisses the review notification, so it isn't displayed again.
*
* @since 1.9.6.7
*/
public function dismiss_review() {

update_option( $this->plugin_slug . '-review-dismissed', 1 );

// Send success response if called via AJAX.
if ( defined( 'DOING_AJAX' ) && DOING_AJAX ) {
wp_send_json_success( 1 );
}

}

/**
* Flag to indicate whether a review request has been dismissed by the user.
*
* @since 1.9.6.7
*
* @return bool Review Dismissed
*/
public function dismissed_review() {

return get_option( $this->plugin_slug . '-review-dismissed' );

}

/**
* Returns the Review URL for this Plugin.
*
* @since 1.9.6.7
*
* @return string Review URL
*/
public function get_review_url() {

return 'https://wordpress.org/support/plugin/' . $this->plugin_slug . '/reviews/?filter=5#new-post';

}

/**
* Returns the Support URL for this Plugin.
*
* @since 1.9.6.7
*
* @return string Review URL
*/
public function get_support_url() {

return 'https://convertkit.com/support';

}

}
1 change: 1 addition & 0 deletions includes/class-wp-convertkit.php
Original file line number Diff line number Diff line change
Expand Up @@ -160,6 +160,7 @@ private function initialize_global() {
$this->classes['blocks_convertkit_content'] = new ConvertKit_Block_Content();
$this->classes['blocks_convertkit_form'] = new ConvertKit_Block_Form();
$this->classes['gutenberg'] = new ConvertKit_Gutenberg();
$this->classes['review_request'] = new ConvertKit_Review_Request( 'ConvertKit', 'convertkit' );
$this->classes['shortcodes'] = new ConvertKit_Shortcodes();
$this->classes['widgets'] = new ConvertKit_Widgets();

Expand Down
3 changes: 2 additions & 1 deletion phpcs.xml
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,10 @@

<!-- Exclude some directories. -->
<exclude-pattern>/.scripts/*</exclude-pattern>
<exclude-pattern>/.wordpress-org/*</exclude-pattern>
<exclude-pattern>/lib/*</exclude-pattern>
<exclude-pattern>/vendor/*</exclude-pattern>
<exclude-pattern>/tests/*</exclude-pattern>
<exclude-pattern>/vendor/*</exclude-pattern>

<!-- Exclude minified Javascript files. -->
<exclude-pattern>*.min.js</exclude-pattern>
Expand Down
12 changes: 12 additions & 0 deletions tests/_support/Helper/Acceptance.php
Original file line number Diff line number Diff line change
Expand Up @@ -114,6 +114,18 @@ public function deactivateConvertKitPlugin($I)
$I->checkNoWarningsAndNoticesOnScreen($I);
}

/**
* Helper method to delete option table rows for review requests.
* Useful for resetting the review state between tests.
*
* @since 1.9.6.7
*/
public function deleteConvertKitReviewRequestOptions($I)
{
$I->dontHaveOptionInDatabase('convertkit-review-request');
$I->dontHaveOptionInDatabase('convertkit-review-dismissed');
}

/**
* Helper method to setup the Plugin's API Key and Secret.
*
Expand Down
Loading

0 comments on commit aa280fe

Please sign in to comment.