Spezialist für Kulturreisen
diff --git a/trunk/app/Resources/views/default/components/pageBoxImage.html.twig b/trunk/app/Resources/views/default/components/pageBoxImage.html.twig
index a732e708..5ff6ab0c 100644
--- a/trunk/app/Resources/views/default/components/pageBoxImage.html.twig
+++ b/trunk/app/Resources/views/default/components/pageBoxImage.html.twig
@@ -8,4 +8,4 @@
{% set image_url = '/bundles/app/images/no-picture.png' %}
{% set image_alt = 'Kein Vorschaubild vorhanden' %}
{% endif %}
-
\ No newline at end of file
+
\ No newline at end of file
diff --git a/trunk/app/Resources/views/default/components/sidebar.html.twig b/trunk/app/Resources/views/default/components/sidebar.html.twig
index 09f3c70d..e8b3b3f5 100644
--- a/trunk/app/Resources/views/default/components/sidebar.html.twig
+++ b/trunk/app/Resources/views/default/components/sidebar.html.twig
@@ -32,13 +32,13 @@
TOP bewertet
diff --git a/trunk/app/Resources/views/default/pages/cms/travelProgram.html.twig b/trunk/app/Resources/views/default/pages/cms/travelProgram.html.twig
index a6672ce1..db0030f8 100644
--- a/trunk/app/Resources/views/default/pages/cms/travelProgram.html.twig
+++ b/trunk/app/Resources/views/default/pages/cms/travelProgram.html.twig
@@ -19,10 +19,11 @@
********* SLIDER *********
#}
-
-
-
ab {{ travel_program.lowestPrice|number_format }} € p.P.
-
+ {% if travel_program.lowestPrice > 0 %}
+
+
ab {{ travel_program.lowestPrice|number_format }} € p.P.
+
+ {% endif %}
+ {{ travel_program.title }}
+ {{ base_url }}{{ travel_program.page.urlPath }}
+
+ {% for country in travel_program.countries %}
+ {% if country.destinations is empty %}
+
+ {{ country.name }}
+
+ {% else %}
+ {% for destination in country.destinations %}
+
+ {{ country.name }}
+ {{ destination.name }}
+ {# Actually instead of , but combination of city + country is not allowed #}
+
+ {% endfor %}
+ {% endif %}
+ {% endfor %}
+
+
+ Rundreisen
+ Kulturreisen
+ Tagesprogramm
+ {% if travel_program.programCode in ['AEGYST001', 'AEGYST002', 'AEGYST003', 'AEGYST004', 'AEGYST005',
+ 'AEGYST006', 'AEGYST008']
+ %}
+ Kreuzfahrten
+ {% endif %}
+
+ Hotel
+ Flugzeug
+ {{ travel_program.programDuration }}
+ {{ travel_program.lowestPrice }}
+ {{ subtitle }}
+ {{ 5 in travel_program.countries.keys ? 2 : 1 }}
+ {{ 6 in travel_program.countries.keys ? 26 : 12 }}
+
+ {% filter escape('html') %}
+ {{ html_description|raw }}
+ {% if included is not empty %}
+ Leistungen inklusive
+
+ {% for travel_program_service in included|split('\n') %}
+ {{ travel_program_service|raw }}
+ {% endfor %}
+
+ {% endif %}
+ {% if travel_program.excluded is not empty %}
+ Nicht eingeschlossene / zubuchbare Leistungen
+
+ {% for option in travel_program.options %}
+
+ {{ option.name }}
+ {{ option.description|raw }}
+
+ {% endfor %}
+
+ {% endif %}
+ {% if advices is not empty %}
+ Hinweise
+
+ {% for travel_program_advice in advices|trim|split('\n') %}
+ {{ travel_program_advice|raw }}
+ {% endfor %}
+
+ {% endif %}
+ {% endfilter %}
+
+
+ {% for image in travel_program.images %}
+ {{ base_url }}/uploads/travel_program/{{ image.fileNameWithExtension }}
+ {% endfor %}
+
+
+ {% for travel_date in travel_program.travelDates if 3 in travel_date.prices|keys %}
+
+ {{ travel_date.start|date('Y-m-d') }}
+ {{ travel_date.end|date('Y-m-d') }}
+ {{ travel_date.status }}
+ {% for price in travel_date.prices %}
+ {% if price.priceTypeId == 1 %}
+ {{ price.effectiveDiscountPrice ?? price.effectivePrice }}
+ {% elseif price.priceTypeId == 3 %}
+ {{ price.effectiveDiscountPrice ?? price.effectivePrice }}
+ {% endif %}
+ {% endfor %}
+
+ {% for departure in travel_date.departures %}
+
+
+ {{ departure.name|lower == 'eigenanreise' ? 'Eigenanreise' : ('Kosten Abflug ' ~ departure.name) }}
+
+ {{ departure.extraCharge }}
+ departure
+ departure
+
+ {% endfor %}
+
+
+ {% endfor %}
+
+
+ {% for travel_program_service in travel_program.included|split('\n') %}
+ {{ travel_program_service }}
+ {% endfor %}
+
+
+ {% for option in travel_program.options %}
+
+ {{ option.name }}
+ {{ option.description }}
+ {{ option.price }}
+ {{ option.priceChildren }}
+
+ {% endfor %}
+
+
\ No newline at end of file
diff --git a/trunk/app/config/parameters.yml.dist b/trunk/app/config/parameters.yml.dist
index 71cc63d5..6b3c6035 100644
--- a/trunk/app/config/parameters.yml.dist
+++ b/trunk/app/config/parameters.yml.dist
@@ -20,3 +20,9 @@ parameters:
st_cache_driver: array
locale: de_DE
+ base_url: https://www.sterntours.de
+
+ # Tripodo export
+ tripodo_host: ~
+ tripodo_user: ~
+ tripodo_pass: ~
diff --git a/trunk/composer.lock b/trunk/composer.lock
index 061b2776..dc814362 100644
--- a/trunk/composer.lock
+++ b/trunk/composer.lock
@@ -4,8 +4,8 @@
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#composer-lock-the-lock-file",
"This file is @generated automatically"
],
- "hash": "2fbdc6452eb1c28efea2c75275631b11",
- "content-hash": "8b127c12f0c4410e2d460ec2047f9b28",
+ "hash": "cafcb1290bf2f23646f9d7c96c217f14",
+ "content-hash": "602fab2a074b1ea2fe86866aa42ba50f",
"packages": [
{
"name": "behat/transliterator",
@@ -1447,6 +1447,30 @@
],
"time": "2016-11-07 23:38:38"
},
+ {
+ "name": "pguardiario/phpuri",
+ "version": "1.0",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/monkeysuffrage/phpuri.git",
+ "reference": "ad0a5ec033fe616cfef55578b9c7f2458be8fbfc"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/monkeysuffrage/phpuri/zipball/ad0a5ec033fe616cfef55578b9c7f2458be8fbfc",
+ "reference": "ad0a5ec033fe616cfef55578b9c7f2458be8fbfc",
+ "shasum": ""
+ },
+ "type": "project",
+ "autoload": {
+ "files": [
+ "phpuri.php"
+ ]
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "description": "A php library for converting relative urls to absolute.",
+ "time": "2015-05-24 09:13:17"
+ },
{
"name": "psr/cache",
"version": "1.0.1",
diff --git a/trunk/src/AppBundle/Command/TripodoExportCommand.php b/trunk/src/AppBundle/Command/TripodoExportCommand.php
new file mode 100644
index 00000000..ad42e318
--- /dev/null
+++ b/trunk/src/AppBundle/Command/TripodoExportCommand.php
@@ -0,0 +1,78 @@
+
+ * @date 03/10/2017
+ */
+
+namespace AppBundle\Command;
+
+
+use AppBundle\Util;
+use Doctrine\ORM\EntityManager;
+use Symfony\Bundle\FrameworkBundle\Command\ContainerAwareCommand;
+use Symfony\Component\Console\Input\InputInterface;
+use Symfony\Component\Console\Output\OutputInterface;
+
+class TripodoExportCommand extends ContainerAwareCommand
+{
+ protected function configure()
+ {
+ $this->setName('sterntours:export-tripodo');
+ }
+
+ protected function execute(InputInterface $input, OutputInterface $output)
+ {
+ /** @var EntityManager $em */
+ $em = $this->getContainer()->get('doctrine')->getManager();
+ $regex = '/(\(\s*)?(((https?:\/\/)?www\.stern-?tours\.de[^\s\)]*)|([^\s]+@stern-?tours\.de)|(030\s*(-\s*)?700\s*94\s*100))(\s*\))?/';
+ $baseUrl = 'https://www.sterntours.de';
+ $xml = '' ."\n\n";
+
+ $travelPrograms = $em->getRepository('AppBundle:TravelProgram')->getProgramsToExport();
+ foreach ($travelPrograms as $travelProgram)
+ {
+ $em->getRepository('AppBundle:TravelPeriod')->getTrueTravelPeriods($travelProgram);
+ $vars = [
+ 'travel_program' => $travelProgram,
+ 'base_url' => $this->getContainer()->getParameter('base_url'),
+ ];
+
+ // Link / E-Mail / Tel. zu Stern Tours entfernen
+ $vars['html_description'] = preg_replace($regex, '', $travelProgram->getHtmlDescription());
+ $vars['included'] = preg_replace($regex, '', $travelProgram->getIncluded());
+ $vars['advices'] = preg_replace($regex, '', $travelProgram->getAdvices());
+
+ $vars['included'] = Util::convertUrisInHtmlToAbsolute($vars['included'], $baseUrl);
+ $vars['advices'] = Util::convertUrisInHtmlToAbsolute($vars['advices'], $baseUrl);
+ $vars['subtitle'] = Util::convertUrisInHtmlToAbsolute($travelProgram->getSubtitle(), $baseUrl);
+
+ // Video-Link entfernen
+ $vars['html_description'] = preg_replace('/\s*\s*<\/p>/', '', $vars['html_description']);
+
+ // Überschriften hervorheben
+ $vars['html_description'] = preg_replace('/(.*?)<\/h2>/', ' \1
', $vars['html_description']);
+ $vars['html_description'] = preg_replace('/(.*?)<\/h3>/', ' \1
', $vars['html_description']);
+
+ $vars['html_description'] = Util::convertUrisInHtmlToAbsolute(
+ html_entity_decode($vars['html_description'], ENT_COMPAT, 'UTF-8'), $baseUrl);
+
+
+ $xml .= $this->getContainer()->get('templating')->render('default/tripodo.xml.twig', $vars);
+ }
+ $xml .= '
';
+
+ file_put_contents('travels.xml', $xml);
+ return;
+ $conn = ftp_connect($this->getContainer()->getParameter('tripodo_host'));
+ if(ftp_login($conn, $this->getContainer()->getParameter('tripodo_user'),
+ $this->getContainer()->getParameter('tripodo_pass')))
+ {
+ $stream = fopen('travels.xml', 'r');
+ ftp_fput($conn, 'travels.xml', $stream, FTP_BINARY);
+ fclose($stream);
+ }
+ ftp_close($conn);
+ }
+
+
+}
\ No newline at end of file
diff --git a/trunk/src/AppBundle/Entity/TravelCountry.php b/trunk/src/AppBundle/Entity/TravelCountry.php
index e1e6ac21..c47451a0 100644
--- a/trunk/src/AppBundle/Entity/TravelCountry.php
+++ b/trunk/src/AppBundle/Entity/TravelCountry.php
@@ -50,6 +50,11 @@ class TravelCountry
*/
private $programs;
+ /**
+ * @ORM\OneToMany(targetEntity="AppBundle\Entity\TravelDestination", mappedBy="country")
+ */
+ private $destinations;
+
/**
@@ -181,4 +186,38 @@ class TravelCountry
}
+
+ /**
+ * Add destination
+ *
+ * @param \AppBundle\Entity\TravelDestination $destination
+ *
+ * @return TravelCountry
+ */
+ public function addDestination(\AppBundle\Entity\TravelDestination $destination)
+ {
+ $this->destinations[] = $destination;
+
+ return $this;
+ }
+
+ /**
+ * Remove destination
+ *
+ * @param \AppBundle\Entity\TravelDestination $destination
+ */
+ public function removeDestination(\AppBundle\Entity\TravelDestination $destination)
+ {
+ $this->destinations->removeElement($destination);
+ }
+
+ /**
+ * Get destinations
+ *
+ * @return \Doctrine\Common\Collections\Collection
+ */
+ public function getDestinations()
+ {
+ return $this->destinations;
+ }
}
diff --git a/trunk/src/AppBundle/Entity/TravelDate.php b/trunk/src/AppBundle/Entity/TravelDate.php
index 21ead819..38cc0010 100644
--- a/trunk/src/AppBundle/Entity/TravelDate.php
+++ b/trunk/src/AppBundle/Entity/TravelDate.php
@@ -6,6 +6,7 @@
namespace AppBundle\Entity;
use AppBundle\Util\DepartureUtil;
+use Doctrine\Common\Collections\ArrayCollection;
/**
* TravelDate is a wrapper for TravelPeriod + start date and end date. This entity doesn't represent a database
@@ -89,10 +90,16 @@ final class TravelDate
}
$this->start = $start;
$this->index = $index;
+ $this->prices = [];
+ foreach ($travelPeriod->getPrices() as $price)
+ {
+ $this->prices[$price->getPriceTypeId()] = clone $price;
+ }
}
else
{
$this->start = $travelPeriod->getStartDate();
+ $this->prices = $travelPeriod->getPrices();
}
$this->flightPeriod = $flightPeriod;
$this->travelProgram = $travelPeriod->getProgram();
@@ -223,14 +230,14 @@ final class TravelDate
$profitMargin = $this->travelProgram->getProfitMargin() / 100 + 1;
}
$currencyFactor = $this->travelProgram->getNettoPricesInEuro() ? 1 : $this->currencyFactor;
- foreach ($this->travelPeriod->getPrices() as $price)
+ foreach ($this->prices as &$price)
{
$price->setEffectivePrice(round(($flightPrice + $price->getPrice() * $currencyFactor) * $profitMargin));
$price->setEffectiveComfortPrice(round($price->getPriceComfort() * $currencyFactor * $profitMargin));
$price->setEffectiveChildPrice(round($price->getPriceChildren() * $currencyFactor * $profitMargin));
}
}
- return $this->travelPeriod->getPrices();
+ return $this->prices;
}
public function getLowestPrice()
diff --git a/trunk/src/AppBundle/Entity/TravelDestination.php b/trunk/src/AppBundle/Entity/TravelDestination.php
index 9a737ad4..6c9e86d6 100644
--- a/trunk/src/AppBundle/Entity/TravelDestination.php
+++ b/trunk/src/AppBundle/Entity/TravelDestination.php
@@ -31,7 +31,7 @@ class TravelDestination
/**
* @var \AppBundle\Entity\TravelCountry
*
- * @ORM\ManyToOne(targetEntity="AppBundle\Entity\TravelCountry")
+ * @ORM\ManyToOne(targetEntity="AppBundle\Entity\TravelCountry", inversedBy="destinations")
* @ORM\JoinColumns({
* @ORM\JoinColumn(name="country_id", referencedColumnName="id")
* })
@@ -39,7 +39,6 @@ class TravelDestination
private $country;
-
/**
* Set name
*
diff --git a/trunk/src/AppBundle/Entity/TravelProgram.php b/trunk/src/AppBundle/Entity/TravelProgram.php
index 523da2e8..67dd3301 100644
--- a/trunk/src/AppBundle/Entity/TravelProgram.php
+++ b/trunk/src/AppBundle/Entity/TravelProgram.php
@@ -317,6 +317,15 @@ class TravelProgram
*/
private $countries;
+ /**
+ * @ORM\ManyToMany(targetEntity="AppBundle\Entity\TravelDestination")
+ * @ORM\JoinTable(name="travel_program_destination",
+ * joinColumns={@ORM\JoinColumn(name="program_id", referencedColumnName="id")},
+ * inverseJoinColumns={@ORM\JoinColumn(name="destination_id", referencedColumnName="id")}
+ * )
+ */
+ private $destinations;
+
/**
* @ORM\OneToMany(targetEntity="AppBundle\Entity\TravelProgramImage", mappedBy="program")
*/
@@ -1509,7 +1518,7 @@ class TravelProgram
/**
* Get options
*
- * @return \Doctrine\Common\Collections\Collection
+ * @return TravelOption[]|\Doctrine\Common\Collections\Collection
*/
public function getOptions()
{
@@ -1556,4 +1565,38 @@ class TravelProgram
{
return ($this->showMap ?? 0) > 0 && ($this->mapHtml or $this->mapHtml);
}
+
+ /**
+ * Add destination
+ *
+ * @param \AppBundle\Entity\TravelDestination $destination
+ *
+ * @return TravelProgram
+ */
+ public function addDestination(\AppBundle\Entity\TravelDestination $destination)
+ {
+ $this->destinations[] = $destination;
+
+ return $this;
+ }
+
+ /**
+ * Remove destination
+ *
+ * @param \AppBundle\Entity\TravelDestination $destination
+ */
+ public function removeDestination(\AppBundle\Entity\TravelDestination $destination)
+ {
+ $this->destinations->removeElement($destination);
+ }
+
+ /**
+ * Get destinations
+ *
+ * @return \Doctrine\Common\Collections\Collection
+ */
+ public function getDestinations()
+ {
+ return $this->destinations;
+ }
}
diff --git a/trunk/src/AppBundle/Entity/TravelProgramRepository.php b/trunk/src/AppBundle/Entity/TravelProgramRepository.php
index 04e9b2bc..fb1159c5 100644
--- a/trunk/src/AppBundle/Entity/TravelProgramRepository.php
+++ b/trunk/src/AppBundle/Entity/TravelProgramRepository.php
@@ -2,6 +2,8 @@
namespace AppBundle\Entity;
+use Doctrine\ORM\Query\Expr;
+
/**
* TravelProgramRepository
*
@@ -10,4 +12,26 @@ namespace AppBundle\Entity;
*/
class TravelProgramRepository extends \Doctrine\ORM\EntityRepository
{
+ /**
+ * @return TravelProgram[]
+ */
+ public function getProgramsToExport()
+ {
+ return $this->createQueryBuilder('tp')
+ ->innerJoin('tp.page', 'page')
+ ->addSelect('page')
+ ->leftJoin('tp.countries', 'country')
+ ->addSelect('country')
+ ->leftJoin('country.destinations', 'destination')
+ ->addSelect('destination')
+ ->leftJoin('tp.options', 'option')
+ ->addSelect('option')
+ ->leftJoin('tp.images', 'image', Expr\Join::WITH, 'image.type = 1')
+ ->addSelect('image')
+ ->where('tp.status = 1')
+ ->andWhere('tp.programType = '. TravelProgram::ORGANIZED_PROGRAM_TYPE)
+ ->getQuery()
+ ->execute()
+ ;
+ }
}
diff --git a/trunk/src/AppBundle/Listener/KernelControllerListener.php b/trunk/src/AppBundle/Listener/KernelControllerListener.php
index 05a14916..93d094b3 100644
--- a/trunk/src/AppBundle/Listener/KernelControllerListener.php
+++ b/trunk/src/AppBundle/Listener/KernelControllerListener.php
@@ -117,6 +117,11 @@ class KernelControllerListener
if ($node)
{
+ if ($node->getStatus() == 0)
+ {
+ throw new NotFoundHttpException('Inactive page');
+ }
+
$request->attributes->set('page', $node);
if ($restOfPath && $node->getTravelProgram() != null && (
@@ -129,6 +134,10 @@ class KernelControllerListener
}
elseif ($node->getTravelProgram() != null)
{
+ if ($node->getTravelProgram()->getStatus() == 0)
+ {
+ throw new NotFoundHttpException('Inactive travel program');
+ }
$request->attributes->set('_controller', 'AppBundle:Cms:travelProgram');
}
else
diff --git a/trunk/src/AppBundle/Util.php b/trunk/src/AppBundle/Util.php
index 95dc3ede..893d6d03 100644
--- a/trunk/src/AppBundle/Util.php
+++ b/trunk/src/AppBundle/Util.php
@@ -40,6 +40,19 @@ class Util
return 'http' . (($_SERVER['SERVER_PORT'] == 443) ? 's://' : '://') .$_SERVER['HTTP_HOST'];
}
+ public static function convertUrisInHtmlToAbsolute($html, $baseUrl = null)
+ {
+ if ($baseUrl === null)
+ {
+ $baseUrl = self::getBaseUrl();
+ }
+ $phpUri = \phpUri::parse($baseUrl);
+
+ return preg_replace_callback('/(href|src)="((\\\\.|[^"\\\\])*)"/', function($matches) use ($phpUri) {
+ return $matches[1] .'="'. $phpUri->join($matches[2]) .'"';
+ }, $html);
+ }
+
public static function formatPrice($value)
{
return number_format($value, 2, ',', '.') .' €';