mostly filebased Content Presentation System
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

elementdispatcher.php 22KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562
  1. <?php
  2. namespace Modules;
  3. class ElementDispatcher {
  4. private $folder = "";
  5. private $config = [];
  6. function __construct($folder = "",$config = []) {
  7. if (is_string($folder)) {
  8. $this->folder = $folder;
  9. }
  10. if (is_array($config)) {
  11. $this->config = $config;
  12. }
  13. }
  14. function content_element($request = [], $body = null) {
  15. $f3 = \Base::instance();
  16. $md = new \freaParsedown();
  17. $md->deactivate_ol();
  18. $new = "";
  19. switch($request[0]) {
  20. case 'test':
  21. $new="seems to work";
  22. break;
  23. case ';':
  24. $new="";
  25. break;
  26. case 'path':
  27. $new="/".$this->folder;
  28. break;
  29. case 'space':
  30. $new=sprintf("<div style=\"height:%s;\"></div>",
  31. $request[1]
  32. );
  33. break;
  34. case 'span':
  35. $new=sprintf("<span class=\"%s\">%s</span>",
  36. $request[1],
  37. $request[2] ? : implode("\n",$body)
  38. );
  39. break;
  40. case 'small-text':
  41. if(count($body)) {
  42. $new=sprintf("<div class=\"smalltext\">%s</div>",
  43. $md->text(implode("\n",$body))
  44. );
  45. } else {
  46. $new=sprintf("<span class=\"smalltext\">%s</span>",
  47. $request[1]
  48. );
  49. }
  50. break;
  51. case 'CE':
  52. switch($request[1]) {
  53. case 'publication':
  54. $CE = new \Modules\CPublication($this->config,['path'=>$this->folder]);
  55. if(count($request)>2) {
  56. $CE->set_layout($request[2]);
  57. }
  58. $new = $CE;
  59. break;
  60. }
  61. break;
  62. case 'TOC':
  63. // throw away TOC part of request, we don't need it
  64. array_shift($request);
  65. $toc = new \Modules\TOC($request,$this->folder,$body);
  66. $toc->dispatch();
  67. $new=sprintf("<div class=\"TOC %s\">%s</div>",
  68. array_shift($request),
  69. $toc);
  70. break;
  71. case 'sql':
  72. //array_shift($request);
  73. switch ($request[1]) {
  74. case 'sqlite':
  75. $array = [];
  76. $db = new \DB\SQL('sqlite:' . $this->folder . $request[2]);
  77. $sql = implode(" ", $body);
  78. if ( strpos($sql,'insert')===false &&
  79. strpos($sql,'update')===false &&
  80. strpos($sql,'drop')===false) {
  81. $rows = $db->exec($sql);
  82. foreach ($rows as $res) {
  83. switch (count($res)) {
  84. case 1:
  85. $keys=array_keys($res);
  86. $array[] = $res[$keys[0]];
  87. break;
  88. case 2:
  89. $keys=array_keys($res);
  90. $array[$res[$keys[0]]] = $res[$keys[1]];
  91. break;
  92. }
  93. }
  94. }
  95. $new = sprintf("<ul><li>%s</li></ul>",
  96. implode("</li><li>",$array));
  97. unset($array);
  98. break;
  99. }
  100. break;
  101. case 'form':
  102. $token_db = $f3->get('TEMP') . "CEform/";
  103. $form_config_file = sprintf("%s%s.cfg",
  104. ROOT.$this->folder,
  105. $request[1]);
  106. $db = new \DB\Jig($token_db,\DB\Jig::FORMAT_JSON);
  107. $formcall = new \DB\Jig\Mapper($db,'form_calls');
  108. $timestamp = time();
  109. $token = md5($timestamp . $form_config_file . rand(100,999));
  110. $f3->config($form_config_file);
  111. $fields = $f3->get('fields');
  112. foreach ($fields as $k => $v) {
  113. if ($v['type'] == 'custom') {
  114. $fields[$k]['template'] = sprintf(
  115. "%s%s",
  116. substr($this->folder,strlen($f3->get('CONTENT_BASE'))),
  117. $v['template']
  118. );
  119. }
  120. if (array_key_exists('db',$v)) {
  121. switch ($v['db']['type']) {
  122. case 'sqlite':
  123. $array = [];
  124. $db = new \DB\SQL('sqlite:' . $this->folder . $v['db']['file']);
  125. $sql = $v['db']['sql'];
  126. if ( strpos($sql,'insert')===false &&
  127. strpos($sql,'update')===false &&
  128. strpos($sql,'drop')===false) {
  129. $rows = $db->exec($sql);
  130. foreach ($rows as $res) {
  131. switch (count($res)) {
  132. case 2:
  133. $keys=array_keys($res);
  134. $array[$res[$keys[0]]] = $res[$keys[1]];
  135. break;
  136. }
  137. }
  138. }
  139. $fields[$k]['el'] = $array;
  140. unset($array);
  141. break;
  142. }
  143. }
  144. }
  145. $f3->set('fields',
  146. array_merge(
  147. $fields,
  148. ['xss-token'=>[
  149. 'type'=>'hidden',
  150. 'value'=>$token,
  151. 'length'=>strlen($token)
  152. ]]
  153. ));
  154. $formcall->token = $token;
  155. $formcall->timestamp = $timestamp;
  156. $formcall->form = $form_config_file;
  157. $formcall->path = ROOT.$this->folder;
  158. $formcall->save();
  159. $form_view = new \Template;
  160. $new=$form_view->render('form.htm');
  161. break;
  162. case 'box':
  163. array_shift($request); //get rid of identifier
  164. $type = array_shift($request);
  165. $pics = explode(":",array_shift($body));
  166. $pic = $pics[0];
  167. $pic_hover = count($pics) > 1 ? $pics[1] : $pic;
  168. if (count($body) >= 3) {
  169. $caption = ['normal'=>['cap1' => array_shift($body),
  170. 'cap2' => array_shift($body)],
  171. 'hover'=> ['cap1' => array_shift($body),
  172. 'cap2' => array_shift($body)]];
  173. $caption_html=[];
  174. foreach ($caption as $state => $set) {
  175. if(!$set['cap2']) {
  176. $caption_html[$state] = [
  177. sprintf('<span class="first">&nbsp;</span>'),
  178. sprintf('<span class="first">%s</span>',$set['cap1'])
  179. ];
  180. } else if (!$set['cap1'] && $set['cap2']) {
  181. $caption_html[$state] = [
  182. sprintf('<span class="second">%s</span>',$set['cap2'])
  183. ];
  184. } else {
  185. $caption_html[$state] = [
  186. sprintf('<span class="first">%s</span>',$set['cap1']?:"&nbsp;"),
  187. sprintf('<span class="second">%s</span>',$set['cap2'])
  188. ];
  189. }
  190. }
  191. $has_caption = TRUE;
  192. } else {
  193. $has_caption = FALSE;
  194. }
  195. if (file_exists($this->folder.$pic)) {
  196. $pic = $this->folder.$pic;
  197. } else {
  198. $pic = $f3->get('RESOURCES')."img/default_img.png";
  199. }
  200. if (file_exists($this->folder.$pic_hover)) {
  201. $pic_hover = $this->folder.$pic_hover;
  202. } else {
  203. $pic_hover = $pic;
  204. }
  205. if(0) {
  206. $PIC = new \Image($pic);
  207. $orientation = $PIC->width() > $PIC->height()
  208. ? 'landscape'
  209. : 'portrait'
  210. ;
  211. unset($PIC);
  212. } else {
  213. list($wwidth, $hheight) = getimagesize($pic);
  214. $orientation = $wwidth > $hheight ? 'landscape' : 'portrait';
  215. }
  216. $pic = new CachedImage($pic);
  217. $pic_hover = new CachedImage($pic_hover);
  218. $class="";
  219. $add="";
  220. switch($type) {
  221. case 'plain':
  222. $link=false;
  223. break;
  224. case 'download':
  225. $file = "/".$this->folder.implode(":",$request);
  226. $link='href="'.$file.'" download ';
  227. break;
  228. case 'lightbox':
  229. $body = implode("\n",$body);
  230. if (count($request) % 2) {
  231. $class = array_pop($request);
  232. }
  233. if (count($request) >= 2) {
  234. $body=str_replace([$request[0],$request[1]],["{|","|}"],$body);
  235. $body=$this->content_element($body);
  236. }
  237. $hash=md5($body);
  238. $add=sprintf("<div id=\"%s\" class=\"content_elment_box_body\">\n%s\n</div>",
  239. $hash,
  240. $md->text($body));
  241. $link='href="#" data-featherlight="#'.$hash.'" ';
  242. break;
  243. case 'internal':
  244. $dest=implode(":",$request);
  245. $data = [];
  246. $base = substr($dest,0,strpos($dest,'?') ? : strlen($dest));
  247. parse_str(parse_url($dest,PHP_URL_QUERY),$data);
  248. $fragment = parse_url($dest,PHP_URL_FRAGMENT);
  249. if ($f3->get('LANG') != $f3->get('default_lang')) {
  250. if (!array_key_exists('lang',$data)) {
  251. $data['lang'] = $f3->get('LANG');
  252. }
  253. }
  254. $new_dest = $base;
  255. if (count($data) > 0) {
  256. $new_dest .= "?" . http_build_query($data);
  257. }
  258. if ($fragment) {
  259. $new_dest .= "#" . $fragment;
  260. }
  261. //if ($f3->get('LANG') != $f3->get('default_lang')) {
  262. // $dest .= "?lang=".$f3->get('LANG');
  263. //}
  264. $link=sprintf('href="%s" ',$f3->get('SITE_URL')."/".$new_dest);
  265. break;
  266. case 'external':
  267. $dest=implode(":",$request);
  268. $target = $f3->get('external_links_open_in_new_window')
  269. ? 'target="_blank"'
  270. : ''
  271. ;
  272. $link=sprintf('href="%s" %s',$dest, $target);
  273. break;
  274. default:
  275. $link='href="#"';
  276. break;
  277. }
  278. $new=sprintf("<div class=\"brick %s\">\n<a class=\"content_element_box\" %s>\n<div class=\"content_element_box\">
  279. <div class=\"image\">
  280. <img class=\"standard\" src=\"%s\" /><img class=\"hover\" src=\"%s\" />
  281. </div>
  282. %s
  283. %s
  284. \n</div>\n</a>\n%s\n</div>",
  285. implode(" ",[$orientation,$class,$type]),
  286. $link,
  287. $pic->get_src(1600),
  288. $pic_hover->get_src(1600),
  289. ($has_caption ? "<div class=\"caption standard\">".implode("<br>",$caption_html['normal'])."</div>": " "),
  290. ($has_caption ? "<div class=\"caption hover\">".implode("<br>",$caption_html['hover'])."</div>" : " " ),
  291. $add
  292. );
  293. break;
  294. case 'brick':
  295. array_shift($request);
  296. $class = array_shift($request);
  297. $new = sprintf("<div class=\"content_element brick %s\">\n%s\n</div>",
  298. $class,
  299. $md->text(implode("\n",$body))
  300. );
  301. break;
  302. case 'calendar':
  303. array_shift($request);
  304. $conf = array('path', $this->folder);
  305. $v = $this->read_config();
  306. $cal = new \Modules\CCalendar($v,$conf);
  307. $new=sprintf("<div class=\"calendar\">\n%s\n</div>",
  308. $cal);
  309. break;
  310. case 'header':
  311. array_shift($request);
  312. $conf = array('path', $this->folder);
  313. $v = $this->read_config();
  314. switch (array_shift($request)) {
  315. case 'event':
  316. $el = new CEvent($v,$conf);
  317. $el->set_layout('archive');
  318. $new = $el;
  319. break;
  320. case 'concert':
  321. $el = new CConcert($v,$conf);
  322. $el->set_layout('header');
  323. $new = $el;
  324. break;
  325. }
  326. break;
  327. case 'data':
  328. $method = strtoupper($request[1]);
  329. //$keys = [];
  330. if (in_array($method,['POST','GET','SESSION'])) {
  331. foreach ($body as $line) {
  332. $key = explode("=",$line);
  333. $raw = $f3->get($method.'.'.$key[0]);
  334. if (count($key) >= 2) {
  335. $type=$key[1];
  336. } else {
  337. $type = false;
  338. }
  339. switch ($type) {
  340. case 'base64':
  341. $new = urlsafe_b64decode($raw);
  342. break;
  343. default:
  344. $new = $raw;
  345. }
  346. }
  347. //var_dump($new);
  348. }
  349. break;
  350. case 'buy':
  351. // synopsis:
  352. // buy:name:price
  353. // TODO: become currency aware (now EURO is hardcoded)
  354. $new = '';
  355. if (count($request)>=2) {
  356. $name=$request[1];
  357. } else {
  358. $name="item";
  359. }
  360. if (count($request)>=3) {
  361. $price=$request[2];
  362. } else {
  363. $price=1.0;
  364. }
  365. $fields = [
  366. 'caller' => $f3->get('page'),
  367. 'name'=>$name,
  368. 'price'=>$price,
  369. 'amount'=>1
  370. ];
  371. $hidden_inputs = [];
  372. foreach ($fields as $k=>$v) {
  373. $hidden_inputs[] = sprintf('<input type="hidden" name="%s" value="%s" />',$k,$v);
  374. }
  375. $new = sprintf('<form method="post" action="%s">%s<button action="submit" >BUY</button><span class="price"> %s</span></form>',
  376. '/api/cart/add',
  377. implode("\n",$hidden_inputs),
  378. $price ."€"
  379. );
  380. break;
  381. case 'checkout':
  382. //first argument, if present, is a path to folder containing order database
  383. $path = '';
  384. if (count($request) > 1) {
  385. $add_path = $request[1];
  386. if (strncmp($add_path,"/",1)) {
  387. $path = $this->folder.$add_path;
  388. } else {
  389. $path = $add_path;
  390. }
  391. } else {
  392. $path = $this->folder;
  393. }
  394. $checkout = new \Controller\Checkout($path);
  395. $new = $checkout->index();
  396. break;
  397. case 'only_cart':
  398. $checkout = new \Controller\Checkout($this->folder);
  399. $new = $checkout->html_cart();
  400. break;
  401. case 'image':
  402. $module = new CEimage($request, $body, $this->structs, $this->content);
  403. $new = $module->index();
  404. unset($module);
  405. break;
  406. case 'devide':
  407. $contents = explode($request[1],implode("\n",$body));
  408. $c=count($contents);
  409. $str="";
  410. for ($iiii=0;$iiii<$c;$iiii++) {
  411. $str .= sprintf(" %f%%",100/$c);
  412. }
  413. $template = sprintf('grid-template-columns:%s;',
  414. $str);
  415. $counter=0;
  416. $new = sprintf('<div class="content_element_devided" style="%s">',$template);
  417. foreach($contents as $part) {
  418. $counter++;
  419. if (count($request) >= 4) {
  420. $part=str_replace([$request[2],$request[3]],["{|","|}"],$part);
  421. $part=$this->content_element($part);
  422. }
  423. $new .= sprintf("<div>\n%s\n</div>",
  424. $md->text($part)
  425. );
  426. }
  427. $new.="</div>";
  428. break;
  429. case 'page':
  430. array_shift($request);
  431. $target = array_shift($request);
  432. $class = array_shift($request);
  433. $folder = $this->folder.$target."/";
  434. $anchor_name=array_pop(explode("/",$target));
  435. $fff = new \Modules\FilesInFolders(
  436. $folder,
  437. ['content'=>[
  438. 'secondary'=>'secondary',
  439. 'zzz'=>'hidden',
  440. 'unpublish'=>'hidden'],
  441. 'keyfiles'=>[
  442. 'banner'=>[
  443. 'until'=>$folder,
  444. 'type'=>'pic']]]
  445. );
  446. $fff->prepare_files();
  447. foreach ($body as $line) {
  448. $ccc = explode(":",$line);
  449. if (count($ccc) == 2) {
  450. if ($ccc[1] == 'false') {
  451. $ccc[1] = false;
  452. }
  453. $fff->config[$ccc[0]] = $ccc[1];
  454. }
  455. }
  456. $fff->fill_content();
  457. //var_dump($fff->config);
  458. $banner = "";
  459. if ($fff->extras['banner']) {
  460. $banner=sprintf("<img class=\"banner\" src=\"%s\" alt=\"section banner\"/>",
  461. $fff->extras['banner']);
  462. }
  463. $new = sprintf("<div class=\"content_element_page %s\">"
  464. ."<a name=\"%s\">%s</a>\n%s\n</div>",
  465. $class,
  466. $anchor_name,
  467. $banner,
  468. implode("\n",$fff->content['default']));
  469. break;
  470. case 'youtube':
  471. $vid=array_shift($request);
  472. $pos= array_shift($request);
  473. if( in_array($pos,array('left','right','full'))) {
  474. $class = $pos;
  475. } else {
  476. $class = 'left';
  477. }
  478. $video=sprintf("<iframe width=\"700\" height=\"394\" class=\"ytvideo\" "
  479. ."src=\"https://www.youtube.com/embed/%s\"></iframe>",
  480. $vid);
  481. $thumbnail = sprintf("<div class=\"video-thumbnail\"><a href=\"%s\" data-featherlight=\"#%s\">"
  482. ."<img class=\"thumbnail\" src=\"https://img.youtube.com/vi/%s/mqdefault.jpg\" alt=\"video-preview\"/>"
  483. ."<img class=\"play-button\" src=\"%s\" alt=\"play-button\" />"
  484. ."</a></div><div class=\"lightbox\" id=\"%s\" >%s</div>",
  485. "https://www.youtube.com/watch?v=".$vid,
  486. $vid,
  487. $vid,
  488. "/rsc/img/play-button.png",
  489. $vid,
  490. $video
  491. );
  492. foreach ($body as $k=>$line) {
  493. if (strpos($line,"©") !== FALSE
  494. || strpos($line,"&copy;") !== FALSE) {
  495. $body[$k] = sprintf("<span class=\"copyright\">%s</span>",$line);
  496. }
  497. }
  498. $new=sprintf("<div class='video-container %s'>"
  499. ."<div class=\"media\">%s</div>"
  500. ."<div class=\"caption\">%s</div>"
  501. ."</div>",
  502. $class,
  503. $thumbnail,
  504. $md->text(implode("\n",$body)));
  505. break;
  506. default:
  507. $new=FilesInFolders::warn("Content Module \"".$request[0]."\" unknown");
  508. break;
  509. }
  510. return $new;
  511. }
  512. }