Skip to content
Open
Show file tree
Hide file tree
Changes from 5 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
7 changes: 4 additions & 3 deletions includes/API/API.php
Original file line number Diff line number Diff line change
Expand Up @@ -756,8 +756,9 @@ public function get_helpful_docs() {
continue;
}

$positive = (int) get_post_meta( $doc->ID, 'positive', true );
$negative = (int) get_post_meta( $doc->ID, 'negative', true );
// Get feedback counts
$positive = (int) get_post_meta($doc->ID, 'positive', true);
$negative = (int) get_post_meta($doc->ID, 'negative', true);
if ( empty( $positive ) && empty( $negative ) ) {
continue;
}
Expand Down Expand Up @@ -1231,7 +1232,7 @@ public function get_promotional_notice() {
return false;
}

/**
/**
* Handle promotional notice hidden action
*
* @since 2.1.11
Expand Down
72 changes: 41 additions & 31 deletions includes/Admin/Docs_List_Table.php
Original file line number Diff line number Diff line change
Expand Up @@ -11,49 +11,59 @@ class Docs_List_Table {
* Constructor
*/
public function __construct() {
add_filter( 'manage_docs_posts_columns', [ $this, 'docs_list_columns' ] );
add_action( 'manage_docs_posts_custom_column', [ $this, 'docs_list_columns_row' ], 10, 2 );
add_filter( 'manage_edit-docs_sortable_columns', [ $this, 'docs_sortable_columns' ] );
add_filter('manage_docs_posts_columns', [$this, 'docs_list_columns']);
add_action('manage_docs_posts_custom_column', [$this, 'docs_list_columns_row'], 10, 2);
add_filter('manage_edit-docs_sortable_columns', [$this, 'docs_sortable_columns']);

add_action( 'load-edit.php', [ $this, 'edit_docs_load' ] );
add_action( 'load-post.php', [ $this, 'add_meta_box' ] );
add_action('load-edit.php', [$this, 'edit_docs_load']);
add_action('load-post.php', [$this, 'add_meta_box']);

// load css
add_action( 'admin_print_styles-post.php', [ $this, 'helpfulness_css' ] );
add_action( 'admin_print_styles-edit.php', [ $this, 'helpfulness_css' ] );
add_action('admin_print_styles-post.php', [$this, 'helpfulness_css']);
add_action('admin_print_styles-edit.php', [$this, 'helpfulness_css']);
}

public function add_meta_box() {
add_meta_box( 'op-menu-meta-box-id', __( 'Helpfulness', 'wedocs' ), [ $this, 'helpfulness_metabox' ], 'docs', 'side', 'core' );
add_meta_box('op-menu-meta-box-id', __('Helpfulness', 'wedocs'), [$this, 'helpfulness_metabox'], 'docs', 'side', 'core');
}

