* Suchformular auf Startseite funktioniert nun

* Neueste Design-Änderungen aufgenommen
* Sortierung auf Reiseübersichtsseiten
* Fehler bei Suche behoben

git-svn-id: http://78.47.251.156/svn/dev/sterntours-3@3285 f459cee4-fb09-11de-96c3-f9c5f16c3c76
This commit is contained in:
uli 2016-12-19 08:41:15 +00:00
parent 99c6715712
commit 23b2c7a7e8
12 changed files with 217 additions and 119 deletions

View file

@ -71,7 +71,9 @@
<div id="fullwidth" class="col-sm-12"> <div id="fullwidth" class="col-sm-12">
{% block breadcrumb %} {% block breadcrumb %}
{{ render(controller('AppBundle:Default:breadcrumb', {'page': page})) }} {% if page is defined %}
{{ render(controller('AppBundle:Default:breadcrumb', {'page': page})) }}
{% endif %}
{% endblock %} {% endblock %}
<!-- START CONTENT --> <!-- START CONTENT -->

View file

@ -58,35 +58,31 @@
<div class="tab-content"> <div class="tab-content">
<div role="tabpanel" class="tab-pane active" id="tab_01"> <div role="tabpanel" class="tab-pane active" id="tab_01">
<form class="bookform form-inline row"> <form class="bookform form-inline row" action="/suche" method="get">
<div class="form-group col-md-3 col-sm-6 col-xs-12"> <div class="form-group col-md-3 col-sm-6 col-xs-12">
<div class="dropdown"> <div class="dropdown">
<select class="selectpicker" data-style="btn-white" data-dropup-auto="false"> <select class="selectpicker" data-style="btn-white" data-dropup-auto="false" name="c">
<option>Reiseziel</option> <option value="">beliebiges Reiseziel</option>
<option value="">beliebig</option> {% for destination in destinations %}
<option value="5">Ägypten</option> <option value="{{ destination.id }}">{{ destination.name }}</option>
<option value="6">Israel</option> {% endfor %}
<option value="7">Jordanien</option>
<option value="9">Marokko</option>
<option value="10">VAE</option>
<option value="11">Türkei</option>
<option value="12">Iran</option>
<option value="15">Usbekistan</option>
<option value="16">Oman</option>
</select> </select>
</div> </div>
</div> </div>
<div class="form-group col-md-2 col-sm-6 col-xs-12"> <div class="form-group col-md-2 col-sm-6 col-xs-12">
<div class="input-group"> <div class="input-group">
<input type="text" class="form-control datepicker" placeholder="Anreise" id=""> <input id="" name="b" value="{{ startDate|date }}"
type="text" class="form-control datepicker" placeholder="Anreise"
>
<div class="input-group-addon"><i class="fa fa-calendar"></i></div> <div class="input-group-addon"><i class="fa fa-calendar"></i></div>
</div> </div>
</div> </div>
<div class="form-group col-md-2 col-sm-6 col-xs-12"> <div class="form-group col-md-2 col-sm-6 col-xs-12">
<div class="input-group"> <div class="input-group">
<input type="text" class="form-control datepicker" placeholder="Abreise" id=""> <input id="" name="e" value="{{ endDate|date }}"
type="text" class="form-control datepicker" placeholder="Abreise"
>
<div class="input-group-addon"><i class="fa fa-calendar"></i></div> <div class="input-group-addon"><i class="fa fa-calendar"></i></div>
</div> </div>
</div> </div>

View file

