Fixed: Improved amenities management, filtering, and room type display across the frontend
Co-authored-by: Name <azharbhat.qlo098@webkul.in>
This commit is contained in:
@@ -25,8 +25,34 @@
|
||||
{extends file="helpers/form/form.tpl"}
|
||||
|
||||
{block name="input_row"}
|
||||
<style>
|
||||
#logo_image-images-thumbnails img {
|
||||
max-width: 80px;
|
||||
max-height: 80px;
|
||||
padding: 5px;
|
||||
}
|
||||
</style>
|
||||
{$smarty.block.parent}
|
||||
{if $input.name == 'name'}
|
||||
{hook h="displayFeatureForm" id_feature=$form_id}
|
||||
{/if}
|
||||
{if $input.name == 'logo_icon'}
|
||||
<script type="text/javascript">
|
||||
$(document).ready(function() {
|
||||
// the uploader renders its own nested .form-group, so pick the field row that holds the label
|
||||
function getFieldRow(selector) {
|
||||
return $(selector).parents('.form-group').filter(function() {
|
||||
return $(this).children('label.control-label').length > 0;
|
||||
}).first();
|
||||
}
|
||||
function toggleFeatureLogoType() {
|
||||
var isIcon = $('#logo_type').val() === 'icon';
|
||||
getFieldRow('#logo_image').toggle(!isIcon);
|
||||
getFieldRow('#logo_icon').toggle(isIcon);
|
||||
}
|
||||
$('#logo_type').on('change', toggleFeatureLogoType);
|
||||
toggleFeatureLogoType();
|
||||
});
|
||||
</script>
|
||||
{/if}
|
||||
{/block}
|
||||
|
||||
@@ -29,6 +29,9 @@ class FeatureCore extends ObjectModel
|
||||
/** @var string Name */
|
||||
public $name;
|
||||
public $position;
|
||||
public $logo_type;
|
||||
public $logo;
|
||||
public $is_featured;
|
||||
|
||||
/**
|
||||
* @see ObjectModel::$definition
|
||||
@@ -39,6 +42,9 @@ class FeatureCore extends ObjectModel
|
||||
'multilang' => true,
|
||||
'fields' => array(
|
||||
'position' => array('type' => self::TYPE_INT, 'validate' => 'isInt'),
|
||||
'logo_type' => array('type' => self::TYPE_STRING, 'validate' => 'isGenericName', 'size' => 10),
|
||||
'logo' => array('type' => self::TYPE_STRING, 'validate' => 'isGenericName', 'size' => 255),
|
||||
'is_featured' => array('type' => self::TYPE_BOOL, 'validate' => 'isBool'),
|
||||
|
||||
/* Lang fields */
|
||||
'name' => array('type' => self::TYPE_STRING, 'lang' => true, 'validate' => 'isGenericName', 'required' => true, 'size' => 128),
|
||||
|
||||
@@ -4859,7 +4859,7 @@ class ProductCore extends ObjectModel
|
||||
}
|
||||
if (!array_key_exists($id_product.'-'.$id_lang, self::$_frontFeaturesCache)) {
|
||||
self::$_frontFeaturesCache[$id_product.'-'.$id_lang] = Db::getInstance(_PS_USE_SQL_SLAVE_)->executeS('
|
||||
SELECT name, value, pf.id_feature
|
||||
SELECT name, value, pf.id_feature, f.logo_type, f.logo, f.is_featured
|
||||
FROM '._DB_PREFIX_.'feature_product pf
|
||||
LEFT JOIN '._DB_PREFIX_.'feature_lang fl ON (fl.id_feature = pf.id_feature AND fl.id_lang = '.(int)$id_lang.')
|
||||
LEFT JOIN '._DB_PREFIX_.'feature_value_lang fvl ON (fvl.id_feature_value = pf.id_feature_value AND fvl.id_lang = '.(int)$id_lang.')
|
||||
@@ -7045,6 +7045,12 @@ class ProductCore extends ObjectModel
|
||||
$feature['value'] = (int) $feature['id_feature'];
|
||||
$feature['input_name'] = 'feature_value_parents';
|
||||
$feature['children'] = array();
|
||||
if (!empty($feature['is_featured'])) {
|
||||
$feature['badge'] = array(
|
||||
'class' => 'badge-success',
|
||||
'title' => Translate::getAdminTranslation('Featured', 'AdminProducts'),
|
||||
);
|
||||
}
|
||||
$selectedValues = isset($selectedFeatureValues[(int) $feature['id_feature']])
|
||||
? $selectedFeatureValues[(int) $feature['id_feature']]
|
||||
: array();
|
||||
|
||||
@@ -397,6 +397,8 @@ class ValidateCore
|
||||
*/
|
||||
public static function isCleanHtml($html, $allow_iframe = false)
|
||||
{
|
||||
$html = (string) $html;
|
||||
|
||||
$eventAttributeRegex = '/<\s*\w+[^>]*\s(on\w+)=["\'][^"\']*["\']/ims';
|
||||
|
||||
$events = 'onabort|onactivate|onactive|onaddsourcebuffer|onaddstream|onaddtrack|onafterprint|onafterscriptexecute|onafterupdate|onalerting|onanimationcancel|onanimationend|onanimationiteration|onanimationstart'
|
||||
|
||||
@@ -60,7 +60,7 @@ class AdminFeaturesControllerCore extends AdminController
|
||||
'logo' => array(
|
||||
'title' => $this->l('Icon'),
|
||||
'align' => 'text-center',
|
||||
'image' => 'rf',
|
||||
'callback' => 'displayLogo',
|
||||
'orderby' => false,
|
||||
'search' => false,
|
||||
'class' => 'fixed-width-xs'
|
||||
@@ -72,6 +72,17 @@ class AdminFeaturesControllerCore extends AdminController
|
||||
'align' => 'center',
|
||||
'class' => 'fixed-width-xs'
|
||||
),*/
|
||||
'is_featured' => array(
|
||||
'title' => $this->l('Is Featured'),
|
||||
'type' => 'select',
|
||||
'list' => array(1 => $this->l('Yes'), 0 => $this->l('No')),
|
||||
'align' => 'center',
|
||||
'callback' => 'displayIsFeatured',
|
||||
'filter_key' => 'a!is_featured',
|
||||
'filter_type' => 'int',
|
||||
'class' => 'fixed-width-sm',
|
||||
'orderby' => false
|
||||
),
|
||||
'position' => array(
|
||||
'title' => $this->l('Position'),
|
||||
'filter_key' => 'a!position',
|
||||
@@ -181,7 +192,7 @@ class AdminFeaturesControllerCore extends AdminController
|
||||
// $ps_img_url = _PS_IMG_DIR_.'rf/'.$obj->id.'.jpg';
|
||||
$img_url = $this->context->link->getMediaLink(_PS_IMG_.'rf/'.$obj->id.'.jpg');
|
||||
if ($img_exist = Tools::file_get_contents($img_url)) {
|
||||
$image = "<img class='img-thumbnail img-responsive' style='max-width:100px' src='".$img_url."'>";
|
||||
$image = "<img class='img-thumbnail img-responsive' src='".$img_url."'>";
|
||||
}
|
||||
|
||||
$this->toolbar_title = $this->l('Add a new room feature');
|
||||
@@ -200,14 +211,50 @@ class AdminFeaturesControllerCore extends AdminController
|
||||
'hint' => $this->l('Enter a name for the room feature. Invalid characters:').' <>;=#{}',
|
||||
'required' => true
|
||||
),
|
||||
array(
|
||||
'type' => 'switch',
|
||||
'label' => $this->l('Is Featured'),
|
||||
'name' => 'is_featured',
|
||||
'is_bool' => true,
|
||||
'values' => array(
|
||||
array('id' => 'is_featured_on', 'value' => 1, 'label' => $this->l('Yes')),
|
||||
array('id' => 'is_featured_off', 'value' => 0, 'label' => $this->l('No')),
|
||||
),
|
||||
),
|
||||
array(
|
||||
'type' => 'select',
|
||||
'label' => $this->l('Logo Type'),
|
||||
'name' => 'logo_type',
|
||||
'required' => true,
|
||||
'options' => array(
|
||||
'query' => array(
|
||||
array('id' => 'image', 'name' => $this->l('Image (Upload)')),
|
||||
array('id' => 'icon', 'name' => $this->l('Icon (Font Awesome)')),
|
||||
),
|
||||
'id' => 'id',
|
||||
'name' => 'name',
|
||||
),
|
||||
),
|
||||
array(
|
||||
'type' => 'file',
|
||||
'label' => $this->l('Room Feature Logo'),
|
||||
'name' => 'logo',
|
||||
'name' => 'logo_image',
|
||||
'image' => $img_exist ? $image : false,
|
||||
'display_image' => true,
|
||||
'hint' => $this->l('Upload a room feature logo.'),
|
||||
'required' => true
|
||||
),
|
||||
array(
|
||||
'type' => 'text',
|
||||
'label' => $this->l('Icon Class'),
|
||||
'name' => 'logo_icon',
|
||||
'required' => true,
|
||||
'col' => 4,
|
||||
'hint' => $this->l('Font Awesome icon class. Replace fa- with icon- (e.g. fa-wifi becomes icon-wifi).'),
|
||||
'desc' => sprintf(
|
||||
$this->l('Refer to %s for available icons.'),
|
||||
'<a href="https://fontawesome.com/v4/cheatsheet" target="_blank">https://fontawesome.com/v4/cheatsheet</a>'
|
||||
),
|
||||
)
|
||||
)
|
||||
);
|
||||
@@ -234,9 +281,50 @@ class AdminFeaturesControllerCore extends AdminController
|
||||
)
|
||||
);
|
||||
|
||||
$this->fields_value['logo_icon'] = ($obj->logo_type == 'icon') ? $obj->logo : '';
|
||||
|
||||
return parent::renderForm();
|
||||
}
|
||||
|
||||
/**
|
||||
* List callback: render the feature logo as an icon or as the uploaded image thumbnail.
|
||||
*
|
||||
* @param string $logo Icon class (when logo type is icon)
|
||||
* @param array $row List row
|
||||
* @return string
|
||||
*/
|
||||
public function displayLogo($logo, $row)
|
||||
{
|
||||
if (isset($row['logo_type']) && $row['logo_type'] == 'icon') {
|
||||
return $logo ? '<i class="'.Tools::safeOutput($logo).'"></i>' : '';
|
||||
}
|
||||
|
||||
$idFeature = (int) $row['id_feature'];
|
||||
|
||||
return ImageManager::thumbnail(
|
||||
_PS_IMG_DIR_.'rf/'.$idFeature.'.jpg',
|
||||
'feature_mini_'.$idFeature.'_'.(int) $this->context->shop->id.'.jpg',
|
||||
45,
|
||||
'jpg'
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* List callback: render the Is Featured value as a status-like label.
|
||||
*
|
||||
* @param int $isFeatured Is featured flag
|
||||
* @param array $row List row
|
||||
* @return string
|
||||
*/
|
||||
public function displayIsFeatured($isFeatured, $row)
|
||||
{
|
||||
if ((int) $isFeatured) {
|
||||
return '<span class="label label-success">'.$this->l('Yes').'</span>';
|
||||
}
|
||||
|
||||
return '<span class="label label-default">'.$this->l('No').'</span>';
|
||||
}
|
||||
|
||||
public function initPageHeaderToolbar()
|
||||
{
|
||||
if (empty($this->display)) {
|
||||
@@ -622,21 +710,63 @@ class AdminFeaturesControllerCore extends AdminController
|
||||
$_POST[$key] = str_replace('\n', '', str_replace('\r', '', $value));
|
||||
}
|
||||
}
|
||||
$featureImage = $_FILES['logo'];
|
||||
if (!$idFeature || (isset($featureImage['tmp_name']) && $featureImage['tmp_name'])) {
|
||||
if ($featureImage && $featureImage['tmp_name'] && $featureImage['name']) {
|
||||
$logoType = Tools::getValue('logo_type');
|
||||
$featureImage = isset($_FILES['logo_image']) ? $_FILES['logo_image'] : null;
|
||||
|
||||
if (!in_array($logoType, array('image', 'icon'))) {
|
||||
$this->errors[] = $this->l('Logo type is invalid.');
|
||||
$logoType = 'image';
|
||||
}
|
||||
if (!in_array(Tools::getValue('is_featured', 0), array('0', '1', 0, 1), true)) {
|
||||
$this->errors[] = $this->l('Is Featured value is invalid.');
|
||||
}
|
||||
$_POST['logo_type'] = $logoType;
|
||||
// Empty logo would be saved as NULL (Feature::add() uses null values), so image type keeps a placeholder until the image is saved.
|
||||
$_POST['logo'] = 'image';
|
||||
|
||||
if ($logoType === 'icon') {
|
||||
$logoIcon = trim(Tools::getValue('logo_icon'));
|
||||
if (!$logoIcon) {
|
||||
$this->errors[] = $this->l('Icon class is required.');
|
||||
} elseif (Tools::strlen($logoIcon) > 255) {
|
||||
$this->errors[] = $this->l('Icon class is too long.');
|
||||
} elseif (!preg_match('/^icon-[a-z0-9]+(-[a-z0-9]+)*$/', $logoIcon)) {
|
||||
$this->errors[] = $this->l('Icon class is invalid. It must start with "icon-" and contain only lowercase letters, numbers and hyphens (e.g. icon-wifi).');
|
||||
} else {
|
||||
$_POST['logo'] = $logoIcon;
|
||||
}
|
||||
} else {
|
||||
$hasUpload = $featureImage && !empty($featureImage['tmp_name']);
|
||||
$hasExisting = $idFeature && file_exists(_PS_IMG_DIR_.'rf/'.$idFeature.'.jpg');
|
||||
if ($hasUpload) {
|
||||
if ($error = ImageManager::validateUpload($featureImage, Tools::getMaxUploadSize())) {
|
||||
$this->errors[] = $error;
|
||||
}
|
||||
} else {
|
||||
} elseif (!$hasExisting) {
|
||||
$this->errors[] = $this->l('Please select a logo for this feature.');
|
||||
}
|
||||
}
|
||||
|
||||
if (count($this->errors)) {
|
||||
$this->display = $idFeature ? 'edit' : 'add';
|
||||
return false;
|
||||
}
|
||||
|
||||
$objFeature = parent::processSave();
|
||||
if (!count($this->errors)) {
|
||||
// icon type does not need the uploaded image
|
||||
if ($logoType === 'icon' && file_exists(_PS_IMG_DIR_.'rf/'.$objFeature->id.'.jpg')) {
|
||||
unlink(_PS_IMG_DIR_.'rf/'.$objFeature->id.'.jpg');
|
||||
}
|
||||
|
||||
// image type stores the image file name
|
||||
if ($logoType === 'image' && $objFeature->logo !== $objFeature->id.'.jpg') {
|
||||
$objFeature->logo = $objFeature->id.'.jpg';
|
||||
$objFeature->update();
|
||||
}
|
||||
|
||||
// save feature image
|
||||
if (isset($featureImage['tmp_name']) && $featureImage['tmp_name']) {
|
||||
if ($logoType === 'image' && isset($featureImage['tmp_name']) && $featureImage['tmp_name']) {
|
||||
// if already feature image then delete it once before uploading new image
|
||||
if ($idFeature) {
|
||||
$currentImg = _PS_TMP_IMG_DIR_.'feature_mini_'.$objFeature->id.'_'.$this->context->shop->id.'.jpg';
|
||||
|
||||
@@ -183,6 +183,7 @@ class CategoryControllerCore extends FrontController
|
||||
$sort_value = Tools::getValue('sort_value');
|
||||
$filter_data = Tools::getValue('filter_data');
|
||||
$amenities = [];
|
||||
$featureValues = [];
|
||||
$price = [];
|
||||
if (!empty($filter_data)) {
|
||||
foreach ($filter_data as $key => $value) {
|
||||
@@ -190,6 +191,10 @@ class CategoryControllerCore extends FrontController
|
||||
foreach ($value as $a_k => $a_v) {
|
||||
$amenities[] = $a_v;
|
||||
}
|
||||
} elseif ($key == 'features') {
|
||||
foreach ($value as $idFeatureValue) {
|
||||
$featureValues[] = (int) $idFeatureValue;
|
||||
}
|
||||
} elseif ($key == 'price') {
|
||||
$price['from'] = $value[0];
|
||||
$price['to'] = $value[1];
|
||||
@@ -207,6 +212,7 @@ class CategoryControllerCore extends FrontController
|
||||
'id_cart' => $this->context->cart->id,
|
||||
'id_guest' => $this->context->cookie->id_guest,
|
||||
'amenities' => $amenities,
|
||||
'feature_values' => $featureValues,
|
||||
'price' => $price,
|
||||
);
|
||||
|
||||
|
||||
@@ -411,6 +411,23 @@ class ProductControllerCore extends FrontController
|
||||
$roomAmenities = HotelRoomTypeAmenities::getAmenities($this->product->id, $this->context->language->id);
|
||||
$hotelAmenities = HotelBranchAmenities::getAmenities($hotel_id, $this->context->language->id);
|
||||
|
||||
// featured amenities: room type level first, then hotel level, without duplicates
|
||||
$featuredAmenities = array();
|
||||
$featuredAmenitiesList = array_merge(
|
||||
HotelRoomTypeAmenities::getAmenities($this->product->id, $this->context->language->id, true),
|
||||
HotelBranchAmenities::getAmenities($hotel_id, $this->context->language->id, true)
|
||||
);
|
||||
|
||||
$featuredAmenities = array_values(array_column(
|
||||
array_reverse($featuredAmenitiesList),
|
||||
null,
|
||||
'id'
|
||||
));
|
||||
|
||||
usort($featuredAmenities, function ($a, $b) {
|
||||
return strcmp($a['name'], $b['name']);
|
||||
});
|
||||
|
||||
$this->context->smarty->assign(
|
||||
array(
|
||||
'id_hotel' => $hotel_id,
|
||||
@@ -440,6 +457,7 @@ class ProductControllerCore extends FrontController
|
||||
'room_type_features' => $roomFeatures,
|
||||
'room_dynamic_amenities' => $roomAmenities,
|
||||
'hotel_dynamic_amenities' => $hotelAmenities,
|
||||
'featured_amenities' => $featuredAmenities,
|
||||
'amenity_img_dir' => _MODULE_DIR_.'hotelreservationsystem/views/img/hotel_amenities/',
|
||||
'hotel_image_link' => $hotelImageLink,
|
||||
'hotel_has_images' => (bool) HotelImage::getCover($hotel_id),
|
||||
|
||||
@@ -824,6 +824,9 @@ CREATE TABLE `PREFIX_employee_shop` (
|
||||
CREATE TABLE `PREFIX_feature` (
|
||||
`id_feature` int(10) unsigned NOT NULL auto_increment,
|
||||
`position` int(10) unsigned NOT NULL DEFAULT '0',
|
||||
`logo_type` varchar(10) NOT NULL DEFAULT 'image',
|
||||
`logo` varchar(255) NOT NULL DEFAULT '',
|
||||
`is_featured` tinyint(1) unsigned NOT NULL DEFAULT '0',
|
||||
PRIMARY KEY (`id_feature`)
|
||||
) ENGINE=ENGINE_TYPE DEFAULT CHARSET=utf8 COLLATION;
|
||||
|
||||
|
||||
@@ -308,6 +308,9 @@ class HotelBookingDetail extends ObjectModel
|
||||
if (!isset($params['amenities'])) {
|
||||
$params['amenities'] = 0;
|
||||
}
|
||||
if (!isset($params['feature_values'])) {
|
||||
$params['feature_values'] = 0;
|
||||
}
|
||||
if (!isset($params['price'])) {
|
||||
$params['price'] = 0;
|
||||
}
|
||||
@@ -1831,14 +1834,24 @@ class HotelBookingDetail extends ObjectModel
|
||||
if (!empty($bookingData)) {
|
||||
foreach ($bookingData['rm_data'] as $key => $value) {
|
||||
// featured amenities for display in room type list
|
||||
$product_feature = HotelRoomTypeAmenities::getAmenities(
|
||||
$featured_amenities = HotelRoomTypeAmenities::getAmenities(
|
||||
$value['id_product'],
|
||||
$context->language->id,
|
||||
true
|
||||
);
|
||||
if ($maxAmenities = (int) Configuration::get('WK_MAX_AMENITIES_ROOM_SEARCH')) {
|
||||
$featured_amenities = array_slice($featured_amenities, 0, $maxAmenities);
|
||||
}
|
||||
if (!empty($amenities) && $amenities) {
|
||||
$roomAmenityIds = array_column(HotelRoomTypeAmenities::getAmenities($value['id_product']), 'id');
|
||||
if (array_diff($amenities, $roomAmenityIds)) {
|
||||
if (!array_intersect($amenities, $roomAmenityIds)) {
|
||||
unset($bookingData['rm_data'][$key]);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
if (!empty($feature_values)) {
|
||||
$roomFeatureValueIds = array_map('intval', array_column(Product::getFeaturesStatic($value['id_product']), 'id_feature_value'));
|
||||
if (!array_intersect($feature_values, $roomFeatureValueIds)) {
|
||||
unset($bookingData['rm_data'][$key]);
|
||||
continue;
|
||||
}
|
||||
@@ -1859,7 +1872,16 @@ class HotelBookingDetail extends ObjectModel
|
||||
$cover_img = $context->link->getImageLink($value['link_rewrite'], $context->language->iso_code.'-default', 'home_default');
|
||||
}
|
||||
$bookingData['rm_data'][$key]['image'] = $cover_img;
|
||||
$bookingData['rm_data'][$key]['feature'] = $product_feature;
|
||||
$bookingData['rm_data'][$key]['featured_amenities'] = $featured_amenities;
|
||||
|
||||
// featured room features (is_featured) for display below the short description
|
||||
$featuredFeatures = array();
|
||||
foreach (Product::getFrontFeaturesStatic($context->language->id, $value['id_product']) as $roomFeature) {
|
||||
if ($roomFeature['is_featured'] && !isset($featuredFeatures[$roomFeature['id_feature']])) {
|
||||
$featuredFeatures[$roomFeature['id_feature']] = $roomFeature;
|
||||
}
|
||||
}
|
||||
$bookingData['rm_data'][$key]['featured_features'] = array_values($featuredFeatures);
|
||||
$bookingData['rm_data'][$key]['price'] = $prod_price;
|
||||
$bookingData['rm_data'][$key]['feature_price'] = $productFeaturePrice;
|
||||
$bookingData['rm_data'][$key]['price_without_reduction'] = $productPriceWithoutReduction;
|
||||
|
||||
@@ -977,6 +977,74 @@ class HotelHelper
|
||||
);
|
||||
// lang fields
|
||||
$languages = Language::getLanguages(false);
|
||||
// FontAwesome icons (admin/front icon- classes) for default amenities, keyed by amenity position.
|
||||
// Amenities without a suitable icon keep their default image.
|
||||
$amenityIcons = array(
|
||||
1 => 'icon-building',
|
||||
2 => 'icon-video-camera',
|
||||
3 => 'icon-users',
|
||||
4 => 'icon-microphone',
|
||||
5 => 'icon-pencil',
|
||||
6 => 'icon-fax',
|
||||
7 => 'icon-wifi',
|
||||
8 => 'icon-wifi',
|
||||
9 => 'icon-bus',
|
||||
10 => 'icon-newspaper-o',
|
||||
11 => 'icon-shopping-cart',
|
||||
12 => 'icon-glass',
|
||||
13 => 'icon-music',
|
||||
14 => 'icon-diamond',
|
||||
16 => 'icon-music',
|
||||
17 => 'icon-microphone',
|
||||
18 => 'icon-film',
|
||||
19 => 'icon-moon-o',
|
||||
21 => 'icon-plug',
|
||||
22 => 'icon-credit-card',
|
||||
23 => 'icon-money',
|
||||
25 => 'icon-book',
|
||||
26 => 'icon-medkit',
|
||||
27 => 'icon-gift',
|
||||
29 => 'icon-paw',
|
||||
30 => 'icon-child',
|
||||
32 => 'icon-fire',
|
||||
33 => 'icon-bell',
|
||||
34 => 'icon-cutlery',
|
||||
35 => 'icon-car',
|
||||
37 => 'icon-shopping-cart',
|
||||
38 => 'icon-hospital-o',
|
||||
39 => 'icon-envelope',
|
||||
41 => 'icon-language',
|
||||
42 => 'icon-car',
|
||||
45 => 'icon-wifi',
|
||||
46 => 'icon-fax',
|
||||
47 => 'icon-tree',
|
||||
48 => 'icon-car',
|
||||
49 => 'icon-fire',
|
||||
50 => 'icon-child',
|
||||
53 => 'icon-car',
|
||||
55 => 'icon-leaf',
|
||||
56 => 'icon-car',
|
||||
57 => 'icon-car',
|
||||
58 => 'icon-key',
|
||||
59 => 'icon-heartbeat',
|
||||
60 => 'icon-bicycle',
|
||||
64 => 'icon-ship',
|
||||
69 => 'icon-life-ring',
|
||||
70 => 'icon-gamepad',
|
||||
72 => 'icon-anchor',
|
||||
73 => 'icon-leaf',
|
||||
87 => 'icon-glass',
|
||||
88 => 'icon-cutlery',
|
||||
89 => 'icon-cutlery',
|
||||
90 => 'icon-coffee',
|
||||
91 => 'icon-cutlery',
|
||||
93 => 'icon-cutlery',
|
||||
94 => 'icon-cutlery',
|
||||
95 => 'icon-coffee',
|
||||
96 => 'icon-beer',
|
||||
97 => 'icon-cutlery',
|
||||
98 => 'icon-leaf',
|
||||
);
|
||||
$imgDir = dirname(__FILE__).'/../views/img/hotel_amenities/';
|
||||
$i = 1;
|
||||
$defaultImageIndex = 0;
|
||||
@@ -1009,6 +1077,13 @@ class HotelHelper
|
||||
$obj_amenity->id_parent = $idParent;
|
||||
$obj_amenity->save();
|
||||
|
||||
if (isset($amenityIcons[$defaultImageIndex])) {
|
||||
$obj_amenity->logo_type = 'icon';
|
||||
$obj_amenity->logo = $amenityIcons[$defaultImageIndex];
|
||||
$obj_amenity->save();
|
||||
continue;
|
||||
}
|
||||
|
||||
$srcImg = $imgDir.'_default/'.$defaultImageIndex.'.jpg';
|
||||
if (file_exists($srcImg)) {
|
||||
if (ImageManager::resize($srcImg, $imgDir.$obj_amenity->id.'.jpg')) {
|
||||
@@ -1114,6 +1189,7 @@ class HotelHelper
|
||||
Configuration::updateValue('PS_MIN_BOOKING_OFFSET', 0);
|
||||
|
||||
Configuration::updateValue('HTL_FEATURE_PRICING_PRIORITY', 'specific_date;special_day;date_range');
|
||||
Configuration::updateValue('WK_MAX_AMENITIES_ROOM_SEARCH', 0);
|
||||
Configuration::updateValue('WK_GOOGLE_ACTIVE_MAP', 0);
|
||||
Configuration::updateValue('WK_MAP_HOTEL_ACTIVE_ONLY', 1);
|
||||
|
||||
|
||||
@@ -189,6 +189,15 @@ class AdminHotelGeneralSettingsController extends ModuleAdminController
|
||||
),
|
||||
'hint' => $this->l('Enable to display hotels list on the contact us page.'),
|
||||
),
|
||||
'WK_MAX_AMENITIES_ROOM_SEARCH' => array(
|
||||
'title' => $this->l('Maximum amenities in room search'),
|
||||
'hint' => $this->l('Maximum number of amenities to display for each room type on the front office room search page.'),
|
||||
'desc' => $this->l('Set to 0 to display all amenities.'),
|
||||
'type' => 'text',
|
||||
'cast' => 'intval',
|
||||
'class' => 'fixed-width-xl',
|
||||
'default' => '0',
|
||||
),
|
||||
),
|
||||
'submit' => array('title' => $this->l('Save')),
|
||||
),
|
||||
@@ -570,6 +579,9 @@ class AdminHotelGeneralSettingsController extends ModuleAdminController
|
||||
} elseif (Tools::getValue('WK_ADVANCED_PAYMENT_GLOBAL_MIN_AMOUNT') > 100) {
|
||||
$this->errors[] = $this->l('Minimum partial payment percentage should not be more than 100.');
|
||||
}
|
||||
if (!Validate::isUnsignedInt(Tools::getValue('WK_MAX_AMENITIES_ROOM_SEARCH'))) {
|
||||
$this->errors[] = $this->l('Maximum amenities in room search is invalid. Enter 0 or a positive number.');
|
||||
}
|
||||
if (Tools::getValue('WK_GOOGLE_ACTIVE_MAP')) {
|
||||
if (!Tools::getValue('PS_API_KEY')) {
|
||||
$this->errors[] = $this->l('Please enter Google API key.');
|
||||
|
||||
@@ -613,6 +613,7 @@ class HotelReservationSystem extends Module
|
||||
'WK_CUSTOMER_SUPPORT_PHONE_NUMBER',
|
||||
'WK_CUSTOMER_SUPPORT_EMAIL',
|
||||
'WK_DISPLAY_CONTACT_PAGE_HOTEL_LIST',
|
||||
'WK_MAX_AMENITIES_ROOM_SEARCH',
|
||||
'QLO_HEADER_MEDIA_TYPE',
|
||||
'QLO_HEADER_CONTENT_ALIGN',
|
||||
'QLO_HEADER_VIDEO_SOURCE_TYPE',
|
||||
|
||||
@@ -61,6 +61,22 @@
|
||||
margin-bottom: 5px;
|
||||
}
|
||||
|
||||
.layered_filt_category
|
||||
{
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
|
||||
.layered_filt_category_name
|
||||
{
|
||||
margin-bottom: 5px;
|
||||
}
|
||||
|
||||
.layered_filt_category_children
|
||||
{
|
||||
padding-left: 15px;
|
||||
border-left: 1px solid #d6d4d4;
|
||||
}
|
||||
|
||||
.filters_name, .price_filter_subcont span
|
||||
{
|
||||
font-size: 16px;
|
||||
|
||||
@@ -26,7 +26,7 @@ $(document).ready(function()
|
||||
{
|
||||
var filter_wrapper = $(this).parents(".layered_filter_heading").siblings(".lf_sub_cont");
|
||||
var make_diff = filter_wrapper.children("div"); //use to make difference between checkbox and price slider
|
||||
if (make_diff.hasClass("layered_filt")) // for checkbox
|
||||
if (make_diff.hasClass("layered_filt") || make_diff.hasClass("layered_filt_category")) // for checkbox (flat or tree)
|
||||
{
|
||||
var selected_filter = filter_wrapper.find("div.layered_filt input.filter:checked").prop("checked", false);
|
||||
selected_filter.parent("span.checked").removeClass("checked");
|
||||
|
||||
@@ -23,6 +23,29 @@
|
||||
{block name='room_types_filters_block'}
|
||||
<div id="filter_results" class="row block">
|
||||
<div class="col-sm-12">
|
||||
{block name='room_types_price_filter'}
|
||||
{if isset($config) && $config['SHOW_PRICE_FILTER']}
|
||||
<div class="row margin-lr-0 layered_filter_cont">
|
||||
<div class="col-sm-12 layered_filter_heading">
|
||||
<div class="row margin-lr-0">
|
||||
<div class="pull-left lf_headingmain_wrapper">
|
||||
<span>{l s='Price' mod='wkhotelfilterblock'}</span>
|
||||
<hr class="theme-text-underline">
|
||||
</div>
|
||||
<span class="pull-right clear_filter">{l s='Clear Filter' mod='wkhotelfilterblock'}</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-sm-12 lf_sub_cont">
|
||||
<div class="row margin-lr-0 price_filter_subcont">
|
||||
<span class="pull-left"><span id="filter_price_from">{displayPrice price=$min_price}</span></span>
|
||||
<span class="pull-right"><span id="filter_price_to">{displayPrice price=$max_price}</span></span>
|
||||
</div>
|
||||
<div id="filter_price_silder"></div>
|
||||
</div>
|
||||
</div>
|
||||
{/if}
|
||||
{/block}
|
||||
|
||||
{block name='room_types_amenities_filter'}
|
||||
{if isset($config) && $config['SHOW_AMENITIES_FILTER'] && $all_amenities}
|
||||
<div class="row margin-lr-0 layered_filter_cont">
|
||||
@@ -47,26 +70,29 @@
|
||||
{/if}
|
||||
{/block}
|
||||
|
||||
{block name='room_types_price_filter'}
|
||||
{if isset($config) && $config['SHOW_PRICE_FILTER']}
|
||||
<div class="row margin-lr-0 layered_filter_cont">
|
||||
<div class="col-sm-12 layered_filter_heading">
|
||||
<div class="row margin-lr-0">
|
||||
<div class="pull-left lf_headingmain_wrapper">
|
||||
<span>{l s='Price' mod='wkhotelfilterblock'}</span>
|
||||
<hr class="theme-text-underline">
|
||||
{block name='room_types_features_filter'}
|
||||
{if isset($config) && $config['SHOW_FEATURES_FILTER'] && isset($room_type_features) && $room_type_features}
|
||||
{foreach $room_type_features as $feature}
|
||||
<div class="row margin-lr-0 layered_filter_cont">
|
||||
<div class="col-sm-12 layered_filter_heading">
|
||||
<div class="row margin-lr-0">
|
||||
<div class="pull-left lf_headingmain_wrapper">
|
||||
<span>{$feature.name|escape:'html':'UTF-8'}</span>
|
||||
<hr class="theme-text-underline">
|
||||
</div>
|
||||
<span class="pull-right clear_filter">{l s='Clear Filter' mod='wkhotelfilterblock'}</span>
|
||||
</div>
|
||||
<span class="pull-right clear_filter">{l s='Clear Filter' mod='wkhotelfilterblock'}</span>
|
||||
</div>
|
||||
<div class="col-sm-12 lf_sub_cont">
|
||||
{foreach $feature.values as $featureValue}
|
||||
<div class="layered_filt">
|
||||
<input type="checkbox" class="filter" data-type="features" value="{$featureValue.id_feature_value|intval}">
|
||||
<span class="filters_name">{$featureValue.value|escape:'html':'UTF-8'}</span>
|
||||
</div>
|
||||
{/foreach}
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-sm-12 lf_sub_cont">
|
||||
<div class="row margin-lr-0 price_filter_subcont">
|
||||
<span class="pull-left"><span id="filter_price_from">{displayPrice price=$min_price}</span></span>
|
||||
<span class="pull-right"><span id="filter_price_to">{displayPrice price=$max_price}</span></span>
|
||||
</div>
|
||||
<div id="filter_price_silder"></div>
|
||||
</div>
|
||||
</div>
|
||||
{/foreach}
|
||||
{/if}
|
||||
{/block}
|
||||
</div>
|
||||
|
||||
@@ -61,6 +61,15 @@ class wkhotelfilterblock extends Module
|
||||
|
||||
public function renderForm()
|
||||
{
|
||||
|
||||
|
||||
$features = array();
|
||||
$featuresList = Feature::getFeatures($this->context->language->id);
|
||||
foreach ($featuresList as $feature) {
|
||||
$features[] = array('id_group' => (int) $feature['id_feature'], 'name' => $feature['name']);
|
||||
}
|
||||
|
||||
|
||||
$fields_form = array();
|
||||
$fields_form['form'] = array(
|
||||
'legend' => array(
|
||||
@@ -102,6 +111,33 @@ class wkhotelfilterblock extends Module
|
||||
),
|
||||
'hint' => $this->l('Enable to display Price filter.'),
|
||||
),
|
||||
array(
|
||||
'type' => 'switch',
|
||||
'label' => $this->l('Show Features filter'),
|
||||
'name' => 'SHOW_FEATURES_FILTER',
|
||||
'is_bool' => true,
|
||||
'values' => array(
|
||||
array(
|
||||
'id' => 'features_on',
|
||||
'value' => 1,
|
||||
),
|
||||
array(
|
||||
'id' => 'features_off',
|
||||
'value' => 0,
|
||||
),
|
||||
),
|
||||
'hint' => $this->l('Enable to display Room Features filter.'),
|
||||
),
|
||||
array(
|
||||
'type' => 'group',
|
||||
'label' => $this->l('Features'),
|
||||
'name' => 'FEATURES_FILTER_BOX',
|
||||
'form_group_class' => 'features_filter_group',
|
||||
'groups_id_title' => $this->l('ID'),
|
||||
'groups_title' => $this->l('Feature name'),
|
||||
'values' => $features,
|
||||
'hint' => $this->l('Mark the features that will be displayed in the Features filter.'),
|
||||
),
|
||||
),
|
||||
'submit' => array(
|
||||
'title' => $this->l('Save'),
|
||||
@@ -120,13 +156,30 @@ class wkhotelfilterblock extends Module
|
||||
'&configure='.$this->name.'&module_name='.$this->name;
|
||||
$helper->token = Tools::getAdminTokenLite('AdminModules');
|
||||
|
||||
$fieldsValue = $this->getConfigFieldsValues();
|
||||
$selectedFeatures = $this->getSelectedFeatureIds();
|
||||
foreach ($features as $feature) {
|
||||
$fieldsValue['FEATURES_FILTER_BOX_'.$feature['id_group']] = in_array($feature['id_group'], $selectedFeatures);
|
||||
}
|
||||
|
||||
$helper->tpl_vars = array(
|
||||
'fields_value' => $this->getConfigFieldsValues(),
|
||||
'fields_value' => $fieldsValue,
|
||||
'languages' => $this->context->controller->getLanguages(),
|
||||
'id_language' => $this->context->language->id,
|
||||
);
|
||||
|
||||
return $helper->generateForm(array($fields_form));
|
||||
// show the features list only when the Features filter is enabled
|
||||
$script = '<script type="text/javascript">
|
||||
$(document).ready(function() {
|
||||
function toggleFeaturesGroup() {
|
||||
$(".features_filter_group").toggle($("input[name=\'SHOW_FEATURES_FILTER\']:checked").val() == 1);
|
||||
}
|
||||
$("input[name=\'SHOW_FEATURES_FILTER\']").on("change", toggleFeaturesGroup);
|
||||
toggleFeaturesGroup();
|
||||
});
|
||||
</script>';
|
||||
|
||||
return $helper->generateForm(array($fields_form)).$script;
|
||||
}
|
||||
|
||||
public function postProcess()
|
||||
@@ -137,7 +190,15 @@ class wkhotelfilterblock extends Module
|
||||
Tools::getValue('SHOW_AMENITIES_FILTER')
|
||||
);
|
||||
Configuration::updateValue('SHOW_PRICE_FILTER', Tools::getValue('SHOW_PRICE_FILTER'));
|
||||
|
||||
Configuration::updateValue('SHOW_FEATURES_FILTER', (int) Tools::getValue('SHOW_FEATURES_FILTER'));
|
||||
if(Tools::getValue('SHOW_FEATURES_FILTER')){
|
||||
Configuration::updateValue(
|
||||
'FEATURES_FILTER_IDS',
|
||||
implode(',', array_map('intval', (array) Tools::getValue('FEATURES_FILTER_BOX', array())))
|
||||
);
|
||||
}else{
|
||||
Configuration::updateValue('FEATURES_FILTER_IDS', '');
|
||||
}
|
||||
// redirect after saving the configuration
|
||||
Tools::redirectAdmin(
|
||||
$this->context->link->getAdminLink('AdminModules').'&configure='.$this->name.'&tab_module='.$this->tab.
|
||||
@@ -154,6 +215,8 @@ class wkhotelfilterblock extends Module
|
||||
|| !$this->registerHook('displayLeftColumn')
|
||||
|| !Configuration::updateValue('SHOW_AMENITIES_FILTER', 1)
|
||||
|| !Configuration::updateValue('SHOW_PRICE_FILTER', 1)
|
||||
|| !Configuration::updateValue('SHOW_FEATURES_FILTER', 0)
|
||||
|| !Configuration::updateValue('FEATURES_FILTER_IDS', '')
|
||||
) {
|
||||
return false;
|
||||
}
|
||||
@@ -229,6 +292,20 @@ class wkhotelfilterblock extends Module
|
||||
$currency = $this->context->currency;
|
||||
|
||||
$config = $this->getConfigFieldsValues();
|
||||
// features with their values for the features tree filter
|
||||
$room_type_features = array();
|
||||
if ($config['SHOW_FEATURES_FILTER'] && Feature::isFeatureActive()) {
|
||||
$selectedFeatures = $this->getSelectedFeatureIds();
|
||||
foreach (Feature::getFeatures($id_lang) as $feature) {
|
||||
if (!in_array((int) $feature['id_feature'], $selectedFeatures)) {
|
||||
continue;
|
||||
}
|
||||
if ($values = FeatureValue::getFeatureValuesWithLang($id_lang, (int) $feature['id_feature'])) {
|
||||
$feature['values'] = $values;
|
||||
$room_type_features[] = $feature;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$num_days = HotelHelper::getNumberOfDays($date_from, $date_to);
|
||||
|
||||
@@ -236,6 +313,7 @@ class wkhotelfilterblock extends Module
|
||||
$this->context->smarty->assign(array(
|
||||
'warning_num' => $warning_num,
|
||||
'all_amenities' => $all_amenities,
|
||||
'room_type_features' => $room_type_features,
|
||||
'max_adult' => $max_adult,
|
||||
'max_child' => $max_child,
|
||||
'cat_link' => $categoryUrl,
|
||||
@@ -259,14 +337,29 @@ class wkhotelfilterblock extends Module
|
||||
return array(
|
||||
'SHOW_AMENITIES_FILTER' => Configuration::get('SHOW_AMENITIES_FILTER'),
|
||||
'SHOW_PRICE_FILTER' => Configuration::get('SHOW_PRICE_FILTER'),
|
||||
'SHOW_FEATURES_FILTER' => Configuration::get('SHOW_FEATURES_FILTER'),
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the ids of the features selected in the configuration for the Features filter.
|
||||
*
|
||||
* @return int[]
|
||||
*/
|
||||
public function getSelectedFeatureIds()
|
||||
{
|
||||
$ids = (string) Configuration::get('FEATURES_FILTER_IDS');
|
||||
|
||||
return $ids === '' ? array() : array_map('intval', explode(',', $ids));
|
||||
}
|
||||
|
||||
public function uninstall()
|
||||
{
|
||||
if (!parent::uninstall()
|
||||
|| !Configuration::deleteByName('SHOW_AMENITIES_FILTER')
|
||||
|| !Configuration::deleteByName('SHOW_PRICE_FILTER')
|
||||
|| !Configuration::deleteByName('SHOW_FEATURES_FILTER')
|
||||
|| !Configuration::deleteByName('FEATURES_FILTER_IDS')
|
||||
) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -103,7 +103,7 @@
|
||||
<p>{l s='qty'}: {$product['quantity']}</p>
|
||||
{/if}
|
||||
</div>
|
||||
<div class="text-right">
|
||||
<div class="text-right service-price-action">
|
||||
<p>{displayPrice price=$product['price']}</p>
|
||||
<a class="btn btn-sm btn-default remove_roomtype_product" data-id-product="{$product['id_product']}"><i class="icon-trash"></i></a>
|
||||
</div>
|
||||
|
||||
@@ -53,13 +53,31 @@
|
||||
{block name='room_type_list_room_description'}
|
||||
<div class="rm_desc">{$room_v['description_short']|truncate:190:"":true} <a class="view_more" href="{$room_v['product_link']|escape:'htmlall':'UTF-8'}">{l s='View More'}....</a></div>
|
||||
{/block}
|
||||
{block name='room_type_list_room_featured_features'}
|
||||
{if !empty($room_v['featured_features'])}
|
||||
<div class="row">
|
||||
<div class="col-sm-12 room_featured_features">
|
||||
{foreach from=$room_v['featured_features'] item=featured_feature}
|
||||
<span class="room_featured_feature">
|
||||
{if $featured_feature.logo_type == 'icon' && $featured_feature.logo}
|
||||
<i class="{$featured_feature.logo|escape:'htmlall':'UTF-8'}"></i>
|
||||
{else}
|
||||
<img src="{$smarty.const._PS_IMG_}rf/{$featured_feature.id_feature|intval}.jpg" alt="" onerror="this.style.display='none'" />
|
||||
{/if}
|
||||
{$featured_feature.name|escape:'htmlall':'UTF-8'}
|
||||
</span>
|
||||
{/foreach}
|
||||
</div>
|
||||
</div>
|
||||
{/if}
|
||||
{/block}
|
||||
<div class="room_features_cont">
|
||||
<div class="row">
|
||||
{block name='room_type_list_room_features'}
|
||||
<div class="col-sm-12 col-md-5 col-lg-6">
|
||||
{if !empty($room_v['feature'])}
|
||||
{if !empty($room_v['featured_amenities'])}
|
||||
<p class="rm_amenities_cont">
|
||||
{foreach from=$room_v['feature'] key=feat_k item=feat_v}
|
||||
{foreach from=$room_v['featured_amenities'] key=feat_k item=feat_v}
|
||||
{if $feat_v.logo_type == 'icon' && $feat_v.logo}
|
||||
<i class="{$feat_v.logo|escape:'htmlall':'UTF-8'} rm_amen" title="{$feat_v.name|escape:'htmlall':'UTF-8'}"></i>
|
||||
{elseif $feat_v.logo_type == 'image' && $feat_v.logo}
|
||||
|
||||
@@ -108,9 +108,6 @@
|
||||
p.capa_txt {
|
||||
margin-bottom: 15px;
|
||||
}
|
||||
.visible-md .capa_txt {
|
||||
padding-left: 15px;
|
||||
}
|
||||
|
||||
.rm_review_cont
|
||||
{
|
||||
@@ -161,6 +158,18 @@ p.capa_txt {
|
||||
margin-bottom: 5px;
|
||||
}
|
||||
|
||||
.room_featured_feature
|
||||
{
|
||||
display: inline-block;
|
||||
margin: 0 15px 5px 0;
|
||||
}
|
||||
|
||||
.room_featured_feature img
|
||||
{
|
||||
max-height: 20px;
|
||||
max-width: 20px;
|
||||
}
|
||||
|
||||
.rm_price_val
|
||||
{
|
||||
clear: both;
|
||||
|
||||
@@ -1442,6 +1442,17 @@ Quick View Styles
|
||||
color: #505050;
|
||||
}
|
||||
|
||||
/* featured amenities (room type + hotel) */
|
||||
.featured_amenities .featured_amenity {
|
||||
display: inline-block;
|
||||
margin: 0 20px 8px 0;
|
||||
}
|
||||
.featured_amenities .featured_amenity img {
|
||||
max-height: 20px;
|
||||
max-width: 20px;
|
||||
}
|
||||
/* end */
|
||||
|
||||
/* service popup design */
|
||||
.services-info-tooltip-cont {
|
||||
min-width: 240px;
|
||||
@@ -1471,6 +1482,15 @@ Quick View Styles
|
||||
flex-wrap: wrap;
|
||||
justify-content: space-between;
|
||||
}
|
||||
.extra-service-panel .services-list .services-list-row .service-price-action {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: flex-end;
|
||||
gap: 10px;
|
||||
}
|
||||
.extra-service-panel .services-list .services-list-row .service-price-action p {
|
||||
margin: 0;
|
||||
}
|
||||
.extra-service-panel .summary-row .service_price {
|
||||
font-weight: 700;
|
||||
}
|
||||
|
||||
@@ -261,18 +261,45 @@
|
||||
</div>
|
||||
{/if}
|
||||
{/block}
|
||||
{block name='product_info_tab_featured_amenities'}
|
||||
{if isset($featured_amenities) && $featured_amenities}
|
||||
<div class="row info_margin_div featured_amenities">
|
||||
<div class="col-sm-12">
|
||||
<div class="room_info_heading">
|
||||
<span>{l s='Featured Amenities'}</span>
|
||||
</div>
|
||||
<div class="room_info_content row">
|
||||
{foreach from=$featured_amenities item=amenity}
|
||||
<div class="col-sm-4 col-xs-6">
|
||||
<span class="featured_amenity" title="{$amenity.name|escape:'html':'UTF-8'}">
|
||||
{if $amenity.logo_type == 'icon' && $amenity.logo}
|
||||
<i class="{$amenity.logo|escape:'html':'UTF-8'}"></i>
|
||||
{elseif $amenity.logo_type == 'image' && $amenity.logo}
|
||||
<img src="{$amenity_img_dir|escape:'html':'UTF-8'}{$amenity.id|intval}.jpg" alt="{$amenity.name|escape:'html':'UTF-8'}" />
|
||||
{/if}
|
||||
<span class="amenity-name">{$amenity.name|escape:'html':'UTF-8'}</span>
|
||||
</span>
|
||||
</div>
|
||||
{/foreach}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{/if}
|
||||
{/block}
|
||||
{block name='product_info_tab_room_features'}
|
||||
{if isset($room_type_features) && $room_type_features}
|
||||
<div class="info_margin_div">
|
||||
{assign var="current_feature_name" value=""}
|
||||
{assign var="current_feature_values" value=""}
|
||||
{assign var="current_feature_id" value=0}
|
||||
{assign var="current_feature_logo_type" value=""}
|
||||
{assign var="current_feature_logo" value=""}
|
||||
{foreach from=$room_type_features item=feature}
|
||||
{if $feature.name != $current_feature_name}
|
||||
{if $current_feature_name != ""}
|
||||
<div class="room_feature_group">
|
||||
<div class="room_info_heading">
|
||||
<img src="{$smarty.const._PS_IMG_}rf/{$current_feature_id|intval}.jpg" alt="{$current_feature_name|escape:'html':'UTF-8'}" title="{$current_feature_name|escape:'html':'UTF-8'}" style="max-height:20px;max-width:20px;" onerror="this.style.display='none'" />
|
||||
{if $current_feature_logo_type == 'icon' && $current_feature_logo}<i class="{$current_feature_logo|escape:'html':'UTF-8'}"></i>{else}<img src="{$smarty.const._PS_IMG_}rf/{$current_feature_id|intval}.jpg" alt="{$current_feature_name|escape:'html':'UTF-8'}" title="{$current_feature_name|escape:'html':'UTF-8'}" style="max-height:20px;max-width:20px;" onerror="this.style.display='none'" />{/if}
|
||||
<span>{$current_feature_name|escape:'html':'UTF-8'}</span>
|
||||
</div>
|
||||
<div class="room_info_content">{$current_feature_values|escape:'html':'UTF-8'}</div>
|
||||
@@ -280,6 +307,8 @@
|
||||
{/if}
|
||||
{assign var="current_feature_name" value=$feature.name}
|
||||
{assign var="current_feature_id" value=$feature.id_feature}
|
||||
{assign var="current_feature_logo_type" value=$feature.logo_type}
|
||||
{assign var="current_feature_logo" value=$feature.logo}
|
||||
{assign var="current_feature_values" value=$feature.value}
|
||||
{else}
|
||||
{assign var="current_feature_values" value="`$current_feature_values`, `$feature.value`"}
|
||||
@@ -287,7 +316,7 @@
|
||||
{if $feature@last}
|
||||
<div class="room_feature_group">
|
||||
<div class="room_info_heading">
|
||||
<img src="{$smarty.const._PS_IMG_}rf/{$current_feature_id|intval}.jpg" alt="{$current_feature_name|escape:'html':'UTF-8'}" title="{$current_feature_name|escape:'html':'UTF-8'}" style="max-height:20px;max-width:20px;" onerror="this.style.display='none'" />
|
||||
{if $current_feature_logo_type == 'icon' && $current_feature_logo}<i class="{$current_feature_logo|escape:'html':'UTF-8'}"></i>{else}<img src="{$smarty.const._PS_IMG_}rf/{$current_feature_id|intval}.jpg" alt="{$current_feature_name|escape:'html':'UTF-8'}" title="{$current_feature_name|escape:'html':'UTF-8'}" style="max-height:20px;max-width:20px;" onerror="this.style.display='none'" />{/if}
|
||||
<span>{$current_feature_name|escape:'html':'UTF-8'}</span>
|
||||
</div>
|
||||
<div class="room_info_content">{$current_feature_values|escape:'html':'UTF-8'}</div>
|
||||
@@ -303,11 +332,11 @@
|
||||
{if isset($room_dynamic_amenities) && $room_dynamic_amenities}
|
||||
<div class="info_margin_div">
|
||||
<div class="room_info_heading">
|
||||
<span>{l s='%s Amenities' sprintf=$property_type}</span>
|
||||
<span>{l s='%s Amenities' sprintf=$room_type_info['selling_object_name']}</span>
|
||||
</div>
|
||||
<div class="room_info_content row">
|
||||
{foreach from=$room_dynamic_amenities item=amenity}
|
||||
<div class="col-sm-4 col-xs-12" title="{$amenity.name|escape:'html':'UTF-8'}">
|
||||
<div class="col-sm-4 col-xs-6" title="{$amenity.name|escape:'html':'UTF-8'}">
|
||||
{if $amenity.logo_type == 'icon' && $amenity.logo}
|
||||
<i class="{$amenity.logo|escape:'html':'UTF-8'}"></i>
|
||||
{elseif $amenity.logo_type == 'image' && $amenity.logo}
|
||||
@@ -331,7 +360,7 @@
|
||||
</div>
|
||||
<div class="room_info_content row">
|
||||
{foreach from=$hotel_dynamic_amenities item=amenity}
|
||||
<div class="col-sm-4 col-xs-12" title="{$amenity.name|escape:'html':'UTF-8'}">
|
||||
<div class="col-sm-4 col-xs-6" title="{$amenity.name|escape:'html':'UTF-8'}">
|
||||
{if $amenity.logo_type == 'icon' && $amenity.logo}
|
||||
<i class="{$amenity.logo|escape:'html':'UTF-8'}"></i>
|
||||
{elseif $amenity.logo_type == 'image' && $amenity.logo}
|
||||
|
||||
Reference in New Issue
Block a user