Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Issue generating pdf in hebrew language using dompdf libraray #3260

Closed
ubaidismail opened this issue Aug 16, 2023 · 7 comments
Closed

Issue generating pdf in hebrew language using dompdf libraray #3260

ubaidismail opened this issue Aug 16, 2023 · 7 comments

Comments

@ubaidismail
Copy link

ubaidismail commented Aug 16, 2023

I create PDFs using the dompdf library. The pdf is generating fine, however I want to translate the content into Hebrew. According to the documentation, https://github.com/dompdf/dompdf/wiki/About-Fonts-and-Character-Encoding. I added hebrew fonts. However, it isn't working and the content is still being translated to this "???????????????????"

function contains the html of pdf:

ob_start(); // Start output buffering
$custom_logo_id = get_theme_mod('custom_logo');
$image = 'https://booking.wemates.com/wp-content/uploads/2022/10/logo_WeMate.svg';
$logo_base64 = base64_encode(file_get_contents($image)); // Fetch and encode the image content
$signature_img_path = get_stylesheet_directory_uri() . '/img/signature-wemates.png';
$signature_base64 = base64_encode(file_get_contents($signature_img_path));
echo "<html>
    <head>
    <meta http-equiv='Content-Type' content='text/html; charset=utf-8' />
    <link href='https://fonts.googleapis.com/css2?family=Noto+Sans+Hebrew:wght@300;400&display=swap' rel='stylesheet'>
    <style>
    @import url('https://fonts.googleapis.com/css2?family=Noto+Sans+Hebrew:wght@300;400&display=swap');
    .m {
        font-family: 'Noto Sans Hebrew', sans-serif';
    }
    </style>
    </head>
    <body> <div class='m'> <table class='head container'><tr><td class='header'>";

echo '<img src="data:image/svg+xml;base64,' . $logo_base64 . '" width="200" alt="Site Logo">';
echo '</td>';
echo '</div></body></html>'; 

$content = ob_get_clean(); // Get the content from the buffer and end buffering
return $content;"

PDF Output

$dompdf = new Dompdf([
    'logOutputFile' => '',
    // authorize DomPdf to download fonts and other Internet assets
    'isRemoteEnabled' => true,
    // all directories must exist and not end with /
    'fontDir' => $tmp,
    'fontCache' => $tmp,
    'tempDir' => $tmp,
    'chroot' => $tmp,
]);
if ($dompdf) {
    $dompdf->loadHtml($pdf_content);
    
    // Set paper size and orientation (optional)
    $dompdf->setPaper('A4', 'portrait');
    
    // Render the PDF
    $dompdf->render();
    
    // Get the PDF content
    $pdf_output = $dompdf->output();
    $upload_dir = wp_upload_dir();
    $upload_path = $upload_dir['basedir'];
    
    // Generate a unique filename for the PDF
    $pdf_filename = 'invoice-hebrew' . uniqid() . '.pdf';
    
    // Build the full path to save the PDF in the upload directory
    $pdf_full_path = $upload_path . '/' . $pdf_filename;
    
    // Save the PDF in the upload directory
    file_put_contents($pdf_full_path, $pdf_output);
    
    // Attach the PDF to the WooCommerce email
    $attachments[] = $pdf_full_path;
    
    return $attachments;
} else {
    $attachments[] = $file_path;
    return $attachments;
}

pdf image: https://i.stack.imgur.com/I0fWM.png

@ubaidismail ubaidismail changed the title Pdf generate in hebrew language using dompdf libraray Isuue generating pdf in hebrew language using dompdf libraray Aug 16, 2023
@ubaidismail ubaidismail changed the title Isuue generating pdf in hebrew language using dompdf libraray Issue generating pdf in hebrew language using dompdf libraray Aug 16, 2023
@bsweeney
Copy link
Member

bsweeney commented Aug 16, 2023

Current releases of Dompdf have problems parsing CSS @import URLs that contain a semi-colon (;). Your HTML references the Google Fonts stylesheet using both a link element and an @import rule. If you remove the @import it should work OK.

