Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
22 changes: 22 additions & 0 deletions assets/js/paywalled-content.js
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,28 @@ jQuery(document).ready(function($) {
jQuery('html, body').animate({ scrollTop: $target.offset().top - headerOffset }, 500);
}
}
// --- NEW: update sticky header to the logged-in state without reload ---
// Keep JS state in sync (used by login script)
if (typeof isLoggedIn !== 'undefined') {
isLoggedIn = true;
}

jQuery.post(
PaywallAjax.ajaxUrl,
{
action: 'paybutton_get_sticky_header',
security: PaywallAjax.nonce
},
function(resp) {
if (resp && resp.success && resp.data && resp.data.html) {
var $header = jQuery('#cashtab-sticky-header');
if ($header.length) {
// Replace the whole header with the freshly rendered one
$header.replaceWith(resp.data.html);
}
}
}
);
}
}
});
Expand Down
2 changes: 1 addition & 1 deletion includes/class-paybutton-admin.php
Original file line number Diff line number Diff line change
Expand Up @@ -204,7 +204,7 @@ public function paywall_settings_page() {

$args = array(
'settings_saved' => $settings_saved,
'admin_wallet_address' => get_option( 'paybutton_admin_wallet_address', '' ),
'paybutton_admin_wallet_address' => get_option( 'paybutton_admin_wallet_address', '' ),
'default_price' => get_option( 'paybutton_paywall_default_price', 5.5 ),
'current_unit' => get_option( 'paybutton_paywall_unit', 'XEC' ),
'btn_text' => get_option( 'paybutton_text', 'Pay to Unlock' ),
Expand Down
37 changes: 35 additions & 2 deletions includes/class-paybutton-ajax.php
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,10 @@ public function __construct() {
// AJAX endpoint to validate an unlock transaction
add_action('wp_ajax_validate_unlock_tx', array($this, 'ajax_validate_unlock_tx'));
add_action('wp_ajax_nopriv_validate_unlock_tx', array($this, 'ajax_validate_unlock_tx'));

// AJAX endpoint to get sticky header HTML for auto-login after content unlock
add_action( 'wp_ajax_paybutton_get_sticky_header', array( $this, 'get_sticky_header' ) );
add_action( 'wp_ajax_nopriv_paybutton_get_sticky_header', array( $this, 'get_sticky_header' ) );
}
/**
* Payment Trigger Handler with Cryptographic Verification
Expand Down Expand Up @@ -307,7 +311,7 @@ public function mark_payment_successful() {
$table = $wpdb->prefix . 'paybutton_paywall_unlocked';

$row = $wpdb->get_row( $wpdb->prepare(
"SELECT id FROM {$table}
"SELECT id, pb_paywall_user_wallet_address FROM {$table}
WHERE pb_paywall_user_wallet_address = %s
AND post_id = %d
AND tx_hash = %s
Expand Down Expand Up @@ -338,6 +342,12 @@ public function mark_payment_successful() {
// Mark this post as "unlocked" in the cookie for this browser session
PayButton_State::add_article( $post_id );

$wallet_address = sanitize_text_field($row->pb_paywall_user_wallet_address);
// 🔐 Auto-login from wallet address returned in the server-verified row
if ( ! PayButton_State::get_address() && ! empty( $wallet_address ) ) {
PayButton_State::set_address( $wallet_address );
}

// If the user is logged in via Cashtab login cookie, mark is_logged_in for this row in DB.
$login_addr = sanitize_text_field(PayButton_State::get_address());
if ( $login_addr && $login_addr === $user_address ) {
Expand Down Expand Up @@ -397,7 +407,7 @@ public function fetch_unlocked_content() {
}

// Run the full post-content pipeline (blocks, shortcodes, embeds, autop, etc.) filter
$body = apply_filters( 'the_content', $inner );
$body = apply_filters( 'the_content', $inner ); // phpcs:ignore WordPress.NamingConventions.PrefixAllGlobals.NonPrefixedHooknameFound -- core hook

// Restore the flag
if ( isset( $wp_query ) ) {
Expand Down Expand Up @@ -599,4 +609,27 @@ public function ajax_validate_unlock_tx() {
'unlock_token' => $token,
));
}

/**
* AJAX endpoint to get sticky header HTML for auto-login after content unlock.
*/
public function get_sticky_header() {
check_ajax_referer( 'paybutton_paywall_nonce', 'security' );

$template = PAYBUTTON_PLUGIN_DIR . 'templates/public/sticky-header.php';
if ( ! file_exists( $template ) ) {
wp_send_json_error( array( 'message' => 'Sticky header template not found.' ), 500 );
}

// IMPORTANT: use the same name as in output_sticky_header() and sticky-header.php
$paybutton_user_wallet_address = sanitize_text_field( PayButton_State::get_address() );

ob_start();
include $template;
$html = ob_get_clean();

wp_send_json_success( array(
'html' => $html,
) );
}
}
16 changes: 8 additions & 8 deletions includes/class-paybutton-public.php
Original file line number Diff line number Diff line change
Expand Up @@ -163,9 +163,9 @@ private function load_public_template( $template_name, $args = array() ) {
* Output the sticky header HTML.
*/
public function output_sticky_header() {
$user_wallet_address = sanitize_text_field( PayButton_State::get_address() );
$paybutton_user_wallet_address = sanitize_text_field( PayButton_State::get_address() );
$this->load_public_template( 'sticky-header', array(
'user_wallet_address' => $user_wallet_address
'paybutton_user_wallet_address' => $paybutton_user_wallet_address
) );
}

Expand Down Expand Up @@ -280,20 +280,20 @@ class="paybutton-container"
* @return string
*/
public function profile_shortcode() {
$user_wallet_address = sanitize_text_field( PayButton_State::get_address() );
if ( empty( $user_wallet_address ) ) {
$paybutton_user_wallet_address = sanitize_text_field( PayButton_State::get_address() );
if ( empty( $paybutton_user_wallet_address ) ) {
return '<p>You must be logged in to view your unlocked content.</p>';
}
global $wpdb;
$table_name = $wpdb->prefix . 'paybutton_paywall_unlocked';
$rows = $wpdb->get_results( $wpdb->prepare(
$paybutton_rows = $wpdb->get_results( $wpdb->prepare(
"SELECT DISTINCT post_id FROM $table_name WHERE pb_paywall_user_wallet_address = %s ORDER BY id DESC",
$user_wallet_address
$paybutton_user_wallet_address
) );
ob_start();
$this->load_public_template( 'profile', array(
'user_wallet_address' => $user_wallet_address,
'rows' => $rows
'paybutton_user_wallet_address' => $paybutton_user_wallet_address,
'paybutton_rows' => $paybutton_rows
) );
return ob_get_clean();
}
Expand Down
14 changes: 6 additions & 8 deletions templates/admin/content.php
Original file line number Diff line number Diff line change
Expand Up @@ -37,23 +37,21 @@ function paybutton_sort_content_table( $col, $label, $orderby, $order, $base_url
</thead>
<tbody>
<?php if ( ! empty( $contentData ) ): ?>
<?php foreach ( $contentData as $row ):
$permalink = get_permalink( $row['post_id'] );
<?php foreach ( $contentData as $paybutton_row ):
$paybutton_permalink = get_permalink( $paybutton_row['post_id'] );
?>
<tr>
<td>
<a href="<?php echo esc_url( $permalink ); ?>" target="_blank">
<?php echo esc_html( $row['title'] ); ?>
<a href="<?php echo esc_url( $paybutton_permalink ); ?>" target="_blank">
<?php echo esc_html( $paybutton_row['title'] ); ?>
</a>
</td>
<td>
<?php
echo intval( $row['unlock_count'] )
// . ' (' . intval( $row['unlock_logged_in_count'] ) . ' accounts)'
;
echo intval( $paybutton_row['unlock_count'] );
?>
</td>
<td><?php echo esc_html( number_format( $row['total_earned'], 2 ) ); ?></td>
<td><?php echo esc_html( number_format( $paybutton_row['total_earned'], 2 ) ); ?></td>
</tr>
<?php endforeach; ?>
<?php else: ?>
Expand Down
60 changes: 30 additions & 30 deletions templates/admin/customers.php
Original file line number Diff line number Diff line change
Expand Up @@ -21,38 +21,38 @@
</tr>
</thead>
<tbody>
<?php foreach ( $rows as $row ):
$post_title = get_the_title( $row->post_id );
$permalink = get_permalink( $row->post_id );
if ( $post_title && $permalink ): ?>
<?php foreach ( $rows as $paybutton_row ):
$paybutton_post_title = get_the_title( $paybutton_row->post_id );
$paybutton_permalink = get_permalink( $paybutton_row->post_id );
if ( $paybutton_post_title && $paybutton_permalink ): ?>
<tr>
<td>
<a href="<?php echo esc_url( $permalink ); ?>" target="_blank">
<?php echo esc_html( $post_title ); ?>
<a href="<?php echo esc_url( $paybutton_permalink ); ?>" target="_blank">
<?php echo esc_html( $paybutton_post_title ); ?>
</a>
</td>
<td><?php echo number_format( floatval( $row->tx_amount ), 2 ); ?></td>
<td><?php echo number_format( floatval( $paybutton_row->tx_amount ), 2 ); ?></td>
<?php
$converted_ts = '(none)';
if ( ! empty( $row->tx_timestamp ) && $row->tx_timestamp !== '0000-00-00 00:00:00' ) {
$local_time = get_date_from_gmt( $row->tx_timestamp );
if ( $local_time ) {
$converted_ts = date_i18n( 'Y-m-d H:i:s', strtotime( $local_time ) );
$paybutton_converted_ts = '(none)';
if ( ! empty( $paybutton_row->tx_timestamp ) && $paybutton_row->tx_timestamp !== '0000-00-00 00:00:00' ) {
$paybutton_local_time = get_date_from_gmt( $paybutton_row->tx_timestamp );
if ( $paybutton_local_time ) {
$paybutton_converted_ts = date_i18n( 'Y-m-d H:i:s', strtotime( $paybutton_local_time ) );
}
}
?>
<td><?php echo esc_html( $converted_ts ); ?></td>
<?php if ( ! empty( $row->tx_hash ) ): ?>
<td><?php echo esc_html( $paybutton_converted_ts ); ?></td>
<?php if ( ! empty( $paybutton_row->tx_hash ) ): ?>
<td>
<a href="https://explorer.e.cash/tx/<?php echo urlencode( $row->tx_hash ); ?>" target="_blank">
<?php echo esc_html( $row->tx_hash ); ?>
<a href="https://explorer.e.cash/tx/<?php echo urlencode( $paybutton_row->tx_hash ); ?>" target="_blank">
<?php echo esc_html( $paybutton_row->tx_hash ); ?>
</a>
</td>
<?php else: ?>
<td>(none)</td>
<?php endif; ?>
<td>
<?php echo esc_html( $row->is_logged_in ? 'true' : 'false' ); ?>
<?php echo esc_html( $paybutton_row->is_logged_in ? 'true' : 'false' ); ?>
</td>
</tr>
<?php endif;
Expand Down Expand Up @@ -98,35 +98,35 @@ function paybutton_sort_customers_table( $col, $label, $orderby, $order, $base_u
</thead>
<tbody>
<?php if ( ! empty( $customers ) ): ?>
<?php foreach ( $customers as $row ):
$detail_link = add_query_arg( array(
<?php foreach ( $customers as $paybutton_row ):
$paybutton_detail_link = add_query_arg( array(
'page' => 'paybutton-paywall-customers',
'address' => $row['pb_paywall_user_wallet_address']
'address' => $paybutton_row['pb_paywall_user_wallet_address']
), admin_url( 'admin.php' ) );
?>
<tr>
<td>
<a href="<?php echo esc_url( $detail_link ); ?>">
<?php echo esc_html( $row['pb_paywall_user_wallet_address'] ); ?>
<a href="<?php echo esc_url( $paybutton_detail_link ); ?>">
<?php echo esc_html( $paybutton_row['pb_paywall_user_wallet_address'] ); ?>
</a>
</td>
<td>
<?php
echo intval( $row['unlocked_count'] )
// . ' (' . intval( $row['unlocked_logged_in_count'] ) . ' accounts)'
echo intval( $paybutton_row['unlocked_count'] )
// . ' (' . intval( $paybutton_row['unlocked_logged_in_count'] ) . ' accounts)'
;
?>
</td>
<td><?php echo esc_html( number_format( $row['total_paid'], 2 ) ); ?></td>
<td><?php echo esc_html( number_format( $paybutton_row['total_paid'], 2 ) ); ?></td>
<td>
<?php
// Convert MySQL datetime to something friendly
if ( ! empty( $row['last_unlock_ts'] ) && $row['last_unlock_ts'] !== '0000-00-00 00:00:00' ) {
$local_time = get_date_from_gmt( $row['last_unlock_ts'] );
if ( $local_time ) {
echo esc_html( date_i18n( 'Y-m-d H:i:s', strtotime( $local_time ) ) );
if ( ! empty( $paybutton_row['last_unlock_ts'] ) && $paybutton_row['last_unlock_ts'] !== '0000-00-00 00:00:00' ) {
$paybutton_local_time = get_date_from_gmt( $paybutton_row['last_unlock_ts'] );
if ( $paybutton_local_time ) {
echo esc_html( date_i18n( 'Y-m-d H:i:s', strtotime( $paybutton_local_time ) ) );
} else {
echo esc_html( $row['last_unlock_ts'] ); // fallback
echo esc_html( $paybutton_row['last_unlock_ts'] ); // fallback
}
} else {
echo '(none)';
Expand Down
4 changes: 2 additions & 2 deletions templates/admin/paybutton-generator.php
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
if ( ! defined( 'ABSPATH' ) ) exit; // Exit if accessed directly

//Get admin's wallet address from paywall settings
$admin_address = get_option( 'paybutton_admin_wallet_address', '' );
$paybutton_admin_wallet_address = get_option( 'paybutton_admin_wallet_address', '' );
?>

<div class="wrap">
Expand All @@ -22,7 +22,7 @@
type="text"
id="pbGenTo"
placeholder="Your Wallet Address (XEC or BCH)"
value="<?php echo esc_attr( $admin_address ); ?>"
value="<?php echo esc_attr( $paybutton_admin_wallet_address ); ?>"
class="pb-generator-input"
>

Expand Down
4 changes: 2 additions & 2 deletions templates/admin/paywall-settings.php
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,8 @@
<tr>
<th scope="row"><label for="paybutton_admin_wallet_address">Wallet Address (required)</label></th>
<td>
<!-- Using the new $admin_wallet_address variable -->
<input type="text" name="paybutton_admin_wallet_address" id="paybutton_admin_wallet_address" class="regular-text" value="<?php echo esc_attr( $admin_wallet_address ); ?>" required>
<!-- Using the new $paybutton_admin_wallet_address variable -->
<input type="text" name="paybutton_admin_wallet_address" id="paybutton_admin_wallet_address" class="regular-text" value="<?php echo esc_attr( $paybutton_admin_wallet_address ); ?>" required>
<!-- This span will be populated by our bundled address validator JS -->
<span id="adminAddressValidationResult"></span>
<p class="description">Enter your wallet address to receive paywall payments.</p>
Expand Down
12 changes: 6 additions & 6 deletions templates/public/profile.php
Original file line number Diff line number Diff line change
Expand Up @@ -6,16 +6,16 @@
<div class="paybutton-profile">
<p>
<strong>Wallet Address:</strong>
<a href="https://explorer.e.cash/address/<?php echo esc_attr( $user_wallet_address ); ?>" target="_blank">
<?php echo esc_html( $user_wallet_address ); ?>
<a href="https://explorer.e.cash/address/<?php echo esc_attr( $paybutton_user_wallet_address ); ?>" target="_blank">
<?php echo esc_html( $paybutton_user_wallet_address ); ?>
</a>
</p>
<h3>Unlocked Content:</h3>
<?php if ( ! empty( $rows ) ): ?>
<?php if ( ! empty( $paybutton_rows ) ): ?>
<ol>
<?php foreach ( $rows as $row ):
$title = get_the_title( $row->post_id );
$link = get_permalink( $row->post_id );
<?php foreach ( $paybutton_rows as $paybutton_row ):
$title = get_the_title( $paybutton_row->post_id );
$link = get_permalink( $paybutton_row->post_id );
if ( $title && $link ): ?>
<li><a href="<?php echo esc_url( $link ); ?>"><?php echo esc_html( $title ); ?></a></li>
<?php endif;
Expand Down
6 changes: 3 additions & 3 deletions templates/public/sticky-header.php
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,8 @@
if ( ! defined( 'ABSPATH' ) ) exit; // Exit if accessed directly

// Check if the admin has set a wallet address
$admin_wallet_address = get_option('paybutton_admin_wallet_address', '');
if ( empty( $admin_wallet_address ) ) {
$paybutton_admin_wallet_address = get_option('paybutton_admin_wallet_address', '');
if ( empty( $paybutton_admin_wallet_address ) ) {
// If no valid address is set, do not display the sticky header.
return;
}
Expand Down Expand Up @@ -39,7 +39,7 @@
?>

<div id="cashtab-sticky-header">
<?php if ( ! $user_wallet_address ): ?>
<?php if ( ! $paybutton_user_wallet_address ): ?>
<div id="loginPaybutton"></div>
<?php else: ?>
<div class="logged-in-actions">
Expand Down