src/Elements/Bundle/DemiFrontendBundle/Resources/views/Includes/teaser/acco-teaser-card.html.twig line 1

Open in your IDE?
  1. {% if freeCancellationInList %}
  2.     {% set freeCancellationInList = accommodationItem.getHasFreeCancellation(searchParam.getDateFrom(), searchParam.getDateTo()) %}
  3. {% endif %}
  4. {% set isWhiteLabel =  demi_core_configuration("getIsWhitelabel",[]) %}
  5. {% set detailUrl = '' %}
  6. {% if noDate %}
  7.     {% set fromDate = null %}
  8. {% else %}
  9.     {% set fromDate = demi_getSearchFrom().getTimeStamp() %}
  10. {% endif %}
  11. {% if accommodationItem %}
  12.     {% set accommodation = pimcore_object(accommodationItem.getAccommodationId()) %}
  13.     {% set minPriceProducts = accommodationItem.getMinPriceProductSets() %}
  14.     {% set totalVacancies = accommodationItem.getTotalVacanciesAndOffers().getTotalVacancies() %}
  15.     {% set totalOffers = accommodationItem.getTotalVacanciesAndOffers().getTotalOffers() %}
  16.     {% set actualBookable = accommodationItem.getActualBookable() %}
  17.     {% set price = noDate ? accommodationItem.getMinPriceBase() : accommodationItem.getMinPrice() %}
  18.     {% set priceBeforeSpecial = demi_getMinPriceBeforeSpecial(accommodationItem) %}
  19.     {% set hasMinprice = demi_hasMinPriceProductSpecials(accommodationItem) %}
  20.     {% set minPriceMeal = demi_getMinPriceProductMeals(accommodationItem)%}
  21.     {% if tvbPackage is defined and tvbPackage is not null and minPriceProducts | length > 0 %}
  22.         {% set mealCode = minPriceProducts.0.getMealCode() %}
  23.     {% endif %}
  24. {% endif %}
  25. {% if tvbPackage is defined and tvbPackage is not null %}
  26.     {% set detailUrl = demi_demiUrl({"accommodation" : accommodation, "package" : tvbPackage, "locale" : app.request.locale},
  27.     'demi_acco_detail_tvbpackage_page', noDate and app.request().get('nearbySearchId') is not defined) %}
  28.     {% set imageGalleryId = "id_" ~ accommodation.getId() %}
  29. {% elseif isPackageSearch %}
  30.     {% set housePackageMaster = pimcore_object(accommodationItem.getHousePackageMasterId()) %}
  31.     {% set detailUrl = demi_demiUrl({'accommodation' : accommodation, 'package' : housePackageMaster, "locale" : app.request.locale},
  32.     'demi_acco_detail_package_page', noDate and app.request().get('nearbySearchId') is not defined) %}
  33.     {% set imageGalleryId = "id_" ~ housePackageMaster.getId() %}
  34. {% else %}
  35.     {% set detailUrl = pimcore_url({'object' : accommodation, "language": app.request.locale},
  36.     'demi_acco_detail_page', noDate and app.request().get('nearbySearchId') is not defined) %}
  37.     {% set imageGalleryId = "id_" ~ accommodation.getId() %}
  38. {% endif %}
  39. {% set lightboxTopBarUrl = url('demi_lightbox_topbar_content', {
  40.     'path' : document.getFullPath | trim('/', 'right')
  41. }) %}
  42. {% set maxRatingValue = demi_core_configuration("getMaxRatingValue", {}) ?: 5 %}
  43. {% set maxRatingNormalized = demi_core_configuration("getMaxRatingNormalized", {}) ?: 5 %}
  44. {% if noDate and isPackageSearch %}
  45.     {% set myMinPrice = 0 %}
  46.     {% for accommodationProduct in accommodationItem.getProducts() %}
  47.         {% if accommodationProduct.getBasePrice() is not null and (myMinPrice == 0 or myMinPrice > accommodationProduct.getBasePrice()) %}
  48.             {% set myMinPrice = accommodationProduct.getBasePrice() %}
  49.         {% endif %}
  50.     {% endfor %}
  51.     {% set price = myMinPrice %}
  52. {% endif %}
  53. {% set targetBlank = '' %}
  54. {% if not isWhiteLabel and not pimcore_device().isPhone() %}
  55.     {% set targetBlank = 'target="_blank"' %}
  56. {% endif %}
  57. {% set accoPosition = accommodation.getPosition() %}
  58. {% set isMapAllowed = not pimcore_checkbox('noMapAllowed').isChecked() %}
  59. {% set showMapToggle = pimcore_checkbox('showMapToggle').isChecked() %}
  60. {% set showMapInitially = not pimcore_checkbox('hideMapInitially').isChecked() %}
  61. {% set useListTeaserStyle = not pimcore_checkbox('useListTiles').isChecked() %}
  62. {% set showMap = isMapAllowed and not pimcore_device().isPhone() and ((app.request.get('showMap') is null and showMapInitially) or app.request.get('showMap') == 1) %}
  63. <section class="card-teaser box-shadow isClickable {{ styleModifier }} js-tracking js-tracking--impression"
  64.          data-acco-id="{{ accommodation.getId() }}"
  65.     {% if accoPosition is not null and (searchParam is instanceof("\\Elements\\Demi\\Accommodation\\Search\\Parameter") and searchParam.getIsAlternative()) %}
  66.         data-acco-lat="{{ accoPosition.getLatitude() }}"
  67.         data-acco-lon="{{ accoPosition.getLongitude() }}"
  68.     {% endif %}
  69.          data-tracking-name="{{ demi_impressionName(accommodation) }}"
  70.          data-tracking-id="{{ accommodation.getId() }}"
  71.          data-tracking-category="{{ demi_impressionCategory(accommodation,housePackageMaster is defined ? housePackageMaster : null,searchParam,tvbPackage is defined ? tvbPackage : null) }}"
  72.          data-tracking-position="{{ position }}"
  73.          data-tracking-brand="{{ demi_impressionBrand(accommodation) }}"
  74.          data-tracking-list="{{ demi_impressionListType(searchParam) }}"
  75.          data-tracking-price="{{ price | number_format(2, '.', '') }}" >
  76.     {#
  77.     // ---
  78.     // Image
  79.     // ---
  80.     #}
  81.     <div>
  82.         {% set gallerySrcUrl = demi_demiUrl({
  83.             'path' : 'demi',
  84.             'objectId' : isPackageSearch ? housePackageMaster.getId() : accommodation.getId(),
  85.             'fallbackId' : isPackageSearch ? accommodation.getId() : '',
  86.             'thumbnail' : 'demi-desktop-gallery',
  87.             'thumbSmall' : 'demi-desktop-gallery-small',
  88.             'dateFrom' : fromDate ?: ''
  89.         }, 'demi_images') %}
  90.         {% set useHpmImage = (tvbPackage is not defined or tvbPackage is null) and housePackageMaster is defined and housePackageMaster is not null and housePackageMaster.getPackagetype()!='HousePackageMasterSelfAssign' %}
  91.         {% set firstImageUrl = demi_demiUrl({
  92.             'path' : 'demi',
  93.             'objectId' : useHpmImage ? housePackageMaster.getId() : accommodation.getId(),
  94.             'fallbackId' : isPackageSearch ? accommodation.getId() : '',
  95.             'thumbnail' : 'demi-hotel-list-card-teaser',
  96.             'dateFrom' : fromDate ?: ''
  97.         }, 'demi_image') %}
  98.         <script type="text/javascript" data-cookieconsent="ignore">
  99.             _config.lightbox = true;
  100.             _config.lazyImg = true;
  101.         </script>
  102.         <div class="embed-responsive embed-responsive-16by9">
  103.             <div class="embed-responsive-item d-flex flex-column">
  104.                 <div class="card-teaser__img btn-show-gallery-container js-lazy-img js-lazy-img--bg flex-fill"
  105.                     data-img-url="{{ firstImageUrl }}"
  106.                     role="img"
  107.                     aria-label="{{ accommodation.getName() | replace({"*" : ""}) }}">
  108.                     {% if not pimcore_device().isPhone() %}
  109.                     <button type="button" class="btn-show-gallery btn-no-styling js-lightbox-group-dyn js-tracking--click-piwik"
  110.                             aria-label="{{ 'demi.detail.open-gallery' | trans }}"
  111.                             title="{{ 'demi.detail.open-gallery' | trans }}"
  112.                             data-lightbox-id="{{ imageGalleryId }}"
  113.                             data-lightbox-src-url="{{ gallerySrcUrl }}"
  114.                             data-lightbox-topbar-content-url="{{ lightboxTopBarUrl }}?ajax=1&id={{ accommodation.getId() }}{{ housePackageMaster is defined and housePackageMaster is not null ? '&pid='~housePackageMaster.getId() : ''}}{{ tvbPackage is defined and tvbPackage is not null ? '&tid='~tvbPackage.getId():''}}"
  115.                             data-lightbox-topbar-wrapper="#lightboxTopBar"
  116.                             data-tracking-category="{{ isPackageSearch ? 'Package list': 'Accommodation list' }}"
  117.                             data-tracking-action="open gallery">
  118.                         <span class="js-lightbox-group-dyn__icon demi-icon demi-icon-search btn-show-gallery__icon" aria-hidden="true"></span>
  119.                         <span class="js-lightbox-group-dyn__loading" hidden>
  120.                             <span class="text-center d-block">
  121.                             <span class="circle-spinner circle-spinner--white"
  122.                                   aria-label="{{ 'demi.content-loading' | trans  }}"
  123.                                   title="{{ 'demi.content-loading' | trans  }}"></span>
  124.                             </span>
  125.                         </span>
  126.                     </button>
  127.                 {% endif %}
  128.                 </div>
  129.                {# // Min Price #}
  130.             {% if hasMinPrice is defined and hasMinPrice %}
  131.                 {% for special in demiAccommodationResultSetHelper.getMinPriceProductSpecials(accommodationItem) %}
  132.                     <div class="card-teaser__label bg-warning text-center p-1 small text-white strong">
  133.                         {{ special }}
  134.                     </div>
  135.                {% endfor %}
  136.            {% endif %}
  137.             </div>
  138.         </div>
  139.     </div>
  140. {#
  141. // Mail
  142. #}
  143.     <div class="px-3 pb-3 pt-2 d-flex flex-column flex-fill">
  144.     <div class="mb-1">
  145.         {% if demi_pimcore_admin_session() %}
  146.             <small style="background: #c5c5cb; padding: 2px">
  147.                 Prio:{{ accommodation.getPriority() }} ContentScore:{{ accommodation.getContentScore() }} bookable:{{ noDate ? accommodation.getBookable() : accommodationItem.getActualBookable()  }}<br/>
  148.                 (nur sichtbar bei aktiver Pimcore Admin Session!)
  149.             </small>
  150.         {% endif %}
  151.         {% if accommodation.getIsTesthotel() %}
  152.             <div class="demi-test-acco-notice text-danger"><strong>Testbetrieb</strong> nur für Debug/aktive Pimcore User sichtbar</div>
  153.         {% endif %}
  154.         {% if isPackageSearch %}
  155.             <h3 class="mb-1 text-primary">
  156.                 <a href="{{ detailUrl }}" {{ targetBlank|raw }}>{{ housePackageMaster.getName() }} </a>
  157.             </h3>
  158.             <h6 class="mb-1">
  159.                 {{ demi_getAccoNameWithStars(accommodation) }}
  160.             </h6>
  161.         {% else %}
  162.             <h3 class="mb-1 text-primary card-teaser__title">
  163.                 <a href="{{ detailUrl }}" {{ targetBlank|raw }}>{{  demi_getAccoNameWithStars(accommodation) }}</a>
  164.             </h3>
  165.         {% endif %}
  166.         {% if accommodation.getRatingSystem() is same as "TrustYou" %}
  167.             {% set normalizedRating = demi_ratingGetNormalized(accommodation, maxRatingValue, maxRatingNormalized) %}
  168.             {% if pimcore_device().isPhone() and normalizedRating %}
  169.                 {{ include('@ElementsDemiFrontend/Includes/rating.html.twig', {
  170.                     "score" : normalizedRating,
  171.                     "text" : accommodation.getRatingScoreDescription(),
  172.                     "styleModifier" : "mb-1 text-success",
  173.                     "isTextWhite" : false
  174.                 }) }}
  175.             {% endif %}
  176.         {% endif %}
  177.         <div class="mb-1">
  178.             {{ accommodation.getCategoryNames() }}
  179.         </div>
  180.         <div class="mb-1">
  181.             {{ include('@ElementsDemiFrontend/Includes/accoClassifications.html.twig', {
  182.                 'classifications' : accommodation.getClassifications()
  183.             }) }}
  184.         </div>
  185.         <div class="mb-1 small text-muted">
  186.             {% if accommodation.getTown() and accommodation.getTown().getName() %}
  187.                 <div class="media">
  188.                     <div class="demi-icon demi-icon-marker mr-1 icon-in-text" title="{{ 'demi.list.town' | trans }}" aria-label="{{ 'demi.list.town' | trans }}"></div>
  189.                     <div class="media-body">
  190.                         {{ accommodation.getTown().getName() }}
  191.                     </div>
  192.                 </div>
  193.             {% elseif accommodation.getDistrict() and (accommodation.getDistrict().getNameLocalized(app.request.locale) or accommodation.getDistrict().getName()) %}
  194.                 <div class="media">
  195.                     <div class="demi-icon demi-icon-marker mr-1 icon-in-text" title="{{ 'demi.list.town' | trans }}" aria-label="{{ 'demi.list.town' | trans }}"></div>
  196.                     <div class="media-body">
  197.                         {{ accommodation.getDistrict().getNameLocalized(app.request.locale) ?? accommodation.getDistrict().getName() }}
  198.                     </div>
  199.                 </div>
  200.             {% endif %}
  201.         </div>
  202.         {% if searchParam is instanceof("\\Elements\\Demi\\Accommodation\\Search\\Parameter") and searchParam.getIsAlternative() %}
  203.             <div class="text-primary small font-medium">
  204.                 {% set nights = searchParam.getNights() %}
  205.                 {% set array = {"[FROM-TO]" : min(nights) ~ '-' ~ max(nights),
  206.                     "[FROM-DATE]" : elements_dateFormat(searchParam.getDateFrom().getTimestamp(), 'date-long'),
  207.                     "[TO-DATE]" : elements_dateFormat(searchParam.getDateTo().getTimestamp(), 'date-long')}
  208.                 %}
  209.                 {{ demi_fillTranslation(array, "demi.detail.alternative-search-suggestion") }}
  210.             </div>
  211.         {% endif %}
  212.         {% if nearbySearchName is defined and nearbySearchName is not null and accoPosition is not null %}
  213.             {% set latAcco = accoPosition.getLatitude() %}
  214.             {% set longAcco = accoPosition.getLongitude() %}
  215.             {% set latNbSO = app.request().get("nearbySearchLat") %}
  216.             {% set longNbSO = app.request().get("nearbySearchLong") %}
  217.             {% set distanceValue = demi_calcDistance(latAcco,longAcco,latNbSO,longNbSO) %}
  218.             {% set distance = {
  219.                 'value' : demi_fillTranslation({"[DISTANCE]" : distanceValue | round(1)}, "demi.list.nearby-search.text"),
  220.                 'from' : 'demi.list.nearby-search.from' | trans ~ ' ' ~ nearbySearchName
  221.             } %}
  222.             {% if distanceValue %}
  223.                 <div class="mb-1 distance-info small">
  224.                     <span class="badge distance-info__badge">{{ distance.value }}</span>
  225.                     {% if accommodationItem.getDistanceMinutesToPoi() %}
  226.                         <span>{{ demi_fillTranslation({"[MIN]" : accommodationItem.getDistanceMinutesToPoi() | round(1)}, "demi.list.nearby-search.distance-in-min") }}</span>
  227.                     {% endif %}
  228.                     <br>
  229.                     <span>{{ distance.from }}</span>
  230.                 </div>
  231.             {% endif %}
  232.         {% endif %}
  233.         {% if accommodationItem %}
  234.             {{ include('@ElementsDemiFrontend/Includes/teaser/badges.html.twig', {
  235.                 'accommodation' : accommodation,
  236.                 'accommodationItem' : accommodationItem
  237.             }) }}
  238.         {% endif %}
  239.         {% set accoTopFacilities = demi_getTopFacilitiesForAccommodation(accommodation,demi_core_configuration("getTopFacilities", {})) %}
  240.         {% if not pimcore_device().isPhone() and accoTopFacilities | length > 0 or freeCancellationInList %}
  241.             <ul class="list-inline list-inline--dots mb-1 small">
  242.                 {% if freeCancellationInList %}
  243.                 <li class="list-inline-item  free-cancellation">
  244.                     {{ searchParam is instanceof("\\Elements\\Demi\\Accommodation\\Search\\Parameter") and searchParam.getFreeCancellation() ? "demi.list.free-cancellation-filtered" : "demi.list.free-cancellation" | trans }}
  245.                 </li>
  246.                 {% endif %}
  247.                 {% if accoTopFacilities | length > 0 %}
  248.                 {% for topFacility in accoTopFacilities %}
  249.                     <li class="list-inline-item">
  250.                         {{ topFacility.getName() }}
  251.                     </li>
  252.                 {% endfor %}
  253.                 {% endif %}
  254.             </ul>
  255.         {% elseif freeCancellationInList %}
  256.         <ul class="list-inline list-inline--dots mb-1 small">
  257.             <li class="list-inline-item free-cancellation">
  258.                 {{ searchParam is instanceof("\\Elements\\Demi\\Accommodation\\Search\\Parameter") and searchParam.getFreeCancellation() ? "demi.list.free-cancellation-filtered" : "demi.list.free-cancellation" | trans }}
  259.             </li>
  260.         </ul>
  261.         {% endif %}
  262.         {% set tvbListNoDate = searchParam is instanceof("\\Elements\\Demi\\Accommodation\\Search\\Parameter") and not searchParam.getDateFrom() %}
  263.         {% if pimcore_device().isPhone() and actualBookable and not tvbListNoDate %}
  264.             {{ include('@ElementsDemiFrontend/Accommodation/includes/acco-teaser-vacancy-info.html.twig', {
  265.                 'totalVacancies':totalVacancies,
  266.                 'totalOffers':totalOffers
  267.             }) }}
  268.         {% endif %}
  269.         {% if accommodation.getRatingSystem() is same as "TrustYou" %}
  270.             {% set normalizedRating = demi_ratingGetNormalized(accommodation, maxRatingValue, maxRatingNormalized) %}
  271.             {% if not pimcore_device().isPhone() and normalizedRating %}
  272.                 <div class="trustyou-logo mb-1"><span class="sr-only">TrustYou Rating</span></div>
  273.                 {{ include('@ElementsDemiFrontend/Includes/rating.html.twig', {
  274.                     "score" : normalizedRating,
  275.                     "text" : accommodation.getRatingScoreDescription(),
  276.                     "styleModifier" : "mb-2 text-success",
  277.                     "showReviewCount" : false,
  278.                     "isTextWhite" : false
  279.                 }) }}
  280.             {% endif %}
  281.         {% endif %}
  282.     </div>
  283.     <div class="row mt-auto">
  284.         <div class="col">
  285.             <div class="small text-muted">
  286.                 <div class="media">
  287.                      {% if minPriceMeal %}
  288.                             <div class="demi-icon demi-icon-restaurant mr-1" aria-label="{{ 'demi.list.meals' | trans }}" title="{{ 'demi.list.meals' | trans }}"></div>
  289.                             <div class="media-body">
  290.                                 {{ minPriceMeal }}
  291.                     </div>
  292.                     {% elseif searchParam.getIsCorridor() %}
  293.                     <div class="media-body">{{ 'demi.detail.priceinfo.per-person-per-night' | trans }}</div>
  294.                     {% elseif accommodationItem and accommodationItem.getPriceInfo() %}
  295.                     <div class="media-body">{{ include('@ElementsDemiFrontend/Includes/priceInfoStr.html.twig', {'type' : accommodationItem.getPriceInfo().type, 'nights' : accommodationItem.getPriceInfo().nights}) }}</div>
  296.                     {% elseif accommodationItem and accommodationItem.getMinPriceProductSets() is not empty and accommodationItem.getMinPriceProductSets().0.getPriceInfo() is iterable and accommodationItem and accommodationItem.getMinPriceProductSets() %}
  297.                         {% set productToUse = accommodationItem.getMinPriceProductSets().0 %}
  298.                         {% if  productToUse.getPriceInfo() is not empty %}
  299.                         <div class="media-body">{{ include('@ElementsDemiFrontend/Includes/priceInfoStr.html.twig', {'type' : productToUse.getPriceInfo().rule, 'nights' : productToUse.getPriceInfo().nights }) }}</div>
  300.                         {% endif %}
  301.                     {% endif %}
  302.                 </div>
  303.             </div>
  304.             <div class="row align-items-baseline">
  305.                 <div class="{{ priceBeforeSpecial > price ? 'col ' : '' }}col-lg-12">
  306.                     {% if priceBeforeSpecial > price %}
  307.                         <span class="sr-only">{{ 'demi.instead-of' | trans }}</span>
  308.                         <span class="col text-muted">
  309.                                 {{ demi_paymentGetPriceObject(priceBeforeSpecial, accommodation) }}
  310.                             </span>
  311.                     {% endif %}
  312.                 </div>
  313.                 {% if price > 0 %}
  314.                     <strong class="col col-auto mr-auto text-success">
  315.                         {{ "demi.price-from-short" | trans }} <span class="acco-teaser__price">{{ demi_paymentGetPriceObject(price, accommodation) }}</span>
  316.                     </strong>
  317.                 {% endif %}
  318.             </div>
  319.             {% set tvbListNoDate = searchParam is instanceof("\\Elements\\Demi\\Accommodation\\Search\\Parameter") and not searchParam.getDateFrom() %}
  320.             {% if actualBookable and not tvbListNoDate %}
  321.                 {{ include('@ElementsDemiFrontend/Accommodation/includes/acco-teaser-vacancy-info.html.twig', {
  322.                     'totalVacancies' : totalVacancies,
  323.                     'totalOffers' : totalOffers,
  324.                     'styleModifier' : ''
  325.                 }) }}
  326.             {% endif %}
  327.             {% if isMapAllowed and accoPosition is not null and accoPosition.getLatitude() and accoPosition.getLongitude()  %}
  328.                 <button type="button" class="btn-no-styling js-accommodation-map__show-on-map teaser__show-on-map mt-2">
  329.                     <span class="demi-icon demi-icon-marker icon-in-text" aria-hidden="true"></span>
  330.                     <span> {{ 'demi.list.show-on-map' | trans }} </span>
  331.                 </button>
  332.             {% endif %}
  333.         </div>
  334.         <div class="col col-auto align-self-center">
  335.             <a href="{{ detailUrl }}" class="btn btn-default teaser__detail-btn" {{ targetBlank|raw }}
  336.                title="{{ 'demi.list.detailsite' | trans }}" aria-label="{{ 'demi.list.detailsite' | trans }}">
  337.                 <span class="demi-icon demi-icon-arrow-right" aria-hidden="true"></span>
  338.             </a>
  339.         </div>
  340.     </div>
  341.     </div>
  342. </section>