TCEMainHook.php 101 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970197119721973197419751976197719781979198019811982198319841985198619871988198919901991199219931994199519961997199819992000200120022003200420052006200720082009201020112012201320142015201620172018201920202021202220232024202520262027202820292030203120322033203420352036203720382039204020412042204320442045204620472048204920502051205220532054205520562057205820592060206120622063206420652066206720682069207020712072207320742075207620772078207920802081208220832084208520862087208820892090209120922093209420952096209720982099210021012102210321042105210621072108210921102111211221132114211521162117211821192120212121222123212421252126212721282129213021312132213321342135213621372138213921402141214221432144214521462147214821492150215121522153215421552156215721582159216021612162216321642165216621672168216921702171217221732174217521762177217821792180218121822183218421852186218721882189219021912192219321942195219621972198219922002201220222032204220522062207220822092210221122122213221422152216221722182219222022212222222322242225222622272228222922302231223222332234223522362237223822392240224122422243224422452246224722482249225022512252225322542255225622572258225922602261226222632264226522662267226822692270227122722273227422752276227722782279228022812282228322842285228622872288228922902291229222932294229522962297229822992300230123022303230423052306230723082309231023112312231323142315231623172318231923202321232223232324232523262327232823292330233123322333233423352336233723382339234023412342234323442345234623472348234923502351235223532354235523562357235823592360236123622363236423652366236723682369237023712372237323742375237623772378237923802381238223832384238523862387238823892390239123922393239423952396239723982399240024012402240324042405240624072408240924102411241224132414241524162417241824192420242124222423242424252426242724282429243024312432243324342435243624372438243924402441244224432444244524462447244824492450245124522453245424552456245724582459246024612462246324642465246624672468246924702471
  1. <?php
  2. namespace Meramo\mrm_be\Hooks\TCE;
  3. use DOMDocument;
  4. use \TYPO3\CMS\Core\Utility\GeneralUtility;
  5. use \TYPO3\CMS\Core\Database\ConnectionPool;
  6. use \TYPO3\CMS\Core\Database\Connection;
  7. use \TYPO3\CMS\Core\Service\FlexFormService;
  8. use \TYPO3\CMS\Core\Configuration\FlexForm\FlexFormTools;
  9. use TYPO3\CMS\Core\Database\Query\Restriction\DeletedRestriction;
  10. use TYPO3\CMS\Core\Database\Query\Restriction\HiddenRestriction;
  11. use TYPO3\CMS\Extbase\Utility\DebuggerUtility;
  12. use \Meramo\mrm_be\Mongoer as Mongoer;
  13. require_once GeneralUtility::getFileAbsFileName('typo3conf/ext/mrm_be/Resources/Private/PHP/phpqrcode/qrlib.php');
  14. class TCEMainHook
  15. {
  16. protected $imageSizes = array(
  17. 'mrm_be_cm_publication' => array(
  18. 'passthru' => array(
  19. 'small' => array('width' => 256),
  20. 'big' => array('width' => 512)
  21. )
  22. ),
  23. 'mrm_be_cm_homeheaderinfo' => array(
  24. 'i_1_1' => array(
  25. 'i_1_1' => array('width' => 140, 'height' => 140),
  26. ),
  27. 'i_16_9' => array(
  28. 'i_16_9' => array('width' => 140, 'height' => 79),
  29. ),
  30. 'default' => array(
  31. 'default' => array('width' => 140, 'height' => 94),
  32. )
  33. ),
  34. 'mrm_be_cm_explorerbox' => array(
  35. 'i_1_1' => array(
  36. 'img' => array('width' => 500, 'height' => 500),
  37. )
  38. ),
  39. 'mrm_be_cm_statementbox' => array(
  40. 'i_1_1' => array(
  41. 'img' => array('width' => 160, 'height' => 160),
  42. )
  43. ),
  44. 'mrm_be_cm_checklist-radiorange' => array(
  45. 'i_1_1' => array(
  46. 'img' => array('width' => 160, 'height' => 160),
  47. )
  48. ),
  49. 'mrm_be_cm_tileoverview' => array(
  50. 'default' => array(
  51. 'default_hero_lte600' => array('width' => 560, 'height' => 373),
  52. )
  53. ),
  54. 'mrm_be_cm_heroimage' => array(
  55. 'default' => array(
  56. 'lte600' => array('width' => 560, 'height' => 373),
  57. 'gt600' => array('width' => 408, 'height' => 272)
  58. ),
  59. ),
  60. 'mrm_be_cm_imageplus' => array(
  61. 'default' => array(
  62. 'ratio32' => array('width' => 439, 'height' => 293)
  63. ),
  64. 'i_16_9' => array(
  65. 'ratio169' => array('width' => 727, 'height' => 409)
  66. ),
  67. 'i_21_9' => array(
  68. 'ratio219' => array('width' => 984, 'height' => 422)
  69. )
  70. ),
  71. 'mrm_be_cm_contentimage' => array(
  72. 'i_1_1' => array(
  73. 'content_image' => array('width' => 160, 'height' => 160),
  74. 'content_image_maximized_lte600' => array('width' => 560, 'height' => 560),
  75. 'content_image_maximized_gt600' => array('width' => 460, 'height' => 460),
  76. ),
  77. ),
  78. 'mrm_be_cm_rawimage' => array('passthru' => true),
  79. 'mrm_be_cm_animation' => array('passthru' => true),
  80. 'mrm_be_cm_picturechoice' => array(
  81. 'i_1_1' => array(
  82. 'pic' => array('width' => 300, 'height' => 300)
  83. )
  84. ),
  85. 'overview_image' => array(
  86. 'default' => array(
  87. 'home_topics_lte767' => array('width' => 725, 'height' => 484),
  88. 'home_topics_gt767' => array('width' => 313, 'height' => 209),
  89. 'sidebar_banner_lte840' => array('width' => 100, 'height' => 66),
  90. 'rubrik_overview' => array('width' => 318, 'height' => 212),
  91. 'default_hero_lte600' => array('width' => 560, 'height' => 373),
  92. 'default_hero_gt600' => array('width' => 408, 'height' => 272, 'allowed_doktypes' => ['102']),
  93. ),
  94. 'i_1_1' => array(
  95. 'home_rubrik' => array('width' => 95, 'height' => 95),
  96. 'archive_block' => array('width' => 160, 'height' => 160),
  97. 'square_big' => array('width' => 520, 'height' => 520),
  98. ),
  99. 'i_16_9' => array(
  100. 'og' => array('width' => 1200, 'height' => 675),
  101. 'sidebar_banner_gt840' => array('width' => 282, 'height' => 159),
  102. ),
  103. 'i_21_9' => array(
  104. 'flat_tile' => array('width' => 400, 'height' => 171),
  105. 'flat_big' => array('width' => 700, 'height' => 300),
  106. ),
  107. )
  108. );
  109. private $imageService;
  110. private $resourceFactory;
  111. private $fileRepository;
  112. private $environmentService;
  113. private $queryBuilder;
  114. private $pageQueryBuilder;
  115. private $pageRepository;
  116. private $linkService;
  117. private $connection;
  118. function __construct()
  119. {
  120. $this->environmentService = GeneralUtility::makeInstance("TYPO3\CMS\Extbase\Service\EnvironmentService");
  121. $this->resourceFactory = GeneralUtility::makeInstance('TYPO3\CMS\Core\Resource\ResourceFactory');
  122. $this->imageService = GeneralUtility::makeInstance("TYPO3\CMS\Extbase\Service\ImageService");
  123. $this->fileRepository = GeneralUtility::makeInstance('TYPO3\CMS\Core\Resource\FileRepository');
  124. $this->pageRepository = GeneralUtility::makeInstance('TYPO3\CMS\Frontend\Page\PageRepository');
  125. $this->linkService = GeneralUtility::makeInstance('TYPO3\CMS\Core\LinkHandling\LinkService');
  126. $connection = GeneralUtility::makeInstance(ConnectionPool::class);
  127. $this->connection = $connection;
  128. $this->queryBuilder = $connection->getQueryBuilderForTable('tt_content');
  129. $this->queryBuilder->getRestrictions()->removeAll()
  130. ->add(GeneralUtility::makeInstance(DeletedRestriction::class))
  131. ->add(GeneralUtility::makeInstance(HiddenRestriction::class));
  132. $this->pageQueryBuilder = $connection->getQueryBuilderForTable('pages');
  133. $this->pageQueryBuilder->getRestrictions()->removeAll();
  134. }
  135. public function processDatamap_beforeStart($pObj)
  136. {
  137. if (!isset($pObj->datamap['pages'])) return;
  138. foreach ($pObj->datamap['pages'] as $pid => &$_d) {
  139. if (!$pid || $pid < 0) continue;
  140. $starttime = $_d["starttime"];
  141. if ($starttime != 0)
  142. $_d["starttime"] = $this->startOfDay($starttime, null, true, true);
  143. $endtime = $_d["endtime"];
  144. if ($endtime != 0)
  145. $_d["endtime"] = $this->endOfDay($endtime, null, true, true);
  146. switch ($_d["red_status"]) {
  147. case "-1": //neu angelegt
  148. case "1": //in Bearbeitung
  149. case "2": //vorbereitet
  150. case "3": //geprüft
  151. case "21": //gesperrt
  152. case "22": //archiviert
  153. $_d["hidden"] = 1;
  154. break;
  155. case "11": //frei
  156. case "12": //online
  157. $_d["hidden"] = 0;
  158. break;
  159. default:
  160. break;
  161. }
  162. }
  163. }
  164. public function processCmdmap_afterFinish(\TYPO3\CMS\Core\DataHandling\DataHandler &$pObj)
  165. {
  166. if (!isset($pObj->datamap['pages'])) return;
  167. foreach ($pObj->datamap['pages'] as $pid => $_d) {
  168. if (!$pid || $pid < 0) continue;
  169. $this->log('processing PID: ' . $pid);
  170. $pageStatement = $this->pageQueryBuilder
  171. ->select('*')
  172. ->from('pages')
  173. ->setMaxResults(1)
  174. ->where(
  175. $this->pageQueryBuilder->expr()->eq('uid', $this->pageQueryBuilder->createNamedParameter($pid))
  176. )
  177. ->execute();
  178. $post = $pageStatement->fetchAll();
  179. $post = $post[0];
  180. if (!$post) continue;
  181. if ($post['doktype'] == 254) {
  182. $this->processFolderContent($post);
  183. continue;
  184. }
  185. if ($post['hidden'] == 1 || $post['deleted'] == 1) {
  186. Mongoer::sendRequest("pages", "delete", array("pageuid" => $pid));
  187. Mongoer::sendRequest("abialtcache", "delete", array("pageuid" => $pid));
  188. Mongoer::sendRequest("search", "delete", array("pageuid" => $pid));
  189. Mongoer::sendRequest("security", "delete", array("pageuid" => $pid));
  190. // DELETE existing page PDF
  191. $this->deletePagePDFIfExists($post['slug']);
  192. //continue;
  193. }
  194. $rootlineutil = GeneralUtility::makeInstance('TYPO3\CMS\Core\Utility\RootlineUtility', $pid);
  195. $rootline = array_reverse($rootlineutil->get($pid));
  196. $processedImages = array();
  197. $slugData = $this->constructSlug($pid);
  198. if (!$slugData) {
  199. $this->log($pid . " slugData empty");
  200. continue;
  201. }
  202. $qrfilename = '/var/www/html/public/typo3temp/' . mt_rand(0, 0xffffff) . '_' . mt_rand(0, 0xffffff) . '.svg';
  203. \QRcode::svg("https://abi.de" . $slugData, $qrfilename);
  204. $qrsvg = file_get_contents($qrfilename);
  205. unlink($qrfilename);
  206. $statement = $this->queryBuilder
  207. ->select('*')
  208. ->from('tt_content')
  209. ->where(
  210. $this->queryBuilder->expr()->eq('pid', $this->queryBuilder->createNamedParameter($pid))
  211. )
  212. ->execute();
  213. $fetchedTTContent = array();
  214. $pageType = "article";
  215. //$this->log($post["doktype"]);
  216. if ($post["doktype"] == 100) $pageType = "event-page";
  217. if ($post["doktype"] == 101) $pageType = "blog-page";
  218. if ($post["doktype"] == 102) $pageType = "blogger-page";
  219. if ($post["doktype"] == 103) $pageType = "archive";
  220. if ($post["doktype"] == 104) $pageType = "video-page";
  221. if ($post['is_siteroot'] == 1) $pageType = "home";
  222. // $overview_image = null;
  223. while ($row = $statement->fetch()) {
  224. $fetchedTTContent[] = $row;
  225. $row["doktype"] = $post["doktype"];
  226. }
  227. /* look for overview_image start */
  228. if ($pageType == "blogger-page" || $pageType == "video-page") {
  229. $overview_image = $this->processImagesTTContent($post, 'overview_image', 'pages', 'overview_image');
  230. $overview_image = $overview_image[0] ? $overview_image[0] : null;
  231. }
  232. if (!$overview_image) {
  233. $x = $this->findFirstAppearingElementByType("mrm_be_cm_postimage", $fetchedTTContent, "CType");
  234. if ($x) {
  235. $overview_image = $this->processImagesTTContent($x, 'overview_image');
  236. $overview_image = $overview_image[0] ? $overview_image[0] : null;
  237. }
  238. }
  239. if (!$overview_image) {
  240. foreach ($fetchedTTContent as $row) {
  241. if (!$overview_image && ($row['CType'] == "mrm_be_cm_heroimage" || $row['CType'] == "mrm_be_cm_contentimage" || $row['CType'] == "mrm_be_cm_rawimage")) {
  242. $overview_image = $this->processImagesTTContent($row, 'overview_image');
  243. $overview_image = $overview_image[0] ? $overview_image[0] : null;
  244. }
  245. }
  246. }
  247. /* look for overview_image end */
  248. if ($pageType != "home") {
  249. $initialContent = $this->createContentElement($pageType, array(), (object) array(), array());
  250. $initialH1Attribs = array();
  251. if ($post["roof"] && $post["roof"] != '') $initialH1Attribs["roof"] = $post["roof"];
  252. if ($post["title"] && $post["title"] != '') $initialH1Attribs["text"] = $post["title"];
  253. if (sizeof($initialH1Attribs) > 0) $initialContent["subElements"][] = $this->createContentElement("h1", array(), $initialH1Attribs);
  254. }
  255. $processedData = array(
  256. 'pageuid' => $pid,
  257. 'documentLanguage' => $post['documentlanguage'],
  258. 'url' => $slugData,
  259. 'shareableUrl' => "https://abi.de" . $slugData,
  260. 'title' => ($post['roof'] != '' ? $post['roof'] . ": " : "") . $post['title'],
  261. 'activeMenuPage' => $post['targetgroup'],
  262. 'overviewImage' => $overview_image,
  263. 'teasers' => array(
  264. 'teaserHome' => $post['teaserHome'],
  265. 'abstract' => $this->removeLinebreaks($post['abstract']),
  266. 'teaserOverview' => $post['teaserOverview'],
  267. 'title' => $post['title'],
  268. 'roof' => $post['roof'],
  269. 'intro' => ($pageType == 'blogger-page') ? $post['overview'] : $post['intro']
  270. ),
  271. 'sharingActivated' => $post['sharing_activated'] == 1 ? true : false,
  272. 'linkableInHTMLSitemap' => $post['forHTMLSitemap'] == 1 ? true : false,
  273. 'linkableOnHome' => $post['forHome'] == 1 ? true : false,
  274. 'linkableOnCategoryOverview' => $post['forCategoryOverview'] == 1 ? true : false,
  275. 'moveToTopPositionOnCategoryOverview' => $post['forCategoryOverviewTopPosition'] == 1 ? true : false,
  276. 'pageType' => $pageType,
  277. 'pageData' => array(
  278. 'title' => ($post['roof'] != '' ? $post['roof'] . ": " : "") . $post['title'],
  279. 'metas' => array(
  280. "<meta name=\"keywords\" content=\"" . $post["keywords"] . "\">",
  281. "<meta name=\"dcterms.date\" content=\"" . date("Y-m-d", $post['tstamp'] > $post['starttime'] ? $post['tstamp'] : $post['starttime']) . "\">",
  282. "<meta name=\"robots\" content=\"" . ($post['no_index'] == 0 ? "index" : "noindex") . ", " . ($post['no_follow'] == 0 ? "follow" : "nofollow") . "\" />",
  283. "<meta property=\"og:title\" content=\"" . ($post['roof'] != '' ? $post['roof'] . ": " : "") . $post['title'] . "\">",
  284. ($overview_image ? "<meta property=\"og:image\" content=\"https://abi.de/cdn/" . $overview_image["sources"]["og"] . "\" >" : ""),
  285. ),
  286. 'breadcrumbs' => $this->constructBreadCrumb($rootline, $post, $pageType),
  287. 'content' => $initialContent,
  288. 'sidebar' => $this->createContentElement("sidebar", array(), (object) array(), array()),
  289. ),
  290. 'linkedPosts' => array(),
  291. 'injections' => array(),
  292. 'qr2page' => $qrsvg,
  293. 'status' => $this->constructStatus($post)
  294. );
  295. //before content
  296. switch ($pageType) {
  297. case "blog-page":
  298. $processedData["pageData"]["content"]["subElements"][] = $this->createContentElement("injection", array("type" => "blog-author-info"));
  299. $processedData["injections"][] = "blog-author-info";
  300. $processedData["pageData"]["sidebar"]["subElements"][] = $this->createContentElement("injection", array("type" => "blog-page-sidebar"));
  301. $processedData["injections"][] = "blog-page-sidebar";
  302. break;
  303. case "blogger-page":
  304. $processedData["pageData"]["content"]["subElements"][] = $this->createContentElement("injection", array("type" => "blogger-page-author-image"));
  305. $processedData["injections"][] = "blogger-page-author-image";
  306. $text = $post['overview'] ?? $post['abstract'];
  307. $processedData["pageData"]["content"]["subElements"][] = $this->createContentElement("typo3_paragraph", array(), array('text' => '<p>' . $this->exchangeLinkBreaksWithBr($text) . '</p>'), null);
  308. $processedData["pageData"]["content"]["subElements"][] = $this->createContentElement("injection", array("type" => "blogger-page-author-latest-blogs"));
  309. $processedData["injections"][] = "blogger-page-author-latest-blogs";
  310. $processedData["pageData"]["sidebar"]["subElements"][] = $this->createContentElement("injection", array("type" => "blogger-page-sidebar"));
  311. $processedData["injections"][] = "blogger-page-sidebar";
  312. break;
  313. case "video-page":
  314. $processedData["pageData"]["content"]["subElements"][] = $this->createContentElement("injection", array("type" => "video-date-category"));
  315. $processedData["injections"][] = "video-date-category";
  316. $processedData["pageData"]["content"]["subElements"][] = $this->createContentElement("injection", array("type" => "video-info"));
  317. $processedData["injections"][] = "video-info";
  318. break;
  319. }
  320. foreach ($fetchedTTContent as $row) {
  321. $this->processData($row, $processedData, $processedImages);
  322. }
  323. //after content
  324. $processedData['pageData']['metas'][] = $this->constructMetaDescription($post['abstract'], $processedData['pageData']['content']);
  325. $processedData['pageData']['metas'][] = $this->constructMetaDescription($post['abstract'], $processedData['pageData']['content'], true);
  326. if ($pageType == "blog-page") {
  327. $processedData['pageData']['metas'][] = $this->constructMetaDescriptionForBlogPage('', $processedData['pageData']['content']);
  328. $processedData['pageData']['metas'][] = $this->constructMetaDescriptionForBlogPage('', $processedData['pageData']['content'], true);
  329. }
  330. $processedData['pageData']['metas'] = array_filter($processedData['pageData']['metas'], function ($val) {
  331. return $val != "";
  332. });
  333. switch ($pageType) {
  334. case "archive":
  335. $hasSpecificOverviewInjection = false;
  336. foreach ($processedData["injections"] as $inj) {
  337. if (str_contains($inj, "-archive-")) {
  338. $hasSpecificOverviewInjection = true;
  339. break;
  340. }
  341. }
  342. if (!$hasSpecificOverviewInjection) {
  343. $processedData["pageData"]["content"]["subElements"][] = $this->createContentElement("injection", array("type" => "archive-of-direct-childurls"));
  344. $processedData["injections"][] = "archive-of-direct-childurls";
  345. }
  346. break;
  347. case "event-page":
  348. if ($post["event_link"] && $post["event_link"] != "") {
  349. $processedData["pageData"]["content"]["subElements"][] = $this->createContentElement("typo3_paragraph", array(), array('text' => '<p><a href="' . $post["event_link"] . '" target="_blank">Weitere Infos zu dieser Veranstaltung »</a></p>'));
  350. }
  351. break;
  352. }
  353. if (sizeof($processedData['pageData']['sidebar']['subElements']) == 0) {
  354. $processedData['pageData']['sidebar'] = null;
  355. }
  356. if (sizeof($processedData['linkedPosts']) == 0) $processedData['linkedPosts'] = null;
  357. else
  358. $processedData['linkedPosts'] = array_values(array_unique($processedData['linkedPosts']));
  359. if (sizeof($processedData['injections']) == 0) $processedData['injections'] = null;
  360. else
  361. $processedData['injections'] = array_unique($processedData['injections']);
  362. if ($post['hidden'] == 1) {
  363. //TODO: SET STATUS ..
  364. }
  365. $this->deletePagePDFIfExists($processedData['url']);
  366. Mongoer::sendRequest("pages", "save", $processedData);
  367. $this->generatePDFPath($processedData['pageuid'], $processedData['url']);
  368. Mongoer::sendRequest("abialtcache", "delete", array("pageuid" => $pid));
  369. $security_user_pass = $post["security_user_pass"];
  370. if (!$security_user_pass || $security_user_pass == '')
  371. Mongoer::sendRequest("security", "delete", array("pageuid" => $pid));
  372. else {
  373. $tmp = array();
  374. foreach (preg_split('/\n|\r\n?/', $security_user_pass) as $itm) {
  375. $itm = trim($itm);
  376. $itm = explode('|', $itm);
  377. $tmp[$itm[0]] = $itm[1];
  378. }
  379. $security_user_pass = $tmp;
  380. Mongoer::sendRequest("security", "save", array("pageuid" => $pid, "url" => $processedData["url"], "data" => $security_user_pass));
  381. }
  382. //if($post['doktype'] != 1) continue;
  383. if ($post['no_search'] == 0) {
  384. $dkzer = new \Meramo\mrm_be\DKZer();
  385. $searchwords = $dkzer->getSearchWords($post['dkz_code_nrs']);
  386. $freesearchwords = preg_split('/\n|\r|,\n?/', $post['free_searchwords']);
  387. foreach ($freesearchwords as $sw) {
  388. $searchwords[] = $this->convertStringToTechnicalName($sw);
  389. }
  390. $ignoredsearchwords = preg_split('/\n|\r|,\n?/', $post['ignored_searchwords']);
  391. foreach ($ignoredsearchwords as &$sw) {
  392. $sw = $this->convertStringToTechnicalName($sw);
  393. }
  394. $searchwords = array_values(array_diff($searchwords, $ignoredsearchwords));
  395. $searchabletext = $this->constructSearchableText($processedData, true);
  396. $searchabletext_full = $this->constructSearchableText($processedData, false);
  397. $arra = array("pageuid" => $pid, "searchwords" => $searchwords, "text" => $searchabletext, "fulltext" => $searchabletext_full, "lesson" => null);
  398. $lessons = array_values(explode(',', $post['lesson']));
  399. if (sizeof($lessons) == 1 && $lessons[0] == "") $lessons = [];
  400. if (sizeof($lessons) > 0) {
  401. foreach ($lessons as &$l) $l = (int) $l;
  402. $arra['lesson'] = $lessons;
  403. }
  404. Mongoer::sendRequest("search", "save", $arra);
  405. } else Mongoer::sendRequest("search", "delete", array("pageuid" => $pid));
  406. }
  407. }
  408. private function createPDFHash($url)
  409. {
  410. $page = md5($url);
  411. return $page[0] . $page[1] . '/' . $page[2] . $page[3] . '/' . $page . '.pdf';
  412. }
  413. private function deletePagePDFIfExists($url)
  414. {
  415. $partialpath = \TYPO3\CMS\Core\Core\Environment::getPublicPath() . '/pdf-storage/';
  416. $file = $this->createPDFHash($url);
  417. $filepath = $partialpath . $file;
  418. if (file_exists($filepath)) {
  419. unlink($filepath);
  420. return true;
  421. } else {
  422. return false;
  423. }
  424. }
  425. private function generatePDFPath($pageuid, $url)
  426. {
  427. $urlencoded = urlencode($url);
  428. // $this->log($url, true);
  429. $urlpart = "https://abi.de/pdfgen?u=";
  430. $pdfgenurl = $urlpart . $urlencoded;
  431. $data = [
  432. 'pageuid' => $pageuid,
  433. 'url' => $pdfgenurl,
  434. 'pdfhash' => $this->createPDFHash($url)
  435. ];
  436. Mongoer::sendRequest('pdfgenjobs', 'save', $data);
  437. }
  438. private function processFolderContent(&$post)
  439. {
  440. $statement = $this->queryBuilder
  441. ->select('*')
  442. ->from('tt_content')
  443. ->where(
  444. $this->queryBuilder->expr()->eq('pid', $this->queryBuilder->createNamedParameter($post["uid"]))
  445. )
  446. ->execute();
  447. $fetchedTTContent = array();
  448. while ($row = $statement->fetch()) {
  449. $fetchedTTContent[] = $row;
  450. }
  451. if ($post['backend_layout'] == 'pagets__19') {
  452. $themenderwoche = array();
  453. $ffs = GeneralUtility::makeInstance(FlexFormService::class);
  454. foreach ($fetchedTTContent as $row) {
  455. $flex = $ffs->convertFlexFormContentToArray($row['pi_flexform']);
  456. $themenderwoche[] = array(
  457. "key" => $flex['key'],
  458. "starttime" => $this->startOfDay($flex['starttime']),
  459. "endtime" => $this->endOfDay($flex['starttime'], '+6 days'),
  460. "monday" => (int) $this->parseUIDFromT3Url($flex['monday']),
  461. "tuesday" => (int) $this->parseUIDFromT3Url($flex['tuesday']),
  462. "wednesday" => (int) $this->parseUIDFromT3Url($flex['wednesday']),
  463. "thursday" => (int) $this->parseUIDFromT3Url($flex['thursday']),
  464. "friday" => (int) $this->parseUIDFromT3Url($flex['friday']),
  465. "saturday" => (int) $this->parseUIDFromT3Url($flex['saturday']),
  466. "sunday" => (int) $this->parseUIDFromT3Url($flex['sunday']),
  467. );
  468. }
  469. Mongoer::sendRequest("themaderwoche", "save", array("data" => $themenderwoche));
  470. }
  471. if ($post['backend_layout'] == 'pagets__20') {
  472. $menus = array();
  473. $ffs = GeneralUtility::makeInstance(FlexFormService::class);
  474. foreach ($fetchedTTContent as $row) {
  475. $flex = $ffs->convertFlexFormContentToArray($row['pi_flexform']);
  476. $items = array();
  477. foreach ((array) $flex["dynamicComponents"] as $link) {
  478. $linkedPostIds = array();
  479. $itm = $this->parseFlexFormLink($link["links"]["link"], null, $linkedPostIds);
  480. //$this->log($itm, false);
  481. unset($itm["href"]);
  482. $itm["pageuid"] = $linkedPostIds["linkedPosts"][0];
  483. $items[] = $itm;
  484. }
  485. $menus[] = array(
  486. 'headline' => $flex['headline'],
  487. 'menu_id' => $flex['mid'],
  488. 'items' => $items
  489. );
  490. }
  491. Mongoer::sendRequest("menues", "save", array("data" => $menus));
  492. }
  493. if ($post['backend_layout'] == 'pagets__21') {
  494. $topthemen = array();
  495. $ffs = GeneralUtility::makeInstance(FlexFormService::class);
  496. foreach ($fetchedTTContent as $row) {
  497. $flex = $ffs->convertFlexFormContentToArray($row['pi_flexform']);
  498. $topthemen[] = array(
  499. "key" => $flex['key'],
  500. "starttime" => $this->startOfDay($flex['starttime']),
  501. "endtime" => $this->endOfDay($flex['starttime'], '+13 days'),
  502. "section1" => (int) $this->parseUIDFromT3Url($flex['section1']),
  503. "section2" => (int) $this->parseUIDFromT3Url($flex['section2']),
  504. "section3" => (int) $this->parseUIDFromT3Url($flex['section3']),
  505. "section4" => (int) $this->parseUIDFromT3Url($flex['section4']),
  506. "section5" => (int) $this->parseUIDFromT3Url($flex['section5']),
  507. );
  508. }
  509. Mongoer::sendRequest("topthemen", "save", array("data" => $topthemen));
  510. }
  511. if ($post['backend_layout'] == 'pagets__23') {
  512. $maintenance = array();
  513. $ffs = GeneralUtility::makeInstance(FlexFormService::class);
  514. foreach ($fetchedTTContent as $row) {
  515. $flex = $ffs->convertFlexFormContentToArray($row['pi_flexform']);
  516. $maintenance[] = array(
  517. "starttime" => $flex['starttime'],
  518. "endtime" => $flex['endtime'],
  519. "infotext" => $flex['infotext']
  520. );
  521. }
  522. Mongoer::sendRequest("maintenance", "save", array("data" => $maintenance));
  523. }
  524. if ($post['backend_layout'] == 'pagets__27' || $post['backend_layout' == 'pagets__28']) {
  525. $chatbot = array();
  526. $ffs = GeneralUtility::makeInstance(FlexFormService::class);
  527. foreach ($fetchedTTContent as $row) {
  528. $isDirect = $row['CType'] == 'mrm_be_cm_chatbot-direct';
  529. $flex = $ffs->convertFlexFormContentToArray($row['pi_flexform']);
  530. $item = array();
  531. $item['terms'] = explode("\n", str_replace(',', '', $flex['settings']['terms']));
  532. $item['type'] = $isDirect ? 'direct' : $flex['settings']['type'];
  533. if ($isDirect) {
  534. $item['url'] = $this->replaceT3Link($flex['settings']['url'], null, $row, false);
  535. }
  536. if ($flex['settings']['type'] == 'reverse') {
  537. $item["category"] = (($flex['settings']['category'] == "Auswählen") ? '' : $flex['settings']['category']);
  538. }
  539. $chatbot[] = $item;
  540. }
  541. Mongoer::sendRequest("chatbot", "save", array("data" => $chatbot));
  542. }
  543. }
  544. private function removeLinebreaks($str)
  545. {
  546. return trim(preg_replace('/\s+/', ' ', $str));
  547. }
  548. private function exchangeLinkBreaksWithBr($str)
  549. {
  550. return trim(preg_replace('/\r\n/', '<br />', $str));
  551. }
  552. private function startOfDay($ts, $modify = null, $isAtomDate = false, $returnAtomDate = false)
  553. {
  554. $dt = null;
  555. if ($isAtomDate) {
  556. if (is_numeric($ts)) {
  557. $ts = $ts + 0;
  558. $dt = new \DateTime();
  559. $dt->setTimezone(new \DateTimeZone('UTC'));
  560. $dt->setTimestamp($ts);
  561. } else {
  562. $dt = new \DateTime($ts);
  563. $dt->setTimezone(new \DateTimeZone('UTC'));
  564. }
  565. } else {
  566. $dt = new \DateTime(null, new \DateTimeZone('Europe/Berlin'));
  567. $dt->setTimestamp($ts);
  568. }
  569. if ($modify) $dt->modify($modify);
  570. $bodStr = $dt->format('Y-m-d 00:00:00');
  571. $bodObj = \DateTime::createFromFormat('Y-m-d H:i:s', $bodStr, $returnAtomDate ? new \DateTimeZone('UTC') : new \DateTimeZone('Europe/Berlin'));
  572. if ($returnAtomDate) return $bodObj->format(\DateTimeInterface::ATOM);
  573. return (int) $bodObj->getTimestamp();
  574. }
  575. private function endOfDay($ts, $modify = null, $isAtomDate = false, $returnAtomDate = false)
  576. {
  577. $dt = null;
  578. if ($isAtomDate) {
  579. if (is_numeric($ts)) {
  580. $ts = $ts + 0;
  581. $dt = new \DateTime();
  582. $dt->setTimezone(new \DateTimeZone('UTC'));
  583. $dt->setTimestamp($ts);
  584. } else {
  585. $dt = new \DateTime($ts);
  586. $dt->setTimezone(new \DateTimeZone('UTC'));
  587. }
  588. } else {
  589. $dt = new \DateTime(null, new \DateTimeZone('Europe/Berlin'));
  590. $dt->setTimestamp($ts);
  591. }
  592. if ($modify) $dt->modify($modify);
  593. $eodStr = $dt->format('Y-m-d 23:59:59');
  594. $eodObj = \DateTime::createFromFormat('Y-m-d H:i:s', $eodStr, $returnAtomDate ? new \DateTimeZone('UTC') : new \DateTimeZone('Europe/Berlin'));
  595. if ($returnAtomDate) return $eodObj->format(\DateTimeInterface::ATOM);
  596. return (int) $eodObj->getTimestamp();
  597. }
  598. function array_search_by_key_recursive($needle, array $haystack, &$return)
  599. {
  600. foreach ($haystack as $k => $v) {
  601. if (is_array($v)) {
  602. $this->array_search_by_key_recursive($needle, $v, $return);
  603. } else {
  604. if ($k === $needle) {
  605. $return[] = $v;
  606. }
  607. }
  608. }
  609. }
  610. private function findFirstAppearingElementByType($type, $subs, $typeKey = "type")
  611. {
  612. foreach ($subs as $v) {
  613. if ($v[$typeKey] == $type) return $v;
  614. }
  615. return null;
  616. }
  617. private function checkOrReduceDescriptionLength($desc, $len)
  618. {
  619. $newStr = '';
  620. $desc = $this->removeLinebreaks($desc);
  621. if (is_string($desc) && mb_strlen($desc) < $len) {
  622. $newStr = $desc;
  623. } else {
  624. $newStr = substr($desc, 0, $len);
  625. $pos = strrpos($newStr, ' ');
  626. $newStr = substr($desc, 0, $pos);
  627. }
  628. return $newStr;
  629. }
  630. private function constructMetaDescription($abstract = '', $content, $isOgTag = false)
  631. {
  632. $desc = '';
  633. if ($abstract != '') $desc = $abstract;
  634. if (!$desc || $desc == '') {
  635. $desc = $this->findFirstAppearingElementByType("introtext", $content["subElements"]);
  636. if ($desc)
  637. $desc = $desc["attributes"]["text"];
  638. }
  639. if (!$desc || $desc == '')
  640. return '';
  641. if ($isOgTag)
  642. return "<meta property=\"og:description\" content=\"" . $this->checkOrReduceDescriptionLength($desc, 320) . "\">";
  643. return "<meta name=\"description\" content=\"" . $this->checkOrReduceDescriptionLength($desc, 320) . "\">";
  644. }
  645. private function constructMetaDescriptionForBlogPage($text = '', $content, $isOgTag = false)
  646. {
  647. $desc = '';
  648. if ($text != '') $desc = $text;
  649. if (!$desc || $desc == '') {
  650. $desc = $this->findFirstAppearingElementByType('typo3_paragraph', $content["subElements"]);
  651. if ($desc)
  652. $desc = strip_tags($desc["attributes"]["text"]);
  653. }
  654. if (!$desc || $desc == '')
  655. return '';
  656. if ($isOgTag)
  657. return "<meta property=\"og:description\" content=\"" . $this->checkOrReduceDescriptionLength($desc, 165) . ' …' . "\">";
  658. return "<meta name=\"description\" content=\"" . $this->checkOrReduceDescriptionLength($desc, 165) . ' …' . "\">";
  659. }
  660. private function constructSearchableText($content, $minimum = true)
  661. {
  662. $cr = [];
  663. if (!$minimum) {
  664. $this->array_search_by_key_recursive("text", $content["pageData"]["content"], $cr);
  665. } else {
  666. //$roof = $this->findFirstAppearingElementByType("roof", $content["pageData"]["content"]["subElements"]);
  667. //if($roof) $cr[] = $roof["attributes"]["text"];
  668. $h1 = $this->findFirstAppearingElementByType("h1", $content["pageData"]["content"]["subElements"]);
  669. if ($h1) {
  670. $cr[] = $h1["attributes"]["roof"];
  671. $cr[] = $h1["attributes"]["text"];
  672. }
  673. $introtext = $this->findFirstAppearingElementByType("introtext", $content["pageData"]["content"]["subElements"]);
  674. if ($introtext) $cr[] = $introtext["attributes"]["text"];
  675. }
  676. $cr = preg_replace("/\r|\n/", " ", strip_tags(implode(" ", $cr)));
  677. return $cr;
  678. }
  679. private function constructStatus($post)
  680. {
  681. $publicationType = null;
  682. switch ($post["red_status"]) {
  683. case "-1": //neu angelegt
  684. case "1": //in Bearbeitung
  685. case "2": //vorbereitet
  686. case "3": //geprüft
  687. case "21": //gesperrt
  688. case "22": //archiviert
  689. $publicationType = "preview";
  690. break;
  691. case "11": //frei
  692. case "12": //online
  693. $publicationType = "live";
  694. break;
  695. default:
  696. break;
  697. }
  698. $status = array(
  699. 'isLiveFrom' => -1,
  700. 'isLiveTill' => -1,
  701. 'publicationType' => $publicationType,
  702. 'orderStatus' => $post['orderStatus'],
  703. 'date-updated' => ($post['orderStatus'] === 'neu') ? $post['starttime'] : (($post['orderStatus'] === 'aktualisiert') ? $post['red_end'] : ''),
  704. 'seo' => array(
  705. 'sitemap_changefreq' => $post['sitemap_changefreq'],
  706. 'sitemap_priority' => $post['sitemap_priority'],
  707. 'sitemap_lastmod' => time(),
  708. ),
  709. );
  710. if ($post['starttime'] != 0) {
  711. $status['isLiveFrom'] = $this->startOfDay($post['starttime']);
  712. }
  713. if ($post['endtime'] != 0) {
  714. $status['isLiveTill'] = $this->endOfDay($post['endtime']);
  715. }
  716. if ($post['doktype'] == '101') {
  717. $status['blog_author'] = $post['blog_author'];
  718. $status['blog_category'] = $post['blog_category'];
  719. }
  720. if ($post['doktype'] == '100') {
  721. $status['event_state'] = $post['event_state'];
  722. $status['event_category'] = $post['event_category'];
  723. }
  724. if ($post['doktype'] == '104') {
  725. $status['video_category'] = $post['event_category'];
  726. }
  727. //$this->log($status, false);
  728. return $status;
  729. }
  730. private function constructRedirects($pageData)
  731. {
  732. $redirects = array(
  733. '/?id=' . $pageData['uid']
  734. );
  735. //TODO: Add a single \r to match old Macs line breaks?
  736. foreach (preg_split('/\n|\r\n?/', $pageData['redirects']) as $redir) {
  737. $redir = trim($redir);
  738. if ($redir == '') continue;
  739. $redirects[] = $redir;
  740. }
  741. return $redirects;
  742. }
  743. private function convertStringToTechnicalName($string)
  744. {
  745. $string = $this->sanitizeString($string);
  746. $string = preg_replace('/-/', '', $string);
  747. return strtoupper($string);
  748. }
  749. private function sanitizeString($string)
  750. {
  751. $table = array(
  752. 'Š' => 'S', 'š' => 's', 'Đ' => 'Dj', 'đ' => 'dj', 'Ž' => 'Z', 'ž' => 'z', 'Č' => 'C', 'č' => 'c', 'Ć' => 'C', 'ć' => 'c',
  753. 'À' => 'A', 'Á' => 'A', 'Â' => 'A', 'Ã' => 'A', 'Ä' => 'AE', 'Å' => 'A', 'Æ' => 'A', 'Ç' => 'C', 'È' => 'E', 'É' => 'E',
  754. 'Ê' => 'E', 'Ë' => 'E', 'Ì' => 'I', 'Í' => 'I', 'Î' => 'I', 'Ï' => 'I', 'Ñ' => 'N', 'Ò' => 'O', 'Ó' => 'O', 'Ô' => 'O',
  755. 'Õ' => 'O', 'Ö' => 'OE', 'Ø' => 'O', 'Ù' => 'U', 'Ú' => 'U', 'Û' => 'U', 'Ü' => 'UE', 'Ý' => 'Y', 'Þ' => 'B', 'ß' => 'Ss',
  756. 'à' => 'a', 'á' => 'a', 'â' => 'a', 'ã' => 'a', 'ä' => 'ae', 'å' => 'a', 'æ' => 'a', 'ç' => 'c', 'è' => 'e', 'é' => 'e',
  757. 'ê' => 'e', 'ë' => 'e', 'ì' => 'i', 'í' => 'i', 'î' => 'i', 'ï' => 'i', 'ð' => 'o', 'ñ' => 'n', 'ò' => 'o', 'ó' => 'o',
  758. 'ô' => 'o', 'õ' => 'o', 'ö' => 'oe', 'ø' => 'o', 'ü' => 'ue', 'ù' => 'u', 'ú' => 'u', 'û' => 'u', 'ý' => 'y', 'ý' => 'y',
  759. 'þ' => 'b', 'ÿ' => 'y', 'Ŕ' => 'R', 'ŕ' => 'r', '/' => ''
  760. );
  761. $x = preg_replace(array('/\s{2,}/', '/[\t\n]/'), ' ', $string);
  762. $x = trim(strtr($x, $table));
  763. $x = preg_replace('/[^A-Za-z0-9]+/', ' ', $x);
  764. $x = trim($x);
  765. $x = preg_replace('/ {1,}/', '-', $x);
  766. $x = trim($x, "-");
  767. return $x;
  768. }
  769. private function constructSlug($pid)
  770. {
  771. $postStatement = $this->pageQueryBuilder
  772. ->select('slug')
  773. ->from('pages')
  774. ->setMaxResults(1)
  775. ->where(
  776. $this->pageQueryBuilder->expr()->eq('uid', $this->pageQueryBuilder->createNamedParameter($pid))
  777. )
  778. ->execute();
  779. $postSlug = $postStatement->fetchAll();
  780. $postSlug = $postSlug[0];
  781. return $postSlug ? $postSlug["slug"] : null;
  782. }
  783. private function constructBreadCrumb($rootline, $page, $pageType)
  784. {
  785. $breadCrumb = $this->createContentElement('breadcrumbs');
  786. foreach ($rootline as $post) {
  787. if ($post['doktype'] == 254) continue;
  788. if ($post['is_siteroot'] == 1) continue;
  789. if ($page['uid'] == $post['uid'] && ($pageType == "blogger-page" || $pageType == "video-page"))
  790. $tit = $post['title'];
  791. else
  792. if ($post['use_roof_as_breadcrumb_text'] == 0)
  793. $tit = $post['title'];
  794. else
  795. $tit = $post['roof'] && $post['roof'] != '' ? $post['roof'] : $post['title'];
  796. $breadCrumb['subElements'][] = $this->createContentElement(
  797. 'breadcrumblink',
  798. array(
  799. 'title' => $tit,
  800. 'alt' => $tit,
  801. 'text' => $tit,
  802. 'href' => $this->constructSlug($post['uid'])
  803. )
  804. );
  805. }
  806. return $breadCrumb;
  807. }
  808. private function processData($dbReference, &$processedData, &$processedImages)
  809. {
  810. $isSidebar = $dbReference['colPos'] == 1;
  811. if ($isSidebar)
  812. $subs = &$processedData['pageData']['sidebar']['subElements'];
  813. else
  814. $subs = &$processedData['pageData']['content']['subElements'];
  815. $ffs = GeneralUtility::makeInstance(FlexFormService::class);
  816. $flex = $ffs->convertFlexFormContentToArray($dbReference['pi_flexform']);
  817. // print_r($flex);
  818. // die();
  819. switch ($dbReference['CType']) {
  820. case "mrm_be_cm_postimage":
  821. break;
  822. case "mrm_be_cm_voting":
  823. $s = $this->createContentElement(
  824. "voting",
  825. array(
  826. "labels" => array(
  827. "startbutton" => $flex["startbuttontext"],
  828. ),
  829. "resultscreen" => array(
  830. "headingTop" => $flex["resultheadingtop"],
  831. ),
  832. ),
  833. array(
  834. "items" => array(array(
  835. "text" => $flex["questiontext"],
  836. "type" => $flex["questiontype"] == "1" || $flex["questiontype"] == 1 ? "multi" : "single",
  837. "answers" => array_values(array_map(function ($x) {
  838. return array("text" => $x["settings"]["answer"]["text"], "value" => null);
  839. }, $flex["dynamicComponents"]))
  840. )),
  841. "validation" => array(
  842. "alreadyVoted" => $this->createContentElement("injection", array("type" => "voting-alreadyVoted")),
  843. "chartData" => $this->createContentElement("injection", array("type" => "voting-chartData|")),
  844. ),
  845. )
  846. );
  847. $cntr = 0;
  848. foreach ($s["attributes"]["items"][0]["answers"] as &$a) {
  849. $a["value"] = $cntr;
  850. $cntr++;
  851. }
  852. $s["attributes"]["validation"]["chartData"]["props"]["type"] .= $cntr;
  853. $processedData["injections"][] = "voting-alreadyVoted";
  854. $processedData["injections"][] = "voting-chartData|" . $cntr;
  855. $subs[] = $s;
  856. $processedData["status"]["hasVoting"] = true;
  857. break;
  858. case "mrm_be_cm_checklist-todo":
  859. $elements = $this->createContentElement(
  860. "checklist-todo",
  861. array(
  862. "headlines" => array(
  863. "main" => $flex["headline_main"],
  864. "done" => $flex["headline_done"],
  865. "not_done" => $flex["headline_not_done"],
  866. ),
  867. "controls" => array(
  868. "print" => $flex["enable_print"] == "1",
  869. "pdf" => $flex["enable_pdf"] == "1",
  870. ),
  871. "labels" => array(
  872. "submit" => $flex["label_submit"],
  873. "print" => $flex["label_print"],
  874. "pdf" => $flex["label_pdf"],
  875. ),
  876. "items" => (function ($flex, $dbReference) {
  877. $itms = array();
  878. $imgs = array();
  879. if ($flex["images"] != "0" && $flex["images"] != 0) {
  880. $imgs = $this->processImagesTTContent($dbReference, 'mrm_be_cm_contentimage', 'tt_content', 'image', 'uid', true, true);
  881. }
  882. foreach ($flex["items"] as $itm) {
  883. $i = $itm["item"];
  884. $a = array();
  885. if ($i["text"] != "") $a["text"] = $i["text"];
  886. if ($i["contains_image"] == "1" || $i["contains_image"] == 1) {
  887. $im = array_shift($imgs);
  888. if (isset($im)) $a["img"] = $im;
  889. }
  890. $itms[] = $a;
  891. }
  892. return $itms;
  893. })($flex, $dbReference),
  894. )
  895. );
  896. $subs[] = $elements;
  897. $processedData["status"]["hasChecklist"] = true;
  898. break;
  899. case "mrm_be_cm_checklist_todo_multi":
  900. $elements = $this->createContentElement(
  901. 'checklist-todo-multi',
  902. array(
  903. "texts" => array(
  904. "mainhead" => $flex['mainhead'],
  905. "description" => $flex['description'],
  906. ),
  907. "controls" => array(
  908. "print" => $flex["enable_print"] == "1",
  909. "pdf" => $flex["enable_pdf"] == "1",
  910. ),
  911. "labels" => array(
  912. "print" => $flex["label_print"],
  913. "pdf" => $flex["label_pdf"],
  914. ),
  915. "items" => (function ($flex) {
  916. $itms = [];
  917. $a = array();
  918. foreach ($flex['items'] as $itm) {
  919. if (is_array($itm)) {
  920. $a['head'] = $itm['item']['head'];
  921. $list = $itm['item']['list'];
  922. $doc = new \DOMDocument('1.0', 'utf-8');
  923. $doc->loadHTML('<?xml encoding="UTF-8">' . $list);
  924. $listitems = $doc->getElementsByTagName('li');
  925. $list = [];
  926. foreach ($listitems as $node) {
  927. foreach ($node->childNodes as $child) {
  928. $list[] = array('text' => $child->nodeValue);
  929. }
  930. $a['items'] = $list;
  931. }
  932. }
  933. $itms[] = $a;
  934. }
  935. return $itms;
  936. })($flex),
  937. ),
  938. );
  939. $subs[] = $elements;
  940. break;
  941. case "mrm_be_cm_checklist-input":
  942. $items = array();
  943. $dynContentCounter = 0;
  944. while (true) {
  945. $dynContentCounter++;
  946. if (!isset($flex["label" . $dynContentCounter])) break;
  947. if ($flex["label" . $dynContentCounter] === "") continue;
  948. $label = array(
  949. "label" => $flex["label" . $dynContentCounter]
  950. );
  951. $items[] = $label;
  952. }
  953. $elements = $this->createContentElement(
  954. "checklist-input",
  955. array(
  956. "headlines" => array(
  957. "main" => $flex["headline_main"],
  958. "results" => $flex["headline_result"],
  959. ),
  960. "intro" => $flex["intro"],
  961. "controls" => array(
  962. "print" => $flex["enable_print"] == "1",
  963. "pdf" => $flex["enable_pdf"] == "1",
  964. ),
  965. "labels" => array(
  966. "submit" => $flex["label_submit"],
  967. "print" => $flex["label_print"],
  968. "pdf" => $flex["label_pdf"],
  969. ),
  970. "items" => $items,
  971. )
  972. );
  973. $subs[] = $elements;
  974. $processedData["status"]["hasChecklist"] = true;
  975. break;
  976. case "mrm_be_cm_checklist-scale":
  977. $items = array();
  978. $dynContentCounter = 0;
  979. while (true) {
  980. $dynContentCounter++;
  981. if (!isset($flex["label" . $dynContentCounter])) break;
  982. if ($flex["label" . $dynContentCounter] === "") continue;
  983. $label = array(
  984. "label" => $flex["label" . $dynContentCounter]
  985. );
  986. $items[] = $label;
  987. }
  988. $elements = $this->createContentElement(
  989. "checklist-scale",
  990. array(
  991. "headlines" => array(
  992. "main" => $flex["headline_main"],
  993. "results" => $flex["headline_result"],
  994. ),
  995. "intro" => $flex["intro"],
  996. "maxPoints" => (int)$flex["maxpoints"],
  997. "controls" => array(
  998. "print" => $flex["enable_print"] == "1",
  999. "pdf" => $flex["enable_pdf"] == "1",
  1000. ),
  1001. "labels" => array(
  1002. "nextbutton" => $flex["label_nextbutton"],
  1003. "lastbutton" => $flex["label_lastbutton"],
  1004. "print" => $flex["label_print"],
  1005. "pdf" => $flex["label_pdf"],
  1006. ),
  1007. "items" => $items,
  1008. )
  1009. );
  1010. $subs[] = $elements;
  1011. $processedData["status"]["hasChecklist"] = true;
  1012. break;
  1013. case "mrm_be_cm_checklist-radiorange":
  1014. $items = array();
  1015. $dynContentCounter = 0;
  1016. while (true) {
  1017. $dynContentCounter++;
  1018. if (!isset($flex["pointsFrom" . $dynContentCounter])) break;
  1019. if ($flex["pointsFrom" . $dynContentCounter] === "") continue;
  1020. $item = array(
  1021. "pointsFrom" => (int)$flex["pointsFrom" . $dynContentCounter],
  1022. "pointsTo" => (int)$flex["pointsTo" . $dynContentCounter],
  1023. "validationText" => $flex["validationText" . $dynContentCounter]
  1024. );
  1025. if ($flex["image" . $dynContentCounter] == 1) {
  1026. $images = $this->processImagesTTContent($dbReference, 'mrm_be_cm_checklist-radiorange', 'tt_content', 'flex_image_' . $dynContentCounter, 'uid', false, true);
  1027. $images = $images[0];
  1028. $images["src"] = $images["sources"]["img"];
  1029. unset($images["sources"]);
  1030. $item["img"] = $images;
  1031. }
  1032. $items[] = $item;
  1033. }
  1034. $elements = $this->createContentElement(
  1035. "checklist-radiorange",
  1036. array(
  1037. "headlines" => array(
  1038. "main" => $flex["headline_main"],
  1039. ),
  1040. "intro" => $flex["intro"],
  1041. "validation" => array(
  1042. "maxPoints" => (int)$flex["maxpoints"],
  1043. "items" => $items,
  1044. )
  1045. )
  1046. );
  1047. $subs[] = $elements;
  1048. $processedData["status"]["hasChecklist"] = true;
  1049. break;
  1050. case "mrm_be_cm_checklist-yesmaybeno":
  1051. $items = array();
  1052. foreach ($flex["dynamicComponents"] as $component) {
  1053. foreach ($component as $key => $value) {
  1054. $item = array(
  1055. "heading" => $value["headline"],
  1056. "text" => $value["text"]
  1057. );
  1058. }
  1059. if ($item) {
  1060. $items[] = $item;
  1061. }
  1062. unset($value);
  1063. }
  1064. $choices = array();
  1065. $choice_yes = array(
  1066. "label" => $flex["choice_value_yes"],
  1067. "value" => "yes"
  1068. );
  1069. $choice_maybe = array(
  1070. "label" => $flex["choice_value_maybe"],
  1071. "value" => "maybe"
  1072. );
  1073. $choice_no = array(
  1074. "label" => $flex["choice_value_no"],
  1075. "value" => "no"
  1076. );
  1077. $choices[] = $choice_yes;
  1078. $choices[] = $choice_maybe;
  1079. $choices[] = $choice_no;
  1080. $elements = $this->createContentElement(
  1081. "checklist-yesmaybeno",
  1082. array(
  1083. "headlines" => array(
  1084. "main" => $flex["headline_main"],
  1085. "results" => $flex["headline_result"],
  1086. ),
  1087. "intro" => $flex["intro"],
  1088. "controls" => array(
  1089. "print" => $flex["enable_print"] == "1",
  1090. "pdf" => $flex["enable_pdf"] == "1",
  1091. ),
  1092. "labels" => array(
  1093. "nextbutton" => $flex["label_nextbutton"],
  1094. "lastbutton" => $flex["label_lastbutton"],
  1095. "print" => $flex["label_print"],
  1096. "pdf" => $flex["label_pdf"],
  1097. ),
  1098. "choices" => $choices,
  1099. "items" => $items,
  1100. )
  1101. );
  1102. $subs[] = $elements;
  1103. $processedData["status"]["hasChecklist"] = true;
  1104. break;
  1105. case "mrm_be_cm_picturechoice":
  1106. $s = $this->createContentElement(
  1107. "picturechoice",
  1108. array(
  1109. "labels" => array(
  1110. "startbutton" => $flex["startbuttontext"],
  1111. "nextbutton" => $flex["nextbuttontext"],
  1112. "lastbutton" => $flex["lastbuttontext"],
  1113. "question" => $flex["question"],
  1114. "repeatbutton" => $flex["repeatbuttontext"],
  1115. ),
  1116. "resultscreen" => array(
  1117. "headingTop" => $flex["resultheadingtop"],
  1118. "end" => $flex["thanks"]
  1119. ),
  1120. "isRestartAble" => $flex["isRestartAble"] == 1 || $flex["isRestartAble"] == "1",
  1121. ),
  1122. array(
  1123. "items" => (function ($flex, $dbReference) {
  1124. $ret = array();
  1125. for ($i = 1; $i <= 3; $i++) {
  1126. $item = array();
  1127. for ($j = 1; $j <= 5; $j++) {
  1128. if ($flex["image" . $i . "_" . $j] == "1") {
  1129. $img = $this->processImagesTTContent($dbReference, 'mrm_be_cm_picturechoice', 'tt_content', 'flex_image_' . $i . "_" . $j, 'uid', false, true);
  1130. $img = $img[0];
  1131. $item[] = array(
  1132. "image" => $img,
  1133. "points" => (int) $flex["pointsOfImage" . $i . "_" . $j]
  1134. );
  1135. }
  1136. }
  1137. if (sizeof($item) > 0)
  1138. $ret[] = $item;
  1139. }
  1140. return $ret;
  1141. })($flex, $dbReference),
  1142. "validation" => array(
  1143. "maxPoints" => (int)$flex["maxpoints"],
  1144. "alreadyReachedPoints" => $this->createContentElement("injection", array("type" => "picturechoice-alreadyReachedPoints")),
  1145. "items" => array_map(
  1146. function ($i) {
  1147. $i["validationText"] = $this->checkTextForInternalLinks($i["validationText"], $dbReference, $processedData);
  1148. $i["pointsFrom"] = (int)$i["pointsFrom"];
  1149. $i["pointsTo"] = (int)$i["pointsTo"];
  1150. return $i;
  1151. },
  1152. array_filter(array_values(array_map(function ($v) {
  1153. return $v['settings']['validation'];
  1154. }, $flex["validations"])), function ($x) {
  1155. return $x != null;
  1156. })
  1157. //TODO: Core: Error handler (BE): PHP Warning: array_filter() expects parameter 1 (or 2 in another error message) to be array, null given in /var/www/html/typo3conf/ext/mrm_be/Classes/Hooks/TCE/TCEMainHook.php line 830
  1158. ),
  1159. ),
  1160. )
  1161. );
  1162. $processedData["injections"][] = "picturechoice-alreadyReachedPoints";
  1163. $subs[] = $s;
  1164. $processedData["status"]["hasPicturechoice"] = true;
  1165. break;
  1166. case "mrm_be_cm_quiz":
  1167. $s = $this->createContentElement(
  1168. "quiz",
  1169. array(
  1170. "labels" => array(
  1171. "startbutton" => $flex["startbuttontext"],
  1172. "nextbutton" => $flex["nextbuttontext"],
  1173. "lastbutton" => $flex["lastbuttontext"],
  1174. "question" => $flex["question"],
  1175. "repeatbutton" => $flex["repeatbuttontext"],
  1176. ),
  1177. "resultscreen" => array(
  1178. "headingTop" => $flex["resultheadingtop"],
  1179. "headingSub" => $flex["resultheadingsub"],
  1180. "validation" => $flex["validationstr"],
  1181. "end" => $flex["thanks"]
  1182. ),
  1183. "isRestartAble" => $flex["isRestartAble"] == 1 || $flex["isRestartAble"] == "1",
  1184. ),
  1185. array(
  1186. "items" => array_values(array_map(function ($v) {
  1187. $questionType = null;
  1188. $quest = $v['settings']['question'];
  1189. if (!isset($quest)) {
  1190. $quest = $v['settings']['question_multi'];
  1191. $questionType = "multi";
  1192. }
  1193. if (isset($quest["additional_text"]) && $quest["additional_text"] != "") {
  1194. $quest["text"] = $quest["text"] . " (" . $quest["additional_text"] . ")";
  1195. unset($quest["additional_text"]);
  1196. }
  1197. if ($questionType) $quest["type"] = $questionType;
  1198. unset($quest["rightanswer"]);
  1199. $i = 0;
  1200. $quest["answers"] = array();
  1201. while (1) {
  1202. $i++;
  1203. if (!isset($quest["answertext" . $i])) break;
  1204. if ($quest["answertext" . $i] === "") continue;
  1205. $quest["answers"][] = array("text" => $quest["answertext" . $i], "points" => (int)$quest["answerpoints" . $i]);
  1206. unset($quest["answertext" . $i]);
  1207. unset($quest["answerpoints" . $i]);
  1208. }
  1209. /* NOTE: DEPRECATED BY SINGLE INPUTS
  1210. $quest["answers"] = array_map(function($x) {
  1211. $x = explode("|", $x);
  1212. $x = array("text" => $x[0], "points" => (int)$x[1]);
  1213. return $x;
  1214. }, explode("\n", $quest["answers"]));
  1215. */
  1216. return $quest;
  1217. }, $flex["dynamicComponents"])),
  1218. "validation" => array(
  1219. "maxPoints" => (int)$flex["maxpoints"],
  1220. "averagePoints" => $this->createContentElement("injection", array("type" => "quiz-averagePoints")),
  1221. "alreadyReachedPoints" => $this->createContentElement("injection", array("type" => "quiz-alreadyReachedPoints")),
  1222. "items" => array_map(
  1223. function ($i) {
  1224. $i["validationText"] = $this->checkTextForInternalLinks($i["validationText"], $dbReference, $processedData);
  1225. return $i;
  1226. },
  1227. array_filter(array_values(array_map(function ($v) {
  1228. return $v['settings']['validation'];
  1229. }, $flex["dynamicComponents2"])), function ($x) {
  1230. return $x != null;
  1231. })
  1232. ),
  1233. ),
  1234. )
  1235. );
  1236. $processedData["injections"][] = "quiz-averagePoints";
  1237. $processedData["injections"][] = "quiz-alreadyReachedPoints";
  1238. $subs[] = $s;
  1239. $processedData["status"]["hasQuiz"] = true;
  1240. break;
  1241. case "mrm_be_cm_animation":
  1242. $script = $flex["script"];
  1243. if ($flex["staticfiles"] != "0" && $flex["staticfiles"] != 0) {
  1244. $imgs = $this->processImagesTTContent($dbReference);
  1245. foreach ($imgs as $idx => $v) {
  1246. $script = implode("#cdnurl#/" . $v["sources"]["passthru"], explode("%ASSET_" . ($idx + 1) . "%", $script));
  1247. }
  1248. }
  1249. $subs[] = $this->createContentElement("animation", array("addJQuery" => $flex["addJQuery"] == 1 || $flex["addJQuery"] == "1"), array("script" => $script));
  1250. $processedData["status"]["hasAnimation"] = true;
  1251. break;
  1252. case "mrm_be_cm_injection":
  1253. $subs[] = $this->createContentElement("injection", array("type" => $flex["text"]));
  1254. $processedData["injections"][] = $flex["text"];
  1255. break;
  1256. case "mrm_be_cm_roof":
  1257. $subs[] = $this->createContentElement("roof", array(), array("text" => $flex["text"]));
  1258. break;
  1259. case "mrm_be_cm_h1":
  1260. $subs[] = $this->createContentElement("h1", array(), array("text" => $flex["text"]));
  1261. break;
  1262. case "mrm_be_cm_h2":
  1263. $subs[] = $this->createContentElement("h2", array(), array("text" => $flex["text"]));
  1264. break;
  1265. case "mrm_be_cm_h3":
  1266. $subs[] = $this->createContentElement("h3", array(), array("text" => $flex["text"]));
  1267. break;
  1268. case "mrm_be_cm_introtext":
  1269. $text = preg_replace("/\n/", "<br />", $flex["text"]);
  1270. $subs[] = $this->createContentElement("introtext", array(), array("text" => $text));
  1271. break;
  1272. case "mrm_be_cm_button":
  1273. $href = $this->parseFlexFormLink($flex["button"], $dbReference, $processedData);
  1274. $buttonType = ($flex['buttonType'] == "0") ? 'button-link' : 'button-scream';
  1275. $button = $this->createContentElement("button", array('buttonType' => $buttonType), array("text" => $flex["text"], "href" => $href["href"], "target" => $href["target"]));
  1276. $subs[] = $button;
  1277. break;
  1278. case "mrm_be_cm_html":
  1279. $subs[] = $this->createContentElement("html", array(), array("text" => $flex["html"]));
  1280. break;
  1281. case "mrm_be_cm_heroimage":
  1282. $props = $this->processImagesTTContent($dbReference)[0];
  1283. $props["type"] = "typo3_hero";
  1284. $subs[] = $this->createContentElement("image", $props);
  1285. break;
  1286. case "mrm_be_cm_contentimage":
  1287. $props = $this->processImagesTTContent($dbReference)[0];
  1288. $props["type"] = "typo3_content";
  1289. $subs[] = $this->createContentElement("image", $props);
  1290. break;
  1291. case "mrm_be_cm_publication":
  1292. $imgprops = $this->processImagesTTContent($dbReference, 'mrm_be_cm_publication')[0];
  1293. $imgprops["type"] = "typo3_publication";
  1294. $publication = $this->createContentElement(
  1295. "publication",
  1296. array(
  1297. "starttime" => $this->startOfDay($flex['starttime']),
  1298. "endtime" => $this->endOfDay($flex['endtime']),
  1299. "issuekey" => $flex['issuekey'],
  1300. ),
  1301. array(
  1302. "image" => $imgprops,
  1303. "number" => $flex["issuenumber"],
  1304. "title" => $flex["issuetitle"],
  1305. "headline" => $flex["issueheadline"],
  1306. "link" => $this->parseFlexFormLink($flex["htmllink"], $dbReference, $processedData),
  1307. "pdf" => $this->parseFlexFormLink($flex["pdflink"], $dbReference, $processedData),
  1308. )
  1309. );
  1310. $subs[] = $publication;
  1311. break;
  1312. case "mrm_be_cm_rawimage":
  1313. $props = $this->processImagesTTContent($dbReference)[0];
  1314. $props["type"] = "typo3_raw";
  1315. $subs[] = $this->createContentElement("image", $props);
  1316. break;
  1317. case "mrm_be_cm_movingimagesvideo":
  1318. $subs[] = $this->createContentElement(
  1319. "movingimagesvideo",
  1320. array(
  1321. "hasNoticeForCrossPromotion" => $flex["hasNoticeForCrossPromotion"] == 1,
  1322. "hasNoticeForAccessibility" => $flex["hasNoticeForAccessibility"] == 1
  1323. ),
  1324. array("vid" => $flex["vid"])
  1325. );
  1326. break;
  1327. case "mrm_be_cm_paragraph":
  1328. $elements = $this->checkText($flex["text"], $dbReference, $processedData, "typo3_paragraph");
  1329. $subs = array_merge($subs, $elements);
  1330. break;
  1331. case "mrm_be_cm_additionalinfobox":
  1332. case "mrm_be_cm_infobox":
  1333. case "mrm_be_cm_extra_infosbox":
  1334. $type = null;
  1335. $open = null;
  1336. $noAutoOpen = null;
  1337. if ($dbReference['CType'] == "mrm_be_cm_additionalinfobox") $type = "typo3_additionalinfobox";
  1338. elseif ($dbReference['CType'] == "mrm_be_cm_infobox") $type = "typo3_infobox";
  1339. else $type = "typo3_extrainfosbox";
  1340. if ($dbReference['CType'] == "mrm_be_cm_additionalinfobox" || $dbReference['CType'] == "mrm_me_cm_extra_infosbox") $open = true;
  1341. else $open = $flex["isInitialyOpen"] == "1";
  1342. if ($dbReference['CType'] == "mrm_be_cm_additionalinfobox" || $dbReference['CType'] == "mrm_be_cm_infobox") $headline = $flex["headline"];
  1343. elseif ($dbReference['CType'] == "mrm_be_cm_extra_infosbox") $headline = '';
  1344. $this->log('Headline: ' . $headline, true);
  1345. $sub = $this->createContentElement(
  1346. $type,
  1347. array("open" => $open, "noAutoOpen" => $flex["noAutoOpen"] == 1),
  1348. array("headline" => $flex["headline"])
  1349. );
  1350. if ($flex["image"] == "1") {
  1351. $props = $this->processImagesTTContent($dbReference, "mrm_be_cm_contentimage")[0];
  1352. $props["type"] = "typo3_content";
  1353. $sub["subElements"][] = $this->createContentElement("image", $props);
  1354. } else {
  1355. switch ($flex["icon"]) {
  1356. case "1":
  1357. $sub["attributes"]["icon"] = "stadtinfo_basics";
  1358. break;
  1359. case "2":
  1360. $sub["attributes"]["icon"] = "geschichte";
  1361. break;
  1362. case "3":
  1363. $sub["attributes"]["icon"] = "kultur_freizeit";
  1364. break;
  1365. case "4":
  1366. $sub["attributes"]["icon"] = "besonderheiten";
  1367. break;
  1368. case "5":
  1369. $sub["attributes"]["icon"] = "kosten_geld";
  1370. break;
  1371. case "6":
  1372. $sub["attributes"]["icon"] = "hochschulen";
  1373. break;
  1374. case "7":
  1375. $sub["attributes"]["icon"] = "studieren";
  1376. break;
  1377. }
  1378. }
  1379. if ($flex["dynamicComponents"] && sizeof($flex["dynamicComponents"]) > 0)
  1380. foreach ($flex["dynamicComponents"] as $comp) {
  1381. $stype = array_keys($comp['settings'])[0];
  1382. $elements = [];
  1383. switch ($stype) {
  1384. case "box":
  1385. $box = $this->createContentElement("boxwrapper");
  1386. $box["subElements"] = array_merge($box["subElements"], $this->checkText($comp['settings']['box']['boxheadline'], $dbReference, $processedData, "h3"));
  1387. $box["subElements"] = array_merge($box["subElements"], $this->checkText($comp['settings']['box']['boxtext'], $dbReference, $processedData, "typo3_paragraph"));
  1388. $elements = [$box];
  1389. break;
  1390. case "boxheadline":
  1391. $elements = $this->checkText($comp['settings'][$stype][$stype], $dbReference, $processedData, "h3");
  1392. //$this->log($elements, false);
  1393. break;
  1394. case "boxtext":
  1395. $elements = $this->checkText($comp['settings'][$stype][$stype], $dbReference, $processedData, "typo3_paragraph");
  1396. break;
  1397. case "html":
  1398. $elements = $this->checkText($comp['settings'][$stype][$stype], $dbReference, $processedData, "html");
  1399. break;
  1400. }
  1401. $sub["subElements"] = array_merge($sub["subElements"], $elements);
  1402. $this->log($sub["subElements"], false);
  1403. }
  1404. $subs[] = $sub;
  1405. break;
  1406. case "mrm_be_cm_extra_infosbox_prefilled":
  1407. $type = "typo3_extrainfosbox_prefilled";
  1408. $open = $flex["isInitialyOpen"] == "0" ? true : false;
  1409. $headline = $flex['headline'];
  1410. $elements = [];
  1411. $sub = $this->createContentElement(
  1412. $type,
  1413. array("open" => $open, "noAutoOpen" => $flex["noAutoOpen"] == 1),
  1414. array("headline" => $flex["headline"])
  1415. );
  1416. if ($flex["image"] == "1") {
  1417. $props = $this->processImagesTTContent($dbReference, "mrm_be_cm_contentimage")[0];
  1418. $props["type"] = "typo3_content";
  1419. $sub["subElements"][] = $this->createContentElement("image", $props);
  1420. } else {
  1421. switch ($flex["icon"]) {
  1422. case "1":
  1423. $sub["attributes"]["icon"] = "stadtinfo_basics";
  1424. break;
  1425. case "2":
  1426. $sub["attributes"]["icon"] = "geschichte";
  1427. break;
  1428. case "3":
  1429. $sub["attributes"]["icon"] = "kultur_freizeit";
  1430. break;
  1431. case "4":
  1432. $sub["attributes"]["icon"] = "besonderheiten";
  1433. break;
  1434. case "5":
  1435. $sub["attributes"]["icon"] = "kosten_geld";
  1436. break;
  1437. case "6":
  1438. $sub["attributes"]["icon"] = "hochschulen";
  1439. break;
  1440. case "7":
  1441. $sub["attributes"]["icon"] = "studieren";
  1442. break;
  1443. }
  1444. }
  1445. $cleaned = [];
  1446. $keys = ["healine", "image", "icon", "isInitialyOpen", "noAutoOpen"];
  1447. foreach ($keys as $k) {
  1448. unset($k);
  1449. }
  1450. foreach ($flex as $key => $val) {
  1451. if (strpos($key, 'headline') != false) {
  1452. $new_value = str_replace('headline', '', $key);
  1453. if (array_key_exists($new_value, $cleaned)) {
  1454. continue;
  1455. } else {
  1456. $cleaned[$new_value]['headline'] = $val;
  1457. }
  1458. } elseif (strpos($key, 'text') != false) {
  1459. $new_value = str_replace('text', '', $key);
  1460. if (!array_key_exists($new_value, $cleaned)) {
  1461. continue;
  1462. } else {
  1463. $cleaned[$new_value]['text'] = $val;
  1464. }
  1465. }
  1466. elseif (strpos($key, 'url') != false) {
  1467. $new_value = str_replace('url', '', $key);
  1468. if (!array_key_exists($new_value, $cleaned)) {
  1469. continue;
  1470. } else {
  1471. $cleaned[$new_value]['url'] = $val;
  1472. }
  1473. }
  1474. }
  1475. foreach($cleaned as $k => $val) {
  1476. foreach($val as $field) {
  1477. if(empty($field)) unset($cleaned[$k]);
  1478. }
  1479. }
  1480. foreach($cleaned as $key => $value) {
  1481. $box = $this->createContentElement("boxwrapper");
  1482. $box["subElements"] = array_merge($box["subElements"], $this->checkText($value['headline'], $dbReference, $processedData, "h3"));
  1483. $box["subElements"] = array_merge($box["subElements"], $this->checkText($value['text'], $dbReference, $processedData, "typo3_paragraph"));
  1484. $box["subElements"] = array_merge($box["subElements"], $this->checkText($value['url'], $dbReference, $processedData, "link"));
  1485. $elements[] = $box;
  1486. }
  1487. $sub["subElements"] = array_merge($sub["subElements"], $elements);
  1488. $subs[] = $sub;
  1489. break;
  1490. case "mrm_be_cm_foldout":
  1491. $sub = $this->createContentElement("typo3_foldout", array("open" => $flex["isInitialyOpen"] == "1", "noAutoOpen" => $flex["noAutoOpen"] == "1"), array("headline" => $flex["headline"]), array());
  1492. if ($flex["image"] == "1") {
  1493. $props = $this->processImagesTTContent($dbReference, "mrm_be_cm_contentimage")[0];
  1494. $props["type"] = "typo3_content";
  1495. $sub["subElements"][] = $this->createContentElement("image", $props);
  1496. } else {
  1497. switch ($flex["icon"]) {
  1498. case "1":
  1499. $sub["attributes"]["icon"] = "stadtinfo_basics";
  1500. break;
  1501. case "2":
  1502. $sub["attributes"]["icon"] = "geschichte";
  1503. break;
  1504. case "3":
  1505. $sub["attributes"]["icon"] = "kultur_freizeit";
  1506. break;
  1507. case "4":
  1508. $sub["attributes"]["icon"] = "besonderheiten";
  1509. break;
  1510. case "5":
  1511. $sub["attributes"]["icon"] = "kosten_geld";
  1512. break;
  1513. case "6":
  1514. $sub["attributes"]["icon"] = "hochschulen";
  1515. break;
  1516. case "7":
  1517. $sub["attributes"]["icon"] = "studieren";
  1518. break;
  1519. }
  1520. }
  1521. if ($flex["dynamicComponents"] && sizeof($flex["dynamicComponents"]) > 0)
  1522. foreach ($flex["dynamicComponents"] as $comp) {
  1523. $stype = array_keys($comp['settings'])[0];
  1524. $elements = $this->checkText($comp['settings'][$stype][$stype], $dbReference, $processedData, $stype == "paragraph" ? "typo3_paragraph" : ($stype == "headline" ? "h3" : $stype));
  1525. $sub["subElements"] = array_merge($sub["subElements"], $elements);
  1526. }
  1527. $subs[] = $sub;
  1528. break;
  1529. case "mrm_be_cm_newsletterabo":
  1530. $newsletterabo = $this->createContentElement("newsletterabo", array("cr_url" => $flex["cr_url"], "cr_url_BIZ" => $flex["cr_url_BIZ"]));
  1531. $subs[] = $newsletterabo;
  1532. break;
  1533. case "mrm_be_cm_linkage":
  1534. $subs[] = $this->createContentElement("sidebarheadline", array(), array("text" => $flex['headline']));
  1535. $banners = $this->createContentElement("sidebarbanners");
  1536. if ($flex['dynamicComponents'] && sizeof($flex['dynamicComponents']) > 0)
  1537. foreach ($flex['dynamicComponents'] as $banner) {
  1538. $banners["subElements"][] = $this->createContentElement("banner", $this->parseFlexFormLink($banner["settings"]["link"]["link"], $dbReference, $processedData));
  1539. }
  1540. $subs[] = $banners;
  1541. $subs[] = $this->createContentElement("injection", array("type" => "rubrik_content"));
  1542. $processedData["injections"][] = "rubrik_content";
  1543. $berufenet = $this->createContentElement("sidebarexternallinks", array("type" => "berufenet"), array("items" => []));
  1544. if ($flex['dynamicComponentsBerufeNet'] && sizeof($flex['dynamicComponentsBerufeNet']) != 0)
  1545. foreach ($flex['dynamicComponentsBerufeNet'] as $itm) {
  1546. $link = $this->parseFlexFormLink($itm["settings"]["link"]["link"], $dbReference, $processedData);
  1547. $link = '<a href="' . $link['href'] . '" target="' . $link['target'] . '" aria-label="Externer Link">' . $link['alt'] . '</a>';
  1548. $berufenet["attributes"]["items"][] = $link;
  1549. }
  1550. if (sizeof($berufenet["attributes"]["items"]) > 0) $subs[] = $berufenet;
  1551. $berufetv = $this->createContentElement("sidebarexternallinks", array("type" => "berufetv"), array("items" => []));
  1552. if ($flex['dynamicComponentsBerufeTV'] && sizeof($flex['dynamicComponentsBerufeTV']) != 0)
  1553. foreach ($flex['dynamicComponentsBerufeTV'] as $itm) {
  1554. $link = $this->parseFlexFormLink($itm["settings"]["link"]["link"], $dbReference, $processedData);
  1555. $link = '<a href="' . $link['href'] . '" target="' . $link['target'] . '" aria-label="Externer Link">' . $link['alt'] . '</a>';
  1556. $berufetv["attributes"]["items"][] = $link;
  1557. }
  1558. if (sizeof($berufetv["attributes"]["items"]) > 0) $subs[] = $berufetv;
  1559. $berufsausbildung = $this->createContentElement("sidebarexternallinks", array("type" => "berufsausbildung"), array("items" => []));
  1560. if ($flex['dynamicComponentsBerufsausbildung'] && sizeof($flex['dynamicComponentsBerufsausbildung']) != 0)
  1561. foreach ($flex['dynamicComponentsBerufsausbildung'] as $itm) {
  1562. $link = $this->parseFlexFormLink($itm["settings"]["link"]["link"], $dbReference, $processedData);
  1563. $link = '<a href="' . $link['href'] . '" target="' . $link['target'] . '" aria-label="Externer Link">' . $link['alt'] . '</a>';
  1564. $berufsausbildung["attributes"]["items"][] = $link;
  1565. }
  1566. if (sizeof($berufsausbildung["attributes"]["items"]) > 0) $subs[] = $berufsausbildung;
  1567. $ba_search = $this->createContentElement("sidebarexternallinks", array("type" => "ba_search"), array("items" => []));
  1568. if ($flex['dynamicComponentsBASearch'] && sizeof($flex['dynamicComponentsBASearch']) != 0)
  1569. foreach ($flex['dynamicComponentsBASearch'] as $itm) {
  1570. $link = $this->parseFlexFormLink($itm["settings"]["link"]["link"], $dbReference, $processedData);
  1571. $link = '<a href="' . $link['href'] . '" target="' . $link['target'] . '" aria-label="Externer Link">' . $link['alt'] . '</a>';
  1572. $ba_search["attributes"]["items"][] = $link;
  1573. }
  1574. if (sizeof($ba_search["attributes"]["items"]) > 0) $subs[] = $ba_search;
  1575. $studienwahl = $this->createContentElement("sidebarexternallinks", array("type" => "studienwahl"), array("items" => []));
  1576. if ($flex['dynamicComponentsStudienwahl'] && sizeof($flex['dynamicComponentsStudienwahl']) != 0)
  1577. foreach ($flex['dynamicComponentsStudienwahl'] as $itm) {
  1578. $link = $this->parseFlexFormLink($itm["settings"]["link"]["link"], $dbReference, $processedData);
  1579. $link = '<a href="' . $link['href'] . '" target="' . $link['target'] . '" aria-label="Externer Link">' . $link['alt'] . '</a>';
  1580. $studienwahl["attributes"]["items"][] = $link;
  1581. }
  1582. if (sizeof($studienwahl["attributes"]["items"]) > 0) $subs[] = $studienwahl;
  1583. if ($flex['enable_check_u']) {
  1584. $check_u = $this->createContentElement("extimgbutton", array("ariaLabel" => "Zur Check-U-Website", "href" => "https://www.arbeitsagentur.de/bildung/welche-ausbildung-welches-studium-passt", "target" => "_blank"), array("imgsrc" => "/public/media/ext-link_check_u.png"));
  1585. $subs[] = $check_u;
  1586. }
  1587. if ($flex['enable_studiencheck']) {
  1588. $studiencheck = $this->createContentElement("extimgbutton", array("ariaLabel" => "Zur Studiencheck-Website", "href" => "https://studiencheck.de/", "target" => "_blank"), array("imgsrc" => "/public/media/ext-link_studiencheck.png"));
  1589. $subs[] = $studiencheck;
  1590. }
  1591. break;
  1592. case "mrm_be_cm_homeheaderinfo":
  1593. $items = array();
  1594. for ($i = 1; $i <= 3; $i++) {
  1595. if ($flex["headline" . $i] != "" && $flex["text" . $i] != "") {
  1596. $item = array("heading" => $flex["headline" . $i], "text" => $flex["text" . $i]);
  1597. if ($flex["link" . $i] != "") {
  1598. $link = $this->parseFlexFormLink($flex["link" . $i], $dbReference, $processedData);
  1599. $item["href"] = $link["href"];
  1600. $item["linkTarget"] = $link["target"];
  1601. }
  1602. if ($flex["image" . $i] == "1") {
  1603. $imgs = $this->processImagesTTContent($dbReference, 'mrm_be_cm_homeheaderinfo', 'tt_content', 'flex_image_' . $i, 'uid', false);
  1604. $item["image"] = "#cdnurl#/" . $imgs[0]["sources"][$flex["imagesize" . $i]];
  1605. }
  1606. $items[] = $item;
  1607. }
  1608. }
  1609. $subs[] = $this->createContentElement("abimessages", array("data" => $items));
  1610. break;
  1611. case "mrm_be_cm_tileoverview":
  1612. $items = array();
  1613. for ($i = 1; $i <= 8; $i++) {
  1614. if ($flex["link" . $i] == "") continue;
  1615. $item = array();
  1616. $link = $this->parseFlexFormLink($flex["link" . $i], $dbReference, $processedData);
  1617. $item["href"] = $link["href"];
  1618. $item["linkTarget"] = $link["target"];
  1619. $item["text"] = $link["alt"];
  1620. if ($flex["image" . $i] == "1") {
  1621. $imgs = $this->processImagesTTContent($dbReference, 'mrm_be_cm_tileoverview', 'tt_content', 'flex_image_' . $i, 'uid', false);
  1622. $item["image"] = "#cdnurl#/" . $imgs[0]["sources"]["default_hero_lte600"];
  1623. }
  1624. $items[] = $item;
  1625. }
  1626. $subs[] = $this->createContentElement("tileoverview", array("items" => $items));
  1627. break;
  1628. case "mrm_be_cm_highlightbox":
  1629. $elements = $this->checkText($flex["text"], $dbReference, $processedData, "typo3_paragraph");
  1630. $subs[] = $this->createContentElement("highlightbox", array("icon" => $flex["icon"]), array(), $elements);
  1631. break;
  1632. case "mrm_be_cm_statementbox":
  1633. $items = array();
  1634. $dynContentCounter = 0;
  1635. while (1) {
  1636. $dynContentCounter++;
  1637. if (!isset($flex['text' . $dynContentCounter])) break;
  1638. if ($flex['text' . $dynContentCounter] === '' || $flex['name' . $dynContentCounter] === '') continue;
  1639. $item = array(
  1640. 'quote' => $flex['text' . $dynContentCounter],
  1641. 'cite' => $flex['name' . $dynContentCounter]
  1642. );
  1643. if ($flex['image' . $dynContentCounter] == 1) {
  1644. $imgs = $this->processImagesTTContent($dbReference, 'mrm_be_cm_statementbox', 'tt_content', 'flex_image_' . $dynContentCounter, 'uid', false);
  1645. $imgs = $imgs[0];
  1646. $imgs['src'] = "#cdnurl#/" . $imgs['sources']['img'];
  1647. unset($imgs['sources']);
  1648. $item['img'] = $imgs;
  1649. }
  1650. $items[] = $item;
  1651. }
  1652. $subs[] = $this->createContentElement('statementbox', array('items' => $items));
  1653. break;
  1654. case "mrm_be_cm_explorerbox":
  1655. $items = array();
  1656. $dynContentCounter = 0;
  1657. while (1) {
  1658. $dynContentCounter++;
  1659. if (!isset($flex['head' . $dynContentCounter])) break;
  1660. if ($flex['head' . $dynContentCounter] === '' || $flex['claim' . $dynContentCounter] === '' || $flex['image' . $dynContentCounter] == 0) continue;
  1661. $item = array(
  1662. 'heading' => $flex['head' . $dynContentCounter],
  1663. 'subheading' => $flex['claim' . $dynContentCounter],
  1664. 'text' => $flex['text' . $dynContentCounter]
  1665. );
  1666. if ($flex['image' . $dynContentCounter] == 1) {
  1667. $imgs = $this->processImagesTTContent($dbReference, 'mrm_be_cm_explorerbox', 'tt_content', 'flex_image_' . $dynContentCounter, 'uid', false);
  1668. $imgs = $imgs[0];
  1669. $imgs['src'] = "#cdnurl#/" . $imgs['sources']['img'];
  1670. unset($imgs['sources']);
  1671. $item['img'] = $imgs;
  1672. }
  1673. if ($flex['link' . $dynContentCounter] !== '') {
  1674. $button = $this->parseFlexFormLink($flex['link' . $dynContentCounter], $dbReference, $processedData);
  1675. $item['button'] = $button;
  1676. }
  1677. $items[] = $item;
  1678. }
  1679. $subs[] = $this->createContentElement('explorerbox', array('items' => $items));
  1680. break;
  1681. case "mrm_be_cm_dynamic_tileoverview":
  1682. $items = array();
  1683. foreach ($flex["dynamicComponents"] as $comp) {
  1684. foreach ($comp as $k => $v) {
  1685. $itm = null;
  1686. switch ($k) {
  1687. case "links":
  1688. $lnk = $this->parseFlexFormLink($v["link"], $dbReference, $processedData);
  1689. $itm = $this->createContentElement("tile_default", array("link" => $lnk, "coloured" => $v["coloured"] == 1, "allowed" => preg_split('/\+/', $v["type"]), "format" => $v["format"]));
  1690. if ($lnk["alt"]) $itm["props"]["headline"] = $lnk["alt"];
  1691. break;
  1692. case "buttons":
  1693. $itm = $this->createContentElement(
  1694. "tile_content",
  1695. array(
  1696. "headline" => $v["headline"],
  1697. "content" => $this->checkTextForInternalLinks($v["buttons"], $dbReference, $processedData)
  1698. )
  1699. );
  1700. break;
  1701. case "icons":
  1702. $lnk = $this->parseFlexFormLink($v["link"], $dbReference, $processedData);
  1703. $itm = $this->createContentElement("tile_icon", array("link" => $lnk, "icon" => $v["icon"]), array());
  1704. if ($lnk["alt"]) $itm["props"]["headline"] = $lnk["alt"];
  1705. break;
  1706. case "flat":
  1707. $lnk = $this->parseFlexFormLink($v["link"], $dbReference, $processedData);
  1708. $itm = $this->createContentElement("tile_flat", array("link" => $lnk));
  1709. if ($lnk["alt"]) $itm["props"]["headline"] = $lnk["alt"];
  1710. break;
  1711. case "injections":
  1712. $itm = $this->createContentElement("injection", array("type" => $v["text"]));
  1713. $processedData["injections"][] = $v["text"];
  1714. break;
  1715. }
  1716. if ($itm)
  1717. $items[] = $itm;
  1718. }
  1719. }
  1720. $dto = $this->createContentElement('dynamic_tileoverview', array(), array(), $items);
  1721. if ($flex["cssClass"] && $flex["cssClass"] !== "")
  1722. $dto["attributes"]["cssClassName"] = $flex["cssClass"];
  1723. $subs[] = $dto;
  1724. $processedData["status"]["hasDynamicTileOverview"] = true;
  1725. break;
  1726. case "mrm_be_cm_podcast":
  1727. //$items = array();
  1728. if ($flex['media'] == "1")
  1729. $media = $this->processAudio($dbReference, 'mrm_be_cm_podcast', 'tt_content', 'media', 'uid', true, true);
  1730. if ($flex['transcript'])
  1731. $transcript = $flex['transcript'];
  1732. $subs[] = $this->createContentElement('podcast', array(), array('media' => $media, 'transcript' => $transcript));
  1733. break;
  1734. case "mrm_be_cm_imageplus":
  1735. $props = $this->processImagesTTContent($dbReference)[0];
  1736. $props["type"] = "imageplus";
  1737. $props["headline"] = $flex['headline'] ?? '';
  1738. $props["description"] = $flex['description'] ?? '';
  1739. $props["link"] = $this->parseFlexFormLink($flex["link"], $dbReference, $processedData);
  1740. $props["customcss"] = $flex['customcss'] ?? '';
  1741. $subs[] = $this->createContentElement('imageplus', $props);
  1742. break;
  1743. case "mrm_be_cm_interviewfrage":
  1744. $props['lang'] = $flex['lang'] ?? '';
  1745. $subs[] = $this->createContentElement("interviewfrage", $props, array("question" => trim($flex['question'])));
  1746. break;
  1747. case "mrm_be_cm_interviewantwort":
  1748. $props['lang'] = $flex['lang'] ?? '';
  1749. $subs[] = $this->createContentElement("interviewantwort", $props, array("interviewee" => trim($flex['interviewee']), "answer" => trim($flex['answer'])));
  1750. break;
  1751. case "mrm_be_cm_foldout_h3":
  1752. $sub = $this->createContentElement("typo3_foldout_h3", array("open" => $flex["isInitialyOpen"] == "1", "noAutoOpen" => $flex["noAutoOpen"] == "1"), array("headline" => $flex["headline"]), array());
  1753. if ($flex["image"] == "1") {
  1754. $props = $this->processImagesTTContent($dbReference, "mrm_be_cm_contentimage")[0];
  1755. $props["type"] = "typo3_content";
  1756. $sub["subElements"][] = $this->createContentElement("image", $props);
  1757. } else {
  1758. switch ($flex["icon"]) {
  1759. case "1":
  1760. $sub["attributes"]["icon"] = "stadtinfo_basics";
  1761. break;
  1762. case "2":
  1763. $sub["attributes"]["icon"] = "geschichte";
  1764. break;
  1765. case "3":
  1766. $sub["attributes"]["icon"] = "kultur_freizeit";
  1767. break;
  1768. case "4":
  1769. $sub["attributes"]["icon"] = "besonderheiten";
  1770. break;
  1771. case "5":
  1772. $sub["attributes"]["icon"] = "kosten_geld";
  1773. break;
  1774. case "6":
  1775. $sub["attributes"]["icon"] = "hochschulen";
  1776. break;
  1777. case "7":
  1778. $sub["attributes"]["icon"] = "studieren";
  1779. break;
  1780. }
  1781. }
  1782. if ($flex["dynamicComponents"] && sizeof($flex["dynamicComponents"]) > 0)
  1783. foreach ($flex["dynamicComponents"] as $comp) {
  1784. $stype = array_keys($comp['settings'])[0];
  1785. $elements = $this->checkText($comp['settings'][$stype][$stype], $dbReference, $processedData, $stype == "paragraph" ? "typo3_paragraph" : ($stype == "headline" ? "h4" : $stype));
  1786. $sub["subElements"] = array_merge($sub["subElements"], $elements);
  1787. }
  1788. $subs[] = $sub;
  1789. break;
  1790. case "mrm_be_cm_quiz_direct":
  1791. //print_r($flex); die();
  1792. $s = $this->createContentElement(
  1793. "quizdirect",
  1794. array(
  1795. "labels" => array(
  1796. "startbutton" => $flex["startbuttontext"],
  1797. "submitbutton" => $flex["submitbuttontext"],
  1798. "nextbutton" => $flex["nextbuttontext"],
  1799. "lastbutton" => $flex["lastbuttontext"],
  1800. "question" => $flex["question"],
  1801. "repeatbutton" => $flex["repeatbuttontext"],
  1802. "qsuccess" => $flex["questionsuccesstext"],
  1803. "qfail" => $flex["questionfailtext"],
  1804. ),
  1805. "resultscreen" => array(
  1806. "headingTop" => $flex["resultheadingtop"],
  1807. "headingSub" => $flex["resultheadingsub"],
  1808. "validation" => $flex["validationstr"],
  1809. "end" => $flex["thanks"]
  1810. ),
  1811. "isRestartAble" => $flex["isRestartAble"] == 1 || $flex["isRestartAble"] == "1",
  1812. ),
  1813. array(
  1814. "items" => array_values(array_map(function ($v) {
  1815. $questionType = null;
  1816. $quest = $v['settings']['question'];
  1817. if (!isset($quest)) {
  1818. $quest = $v['settings']['question_multi'];
  1819. $questionType = "multi";
  1820. }
  1821. if (isset($quest["additional_text"]) && $quest["additional_text"] != "") {
  1822. $quest["text"] = $quest["text"] . " (" . $quest["additional_text"] . ")";
  1823. unset($quest["additional_text"]);
  1824. }
  1825. if ($questionType) $quest["type"] = $questionType;
  1826. unset($quest["rightanswer"]);
  1827. if (isset($quest['solutionText'])) $solution = $quest['solutionText'];
  1828. unset($quest['solutionText']);
  1829. $i = 0;
  1830. $quest["answers"] = array();
  1831. while (1) {
  1832. $i++;
  1833. if (!isset($quest["answertext" . $i])) break;
  1834. if ($quest["answertext" . $i] === "") continue;
  1835. $quest["answers"][] = array("text" => $quest["answertext" . $i], "points" => (int)$quest["answerpoints" . $i]);
  1836. unset($quest["answertext" . $i]);
  1837. unset($quest["answerpoints" . $i]);
  1838. }
  1839. $quest["solution"] = $solution;
  1840. return $quest;
  1841. }, $flex["dynamicComponents"])),
  1842. "validation" => array(
  1843. "maxPoints" => (int)$flex["maxpoints"],
  1844. "averagePoints" => $this->createContentElement("injection", array("type" => "quiz-averagePoints")),
  1845. "alreadyReachedPoints" => $this->createContentElement("injection", array("type" => "quiz-alreadyReachedPoints")),
  1846. "items" => ($flex["dynamicComponents2"] == 0) ? [] : array_map(
  1847. function ($i) {
  1848. if (empty($i["validationText"])) $i["validationText"] = "";
  1849. else $i["validationText"] = $this->checkTextForInternalLinks($i["validationText"], $dbReference, $processedData);
  1850. return $i;
  1851. },
  1852. array_filter(array_values(array_map(function ($v) {
  1853. return $v['settings']['validation'];
  1854. }, $flex["dynamicComponents2"])), function ($x) {
  1855. return $x != null;
  1856. })
  1857. ),
  1858. ),
  1859. )
  1860. );
  1861. $processedData["injections"][] = "quiz-averagePoints";
  1862. $processedData["injections"][] = "quiz-alreadyReachedPoints";
  1863. $subs[] = $s;
  1864. $processedData["status"]["hasQuiz"] = true;
  1865. break;
  1866. default:
  1867. $this->log("MISSING PROCESSDATA 4 " . $dbReference['CType']);
  1868. $this->log($flex, false);
  1869. break;
  1870. }
  1871. }
  1872. private function checkText($txt, $dbReference, &$processedData, $defaultElementType = "typo3_paragraph")
  1873. {
  1874. $txt = $this->checkTextForInternalLinks($txt, $dbReference, $processedData);
  1875. $txt = $this->refactorTextElements($txt, $defaultElementType);
  1876. return $txt;
  1877. }
  1878. private function refactorTextElements($txt, $defaultElementType)
  1879. {
  1880. if (strpos($txt, "<table") === FALSE) return [$this->createContentElement($defaultElementType, array(), array("text" => $txt))];
  1881. $elements = [];
  1882. while (($tablepos = strpos($txt, "<table")) !== FALSE) {
  1883. if ($tablepos != 0) {
  1884. //$this->log(trim(substr($txt, 0, $tablepos)));
  1885. $elements[] = $this->createContentElement($defaultElementType, array(), array("text" => trim(substr($txt, 0, $tablepos))));
  1886. $txt = substr($txt, $tablepos);
  1887. }
  1888. $tablepos = strpos($txt, "</table>") + 8;
  1889. $dom = new \DOMDocument();
  1890. @$dom->loadHTML('<?xml encoding="utf-8" ?><div id="sexy">' . trim(substr($txt, 0, $tablepos)) . '</div>', LIBXML_HTML_NOIMPLIED | LIBXML_HTML_NODEFDTD);
  1891. $tab = $this->createContentElement("table", array("rows" => array(), "columnCount" => 0));
  1892. foreach ($dom->getElementsByTagName('tr') as $tr) {
  1893. $par = $tr->parentNode;
  1894. $row = [];
  1895. if ($tab["props"]["columnCount"] == 0) {
  1896. foreach ($tr->childNodes as $e) {
  1897. if ($e->tagName == "td" || $e->tagName == "th") {
  1898. $tab["props"]["columnCount"]++;
  1899. }
  1900. }
  1901. }
  1902. foreach ($tr->childNodes as $e) {
  1903. if ($e->tagName != "td" && $e->tagName != "th") continue;
  1904. $innerHTML = '';
  1905. foreach ($e->childNodes as $n) $innerHTML .= $dom->saveHtml($n);
  1906. $row[] = array(
  1907. "html" => "<p>" . $innerHTML . "</p>",
  1908. "isHeader" => $par->tagName == "thead",
  1909. "isRowHeader" => $e->tagName == "th" && $par->tagName != "thead",
  1910. );
  1911. }
  1912. $tab["props"]["rows"][] = $row;
  1913. }
  1914. $elements[] = $tab;
  1915. $txt = substr($txt, $tablepos);
  1916. }
  1917. $txt = trim($txt);
  1918. if ($txt != "")
  1919. $elements[] = $this->createContentElement($defaultElementType, array(), array("text" => $txt));
  1920. return $elements;
  1921. }
  1922. private function checkTextForInternalLinks($txt, $dbReference, &$processedData)
  1923. {
  1924. $dom = new \DOMDocument();
  1925. @$dom->loadHTML('<?xml encoding="utf-8" ?><div id="sexy">' . $txt . '</div>', LIBXML_HTML_NOIMPLIED | LIBXML_HTML_NODEFDTD);
  1926. foreach ($dom->getElementsByTagName('a') as $link) {
  1927. $emptyHref = false;
  1928. $title = null;
  1929. $alt = null;
  1930. $href = null;
  1931. for ($i = 0; $i < $link->attributes->length; ++$i) {
  1932. $node = $link->attributes->item($i);
  1933. if ($node->nodeName == "href" && strpos($node->nodeValue, 'smartadserver.com') === FALSE) {
  1934. $nv = $node->nodeValue;
  1935. $nv = str_replace('&amp;', '&', $nv);
  1936. $href = $this->replaceT3Link($nv, $dbReference, $processedData);
  1937. $node->nodeValue = htmlspecialchars($href);
  1938. if ($node->nodeValue == '') $emptyHref = true;
  1939. }
  1940. if ($node->nodeName == "title" && $node->nodeValue != '') $title = $node->nodeValue;
  1941. if ($node->nodeName == "alt" && $node->nodeValue != '') $alt = $node->nodeValue;
  1942. }
  1943. if ($emptyHref) $link->removeAttribute('href');
  1944. else {
  1945. if (!$alt) {
  1946. //check for pdf files (AS-337)
  1947. if (strtolower(pathinfo($href, PATHINFO_EXTENSION)) == "pdf") {
  1948. $alt = "PDF-Download (öffnet sich in neuem Fenster)";
  1949. $link->setAttribute('target', '_blank');
  1950. $link->setAttribute('alt', $alt);
  1951. }
  1952. }
  1953. }
  1954. if ($title && !$alt) $link->setAttribute('alt', $title);
  1955. if ($title) $link->removeAttribute('title');
  1956. }
  1957. $txt = $dom->saveHTML($dom->getElementById('sexy'));
  1958. $txt = str_replace('<div id="sexy">', '', $txt);
  1959. $txt = substr($txt, 0, -6);
  1960. return trim($txt);
  1961. }
  1962. private function parseFlexFormLink($link, $dbReference, &$processedData)
  1963. {
  1964. $link = implode("/", explode("\/", $link));
  1965. [$href, $target, $css] = explode(" ", $link);
  1966. $alt = substr($link, strlen($href . $target . $css) + 3);
  1967. $alt = preg_replace('/&quot;/', '', trim($alt, " \""));
  1968. if ($href == "-") return null;
  1969. $href = $this->replaceT3Link($href, $dbReference, $processedData, true);
  1970. $ret = array("href" => $href);
  1971. if (!$target || $target == "-") $ret["target"] = "_top";
  1972. else $ret["target"] = $target;
  1973. if ($alt && $alt != "-") $ret["alt"] = $alt;
  1974. return $ret;
  1975. }
  1976. private function replaceT3Link($link, $dbReference, &$processedData, $addToLinkedPosts = false)
  1977. {
  1978. $uid = $this->parseUIDFromT3Url($link);
  1979. if (!$uid || $uid == '') return $link;
  1980. if (strpos($link, 't3://page?') !== false) {
  1981. if ($uid == "current") {
  1982. $link = str_replace('t3://page?uid=current', '', $link);
  1983. } else {
  1984. if ($addToLinkedPosts) {
  1985. $processedData['linkedPosts'][] = (int)$uid;
  1986. $link = "#linkedPost#" . $uid . "#/linkedPost#";
  1987. } else {
  1988. $pageStatement = $this->pageQueryBuilder
  1989. ->select('*')
  1990. ->from('pages')
  1991. ->setMaxResults(1)
  1992. ->where(
  1993. $this->pageQueryBuilder->expr()->eq('uid', $this->pageQueryBuilder->createNamedParameter($uid))
  1994. )
  1995. ->execute();
  1996. $post = $pageStatement->fetchAll();
  1997. $post = $post[0];
  1998. $link = $post['slug'];
  1999. }
  2000. }
  2001. }
  2002. if (strpos($link, 't3://file?') !== false)
  2003. $link = $this->setStaticFile($dbReference, $uid);
  2004. return $link;
  2005. }
  2006. private function setStaticFile($dbReference, $uid, $publicUrl = null)
  2007. {
  2008. $fnNameRef = $dbReference['pid'] . "|" . $dbReference['uid'] . "|" . $dbReference['CType'] . "|file|" . $uid;
  2009. if (!$publicUrl) {
  2010. $file = $this->resourceFactory->getFileObject($uid);
  2011. $publicUrl = $file->getPublicUrl();
  2012. }
  2013. try {
  2014. $fnName = basename($publicUrl);
  2015. $fnName = explode(".", $fnName);
  2016. $extension = array_pop($fnName);
  2017. $fnName = implode(".", $fnName);
  2018. } catch (Exception $e) {
  2019. $fnName = null;
  2020. }
  2021. return "#cdnurl#/" . $this->copyAndRenameFile($fnNameRef, "/" . $publicUrl, $fnName);
  2022. }
  2023. private function parseUIDFromT3Url($t3url)
  2024. {
  2025. $uid = null;
  2026. if ($t3url && $t3url != '' && substr($t3url, 0, 2) == "t3")
  2027. try {
  2028. parse_str(parse_url($t3url)['query'], $query);
  2029. $uid = $query['uid'];
  2030. } catch (Exception $e) {
  2031. }
  2032. return $uid;
  2033. }
  2034. private function createContentElement($type, $props = null, $attributes = null, $subElements = null)
  2035. {
  2036. if (is_null($props)) $props = array();
  2037. if (is_null($attributes)) $attributes = (object) array();
  2038. $props["__hbs_uid"] = '_ab' . mt_rand(0, 0xffffff) . '_' . mt_rand(0, 0xffffff);
  2039. $ele = array(
  2040. 'type' => $type,
  2041. 'props' => $props,
  2042. 'attributes' => $attributes,
  2043. );
  2044. if (!is_null($subElements)) $ele['subElements'] = $subElements;
  2045. else $ele['subElements'] = [];
  2046. return $ele;
  2047. }
  2048. private function processVideo($dbReference)
  2049. {
  2050. $data = $this->resourceFactory->convertFlexFormDataToConfigurationArray($dbReference['pi_flexform']);
  2051. $vids = array();
  2052. foreach ($data['settings']['video'] as $value) {
  2053. if ($value['posterConfiguration'] && $value['posterConfiguration'] != '') $vids['poster'] = $value['posterConfiguration']['image'];
  2054. if ($value['mp4Configuration'] && $value['mp4Configuration'] != '') $vids['mp4'] = $value['mp4Configuration']['video'];
  2055. if ($value['ogvConfiguration'] && $value['ogvConfiguration'] != '') $vids['ogv'] = $value['ogvConfiguration']['video'];
  2056. if ($value['webmConfiguration'] && $value['webmConfiguration'] != '') $vids['webm'] = $value['webmConfiguration']['video'];
  2057. if ($value['threegpConfiguration'] && $value['threegpConfiguration'] != '') $vids['3gp'] = $value['threegpConfiguration']['video'];
  2058. }
  2059. foreach ($vids as $key => &$value) {
  2060. $value = "/" . $value;
  2061. $fnNameRef = $dbReference['pid'] . "|" . $dbReference['uid'] . "|" . $dbReference['CType'] . "|" . $key;
  2062. $value = $this->copyAndRenameFile($fnNameRef, $value);
  2063. }
  2064. return $vids;
  2065. }
  2066. private function processImagesTTContent($dbReference, $ctypeOverride = '', $table = 'tt_content', $tableColumn = 'image', $refField = 'uid', $useRelationFetch = true, $addCDNPrefix = false)
  2067. {
  2068. if ($useRelationFetch)
  2069. $fileObjects = $this->fileRepository->findByRelation($table, $tableColumn, $dbReference[$refField]);
  2070. else {
  2071. $sysfilerefQueryBuilder = $this->connection->getQueryBuilderForTable('sys_file_reference');
  2072. $sysfileStatement = $sysfilerefQueryBuilder
  2073. ->select('uid')
  2074. ->from('sys_file_reference')
  2075. ->andWhere(
  2076. $sysfilerefQueryBuilder->expr()->eq('uid_foreign', intval($dbReference[$refField])),
  2077. $sysfilerefQueryBuilder->expr()->eq('tablenames', $sysfilerefQueryBuilder->createNamedParameter($table)),
  2078. $sysfilerefQueryBuilder->expr()->eq('fieldname', $sysfilerefQueryBuilder->createNamedParameter($tableColumn)),
  2079. )
  2080. ->execute();
  2081. $frows = $sysfileStatement->fetchAll();
  2082. foreach ($frows as $fileuid) {
  2083. $fileObjects[] = $this->fileRepository->findFileReferenceByUid(intval($fileuid['uid']));
  2084. }
  2085. }
  2086. $processedImages = array();
  2087. $ctypeOverride = $ctypeOverride != '' ? $ctypeOverride : $dbReference['CType'];
  2088. foreach ($fileObjects as $key => $value) {
  2089. $img = array(
  2090. 'reference' => $value->getReferenceProperties(),
  2091. 'original' => $value->getOriginalFile()->getProperties(),
  2092. );
  2093. $imgfn = rtrim($img['original']['identifier'], "/");
  2094. $image = $this->imageService->getImage('fileadmin/' . $imgfn, null, false);
  2095. $cropvariantcollection = \TYPO3\CMS\Core\Imaging\ImageManipulation\CropVariantCollection::create($img['reference']['crop']);
  2096. $cropareas = $this->imageSizes[$ctypeOverride];
  2097. $processArray = array(
  2098. 'sources' => array()
  2099. );
  2100. $alt = $img['reference']['alternative'] != NULL ? $img['reference']['alternative'] : ($img['original']['alternative'] != NULL ? $img['original']['alternative'] : NULL);
  2101. $title = $img['reference']['title'] != NULL ? $img['reference']['title'] : ($img['original']['title'] != NULL ? $img['original']['title'] : NULL);
  2102. $caption = $img['reference']['description'] != NULL ? $img['reference']['description'] : ($img['original']['description'] != NULL ? $img['original']['description'] : NULL);
  2103. $copyright = $img['reference']['copyright'] != NULL ? $img['reference']['copyright'] : ($img['original']['copyright'] != NULL ? $img['original']['copyright'] : NULL);
  2104. if ($alt != NULL) $processArray['alt'] = $alt;
  2105. if ($title != NULL) $processArray['title'] = $title;
  2106. if ($caption != NULL) $processArray['caption'] = $caption;
  2107. if ($copyright != NULL) $processArray['copyright'] = $copyright;
  2108. if ($cropareas['passthru']) {
  2109. if (is_array($cropareas['passthru'])) {
  2110. foreach ($cropareas['passthru'] as $sizename => $size) {
  2111. $processingInstructions = array(
  2112. 'width' => $size['width'],
  2113. 'minWidth' => $size['width'],
  2114. 'maxWidth' => $size['width'],
  2115. 'crop' => null
  2116. );
  2117. if ($size['height']) {
  2118. $processingInstructions = array_merge(
  2119. $processingInstructions,
  2120. array(
  2121. 'height' => $size['height'],
  2122. 'minHeight' => $size['height'],
  2123. 'maxHeight' => $size['height']
  2124. )
  2125. );
  2126. }
  2127. if ($size['maxHeight'])
  2128. $processingInstructions['maxHeight'] = $size['maxHeight'];
  2129. if ($size['minHeight'])
  2130. $processingInstructions['minHeight'] = $size['minHeight'];
  2131. $processedImage = $this->imageService->applyProcessingInstructions($image, $processingInstructions);
  2132. $imageUri = $this->imageService->getImageUri($processedImage);
  2133. $fnNameRef = $dbReference['pid'] . "|" . $dbReference['uid'] . "|" . $ctypeOverride . "|" . $img['reference']['uid'] . "|passthru|" . $sizename;
  2134. $processArray['sources'][$sizename] = $this->copyAndRenameFile($fnNameRef, $imageUri, $processArray['alt']);
  2135. }
  2136. } else {
  2137. $fnNameRef = $dbReference['pid'] . "|" . $dbReference['uid'] . "|" . $ctypeOverride . "|" . $img['reference']['uid'] . "|passthru";
  2138. $imageUri = $this->imageService->getImageUri($image);
  2139. $processArray['sources']['passthru'] = ($addCDNPrefix ? "#cdnurl#/" : "") . $this->copyAndRenameFile($fnNameRef, $imageUri, $processArray['alt']);
  2140. }
  2141. } else
  2142. foreach ($cropareas as $cropareaname => $sizes) {
  2143. $croparea = $cropvariantcollection->getCropArea($cropareaname);
  2144. foreach ($sizes as $sizename => $size) {
  2145. if ($dbReference["doktype"] && $size['allowed_doktypes'] && !in_array($dbReference["doktype"], $size['allowed_doktypes'])) continue;
  2146. $processingInstructions = array(
  2147. 'width' => $size['width'],
  2148. 'minWidth' => $size['width'],
  2149. 'maxWidth' => $size['width'],
  2150. 'crop' => $croparea->isEmpty() ? null : $croparea->makeAbsoluteBasedOnFile($image)
  2151. );
  2152. if ($size['height']) {
  2153. $processingInstructions = array_merge(
  2154. $processingInstructions,
  2155. array(
  2156. 'height' => $size['height'],
  2157. 'minHeight' => $size['height'],
  2158. 'maxHeight' => $size['height']
  2159. )
  2160. );
  2161. }
  2162. if ($size['maxHeight'])
  2163. $processingInstructions['maxHeight'] = $size['maxHeight'];
  2164. if ($size['minHeight'])
  2165. $processingInstructions['minHeight'] = $size['minHeight'];
  2166. $processedImage = $this->imageService->applyProcessingInstructions($image, $processingInstructions);
  2167. $imageUri = $this->imageService->getImageUri($processedImage);
  2168. $fnNameRef = $dbReference['pid'] . "|" . $dbReference['uid'] . "|" . $ctypeOverride . "|" . $img['reference']['uid'] . "|" . $cropareaname . "|" . $sizename;
  2169. $processArray['sources'][$sizename] = ($addCDNPrefix ? "#cdnurl#/" : "") . $this->copyAndRenameFile($fnNameRef, $imageUri, $processArray['alt']);
  2170. }
  2171. }
  2172. $processedImages[] = $processArray;
  2173. }
  2174. return $processedImages;
  2175. }
  2176. private function processAudio($dbReference, $ctypeOverride = '', $table = 'tt_content', $tableColumn = 'media', $refField = 'uid', $useRelationFetch = true, $copyToCDN = false)
  2177. {
  2178. if ($useRelationFetch)
  2179. $fileObjects = $this->fileRepository->findByRelation($table, $tableColumn, $dbReference[$refField]);
  2180. else {
  2181. $sysfilerefQueryBuilder = $this->connection->getQueryBuilderForTable('sys_file_reference');
  2182. $sysfileStatement = $sysfilerefQueryBuilder
  2183. ->select('uid')
  2184. ->from('sys_file_reference')
  2185. ->andWhere(
  2186. $sysfilerefQueryBuilder->expr()->eq('uid_foreign', intval($dbReference[$refField])),
  2187. $sysfilerefQueryBuilder->expr()->eq('tablenames', $sysfilerefQueryBuilder->createNamedParameter($table)),
  2188. $sysfilerefQueryBuilder->expr()->eq('fieldname', $sysfilerefQueryBuilder->createNamedParameter($tableColumn)),
  2189. )
  2190. ->execute();
  2191. $frows = $sysfileStatement->fetchAll();
  2192. foreach ($frows as $fileuid) {
  2193. $fileObjects[] = $this->fileRepository->findFileReferenceByUid(intval($fileuid['uid']));
  2194. }
  2195. }
  2196. $processedAudio = array();
  2197. $audio = [];
  2198. $ctypeOverride = $ctypeOverride != '' ? $ctypeOverride : $dbReference['CType'];
  2199. foreach ($fileObjects as $key => $value) {
  2200. $processedAudio = array(
  2201. 'reference' => $value->getReferenceProperties(),
  2202. 'original' => $value->getOriginalFile()->getProperties(),
  2203. );
  2204. if ($copyToCDN) {
  2205. $oringalFile = $processedAudio['original']['identifier'];
  2206. $extension = pathinfo($processedAudio['original']['identifier'], PATHINFO_EXTENSION);
  2207. $targetFile = substr(sha1($processedAudio['original']['identifier']), 0, 5) . '_podcast.' . $extension;
  2208. $oringalFile = '/fileadmin' . $oringalFile;
  2209. $url = $this->copyPodcastAudioFileToCDN($oringalFile, $targetFile);
  2210. }
  2211. $audio['name'] = $processedAudio['original']['name'];
  2212. $audio['url'] = $url;
  2213. $audio['title'] = $processedAudio['reference']['title'];
  2214. $audio['description'] = $processedAudio['reference']['description'];
  2215. }
  2216. return $audio;
  2217. }
  2218. private function copyAndRenameFile($destinationFnRef, $sourceUri, $altText = null)
  2219. {
  2220. $shaFileRef = sha1($destinationFnRef);
  2221. $workPath = substr($shaFileRef, 0, 2) . "/" . substr($shaFileRef, 2, 2);
  2222. $workFnPrefix = $shaFileRef;
  2223. if ($altText) {
  2224. $altText = substr($altText, 0, 100);
  2225. $workFnPrefix = $this->sanitizeString($altText) . "-" . $shaFileRef;
  2226. }
  2227. $workFn = $workFnPrefix . "." . pathinfo($sourceUri, PATHINFO_EXTENSION);
  2228. if (!file_exists(\TYPO3\CMS\Core\Core\Environment::getPublicPath() . '/cdn/' . $workPath)) {
  2229. mkdir(\TYPO3\CMS\Core\Core\Environment::getPublicPath() . '/cdn/' . $workPath, 0777, true);
  2230. }
  2231. copy(\TYPO3\CMS\Core\Core\Environment::getPublicPath() . $sourceUri, \TYPO3\CMS\Core\Core\Environment::getPublicPath() . '/cdn/' . $workPath . '/' . $workFn);
  2232. return $workPath . '/' . $workFn;
  2233. }
  2234. private function copyPodcastAudioFileToCDN($sourceFile, $destinationFile)
  2235. {
  2236. $dir = 'podcast';
  2237. if (!file_exists(\TYPO3\CMS\Core\Core\Environment::getPublicPath() . '/cdn/' . $dir)) {
  2238. mkdir(\TYPO3\CMS\Core\Core\Environment::getPublicPath() . '/cdn/' . $dir, 0777, true);
  2239. }
  2240. copy(\TYPO3\CMS\Core\Core\Environment::getPublicPath() . $sourceFile, \TYPO3\CMS\Core\Core\Environment::getPublicPath() . '/cdn/' . $dir . '/' . $destinationFile);
  2241. return '#cdnurl#/' . $dir . '/' . $destinationFile;
  2242. }
  2243. public function processCmdmap_deleteAction($table, $id, $recordToDelete, $recordWasDeleted = NULL, \TYPO3\CMS\Core\DataHandling\DataHandler &$pObj)
  2244. {
  2245. //$this->log('processCmdmap_deleteAction');
  2246. if ($table == "pages") {
  2247. Mongoer::sendRequest("pages", "delete", array("pageuid" => $id));
  2248. Mongoer::sendRequest("abialtcache", "delete", array("pageuid" => $pid));
  2249. Mongoer::sendRequest("search", "delete", array("pageuid" => $id));
  2250. Mongoer::sendRequest("security", "delete", array("pageuid" => $id));
  2251. Mongoer::sendRequest("previews", "delete", array("pageuid" => $id));
  2252. }
  2253. }
  2254. /* PRIVATES */
  2255. private function log($msg, $isString = true)
  2256. {
  2257. if (!$isString) {
  2258. $msg = json_encode($msg, JSON_PRETTY_PRINT);
  2259. }
  2260. file_put_contents('/var/www/html/public/typo3temp/debug.log', $msg . PHP_EOL, FILE_APPEND);
  2261. }
  2262. }