logger = Qixit_Logger::get_instance(); // Inject paid-comment CSS/JS through WordPress enqueue APIs. add_action('wp_enqueue_scripts', array($this, 'inject_comment_scripts')); // Server-side guard: block free/native comment submissions on paid-comment posts. add_filter('preprocess_comment', array($this, 'enforce_paid_comment_submission'), 1); // AJAX handlers for comment submission add_action('wp_ajax_qixit_submit_paid_comment', array($this, 'ajax_submit_paid_comment')); add_action('wp_ajax_nopriv_qixit_submit_paid_comment', array($this, 'ajax_submit_paid_comment')); // Auto-enable WordPress comments when paid comments are enabled add_action('save_post', array($this, 'auto_enable_comments_on_save'), 20, 3); } /** * Auto-enable WordPress comments and sync comments product when paid comments are enabled */ public function auto_enable_comments_on_save($post_id, $post, $update) { if (!empty($GLOBALS['qixit_skip_save_hooks'])) { return; } // Skip autosaves and revisions if (defined('DOING_AUTOSAVE') && DOING_AUTOSAVE) return; if (wp_is_post_revision($post_id)) return; if (!$post instanceof WP_Post) { $post = get_post($post_id); } if (!$post instanceof WP_Post) { return; } // Check if paid comments are being enabled OR unpaid comments are explicitly allowed. // save_post originates from WP editor submit; nonce is validated by metabox save handlers. // phpcs:ignore WordPress.Security.NonceVerification.Missing -- state change is protected by editor save flow nonce checks. $enable_paid_comments = isset($_POST['qixit_enable_paid_comments']) && sanitize_text_field(wp_unslash($_POST['qixit_enable_paid_comments'])) === '1'; // phpcs:ignore WordPress.Security.NonceVerification.Missing -- state change is protected by editor save flow nonce checks. $allow_unpaid_comments = isset($_POST['qixit_allow_unpaid_comments']) && sanitize_text_field(wp_unslash($_POST['qixit_allow_unpaid_comments'])) === '1'; if ($allow_unpaid_comments) { update_post_meta($post_id, '_qixit_allow_unpaid_comments', '1'); // phpcs:ignore WordPress.Security.NonceVerification.Missing -- state change is protected by editor save flow nonce checks. } elseif (isset($_POST['qixit_allow_unpaid_comments'])) { delete_post_meta($post_id, '_qixit_allow_unpaid_comments'); } if ($enable_paid_comments || $allow_unpaid_comments) { // Ensure WordPress comments are open for this post (no nested save_post). if ($post->comment_status !== 'open') { $GLOBALS['qixit_skip_save_hooks'] = true; wp_update_post(array( 'ID' => $post_id, 'comment_status' => 'open' )); $GLOBALS['qixit_skip_save_hooks'] = false; $this->logger->log("Auto-enabled WordPress comments for post {$post_id} (paid or unpaid comments enabled)"); } // Auto-sync the comments product to the API $product_manager = Qixit_Product::get_instance(); $product = $product_manager->get_product_by_post_id($post_id); $existing_comments_guid = $product_manager->get_comments_purchase_guid_for_post($post_id, $product); if ($enable_paid_comments && $product && empty($existing_comments_guid)) { $this->logger->log("Auto-syncing comments product for post {$post_id}"); try { $product_manager->sync_product_to_api($post_id); } catch (\Throwable $e) { $this->logger->log('Auto-sync comments product failed: ' . $e->getMessage(), 'error'); } } } } /** * Enable paid comments for a post (called from bulk actions) */ public static function enable_paid_comments_for_post($post_id, $price = 0.05, $sync_to_api = true) { global $wpdb; $product_manager = Qixit_Product::get_instance(); $product = $product_manager->get_product_by_post_id($post_id); // Ensure minimum price $price = max(0.01, floatval($price)); if ($product) { $product_manager->update_local_product($product->product_id, array( 'enable_paid_comments' => 1, 'premium_comments_cost' => $price )); } else { $product_manager->create_product_for_post($post_id, array( 'qixit_post_type' => QIXIT_REG, 'enable_paid_comments' => 1, 'premium_comments_cost' => $price )); } // Auto-enable WordPress comments wp_update_post(array( 'ID' => $post_id, 'comment_status' => 'open' )); // Sync to API to create comments product when requested. if ($sync_to_api) { $product_manager->sync_product_to_api($post_id); } return true; } /** * Disable paid comments for a post */ public static function disable_paid_comments_for_post($post_id) { $product_manager = Qixit_Product::get_instance(); $product = $product_manager->get_product_by_post_id($post_id); if ($product) { $product_manager->update_local_product($product->product_id, array( 'enable_paid_comments' => 0, 'premium_comments_cost' => 0 )); } return true; } /** * Whether site-level fallback paid comments are enabled. * * @return bool */ public static function is_global_paid_comments_enabled() { return boolval(get_option('qixit_enable_paid_comments_global', false)); } /** * Site-level default comment price for global fallback. * * @return float */ public static function get_global_paid_comments_default_price() { $price = floatval(get_option('qixit_global_paid_comments_price', 0.05)); return max(0.01, round($price, 2)); } /** * Per-post opt-out for global paid comments fallback. * * @param int $post_id * @return bool */ private static function is_global_paid_comments_opted_out($post_id) { return get_post_meta(intval($post_id), '_qixit_paid_comments_opt_out', true) === '1'; } /** * Determine effective paid-comments state for a post. * Priority: * 1) Explicit per-post paid-comments setting * 2) Site-level fallback setting * Explicit unpaid/opt-out flags always disable paid comments. * * @param int $post_id * @param object|null $product * @return bool */ public static function is_paid_comments_effectively_enabled($post_id, $product = null) { $post_id = intval($post_id); if ($post_id <= 0) { return false; } if (get_post_meta($post_id, '_qixit_allow_unpaid_comments', true) === '1') { return false; } if (self::is_global_paid_comments_opted_out($post_id)) { return false; } if ($product === null) { $product = Qixit_Product::get_instance()->get_product_by_post_id($post_id); } if ($product && isset($product->enable_paid_comments) && intval($product->enable_paid_comments) === 1) { return true; } return self::is_global_paid_comments_enabled(); } /** * Determine effective comment price for a post. * * @param int $post_id * @param object|null $product * @return float */ public static function get_effective_comment_price($post_id, $product = null) { if ($product === null) { $product = Qixit_Product::get_instance()->get_product_by_post_id($post_id); } if ($product && isset($product->premium_comments_cost) && floatval($product->premium_comments_cost) > 0) { return max(0.01, floatval($product->premium_comments_cost)); } return self::get_global_paid_comments_default_price(); } /** * Inject JavaScript to make comment submit button use microframe * Uses the same pattern as product purchase links - tooltip on hover, microframe on click */ public function inject_comment_scripts() { // Only on singular posts/pages with comments if (!is_singular() || !comments_open()) { return; } // Ensure jQuery is available for comment-form interception. wp_enqueue_script('jquery'); // In some themes/footer contexts get_the_ID() can be empty in wp_footer. // Resolve from queried object first, then fall back to loop/global post IDs. $post_id = intval(get_queried_object_id()); if ($post_id <= 0) { $post_id = intval(get_the_ID()); } if ($post_id <= 0 && isset($GLOBALS['post']) && isset($GLOBALS['post']->ID)) { $post_id = intval($GLOBALS['post']->ID); } if ($post_id <= 0) { $this->logger->log('Qixit Comments: Unable to resolve post ID in footer; skipping paid-comment script injection.', 'warning'); return; } $product_manager = Qixit_Product::get_instance(); $product = $product_manager->get_product_by_post_id($post_id); // Check if paid comments are enabled (per-post or global fallback). if (!self::is_paid_comments_effectively_enabled($post_id, $product)) { return; } // Ensure local product context exists when global fallback is active. if (!$product) { self::enable_paid_comments_for_post($post_id, self::get_global_paid_comments_default_price(), false); $product = $product_manager->get_product_by_post_id($post_id); } $comments_cost = self::get_effective_comment_price($post_id, $product); $comments_guid = $product_manager->get_comments_purchase_guid_for_post($post_id, $product); // If paid comments are enabled but GUID is missing, attempt a single auto-sync // to provision/resolve the canonical comments product for this post context. if (empty($comments_guid)) { $sync_lock_key = 'qixit_comments_guid_sync_lock_' . $post_id; if (!get_transient($sync_lock_key)) { set_transient($sync_lock_key, 1, 30); $product_manager->sync_product_to_api($post_id); $product = $product_manager->get_product_by_post_id($post_id); $comments_guid = $product_manager->get_comments_purchase_guid_for_post($post_id, $product); } } elseif ($comments_cost > 0) { // Keep shared comments product price/delivery URL aligned with this post before checkout. $api_price = function_exists('qixit_get_product_price') ? qixit_get_product_price($comments_guid) : 0; if ($api_price <= 0 || abs($api_price - $comments_cost) > 0.0001) { $sync_lock_key = 'qixit_comments_price_sync_' . $post_id; if (!get_transient($sync_lock_key)) { set_transient($sync_lock_key, 1, 60); $product_manager->sync_comments_product_to_api($post_id, $product); delete_transient('qixit_product_price_' . $comments_guid); $api_price = function_exists('qixit_get_product_price') ? qixit_get_product_price($comments_guid) : 0; } } if ($api_price > 0) { $comments_cost = $api_price; } } // Get products portal URL for purchase $products_web_url = qixit_get_products_web_url(); $purchase_url = ''; if (!empty($comments_guid)) { $purchase_url = rtrim($products_web_url, '/') . '/purchasefast?PID=' . urlencode($comments_guid); } // Format price for tooltip (2 decimal places) $price_display = '$' . number_format($comments_cost, 2); if (class_exists('Qixit_Frontend')) { Qixit_Frontend::require_assets(); } wp_enqueue_script('qixit-frontend'); wp_add_inline_style('qixit-frontend', ' .qixit-comment-tooltip-wrapper { position: relative; display: inline-block; } .qixit-comment-tooltip-wrapper .qixit-comment-tooltip { visibility: hidden; opacity: 0; position: absolute; bottom: calc(100% + 8px); left: 50%; transform: translateX(-50%); background: linear-gradient(135deg, var(--qixit-brand-start, #52ac5b) 0%, var(--qixit-brand-end, #306817) 100%); color: white; padding: 6px 12px; border-radius: 6px; font-size: 13px; font-weight: 500; white-space: nowrap; z-index: 10000; box-shadow: 0 2px 8px rgba(48, 104, 23, 0.35); transition: opacity 0.2s, visibility 0.2s; } .qixit-comment-tooltip-wrapper .qixit-comment-tooltip::after { content: ""; position: absolute; top: 100%; left: 50%; transform: translateX(-50%); border: 6px solid transparent; border-top-color: var(--qixit-brand-end, #306817); } .qixit-comment-tooltip-wrapper:hover .qixit-comment-tooltip { visibility: visible; opacity: 1; } '); $comment_config = array( 'postId' => intval($post_id), 'price' => floatval($comments_cost), 'priceDisplay' => $price_display, 'purchaseUrl' => $purchase_url, 'commentsGuid' => $comments_guid, 'ajaxUrl' => admin_url('admin-ajax.php'), 'nonce' => wp_create_nonce('qixit_comment_nonce'), ); wp_add_inline_script('qixit-frontend', 'window.qixitCommentConfig = ' . wp_json_encode($comment_config) . ';', 'before'); wp_add_inline_script('qixit-frontend', <<<'JS' (function($) { 'use strict'; if (typeof $ === 'undefined') { console.warn('Qixit Comments: jQuery not available; skipping paid comment JS initialization.'); return; } var qixitCommentConfig = window.qixitCommentConfig || {}; var pendingComment = null; var messageHandlerBound = false; $(document).ready(function() { initCommentPayment(); }); function initCommentPayment() { // Bind at form level first so theme-specific submit buttons cannot bypass interception. var $form = $('#commentform, form[action*="wp-comments-post.php"]').first(); if (!$form.length) { console.log('Qixit Comments: No comment form found'); return; } // Find submit control if present (input/button variants). var $submitBtn = $form.find('#submit, input[type="submit"], button[type="submit"]').first(); // Check if comments product is configured if (!qixitCommentConfig.purchaseUrl) { console.log('Qixit Comments: Paid comments enabled but product not configured. GUID: ' + qixitCommentConfig.commentsGuid); return; } console.log('Qixit Comments: Initializing with price ' + qixitCommentConfig.priceDisplay); // Wrap button and add tooltip (positioned above) when submit control exists. if ($submitBtn.length && !$submitBtn.parent().hasClass('qixit-comment-tooltip-wrapper')) { $submitBtn.wrap(''); $submitBtn.parent().append('Purchase for ' + qixitCommentConfig.priceDisplay + ''); } function startPaidCommentFlow(e) { // If we have a pending paid comment, allow submission if (pendingComment && pendingComment.paid) { return true; } if (e && typeof e.preventDefault === 'function') { e.preventDefault(); } if (e && typeof e.stopImmediatePropagation === 'function') { e.stopImmediatePropagation(); } // Get comment data var $comment = $form.find('textarea[name="comment"], #comment'); var $author = $form.find('input[name="author"]'); var $email = $form.find('input[name="email"]'); var $url = $form.find('input[name="url"]'); var $parent = $form.find('input[name="comment_parent"]'); if (!$comment.length || !$comment.val().trim()) { alert('Please enter a comment.'); return false; } // Store comment data pendingComment = { comment: $comment.val(), author: $author.length ? $author.val() : '', email: $email.length ? $email.val() : '', url: $url.length ? $url.val() : '', parent: $parent.length ? $parent.val() : '0', postId: qixitCommentConfig.postId, paid: false }; // Store in sessionStorage sessionStorage.setItem('qixit_pending_comment_' + qixitCommentConfig.postId, JSON.stringify(pendingComment)); // Bind message handler if not already bound if (!messageHandlerBound) { window.addEventListener('message', handlePaymentMessage); messageHandlerBound = true; } // Get anchor position for microframe placement (prefer submit button; fallback to form box). var anchorEl = $submitBtn.length ? $submitBtn[0] : $form[0]; var buttonRect = anchorEl.getBoundingClientRect(); var clickX = buttonRect.left + (buttonRect.width / 2) + window.pageXOffset; var clickY = buttonRect.top + window.pageYOffset; // Top anchor so frame opens above // Open microframe using QixitFrontend if (typeof window.QixitFrontend !== 'undefined') { // Create a temporary trigger element var $fakeTrigger = $('') .attr('data-purchase-url', qixitCommentConfig.purchaseUrl) .attr('data-product-guid', qixitCommentConfig.commentsGuid) .attr('data-post-id', qixitCommentConfig.postId) .attr('data-comment-checkout', 'true') .css({ position: 'absolute', left: '-9999px' }); $('body').append($fakeTrigger); window.QixitFrontend.openMicroFrame($fakeTrigger[0], true, clickX, clickY); $fakeTrigger.remove(); } else { // Fallback: open in popup window.open(qixitCommentConfig.purchaseUrl, 'qixit_payment', 'width=400,height=300'); } return false; } $form.off('submit.qixitPaidComment').on('submit.qixitPaidComment', startPaidCommentFlow); $submitBtn.off('click.qixitPaidComment').on('click.qixitPaidComment', startPaidCommentFlow); } function handlePaymentMessage(event) { if (!event.data) { return; } var isPurchaseComplete = event.data.type === 'purchaseComplete'; var isPurchaseRedirect = event.data.type === 'redirect'; if (!isPurchaseComplete && !isPurchaseRedirect) { return; } console.log('Qixit Comments: Received purchase callback', event.data); // Get stored comment var stored = sessionStorage.getItem('qixit_pending_comment_' + qixitCommentConfig.postId); if (!stored) { console.log('Qixit Comments: No pending comment found'); return; } pendingComment = JSON.parse(stored); // Get username from message var qixitUsername = event.data.username || event.data.qixitUser || ''; if (!qixitUsername) { console.log('Qixit Comments: No username in payment response'); // Try to get from userId as fallback qixitUsername = event.data.userId || 'Anonymous'; } pendingComment.qixitUsername = qixitUsername; pendingComment.paid = true; pendingComment.txnId = event.data.transactionId || event.data.txnId || ''; sessionStorage.setItem('qixit_pending_comment_' + qixitCommentConfig.postId, JSON.stringify(pendingComment)); console.log('Qixit Comments: Submitting comment for user ' + qixitUsername); if (window.QixitFrontend && typeof window.QixitFrontend.closeMicroFrame === 'function') { window.QixitFrontend.closeMicroFrame(); } // Submit comment via AJAX submitPaidComment(); } function submitPaidComment() { if (!pendingComment || !pendingComment.paid) { console.log('Qixit Comments: No paid comment to submit'); return; } console.log('Qixit Comments: Posting comment via AJAX'); $.ajax({ url: qixitCommentConfig.ajaxUrl, type: 'POST', data: { action: 'qixit_submit_paid_comment', nonce: qixitCommentConfig.nonce, post_id: pendingComment.postId, comment: pendingComment.comment, author: pendingComment.author, email: pendingComment.email, url: pendingComment.url, parent: pendingComment.parent, qixit_username: pendingComment.qixitUsername, txn_id: pendingComment.txnId || '' }, success: function(response) { console.log('Qixit Comments: AJAX response', response); // Clear stored data sessionStorage.removeItem('qixit_pending_comment_' + qixitCommentConfig.postId); pendingComment = null; if (response.success) { // Refresh page and scroll to new comment var commentId = response.data.comment_id; var currentUrl = window.location.href.split('#')[0].split('?')[0]; window.location.href = currentUrl + '#comment-' + commentId; window.location.reload(); } else { alert('Error posting comment: ' + (response.data ? response.data.message : 'Unknown error')); } }, error: function(xhr, status, error) { console.log('Qixit Comments: AJAX error', status, error); alert('Error posting comment. Please try again.'); } }); } })(window.jQuery); JS ); } /** * AJAX handler for submitting paid comments */ public function ajax_submit_paid_comment() { $this->logger->log("ajax_submit_paid_comment called"); // Verify nonce if (!isset($_POST['nonce']) || !wp_verify_nonce(sanitize_text_field(wp_unslash($_POST['nonce'])), 'qixit_comment_nonce')) { $this->logger->log("Nonce verification failed"); wp_send_json_error(array('message' => __('Security check failed.', '2waymicropay'))); } $post_id = isset($_POST['post_id']) ? intval(wp_unslash($_POST['post_id'])) : 0; $comment_text = isset($_POST['comment']) ? sanitize_textarea_field(wp_unslash($_POST['comment'])) : ''; $author = isset($_POST['author']) ? sanitize_text_field(wp_unslash($_POST['author'])) : ''; $email = isset($_POST['email']) ? sanitize_email(wp_unslash($_POST['email'])) : ''; $url = isset($_POST['url']) ? esc_url_raw(wp_unslash($_POST['url'])) : ''; $parent = isset($_POST['parent']) ? intval(wp_unslash($_POST['parent'])) : 0; $qixit_username = isset($_POST['qixit_username']) ? sanitize_text_field(wp_unslash($_POST['qixit_username'])) : ''; $txn_id = isset($_POST['txn_id']) ? sanitize_text_field(wp_unslash($_POST['txn_id'])) : ''; $this->logger->log("Comment data: post_id={$post_id}, author={$author}, qixit_username={$qixit_username}, txn_id={$txn_id}"); // Validate required fields if (empty($comment_text)) { wp_send_json_error(array('message' => __('Comment text is required.', '2waymicropay'))); } if (empty($qixit_username)) { wp_send_json_error(array('message' => __('Payment verification failed.', '2waymicropay'))); } // Check if paid comments are enabled for this post $product = Qixit_Product::get_instance()->get_product_by_post_id($post_id); if (!self::is_paid_comments_effectively_enabled($post_id, $product)) { $this->logger->log("Paid comments not enabled for post {$post_id}"); wp_send_json_error(array('message' => __('Paid comments are not enabled for this post.', '2waymicropay'))); } $product_manager = Qixit_Product::get_instance(); $comments_guid = $product_manager->get_comments_purchase_guid_for_post($post_id, $product); if ($comments_guid === '') { wp_send_json_error(array('message' => __('Comment product is not configured.', '2waymicropay'))); } $payment_verified = false; if ($txn_id !== '') { $verify = qixit_verify_purchase_with_portal($txn_id, $comments_guid, $qixit_username, null); $payment_verified = !empty($verify['success']); if (!$payment_verified) { $this->logger->log( "Paid comment txn verification failed for {$qixit_username} on {$comments_guid}: " . (isset($verify['message']) ? $verify['message'] : 'unknown'), 'warning' ); } } if (!$payment_verified) { $ownership = Qixit_API::get_instance()->check_ownership($comments_guid, $qixit_username); $payment_verified = ( !empty($ownership['success']) && !empty($ownership['data']['owned']) ); } if (!$payment_verified) { $this->logger->log("Paid comment rejected — payment not verified for {$qixit_username} on {$comments_guid}", 'warning'); wp_send_json_error(array('message' => __('Payment verification failed.', '2waymicropay'))); } // Get WordPress user if logged in $user_id = 0; if (is_user_logged_in()) { $current_user = wp_get_current_user(); $user_id = $current_user->ID; if (empty($author)) { $author = $current_user->display_name; } if (empty($email)) { $email = $current_user->user_email; } } // If still no author, use Qixit username if (empty($author)) { $author = $qixit_username; } // Append Qixit username in parentheses after author name (for accountability) $display_author = $author; if ($author !== $qixit_username) { $display_author = $author . ' (' . $qixit_username . ')'; } // Insert the comment with auto-approve $comment_data = array( 'comment_post_ID' => $post_id, 'comment_content' => $comment_text, 'comment_author' => $display_author, 'comment_author_email' => $email, 'comment_author_url' => $url, 'comment_parent' => $parent, 'user_id' => $user_id, 'comment_approved' => 1 // Auto-approve paid comments ); $this->logger->log("Inserting comment: " . json_encode($comment_data)); $comment_id = wp_insert_comment($comment_data); if ($comment_id) { // Save metadata for internal tracking (not displayed publicly) update_comment_meta($comment_id, 'qixit_paid_comment', 1); update_comment_meta($comment_id, 'qixit_username', $qixit_username); update_comment_meta($comment_id, 'qixit_comment_paid_date', current_time('mysql')); if ($txn_id !== '') { update_comment_meta($comment_id, 'qixit_comment_txn_id', $txn_id); } $this->logger->log("Paid comment #{$comment_id} posted by Qixit user: {$qixit_username}"); wp_send_json_success(array( 'message' => __('Comment posted successfully!', '2waymicropay'), 'comment_id' => $comment_id )); } else { $this->logger->log("Failed to insert comment"); wp_send_json_error(array('message' => __('Failed to post comment.', '2waymicropay'))); } } /** * Block native/free comment submissions when paid comments are required. * * @param array $comment_data Incoming comment payload. * @return array */ public function enforce_paid_comment_submission($comment_data) { $post_id = isset($comment_data['comment_post_ID']) ? intval($comment_data['comment_post_ID']) : 0; if ($post_id <= 0) { return $comment_data; } $product = Qixit_Product::get_instance()->get_product_by_post_id($post_id); if (!self::is_paid_comments_effectively_enabled($post_id, $product)) { return $comment_data; } // Allow only the plugin's paid AJAX flow for paid-comment posts. // Require a valid nonce so native/free submissions cannot spoof this path. if (defined('DOING_AJAX') && DOING_AJAX) { $nonce = isset($_POST['nonce']) ? sanitize_text_field(wp_unslash($_POST['nonce'])) : ''; if (!empty($nonce) && wp_verify_nonce($nonce, 'qixit_comment_nonce')) { $action = isset($_POST['action']) ? sanitize_key(wp_unslash($_POST['action'])) : ''; if ($action === 'qixit_submit_paid_comment') { return $comment_data; } } } $this->logger->log("Blocked native/free comment submit on paid-comment post {$post_id}"); wp_die( esc_html__('This post requires paid comments. Please use the paid comment button to purchase before posting.', '2waymicropay'), esc_html__('Payment Required', '2waymicropay'), array('response' => 403) ); } /** * Check if paid comments are enabled for a post */ public function is_paid_comments_enabled($post_id) { $product = Qixit_Product::get_instance()->get_product_by_post_id($post_id); return self::is_paid_comments_effectively_enabled($post_id, $product); } /** * Get comment price for a post */ public function get_comment_price($post_id) { $product = Qixit_Product::get_instance()->get_product_by_post_id($post_id); return self::get_effective_comment_price($post_id, $product); } /** * Apply site-level fallback paid-comment defaults across existing posts/pages. * This enables rapid anti-spam monetization while preserving per-post overrides. * * @return array{processed:int,synced:int} */ public static function apply_global_paid_comments_defaults_to_existing_content() { if (!self::is_global_paid_comments_enabled()) { return array('processed' => 0, 'synced' => 0); } $post_ids = get_posts(array( 'post_type' => array('post', 'page'), 'post_status' => array('publish', 'future', 'draft', 'pending', 'private'), 'fields' => 'ids', 'numberposts' => -1, )); if (!is_array($post_ids) || empty($post_ids)) { return array('processed' => 0, 'synced' => 0); } $default_price = self::get_global_paid_comments_default_price(); $processed = 0; $seed_post_id = 0; foreach ($post_ids as $post_id) { $post_id = intval($post_id); if ($post_id <= 0) { continue; } if (get_post_meta($post_id, '_qixit_allow_unpaid_comments', true) === '1') { continue; } if (self::is_global_paid_comments_opted_out($post_id)) { continue; } self::enable_paid_comments_for_post($post_id, $default_price, false); $processed++; if ($seed_post_id === 0) { $seed_post_id = $post_id; } } $synced = 0; if ($seed_post_id > 0) { $result = Qixit_Product::get_instance()->sync_product_to_api($seed_post_id); if (!empty($result['success'])) { $synced = 1; } } return array('processed' => $processed, 'synced' => $synced); } } // Initialize Qixit_Comments::get_instance();