From fae6dff86f896e570a9bc90477dc327df83f2a0d Mon Sep 17 00:00:00 2001 From: azhar bhat Date: Wed, 21 Jan 2026 17:17:38 +0530 Subject: [PATCH 01/52] customer service improvement --- .../controllers/orders/helpers/view/view.tpl | 6 +- .../orders/modals/_add_room_booking.tpl | 6 + .../orders/modals/_delete_room_booking.tpl | 54 ++++++++ .../orders/modals/_edit_room_tab_content.tpl | 6 + .../orders/modals/_room_reallocation.tpl | 12 ++ classes/PaymentModule.php | 6 +- controllers/admin/AdminCartsController.php | 1 + .../admin/AdminCustomerThreadsController.php | 23 +++- controllers/admin/AdminOrdersController.php | 99 ++++++++++++++- controllers/front/OrderDetailController.php | 2 +- install/data/xml/configuration.xml | 4 +- js/admin/orders.js | 120 ++++++++++++------ js/admin/reallocation.js | 1 + 13 files changed, 284 insertions(+), 56 deletions(-) create mode 100644 admin/themes/default/template/controllers/orders/modals/_delete_room_booking.tpl diff --git a/admin/themes/default/template/controllers/orders/helpers/view/view.tpl b/admin/themes/default/template/controllers/orders/helpers/view/view.tpl index c0c841758..32887116b 100644 --- a/admin/themes/default/template/controllers/orders/helpers/view/view.tpl +++ b/admin/themes/default/template/controllers/orders/helpers/view/view.tpl @@ -720,11 +720,11 @@ {$message['elastname']|escape:'html':'UTF-8'}{else}{$message['cfirstname']|escape:'html':'UTF-8'} {$message['clastname']|escape:'html':'UTF-8'} {/if},   - {dateFormat date=$message['date_add']} + {dateFormat date=$message.date_add full=1} - {if ($message['private'] == 1)} + {* {if ($message['private'] == 1)} {l s='Private'} - {/if} + {/if} *}

