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); + } + }