Compare commits

...

21 commits

Author SHA1 Message Date
Julien Liabeuf
8c3a084e10
Merge pull request #6 from mallardduck/patch-1
Fix comparison within is_time() method
2018-11-20 19:56:19 +07:00
Dan
c9bae4c60f
Update review.php 2018-11-16 17:49:38 -05:00
Julien Liabeuf
8df8feafa4
Merge pull request #11 from Mte90/patch-1
Improve composer loading
2018-08-15 08:34:30 +07:00
Daniele Scasciafratte
a9efc4fb2d
Update review.php 2018-08-13 22:10:27 +02:00
Dan
a47a0fc6fa Fix comparison within is_time() method
Using false here is causing the check to ALWAYS evaluate as false since the value is being cast to an int. A check of `bool === int` can never be true, so updating this to comparing for 0 is the best solution.
2017-04-09 17:34:56 -04:00
Julien Liabeuf
cb43e768e0 Bump version number again. Actually forgot to do it when releasing 2.0. 2016-09-27 11:04:50 +07:00
Julien Liabeuf
0f616f7edd Update review URLs - fixes #4 2016-09-27 11:02:43 +07:00
Julien Liabeuf
973892a9a0 Bump version number 2016-09-27 11:02:12 +07:00
Julien Liabeuf
4f9d9633a1 Fix calculation error 2016-09-27 11:01:36 +07:00
Julien Liabeuf
66baf1dbd9 Typecast var 2016-09-27 11:01:06 +07:00
Julien Liabeuf
1e24fa8a8f Update image src 2016-07-03 21:31:46 +07:00
Julien Liabeuf
686edccb6e Merge branch 'develop' of github.com:julien731/WP-Review-Me into develop 2016-04-20 19:38:24 +07:00
Julien Liabeuf
f55e83a0e5 Add info note about dropping integrations 2016-04-20 19:37:05 +07:00
Julien Liabeuf
e7ea9ad376 Update instructions in readme.md 2016-04-20 19:37:05 +07:00
Julien Liabeuf
9930e7085b Remove integrations - closes #3 closes #2 2016-04-20 19:37:05 +07:00
Julien Liabeuf
1f454a7629 Track the develop branch on Scrutinizer 2016-04-20 19:37:05 +07:00
Julien Liabeuf
25598778fc Finish integrationless 2016-04-20 19:35:44 +07:00
Julien Liabeuf
db6090587d Add info note about dropping integrations 2016-04-20 19:35:18 +07:00
Julien Liabeuf
ca9d11a379 Update instructions in readme.md 2016-04-20 08:39:28 +07:00
Julien Liabeuf
5688afde4e Remove integrations - closes #3 closes #2 2016-04-20 08:37:23 +07:00
Julien Liabeuf
73c551ebe6 Track the develop branch on Scrutinizer 2016-04-19 01:01:37 +07:00
5 changed files with 26 additions and 624 deletions

View file

@ -1,6 +1,8 @@
# WP Review Me # WP Review Me


