Reputation: 8348
I am developing a plugin that generates various PDFs using AJAX. I have done all but stuck on generating multiple PDFs for each user using the loop.
I prefer to generate PDF with multiple pages for each user. However, if not possible, then a separate PDF for each user would work as well.
The below code is generating only one page for probably for the first user in the loop. Then generate one blank page and stop the iteration.
Please see mPDF Library
Array
(
[group_name] => Food Lovers
[group_admin] => John Doe
[identifier] => AtR4deAVgU4Ensi1_1ac2b33a4df7c5f0cf148d6232074352
[group_order_number] => 1615962332298
[start_date] => 2021-03-20
[group_user_ids] => Array
(
[0] => 63
[1] => 73
[2] => 83
)
[63] => Array
(
[products] => Array
(
[0] => stdClass Object
(
[id] => 100
[order_number] => 2021031729863
[group_order_number] => 1615962332298
[product] => 100
[product_option] =>
[qty] => 6
[group_id] => 298
[group_admin] => 72
[group_user] => 63
[identifier] => AtR4deAVgU4Ensi1_1ac2b33a4df7c5f0cf148d6232074352
[added_at] => 2021-03-17 10:25:32
[price] => 428
[total] => 2568
[product_name] => Ea ad doloribus consequuntur et qui nihil
[customers] => Array
(
[Subotdh [email protected]] => Array
(
[name] => Subotdh Ringo
[email] => [email protected]
[qty] => 2
[total_qty] => 8
)
[[email protected]] => Array
(
[name] => Chintamani
[email] => [email protected]
[qty] => 4
[total_qty] => 17
)
)
)
...
)
[product_groups] => Array
(
[0] => stdClass Object
(
[id] => 2
[order_number] => 2021031729863
[group_order_number] => 1615962332298
[product_group] => 40
[qty] => 6
[group_id] => 298
[group_admin] => 72
[group_user] => 63
[customers] => Array
(
[0] => stdClass Object
(
[name] => Subotdh Ringo
[email] => [email protected]
[qty] => 2
[discount] => 316
)
[1] => stdClass Object
(
[name] => Chintamani
[email] => [email protected]
[qty] => 4
[discount] => 632
)
)
[identifier] => AtR4deAVgU4Ensi1_1ac2b33a4df7c5f0cf148d6232074352
[added_at] => 2021-03-17 10:25:32
[price] => 1621
[discount] => 158
[discounted_price] => 1463
[total] => 8778
[product_count] => 4
[product_group_name] => Quibusdam unde
)
...
)
[pg_discount] => Array
(
[Subotdh [email protected]] => Array
(
[name] => Subotdh Ringo
[email] => [email protected]
[total_qty] => 2
[total_discount] => 316
)
[[email protected]] => Array
(
[name] => Chintamani
[email] => [email protected]
[total_qty] => 4
[total_discount] => 632
)
[Dingon [email protected]] => Array
(
[name] => Dingon Dksi
[email] => [email protected]
[total_qty] => 1
[total_discount] => 150
)
)
)
...
)
function gs_group_users_order_pdf_generator_ajax()
{
// Check if user is logged in
if ( ! is_user_logged_in()) {
// throw error if user is not logged in
wp_send_json_error(__('Please login to order', 'group-shop'));
// we use this manually as want to print error
wp_die();
}
// Check if user is logged in
if ( ! current_user_can('administrator')) {
// throw error if user is not logged in
wp_send_json_error(__('You are not authorized to perform this action', 'group-shop'));
// we use this manually as want to print error
wp_die();
}
// check and validate nonce
if ( ! check_ajax_referer('gs_nonce', 'nonce', FALSE)) {
// throw error if validation fails
wp_send_json_error(__('Do not be nasty with validation', 'group-shop'));
// we use this manually as want to print error
wp_die();
}
$action = $_POST[ 'action' ];
$nonce = $_POST[ 'nonce' ];
$group_order_number = $_POST[ 'group_order_number' ];
$group_id = $_POST[ 'group_id' ];
$group_admin_id = $_POST[ 'group_admin' ];
$identifier = $_POST[ 'identifier' ];
$status = $_POST[ 'status' ];
$group = get_the_title($group_id);
$group_admin = get_userdata($group_admin_id);
$order = new Group_Shop_Order();
$data = $order->prepare_group_users_orders_pdf_data($group_order_number, $group_id, $group_admin_id, $identifier);
$group_user_ids = $data[ 'group_user_ids' ];
$filename = $group_order_number . '.pdf';
ob_clean();
// init mpdf
try {
$mpdf = new Mpdf([
'default_font_size' => 6,
'default_font' => 'Helvetica',
'orientation' => 'L',
]);
// write pdf
$stylesheet = file_get_contents(GROUP_SHOP_ROOT . 'public/css/invoice.css');
$mpdf->shrink_tables_to_fit = 1;
$mpdf->WriteHTML($stylesheet, HTMLParserMode::HEADER_CSS);
foreach ($group_user_ids as $group_user_id) :
$user_data = get_userdata($group_user_id);
header('Content-type: application/pdf');
header('Content-Disposition: inline; filename="' . $filename . '"');
header('Content-Transfer-Encoding: binary');
header('Accept-Ranges: bytes');
// create pdf
$markup = '<div class="info">';
$markup .= '<p><strong>' . __('User', 'group-shop') . ':</strong> ' . $user_data->display_name . '</p>';
$markup .= '<p><strong>Email:</strong> ' . $user_data->user_email . '</p>';
$markup .= '<p><strong>Admin:</strong> ' . $data[ 'group_admin' ] . '</p>';
$markup .= '<p><strong>Group:</strong> ' . $data[ 'group_name' ] . '</p>';
$markup .= '</div>';
$markup .= '<table class="table">';
// table markup
$markup .= '</table>';
// end of order table
$markup .= '<pagebreak />'; //page break
endforeach; // $group_user_ids end
$mpdf->WriteHTML($markup, HTMLParserMode::HTML_BODY, TRUE);
// create directory if not exists
$orders_dirname = 'tvm-orders' . DIRECTORY_SEPARATOR . 'user-orders';
$orders_root_dir = WP_CONTENT_DIR . DIRECTORY_SEPARATOR . $orders_dirname;
$orders_pdf_dir = $orders_root_dir . DIRECTORY_SEPARATOR . $group_order_number;
$order_pdf_url = content_url($orders_dirname . '/' . $group_order_number . '/' . $filename);
$success_message = __('Group User Orders PDF is generated and opened in another tab.', 'group-shop');
// check if pdf is exists, just open it
// @todo uncomment in production
// if (file_exists($orders_pdf_dir . DIRECTORY_SEPARATOR . $filename)) {
//
// wp_send_json_success([
// 'message' => $success_message,
// 'redirect_url' => $order_pdf_url,
// ], 200);
// }
// create directory
if ( ! is_dir($orders_pdf_dir)) {
// create directories
wp_mkdir_p($orders_pdf_dir);
// create index.php file for root and sub-folders
gs_create_file_recursively($orders_root_dir, 'index.php');
}
// save pdf file
$mpdf->Output($orders_pdf_dir . DIRECTORY_SEPARATOR . $filename, 'F');
// show success message once record updated
wp_send_json_success([
'message' => $success_message,
'generated_url' => $order_pdf_url,
], 200);
} catch
(MpdfException $e) {
// throw error if fails to insert record
wp_send_json_error(__('Something went wrong', 'group-shop'));
}
ob_end_flush();
}
// hook the function
add_action('wp_ajax_gs_group_users_order_pdf_generator', 'gs_group_users_order_pdf_generator_ajax');
add_action('wp_ajax_nopriv_gs_group_users_order_pdf_generator', 'gs_group_users_order_pdf_generator_ajax');
// to generate group user orders pdfs
$(document).on('click', '.gs-guo-pdf-orders', function () {
if (confirm('Are you sure you want to generate group users order PDFs?')) {
// process ajax data
ajax_process.call(this, '', 'gs_group_users_order_pdf_generator', 'fa-window-close');
}
});
(function ($) {
$(function () {
let response_alert = $('#response');
response_alert.hide();
/**
* process ajax data
*
* @param {string} status - Order status. Available options are P, C, D
* @param icon
* @param action
* @returns void
*/
function ajax_process(status, action, icon) {
// process data
let data_order_num = $(this).data('ordernum');
let data_gid = $(this).data('gid');
let data_gadmin = $(this).data('gadmin');
let data_identifier = $(this).data('identifier');
// button feedback and disable
$(this).find('i').removeClass(icon).addClass('fa-sync-alt');
$(this).addClass('updating').prop('disabled', true);
$.ajax({
method: 'POST',
dataType: 'json',
context: this,
url: ajax_vars.ajax_url,
data: {
action: action,
nonce: ajax_vars.nonce,
group_order_number: data_order_num,
group_id: data_gid,
group_admin: data_gadmin,
identifier: data_identifier,
status: status,
},
success: function (response) {
if (response.success === true) {
// get the response message
let message = response.data.message;
// display success message
response_alert.fadeIn().prepend(alerts('success', message));
// redirect if already exists
if (response.data.redirect_url !== undefined) {
// window.location.href = response.data.redirect_url;
window.open(
response.data.redirect_url,
'_blank'
)
}
// redirect if newly generated
if (response.data.generated_url !== undefined) {
// window.location.href = response.data.redirect_url;
window.open(
response.data.generated_url,
'_blank'
)
}
}
if (response.success === false) {
response_alert.fadeIn().prepend(alerts('error', response.data));
}
gs_alert_stats();
// update datatables data
$('#gsAllOrdersTable').DataTable().ajax.reload();
},
error: function (response) {
let error_message = (response.data === undefined) ? 'Something went wrong!' : response.data;
response_alert.fadeIn().prepend(alerts('error', error_message));
gs_alert_stats();
},
complete: function () {
$(this).find('i').removeClass('fa-sync-alt').addClass('fa-check');
$(this).removeClass('updating').prop('disabled', false);
}
});
}
// to deliver
$(document).on('click', '.gs-deliver-order', function () {
if (confirm('Are you sure you want to change status to Deliver?')) {
//process ajax data
ajax_process.call(this, 'D', 'gs_status_group_order_item', 'fa-shipping-fast');
}
});
// to pending
$(document).on('click', '.gs-pending-order', function () {
if (confirm('Are you sure you want to change status to Pending?')) {
//process ajax data
ajax_process.call(this, 'P', 'gs_status_group_order_item', 'fa-exclamation-triangle');
}
});
// to cancel
$(document).on('click', '.gs-cancel-order', function () {
if (confirm('Are you sure you want to change status to Cancel?')) {
// process ajax data
ajax_process.call(this, 'C', 'gs_status_group_order_item', 'fa-window-close');
}
});
// to generate group order pdf
$(document).on('click', '.gs-go-pdf-order', function () {
if (confirm('Are you sure you want to generate a group order PDF?')) {
// process ajax data
ajax_process.call(this, '', 'gs_group_order_pdf_generator', 'fa-window-close');
}
});
// to generate group user orders pdfs
$(document).on('click', '.gs-guo-pdf-orders', function () {
if (confirm('Are you sure you want to generate group users order PDFs?')) {
// process ajax data
ajax_process.call(this, '', 'gs_group_users_order_pdf_generator', 'fa-window-close');
}
});
/**
* response alert
*/
function gs_alert_stats() {
let gs_alert = $('.gs-message');
$('.gs-close').on('click', function () {
alerts('Clicked');
$(this).parent(gs_alert).fadeOut();
});
}
});
})(jQuery);
<button class="gs-guo-pdf-orders btn btn-sm btn-outline-info ml-3" type="button" title="Generate Group Users Order PDFs"
data-ordernum="1615962332298" data-gid="298" data-gadmin="72" data-identifier="AtR4deAVgU4Ensi1_1ac2b33a4df7c5f0cf148d6232074352">
<i class="fas fa-copy"></i></button>
Upvotes: 1
Views: 1371
Reputation: 36
I'm not sure if this is the problem. But you are rewriting $markup variable every loop in the foreach with this sentence:
$markup = '<div class="info">';
You must to define $markup as empty before the foreach and then concatenate strings inside the foreach
$markup = ''; //<-- Add this first
// Headers are better out of the loop
header('Content-type: application/pdf');
header('Content-Disposition: inline; filename="' . $filename . '"');
header('Content-Transfer-Encoding: binary');
header('Accept-Ranges: bytes');
foreach ($group_user_ids as $group_user_id) {
$user_data = get_userdata($group_user_id);
// create pdf
$markup .= '<div class="info">'; //<-- Concat here, you are rewriting
$markup .= '<p><strong>' . __('User', 'group-shop') . ':</strong> ' . $user_data->display_name . '</p>';
$markup .= '<p><strong>Email:</strong> ' . $user_data->user_email . '</p>';
$markup .= '<p><strong>Admin:</strong> ' . $data[ 'group_admin' ] . '</p>';
$markup .= '<p><strong>Group:</strong> ' . $data[ 'group_name' ] . '</p>';
$markup .= '</div>';
$markup .= '<table class="table">';
// table markup
$markup .= '</table>';
// end of order table
$markup .= '<pagebreak />'; //page break
} // $group_user_ids end
$mpdf->WriteHTML($markup, HTMLParserMode::HTML_BODY, TRUE);
Upvotes: 1