2018-09-01 01:50:29 +02:00
< ? php
/**
* Class for intializing and displaying all admin settings
*
* @ package LBRYPress
*/
class LBRY_Admin
{
2018-09-13 01:39:13 +02:00
private $options ;
2018-09-01 01:50:29 +02:00
/**
2018-09-13 21:02:32 +02:00
* LBRY_Admin Constructor
*/
2018-09-13 01:39:13 +02:00
public function __construct ()
2018-09-01 01:50:29 +02:00
{
add_action ( 'admin_menu' , array ( $this , 'create_options_page' ));
2018-09-13 01:39:13 +02:00
add_action ( 'admin_init' , array ( $this , 'page_init' ));
2018-10-24 01:07:55 +02:00
add_action ( 'admin_init' , array ( $this , 'wallet_balance_warning' ));
2018-09-13 21:02:32 +02:00
add_action ( 'admin_post_lbry_add_channel' , array ( $this , 'add_channel' ));
2018-09-01 01:50:29 +02:00
}
/**
2018-09-13 21:02:32 +02:00
* Creates the options page in the WP admin interface
*/
2018-09-01 01:50:29 +02:00
public function create_options_page ()
{
add_options_page (
__ ( 'LBRYPress Settings' , 'lbrypress' ),
__ ( 'LBRYPress' , 'lbrypress' ),
'manage_options' ,
2018-09-13 01:39:13 +02:00
LBRY_ADMIN_PAGE ,
2018-09-01 01:50:29 +02:00
array ( $this , 'options_page_html' )
);
}
2018-09-13 01:39:13 +02:00
/**
2018-09-13 21:02:32 +02:00
* Registers all settings for the plugin
*/
2018-09-13 01:39:13 +02:00
public function page_init ()
{
// Register the LBRY Setting array
2019-01-24 20:26:30 +01:00
register_setting ( LBRY_SETTINGS_GROUP , LBRY_SETTINGS , array ( 'sanitize_callback' => array ( $this , 'sanitize' )));
2018-09-13 01:39:13 +02:00
// Add Required Settings Sections
add_settings_section (
2018-09-13 21:02:32 +02:00
LBRY_SETTINGS_SECTION_GENERAL , // ID
'General Settings' , // Title
array ( $this , 'general_section_info' ), // Callback
LBRY_ADMIN_PAGE // Page
2018-09-13 01:39:13 +02:00
);
// Add all settings fields
add_settings_field (
LBRY_WALLET ,
'LBRY Wallet Address' ,
array ( $this , 'wallet_callback' ),
LBRY_ADMIN_PAGE ,
LBRY_SETTINGS_SECTION_GENERAL
);
add_settings_field (
2019-01-24 20:26:30 +01:00
LBRY_SPEECH ,
'Spee.ch URL' ,
array ( $this , 'speech_callback' ),
LBRY_ADMIN_PAGE ,
LBRY_SETTINGS_SECTION_GENERAL
);
add_settings_field (
LBRY_SPEECH_CHANNEL ,
'Spee.ch Channel' ,
array ( $this , 'speech_channel_callback' ),
LBRY_ADMIN_PAGE ,
LBRY_SETTINGS_SECTION_GENERAL
);
add_settings_field (
LBRY_SPEECH_PW ,
'Spee.ch Password' ,
array ( $this , 'speech_pw_callback' ),
LBRY_ADMIN_PAGE ,
LBRY_SETTINGS_SECTION_GENERAL
2018-09-13 01:39:13 +02:00
);
add_settings_field (
LBRY_LICENSE ,
'LBRY Publishing License' ,
array ( $this , 'license_callback' ),
LBRY_ADMIN_PAGE ,
LBRY_SETTINGS_SECTION_GENERAL
);
add_settings_field (
LBRY_LBC_PUBLISH ,
'LBC Per Publish' ,
array ( $this , 'lbc_publish_callback' ),
LBRY_ADMIN_PAGE ,
LBRY_SETTINGS_SECTION_GENERAL
);
}
2018-09-01 01:50:29 +02:00
/**
2018-09-13 21:02:32 +02:00
* Returns the Options Page HTML for the plugin
*/
2018-09-01 01:50:29 +02:00
public function options_page_html ()
{
2018-09-13 01:39:13 +02:00
// Set class property to be referenced in callbacks
$this -> options = get_option ( LBRY_SETTINGS );
2018-09-11 22:10:15 +02:00
require_once ( LBRY_ABSPATH . 'templates/options_page.php' );
2018-09-01 01:50:29 +02:00
}
2018-09-13 01:39:13 +02:00
/**
2018-09-13 21:02:32 +02:00
* Sanitizes setting input
2019-01-24 20:26:30 +01:00
* // COMBAK Potentially sanitize more
2018-09-13 21:02:32 +02:00
*/
2018-09-13 01:39:13 +02:00
public function sanitize ( $input )
{
2019-01-24 21:05:46 +01:00
if ( ! empty ( $input [ LBRY_SPEECH_CHANNEL ])) {
$channel = $input [ LBRY_SPEECH_CHANNEL ];
$channel = str_replace ( '@' , '' , $channel );
$input [ LBRY_SPEECH_CHANNEL ] = $channel ;
}
if ( ! empty ( $input [ LBRY_SPEECH_PW ])) {
2019-01-24 20:26:30 +01:00
$encrypted = $this -> encrypt ( $input [ 'lbry_speech_pw' ]);
2019-01-24 21:05:46 +01:00
$input [ LBRY_SPEECH_PW ] = $encrypted ;
} else {
// If we have a password and its empty, keep orginal password
if ( ! empty ( get_option ( LBRY_SETTINGS )[ LBRY_SPEECH_PW ])) {
$input [ LBRY_SPEECH_PW ] = get_option ( LBRY_SETTINGS )[ LBRY_SPEECH_PW ];
}
2019-01-24 20:26:30 +01:00
}
2018-09-13 01:39:13 +02:00
return $input ;
}
/**
2018-09-13 21:02:32 +02:00
* Section info for the General Section
*/
2018-09-13 01:39:13 +02:00
public function general_section_info ()
{
print 'This is where you can configure how LBRYPress will distribute your content:' ;
}
/**
2018-09-13 21:02:32 +02:00
* Prints Wallet input
*/
2018-09-13 01:39:13 +02:00
public function wallet_callback ()
{
2018-11-04 00:37:32 +01:00
// Get first available address from Daemon
$address = LBRY () -> daemon -> address_list ();
$address = is_array ( $address ) && ! empty ( $address ) ? $address [ 0 ] : '' ;
2018-09-13 01:39:13 +02:00
printf (
'<input type="text" id="%1$s" name="%2$s[%1$s]" value="%3$s" readonly />' ,
LBRY_WALLET ,
LBRY_SETTINGS ,
2018-11-04 00:37:32 +01:00
$address
2018-09-13 01:39:13 +02:00
);
}
/**
2018-09-13 21:02:32 +02:00
* Prints Spee . ch input
*/
2018-09-13 01:39:13 +02:00
public function speech_callback ()
{
printf (
2018-09-13 21:02:32 +02:00
'<input type="text" id="%1$s" name="%2$s[%1$s]" value="%3$s" placeholder="https://your-speech-address.com"/>' ,
LBRY_SPEECH ,
LBRY_SETTINGS ,
isset ( $this -> options [ LBRY_SPEECH ]) ? esc_attr ( $this -> options [ LBRY_SPEECH ]) : ''
2018-09-13 01:39:13 +02:00
);
}
2019-01-24 20:26:30 +01:00
/**
* Prints Spee . ch channel input
*/
public function speech_channel_callback ()
{
printf (
'<span>@</span><input type="text" id="%1$s" name="%2$s[%1$s]" value="%3$s" placeholder="your-channel"/>' ,
LBRY_SPEECH_CHANNEL ,
LBRY_SETTINGS ,
isset ( $this -> options [ LBRY_SPEECH_CHANNEL ]) ? esc_attr ( $this -> options [ LBRY_SPEECH_CHANNEL ]) : ''
);
}
/**
* Prints Spee . ch password input
*/
public function speech_pw_callback ()
{
printf (
2019-01-24 21:05:46 +01:00
'<input type="password" id="%1$s" name="%2$s[%1$s]" value="" placeholder="Leave empty for same password"' ,
2019-01-24 20:26:30 +01:00
LBRY_SPEECH_PW ,
2019-01-24 21:05:46 +01:00
LBRY_SETTINGS
2019-01-24 20:26:30 +01:00
);
}
2018-09-13 01:39:13 +02:00
/**
2018-09-13 21:02:32 +02:00
* Prints License input
*/
2018-09-13 01:39:13 +02:00
public function license_callback ()
{
// TODO: Maybe make this more elegant?
$options = '' ;
// Create options list, select current license
2018-11-04 00:37:32 +01:00
//
foreach ( LBRY () -> licenses as $value => $name ) {
2018-09-13 01:39:13 +02:00
$selected = $this -> options [ LBRY_LICENSE ] === $value ;
$options .= '<option value="' . $value . '"' ;
if ( $selected ) {
$options .= ' selected' ;
}
$options .= '>' . $name . '</option>' ;
}
printf (
'<select id="%1$s" name="%2$s[%1$s]">%3$s</select>' ,
LBRY_LICENSE ,
LBRY_SETTINGS ,
$options
);
}
/**
2018-09-13 21:02:32 +02:00
* Prints LBC per publish input
*/
2018-09-13 01:39:13 +02:00
public function lbc_publish_callback ()
{
printf (
2018-09-13 21:02:32 +02:00
'<input type="number" id="%1$s" name="%2$s[%1$s]" value="%3$s" min="0.01" step="0.01"/>' ,
LBRY_LBC_PUBLISH ,
LBRY_SETTINGS ,
$this -> options [ LBRY_LBC_PUBLISH ]
);
}
/**
* Handles new channel form submission
*/
public function add_channel ()
{
$redirect_url = admin_url ( 'options-general.php?page=' . LBRY_ADMIN_PAGE );
// Check that nonce
if ( ! isset ( $_POST [ '_lbrynonce' ]) || ! wp_verify_nonce ( $_POST [ '_lbrynonce' ], 'lbry_add_channel' )) {
2018-09-13 21:10:37 +02:00
LBRY () -> notice -> set_notice ( 'error' );
2018-09-14 02:34:11 +02:00
} elseif ( ! isset ( $_POST [ 'new_channel' ]) || ! isset ( $_POST [ 'bid_amount' ])) {
LBRY () -> notice -> set_notice ( 'error' , 'Must supply both channel name and bid amount' );
2018-09-13 21:02:32 +02:00
} else {
2018-09-14 02:34:11 +02:00
$new_channel = $_POST [ 'new_channel' ];
$bid_amount = $_POST [ 'bid_amount' ];
2018-10-05 19:22:47 +02:00
// Try to add the new channel
try {
$result = LBRY () -> daemon -> channel_new ( $new_channel , $bid_amount );
// Tell the user it takes some time to go through
LBRY () -> notice -> set_notice ( 'success' , 'Successfully added a new channel! Please wait a few minutes for the bid to process.' , true );
} catch ( \Exception $e ) {
LBRY () -> notice -> set_notice ( 'error' , $e -> getMessage (), false );
}
2018-09-13 21:02:32 +02:00
}
wp_safe_redirect ( $redirect_url );
exit ();
}
2018-10-15 20:20:29 +02:00
2018-10-24 01:07:55 +02:00
/**
* Checks at most once an hour to see if the wallet balance is too low
*/
2018-11-01 01:29:49 +01:00
// IDEA: Check user permissions possibly
2018-10-24 01:07:55 +02:00
public static function wallet_balance_warning ()
2018-10-15 20:20:29 +02:00
{
2018-10-24 18:34:44 +02:00
// See if we've checked in the past two hours
if ( ! get_transient ( 'lbry_wallet_check' )) {
2018-10-24 01:07:55 +02:00
$balance = LBRY () -> daemon -> wallet_balance ();
2018-11-01 01:29:49 +01:00
if ( $balance < get_option ( LBRY_SETTINGS )[ LBRY_LBC_PUBLISH ] * 20 ) {
2018-10-24 18:34:44 +02:00
// If LBRY Balance is low, send email, but only once per day
2018-10-24 01:07:55 +02:00
if ( ! get_transient ( 'lbry_wallet_warning_email' )) {
$email = get_option ( 'admin_email' );
$subject = 'Your LBRYPress Wallet Balance is Low!' ;
2018-10-24 18:30:47 +02:00
$message = " You LBRY Wallet for your wordpress installation at " . site_url () . " is running very low. \r \n \r \n You currently have " . $balance . ' LBC left in your wallet. In order to keep publishing to the LBRY network, please add some LBC to your account.' ;
2018-10-24 01:07:55 +02:00
wp_mail ( $email , $subject , $message );
2018-10-24 18:30:47 +02:00
set_transient ( 'lbry_wallet_warning_email' , true , DAY_IN_SECONDS );
2018-10-24 01:07:55 +02:00
}
}
2018-10-24 18:34:44 +02:00
set_transient ( 'lbry_wallet_check' , true , 2 * HOUR_IN_SECONDS );
2018-10-24 01:07:55 +02:00
}
2018-10-15 20:20:29 +02:00
}
2019-01-24 20:26:30 +01:00
private function encrypt ( $plaintext )
{
$ivlen = openssl_cipher_iv_length ( $cipher = " AES-256-CTR " );
$iv = openssl_random_pseudo_bytes ( $ivlen );
$ciphertext_raw = openssl_encrypt ( $plaintext , $cipher , wp_salt (), $options = OPENSSL_RAW_DATA , $iv );
$hmac = hash_hmac ( 'sha256' , $ciphertext_raw , wp_salt (), $as_binary = true );
return base64_encode ( $iv . $hmac . $ciphertext_raw );
}
private function decrypt ( $ciphertext )
{
$c = base64_decode ( $ciphertext );
$ivlen = openssl_cipher_iv_length ( $cipher = " AES-256-CTR " );
$iv = substr ( $c , 0 , $ivlen );
$hmac = substr ( $c , $ivlen , $sha2len = 32 );
$ciphertext_raw = substr ( $c , $ivlen + $sha2len );
$original_plaintext = openssl_decrypt ( $ciphertext_raw , $cipher , wp_salt (), $options = OPENSSL_RAW_DATA , $iv );
$calcmac = hash_hmac ( 'sha256' , $ciphertext_raw , wp_salt (), $as_binary = true );
if ( hash_equals ( $hmac , $calcmac )) { //PHP 5.6+ timing attack safe comparison
return $original_plaintext ;
}
return false ;
}
public function get_speech_pw ()
{
$ciphertext = get_option ( LBRY_SETTINGS )[ LBRY_SPEECH_PW ];
if ( empty ( $ciphertext )) {
return false ;
}
return $this -> decrypt ( $ciphertext );
}
2018-09-01 01:50:29 +02:00
}