[![Scrutinizer Code Quality](https://scrutinizer-ci.com/g/julien731/WP-Review-Me/badges/quality-score.png?b=master)](https://scrutinizer-ci.com/g/julien731/WP-Review-Me/?branch=master) [![Scrutinizer Code Quality](https://scrutinizer-ci.com/g/julien731/WP-Review-Me/badges/quality-score.png?b=develop)](https://scrutinizer-ci.com/g/julien731/WP-Review-Me/?branch=develop)

*In order to comply with the WordPress.org guidelines, the EDD integration has been removed and the WooCommerce integration has been dropped.*


Are you distributing WordPress themes or plugins on WordPress.org? Then you know how important reviews are. Are you distributing WordPress themes or plugins on WordPress.org? Then you know how important reviews are.


@ -8,7 +10,7 @@ The bad thing with reviews is that, while unhappy users love to let the world kn


How can you get more good reviews? Simply ask your users. How can you get more good reviews? Simply ask your users.


![WP Review Me](http://i.imgur.com/iZk4Bgu.png) ![WP Review Me](http://i.imgur.com/9oNGvm2.png)


## How It Works ## How It Works


@ -31,17 +33,9 @@ composer require julien731/wp-review-me
Creating a new review prompt would look like that: Creating a new review prompt would look like that:


``` ```
new WRM_WordPress( array( 'days_after' => 10, 'type' => 'plugin', 'slug' => 'my-plugin' ) ); new WP_Review_Me( array( 'days_after' => 10, 'type' => 'plugin', 'slug' => 'my-plugin' ) );
``` ```


This is the simplest way of creating a review prompt. If you want to customize it further, a few advanced parameters are available. This is the simplest way of creating a review prompt. If you want to customize it further, a few advanced parameters are available.


You can see the documentation on the wiki page: https://github.com/julien731/WP-Review-Me/wiki You can see the documentation on the wiki page: https://github.com/julien731/WP-Review-Me/wiki

## Integrations

Because users sometimes won't take the time to leave a review without an incentive, there are a couple of integrations made just for that.

### Easy Digital Downloads

With the EDD integration, you can automatically generate a discount code for the user in exchange for a review. See the [documentation for the EDD integration](https://github.com/julien731/WP-Review-Me/wiki/Integration:-EDD).

View file

@ -1,243 +0,0 @@
<?php
/**
* WP Review Me
*
* @package WP Review Me/Integrations
* @author Julien Liabeuf <julien@liabeuf.fr>
* @version 1.0
* @license GPL-2.0+
* @link https://julienliabeuf.com
* @copyright 2016 Julien Liabeuf
*/

// If this file is called directly, abort.
if ( ! defined( 'WPINC' ) ) {
die;
}

class WRM_EDD extends WP_Review_Me {

/**
* URL of the EDD shop
*
* @since 1.0
* @var string
*/
protected $edd_url;

/**
* The discount code settings
*
* @since 1.0
* @var array
*/
protected $discount;

/**
* The discount code generated
*
* @since 1.0
* @var string
*/
protected $code;

/**
* The confirmation e-mail data
*
* @since 1.0
* @var array
*/
protected $email;

public function __construct( $args, $email = array() ) {

$this->edd_url = isset( $args['edd_url'] ) ? esc_url( $args['edd_url'] ) : '';
$this->discount = isset( $args['edd_discount'] ) && is_array( $args['edd_discount'] ) ? wp_parse_args( $args['edd_discount'], $this->discount_defaults() ) : $this->discount_defaults();
$this->email = $email;

// Call parent constructor
parent::__construct( $args );

// Register our discount action
add_action( 'wrm_after_notice_dismissed', array( $this, 'query_discount_ajax' ), 10, 2 );

}

/**
* Get the EDD discount default options
*
* @since 1.0
* @return array
*/
private function discount_defaults() {

$defaults = array(
'type' => 'percentage',
'amount' => 20,
'validity' => 30, // In days
);

return $defaults;

}

/**
* Trigger the EDD discount query via Ajax
*
* @since 1.0
*
* @param string $link_id Unique ID of the link clicked to generate the discount
*
* @return void
*/
public function query_discount_ajax( $link_id ) {

// Not this notice. Abort.
if ( $link_id !== $this->link_id ) {
echo 'not this instance job';

return;
}

echo $this->query_discount();

}

/**
* Send the HTTP query to the EDD shop
*
* @since 1.0
* @return string|true
*/
protected function query_discount() {

$endpoint = esc_url( add_query_arg( 'wrm_action', 'discount', $this->edd_url ) );
$data = array( 'wrm_email' => get_bloginfo( 'admin_email' ), 'wrm_discount' => $this->discount ); // Wrap our vars to avoid post names issues

$response = wp_remote_post( $endpoint, array(
'method' => 'POST',
'timeout' => 20,
'redirection' => 5,
'httpversion' => '1.1',
'blocking' => true,
'body' => $data,
'user-agent' => 'WRM/' . $this->version . '; ' . get_bloginfo( 'url' )
) );

if ( is_wp_error( $response ) ) {
return $response->get_error_message();
}

if ( 200 != wp_remote_retrieve_response_code( $response ) ) {
return wp_remote_retrieve_response_message( $response );
}

$body = json_decode( wp_remote_retrieve_body( $response ) );

if ( false === $body ) {
return __( 'Unknown error', 'wp-review-me' );
}

if ( 'success' === $body->result ) {
$this->code = trim( $body->message );
$this->email_code();
return $this->code;
}

return $body->message;

}

/**
* Get the e-mail data
*
* @since 1.0
* @return array
*/
protected function get_email_data() {

$body = '<p>Hi,</p><p>From our entire team, many thanks for your review.</p><p>While you just spent a few minutes writing it, your testimonial will be a big help to us.</p><p>Many users don\'t realize it but reviews are a key part of the promotion work for our product. This allows us to increase our user base, and thus get more support for improving our product.</p><p>As a thank you from us, please find hereafter your discount code for a {{amount}} discount valid until {{expiration}}:</p><p>Your discount code: <strong>{{code}}</strong></p><p>Enjoy the product!</p>';

if ( isset( $this->email['body'] ) ) {
$body = $this->email['body'];
}

$tags = array( 'code', 'amount', 'expiration' );

foreach ( $tags as $tag ) {

$find = '{{' . $tag . '}}';

switch ( $tag ) {

case 'code':
$body = str_replace( $find, $this->code, $body );
break;

case 'amount':

$amount = $this->discount['amount'];

if ( 'percentage' === $this->discount['type'] ) {
$amount = $amount . '%';
}

$body = str_replace( $find, $amount, $body );
break;

case 'expiration':
$expiration = date( get_option( 'date_format' ), time() + ( (int) $this->discount['validity'] * 86400 ) );
$body = str_replace( $find, $expiration, $body );
break;

}

}

$email['body'] = $body;
$email['subject'] = isset( $this->email['subject'] ) ? sanitize_text_field( $this->email['subject'] ) : esc_html__( 'Your discount code', 'wp-review-me' );
$email['from_name'] = isset( $this->email['from_name'] ) ? sanitize_text_field( $this->email['from_name'] ) : get_bloginfo( 'name' );
$email['from_email'] = isset( $this->email['from_email'] ) ? sanitize_text_field( $this->email['from_email'] ) : get_bloginfo( 'admin_email' );

return apply_filters( 'wrm_edd_email', $email );

}

/**
* E-mail the discount code to the reviewer
*
* @since 1.0
* @return bool
*/
protected function email_code() {

$email = $this->get_email_data();
$from_name = $email['from_name'];
$from_email = $email['from_email'];
$headers = array(
"MIME-Version: 1.0",
"Content-type: text/html; charset=utf-8",
"From: $from_name <$from_email>",
);

return wp_mail( get_bloginfo( 'admin_email' ), $email['subject'], $email['body'], $headers );

}

/**
* Get the review prompt message
*
* @since 1.0
* @return string
*/
protected function get_message() {

$message = $this->message;
$link = $this->get_review_link_tag();
$message = $message . ' ' . $link;

return wp_kses_post( $message );

}

}

View file

@ -1,47 +0,0 @@
<?php
/**
* WP Review Me
*
* @package WP Review Me/Integrations
* @author Julien Liabeuf <julien@liabeuf.fr>
* @version 1.0
* @license GPL-2.0+
* @link https://julienliabeuf.com
* @copyright 2016 Julien Liabeuf
*/

// If this file is called directly, abort.
if ( ! defined( 'WPINC' ) ) {
die;
}

class WRM_WordPress extends WP_Review_Me {

/**
* WRM_WordPress constructor
*
* @since 1.0
*
* @param array $args
*/
public function __construct( $args ) {
parent::__construct( $args );
}

/**
* Get the review prompt message
*
* @since 1.0
* @return string
*/
protected function get_message() {

$message = $this->message;
$link = $this->get_review_link_tag();
$message = $message . ' ' . $link;

return wp_kses_post( $message );

}

}

View file

@ -13,20 +13,15 @@
* *
* @package WP Review Me * @package WP Review Me
* @author Julien Liabeuf <julien@liabeuf.fr> * @author Julien Liabeuf <julien@liabeuf.fr>
* @version 1.0 * @version 2.0.1
* @license GPL-2.0+ * @license GPL-2.0+
* @link https://julienliabeuf.com * @link https://julienliabeuf.com
* @copyright 2016 Julien Liabeuf * @copyright 2016 Julien Liabeuf
*/ */


// If this file is called directly, abort.
if ( ! defined( 'WPINC' ) ) {
die;
}

if ( ! class_exists( 'WP_Review_Me' ) ) { if ( ! class_exists( 'WP_Review_Me' ) ) {


abstract class WP_Review_Me { class WP_Review_Me {


/** /**
* Library version * Library version
@ -34,7 +29,7 @@ if ( ! class_exists( 'WP_Review_Me' ) ) {
* @since 1.0 * @since 1.0
* @var string * @var string
*/ */
public $version = '1.0'; public $version = '2.0.1';


/** /**
* Required version of PHP. * Required version of PHP.
@ -238,14 +233,14 @@ if ( ! class_exists( 'WP_Review_Me' ) ) {
*/ */
public function is_time() { public function is_time() {


$installed = get_option( $this->key, false ); $installed = (int) get_option( $this->key, 0 );


if ( false === $installed ) { if ( 0 === $installed ) {
$this->setup_date(); $this->setup_date();
$installed = time(); $installed = time();
} }


if ( $installed + ( $this->days + 86400 ) > time() ) { if ( $installed + ( $this->days * 86400 ) > time() ) {
return false; return false;
} }


@ -271,23 +266,23 @@ if ( ! class_exists( 'WP_Review_Me' ) ) {
*/ */
protected function get_review_link() { protected function get_review_link() {


$link = 'https://wordpress.org/support/view/'; $link = 'https://wordpress.org/support/';


switch ( $this->type ) { switch ( $this->type ) {


case 'theme': case 'theme':
$link .= 'theme-reviews/'; $link .= 'theme/';
break; break;


case 'plugin': case 'plugin':
$link .= 'plugin-reviews/'; $link .= 'plugin/';
break; break;


} }


$link .= $this->slug; $link .= $this->slug . '/reviews';
$link = add_query_arg( 'rate', $this->rating, $link ); $link = add_query_arg( 'rate', $this->rating, $link );
$link = esc_url( $link . '#postform' ); $link = esc_url( $link . '#new-post' );


return $link; return $link;


@ -411,12 +406,16 @@ if ( ! class_exists( 'WP_Review_Me' ) ) {
* @since 1.0 * @since 1.0
* @return string * @return string
*/ */
abstract protected function get_message(); protected function get_message() {

$message = $this->message;
$link = $this->get_review_link_tag();
$message = $message . ' ' . $link;

return wp_kses_post( $message );

}


} }


// Load integrations
require_once( dirname( __FILE__ ) . '/includes/integrations/class-wordpress.php' );
require_once( dirname( __FILE__ ) . '/includes/integrations/class-edd.php' );

} }

View file

@ -1,301 +0,0 @@
<?php
/**
* WP Review Me EDD Bridge
*
* This bridge plugin handles the discount creation triggered by WP Review Me
*
* LICENSE: This program is free software; you can redistribute it and/or modify it under the terms of the GNU
* General Public License as published by the Free Software Foundation; either version 3 of the License, or (at
* your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY
* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details. You should have received a copy of the GNU General Public License along
* with this program. If not, see <http://opensource.org/licenses/gpl-license.php>
*
* @package WP Review Me EDD Bridge
* @author Julien Liabeuf <julien@liabeuf.fr>
* @version 1.0
* @license GPL-2.0+
* @link https://julienliabeuf.com
* @copyright 2016 Julien Liabeuf
*
* Plugin Name: WP Review Me EDD Bridge
* Plugin URI: https://github.com/julien731/WP-Review-Me
* Description: Handles POST requests from a WP Review Me client
* Author: Julien Liabeuf
* Author URI: https://julienliabeuf.com
* Version: 1.0
* Text Domain: wp-review-me
* Domain Path: languages
*/

// If this file is called directly, abort.
if ( ! defined( 'WPINC' ) ) {
die;
}

if ( ! class_exists( 'WRM_EDD_Bridge' ) ):

/**
* Main WRM EDD class
*
* This class is the one and only instance of the plugin. It is used
* to load the core and all its components.
*
* @since 3.2.5
*/
final class WRM_EDD_Bridge {

/**
* Minimum version of WordPress required ot run the plugin
*
* @since 1.0
* @var string
*/
public $wordpress_version_required = '3.8';

/**
* Required version of PHP.
*
* Follow WordPress latest requirements and require
* PHP version 5.2 at least.
*
* @since 1.0
* @var string
*/
public $php_version_required = '5.2';

/**
* Email of the user
*
* @since 1.0
* @var string
*/
protected $email;

/**
* Discount code
*
* @since 1.0
* @var string
*/
protected $code;

/**
* Throw error on object clone
*
* The whole idea of the singleton design pattern is that there is a single
* object therefore, we don't want the object to be cloned.
*
* @since 3.2.5
* @return void
*/
public function __clone() {
// Cloning instances of the class is forbidden
_doing_it_wrong( __FUNCTION__, __( 'Cheatin&#8217; huh?', 'awesome-support' ), '3.2.5' );
}

/**
* Disable unserializing of the class
*
* @since 3.2.5
* @return void
*/
public function __wakeup() {
// Unserializing instances of the class is forbidden
_doing_it_wrong( __FUNCTION__, __( 'Cheatin&#8217; huh?', 'awesome-support' ), '3.2.5' );
}

public function __construct() {
add_action( 'init', array( $this, 'init' ) );
}

/**
* Initialize the bridge
*
* @since 1.0
* @return bool|void
*/
public function init() {

// Some work to do?
if ( ! empty( $_GET ) && isset( $_GET['wrm_action'] ) ) {

switch ( $_GET['wrm_action'] ) {

case 'discount':
$this->discount();
break;
}

}

}

/**
* Run some checks and generate the discount if it's all good
*
* @since 1.0
* @return void
*/
protected function discount() {

$result = array( 'result' => 'error' );

// Make sure the WordPress version is recent enough
if ( ! $this->is_version_compatible() ) {
$result['message'] = 'WordPress version incompatible';
echo json_encode( $result );
die();
}

// Make sure we have a version of PHP that's not too old
if ( ! $this->is_php_version_enough() ) {
$result['message'] = 'PHP version incompatible';
echo json_encode( $result );
die();
}

// Check if EDD is here
if ( ! function_exists( 'edd_store_discount' ) ) {
$result['message'] = 'EDD not active';
echo json_encode( $result );
die();
}

// Make sure we have an e-mail
if ( ! isset( $_POST['wrm_email'] ) ) {
$result['message'] = 'Email missing';
echo json_encode( $result );
die();
}

$this->email = $_POST['wrm_email'];
$this->code = md5( $this->email );

if ( ! $this->is_code_unique() ) {
$result['message'] = 'Code already claimed';
echo json_encode( $result );
die();
}

$message = $this->insert_discount();
$result['result'] = $message ? 'success' : 'error';
$result['message'] = $message ? $this->code : 'unknown error';

echo json_encode( $result );
die();

}

/**
* Check if the core version is compatible with this.
*
* @since 3.3
* @return boolean
*/
private function is_version_compatible() {

if ( empty( $this->wordpress_version_required ) ) {
return true;
}

if ( version_compare( get_bloginfo( 'version' ), $this->wordpress_version_required, '<' ) ) {
return false;
}

return true;

}

/**
* Check if the version of PHP is compatible with this addon.
*
* @since 3.3
* @return boolean
*/
private function is_php_version_enough() {

/**
* No version set, we assume everything is fine.
*/
if ( empty( $this->php_version_required ) ) {
return true;
}

if ( version_compare( phpversion(), $this->php_version_required, '<' ) ) {
return false;
}

return true;

}

protected function is_code_unique() {
return ! is_null( $this->code ) && edd_get_discount_by_code( $this->code ) ? false : true;
}

/**
* Get the EDD discount default options
*
* @since 1.0
* @return array
*/
private function discount_defaults() {

$defaults = array(
'type' => 'percentage',
'amount' => 20,
'validity' => 30, // In days
);

return $defaults;

}

/**
* Insert the discount code.
*
* @since 0.1.0
* @return integer Discount ID
*/
protected function insert_discount() {

$discount = isset( $_POST['wrm_discount'] ) ? wp_parse_args( $_POST['wrm_discount'], $this->discount_defaults() ) : $this->discount_defaults();

// Make sure the discount type exists
if ( ! in_array( $discount['type'], array( 'percent', 'flat' ) ) ) {
$discount['type'] = 'percent';
}

// Make sure the discount is not over 100% (for percentage discounts)
if ( 'percent' === $discount['type'] && (int) $discount['amount'] > 100 ) {
$discount['amount'] = 100;
}

$details = array(
'code' => $this->code,
'name' => sprintf( 'Discount for a review %s', $this->email ),
'status' => 'active',
'uses' => 0,
'max' => 1,
'amount' => $discount['amount'],
'start' => date( 'Y-m-d' ),
'expiration' => date( 'Y-m-d', strtotime( date( 'Y-m-d' ) . "+ {$discount['validity']} days" ) ),
'type' => $discount['type'],
'min_price' => 0,
'products' => array(),
'product_condition' => 'any',
'excluded_products' => array(),
'not_global' => true,
'use_once' => true,
);

return edd_store_discount( $details );

}

}

endif;

new WRM_EDD_Bridge();