diff --git a/.gitignore b/.gitignore index 70d3e4c..0586cae 100644 --- a/.gitignore +++ b/.gitignore @@ -4,6 +4,8 @@ !*.* .DS_Store +extensions.json +.vscode/* tmp/* logs/* diff --git a/README.md b/README.md index 8904846..960670d 100644 --- a/README.md +++ b/README.md @@ -43,10 +43,11 @@ WantedBy=multi-user.target 1) Start it with: `sudo service lbrynet start`. If you are already running LBRY in the background, issue a `lbrynet stop` command first. ## Funding and preparing your wallet -LBRY will require LBRY Credits (LBC) for the channel creation and publishing process. You can send LBC to this instance from your LBRY app / lbry.tv using the Wallet page > Send Credits. If you need LBC, sign up for a [lbry.tv account](https://lbry.tv) or [email us](mailto:hello@lbry.com). After you send credits, they will be split into smaller amounts to facilatate the publishing process. You can also use an existing LBRY Desktop wallet/ channel by copying the default_wallet file into `~/.local/shared/lbry/lbryum/wallets`. +LBRY will require LBRY Credits (LBC) for the channel creation and publishing process. You can send LBC to this instance from your LBRY app / lbry.tv using the Wallet page > Send Credits. If you need LBC, sign up for a [lbry.tv account](https://lbry.tv) or [email us](mailto:hello@lbry.com). After you send credits, they will be split into smaller amounts to facilitate the publishing process. You can also use an existing LBRY Desktop wallet/ channel by copying the default_wallet file into `~/.local/shared/lbry/lbryum/wallets`. 1) Go to the LBRYPress plugin page and find your wallet address: -![](https://spee.ch/d/address.jpg) + +![](/admin/images/wallet-address.jpg) 1) Copy this address and send at least a few credits to it. From the Desktop app/lbry.tv, go to the Wallet page > Send Credits. 1) We will take the amount you deposited and split it up by a factor of 10. So if you deposited 10 LBC, you'd split it into 100: The decimal point is important, it will throw back an error without the structure of "10.0" @@ -58,19 +59,29 @@ Experimental: republishing of images in blog to LBRY: If images or GIFs are used **Please note: spee.ch channel creation is no longer available and that step can be skiped.** -1) Enter 0.1 for **LBC per Publish**. +1) Select the channel you wish as a **Default Publish Channel**. Can change later on a per-post basis. +1) Select the **Default Publish License** you wish to use as your default. +1) Enter 0.001 for **LBC per Publish** (later you can add more as a support if needed). 1) Click **Save Settings**. -![](https://spee.ch/8/speech-setup-lbrypress.jpeg) +![](/admin/images/settings-tab.jpg) -## Setting up a your blog publishing channel -If you don't already have a channel, this process will create a channel in your local wallet where your blog posts will be published to. Any available channels will be listed at the top of the **Your Publishable Channels** section. +## Setting up your blog publishing channel +If you don't already have a channel, this process will create a channel in your local wallet where your blog posts will be published to. Any available channels will be listed at the top of the **Your Publishable Channels** section on the **Channels** tab. 1) Enter the channel you wish to create and publish under in **New Channel Name**. -1) Enter a bid of 0.01 (this can be increased later). +Your channel will be created with a single @ prefix and all spaces and underscores are changed to a dash. Uppercase characters are allowed. Most special characters are removed. +1) Enter an **Amount of LBC to Bid** of 0.001 (current minimum, you can increase the amount or use supports later). +By adding as a support you push your content higher in the search but also keep your LBC fluid and easily moved without needing to abandon your claim. 1) Click **Add New Channel**. -![](https://spee.ch/7/channel-lbrypress.jpg) +![](/admin/images/add-channel.jpg) + +![](/admin/images/channel-create-success.jpg) + +Wait a few minutes and do a page refresh, your new channel should now be in the list. + +![](/admin/images/new-channel.jpg) ## Publishing blog posts When creating a new post (or editing an existing one), you can choose to publish it on LBRY as well. If you do this for an existing post, it will not retain the original date (known issue). diff --git a/admin/css/index.php b/admin/css/index.php new file mode 100644 index 0000000..4a77e23 --- /dev/null +++ b/admin/css/index.php @@ -0,0 +1,2 @@ +define_constants(); - spl_autoload_register(array($this, 'lbry_autoload_register')); + spl_autoload_register( array( $this, 'lbry_autoload_register' ) ); $this->init(); $this->init_hooks(); } @@ -88,10 +89,10 @@ class LBRYPress * @param string $name Constant name. * @param string|bool $value Constant value. */ - private function define($name, $value) + private function define( $name, $value ) { - if (! defined($name)) { - define($name, $value); + if ( ! defined( $name ) ) { + define( $name, $value ); } } @@ -107,18 +108,20 @@ class LBRYPress $this->define('LBRY_VERSION', $this->version); // Library Options Names - $this->define('LBRY_SETTINGS_GROUP', 'lbry_settings_group'); + //$this->define('LBRY_SETTINGS_GROUP', 'lbry_settings_group'); $this->define('LBRY_SETTINGS', 'lbry_settings'); $this->define('LBRY_SETTINGS_SECTION_GENERAL', 'lbry_settings_section_general'); $this->define('LBRY_ADMIN_PAGE', 'lbrypress'); $this->define('LBRY_WALLET', 'lbry_wallet'); // the wallet address + $this->define('LBRY_SPEECH_SETTINGS', 'lbry_speech_settings'); $this->define('LBRY_SPEECH', 'lbry_speech'); // the spee.ch address $this->define('LBRY_SPEECH_CHANNEL', 'lbry_speech_channel'); // The spee.ch channel $this->define('LBRY_SPEECH_PW', 'lbry_speech_pw'); // The password for the spee.ch channel $this->define('LBRY_LICENSE', 'lbry_license'); // the license to publish with to the LBRY network $this->define('LBRY_LBC_PUBLISH', 'lbry_lbc_publish'); // amount of lbc to use per publish $this->define('LBRY_WILL_PUBLISH', '_lbry_will_publish'); // The meta key for if to publish to LBRY Network or not - $this->define('LBRY_POST_CHANNEL', '_lbry_channel'); // The meta key for which channel to publish + $this->define('LBRY_POST_CHANNEL', '_lbry_post_pub_channel'); // The meta key for which channel to publish + $this->define('LBRY_POST_LICENSE', '_lbry_post_pub_license'); // The meta key for which license to publish on $this->define('LBRY_CLAIM_ID', '_lbry_claim_id'); // The Claim ID for the post as it was published on LBRY $this->define('LBRY_CANONICAL_URL', '_lbry_canonical_url'); // The canonical url for the published lbry post $this->define('LBRY_SPEECH_ASSET_URL', 'speech_asset_url'); // The meta key for an asset's speech url @@ -127,11 +130,11 @@ class LBRYPress /** * Autoloader Registration */ - private function lbry_autoload_register($class) + private function lbry_autoload_register( $class ) { $file_name = LBRY_ABSPATH . 'classes/' . $class . '.php'; - if (file_exists($file_name)) { + if ( file_exists( $file_name ) ) { require $file_name; return; } @@ -146,7 +149,7 @@ class LBRYPress $this->speech = new LBRY_Speech(); // Admin request - if (is_admin()) { + if ( is_admin() ) { $this->admin = new LBRY_Admin(); $this->notice = new LBRY_Admin_Notice(); $this->network = new LBRY_Network(); @@ -158,15 +161,15 @@ class LBRYPress */ private function init_hooks() { - register_activation_hook(LBRY_PLUGIN_FILE, array($this, 'activate')); - register_deactivation_hook(LBRY_PLUGIN_FILE, array($this, 'deactivate')); + register_activation_hook( LBRY_PLUGIN_FILE, array( $this, 'activate' ) ); + register_deactivation_hook( LBRY_PLUGIN_FILE, array( $this, 'deactivate' ) ); // Banner output for published posts // NOTE: move this to its own class to reduce clutter? - add_action('the_content', array($this, 'published_on_lbry_banner'), 12, 1); + add_action( 'the_content', array( $this, 'published_on_lbry_banner' ), 12, 1 ); - add_action('wp_enqueue_scripts', function () { - wp_enqueue_style('lbry-css', plugins_url('/frontend/lbry.css', LBRY_PLUGIN_FILE)); + add_action( 'wp_enqueue_scripts', function () { + wp_enqueue_style( 'lbry-css', plugins_url( '/frontend/lbry.css', LBRY_PLUGIN_FILE ) ); }); } @@ -178,16 +181,28 @@ class LBRYPress // TODO: Make sure errors are thrown if daemon can't be contacted, stop activation // Add options to the options table we need - if (! get_option(LBRY_SETTINGS)) { + if (! get_option( LBRY_SETTINGS ) ) { - // Default options + //Default options $option_defaults = array( - LBRY_SPEECH => null, - LBRY_LICENSE => $this->licenses[0], - LBRY_LBC_PUBLISH => 1 + LBRY_WALLET => '', + 'lbry_default_publish_setting' => '', + 'default_lbry_channel' => '', + LBRY_LICENSE => '', + LBRY_LBC_PUBLISH => 0.001, ); - add_option(LBRY_SETTINGS, $option_defaults, false); + add_option( LBRY_SETTINGS, $option_defaults, false ); + } + + if ( ! get_option( LBRY_SPEECH_SETTINGS ) ) { + // Default Speech Settings + $option_defaults = array( + LBRY_SPEECH =>'', + LBRY_SPEECH_CHANNEL => '', + LBRY_SPEECH_PW => '', + ); + add_option( LBRY_SPEECH_SETTINGS, $option_defaults, false ); } // COMBAK: decide if we need to check for missing or corrupt settings. May be unecessary. @@ -208,26 +223,26 @@ class LBRYPress public function deactivate() { // TODO: Stop the daemon - error_log('Deactivated LBRYPress'); + error_log( 'Deactivated LBRYPress' ); } public function published_on_lbry_banner($content) { - if (!is_single() || !in_the_loop() || !is_main_query()) { + if ( ! is_single() || ! in_the_loop() || ! is_main_query() ) { return $content; } global $post; - if ($post->post_type != 'post') { + if ( $post->post_type != 'post' ) { return $content; } - if (!get_post_meta($post->ID, LBRY_WILL_PUBLISH, true)) { + if ( ! get_post_meta( $post->ID, LBRY_WILL_PUBLISH, true ) ) { return $content; } ob_start(); - require(LBRY_ABSPATH . 'templates/published_on_lbry_banner.php'); + require( LBRY_ABSPATH . 'templates/published_on_lbry_banner.php' ); $banner = ob_get_clean(); return $content .= $banner; diff --git a/classes/LBRY_Admin.php b/classes/LBRY_Admin.php index 23c5303..a5e5e21 100644 --- a/classes/LBRY_Admin.php +++ b/classes/LBRY_Admin.php @@ -4,6 +4,7 @@ * * @package LBRYPress */ +defined('ABSPATH') || die(); // Exit if accessed directly class LBRY_Admin { @@ -25,14 +26,56 @@ class LBRY_Admin */ public function create_options_page() { - add_menu_page( - __('LBRYPress Settings', 'lbrypress'), - __('LBRYPress', 'lbrypress'), - 'manage_options', - LBRY_ADMIN_PAGE, - array($this, 'options_page_html'), - plugin_dir_url(LBRY_PLUGIN_FILE) . '/admin/images/lbry-logo.svg' - ); + + $hook_suffix = add_menu_page( + __( 'LBRYPress Settings', 'lbrypress' ), + __( 'LBRYPress', 'lbrypress' ), + 'manage_options', + LBRY_ADMIN_PAGE, + array( $this, 'options_page_html' ), + plugin_dir_url( LBRY_PLUGIN_FILE ) . '/admin/images/lbry-icon.png' + ); + + // Admin stylesheet enqueue + function load_admin_stylesheet( $hook ) { + + if ( ( $hook == 'post.php' ) || ( $hook == 'post-new.php' ) || ( $_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' ); + + // Admin Error Notices + function lbry_plugin_not_configured_notice() { + echo "

LBRYPress plugin is not configured yet. Please do it now.

\n"; + } + $lbry_wallet = get_option('lbry_wallet'); + if ( ! isset($lbry_wallet) ) { + add_action( 'admin_notices', 'lbry_plugin_not_configured_notice' ); + } + function admin_permission_check() { + if ( ! current_user_can( 'manage_options' ) ) { + wp_die( __( 'You do not have sufficient permissions to access this page.' ) ); + } + } + } + + /** + * Returns the Options Page HTML for the plugin + */ + public function options_page_html() { + //$LBRY = LBRY(); + // Set class properties to be referenced in callbacks + $this->options = get_option( LBRY_SETTINGS ); + //$this->options_channel = get_option( 'lbry_channel_settings' ); + $this->options_speech = get_option( LBRY_SPEECH_SETTINGS ); + require_once( LBRY_ABSPATH . 'templates/options-page.php' ); } /** @@ -41,13 +84,17 @@ class LBRY_Admin public function page_init() { // Register the LBRY Setting array - register_setting(LBRY_SETTINGS_GROUP, LBRY_SETTINGS, array('sanitize_callback' => array($this, 'sanitize'))); + register_setting( + 'lbry_general_settings', + LBRY_SETTINGS, + array( $this, 'sanitize_general_settings' ) + ); // Add Required Settings Sections add_settings_section( LBRY_SETTINGS_SECTION_GENERAL, // ID 'General Settings', // Title - array( $this, 'general_section_info' ), // Callback + array( $this, 'general_section_callback' ), // Callback LBRY_ADMIN_PAGE // Page ); @@ -59,35 +106,43 @@ class LBRY_Admin LBRY_ADMIN_PAGE, LBRY_SETTINGS_SECTION_GENERAL ); - +// remove from commit: add_settings_field( - LBRY_SPEECH, - 'Spee.ch URL', - array( $this, 'speech_callback' ), + 'lbry_default_publish_setting', + 'Always Publish to LBRY', + array( $this, 'lbry_always_pub_callback' ), LBRY_ADMIN_PAGE, LBRY_SETTINGS_SECTION_GENERAL ); add_settings_field( - LBRY_SPEECH_CHANNEL, - 'Spee.ch Channel', - array( $this, 'speech_channel_callback' ), + 'lbry_default_publish_setting', + 'Always Publish to LBRY', + array( $this, 'lbry_always_pub_callback' ), LBRY_ADMIN_PAGE, LBRY_SETTINGS_SECTION_GENERAL ); add_settings_field( - LBRY_SPEECH_PW, - 'Spee.ch Password', - array( $this, 'speech_pw_callback' ), + 'default_lbry_channel', + 'Default Publish Channel', + array( $this, 'default_channel_callback' ), + LBRY_ADMIN_PAGE, + LBRY_SETTINGS_SECTION_GENERAL + ); +// remove from commit: + add_settings_field( + 'lbry_default_publish_setting', + 'Always Publish to LBRY', + array( $this, 'lbry_always_pub_callback' ), LBRY_ADMIN_PAGE, LBRY_SETTINGS_SECTION_GENERAL ); add_settings_field( - LBRY_LICENSE, - 'LBRY Publishing License', - array( $this, 'license_callback' ), + 'lbry_default_publish_setting', + 'Always Publish to LBRY', + array( $this, 'lbry_always_pub_callback' ), LBRY_ADMIN_PAGE, LBRY_SETTINGS_SECTION_GENERAL ); @@ -95,55 +150,147 @@ class LBRY_Admin add_settings_field( LBRY_LBC_PUBLISH, 'LBC Per Publish', - array( $this, 'lbc_publish_callback' ), + array( $this, 'lbc_per_publish_callback' ), LBRY_ADMIN_PAGE, LBRY_SETTINGS_SECTION_GENERAL ); - } - /** - * Returns the Options Page HTML for the plugin - */ - public function options_page_html() - { - // Set class property to be referenced in callbacks - $this->options = get_option(LBRY_SETTINGS); - require_once(LBRY_ABSPATH . 'templates/options_page.php'); + /** + * 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. + */ + + + /** + * 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 + ); + + add_settings_field( + LBRY_SPEECH, + 'Spee.ch URL', + array( $this, 'speech_callback' ), + 'lbrypress-speech', + 'lbry_settings_section_speech' + ); + + add_settings_field( + LBRY_SPEECH_CHANNEL, + 'Spee.ch Channel', + array( $this, 'speech_channel_callback' ), + 'lbrypress-speech', + 'lbry_settings_section_speech' + ); + + add_settings_field( + LBRY_SPEECH_PW, + 'Spee.ch Password', + array( $this, 'speech_pw_callback' ), + 'lbrypress-speech', + 'lbry_settings_section_speech' + ); } /** * Sanitizes setting input * // COMBAK Potentially sanitize more */ - public function sanitize($input) + + public function sanitize_general_settings( $input ) { - if (!empty($input[LBRY_SPEECH_CHANNEL])) { + $new_input = get_option( LBRY_SETTINGS ); // get saved data + + if ( isset( $input[LBRY_WALLET] ) ) { + $new_input[LBRY_WALLET] = sanitize_text_field( $input[LBRY_WALLET] ); + } + $new_input['lbry_default_publish_setting'] = $input['lbry_default_publish_setting']; + + if ( isset( $input['default_lbry_channel'] ) ) { + $new_input['default_lbry_channel'] = sanitize_text_field( $input['default_lbry_channel'] ); + } + $license_array = LBRY()->licenses; + if ( isset( $input[LBRY_LICENSE] ) && ( in_array( $input[LBRY_LICENSE], $license_array ) ) ) { + $new_input[LBRY_LICENSE] = sanitize_text_field( $input[LBRY_LICENSE] ); + } + if ( isset( $input[LBRY_LBC_PUBLISH] ) ) { + $new_input[LBRY_LBC_PUBLISH] = number_format( floatval( $input[LBRY_LBC_PUBLISH] ), 3, '.', '' ); + } + return $new_input; + } + + 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); - $input[LBRY_SPEECH_CHANNEL] = $channel; + $channel = str_replace( '@', '', $channel ); + $new_input[LBRY_SPEECH_CHANNEL] = sanitize_user( $channel ); } - - if (!empty($input[LBRY_SPEECH_PW])) { - $encrypted = $this->encrypt($input['lbry_speech_pw']); - $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]; - } + 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 $input; + return $new_input; + update_option( LBRY_SPEECH_SETTINGS, $new_input ); } /** * Section info for the General Section */ - public function general_section_info() + public function general_section_callback() { print 'This is where you can configure how LBRYPress will distribute your content:'; } + /** + * Section info for the Available Channel(s) Section + */ + public function available_channels_callback() + { + $channel_list = LBRY()->daemon->channel_list(); + + if ( $channel_list ) { ?> + + +

Looks like you haven't added any channels yet, feel free to do so below:

+ daemon->address_list(); - $address = is_array($address) && !empty($address) ? $address[0]->address : ''; + $address = is_array( $address ) && ! empty( $address ) ? $address[0]->address : ''; printf( - '', + '', LBRY_WALLET, LBRY_SETTINGS, $address ); } - +// remove from commit: /** - * Prints Spee.ch input - */ - public function speech_callback() + * 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( - '', - LBRY_SPEECH, - LBRY_SETTINGS, - isset($this->options[LBRY_SPEECH]) ? esc_attr($this->options[LBRY_SPEECH]) : '' + '

Set Default to always Publish to LBRY, this can be adjusted when publishing a New Post.

', + 'lbry_default_publish_setting', + LBRY_SETTINGS, + ); } - + /** - * Prints Spee.ch channel input - */ - public function speech_channel_callback() + * Prints select to choose a default to publish to channel + */ + public function default_channel_callback() { - printf( - '@', - LBRY_SPEECH_CHANNEL, - LBRY_SETTINGS, - isset($this->options[LBRY_SPEECH_CHANNEL]) ? esc_attr($this->options[LBRY_SPEECH_CHANNEL]) : '' - ); - } + $options = ''; + $channel_list = LBRY()->daemon->channel_list(); - /** - * Prints Spee.ch password input - */ - public function speech_pw_callback() - { - printf( - 'options['default_lbry_channel'] === $channel->name; + + $options .= ''; + } + + printf( + '', + 'default_lbry_channel', + LBRY_SETTINGS, + $options + ); + } else { ?> +

Looks like you haven't added any channels yet, you can do that now on the Channels Tab

+ licenses as $value => $name) { + foreach ( LBRY()->licenses as $value => $name ) { $selected = $this->options[LBRY_LICENSE] === $value; $options .= '