Note that there are other issues that are likely to occur if the text has not been pre-processed since Dompdf does not yet fully support complex text layout (see #2619).

@ubaidismail
Copy link
Author

ubaidismail commented Aug 16, 2023

I have checked, font is now working but content in hebrew is still showing this "?????"

Font applied: https://fonts.googleapis.com/css2?family=Noto+Sans+Hebrew:wght@300;400&display=swap

@bsweeney
Copy link
Member

As I said, that semi-colon in the @import URL is problematic for current releases of Dompdf.

Instead of:

<head>
<meta http-equiv='Content-Type' content='text/html; charset=utf-8' />
<link href='https://fonts.googleapis.com/css2?family=Noto+Sans+Hebrew:wght@300;400&display=swap' rel='stylesheet'>
<style>
    @import url('https://fonts.googleapis.com/css2?family=Noto+Sans+Hebrew:wght@300;400&display=swap');
    .m {
        font-family: 'Noto Sans Hebrew', sans-serif';
    }
</style>
</head>

try this:

<head>
<meta http-equiv='Content-Type' content='text/html; charset=utf-8' />
<link href='https://fonts.googleapis.com/css2?family=Noto+Sans+Hebrew:wght@300;400&display=swap' rel='stylesheet'>
<style>
    .m {
        font-family: 'Noto Sans Hebrew', sans-serif';
    }
</style>
</head>

@ubaidismail
Copy link
Author

ubaidismail commented Aug 17, 2023

Hello, I have trye yours and removed the import url and fonts are working fine but content in hebrew still not translated and showing "???????"
Hebrew Content: הסכם השכרת דירה לא מוגן

Here is the the code:

PDF Output:

add_filter('woocommerce_email_attachments', 'hebrew_custom_attach_to_wc_emails', 10, 3);
function hebrew_custom_attach_to_wc_emails($attachments, $email_id, $order)
{


	if (!is_a($order, 'WC_Order') || !isset($email_id)) {
		return $attachments;
	}
	$file_path = 'none'; // directory of the current theme

	// Generate the PDF content

	$pdf_content = generate_custom_pdf_content($order);

	// Create a new instance of Dompdf
	$font_path = get_stylesheet_directory_uri() . '/fonts/Hebrew.ttf';
	// $font_read = file_get_contents($font_path);
	$options = new Options();
	$tmp = sys_get_temp_dir();
	// $options->set('defaultFont', 'Noto Sans Hebrew');
	$dompdf = new Dompdf([
		'logOutputFile' => '',
		// authorize DomPdf to download fonts and other Internet assets
		'isRemoteEnabled' => true,
		// all directories must exist and not end with /
		'fontDir' => $tmp,
		'fontCache' => $tmp,
		'tempDir' => $tmp,
		'chroot' => $tmp,
	]);
	if ($dompdf) {
		$dompdf->loadHtml($pdf_content);

		// Set paper size and orientation (optional)
		$dompdf->setPaper('A4', 'portrait');

		// Render the PDF
		$dompdf->render();

		// Get the PDF content
		$pdf_output = $dompdf->output();
		$upload_dir = wp_upload_dir();
		$upload_path = $upload_dir['basedir'];

		// Generate a unique filename for the PDF
		$pdf_filename = 'invoice-hebrew' . uniqid() . '.pdf';

		// Build the full path to save the PDF in the upload directory
		$pdf_full_path = $upload_path . '/' . $pdf_filename;

		// Save the PDF in the upload directory
		file_put_contents($pdf_full_path, $pdf_output);

		// Attach the PDF to the WooCommerce email
		$attachments[] = $pdf_full_path;

		return $attachments;
	} else {
		$attachments[] = $file_path;
		return $attachments;
	}
	// Load HTML content into Dompdf

}

Content function:

function generate_custom_pdf_content($order)
{
	$order_id = $order->get_id(); // Get the order ID

	// Use a unique class name
	if (!class_exists('order_document_custom_class')) {
		class order_document_custom_class extends \WPO\WC\PDF_Invoices\Documents\Order_Document
		{
			public $order; // Add a property to hold the $order object

			public function set_order($order) // Add a method to set the $order property
			{
				$this->order = $order;
			}
			public function generate_content()
			{
				ob_start(); // Start output buffering
				$custom_logo_id = get_theme_mod('custom_logo');
				$image = 'img url ';
				$logo_base64 = base64_encode(file_get_contents($image)); // Fetch and encode the image content

				$signature_img_path = get_stylesheet_directory_uri() . '/img/signature-wemates.png';
				$signature_base64 = base64_encode(file_get_contents($signature_img_path));



				echo "<html>
				<head>
				<meta http-equiv='Content-Type' content='text/html; charset=utf-8' />
				<link href='https://fonts.googleapis.com/css2?family=Noto+Sans+Hebrew:wght@300;400&display=swap' rel='stylesheet'>
				<style>
					.m {
						font-family: 'Noto Sans Hebrew', sans-serif';
					}
				</style>
				</head>
				<body> <div class='m'> <table class='head container'><tr><td class='header'>";

				echo '<img src="data:image/svg+xml;base64,' . $logo_base64 . '" width="200" alt="Site Logo">';

				echo '</td>
				
				<td class="shop-info">';

				do_action('wpo_wcpdf_before_shop_name', $this->get_type(), $this->order);
				echo '<div class="shop-name">
				<h3 style="font-size:16px;">';
				$this->shop_name();
				echo '</h3>
			</div>';
				do_action('wpo_wcpdf_after_shop_name', $this->get_type(), $this->order);
				do_action('wpo_wcpdf_before_shop_address', $this->get_type(), $this->order);
				echo '<div class="shop-address">';
				$this->shop_address();
				echo '</div>';
				do_action('wpo_wcpdf_after_shop_address', $this->get_type(), $this->order);

				echo '</td>
	</tr>
</table>';

				echo '<div class="document-label">';
				do_action('wpo_wcpdf_before_document_label', $this->get_type(), $this->order);
				echo '<h1 class="document-type-label">';
				if ($this->has_header_logo()) {
					echo $this->get_title();
				}
				echo '</h1>';
				do_action('wpo_wcpdf_after_document_label', $this->get_type(), $this->order);
				echo '</div>';

				echo '<div class="order-details">';
				do_action('wpo_wcpdf_before_order_details', $this->get_type(), $this->order);

				// Get checkout data
				$billing_first_name = WC()->checkout->get_value('billing_first_name');
				$billing_last_name = WC()->checkout->get_value('billing_last_name');
				$billing_company = WC()->checkout->get_value('billing_company');
				$billing_address_1 = WC()->checkout->get_value('billing_address_1');
				$billing_address_2 = WC()->checkout->get_value('billing_address_2');
				$billing_city = WC()->checkout->get_value('billing_city');
				$billing_state = WC()->checkout->get_value('billing_state');
				$billing_postcode = WC()->checkout->get_value('billing_postcode');
				$billing_country = WC()->checkout->get_value('billing_country');
				$billing_email = WC()->checkout->get_value('billing_email');
				$billing_phone = WC()->checkout->get_value('billing_phone');

				$order_data = $this->order;
				// var_dump($order_data);
				$decoded_data = json_decode($order_data, true);

				// Find the "_jet_abaf_wc_details" meta data
				$jet_abaf_wc_details = array_filter($decoded_data['meta_data'], function ($item) {
					return $item['key'] === '_jet_abaf_wc_details';
				});
				// var_dump($jet_abaf_wc_details);
				// Check if the key is found and get its value

				foreach ($jet_abaf_wc_details as $jet) {
					$check_in_out = $jet['value']['form_data']['_check_in_out'];

					list($check_in, $check_out) = explode(' - ', $check_in_out);
					$tot_price = $jet['value']['form_data']['room_price'];
					// Trim any leading/trailing spaces from the dates
					$check_in = trim($check_in);
					$check_out = trim($check_out);

					$check_in_date = DateTime::createFromFormat('d/m/Y', $check_in);
					$check_out_date = DateTime::createFromFormat('d/m/Y', $check_out);

					if ($check_in_date && $check_out_date) {
						// Calculate the difference between the check-in and check-out dates
						$date_interval = $check_in_date->diff($check_out_date);

						// Get the number of days from the date interval
						$days_count = $date_interval->days;

						// Get the number of months from the date interval
						$months_count = $date_interval->y * 12 + $date_interval->m;
						$remaining_days = $date_interval->d;
						// Now you can use $months_count for further processing
					} else {
						echo "Invalid date format for check-in or check-out date.";
					}
					if ($days_count == 180 || $days_count > 180) {
						// Apply a 25% discount
						$discount = 0.25;
						$discount_amount = $tot_price * $discount;
						$romm_price_after_discount = $tot_price - $discount_amount;
					} else {
						$romm_price_after_discount = $tot_price;
					}
				}
				$product_names = array();
				$quantities = array();
				$variations = array();
				$order_items = $this->order->get_items();
				foreach ($order_items as $item_id => $item) {
					$product_name = $item->get_name();
					$quantity = $item->get_quantity();
				}
				$product_names_str = implode(', ', $product_names);
				$quantities_str = implode(', ', $quantities);
				$variations_str = implode(', ', $variations);

				echo "<h2 class='elementor-heading-title elementor-size-default m' style='text-align: center;'>הסכם השכרת דירה
				לא מוגן</h2>";
	

			echo '<div class="bottom-spacer"></div><div style="clear: both;"></div><div style="float:left;">';

				do_action('wpo_wcpdf_after_order_details', $this->get_type(), $this->order);

				echo '</div><img src="data:image/png;base64,' . $signature_base64 . '" width="200px" style="float:right;" alt="Your PNG Image">';
				echo '</div></div></body></html>'; // Close order-details div

				$content = ob_get_clean(); // Get the content from the buffer and end buffering
				return $content;
			}
		}
	}

	// Instantiate the custom class
	$class_custom = new order_document_custom_class();
	$class_custom->set_order($order);

	return $class_custom->generate_content();
}

@bsweeney
Copy link
Member

You might try deleting the installed-fonts.json file from the fonts directory, in case the previous attempt to install the font produced a corrupt file.

Also, I can't really determine if there's an issue in the HTML since you've only provided the PHP that generated the page. Can you provide the actual HTML generated by your code?

@ubaidismail
Copy link
Author

Well, this link solved my issue: https://github.com/dompdf/dompdf/wiki/UnicodeHowTo

and does it support Rtl?

@bsweeney
Copy link
Member

Dompdf does not fully support rtl, no. We had started some work related to that (see #2107) but ran into issues around layout when a line was broken into multiple frames (e.g., with inline elements).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants