<?php declare(strict_types=1);
/**
* @package Memo\MemoFoundationBundle
* @author Media Motion AG
* @license LGPL-3.0+
* @copyright Media Motion AG
*/
namespace Memo\FoundationBundle\Service;
use Contao\CoreBundle\DataContainer\PaletteManipulator;
use Contao\CoreBundle\Routing\ResponseContext\HtmlHeadBag\HtmlHeadBag;
use Contao\CoreBundle\Routing\ResponseContext\JsonLd\JsonLdManager;
use Contao\CoreBundle\Routing\ResponseContext\ResponseContext;
use Spatie\SchemaOrg\Graph;
use Spatie\SchemaOrg\JobPosting;
use Spatie\SchemaOrg\Organization;
use Spatie\SchemaOrg\Place;
use Spatie\SchemaOrg\PostalAddress;
use Contao\FilesModel;
use Contao\System;
use Ivory\GoogleMap\Service\Geocoder\GeocoderService;
use Http\Adapter\Guzzle6\Client;
use Http\Message\MessageFactory\GuzzleMessageFactory;
class ToolboxService
{
/**
* On Save Callback for coordinates
* @param DataContainer $dc
*/
public function setCoordinates(\DataContainer $dc)
{
$strTable = $dc->table;
if($strTable == ''){
return;
}
\Controller::loadDataContainer($strTable);
$strModel = $GLOBALS['TL_MODELS'][$strTable];
if($strModel == ''){
return;
}
$objItem = $strModel::findOneById($dc->activeRecord->id);
if(($dc->activeRecord->lat == '' || $dc->activeRecord->long == '') && $dc->activeRecord->address != ''){
$arrCoordinates = false;
if(class_exists('\delahaye\GeoCode')){
$strKey = \Config::get('dlh_googlemaps_apikey');
$strCoordinates = \delahaye\GeoCode::getCoordinates($dc->activeRecord->address . $dc->activeRecord->object_location, 'ch', 'de', $strKey);
$arrCoordinates = explode(',', $strCoordinates);
} elseif(class_exists('\Spatie\Geocoder\Geocoder')){
$strKey = \Config::get('googlemaps_apiKey') ?? \Config::get('dlh_googlemaps_apikey');
$client = new \GuzzleHttp\Client();
$geocoder = new \Spatie\Geocoder\Geocoder($client);
$geocoder->setApiKey($strKey);
$geocoder->setCountry('CH');
$response = $geocoder->getCoordinatesForAddress($dc->activeRecord->address . $dc->activeRecord->object_location);
$arrCoordinates = array($response['lat'], $response['lng']);
}
if ($arrCoordinates && is_array($arrCoordinates)){
if(!is_null($arrCoordinates[0])){
$objItem->lat = $arrCoordinates[0];
}
if(!is_null($arrCoordinates[1])){
$objItem->long = $arrCoordinates[1];
}
$objItem->save();
}
}
}
/**
* Format Date for DCA-View
* @param $value
* @return false|int
*/
public function loadDate($value)
{
return strtotime(date('Y-m-d', (int)$value) . ' 00:00:00');
}
public static function setJsonLd($JsonLdItem){
// Get Response Context and check it
$objResponseContext = \System::getContainer()->get('contao.routing.response_context_accessor')->getResponseContext();
if (!$objResponseContext || !$objResponseContext->has(JsonLdManager::class)) {
return;
}
// Get JsonLdManager
$objJsonLdManager = $objResponseContext->get(JsonLdManager::class);
// Check Input Parameter and transform (auto) if needed
if(is_object($JsonLdItem)){
$objJsonLdItem = $JsonLdItem;
} elseif(is_array($JsonLdItem)){
$objJsonLdItem = $objJsonLdManager->createSchemaOrgTypeFromArray($JsonLdItem);
}
// Add the Schema to the Graph (Response)
$objJsonLdManager->getGraphForSchema(JsonLdManager::SCHEMA_ORG)->set($objJsonLdItem, Graph::IDENTIFIER_DEFAULT);
}
/**
* Toggle alias and seo-fields, if no detail-page is set on the parent-archive
* @param $strTablename
*/
public static function toggleDetailFieldsFromPalette($strTablename)
{
$arrDetailPageIds = array();
// Get the archive details
if(array_key_exists('ptable', $GLOBALS['TL_DCA'][$strTablename]['config'])){
$strArchiveTable = $GLOBALS['TL_DCA'][$strTablename]['config']['ptable'];
$strArchiveModel = $GLOBALS['TL_MODELS'][$strArchiveTable];
// Try to get the jumpTo page ids
$arrDetailPageIds = $strArchiveModel::getDetailPages(false);
}
// If no ids were found, there are now detailpages to be expected - so we can cleanup the palette
if(count($arrDetailPageIds) == 0){
$objLanguageService = \System::getContainer()->get('memo.foundation.language');
$arrLanguages = $objLanguageService->getAllLanguages(true);
foreach($arrLanguages as $strLanguage)
{
$strPostfix = $objLanguageService->getLanguagePostfix($strLanguage);
if($strPostfix == ''){
$arrFieldsToRemove = array(
array('general_legend', 'alias'),
array('meta_legend', 'seo_title'),
array('meta_legend', 'seo_description'),
array('meta_legend', 'serpPreview'),
);
} else {
$arrFieldsToRemove = array(
array('translation' . $strPostfix, 'alias'. $strPostfix),
array('translation' . $strPostfix, 'seo_title'. $strPostfix),
array('translation' . $strPostfix, 'seo_description'. $strPostfix),
);
}
foreach($GLOBALS['TL_DCA'][$strTablename]['palettes'] as $strKey => $strPalette){
if ($strKey == '__selector__') {
continue;
}
foreach($arrFieldsToRemove as $arrFields)
{
PaletteManipulator::create()
->removeField($arrFields[1], $arrFields[0])
->applyToPalette($strKey, $strTablename)
;
}
}
}
}
}
public static function collectionToArray($objCollection, $bolResetKeys=false, $strField='title')
{
$arrCollection = array();
if($objCollection != null)
{
foreach($objCollection as $objItem)
{
if($bolResetKeys){
$arrCollection[] = $objItem->$strField;
} else {
$arrCollection[$objItem->id] = $objItem->$strField;
}
}
}
return $arrCollection;
}
public static function convertOrderString($strOrderBy, $strTable)
{
$strSQL = '';
switch($strOrderBy)
{
case 'order_title':
$strSQL = "$strTable.title";
break;
case 'order_title_desc':
$strSQL = "$strTable.title DESC";
break;
case 'order_sorting':
$strSQL = "$strTable.sorting";
break;
case 'order_sorting_desc':
$strSQL = "$strTable.sorting DESC";
break;
case 'order_date':
$strSQL = "$strTable.date";
break;
case 'order_date_desc':
$strSQL = "$strTable.date DESC";
break;
}
return $strSQL;
}
/**
* Set page header meta by associative array.
* @param array $arr
* @return void
*/
public static function setPageHeaderMeta(array $arr): void
{
if (System::getContainer()->has('contao.routing.response_context_accessor')) {
$responseContext = System::getContainer()->get('contao.routing.response_context_accessor')->getResponseContext();
$htmlHeadBag = $responseContext->get(HtmlHeadBag::class);
if ($responseContext && $responseContext->has(HtmlHeadBag::class)) {
foreach ($arr as $tag => $value) {
switch ($tag) {
case 'robots':
$htmlHeadBag->setMetaRobots($value);
break;
case 'title':
$htmlHeadBag->setTitle($value);
break;
case 'description':
$htmlHeadBag->setMetaDescription($value);
break;
case 'canonical':
$htmlHeadBag->setCanonicalUri($value);
break;
}
}
}
} else {
global $objPage;
foreach ($arr as $tag => $value) {
$objPage->{$tag} = $value;
}
}
}
public static function generateMarker(\DataContainer $dc)
{
// Get & Check Table
$strTable = $dc->table;
if($strTable == ''){
\System::log('No table given for marker generation', __METHOD__, TL_ERROR);
return;
}
// Get and check Class/Model
\Controller::loadDataContainer($strTable);
$strModel = $GLOBALS['TL_MODELS'][$strTable];
if($strModel == '' || !class_exists($strModel)){
\System::log('No model found for table ' . $strTable, __METHOD__, TL_ERROR);
return;
}
// Get Item
$objItem = $strModel::findOneById($dc->activeRecord->id);
if(!$objItem){
\System::log('No item found for table ' . $strTable . ' with id ' . $dc->activeRecord->id, __METHOD__, TL_ERROR);
return;
}
// Get Parent / Archive
$objArchive = $objItem->getRelated('pid');
if(!$objArchive){
\System::log('No archive found for table ' . $strTable . ' with id ' . $dc->activeRecord->id, __METHOD__, TL_ERROR);
return;
}
// Check data
if(!$objArchive->addMarker || !$objArchive->markerSRC || $objArchive->markerSRC == ''){
\System::log('No marker found for table ' . $strTable . ' with id ' . $dc->activeRecord->id, __METHOD__, TL_ERROR);
return;
}
if(!$objItem->singleSRC || $objItem->singleSRC == ''){
\System::log('No image found for item: table ' . $strTable . ' with id ' . $dc->activeRecord->id, __METHOD__, TL_ERROR);
return;
}
// Get Item Image
$objItemImage = \FilesModel::findByUuid($objItem->singleSRC);
// Check File
if(!$objItemImage || file_exists($objItemImage->path) === false){
\System::log('Defined image not found for item: table ' . $strTable . ' with id ' . $dc->activeRecord->id, __METHOD__, TL_ERROR);
return;
}
// Get Template Image
$objTemplateImage = \FilesModel::findByUuid($objArchive->markerSRC);
// Check File
if(!$objTemplateImage || file_exists($objTemplateImage->path) === false){
\System::log('Defined marker background image not found for item: table ' . $strTable . ' with id ' . $dc->activeRecord->id, __METHOD__, TL_ERROR);
return;
}
// Check the destination
$objMarkerFolder = FilesModel::findByUuid($objArchive->markerFolder);
if(!$objMarkerFolder || file_exists($objMarkerFolder->path) === false){
\System::log('Defined marker folder not found', __METHOD__, TL_ERROR);
return;
}
// Create Base from Original Image
switch($objItemImage->extension){
case 'jpeg':
case 'jpg':
$objItemImageSource = imagecreatefromjpeg($objItemImage->path);
break;
case 'png':
$objItemImageSource = imagecreatefrompng($objItemImage->path);
break;
case 'gif':
$objItemImageSource = imagecreatefromgif($objItemImage->path);
break;
default:
\System::log('Image type not supported for marker generation: ' . $objItemImage->extension, __METHOD__, TL_ERROR);
return;
}
// Define filename, path etc.
if($objItem->alias != ''){
$strFilename = 'marker-' . $objItem->alias . '-'.$objItem->id.'.png';
} else {
$strFilename = 'marker-' . $objItem->id.'.png';
}
$strFilename = $objItem->alias . '-'.$objItem->id.'.png';
$strFilepath = $objMarkerFolder->path . '/' . $strFilename;
// Get Image Size
list($intSourceWidth, $intSourceHeight) = getimagesize($objItemImage->path);
// Load Marker Template
switch($objTemplateImage->extension){
case 'jpeg':
case 'jpg':
$objMarker = imagecreatefromjpeg($objTemplateImage->path);
break;
case 'png':
$objMarker = imagecreatefrompng($objTemplateImage->path);
break;
case 'gif':
$objMarker = imagecreatefromgif($objTemplateImage->path);
break;
default:
\System::log('Image type not supported for marker generation: ' . $objTemplateImage->extension, __METHOD__, TL_ERROR);
return;
}
imagesavealpha($objMarker, true);
// Get Marker Sizes
$intMarkerWidth = imagesx( $objMarker );
$intMarkerHeight = imagesy( $objMarker );
// Create new Image and crop on Item Image
$objMarkerImage = imagecreatetruecolor($intMarkerWidth,$intMarkerHeight);
imagealphablending( $objMarkerImage, false );
imagecopyresampled( $objMarkerImage, $objItemImageSource, 0, 0, 0, 0, $intMarkerWidth - $objArchive->markerWidthTrim, $intMarkerHeight - $objArchive->markerHeightTrim, $intSourceWidth, $intSourceHeight);
// Merge Item Image into Marker Image with offset (for border)
imagecopyresampled( $objMarker, $objMarkerImage , $objArchive->markerOffsetX, $objArchive->markerOffsetY, 0, 0, $intMarkerWidth - $objArchive->markerWidthTrim, $intMarkerHeight - $objArchive->markerHeightTrim, $intMarkerWidth - $objArchive->markerWidthTrim, $intMarkerHeight - $objArchive->markerHeightTrim);
// Write Marker to Folder
imagepng( $objMarker,$strFilepath );
if(!file_exists($strFilepath)){
\System::log('Marker could not be created', __METHOD__, TL_ERROR);
return;
}
\Dbafs::addResource($strFilepath);
// Get Marker Object
$objMarkerFile = \FilesModel::findByPath($strFilepath);
// Check Marker Object
if(!$objMarkerFile){
\System::log('Marker could not be added to database', __METHOD__, TL_ERROR);
return;
}
// Update Item
$objItem->markerSRC = $objMarkerFile->uuid;
$objItem->save();
}
}