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 ()
{
2022-02-12 20:55:16 +01:00
add_menu_page (
2022-02-12 22:28:25 +01:00
__ ( 'LBRYPress Settings' , 'lbrypress' ),
__ ( 'LBRYPress' , 'lbrypress' ),
2018-09-01 01:50:29 +02:00
'manage_options' ,
2018-09-13 01:39:13 +02:00
LBRY_ADMIN_PAGE ,
2022-02-12 22:28:25 +01:00
array ( $this , 'options_page_html' ),
2020-02-17 23:08:54 +01:00
plugin_dir_url ( LBRY_PLUGIN_FILE ) . '/admin/images/lbry-logo.svg'
2018-09-01 01:50:29 +02:00
);
2022-02-09 14:59:26 +01:00
// Admin stylesheet enqueue
function load_admin_stylesheet ( $hook ) {
if ( ( $_GET [ 'page' ] == 'lbrypress' ) ) {
wp_enqueue_style (
'lbry-admin' ,
plugins_url ( '/admin/css/lbry-admin.css' , LBRY_PLUGIN_FILE ),
array (),
LBRY_VERSION ,
'all'
);
}
}
add_action ( 'admin_enqueue_scripts' , 'load_admin_stylesheet' );
2018-09-01 01:50:29 +02:00
}
2022-02-12 20:55:16 +01:00
/**
* Returns the Options Page HTML for the plugin
*/
public function options_page_html ()
{
// Set class properties to be referenced in callbacks
$this -> options = get_option ( LBRY_SETTINGS );
$this -> options_speech = get_option ( LBRY_SPEECH_SETTINGS );
require_once ( LBRY_ABSPATH . 'templates/options-page.php' );
}
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
2022-02-09 14:13:33 +01:00
register_setting (
2022-02-13 17:39:42 +01:00
'lbry_general_settings' ,
2022-02-09 14:13:33 +01:00
LBRY_SETTINGS ,
array ( $this , 'sanitize_general_settings' )
);
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
2022-02-09 14:13:33 +01:00
array ( $this , 'general_section_callback' ), // Callback
2018-09-13 21:02:32 +02:00
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
);
2022-02-13 17:39:42 +01:00
add_settings_field (
2022-02-13 17:57:41 +01:00
'lbry_default_publish_setting' ,
'Always Publish to LBRY' ,
array ( $this , 'lbry_always_pub_callback' ),
LBRY_ADMIN_PAGE ,
LBRY_SETTINGS_SECTION_GENERAL
);
add_settings_field (
2022-02-13 17:39:42 +01:00
'default_lbry_channel' ,
'Default Publish Channel' ,
array ( $this , 'default_channel_callback' ),
LBRY_ADMIN_PAGE ,
LBRY_SETTINGS_SECTION_GENERAL
);
2022-02-13 17:57:41 +01:00
2018-09-13 01:39:13 +02:00
add_settings_field (
2022-02-09 16:04:03 +01:00
LBRY_LICENSE ,
'LBRY Publishing License' ,
array ( $this , 'license_callback' ),
2019-01-24 20:26:30 +01:00
LBRY_ADMIN_PAGE ,
LBRY_SETTINGS_SECTION_GENERAL
);
add_settings_field (
2022-02-09 16:04:03 +01:00
LBRY_LBC_PUBLISH ,
'LBC Per Publish' ,
array ( $this , 'lbc_publish_callback' ),
2019-01-24 20:26:30 +01:00
LBRY_ADMIN_PAGE ,
LBRY_SETTINGS_SECTION_GENERAL
);
2022-02-09 17:17:45 +01:00
/**
* Channel Page Settings
* We are using a custom page so that we can use the admin - post action and retrieve the $_POST
* global variable to populate the cURL request to create_channel , not saving the inputs to
* our database .
*/
2022-02-09 16:04:03 +01:00
/**
* Speech Admin Page settings
*/
register_setting (
LBRY_SPEECH_SETTINGS ,
LBRY_SPEECH_SETTINGS ,
array ( $this , 'sanitize_speech_settings' )
);
add_settings_section (
'lbry_settings_section_speech' , // ID
'Spee.ch Channel Settings' , // Title
array ( $this , 'speech_section_callback' ), // Callback
'lbrypress-speech' // Page
);
2019-01-24 20:26:30 +01:00
add_settings_field (
2022-02-09 16:04:03 +01:00
LBRY_SPEECH ,
'Spee.ch URL' ,
array ( $this , 'speech_callback' ),
'lbrypress-speech' ,
'lbry_settings_section_speech'
2018-09-13 01:39:13 +02:00
);
add_settings_field (
2022-02-09 16:04:03 +01:00
LBRY_SPEECH_CHANNEL ,
'Spee.ch Channel' ,
array ( $this , 'speech_channel_callback' ),
'lbrypress-speech' ,
'lbry_settings_section_speech'
2018-09-13 01:39:13 +02:00
);
add_settings_field (
2022-02-09 16:04:03 +01:00
LBRY_SPEECH_PW ,
'Spee.ch Password' ,
array ( $this , 'speech_pw_callback' ),
'lbrypress-speech' ,
'lbry_settings_section_speech'
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
*/
2022-02-09 14:13:33 +01:00
public function sanitize_general_settings ( $input )
2018-09-13 01:39:13 +02:00
{
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 ;
}
2022-02-09 16:04:03 +01:00
public function sanitize_speech_settings ( $input )
{
$new_input = get_option ( LBRY_SPEECH_SETTINGS );
if ( isset ( $input [ LBRY_SPEECH ] ) ) {
$new_input [ LBRY_SPEECH ] = sanitize_text_field ( $input [ LBRY_SPEECH ] );
}
if ( isset ( $input [ LBRY_SPEECH_CHANNEL ] ) ) {
$channel = $input [ LBRY_SPEECH_CHANNEL ];
$channel = str_replace ( '@' , '' , $channel );
$new_input [ LBRY_SPEECH_CHANNEL ] = sanitize_user ( $channel );
}
if ( isset ( $input [ LBRY_SPEECH_PW ] ) ) {
$input [ LBRY_SPEECH_PW ] = sanitize_text_field ( $input [ LBRY_SPEECH_PW ] );
$encrypted = $this -> encrypt ( $input [ LBRY_SPEECH_PW ] );
$new_input [ LBRY_SPEECH_PW ] = $encrypted ;
} else {
// If we have a password and it's empty, keep original password
if ( empty ( $input [ LBRY_SPEECH_PW ] ) )
$new_input [ LBRY_SPEECH_PW ] = get_option ( LBRY_SPEECH_SETTINGS [ LBRY_SPEECH_PW ] );
}
return $new_input ;
update_option ( LBRY_SPEECH_SETTINGS , $new_input );
}
2018-09-13 01:39:13 +02:00
/**
2018-09-13 21:02:32 +02:00
* Section info for the General Section
*/
2022-02-09 14:13:33 +01:00
public function general_section_callback ()
2018-09-13 01:39:13 +02:00
{
print 'This is where you can configure how LBRYPress will distribute your content:' ;
}
2022-02-12 20:20:25 +01:00
/**
2022-02-12 19:00:14 +01:00
* Section info for the Speech Channel Section
*/
public function speech_section_callback ()
{
print 'If you have a Spee.ch account, you can enter your account details here, if you don\'t already have a Spee.ch account, no need to enter anything here.' ;
}
2022-02-09 17:17:45 +01:00
/**
* Section info for the Available Channel ( s ) Section
*/
public function available_channels_callback ()
{
$channel_list = LBRY () -> daemon -> channel_list ();
if ( $channel_list ) { ?>
< ul class = " lbry-channel-list " >
< ? php foreach ( $channel_list as $channel ) { ?>
< li >< ? php esc_html_e ( $channel -> name ) ?> </li>
< ? php } ?>
</ ul >
< ? php } else { ?>
< p > Looks like you haven ' t added any channels yet , feel free to do so below :</ p >
< ? php }
}
2018-09-13 01:39:13 +02:00
/**
2018-09-13 21:02:32 +02:00
* Prints Wallet input
*/
2018-09-13 01:39:13 +02:00
public function wallet_callback ()
{
2020-01-27 23:49:03 +01:00
// Get first available account address from Daemon
2020-01-28 00:04:37 +01:00
$address = LBRY () -> daemon -> address_list ();
2022-02-12 22:28:25 +01:00
$address = is_array ( $address ) && ! empty ( $address ) ? $address [ 0 ] -> address : '' ;
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
);
}
2022-02-13 17:57:41 +01:00
/**
* Checkbox to default to always allow publish on LBRY
*/
public function lbry_always_pub_callback ()
{
$options = get_option ( LBRY_SETTINGS )[ 'lbry_default_publish_setting' ];
if ( ! isset ( $options ) ) {
$options = 0 ;
}
$checked = checked ( $options , 1 , false );
printf (
'<input type="checkbox" id="lbry_default_publish_setting" name="' . esc_attr ( '%2$s[%1$s]' ) . '" value="1" ' . esc_attr ( $checked ) . '><p>Set Default to always Publish to <strong>LBRY</strong>, this can be adjusted when publishing a New Post.</p>' ,
'lbry_default_publish_setting' ,
LBRY_SETTINGS ,
);
}
2022-02-13 17:39:42 +01:00
/**
* Prints select to choose a default to publish to channel
*/
public function default_channel_callback ()
{
$options = '' ;
$channel_list = LBRY () -> daemon -> channel_list ();
if ( $channel_list ) {
foreach ( $channel_list as $channel ) {
$selected = $this -> options [ 'default_lbry_channel' ] === $channel -> claim_id ;
$options .= '<option value="' . esc_attr ( $channel -> claim_id ) . '"' ;
if ( $selected ) {
$options .= ' selected' ;
}
$options .= '>' . esc_html ( $channel -> name ) . '</option>' ;
}
printf (
'<select id="' . esc_attr ( '%1$s' ) . '" name="' . esc_attr ( '%2$s[%1$s]' ) . '">' . esc_html ( '%3$s' ) . '</select>' ,
'default_lbry_channel' ,
LBRY_SETTINGS ,
$options
);
} else { ?>
< p > Looks like you haven 't added any channels yet, you can do that now on the <a href="<?php echo esc_url( admin_url( add_query_arg( array( ' page ' => ' lbrypress ', ' tab ' => ' channels ' ), ' options . php ' ) ) ); ?> " class="">Channels Tab</a></p>
< ? php }
}
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
//
2022-02-12 22:28:25 +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 . '"' ;
2022-02-12 22:28:25 +01:00
if ( $selected ) {
2018-09-13 01:39:13 +02:00
$options .= ' selected' ;
}
$options .= '>' . $name . '</option>' ;
}
printf (
2022-02-13 17:39:42 +01:00
'<select id="' . esc_attr ( '%1$s' ) . '" name="' . esc_attr ( '%2$s[%1$s]' ) . '">' . esc_html ( '%3$s' ) . '</select>' ,
2018-09-13 01:39:13 +02:00
LBRY_LICENSE ,
LBRY_SETTINGS ,
$options
);
}
2022-02-13 17:39:42 +01:00
2018-09-13 01:39:13 +02:00
/**
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 ]
);
}
2022-02-12 19:00:14 +01:00
2022-02-09 17:17:45 +01:00
/**
* Channels Page
* Channels page uses admin . php so we are able to use the admin - post action instead of options . php
*/
2022-02-12 20:20:25 +01:00
/**
2022-02-09 16:04:03 +01:00
* Prints Spee . ch input
*/
public function speech_callback ()
{
$options = get_option ( LBRY_SPEECH_SETTINGS );
printf (
'<input type="text" id="' . esc_attr ( '%1$s' ) . '" name="' . esc_attr ( '%2$s[%1$s]' ) . '" value="' . esc_attr ( '%3$s' ) . '" placeholder="https://your-speech-address.com">' ,
LBRY_SPEECH ,
LBRY_SPEECH_SETTINGS ,
isset ( $options [ LBRY_SPEECH ] ) ? $options [ LBRY_SPEECH ] : '' ,
);
}
/**
* Prints Spee . ch channel input
*/
public function speech_channel_callback ()
{
$options = get_option ( LBRY_SPEECH_SETTINGS );
printf (
'<input type="text" id="' . esc_attr ( '%1$s' ) . '" name="' . esc_attr ( '%2$s[%1$s]' ) . '" value="@' . esc_attr ( '%3$s' ) . '" placeholder="your-speech-channel">' ,
LBRY_SPEECH_CHANNEL ,
LBRY_SPEECH_SETTINGS ,
isset ( $options [ LBRY_SPEECH_CHANNEL ] ) ? $options [ LBRY_SPEECH_CHANNEL ] : '' ,
);
}
/**
* Prints Spee . ch password input
*/
public function speech_pw_callback ()
{
printf (
'<input type="password" id="' . esc_attr ( '%1$s' ) . '" name="' . esc_attr ( '%2$s[%1$s]' ) . '" placeholder="Leave empty for same password">' ,
LBRY_SPEECH_PW ,
LBRY_SPEECH_SETTINGS ,
);
}
2018-09-13 21:02:32 +02:00
/**
* Handles new channel form submission
*/
public function add_channel ()
{
2022-02-09 17:17:45 +01:00
$redirect_url = admin_url ( add_query_arg ( array ( 'page' => 'lbrypress' , 'tab' => 'channels' ), 'options.php' ) );
2018-09-13 21:02:32 +02:00
// Check that nonce
2022-02-09 17:17:45 +01:00
if ( isset ( $_POST [ '_lbrynonce' ] ) && wp_verify_nonce ( $_POST [ '_lbrynonce' ], 'add_channel_nonce' ) ) {
if ( empty ( $_POST [ 'lbry_new_channel' ] ) || empty ( $_POST [ 'lbry_channel_bid_amount' ] ) ) {
LBRY () -> notice -> set_notice ( 'error' , 'Must supply both channel name and bid amount' );
} elseif ( isset ( $_POST [ 'lbry_new_channel' ] ) && isset ( $_POST [ 'lbry_channel_bid_amount' ] ) ) {
$channel = $_POST [ 'lbry_new_channel' ]; // TODO: sanitize key() only allows for lowercase chars, dashes, and underscores. maybe remove to allow more characters? and use something else for better control?
$channel = trim ( $channel );
$channel = str_replace ( '@' , '' , $channel );
$channel = str_replace ( ' ' , '-' , $channel );
$channel = str_replace ( '_' , '-' , $channel );
$channel_name = sanitize_user ( $channel );
$bid = $_POST [ 'lbry_channel_bid_amount' ];
$channel_bid = number_format ( floatval ( $bid ), 3 , '.' , '' );
// Try to add the new channel
try {
$result = LBRY () -> daemon -> channel_new ( $channel_name , $channel_bid );
// Tell the user it takes some time to go through
LBRY () -> notice -> set_notice (
'success' , 'Successfully added a new channel: @' . esc_html ( $channel_name ) . '! Please allow a few minutes for the bid to process.' , true );
} catch ( \Exception $e ) {
LBRY () -> notice -> set_notice ( 'error' , $e -> getMessage (), false );
}
2018-10-05 19:22:47 +02:00
}
2022-02-09 17:17:45 +01:00
} else {
LBRY () -> notice -> set_notice ( 'error' , 'Security check failed' );
die ( __ ( 'Security check failed' , 'lbrypress' ) );
2018-09-13 21:02:32 +02:00
}
2022-02-09 17:17:45 +01:00
wp_safe_redirect ( $redirect_url );
2018-09-13 21:02:32 +02:00
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!' ;
2022-02-12 22:28:25 +01:00
$message = " Your 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
}