@ -37,7 +37,7 @@
<div class="dates-count"> <div class="dates-count">
{{ travel_program.travelDates|length }} passende{% if travel_program.travelDates|length > 1 %} Termine{% else %}r Termin{% endif %} {{ travel_program.travelDates|length }} passende{% if travel_program.travelDates|length > 1 %} Termine{% else %}r Termin{% endif %}
</div> </div>
<div class="price pull-left"><span class="small">p.P.</span> ab {{ travel_program.lowestPrice|number_format(2) }} €</div> <div class="price pull-left"><span class="small">p.P.</span> ab {{ travel_program.lowestPrice|number_format }} €</div>
<div class="pull-right"> <div class="pull-right">
{# #TODO #} {# #TODO #}
@ -76,8 +76,8 @@
<td data-title="Termin-Nr."><strong>{{ travel_date.name }}</strong></td> <td data-title="Termin-Nr."><strong>{{ travel_date.name }}</strong></td>
<td data-title="Beginn">{{ travel_date.start|date }}</td> <td data-title="Beginn">{{ travel_date.start|date }}</td>
<td data-title="Ende">{{ travel_date.end|date }}</td> <td data-title="Ende">{{ travel_date.end|date }}</td>
<td data-title="Preis p.P im Doppelzimmer">ab {{ travel_date.prices[3].effectivePrice|number_format(2) }} €</td> <td data-title="Preis p.P im Doppelzimmer">ab {{ travel_date.prices[3].effectivePrice|number_format }} €</td>
<td data-title="Preis p.P im Einzelzimmer">ab {{ travel_date.prices[1].effectivePrice|number_format(2) }} €</td> <td data-title="Preis p.P im Einzelzimmer">ab {{ travel_date.prices[1].effectivePrice|number_format }} €</td>
<td data-title="Abflugorte / Zuschläge"> <td data-title="Abflugorte / Zuschläge">
<a href="#" class="color-brand" data-toggle="modal" <a href="#" class="color-brand" data-toggle="modal"

View file

@ -6,13 +6,24 @@
{#{% for i in 0..page.children|length//3 %}#} {#{% for i in 0..page.children|length//3 %}#}
<div class="row"> <div class="row">
{% for child_page in child_pages if child_page.status == 1 %} {% for child_page in child_pages if child_page.status == 1 and child_page.travelProgram is defined %}
{# @var child_page \AppBundle\Entity\Page #} {# @var child_page \AppBundle\Entity\Page #}
<div class="col-md-4 col-sm-4"> <div class="col-md-4 col-sm-4">
<div class="travel-wrapper get-box-link"> <div class="travel-wrapper get-box-link">
<div class="item text-left"> <div class="item text-left">
<div class="item-img"> <div class="item-img">
<img src="{{ child_page.previewImageUrl ?? '/bundles/app/images/page1_img'~ (random(3)+1) ~'.jpg' }}" alt="{{ child_page.title }}"> <div class="lb">
{% if child_page.travelProgram.id > 0 and child_page.travelProgram.id <= 10 %}
<div class="cstar_left">{{ child_page.travelProgram.id }}</div>
{% endif %}
<div class="cprice">ab {{ child_page.travelProgram.lowestPrice|number_format }} € p.P.</div>
<div class="cdiscount">Frühbucherrabatt</div>
</div>
{% if child_page.travelProgram.previewImage is defined %}
<img src="https://www.sterntours.de/uploads/travel_program/{{ child_page.travelProgram.previewImage.fileNameWithExtension }}"
alt="{{ child_page.title }}"
>
{% endif %}
</div> </div>
<div class="box_mid"> <div class="box_mid">
<div class="hl5">{{ child_page.title }}</div> <div class="hl5">{{ child_page.title }}</div>

View file

@ -15,83 +15,6 @@ use Symfony\Component\Stopwatch\Stopwatch;
class DefaultController extends Controller class DefaultController extends Controller
{ {
/*
Suche Kindknoten
Für jeden Kindknoten
++LFT
Setze LFT
f()
++LFT
RGT = LFT
Setze RGT
*/
/**
* @Route("/create-tree")
*/
public function createTreeAction()
{
set_time_limit(0);
ini_set('memory_limit', '2048M');
$em = $this->getEntityManager();
foreach ($em->getEventManager()->getListeners() as $event => $listeners) {
foreach ($listeners as $hash => $listener) {
if ($listener instanceof TreeListener)
{
$em->getEventManager()->removeEventListener($event, $listener);
}
}
}
$em->beginTransaction();
$lft = 0;
$this->createTree(0, $lft, 0);
$em->commit();
$em->flush();
}
private function createTree($owner, &$lft, $lvl, $root = null)
{
$em = $this->getEntityManager();
$qb = $em->createQueryBuilder()->from('AppBundle:Page', 'p')->select('p');
$qb->where($qb->expr()->eq('p.owner', $owner));
if ($owner == 0)
{
$qb->orWhere('p.owner IS NULL');
}
$qb->orderBy('p.title');
$pages = $qb->getQuery()->execute();
foreach ($pages as $page)
{
/** @var Page $page */
if ($owner == 0)
{
$root = $page->getId();
}
++$lft;
$page->setLft($lft);
$page->setLvl($lvl);
$page->setRoot($em->getReference('AppBundle:Page', $root));
if ($owner != 0)
{
$page->setParent($em->getReference('AppBundle:Page', $owner));
}
$this->createTree($page->getId(), $lft, $lvl + 1, $root);
++$lft;
$page->setRgt($lft);
$em->persist($page);
}
}
/** /**
* @return EntityManager * @return EntityManager
*/ */
@ -100,11 +23,9 @@ Für jeden Kindknoten
return $this->getDoctrine()->getManager(); return $this->getDoctrine()->getManager();
} }
/**
* @Route(path="/{req}", requirements={"req": ".+"})
*/
public function defaultAction(Request $request) public function defaultAction(Request $request)
{ {
// #TODO 404
die ("caught"); die ("caught");
} }
@ -113,8 +34,14 @@ Für jeden Kindknoten
*/ */
public function homeAction() public function homeAction()
{ {
//$departures = $this->getEntityManager()->getRepository('AppBundle:TravelDeparturePoint')->findAll();
$destinations = $this->getEntityManager()->getRepository('AppBundle:TravelCountry')->findAll();
return $this->render('default/pages/home.html.twig', [ return $this->render('default/pages/home.html.twig', [
'base_dir' => realpath($this->getParameter('kernel.root_dir').'/..').DIRECTORY_SEPARATOR, 'base_dir' => realpath($this->getParameter('kernel.root_dir').'/..').DIRECTORY_SEPARATOR,
'destinations' => $destinations,
'startDate' => new \DateTime('+5 day'),
'endDate' => new \DateTime('+19 day')
]); ]);
} }
@ -161,14 +88,25 @@ Für jeden Kindknoten
/** /**
* @Route("/suche") * @Route("/suche")
*/ */
public function searchAction() public function searchAction(Request $request)
{ {
$stopwatch = $this->get('debug.stopwatch'); $stopwatch = $this->get('debug.stopwatch');
$em = $this->getEntityManager();
$destinationsIds = [6,7];
$destination = $em->getRepository('AppBundle:TravelCountry')->find($request->query->get('c'));
if ($destination)
{
$destinationsIds = [$destination->getId()];
}
$startDate = $request->query->has('b')
? \DateTime::createFromFormat('d.m.Y', $request->query->get('b'))
: new \DateTime();
$endDate = \DateTime::createFromFormat('d.m.Y', $request->query->get('e'));
$stopwatch->start('search'); $stopwatch->start('search');
$r = $this->getDoctrine()->getRepository('AppBundle:TravelPeriod')->getTravelProgramsWithTravelDatesForTimePeriod( $r = $this->getDoctrine()->getRepository('AppBundle:TravelPeriod')->getTravelProgramsWithTravelDatesForTimePeriod(
//new \DateTime('2014-01-01'), new \DateTime('2017-01-01'), null, true); $startDate, $endDate, $destinationsIds, true);
new \DateTime(), new \DateTime('2016-12-12'), null, true);
$stopwatch->stop('search'); $stopwatch->stop('search');
return $this->render('default/pages/search.html.twig', [ return $this->render('default/pages/search.html.twig', [
@ -206,8 +144,84 @@ Für jeden Kindknoten
]); ]);
} }
/*
Suche Kindknoten
Für jeden Kindknoten
++LFT
Setze LFT
f()
++LFT
RGT = LFT
Setze RGT
*/
/**
* @Route("/create-tree")
*/
public function createTreeAction()
{
set_time_limit(0);
ini_set('memory_limit', '2048M');
$em = $this->getEntityManager();
$em->getConnection()->executeUpdate(
'UPDATE page SET lvl = NULL, lft = NULL, rgt = NULL, parent_id = NULL, tree_root = NULL');
foreach ($em->getEventManager()->getListeners() as $event => $listeners) {
foreach ($listeners as $hash => $listener) {
if ($listener instanceof TreeListener)
{
$em->getEventManager()->removeEventListener($event, $listener);
}
}
}
$em->beginTransaction();
$lft = 0;
$this->createTree(0, $lft, 0);
$em->commit();
$em->flush();
die("DONE.");
}
private function createTree($owner, &$lft, $lvl, $root = null)
{
$em = $this->getEntityManager();
$qb = $em->createQueryBuilder()->from('AppBundle:Page', 'p')->select('p');
$qb->where($qb->expr()->eq('p.owner', $owner));
if ($owner == 0)
{
$qb->orWhere('p.owner IS NULL');
}
$qb->orderBy('p.title');
$pages = $qb->getQuery()->execute();
foreach ($pages as $page)
{
/** @var Page $page */
if ($owner == 0)
{
$root = $page->getId();
}
++$lft;
$page->setLft($lft);
$page->setLvl($lvl);
$page->setRoot($em->getReference('AppBundle:Page', $root));
if ($owner != 0)
{
$page->setParent($em->getReference('AppBundle:Page', $owner));
}
$this->createTree($page->getId(), $lft, $lvl + 1, $root);
++$lft;
$page->setRgt($lft);
$em->persist($page);
}
}
} }

View file

@ -20,12 +20,15 @@ class PageRepository extends NestedTreeRepository
public function getChildrenWithTravelProgramsAndDates(Page $page) public function getChildrenWithTravelProgramsAndDates(Page $page)
{ {
$pages = $this->getChildrenQueryBuilder($page) $pages = $this->getChildrenQueryBuilder($page)
->leftJoin('node.travelProgram', 'tp') ->leftJoin('node.travelProgram', 'tp')
->addSelect('tp') ->addSelect('tp')
->andWhere('tp.status > 0') ->andWhere('tp.status > 0')
->andWhere('node.status > 0') ->andWhere('node.status > 0')
->getQuery() ->orderBy('node.order')
->execute(); ->addOrderBy('tp.position')
->addOrderBy('node.title')
->getQuery()
->execute();
/** @var Page $childPage */ /** @var Page $childPage */
foreach ($pages as &$childPage) foreach ($pages as &$childPage)
{ {

View file

@ -45,6 +45,11 @@ class TravelCountry
*/ */
private $feedbackPage; private $feedbackPage;
/**
* @ORM\ManyToMany(targetEntity="AppBundle\Entity\TravelProgram", mappedBy="countries")
*/
private $programs;
/** /**

View file

@ -230,7 +230,7 @@ final class TravelDate
$lowest = -1; $lowest = -1;
foreach ($this->getPrices() as $price) foreach ($this->getPrices() as $price)
{ {
if ($price->getPriceType() == 3) if ($price->getPriceTypeId() == 3)
{ {
// Use double room if available (#1076) // Use double room if available (#1076)
return /*$price->getEffectiveDiscountPrice() ??*/ $price->getEffectivePrice(); return /*$price->getEffectiveDiscountPrice() ??*/ $price->getEffectivePrice();

View file

@ -40,7 +40,10 @@ class TravelPeriodRepository extends \Doctrine\ORM\EntityRepository
$startDate = $now; $startDate = $now;
} }
$startDateStr = $startDate->format('Y-m-d'); $startDateStr = $startDate->format('Y-m-d');
$endDateStr = $endDate->format('Y-m-d'); if ($endDate)
{
$endDateStr = $endDate->format('Y-m-d');
}
$qb = $this->getEntityManager()->createQueryBuilder() $qb = $this->getEntityManager()->createQueryBuilder()
->from('AppBundle:TravelProgram', 'tp', 'tp.id') ->from('AppBundle:TravelProgram', 'tp', 'tp.id')
@ -64,7 +67,7 @@ class TravelPeriodRepository extends \Doctrine\ORM\EntityRepository
{ {
$priceTypeKey = 'price_'. $priceType->getId(); $priceTypeKey = 'price_'. $priceType->getId();
$qb->leftJoin('p.prices', $priceTypeKey, Expr\Join::WITH, $qb->leftJoin('p.prices', $priceTypeKey, Expr\Join::WITH,
$priceTypeKey .'.priceType = '. $priceType->getId(), null, $priceTypeKey .'.priceType'); $priceTypeKey .'.priceType = '. $priceType->getId(), $priceTypeKey .'.priceTypeId');
$qb->addSelect($priceTypeKey); $qb->addSelect($priceTypeKey);
} }
$qb->leftJoin('p.discounts', 'discount'); $qb->leftJoin('p.discounts', 'discount');
@ -77,11 +80,14 @@ class TravelPeriodRepository extends \Doctrine\ORM\EntityRepository
// Destinations // Destinations
if (!empty($destinationIds) && is_array($destinationIds)) if (!empty($destinationIds) && is_array($destinationIds))
{ {
$qb->innerJoin('AppBundle:TravelProgramCountry', 'tpc', Expr\Join::WITH, //$qb->innerJoin('AppBundle:TravelProgramCountry', 'tpc', Expr\Join::WITH,
'tpc.program = tp AND IDENTITY(tpc.country) IN ('. implode(', ', $destinationIds) .')'); // 'tpc.program = tp AND IDENTITY(tpc.country) IN ('. implode(', ', $destinationIds) .')');
$qb->innerJoin('tp.countries', 'tc', Expr\Join::WITH,
'tc.id IN ('. implode(', ', $destinationIds) .')');
if ($combi) if ($combi)
{ {
$qb->having('COUNT(DISTINCT tpc.country) = '. count($destinationIds)); //$qb->having('COUNT(DISTINCT tpc.country) = '. count($destinationIds));
$qb->having('COUNT(DISTINCT tc) = '. count($destinationIds));
} }
} }
$qb->groupBy('p.id, p_dep.id, d.id'); $qb->groupBy('p.id, p_dep.id, d.id');

View file

@ -309,7 +309,7 @@ class TravelProgram
private $departures; private $departures;
/** /**
* @ORM\ManyToMany(targetEntity="AppBundle\Entity\TravelCountry") * @ORM\ManyToMany(targetEntity="AppBundle\Entity\TravelCountry", inversedBy="programs")
* @ORM\JoinTable(name="travel_program_country", * @ORM\JoinTable(name="travel_program_country",
* joinColumns={@ORM\JoinColumn(name="program_id", referencedColumnName="id")}, * joinColumns={@ORM\JoinColumn(name="program_id", referencedColumnName="id")},
* inverseJoinColumns={@ORM\JoinColumn(name="country_id", referencedColumnName="id")} * inverseJoinColumns={@ORM\JoinColumn(name="country_id", referencedColumnName="id")}
@ -1501,4 +1501,16 @@ class TravelProgram
{ {
return $this->options; return $this->options;
} }
public function getPreviewImage()
{
foreach ($this->getImages() as $image)
{
if ($image->getType() == 2)
{
return $image;
}
}
return $this->getImages()[0];
}
} }

View file

@ -756,6 +756,55 @@ a,
.travel-wrapper .item > a.item-button.dobble_line { .travel-wrapper .item > a.item-button.dobble_line {
height: 3.6em; height: 3.6em;
} }
.travel-wrapper .lb {
position: relative;
}
.travel-wrapper .lb .cstar_right {
position: absolute;
z-index: 10;
background: url(../images/star.png) no-repeat scroll center center / cover rgba(0, 0, 0, 0);
width: 60px;
height: 60px;
padding-top: 20px;
font-weight: bold;
text-align: center;
right: 4px;
top: 6px;
color: #1a457c;
}
.travel-wrapper .lb .cstar_left {
position: absolute;
z-index: 10;
background: url(../images/star.png) no-repeat scroll center center / cover rgba(0, 0, 0, 0);
width: 60px;
height: 60px;
padding-top: 20px;
font-weight: bold;
text-align: center;
left: 4px;
top: 6px;
color: #1a457c;
}
.travel-wrapper .lb .cprice {
position: absolute;
z-index: 10;
left: 0;
top: 140px;
background-color: #648859;
color: #fff;
padding: 4px 6px 4px 12px;
font-weight: bold;
}
.travel-wrapper .lb .cdiscount {
position: absolute;
z-index: 10;
right: 0;
top: 23px;
background-color: #ffc926;
color: #1a457c;
padding: 4px 12px 4px 6px;
font-weight: bold;
}
.travel-wrapper .item .hl5 { .travel-wrapper .item .hl5 {
text-overflow: ellipsis; text-overflow: ellipsis;
word-wrap: break-word; word-wrap: break-word;

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.3 KiB