<?php
declare(strict_types=1);
/*
* Contao KrPano bundle for Contao Open Source CMS
*
* Copyright (c) 2022 pdir / digital agentur // pdir GmbH
*
* @package krpano-bundle
* @link https://pdir.de/krpano-bundle/
* @license LGPL-3.0-or-later
* @author Mathias Arzberger <develop@pdir.de>
* @author Christian Mette <develop@pdir.de>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Pdir\KrPanoBundle\Controller\ContentElement;
use Contao\BackendTemplate;
use Contao\ContentModel;
use Contao\CoreBundle\Controller\ContentElement\AbstractContentElementController;
use Contao\CoreBundle\DependencyInjection\Attribute\AsContentElement;
use Contao\FilesModel;
use Contao\PageModel;
use Contao\StringUtil;
use Contao\System;
use Contao\Template;
use Pdir\KrPanoBundle\Model\ConfigModel;
use Pdir\KrPanoBundle\Model\PanoramaModel;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
#[AsContentElement(category:'pdir', template:'ce_krpanorama')]
class KrPanoramaController extends AbstractContentElementController
{
// set the template name
public $strTemplate = 'ce_krpanorama';
public null|PageModel $page;
public null|Template $template;
public null|ContentModel $model;
// set the assets dir
protected $assetsDir = 'bundles/pdirkrpano';
// sets the source directory for the html5 viewer
protected $viewerDir = 'bundles/pdirkrpano/krpano/viewer';
// sets the source directory for all plugins
protected $pluginsDir = '/bundles/pdirkrpano/krpano/viewer/plugins';
// sets the source directory for the default skin
protected $skinDir = '/bundles/pdirkrpano/krpano/skins/myskin';
// sets the pano source.xml for an empty panorama
protected $emptyPano = '/bundles/pdirkrpano/krpano/skins/myskin/empty_pano.xml';
protected $objPanoPanorama;
protected $objConfig;
/**
* Retrieve the panorama and config model.
*/
public function retrievePanoramaAndConfig(): void
{
// get the panorama data record
/** @var PanoramaModel $this->objPanoPanorama */
$this->objPanoPanorama = PanoramaModel::findByPk($this->model->pdir_pano_panorama_id);
// get the panorama configuration
$this->objConfig = ConfigModel::findByPk($this->model->pdir_pano_config_id);
// check whether the viewer directory has been overwritten
if (isset($this->objConfig->override_krpanojs)) {
// user has own krpano viewer activated - krpanojsSRC is mandatory
if ($this->objConfig->krpanojsSRC) {
// get the path
$this->viewerDir = FilesModel::findByUuid($this->objConfig->krpanojsSRC)->path;
}
}
}
/**
* Render a wildcard in backend view.
*/
public function renderBackendView($id, $debug): void
{
$this->template = new BackendTemplate('be_wildcard');
$this->template->wildcard = sprintf(
'### %s - Panorama-Id: %s (%s) ###%s',
$this->objPanoPanorama->name ?? 'NO PANORAMA SET',
$id ?? '-',
$this->objConfig->title ?? 'NO CONFIG SET',
$debug ? ' <span style="color:red;"> (DEBUG-MODE)</span> ###' : ''
);
}
public function renderPanoramaView(): void
{
// set the customTpl template
if ($this->model->customTpl) {
$this->template->strTemplate = $this->model->customTpl;
}
// prevent accumulation of CSS ToDo: move this stuff into config?
$feCSS = $this->assetsDir.'/css/fe_krpano.scss|static';
if (!isset($GLOBALS['TL_CSS']['fe_krpano'])) {
$GLOBALS['TL_CSS']['fe_krpano'] = $feCSS;
}
// prevent accumulation of javascript
$krpanojs = $this->viewerDir.'/krpano.js';
$fekrpanojs = $this->assetsDir.'/js/fe_krpano.js';
if (!isset($GLOBALS['TL_JAVASCRIPT']['krpano'])) {
$GLOBALS['TL_JAVASCRIPT']['krpano'] = $krpanojs;
}
if (!isset($GLOBALS['TL_JAVASCRIPT']['fe_krpano'])) {
$GLOBALS['TL_JAVASCRIPT']['fe_krpano'] = $fekrpanojs;
}
$this->template->errorTitle = $GLOBALS['TL_LANG']['tl_pano_panorama']['errorTitle'];
$this->template->errorText = $GLOBALS['TL_LANG']['tl_pano_panorama']['errorText'];
$this->template->viewerDir = $this->viewerDir;
$this->template->pluginsDir = $this->pluginsDir;
$this->template->skinDir = $this->skinDir;
$this->template->contentId = $this->model->id;
// use the panorama_id for xml requests
$this->template->panoramaId = $this->model->pdir_pano_panorama_id;
$this->template->configId = $this->model->pdir_pano_config_id;
// arstempano fix @todo remove if not needed!
$hlookat = $this->model->pdir_pano_hlookat;
if ($hlookat > 180) {
$hlookat -= 360;
}
if ($hlookat < -180) {
$hlookat += 360;
}
$vlookat = $this->model->pdir_pano_vlookat;
if ($vlookat > 180) {
$vlookat -= 360;
}
if ($vlookat < -180) {
$vlookat += 360;
}
// check overriding view parameter
if ('1' === $this->model->pdir_pano_override_view) {
// use tl_content view parameters
$this->template->hlookat = $hlookat;
$this->template->vlookat = $vlookat;
$this->template->fov = $this->model->pdir_pano_fov;
} else {
// use tl_pano_panorama view parameters
$this->template->hlookat = $this->objPanoPanorama->start_poh;
$this->template->vlookat = $this->objPanoPanorama->start_pov;
$this->template->fov = $this->objPanoPanorama->start_zoom;
}
// calculate xml uri
$this->template->panoUri = FilesModel::findByUuid($this->objPanoPanorama->pano_xml)->path;
if ($this->template->panoUri) {
$this->template->panoUri = "krpano/config/{$this->template->configId}/panorama/{$this->template->panoramaId}";
} else {
$this->template->panoUri = $this->emptyPano;
$this->template->hlookat = 0.0;
$this->template->vlookat = 0.0;
$this->template->fov = 150.0;
}
// set browser session history
$this->template->jumpTo = false;
if ($this->model->pdir_pano_history) {
$this->template->urlSuffix = System::getContainer()->getParameter('contao.url_suffix');
// use current page
$this->template->jumpTo = $this->page->alias;
// use redirect page
if ($this->model->pdir_pano_history_jump_to) {
$this->template->jumpTo = PageModel::findById($this->pdir_pano_history_jump_to)->alias;
}
}
$cssID = StringUtil::deserialize($this->model->cssID, true);
$this->template->cssID = !empty($cssID[0]) ? " {$cssID[0]}" : '';
$this->template->cssClass = !empty($cssID[1]) ? " {$cssID[1]}" : '';
$this->template->tlMode = TL_MODE;
// prepare debug data
$this->template->debug = (bool) $this->model->pdir_pano_debug;
$this->template->debugHtml = sprintf(
'<div id="debug_%s" class="overlay debug"></div>',
$this->model->id
);
$this->template->invisible = $this->model->invisible;
}
protected function getResponse(Template $template, ContentModel $model, Request $request): ?Response
{
$request = System::getContainer()->get('request_stack')->getCurrentRequest();
$this->template = $template;
$this->model = $model;
$this->page = $this->getPageModel();
System::loadLanguageFile('tl_pano_panorama');
$this->retrievePanoramaAndConfig();
// Display a wildcard in the back end.
if ($request && System::getContainer()->get('contao.routing.scope_matcher')->isBackendRequest($request)) {
$this->renderBackendView($model->id, $model->pdir_pano_debug);
}
if ($request && System::getContainer()->get('contao.routing.scope_matcher')->isFrontendRequest($request) && ($model->invisible || null === $this->objPanoPanorama || '1' !== $this->objPanoPanorama->published)) {
return new Response('');
}
if ($request && System::getContainer()->get('contao.routing.scope_matcher')->isFrontendRequest($request)) {
$this->renderPanoramaView();
}
return $this->template->getResponse();
}
}