public function helpfulness_css() {
if ( 'docs' != get_current_screen()->post_type ) {
if ('docs' != get_current_screen()->post_type) {
return;
} ?>
<style type="text/css">
.wedocs-positive { color: green; }
.wedocs-negative { color: red; text-align: right; }
.wedocs-positive {
color: green;
}

.wedocs-negative {
color: red;
text-align: right;
}
</style>
<?php
<?php
}

public function helpfulness_metabox() {
global $post; ?>
global $post;

$positive = (int) get_post_meta($post->ID, 'positive', true);
$negative = (int) get_post_meta($post->ID, 'negative', true);
?>
<table style="width: 100%;">
<tr>
<td class="wedocs-positive">
<span class="dashicons dashicons-thumbs-up"></span>
<?php printf( '%d', get_post_meta( $post->ID, 'positive', true ) ); ?>
<?php printf('%d', $positive); ?>
</td>

<td class="wedocs-negative">
<span class="dashicons dashicons-thumbs-down"></span>
<?php printf( '%d', get_post_meta( $post->ID, 'negative', true ) ); ?>
<?php printf('%d', $negative); ?>
</td>
</tr>
</table>
<?php
<?php
}

/**
Expand All @@ -63,41 +73,41 @@ public function helpfulness_metabox() {
*
* @return array
*/
public function docs_list_columns( $columns ) {
$vote = [ 'votes' => __( 'Votes', 'wedocs' ) ];
public function docs_list_columns($columns) {
$vote = ['votes' => __('Votes', 'wedocs')];

// insert before last element, date
$first_items = array_splice( $columns, 0, 3 ); // remove first 3 items and store to $first_items, date remains to $columns
$new_columns = array_merge( $first_items, $vote, $columns ); // merge all those
$first_items = array_splice($columns, 0, 3); // remove first 3 items and store to $first_items, date remains to $columns
$new_columns = array_merge($first_items, $vote, $columns); // merge all those

return $new_columns;
}

public function docs_sortable_columns( $columns ) {
$columns['votes'] = [ 'votes', true ];
public function docs_sortable_columns($columns) {
$columns['votes'] = ['votes', true];

return $columns;
}

public function docs_list_columns_row( $column_name, $post_id ) {
if ( 'votes' == $column_name ) {
$positive = get_post_meta( $post_id, 'positive', true );
$negative = get_post_meta( $post_id, 'negative', true );
public function docs_list_columns_row($column_name, $post_id) {
if ('votes' == $column_name) {
$positive = get_post_meta($post_id, 'positive', true);
$negative = get_post_meta($post_id, 'negative', true);

printf( '<span class="wedocs-positive">%d</span>/<span class="wedocs-negative">%d</span>', $positive, $negative );
printf('<span class="wedocs-positive">%d</span>/<span class="wedocs-negative">%d</span>', $positive, $negative);
}
}

public function edit_docs_load() {
add_filter( 'request', [ $this, 'sort_docs' ] );
add_filter('request', [$this, 'sort_docs']);
}

// Sorts the movies.
public function sort_docs( $vars ) {
public function sort_docs($vars) {
// Check if we're viewing the 'movie' post type.
if ( isset( $vars['post_type'] ) && 'docs' == $vars['post_type'] ) {
if (isset($vars['post_type']) && 'docs' == $vars['post_type']) {
// Check if 'orderby' is set to 'duration'.
if ( isset( $vars['orderby'] ) && 'votes' == $vars['orderby'] ) {
if (isset($vars['orderby']) && 'votes' == $vars['orderby']) {
$vars = array_merge(
$vars,
[
Expand Down
184 changes: 184 additions & 0 deletions includes/Ajax.php
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,18 @@ public function __construct() {
// Handle load more for DocsGrid widget
add_action('wp_ajax_wedocs_load_more_docs', [$this, 'load_more_docs']);
add_action('wp_ajax_nopriv_wedocs_load_more_docs', [$this, 'load_more_docs']);

// Handle "Was This Helpful" votes
add_action('wp_ajax_wedocs_helpful_vote', [$this, 'handle_helpful_vote']);
add_action('wp_ajax_nopriv_wedocs_helpful_vote', [$this, 'handle_helpful_vote']);

// Handle "Was This Helpful" feedback
add_action('wp_ajax_wedocs_helpful_feedback', [$this, 'handle_helpful_feedback']);
add_action('wp_ajax_nopriv_wedocs_helpful_feedback', [$this, 'handle_helpful_feedback']);

// Handle "Need More Help" form submission
add_action('wp_ajax_wedocs_need_help_submit', [$this, 'handle_need_help_submit']);
add_action('wp_ajax_nopriv_wedocs_need_help_submit', [$this, 'handle_need_help_submit']);
}

/**
Expand Down Expand Up @@ -574,4 +586,176 @@ public function quick_search() {
wp_send_json_success( $results );
}
}

/**
* Handle "Was This Helpful" vote.
*/
public function handle_helpful_vote() {
check_ajax_referer('wedocs_helpful_vote', 'nonce');

$post_id = intval($_POST['post_id'] ?? 0);
$vote = sanitize_text_field($_POST['vote'] ?? '');

if (!$post_id || !in_array($vote, ['yes', 'no'], true)) {
wp_send_json_error(['message' => __('Invalid vote.', 'wedocs')]);
}

$meta_key = $vote === 'yes' ? 'positive' : 'negative';
$current = (int) get_post_meta($post_id, $meta_key, true);
update_post_meta($post_id, $meta_key, $current + 1);

wp_send_json_success([
'yes' => (int) get_post_meta($post_id, 'positive', true),
'no' => (int) get_post_meta($post_id, 'negative', true),
]);
}
Comment thread
coderabbitai[bot] marked this conversation as resolved.

/**
* Handle "Was This Helpful" negative feedback text.
*/
public function handle_helpful_feedback() {
check_ajax_referer('wedocs_helpful_vote', 'nonce');

$post_id = intval($_POST['post_id'] ?? 0);
$feedback = sanitize_textarea_field($_POST['feedback'] ?? '');

if (!$post_id || empty($feedback)) {
wp_send_json_error(['message' => __('Invalid feedback.', 'wedocs')]);
}

$existing = get_post_meta($post_id, '_wedocs_helpful_feedback', true);
if (!is_array($existing)) {
$existing = [];
}

$existing[] = [
'feedback' => $feedback,
'date' => current_time('mysql'),
'ip' => sanitize_text_field($_SERVER['REMOTE_ADDR'] ?? ''),
];

update_post_meta($post_id, '_wedocs_helpful_feedback', $existing);
wp_send_json_success();
}
Comment thread
coderabbitai[bot] marked this conversation as resolved.

/**
* Handle "Need More Help" contact form submission.
*/
public function handle_need_help_submit() {
$widget_id = sanitize_text_field($_POST['widget_id'] ?? '');

if (!wp_verify_nonce($_POST['nonce'] ?? '', 'wedocs_need_help_' . $widget_id)) {
wp_send_json_error(['message' => __('Security check failed.', 'wedocs')]);
}

$name = sanitize_text_field($_POST['name'] ?? '');
$email = sanitize_email($_POST['email'] ?? '');
$subject = sanitize_text_field($_POST['subject'] ?? '');
$message = sanitize_textarea_field($_POST['message'] ?? '');
$page_url = esc_url_raw($_POST['page_url'] ?? '');
$page_title = sanitize_text_field($_POST['page_title'] ?? '');
$recipient = sanitize_email($_POST['recipient'] ?? get_option('admin_email'));
$save_to_elementor = sanitize_text_field($_POST['save_to_elementor'] ?? '');
$post_id = intval($_POST['post_id'] ?? 0);

if (empty($message)) {
wp_send_json_error(['message' => __('Message is required.', 'wedocs')]);
}

if (empty($recipient) || !is_email($recipient)) {
$recipient = get_option('admin_email');
}

// Send email
$email_subject = !empty($subject) ? $subject : sprintf(__('[weDocs] Support request from %s', 'wedocs'), $page_title);

$body = sprintf(__("Name: %s\n", 'wedocs'), $name ?: __('Not provided', 'wedocs'));
$body .= sprintf(__("Email: %s\n", 'wedocs'), $email ?: __('Not provided', 'wedocs'));
$body .= sprintf(__("Page: %s (%s)\n\n", 'wedocs'), $page_title, $page_url);
$body .= sprintf(__("Message:\n%s", 'wedocs'), $message);

$headers = ['Content-Type: text/plain; charset=UTF-8'];
if (!empty($email) && is_email($email)) {
$headers[] = 'Reply-To: ' . ($name ? "$name <$email>" : $email);
}

$sent = wp_mail($recipient, $email_subject, $body, $headers);

// Save to Elementor Pro submissions if enabled
if ($save_to_elementor === 'yes') {
$this->save_to_elementor_submissions($widget_id, $post_id, $page_url, $page_title, [
'name' => $name,
'email' => $email,
'subject' => $subject,
'message' => $message,
]);
}

if ($sent) {
wp_send_json_success();
} else {
wp_send_json_error(['message' => __('Failed to send email. Please try again.', 'wedocs')]);
}
}

/**
* Save form data to Elementor Pro submissions table.
*
* @param string $widget_id The Elementor widget ID.
* @param int $post_id The post/page ID where the form was submitted.
* @param string $page_url The page URL (referer).
* @param string $page_title The page title.
* @param array $fields Associative array of field id => value.
*/
private function save_to_elementor_submissions($widget_id, $post_id, $page_url, $page_title, $fields) {
// Check if Elementor Pro submissions are available
if (!class_exists('\ElementorPro\Modules\Forms\Submissions\Database\Query')) {
return;
}

$query = \ElementorPro\Modules\Forms\Submissions\Database\Query::get_instance();

$fields_data = [];
foreach ($fields as $id => $value) {
if (empty($value)) {
continue;
}

$type = 'text';
if ($id === 'email') {
$type = 'email';
} elseif ($id === 'message') {
$type = 'textarea';
}

$fields_data[] = [
'id' => $id,
'value' => $value,
'type' => $type,
];
}

if (empty($fields_data)) {
return;
}

$submission_data = [
'post_id' => $post_id ?: 0,
'referer' => $page_url,
'referer_title' => $page_title,
'element_id' => $widget_id,
'form_name' => __('weDocs - Need More Help', 'wedocs'),
'campaign_id' => 0,
'user_id' => get_current_user_id() ?: null,
'user_ip' => sanitize_text_field($_SERVER['REMOTE_ADDR'] ?? ''),
'user_agent' => sanitize_text_field($_SERVER['HTTP_USER_AGENT'] ?? ''),
'actions_count' => 1,
'actions_succeeded_count' => 1,
'meta' => wp_json_encode([
'edit_post_id' => $post_id ?: 0,
]),
];

$query->add_submission($submission_data, $fields_data);
}
}
Loading
Loading