diff --git a/app/code/Magento/Sales/Model/Order/Pdf/AbstractPdf.php b/app/code/Magento/Sales/Model/Order/Pdf/AbstractPdf.php
index ba82478c9cea1..bc1cd32931471 100644
--- a/app/code/Magento/Sales/Model/Order/Pdf/AbstractPdf.php
+++ b/app/code/Magento/Sales/Model/Order/Pdf/AbstractPdf.php
@@ -28,6 +28,13 @@ abstract class AbstractPdf extends \Magento\Framework\DataObject
*/
public $y;
+ /**
+ * Is RTL Country Order
+ *
+ * @var bool;
+ */
+ public $isRTLCountry = FALSE;
+
/**
* Item renderers with render type key
* model => the model name
@@ -307,6 +314,126 @@ protected function insertLogo(&$page, $store = null)
}
}
+ /**
+ * Is RTL Characters
+ *
+ * @param string $locale
+ * @return bool
+ */
+ protected function isRTLLocale($locale)
+ {
+ // from magento List of allowed locales
+ $rtlLocales = array(
+ 'ar_DZ', /*Arabic (Algeria)*/
+ 'ar_EG', /*Arabic (Egypt)*/
+ 'ar_KW', /*Arabic (Kuwait)*/
+ 'ar_MA', /*Arabic (Morocco)*/
+ 'ar_SA', /*Arabic (Saudi Arabia)*/
+ 'fa_IR', /*Persian (Iran)*/
+ 'he_IL' /*Hebrew (Israel)*/
+ );
+
+ if (in_array($locale, $rtlLocales)) {
+ return TRUE;
+ }
+ return FALSE;
+ }
+
+ /**
+ * Is RTL Currencies
+ *
+ * @param string $currency
+ * @return bool
+ */
+ protected function isRTLCurrency($currency)
+ {
+ // from magento List of allowed currencies
+ $rtlCurrencies = array(
+ 'AFN', /*Afghani*/
+ 'DZD', /*Algerian Dinar*/
+ 'BHD', /*Bahraini Dinar*/
+ 'DJF', /*Djibouti Franc*/
+ 'EGP', /*Egyptian Pound*/
+ 'IQD', /*Iraqi Dinar*/
+ 'ILS', /*Israeli New Sheqel*/
+ 'JOD', /*Jordanian Dinar*/
+ 'KWD', /*Kuwaiti Dinar*/
+ 'LBP', /*Lebanese Pound*/
+ 'LYD', /*Libyan Dinar*/
+ 'MRO', /*Mauritania Ouguiya*/
+ 'MAD', /*Moroccan Dirham*/
+ 'OMR', /*Oman Rial*/
+ 'PKR', /*Pakistan Rupee*/
+ 'QAR', /*Qatari Rial*/
+ 'SOS', /*Somali Shilling*/
+ 'SDG', /*Sudanese Pound*/
+ 'SYP', /*Syrian Pound*/
+ 'TND', /*Tunisian Dinar*/
+ 'AED', /*United Arab Emirates Dirham*/
+ 'YER' /*Yemeni Rial*/
+ );
+
+ if (in_array($currency, $rtlCurrencies)) {
+ return TRUE;
+ }
+ return FALSE;
+ }
+
+ /**
+ * Is Shipping Country uses RTL language
+ *
+ * @param string $country
+ * @return bool
+ */
+ protected function isRTLCountry($country)
+ {
+ // from magento USPS countries
+ $rtlCountries = array(
+ 'AE' => 'United Arab Emirates',
+ 'AF' => 'Afghanistan',
+ 'BH' => 'Bahrain',
+ 'DJ' => 'Djibouti',
+ 'EG' => 'Egypt',
+ 'IL' => 'Israel',
+ 'IQ' => 'Iraq',
+ 'JO' => 'Jordan',
+ 'KM' => 'Comoros',
+ 'KW' => 'Kuwait',
+ 'LB' => 'Lebanon',
+ 'LY' => 'Libya',
+ 'MA' => 'Morocco',
+ 'MR' => 'Mauritania',
+ 'OM' => 'Oman',
+ 'PK' => 'Pakistan',
+ 'QA' => 'Qatar',
+ 'SA' => 'Saudi Arabia',
+ 'SD' => 'Sudan',
+ 'SO' => 'Somalia',
+ 'SY' => 'Syrian Arab Republic',
+ 'TD' => 'Chad',
+ 'TN' => 'Tunisia',
+ 'YE' => 'Yemen'
+ );
+
+ if (array_key_exists($country, $rtlCountries)) {
+ return TRUE;
+ }
+ return FALSE;
+ }
+
+ /**
+ * Reverse Characters on RTL Language
+ *
+ * @param string $sentense
+ * @return string $sentense
+ */
+ protected function reverseRTLCharacters($sentense, $store = null)
+ {
+
+ $sentense = $this->string->revRTLSentense($sentense);
+ return $sentense;
+ }
+
/**
* Insert address to pdf page
*
@@ -329,9 +456,16 @@ protected function insertAddress(&$page, $store = null)
$store
)
);
+
foreach ($values as $value) {
if ($value !== '') {
$value = preg_replace('/
]*>/i', "\n", $value);
+ // Reverse Characters on ship to RTL Countries
+ /* is RTL Country */
+ if($this->isRTLCountry)
+ {
+ $value = $this->reverseRTLCharacters($value, $store);
+ }
foreach ($this->string->split($value, 45, true, true) as $_value) {
$page->drawText(
trim(strip_tags($_value)),
@@ -499,11 +633,17 @@ protected function insertOrder(&$page, $obj, $putOrderId = true)
foreach ($billingAddress as $value) {
if ($value !== '') {
+ if($this->isRTLCountry)
+ {
+ // Reverse Characters
+ $value = $this->reverseRTLCharacters($value);
+ }
$text = [];
foreach ($this->string->split($value, 45, true, true) as $_value) {
$text[] = $_value;
}
foreach ($text as $part) {
+
$page->drawText(strip_tags(ltrim($part)), 35, $this->y, 'UTF-8');
$this->y -= 15;
}
@@ -516,6 +656,11 @@ protected function insertOrder(&$page, $obj, $putOrderId = true)
$this->y = $addressesStartY;
foreach ($shippingAddress as $value) {
if ($value !== '') {
+ if($this->isRTLCountry)
+ {
+ // Reverse Characters
+ $value = $this->reverseRTLCharacters($value);
+ }
$text = [];
foreach ($this->string->split($value, 45, true, true) as $_value) {
$text[] = $_value;
@@ -558,6 +703,11 @@ protected function insertOrder(&$page, $obj, $putOrderId = true)
if (trim($value) != '') {
//Printing "Payment Method" lines
$value = preg_replace('/
]*>/i', "\n", $value);
+ if($this->isRTLCountry)
+ {
+ // Reverse Characters
+ $value = $this->reverseRTLCharacters($value);
+ }
foreach ($this->string->split($value, 45, true, true) as $_value) {
$page->drawText(strip_tags(trim($_value)), $paymentLeft, $yPayments, 'UTF-8');
$yPayments -= 15;
@@ -577,6 +727,12 @@ protected function insertOrder(&$page, $obj, $putOrderId = true)
$topMargin = 15;
$methodStartY = $this->y;
$this->y -= 15;
+
+ if($this->isRTLCountry)
+ {
+ // Reverse Characters
+ $shippingMethod = $this->reverseRTLCharacters($shippingMethod);
+ }
foreach ($this->string->split($shippingMethod, 45, true, true) as $_value) {
$page->drawText(strip_tags(trim($_value)), 285, $this->y, 'UTF-8');
@@ -616,6 +772,12 @@ protected function insertOrder(&$page, $obj, $putOrderId = true)
$maxTitleLen = 45;
$endOfTitle = strlen($track->getTitle()) > $maxTitleLen ? '...' : '';
$truncatedTitle = substr($track->getTitle(), 0, $maxTitleLen) . $endOfTitle;
+
+ if($this->isRTLCountry)
+ {
+ // Reverse Characters
+ $truncatedTitle = $this->reverseRTLCharacters($truncatedTitle);
+ }
$page->drawText($truncatedTitle, 292, $yShipments, 'UTF-8');
$page->drawText($track->getNumber(), 410, $yShipments, 'UTF-8');
$yShipments -= $topMargin - 5;
diff --git a/app/code/Magento/Sales/Model/Order/Pdf/Creditmemo.php b/app/code/Magento/Sales/Model/Order/Pdf/Creditmemo.php
index f1430757939e7..6fa84f7ac3853 100644
--- a/app/code/Magento/Sales/Model/Order/Pdf/Creditmemo.php
+++ b/app/code/Magento/Sales/Model/Order/Pdf/Creditmemo.php
@@ -155,6 +155,9 @@ public function getPdf($creditmemos = [])
}
$page = $this->newPage();
$order = $creditmemo->getOrder();
+ /* Check Ship Country for RTL */
+ $shiptoCountry = $order->getShippingAddress()->getCountryId();
+ $this->isRTLCountry = $this->isRTLCountry($shiptoCountry);
/* Add image */
$this->insertLogo($page, $creditmemo->getStore());
/* Add address */
diff --git a/app/code/Magento/Sales/Model/Order/Pdf/Invoice.php b/app/code/Magento/Sales/Model/Order/Pdf/Invoice.php
index f294128a72f9f..5b2355b873bae 100644
--- a/app/code/Magento/Sales/Model/Order/Pdf/Invoice.php
+++ b/app/code/Magento/Sales/Model/Order/Pdf/Invoice.php
@@ -132,6 +132,9 @@ public function getPdf($invoices = [])
}
$page = $this->newPage();
$order = $invoice->getOrder();
+ /* Check Ship Country for RTL */
+ $shiptoCountry = $order->getShippingAddress()->getCountryId();
+ $this->isRTLCountry = $this->isRTLCountry($shiptoCountry);
/* Add image */
$this->insertLogo($page, $invoice->getStore());
/* Add address */
diff --git a/app/code/Magento/Sales/Model/Order/Pdf/Shipment.php b/app/code/Magento/Sales/Model/Order/Pdf/Shipment.php
index 32a289c0f5fa8..913852d4ab74d 100644
--- a/app/code/Magento/Sales/Model/Order/Pdf/Shipment.php
+++ b/app/code/Magento/Sales/Model/Order/Pdf/Shipment.php
@@ -123,6 +123,9 @@ public function getPdf($shipments = [])
}
$page = $this->newPage();
$order = $shipment->getOrder();
+ /* Check Ship Country for RTL */
+ $shiptoCountry = $order->getShippingAddress()->getCountryId();
+ $this->isRTLCountry = $this->isRTLCountry($shiptoCountry);
/* Add image */
$this->insertLogo($page, $shipment->getStore());
/* Add address */
diff --git a/lib/internal/Magento/Framework/Stdlib/StringUtils.php b/lib/internal/Magento/Framework/Stdlib/StringUtils.php
index 35decd7dab0a0..b52a2dc60eb35 100644
--- a/lib/internal/Magento/Framework/Stdlib/StringUtils.php
+++ b/lib/internal/Magento/Framework/Stdlib/StringUtils.php
@@ -210,4 +210,41 @@ public function strpos($haystack, $needle, $offset = null)
{
return mb_strpos($haystack, $needle, $offset, self::ICONV_CHARSET);
}
+
+ /**
+ * Detect if a word are consists of RTL characters (Used in PDF Invoices)
+ *
+ * @param string $string
+ * @return int|float
+ */
+ public function isRTLWord($string)
+ {
+ $rtl_chars_pattern = '/[\x{0590}-\x{083F}]|[\x{08A0}-\x{08FF}]|[\x{FB1D}-\x{FDFF}]|[\x{FE70}-\x{FEFF}]/u';
+ // $rtl_chars_pattern = '/[\x{0590}-\x{05ff}\x{0600}-\x{06ff}]/u';
+ preg_match_all($rtl_chars_pattern, $string, $matches);
+ $rtl_chars_count = count($matches[0]);
+
+ return $rtl_chars_count==0? 0:
+ $rtl_chars_count/$this->strlen($string);
+ }
+
+ /**
+ * Reverse characters of word with RTL characters only
+ *
+ * @param string $string
+ * @return string
+ */
+ public function revRTLSentense($string)
+ {
+ $words = explode(' ', $string);
+ for ($i=0; $iisRTLWord($words[$i]) > 0.8)
+ {
+ $words[$i] = $this->strrev($words[$i]);
+ }
+ }
+ return implode(" ", $words);
+ }
+
}