<?php
declare(strict_types=1);
namespace vonRotenberg\RealEstateListingBundle\Controller\FrontendModule;
use vonRotenberg\RealEstateListingBundle\Model\ManagedPropertyModel;
use Contao\ArrayUtil;
use Contao\CoreBundle\Controller\FrontendModule\AbstractFrontendModuleController;
use Contao\CoreBundle\DependencyInjection\Attribute\AsFrontendModule;
use Contao\CoreBundle\Exception\ResponseException;
use Contao\CoreBundle\Image\Studio\Figure;
use Contao\CoreBundle\Image\Studio\FigureBuilder;
use Contao\CoreBundle\Twig\FragmentTemplate;
use Contao\File;
use Contao\FilesModel;
use Contao\Input;
use Contao\ModuleModel;
use Contao\PageModel;
use Contao\StringUtil;
use Contao\System;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
#[AsFrontendModule(category: 'vr_real_estate')]
class ManagedPropertyController extends AbstractFrontendModuleController
{
public const TYPE = 'managed_property';
protected function getResponse(FragmentTemplate $template, ModuleModel $model, Request $request): Response
{
$arrAssets = [];
$arrFilterOptions = [
'city' => []
];
$arrFilterSelected = [];
$arrAssetsOptions = [];
$jumpTo = PageModel::findByPk($model->jumpTo);
$urlGenerator = System::getContainer()->get('contao.routing.content_url_generator');
// Filter
if (isset($_GET['filter']) && \is_array(Input::get('filter')))
{
foreach (Input::get('filter') as $filter=>$value)
{
if (in_array($filter, array_keys($arrFilterOptions)) && !empty($value))
{
$rawValue = StringUtil::decodeEntities($value);
$arrFilterSelected[$filter] = $rawValue;
if (preg_match('/^.*<>.*$/',$rawValue))
{
list($start,$stop) = preg_split('/<>/',$rawValue, 2);
$arrAssetsOptions['column'][$filter] = "$filter BETWEEN $start AND $stop";
} else {
$arrAssetsOptions['column'][$filter] = "$filter = ?";
$arrAssetsOptions['value'][$filter] = $rawValue;
}
}
}
}
if (($assets = ManagedPropertyModel::findAllPublished(0,0,$arrAssetsOptions)) === null)
{
return $template->getResponse();
}
// Figure Builder
$figureBuilder = System::getContainer()
->get('contao.image.studio')
->createFigureBuilder()
->setSize($model->imgSize)
->setLightboxGroupIdentifier('lb' . $model->id);
foreach ($assets as $asset)
{
$arrItem = array_merge($asset->row(), [
'teaserFigure' => $this->getImageFigures($asset->gallerySRC, $figureBuilder, $asset->orderSRC, 1),
'detailsUrl' => $jumpTo !== null ? $urlGenerator->generate($jumpTo, ['parameters'=>'/items/'.$asset->id]) : null
]);
$arrAssets[] = $arrItem;
}
// Populate filters
$filterAssets = ManagedPropertyModel::findAllPublished();
foreach ($filterAssets as $asset)
{
// Filter options
if (!empty($asset->city))
{
$tmpOptions = $arrAssetsOptions;
$tmpOptions['column'] = array_merge((isset($arrAssetsOptions['column']) ? $arrAssetsOptions['column'] : []),['city'=>'city = ?']);
$tmpOptions['value'] = array_merge((isset($arrAssetsOptions['value']) ? $arrAssetsOptions['value'] : []),['city'=>$asset->city]);
$count = ManagedPropertyModel::countAllPublished($tmpOptions);
$arrFilterOptions['city'][$asset->city] = $asset->city . ' ('.$count.')';
}
}
foreach (array_keys($arrFilterOptions) as $filterName)
{
$arrFilterOptions[$filterName] = array_unique($arrFilterOptions[$filterName]);
}
// Set template data
$template->set('filterOptions',$arrFilterOptions);
$template->set('filter',$arrFilterSelected);
$template->set('assets',$arrAssets);
// Handle ajax
if ($request->headers->get('VR-Ajax') == 'RePropertiesList')
{
throw new ResponseException($template->getResponse());
}
return $template->getResponse();
}
/**
* @param string|array $strUuids
* @param FigureBuilder $figureBuilder
* @param string|array $strOrder
*
* @return array|Figure
* @throws \Exception
*/
public function getImageFigures($strUuids, $figureBuilder, $strOrder = null, int $intLimit = 0, int $intOffset = 0)
{
$arrImageFigures = [];
if (($imageFiles = FilesModel::findMultipleByUuids(StringUtil::deserialize($strUuids))) !== null)
{
$images = array();
while ($imageFiles->next())
{
// Continue if the files has been processed or does not exist
if (isset($images[$imageFiles->path]) || !file_exists(System::getContainer()->getParameter('kernel.project_dir') . '/' . $imageFiles->path))
{
continue;
}
// Single files
if ($imageFiles->type == 'file')
{
$objFile = new File($imageFiles->path);
if (!$objFile->isImage)
{
continue;
}
// Add the image
$images[$imageFiles->path] = $imageFiles->current();
} // Folders
else
{
$objSubfiles = FilesModel::findByPid($imageFiles->uuid, array('order' => 'name'));
if ($objSubfiles === null)
{
continue;
}
while ($objSubfiles->next())
{
// Skip subfolders
if ($objSubfiles->type == 'folder')
{
continue;
}
$objFile = new File($objSubfiles->path);
if (!$objFile->isImage)
{
continue;
}
// Add the image
$images[$objSubfiles->path] = $objSubfiles->current();
}
}
}
if ($strOrder !== null)
{
$images = ArrayUtil::sortByOrderField($images, $strOrder);
}
$images = array_values($images);
// Offset images
if ($intOffset > 0)
{
$images = \array_slice($images, ($intOffset < count($images) ? $intOffset : count($images)));
}
// Limit number of images
if ($intLimit > 0)
{
$images = \array_slice($images, 0, $intLimit);
}
// Build figures of images
foreach ($images as $image)
{
$figure = $figureBuilder
->fromFilesModel($image)
->build();
$arrImageFigures[] = $figure;
}
}
return count ($arrImageFigures) === 1 && $intLimit === 1 ? array_shift($arrImageFigures) : $arrImageFigures;
}
}