File: /home/citaqlmd/nt.lmskreators.com/wp-content/plugins/mycred/includes/mycred-remote.php
<?php
if ( ! defined( 'myCRED_VERSION' ) ) exit;
/**
* myCRED Remote API
* Allows execution of remote actions such as adding points, removing points,
* transfering points between two users and balance checks.
* @see http://codex.mycred.me/classes/mycred_remote/
* @since 1.3
* @version 1.0.1
*/
if ( ! class_exists( 'myCRED_Remote' ) ) :
class myCRED_Remote {
public $method;
public $uri;
public $request;
public $host;
public $format;
public $user;
public $recipient;
public $reply = 'PROCESSING';
public $core;
public $key;
/**
* Construct
*/
function __construct( $key = NULL ) {
$this->handle_magic();
$this->core = mycred();
$this->key = $key;
$this->method = isset( $_SERVER['REQUEST_METHOD'] ) ? sanitize_text_field( wp_unslash( $_SERVER['REQUEST_METHOD'] ) ) : '';
$this->uri = explode( '/', isset( $_SERVER['REQUEST_URI'] ) ? esc_url_raw( wp_unslash( $_SERVER['REQUEST_URI'] ) ) : '' );
$this->format = '';
$this->parse_call();
$this->get_host_IP();
// Let others play
do_action_ref_array( 'mycred_remote', array( &$this ) );
}
/**
* Handle Magic Quotes
* @since 1.3
* @version 1.1
*/
public function handle_magic() {
$process = array( &$_GET, &$_POST, &$_COOKIE, &$_REQUEST );
foreach ( $process as $key => $val ) {
foreach ( $val as $k => $v ) {
unset( $process[ $key ][ $k ] );
if ( is_array( $v ) ) {
$process[ $key ][ stripslashes( $k ) ] = $v;
$process[] = &$process[ $key ][ stripslashes( $k ) ];
} else {
$process[ $key ][ stripslashes( $k ) ] = stripslashes( $v );
}
}
}
unset( $process );
// Let others play
do_action_ref_array( 'mycred_remote_magic', array( &$this ) );
}
/**
* Set Headers
* @since 1.3
* @version 1.0
*/
public function set_headers() {
header( 'Expires: ' . gmdate( 'D, d M Y H:i:s', mktime( 0, 0, 0, 1, 1, date( 'Y' ) ) - 604800 ) . ' GMT' );
header( 'Last-Modified: ' . gmdate( 'D, d M Y H:i:s' ) . ' GMT' );
header( 'Cache-Control: no-store, no-cache, must-revalidate' );
header( 'Pragma: no-cache' );
header_remove( 'x-powered-by' );
header_remove( 'link' );
header_remove( 'set-cookie' );
// Let others play
do_action( 'mycred_remote_headers', $this );
}
/**
* Parse Call
* @since 1.3
* @version 1.0
*/
public function parse_call() {
$parameters = array();
if ( isset( $_SERVER['QUERY_STRING'] ) )
parse_str( sanitize_text_field( wp_unslash( $_SERVER['QUERY_STRING'] ) ), $parameters );
$body = file_get_contents( "php://input" );
$content_type = false;
if ( isset( $_SERVER['CONTENT_TYPE'] ) ) {
$content_type = sanitize_text_field( wp_unslash( $_SERVER['CONTENT_TYPE'] ) );
}
switch ( $content_type ) {
case 'application/json':
$body_params = json_decode( $body );
if ( $body_params ) {
foreach ( $body_params as $param_name => $param_value ) {
$parameters[ $param_name ] = sanitize_text_field( $param_value );
}
}
$this->format = 'json';
break;
case 'application/x-www-form-urlencoded; charset=UTF-8' :
case 'application/x-www-form-urlencoded':
parse_str( $body, $vars );
if ( ! empty( $vars ) ) {
foreach ( $vars as $field => $value ) {
$parameters[ $field ] = sanitize_text_field( $value );
}
}
$this->format = 'html';
break;
default:
$this->format = 'other';
break;
}
$this->request = $parameters;
if ( isset( $this->request['format'] ) )
$this->format = $this->request['format'];
elseif ( empty( $this->format ) )
$this->format = 'unknown';
// Let others play
do_action_ref_array( 'mycred_remote_parse', array( &$this ) );
}
/**
* Get Host IP
* @since 1.3
* @version 1.0
*/
public function get_host_IP() {
if ( isset( $_SERVER['HTTP_CLIENT_IP'] ) )
$this->host = sanitize_text_field( wp_unslash( $_SERVER['HTTP_CLIENT_IP'] ) );
elseif ( isset( $_SERVER['HTTP_X_FORWARDED_FOR'] ) )
$this->host = sanitize_text_field( wp_unslash( $_SERVER['HTTP_X_FORWARDED_FOR'] ) );
elseif ( isset( $_SERVER['HTTP_X_FORWARDED'] ) )
$this->host = sanitize_text_field( wp_unslash( $_SERVER['HTTP_X_FORWARDED'] ) );
elseif ( isset( $_SERVER['HTTP_FORWARDED_FOR'] ) )
$this->host = sanitize_text_field( wp_unslash( $_SERVER['HTTP_FORWARDED_FOR'] ) );
elseif ( isset( $_SERVER['HTTP_FORWARDED'] ) )
$this->host = sanitize_text_field( wp_unslash( $_SERVER['HTTP_FORWARDED'] ) );
elseif ( isset( $_SERVER['REMOTE_ADDR'] ) )
$this->host = sanitize_text_field( wp_unslash( $_SERVER['REMOTE_ADDR'] ) );
else
$this->host = 'UNKNOWN';
do_action_ref_array( 'mycred_remote_host_IP', array( &$this ) );
}
/**
* Validate Call
* @since 1.3
* @version 1.0
*/
public function validate_call() {
// Let others play first
do_action_ref_array( 'mycred_remote_validate', array( &$this ) );
// Key has not been setup
if ( $this->key === NULL )
return 'ERROR: 99';
// Empty Request
if ( empty( $this->request ) )
return 'ERROR: 101';
// Missing action
if ( ! isset( $this->request['action'] ) || empty( $this->request['action'] ) )
return 'ERROR: 102';
// Missing account
elseif ( ! isset( $this->request['account'] ) || empty( $this->request['account'] ) )
return 'ERROR: 103';
// Missing token
elseif ( ! isset( $this->request['token'] ) || empty( $this->request['token'] ) )
return 'ERROR: 104';
// Missing Host
if ( ! isset( $this->request['host'] ) || empty( $this->request['host'] ) )
return 'ERROR: 105';
// Populate User and check if user exists
$this->user = get_user_by( 'email', $this->request['account'] );
if ( $this->user === false )
return 'ERROR: 201';
// Check for exclusion
if ( $this->core->exclude_user( $this->user->ID ) )
return 'ERROR: 202';
// Action specific validations
switch ( $this->request['action'] ) {
// Add points
case 'CREDIT' :
// Pay (deduct)
case 'DEBIT' :
// Reference is required
if ( ! isset( $this->request['ref'] ) || empty( $this->request['ref'] ) )
return 'ERROR: 401';
// Entry is required
if ( ! isset( $this->request['entry'] ) || empty( $this->request['entry'] ) )
return 'ERROR: 402';
// Amount is required
if ( ! isset( $this->request['amount'] ) || empty( $this->request['amount'] ) )
return 'ERROR: 403';
// Validate Token
// ( host + acount + amount + api_key )
$check = md5( $this->request['host'] . $this->request['action'] . $this->request['amount'] . $this->key );
if ( $this->request['token'] != $check )
return 'ERROR: 301';
break;
// Get balance
case 'GET' :
// Validate Token
// ( host + action + api_key )
$check = md5( $this->request['host'] . $this->request['action'] . $this->key );
if ( $this->request['token'] != $check )
return 'ERROR: 301';
break;
// Transfer
case 'PAY' :
// Reference is required
if ( ! isset( $this->request['ref'] ) || empty( $this->request['ref'] ) )
return 'ERROR: 501';
// Entry is required
if ( ! isset( $this->request['entry'] ) || empty( $this->request['entry'] ) )
return 'ERROR: 502';
// Amount is required
if ( ! isset( $this->request['amount'] ) || empty( $this->request['amount'] ) )
return 'ERROR: 503';
// Make sure the recipient is set
if ( ! isset( $this->request['to'] ) || empty( $this->request['to'] ) )
return 'ERROR: 504';
// Data is required
if ( ! isset( $this->request['data'] ) || empty( $this->request['data'] ) )
return 'ERROR: 505';
// Validate Token
// ( host + action + amount + from + to + api_key )
$check = md5( $this->request['host'] . $this->request['action'] . $this->request['amount'] . $this->request['account'] . $this->request['to'] . $this->key );
if ( $this->request['token'] != $check )
return 'ERROR: 301';
// Make sure recipient exists
$this->recipient = get_user_by( 'email', $this->request['to'] );
if ( $this->recipient === false )
return 'ERROR: 506';
// Can not pay yourself
if ( $this->recipient->ID == $this->user->ID )
return 'ERROR: 507';
// Check for exclusion
if ( $this->core->exclude_user( $this->recipient->ID ) )
return 'ERROR: 508';
break;
// Default
default :
// Unsupported action
return 'ERROR: 302';
break;
}
return true;
}
/**
* Process
* @since 1.3
* @version 1.0
*/
public function process() {
switch ( $this->request['action'] ) {
// Add points
case 'CREDIT' :
// Pay (deduct)
case 'DEBIT' :
$ref_id = $data = $type = '';
// Prep Reference ID
if ( isset( $this->request['ref_id'] ) && ! empty( $this->request['ref_id'] ) )
$ref_id = abs( $this->request['ref_id'] );
// Prep Data
if ( isset( $this->request['data'] ) && ! empty( $this->request['data'] ) )
$data = unserialize($this->request['data'], array('allowed_classes' => false));
// Prep Points Type
if ( isset( $this->request['type'] ) && ! empty( $this->request['type'] ) )
$type = sanitize_text_field( $this->request['type'] );
else
$type = $this->core->get_cred_id();
// Prep Amount
$amount = floatval( $this->request['amount'] );
if ( $this->request['action'] == 'DEBIT' )
$amount = 0-$amount;
else
$amount = abs( $amount );
// Prevent Duplicate
if ( ! empty( $data ) || ! empty( $ref_id ) ) {
if ( $this->core->has_entry( $this->request['ref'], $ref_id, $this->user->ID, $data ) ) {
$this->reply = 'DUPLICATE';
return;
}
}
// Check that user has enough points if we are charging
if ( $this->request['action'] == 'DEBIT' ) {
$balance = $this->core->get_users_balance( $this->user->ID, $type );
$min_balance = apply_filters( 'mycred_transfer_acc_limit', 0 );
if ( $balance-$amount < $min_balance ) {
$this->reply = 'DECLINED';
return;
}
}
// Add creds
if ( $this->core->add_creds(
$this->request['ref'],
$this->user->ID,
$amount,
$this->request['entry'],
$ref_id,
$data,
$type
) ) {
$this->reply = 'COMPLETED';
// Let others play on success
do_action( 'mycred_remote_action_' . $this->request['action'], $this );
}
else {
$this->reply = 'FAILED';
}
break;
// Get balance
case 'GET' :
// Prep Type
if ( isset( $this->request['type'] ) && ! empty( $this->request['type'] ) )
$type = sanitize_text_field( $this->request['type'] );
else
$type = $this->core->get_cred_id();
// Get balance
$balance = $this->core->get_users_balance( $this->user->ID, $type );
$this->reply = $this->core->format_number( $balance );
// Let other splay
do_action( 'mycred_remote_action_GET', $this );
break;
// Transfer
case 'PAY' :
// Amount
$amount = $this->core->format_number( $this->request['amount'] );
// Cred Type
if ( isset( $this->request['type'] ) && ! empty( $this->request['type'] ) )
$type = sanitize_text_field( $this->request['type'] );
else
$type = $this->core->get_cred_id();
// Prevent Duplicate
if ( $this->core->has_entry( $this->request['ref'], $this->recipient->ID, $this->user->ID, $this->request['data'] ) ) {
$this->reply = 'DUPLICATE';
return;
}
$balance = $this->core->get_users_balance( $this->user->ID, $type );
// Check that user has enough points if we are charging
$min_balance = apply_filters( 'mycred_transfer_acc_limit', 0 );
if ( $balance-$amount < $min_balance ) {
$this->reply = 'DECLINED';
return;
}
// Deduct points first from sender
if ( $this->core->add_creds(
$this->request['ref'],
$this->user->ID,
0-$amount,
$this->request['entry'],
$this->recipient->ID,
$this->request['data'],
$type
) ) {
// Once we have successfully deducted, pay the recipient
if ( $this->core->add_creds(
$this->request['ref'],
$this->recipient->ID,
$amount,
$this->request['entry'],
$this->user->ID,
$this->request['data'],
$type
) ) {
$this->reply = 'COMPLETED';
// Let others play
do_action( 'mycred_remote_action_PAY', $this );
}
else {
$this->reply = 'FAILED';
}
}
else {
$this->reply = 'FAILED';
}
break;
// Default
default :
// Let others play
do_action_ref_array( 'mycred_remote_process', array( &$this ) );
do_action_ref_array( 'mycred_remote_process_' . $this->request['action'], array( &$this ) );
// If reply is still empty we bail
if ( empty( $this->reply ) )
$this->reply = 'UNKNOWN';
break;
}
}
}
endif;
/**
* Remote Init
* @since 1.3
* @version 1.0
*/
if ( ! function_exists( 'mycred_remote_init' ) ) :
function mycred_remote_init() {
if ( is_admin() && defined( 'DOING_AJAX' ) && DOING_AJAX ) return;
$prefs = mycred_get_remote();
if ( ! $prefs['enabled'] ) return;
$uri = explode( '/', isset( $_SERVER['REQUEST_URI'] ) ? esc_url_raw( wp_unslash( $_SERVER['REQUEST_URI'] ) ) : '' );
if ( isset( $uri[1] ) && $uri[1] == $prefs['uri'] ) {
// Load
$remote = new myCRED_Remote( $prefs['key'] );
$remote->set_headers();
// Validate Call
$valid = $remote->validate_call();
// Request passed validation
if ( $valid === true ) {
// Run request
$remote->process();
die( esc_html( $remote->reply ) );
}
// Request failed validation
else {
$reply = ( ! $prefs['debug'] ) ? '' : $valid;
die( esc_html( $reply ) );
}
}
}
endif;
add_action( 'init', 'mycred_remote_init' );
/**
* Remote API Settings Page
* @since 1.3
* @version 1.0
*/
if ( ! function_exists( 'mycred_remote_settings_page' ) ) :
function mycred_remote_settings_page( $mycred_general ) {
$settings = mycred_get_remote();
$key_length = strlen( $settings['key'] );
$block = '';
$disabled_message = '';
if ( ! get_option( 'permalink_structure' ) ) {
$block = ' disabled="disabled"';
$disabled_message = __( 'This feature requires WordPress Permalinks to be setup and enabled!', 'mycred' );
}
elseif ( ! $settings['enabled'] )
$disabled_message = __( 'Click Update Settings to load the Remote API settings.', 'mycred' );
?>
<div class="mycred-ui-accordion">
<div class="mycred-ui-accordion-header">
<h4 class="mycred-ui-accordion-header-title">
<span class="dashicons dashicons-cloud mycred-ui-accordion-header-icon <?php if ( empty( $settings['key'] ) ) echo 'static'; else echo 'active'; ?>"></span>
<label><?php esc_html_e( 'Remote Access', 'mycred' ); ?></label>
</h4>
<div class="mycred-ui-accordion-header-actions hide-if-no-js">
<button type="button" aria-expanded="true">
<span class="mycred-ui-toggle-indicator" aria-hidden="true"></span>
</button>
</div>
</div>
<div class="body mycred-ui-accordion-body" style="display:none;">
<div class="row">
<div class="col-lg-12 col-md-12 col-sm-12 col-xs-12">
<div class="mycred-toggle-wrapper">
<label for="myCRED-General-remote"><strong><?php esc_html_e( 'Enable', 'mycred' ); ?></strong></label>
<label class="mycred-toggle">
<input type="checkbox" name="mycred_pref_core[allow_remote]" id="myCRED-General-remote" value="1" <?php if ( $settings['enabled'] ) echo ' checked="checked"'; echo wp_kses_post( $block ); ?> />
<span class="slider round"></span>
</label>
</div>
</div>
</div>
<hr class="mb-4">
<div class="row">
<div class="col-lg-6 col-md-6 col-sm-12 col-xs-12">
<h3><?php esc_html_e( 'API Key', 'mycred' ); ?></h3>
<div class="mycred-remote-key-wrapper">
<div class="form-group">
<label for="myCRED-remote-key"><?php esc_html_e( 'Key', 'mycred' ); ?></label>
<input type="text" name="mycred_pref_core[remote][key]" id="myCRED-remote-key" value="<?php echo esc_attr( $settings['key'] ); ?>" placeholder="<?php esc_attr_e( '12, 16, 24 or 32 characters', 'mycred' ); ?>" class="form-control" />
<p><?php esc_html_e( 'A minimum of 12 characters is required.', 'mycred' ); ?></p>
<div style="color:<?php if ( $key_length == 0 ) echo 'gray'; elseif ( $key_length >= 12 ) echo 'green'; ?>">(<span id="mycred-length-counter"><?php echo esc_html( $key_length ); ?></span>)</span>
</div>
</div>
<input type="button" id="mycred-generate-api-key" value="<?php esc_attr_e( 'Generate New Key', 'mycred' ); ?>" class="button button-large button-primary" />
</div>
<div class="m-alert m-alert-warning"><strong><?php esc_html_e( 'Warning!', 'mycred' ); ?></strong> <?php echo esc_html( $mycred_general->core->template_tags_general( __( 'Keep this key safe! Those you share this key with will be able to remotely deduct / add / transfer %plural%!', 'mycred' ) ) ); ?></div>
</div>
<div class="col-lg-6 col-md-6 col-sm-12 col-xs-12">
<h3><?php esc_html_e( 'Incoming URI', 'mycred' ); ?></h3>
<div class="form-group">
<label for="myCRED-remote-uri"><?php esc_html_e( 'URI', 'mycred' ); ?></label>
<div class="mycred-remote-uri-wrapper">
<?php echo esc_url( site_url() . '/' ); ?> <input type="text" name="mycred_pref_core[remote][uri]" id="myCRED-remote-uri" value="<?php echo esc_attr( $settings['uri'] ); ?>" /> /
</div>
<p>The incoming call address. Remote calls made to any other URL will be ignored.</p>
</div>
</div>
</div>
<hr class="mb-4">
<div class="row">
<div class="col-lg-12 col-md-12 col-sm-12 col-xs-12">
<h3><?php esc_html_e( 'Debug Mode', 'mycred' ); ?></h3>
<input type="checkbox" name="mycred_pref_core[remote][debug]" id="myCRED-remote-debug-mode"<?php if ( $settings['debug'] ) echo ' checked="checked"'; ?> value="1" /> <span class="description"><?php esc_html_e( 'Remember to disable when not used to prevent mischievous calls from learning about your setup!', 'mycred' ); ?></span>
</div>
</div>
<?php do_action( 'mycred_after_remote_prefs', $mycred_general ); ?>
</div>
</div>
<?php
}
endif;
add_action( 'mycred_after_core_prefs', 'mycred_remote_settings_page' );
/**
* Remote API Settings Save
* @since 1.3
* @version 1.0
*/
if ( ! function_exists( 'mycred_remote_save_settings' ) ) :
function mycred_remote_save_settings( $new_data, $post, $mycred_general ) {
$current = mycred_get_remote();
$new_remote = array();
if ( isset( $post['allow_remote'] ) )
$new_remote['enabled'] = 1;
else
$new_remote['enabled'] = 0;
if ( isset( $post['remote']['key'] ) )
$new_remote['key'] = sanitize_text_field( $post['remote']['key'] );
else
$new_remote['key'] = $current['key'];
if ( isset( $post['remote']['uri'] ) )
$new_remote['uri'] = sanitize_text_field( $post['remote']['uri'] );
else
$new_remote['uri'] = $current['uri'];
if ( isset( $post['remote']['debug'] ) )
$new_remote['debug'] = 1;
else
$new_remote['debug'] = 0;
// Let others play
$new_remote = apply_filters( 'mycred_remote_save_prefs', $new_remote, $current, $post, $mycred_general );
update_option( 'mycred_pref_remote', $new_remote );
return $new_data;
}
endif;
add_filter( 'mycred_save_core_prefs', 'mycred_remote_save_settings', 10, 3 );