{if !$smarty.foreach.customerMessage.last}
{/if} diff --git a/admin/themes/default/template/controllers/orders/modals/_add_room_booking.tpl b/admin/themes/default/template/controllers/orders/modals/_add_room_booking.tpl index b9e6524cf..d63ce2421 100644 --- a/admin/themes/default/template/controllers/orders/modals/_add_room_booking.tpl +++ b/admin/themes/default/template/controllers/orders/modals/_add_room_booking.tpl @@ -128,6 +128,12 @@ {/if} +
+
+ + +
+
{if isset($invoices_collection) && sizeof($invoices_collection)} +
+
+ + +
+
+ +
+
+ + +
+
+{/if} \ No newline at end of file diff --git a/modules/qloicsexport/views/templates/hook/index.php b/modules/qloicsexport/views/templates/hook/index.php new file mode 100644 index 000000000..1ac4dd02b --- /dev/null +++ b/modules/qloicsexport/views/templates/hook/index.php @@ -0,0 +1,32 @@ +ppStatusDetail[$response['data']['purchase_units'][0]['payments']['captures'][0]['status_details']['reason']])) { - $smartyVars['ppstatusDetailMsg'] = $objPPOrder->ppStatusDetail[$response['data']['purchase_units'][0]['payments']['captures'][0]['status_details']['reason']]; + // Buyer making a payment in a different currency (ex: EUR) which is different from the default currency of merchant (Ex: USD), In all those cross currency cases, After Capture, transaction will fall into Pending state and will require merchant to manually go to his PayPal account and accept the payment. + $objPPOrder = new WKPayPalCommerceOrder(); + if ( + isset($response['data']['purchase_units'][0]['payments']['captures'][0]['status_details']['reason']) + && ($transactionData['pp_payment_status'] == 'PENDING' || $transactionData['pp_payment_status'] == 'DENIED') + && isset($response['data']['purchase_units'][0]['payments']['captures'][0]['status_details']['reason']) + ) { + if (isset($objPPOrder->ppStatusDetail[$response['data']['purchase_units'][0]['payments']['captures'][0]['status_details']['reason']])) { + $smartyVars['ppstatusDetailMsg'] = $objPPOrder->ppStatusDetail[$response['data']['purchase_units'][0]['payments']['captures'][0]['status_details']['reason']]; + } } - } - $smartyVars['transaction_url'] = $this->context->link->getAdminLink('AdminPaypalCommerceTransaction',Tools::getAdminTokenLite('AdminPaypalCommerceTransaction')).'&viewwk_paypal_commerce_order&id_paypal_commerce_order=' . (int)$idTrans; - $smartyVars['transaction_data'] = $transactionData; - $smartyVars['refund_data'] = $refundData; - $smartyVars['refunded_amount'] = $totalRefundedFormatted; - $smartyVars['remaining_refund'] = $remainingRefund; - $smartyVars['remaining_refund_format'] = Tools::displayPrice($remainingRefund, $orderCurrency); - $smartyVars['currency'] = $orderCurrency; - $smartyVars['WK_PAYPAL_COMMERCE_REFUND_TYPE_FULL'] = WkPaypalCommerceRefund::WK_PAYPAL_COMMERCE_REFUND_TYPE_FULL; - $smartyVars['WK_PAYPAL_COMMERCE_REFUND_TYPE_PARTIAL'] = WkPaypalCommerceRefund::WK_PAYPAL_COMMERCE_REFUND_TYPE_PARTIAL; + + $smartyVars['transaction_url'] = $this->context->link->getAdminLink('AdminPaypalCommerceTransaction',Tools::getAdminTokenLite('AdminPaypalCommerceTransaction')).'&viewwk_paypal_commerce_order&id_paypal_commerce_order=' . (int)$idTrans; + $smartyVars['transaction_data'] = $transactionData; + $smartyVars['refund_data'] = $refundData; + $smartyVars['refunded_amount'] = $totalRefundedFormatted; + $smartyVars['remaining_refund'] = $remainingRefund; + $smartyVars['remaining_refund_format'] = Tools::displayPrice($remainingRefund, $orderCurrency); + $smartyVars['currency'] = $orderCurrency; + $smartyVars['WK_PAYPAL_COMMERCE_REFUND_TYPE_FULL'] = WkPaypalCommerceRefund::WK_PAYPAL_COMMERCE_REFUND_TYPE_FULL; + $smartyVars['WK_PAYPAL_COMMERCE_REFUND_TYPE_PARTIAL'] = WkPaypalCommerceRefund::WK_PAYPAL_COMMERCE_REFUND_TYPE_PARTIAL; - $this->context->smarty->assign($smartyVars); + $this->context->smarty->assign($smartyVars); + $this->base_tpl_view = 'view.tpl'; + return parent::renderView(); + } else { + Tools::redirectAdmin(self::$currentIndex . '&token=' . $this->token); + } + } else { + Tools::redirectAdmin(self::$currentIndex . '&token=' . $this->token); } - $this->base_tpl_view = 'view.tpl'; - return parent::renderView(); } public function postProcess() diff --git a/modules/qlopaypalcommerce/views/css/front/wk_payment.css b/modules/qlopaypalcommerce/views/css/front/wk_payment.css index 27256b7ff..5843f2c29 100644 --- a/modules/qlopaypalcommerce/views/css/front/wk_payment.css +++ b/modules/qlopaypalcommerce/views/css/front/wk_payment.css @@ -45,3 +45,15 @@ @keyframes rotate { 0% {transform: rotate(0deg);} 100% {transform: rotate(360deg);}} + +p.payment_module a#qlo_paypal_btn { + background: url(../../img/paypal-payment-icon.png) 15px 8px no-repeat #fbfbfb; +} + +.qlo_paypal_methods_wrapper { + text-align: center; + padding: 20px 15px; + background: #fbfbfb; + border-radius: 3px; + border: 1px solid #d6d4d4; +} diff --git a/modules/qlopaypalcommerce/views/img/index.php b/modules/qlopaypalcommerce/views/img/index.php new file mode 100644 index 000000000..409280877 --- /dev/null +++ b/modules/qlopaypalcommerce/views/img/index.php @@ -0,0 +1,32 @@ +5(nvsLvJR*L zU2#VgPf*Zh5giXK5l4Yyz+qKDL>CprK}I}S0jG3!U6JiL;%seAO>I|o|Bm{;_rCYu z_ea}gE59JR&UOU=fGCa>#bT?#{yIBh-x^)!Lu~O!!{gC7qXx}Znh-#!Hl`q;Sg%Y) zViBb}C$k+11^|b}I(a-AFImA;8TB-!9YeF|GcYy)1TVK_C{<|)3Z@{bIs>0HdbyDV z>ePJF8kU4E$p}NVy2xA;5|_JDuF6eQan+>dAz-kDhXv3hs1mg3(+y^xg-`krmxt}` z*ANN(0729Eq+dkEOJrb}(S(338jGr;GhmR-rNJyF7ltVygANBmFdbrWsW8lAvUzY2 z`0*iO*-UB;FIE)sF&B2?le8$B!Goae>}*g4e)H*dU zlpzudxxz3}7|ev>@IYZus3?@hV2YS@Hj68anBs~JW>jfVAyZu4uiVhz`fzztGOqsBw#ZfMoi{WIX|mjs8>rvUc^7sL7R=~ADfvek zF(6(X5lPk$HK1>n?Y-jKzPV_A`P;_b6nt0fsWm$~j{I|^vZN;Dm^PDt2UvG4q^#Ow zgV}9FR`=$V(`Ln3+!yQSckex%f8|duxUzC6#_|%X=r7TxKV}qOB}ph7B~1~n!}k~M zV3n>cnhZa8_c*cXJI$rR^NiO6!@6nb>l3Qp*a*?erG$Y~6`90_E`Yhhvo*Cb@{Pfh znCtF0Bp3T?1l`htw$?s#wq6GO*%2lcvHySrYR1c`@zy=HW(QVrC=s zb2k-1X;#pn2Qgy$cOmCwu+)XnsAZB4EuZsjd4S=uk9!OCOM{eaifW?Y1#}lV{M?IfdNK--Nxs7XSFfKv_#2d3(*n zinEhn(XB)>ylv+>3ty5>S+(AUv)Hn+=*RYpag$eD+nSx{%9DnALT<1$=Mr*Wz7^r{mT#{r9J}Y!d8C|Mzn+{F*e`@sP4Idp!JPkx##; zFXh=MXJ>73VHd>W`&Hc{E*yd$z}Um;baR`N(v_SbJv{Y0&dCYT>?f9uw>X zrydMGeLQaH-2BQ{>$dK;%?dZGUcN=|{l s='Amount' mod='qlopaypalcommerce'} {l s='Type' mod='qlopaypalcommerce'} {l s='Status' mod='qlopaypalcommerce'} + {l s='Remark' mod='qlopaypalcommerce'} {l s='Date' mod='qlopaypalcommerce'} {if $refund_data} @@ -197,6 +198,7 @@ {/if} + {$refund.refund_reason|escape:'html':'UTF-8'} {$refund.date_add|escape:'html':'UTF-8'} {/foreach} diff --git a/modules/qlopaypalcommerce/views/templates/hook/payment.tpl b/modules/qlopaypalcommerce/views/templates/hook/payment.tpl index f5bcbe0de..d1a6a8f8a 100644 --- a/modules/qlopaypalcommerce/views/templates/hook/payment.tpl +++ b/modules/qlopaypalcommerce/views/templates/hook/payment.tpl @@ -20,82 +20,114 @@ * @license https://opensource.org/license/osl-3-0-php Open Software License version 3.0 *} -
-
-

{$product['name']|escape:'html':'UTF-8'}

+
{$product['name']|escape:'html':'UTF-8'}
+ {if $product.price_calculation_method == Product::PRICE_CALCULATION_METHOD_PER_DAY} +
+ {if ($product.show_price && !isset($restricted_country_mode)) || isset($groups)}{if !$priceDisplay}{convertPrice price=$product.price_tax_incl}{else}{convertPrice price=$product.price_tax_exc}{/if}{/if}{l s='/night'} +
+ {/if} {if $product.allow_multiple_quantity}
@@ -150,7 +155,21 @@
{if ($product.show_price && !isset($restricted_country_mode)) || isset($groups)} - {if !$priceDisplay}{convertPrice price=$product.price_tax_incl}{else}{convertPrice price=$product.price_tax_exc}{/if}{if $product.price_calculation_method == Product::PRICE_CALCULATION_METHOD_PER_DAY}{l s='/Night'}{/if} + + {if !$priceDisplay} + {if $serviceSelected} + {convertPrice price=$cartRoom['selected_service'][$product['id_product']]['total_price_tax_incl']} + {else} + {convertPrice price=$product.price_tax_incl} + {/if} + {else} + {if $serviceSelected} + {convertPrice price=$cartRoom['selected_service'][$product['id_product']]['total_price_tax_excl']} + {else} + {convertPrice price=$product.price_tax_exc} + {/if} + {/if} + {/if}
diff --git a/themes/hotel-reservation-theme/css/global.css b/themes/hotel-reservation-theme/css/global.css index 1c8ecf2e3..1f84e79ca 100644 --- a/themes/hotel-reservation-theme/css/global.css +++ b/themes/hotel-reservation-theme/css/global.css @@ -5776,10 +5776,13 @@ textarea { background: #fff; } #columns { + padding: 0; +} +#columns:has(#center_column > *) { position: relative; padding-bottom: 50px; - padding-top: 15px; } - + padding-top: 15px; +} #index .tab-content { margin-top: 35px; margin-bottom: 34px; } @@ -9049,6 +9052,11 @@ a.open_rooms_extra_services_panel { border-radius: 0 0 4px 0; box-shadow: 0 1px 0 0 rgb(0 0 0 / 13%); } +#rooms_extra_services .price-per-night { + font-size: 12px; + color: #777; + margin-bottom: 5px; +} /* fancybox changes */ diff --git a/themes/hotel-reservation-theme/js/order-opc.js b/themes/hotel-reservation-theme/js/order-opc.js index 854f90fbb..4c9ae91f1 100644 --- a/themes/hotel-reservation-theme/js/order-opc.js +++ b/themes/hotel-reservation-theme/js/order-opc.js @@ -638,6 +638,9 @@ $(document).ready(function() $(document).on('click', '#rooms_extra_services .qty_up', function(e) { e.preventDefault(); qtyfield = $(this).closest('.qty_container').find('input.qty'); + roomServiceProductValue = $(this).closest('.room_demand_block').find('.room-service-product-value'); + roomServiceProductUnitPrice = roomServiceProductValue.data('unit_price'); + roomServiceProductCurrencySign = roomServiceProductValue.data('currency_sign'); var newQuantity = parseInt(qtyfield.val()) + 1; if (qtyfield.data('max_quantity') && qtyfield.data('max_quantity') < newQuantity) { newQuantity = qtyfield.data('max_quantity'); @@ -647,6 +650,8 @@ $(document).ready(function() showErrorMessage(txtMaxQuantityAdded); } } else { + roomServiceProductTotalPriceQtyUp = newQuantity*roomServiceProductUnitPrice; + roomServiceProductValue.text(roomServiceProductCurrencySign + roomServiceProductTotalPriceQtyUp.toFixed(priceDisplayPrecision)) qtyfield.val(newQuantity).trigger('focusout'); } }); @@ -654,9 +659,15 @@ $(document).ready(function() $(document).on('click', '#rooms_extra_services .qty_down', function(e) { e.preventDefault(); qtyfield = $(this).closest('.qty_container').find('input.qty'); + roomServiceProductValue = $(this).closest('.room_demand_block').find('.room-service-product-value'); + roomServiceProductUnitPrice = roomServiceProductValue.data('unit_price'); + roomServiceProductCurrencySign = roomServiceProductValue.data('currency_sign'); var currentVal = parseInt(qtyfield.val()); if (!isNaN(currentVal) && currentVal > 1) { qtyfield.val(currentVal - 1).trigger('focusout'); + roomServiceProductTotalPriceQtyDown = qtyfield.val()*roomServiceProductUnitPrice; + roomServiceProductValue.text(roomServiceProductCurrencySign + roomServiceProductTotalPriceQtyDown.toFixed(priceDisplayPrecision)) + } else { qtyfield.val(1); if (currentVal != 1) { @@ -667,12 +678,20 @@ $(document).ready(function() $(document).on('focusout', '#rooms_extra_services .qty', function(e) { var qty_wntd = $(this).val(); - if (qty_wntd == '' || !$.isNumeric(qty_wntd)) { + roomServiceProductValue = $(this).closest('.room_demand_block').find('.room-service-product-value'); + roomServiceProductUnitPrice = roomServiceProductValue.data('unit_price'); + roomServiceProductCurrencySign = roomServiceProductValue.data('currency_sign'); + + if (qty_wntd == '' || !$.isNumeric(qty_wntd) || qty_wntd < 1) { $(this).val(1); } if ($(this).data('max_quantity') && $(this).data('max_quantity') < qty_wntd) { $(this).val(qtyfield.data('max_quantity')); } + + roomServiceProductTotalPriceQty = $(this).val()*roomServiceProductUnitPrice; + roomServiceProductValue.text(roomServiceProductCurrencySign + roomServiceProductTotalPriceQty.toFixed(priceDisplayPrecision)) + if ($(this).closest('.room_demand_block').find('.change_room_type_service_product').is(':checked')) { updateServiceProducts($(this).closest('.room_demand_block').find('.change_room_type_service_product')); } diff --git a/themes/hotel-reservation-theme/our-properties.tpl b/themes/hotel-reservation-theme/our-properties.tpl index 094f83dff..88f46e6ac 100644 --- a/themes/hotel-reservation-theme/our-properties.tpl +++ b/themes/hotel-reservation-theme/our-properties.tpl @@ -74,7 +74,7 @@ {$hotel['email']}

- {l s='View Rooms'} + {l s='View Property'} {if ($hotel['latitude'] != 0 || $hotel['longitude'] != 0) && $viewOnMap} {l s='View on map'} {/if} diff --git a/themes/hotel-reservation-theme/product.tpl b/themes/hotel-reservation-theme/product.tpl index 9492fbc86..67f4a03fe 100644 --- a/themes/hotel-reservation-theme/product.tpl +++ b/themes/hotel-reservation-theme/product.tpl @@ -238,13 +238,13 @@
{/block} {block name='product_info_tab_room_guests'} - {if isset($room_type_info['adults']) && isset($room_type_info['children']) } + {if isset($room_type_info['max_adults']) && isset($room_type_info['max_children']) }
{l s='Max Capacity'}
-

{$room_type_info['adults']} {l s='Adults'}, {$room_type_info['children']} {if $room_type_info['children'] > 1}{l s='Children'}{else}{l s='Child'}{/if} ({l s='Max guests'}: {$room_type_info['max_guests']|escape:'htmlall':'UTF-8'})

+

{$room_type_info['max_adults']} {l s='Adults'}, {$room_type_info['max_children']} {if $room_type_info['max_children'] > 1}{l s='Children'}{else}{l s='Child'}{/if} ({l s='Max guests'}: {$room_type_info['max_guests']|escape:'htmlall':'UTF-8'})

{/if} From ca1c222c36090adc88bebdf73143caf130174ee3 Mon Sep 17 00:00:00 2001 From: aradhana kumari Date: Fri, 15 May 2026 12:30:30 +0530 Subject: [PATCH 47/52] Fixed: Prevent unauthorized file read via email parameter in ajax endpoint Co-authored-by: Name --- admin/ajax.php | 3 +++ controllers/admin/AdminTranslationsController.php | 9 +++++++-- 2 files changed, 10 insertions(+), 2 deletions(-) diff --git a/admin/ajax.php b/admin/ajax.php index 2506e809d..d5b294f95 100644 --- a/admin/ajax.php +++ b/admin/ajax.php @@ -125,6 +125,9 @@ if (Tools::isSubmit('getZones')) { } if (Tools::isSubmit('getEmailHTML') && $email = Tools::getValue('email')) { + if (strpos($email, '..') !== false) { + die(''); + } $email_html = AdminTranslationsController::getEmailHTML($email); die($email_html); } diff --git a/controllers/admin/AdminTranslationsController.php b/controllers/admin/AdminTranslationsController.php index 1232fb59e..0fd5fe809 100644 --- a/controllers/admin/AdminTranslationsController.php +++ b/controllers/admin/AdminTranslationsController.php @@ -3045,8 +3045,13 @@ class AdminTranslationsControllerCore extends AdminController $email_file = _PS_ROOT_DIR_.$email; } - $email_html = file_get_contents($email_file); + $sanitizedFilePath = realpath($email_file); + $permittedMailDir = realpath(_PS_MAIL_DIR_); - return $email_html; + if ($sanitizedFilePath === false || $permittedMailDir === false || strpos($sanitizedFilePath, $permittedMailDir) !== 0) { + return false; + } + + return file_get_contents($sanitizedFilePath); } } From 61ddc310c4fadd98ac98cdac75bc34355bc1cdaa Mon Sep 17 00:00:00 2001 From: aradhana kumari Date: Fri, 15 May 2026 14:58:01 +0530 Subject: [PATCH 48/52] fix: prevent remote code execution in AdminTranslations language pack import Co-authored-by: Name --- .../admin/AdminTranslationsController.php | 39 ++++++++++++------- 1 file changed, 24 insertions(+), 15 deletions(-) diff --git a/controllers/admin/AdminTranslationsController.php b/controllers/admin/AdminTranslationsController.php index 0fd5fe809..5f70e049c 100644 --- a/controllers/admin/AdminTranslationsController.php +++ b/controllers/admin/AdminTranslationsController.php @@ -750,24 +750,28 @@ class AdminTranslationsControllerCore extends AdminController $uniqid = uniqid(); $sandbox = _PS_CACHE_DIR_.'sandbox'.DIRECTORY_SEPARATOR.$uniqid.DIRECTORY_SEPARATOR; - if ($gz->extractList($files_paths, $sandbox)) { - foreach ($files_list as $file2check) { - //don't validate index.php, will be overwrite when extract in translation directory - if (pathinfo($file2check['filename'], PATHINFO_BASENAME) == 'index.php') { - continue; - } - - if (preg_match('@^[0-9a-z-_/\\\\]+\.php$@i', $file2check['filename'])) { - if (!@filemtime($sandbox.$file2check['filename']) || !AdminTranslationsController::checkTranslationFile(file_get_contents($sandbox.$file2check['filename']))) { - $this->errors[] = sprintf(Tools::displayError('Validation failed for: %s'), $file2check['filename']); - } - } elseif (!preg_match('@mails[0-9a-z-_/\\\\]+\.(html|tpl|txt)$@i', $file2check['filename'])) { - $this->errors[] = sprintf(Tools::displayError('Unidentified file found: %s'), $file2check['filename']); - } - } + if (!$gz->extractList($files_paths, $sandbox)) { + $this->errors[] = Tools::displayError('The archive cannot be extracted.'); Tools::deleteDirectory($sandbox, true); + return false; } + foreach ($files_list as $file2check) { + //don't validate index.php, will be overwrite when extract in translation directory + if (pathinfo($file2check['filename'], PATHINFO_BASENAME) == 'index.php') { + continue; + } + + if (preg_match('@^[0-9a-z-_/\\\\]+\.php$@i', $file2check['filename'])) { + if (!@filemtime($sandbox.$file2check['filename']) || !AdminTranslationsController::checkTranslationFile(file_get_contents($sandbox.$file2check['filename']))) { + $this->errors[] = sprintf(Tools::displayError('Validation failed for: %s'), $file2check['filename']); + } + } elseif (!preg_match('@mails[0-9a-z-_/\\\\]+\.(html|tpl|txt)$@i', $file2check['filename'])) { + $this->errors[] = sprintf(Tools::displayError('Unidentified file found: %s'), $file2check['filename']); + } + } + Tools::deleteDirectory($sandbox, true); + $i = 0; $tmp_array = array(); foreach ($files_paths as $files_path) { @@ -837,10 +841,15 @@ class AdminTranslationsControllerCore extends AdminController public static function filterTranslationFiles($list) { $kept = array(); + $allowedExtensions = array('php', 'html', 'tpl', 'txt'); foreach ($list as $file) { if ('index.php' == basename($file['filename'])) { continue; } + $extension = strtolower(pathinfo($file['filename'], PATHINFO_EXTENSION)); + if (!in_array($extension, $allowedExtensions)) { + continue; + } if (preg_match('#^modules/([^/]+)/#', $file['filename'], $m)) { if (is_dir(_PS_MODULE_DIR_.$m[1])) { $kept[] = $file; From 4d3dfb100e55c1b0b207f693c4aab4ef4aceb6b9 Mon Sep 17 00:00:00 2001 From: aradhana kumari Date: Tue, 19 May 2026 15:19:08 +0530 Subject: [PATCH 49/52] Fixed: When the hotel location field is disabled, the hotel list dropdown appears at bottom Co-authored-by: Name --- .../views/js/wk-room-search-block.js | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/modules/wkroomsearchblock/views/js/wk-room-search-block.js b/modules/wkroomsearchblock/views/js/wk-room-search-block.js index 0b6c67465..8cf8d02b2 100644 --- a/modules/wkroomsearchblock/views/js/wk-room-search-block.js +++ b/modules/wkroomsearchblock/views/js/wk-room-search-block.js @@ -934,6 +934,10 @@ $(document).ready(function() { }); }); + $('select#id_hotel_button').on('chosen:showing_dropdown', function() { + setBookingSearchPositions(); + }); + $('#daterange_value').click(function () { setBookingSearchPositions(); }); @@ -979,9 +983,9 @@ function setBookingSearchPositions() { let searchForm = $('#search_hotel_block_form'); let inputFieldsAndDropdowns = [ - { input: $('#hotel_location'), dropdown: $('.location_search_results_ul')}, + { input: $('#hotel_location'), dropdown: $('.location_search_results_ul')}, { input: $('.hotel-selector-wrap'), dropdown: $('#id_hotel_button_chosen .chosen-drop')}, - { input: $('#guest_occupancy'), dropdown: $('#search_occupancy_wrapper')}, + { input: $('#guest_occupancy'), dropdown: $('#search_occupancy_wrapper')}, ]; let positionClass = 'bottom'; @@ -993,9 +997,8 @@ function setBookingSearchPositions() { // calculate max height for dropdowns let maxHeightNeeded = 0; $(inputFieldsAndDropdowns).each(function (i, inputFieldAndDropdown) { - if (!inputFieldAndDropdown.input.length) return false; + if (!inputFieldAndDropdown.input.length || !inputFieldAndDropdown.input.is(':visible')) return true; - // find needed space height let cssMaxHeight = parseInt(inputFieldAndDropdown.dropdown.css('max-height')); if (Number.isInteger(cssMaxHeight)) { maxHeightNeeded = Math.max(maxHeightNeeded, cssMaxHeight); @@ -1003,7 +1006,7 @@ function setBookingSearchPositions() { }); // determine position class - if (spaceBottom < maxHeightNeeded && spaceTop > spaceBottom) { + if (spaceTop > spaceBottom && (maxHeightNeeded === 0 || spaceBottom < maxHeightNeeded)) { positionClass = 'top'; } } From 4bf8f43c57cdf388fcdd39c7fb8e39c936838cf7 Mon Sep 17 00:00:00 2001 From: aradhana kumari Date: Wed, 20 May 2026 19:00:10 +0530 Subject: [PATCH 50/52] Add some more restrictions Co-authored-by: Name --- .../admin/AdminTranslationsController.php | 27 ++++++++++++++----- 1 file changed, 21 insertions(+), 6 deletions(-) diff --git a/controllers/admin/AdminTranslationsController.php b/controllers/admin/AdminTranslationsController.php index 5f70e049c..e56831c50 100644 --- a/controllers/admin/AdminTranslationsController.php +++ b/controllers/admin/AdminTranslationsController.php @@ -748,6 +748,11 @@ class AdminTranslationsControllerCore extends AdminController $files_list = AdminTranslationsController::filterTranslationFiles($gz->listContent()); $files_paths = AdminTranslationsController::filesListToPaths($files_list); + if (empty($files_list)) { + $this->errors[] = Tools::displayError('No valid translation files found in the archive.'); + return false; + } + $uniqid = uniqid(); $sandbox = _PS_CACHE_DIR_.'sandbox'.DIRECTORY_SEPARATOR.$uniqid.DIRECTORY_SEPARATOR; if (!$gz->extractList($files_paths, $sandbox)) { @@ -843,14 +848,24 @@ class AdminTranslationsControllerCore extends AdminController $kept = array(); $allowedExtensions = array('php', 'html', 'tpl', 'txt'); foreach ($list as $file) { - if ('index.php' == basename($file['filename'])) { - continue; - } - $extension = strtolower(pathinfo($file['filename'], PATHINFO_EXTENSION)); + $filename = $file['filename']; + $extension = strtolower(pathinfo($filename, PATHINFO_EXTENSION)); + if (!in_array($extension, $allowedExtensions)) { continue; } - if (preg_match('#^modules/([^/]+)/#', $file['filename'], $m)) { + + if ('index.php' == basename($filename)) { + continue; + } + + if ($extension === 'php' + && !preg_match('#^modules/([^/]+)/#', $filename) + && !preg_match('@^translations/[a-z]{2,3}/[a-z0-9_-]+\.php$@i', $filename)) { + continue; + } + + if (preg_match('#^modules/([^/]+)/#', $filename, $m)) { if (is_dir(_PS_MODULE_DIR_.$m[1])) { $kept[] = $file; } @@ -3055,7 +3070,7 @@ class AdminTranslationsControllerCore extends AdminController } $sanitizedFilePath = realpath($email_file); - $permittedMailDir = realpath(_PS_MAIL_DIR_); + $permittedMailDir = realpath(_PS_MAIL_DIR_) . DIRECTORY_SEPARATOR; if ($sanitizedFilePath === false || $permittedMailDir === false || strpos($sanitizedFilePath, $permittedMailDir) !== 0) { return false; From bc4e92e85abce1412b6e23cc4eb6bf8108408214 Mon Sep 17 00:00:00 2001 From: aradhana kumari Date: Fri, 22 May 2026 12:30:07 +0530 Subject: [PATCH 51/52] Remove the extra space Co-authored-by: Name --- modules/wkroomsearchblock/views/js/wk-room-search-block.js | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/modules/wkroomsearchblock/views/js/wk-room-search-block.js b/modules/wkroomsearchblock/views/js/wk-room-search-block.js index 8cf8d02b2..a07e68027 100644 --- a/modules/wkroomsearchblock/views/js/wk-room-search-block.js +++ b/modules/wkroomsearchblock/views/js/wk-room-search-block.js @@ -923,6 +923,8 @@ $(document).ready(function() { // set positions of popups when required if (page_name == 'index') { + setBookingSearchPositions(); + $('#hotel_location, #id_hotel_button_chosen, #guest_occupancy').focus(function () { setBookingSearchPositions(); }); @@ -983,9 +985,9 @@ function setBookingSearchPositions() { let searchForm = $('#search_hotel_block_form'); let inputFieldsAndDropdowns = [ - { input: $('#hotel_location'), dropdown: $('.location_search_results_ul')}, + { input: $('#hotel_location'), dropdown: $('.location_search_results_ul')}, { input: $('.hotel-selector-wrap'), dropdown: $('#id_hotel_button_chosen .chosen-drop')}, - { input: $('#guest_occupancy'), dropdown: $('#search_occupancy_wrapper')}, + { input: $('#guest_occupancy'), dropdown: $('#search_occupancy_wrapper')}, ]; let positionClass = 'bottom'; From d0bbff5e12720b5ac9f8289a87387778d1ebb004 Mon Sep 17 00:00:00 2001 From: aradhana kumari Date: Tue, 26 May 2026 19:23:47 +0530 Subject: [PATCH 52/52] Update the code Co-authored-by: Name --- admin/ajax.php | 3 --- 1 file changed, 3 deletions(-) diff --git a/admin/ajax.php b/admin/ajax.php index d5b294f95..2506e809d 100644 --- a/admin/ajax.php +++ b/admin/ajax.php @@ -125,9 +125,6 @@ if (Tools::isSubmit('getZones')) { } if (Tools::isSubmit('getEmailHTML') && $email = Tools::getValue('email')) { - if (strpos($email, '..') !== false) { - die(''); - } $email_html = AdminTranslationsController::getEmailHTML($email); die($email_html); }