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.

filesinfolders.php 39KB

3 jaren geleden
3 jaren geleden
3 jaren geleden
4 jaren geleden
4 jaren geleden
4 jaren geleden
4 jaren geleden
4 jaren geleden
1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024
  1. <?php
  2. namespace Modules;
  3. class FilesInFolders {
  4. private $folder;
  5. public $content = array();
  6. public $extras = array();
  7. private $domains = array('default'=>'default');
  8. private $keyfiles = array();
  9. public $structs = array();
  10. public $EXT=array(
  11. 'txt'=>array( 'txt', 'text', 'md' ),
  12. 'pic'=>array( 'jpg', 'jpeg', 'png', 'svg' ),
  13. 'tpl'=>array( 'html', 'htm' ),
  14. 'audio'=>array('mp3','wav','ogg'),
  15. 'csv'=>array( 'csv' )
  16. );
  17. public $config = array();
  18. private $state=array();
  19. function __construct($folder,$conf=array()) {
  20. debug("about to construct FIF: $folder");
  21. $f3 = \Base::instance();
  22. if(is_dir($folder)) { // are we given a valid path?
  23. $this->folder = $folder;
  24. } else { // and if not?
  25. $this->folder = $f3->get('CONTENT')."./";
  26. }
  27. if(is_array($conf)) {
  28. foreach($conf as $key=>$value) {
  29. switch($key) {
  30. case 'content':
  31. if(is_array($value)) {
  32. foreach($value as $k=>$v) {
  33. $this->domains[$k] = $v;
  34. }
  35. }
  36. break;
  37. case 'keyfiles':
  38. if(is_array($value)) {
  39. foreach($value as $k=>$v) {
  40. $this->keyfiles[$k] = $v;
  41. }
  42. }
  43. break;
  44. }
  45. }
  46. }
  47. foreach($this->domains as $domain) {
  48. $this->content[$domain] = array();
  49. }
  50. foreach($this->keyfiles as $keys=>$d) {
  51. $this->extras[$keys] = "";
  52. }
  53. debug("constructed files in folder: $folder");
  54. }
  55. /////////////////////////////
  56. // read folder into struct //
  57. /////////////////////////////
  58. function prepare_files() {
  59. foreach ($this->domains as $k=>$v) {
  60. foreach($this->EXT as $cat=>$endings) {
  61. $this->structs[$k][$cat]=array();
  62. }
  63. }
  64. $ls = scandir($this->folder);
  65. foreach ($ls as $k=>$f) {
  66. if (!strncmp($f,'.',1)) continue; // ignore hidden files
  67. $ex=explode(".", $f);
  68. $ext=strtolower(end($ex));
  69. if (array_key_exists($ex[0],$this->domains)) {
  70. $domain_key=$ex[0];
  71. $sort_key=1;
  72. } elseif (array_key_exists($ex[0], $this->keyfiles)) {
  73. if(in_array($ext,$this->EXT[$this->keyfiles[$ex[0]]['type']])) {
  74. $this->extras[$ex[0]]=$this->folder.$f;
  75. continue;
  76. }
  77. $domain_key='default';
  78. $sort_key=0;
  79. } else {
  80. $domain_key='default';
  81. $sort_key=0;
  82. }
  83. foreach ($this->EXT as $cat=>$endings) {
  84. if (in_array($ext, $endings)) {
  85. $this->structs[$domain_key][$cat][$ex[$sort_key]] = $this->folder.$f;
  86. break;
  87. }
  88. }
  89. }
  90. foreach($this->keyfiles as $key=>$param) {
  91. if(!$this->extras[$key]) {
  92. $this->extras[$key] = self::search_up(
  93. $key,
  94. array($this->folder,$param['until']),
  95. $this->EXT[$param['type']]
  96. );
  97. }
  98. if($this->extras[$key]) {
  99. if ($param['type'] == 'txt') {
  100. $this->read_textfile($this->extras[$key]);
  101. }
  102. }
  103. }
  104. }
  105. ///////////////////////////////////////
  106. // prepare content as per the struct //
  107. ///////////////////////////////////////
  108. function fill_content() {
  109. $f3 = \Base::instance();
  110. $md = new \freaParsedown();
  111. $md->deactivate_ol();
  112. //var_dump($md->get_BlockTypes());
  113. foreach($this->domains as $domain_key=>$domain) {
  114. // don't act on hidden files
  115. if ($domain == 'hidden') { continue; }
  116. $this->state['current_domain'] = $domain_key;
  117. foreach($this->structs[$domain_key]['txt'] as $key=>$file) {
  118. $str = $this->read_textfile($file);
  119. $str = self::content_element_dispatcher($str);
  120. $str = $md->text($str);
  121. //$str = sprintf("%s", $str);
  122. $this->content[$domain][$key."30text"] = sprintf(
  123. "<div class=\"item %s %s\"><a name=\"%s\"></a>%s</div>",
  124. '',
  125. $key,
  126. $key,
  127. $str
  128. );
  129. }
  130. $includeTemplates = array_key_exists('includeTemplates', $this->config)
  131. ? $this->config['includeTemplates']
  132. : ($f3->get('includeTemplates') ? : FALSE)
  133. ;
  134. if ($includeTemplates) {
  135. foreach($this->structs[$domain_key]['tpl'] as $key=>$file) {
  136. $str = \Template::instance()->render(substr($file,7));
  137. $str = self::linkify($str);
  138. $this->content[$domain][$key."00tpl"] = sprintf(
  139. "<div class=\"item %s %s\">%s</div>",
  140. '',
  141. $key,
  142. $str
  143. );
  144. }
  145. }
  146. $bulkIncludePic = array_key_exists('bulkIncludePic',$this->config)
  147. ? $this->config['bulkIncludePic']
  148. : ($f3->get('bulkIncludePic') ? : FALSE)
  149. ;
  150. if ($bulkIncludePic) {
  151. foreach($this->structs[$domain_key]['pic'] as $key=>$file) {
  152. $image_include_version = 2;
  153. switch ($image_include_version) {
  154. case 1:
  155. $this->content[$domain][$key."10image"] = sprintf(
  156. "<img class=\"bulkImportedImage $bulkIncludePic\" src=\"/$file\" />"
  157. );
  158. break;
  159. case 2:
  160. $module = new CEimage(['image',$file,$bulkIncludePic,'gallery']);
  161. $this->content[$domain][$key."10image"] = $module->index();
  162. unset($module);
  163. break;
  164. case 3:
  165. //$this->content[$domain][] = "asdasd";
  166. break;
  167. }
  168. }
  169. }
  170. $bulkIncludeAudio = array_key_exists('bulkIncludeAudio',$this->config)
  171. ? $this->config['bulkIncludeAudio']
  172. : ($f3->get('bulkIncludeAudio') ? : FALSE)
  173. ;
  174. if ($bulkIncludeAudio) {
  175. foreach ($this->structs[$domain_key]['audio'] as $key=>$file) {
  176. $this->content[$domain][$key."20audio"] = sprintf(
  177. '<a href="%s" class="audio">%s</a><br>',
  178. $file, $key
  179. );
  180. }
  181. }
  182. foreach($this->structs[$domain_key]['csv'] as $key=>$file) {
  183. $csv = new \Modules\Ography($file,TRUE);
  184. $str="<table>";
  185. foreach($csv->entries as $entry) {
  186. $tmp="";
  187. foreach($entry as $key=>$value) {
  188. $tmp .= sprintf("<td class=\"%s\">%s</td>", $key, $value);
  189. }
  190. $str .= sprintf("<tr>%s</tr>",$tmp);
  191. }
  192. $str.="</table>";
  193. $this->content[$domain][$key."30csv"] = $str;
  194. }
  195. }
  196. }
  197. //////////////////////
  198. // read config data //
  199. //////////////////////
  200. function read_config($domain=false) {
  201. foreach ($this->domains as $source=>$destination) {
  202. if (is_string($domain)) {
  203. if ($source != $domain) { continue; }
  204. } elseif (is_array($domain)) {
  205. if (!in_array($source,$domain)) { continue; }
  206. }
  207. foreach ($this->structs[$source]['txt'] as $key=>$file) {
  208. $this->read_textfile($file);
  209. }
  210. }
  211. return $this->config;
  212. }
  213. ////////////////
  214. // recursions //
  215. ////////////////
  216. function search_up($key,$paths,$ext) {
  217. $return = "";
  218. if(count($paths) == 2) {
  219. $current = $paths[0];
  220. $last_try = $paths[1];
  221. $ls=scandir($current);
  222. foreach($ls as $f) {
  223. if(!strncmp($f,'.',1)) continue; // ignore hidden files
  224. $ex=explode(".", $f);
  225. if(in_array(strtolower(end($ex)),$ext)) {
  226. if($ex[0]==$key) {
  227. $return = $current.$f;
  228. break;
  229. }
  230. }
  231. }
  232. }
  233. if ($return) {
  234. return $return;
  235. } elseif($current == $last_try) {
  236. return false;
  237. } else {
  238. $p = explode('/',$current);
  239. array_pop($p);
  240. array_pop($p);
  241. return self::search_up($key,array(implode("/",$p)."/",$last_try),$ext);
  242. }
  243. }
  244. ///////////////////////
  245. // Utility functions //
  246. ///////////////////////
  247. function read_textfile($file) {
  248. debug("about to read file: $file");
  249. $str = file_get_contents($file);
  250. debug("read file: $file");
  251. $str = self::linkify($str);
  252. $str = self::strip_comments($str);
  253. $str = self::get_config_from_content($str);
  254. debug("processed file: $file");
  255. return $str;
  256. }
  257. function strip_comments($str) {
  258. $single_line_comments = "/(^;.*\R)/m";
  259. $str = preg_replace($single_line_comments,"",$str);
  260. $multi_line_comments = "/\/\*.*?\*\//s";
  261. $str = preg_replace($multi_line_comments,"",$str);
  262. return $str;
  263. }
  264. function linkify($string) {
  265. $pattern = "/\s@(\w+)[=]([\w,]+)\s/";
  266. $count = 0;
  267. $new = preg_replace_callback
  268. ($pattern,
  269. function($m){
  270. $f3 = \Base::instance();
  271. return $f3->get('SITE_URL')
  272. .$f3->alias($m[1],self::$keyword."=".$m[2])
  273. ;},
  274. $string);
  275. return $new;
  276. }
  277. function get_config_from_content($string) {
  278. $f3 = \Base::instance();
  279. $f = 0;
  280. $pattern = "/#\+(\w+):\s?(.*)/";
  281. $f = preg_match_all($pattern, $string,$matches,PREG_PATTERN_ORDER);
  282. for ($i=0;$i<$f;$i++) {
  283. $string = str_replace($matches[0][$i],"",$string);
  284. $key = $matches[1][$i];
  285. $value = trim($matches[2][$i]);
  286. if(strtolower($value) == "false") {
  287. $value = FALSE;
  288. }
  289. if(!strncmp(trim($value),'@',1)) {
  290. //var_dump($f3->get('DATA'));
  291. if (array_key_exists($key,$f3->get('DATA'))) {
  292. $DATA = $f3->get('DATA.'.$key);
  293. $conf = array($DATA['type'],$DATA['dir']);
  294. $relation = new \Modules\TOC($conf,$f3->get('CONTENT'),substr($value,1));
  295. $relation->dispatch();
  296. $this->config[$key]=array_shift($relation->entries);
  297. } else {
  298. $this->config[$key]=$value;
  299. }
  300. } else {
  301. $this->config[$key]=$value;
  302. }
  303. }
  304. $pattern = "/§>\s*(\w+):(.*?)\R[\011\040]*\R/s";
  305. $f = preg_match_all($pattern, $string,$matches,PREG_PATTERN_ORDER);
  306. for ($i=0;$i<$f;$i++) {
  307. $string = str_replace($matches[0][$i],"",$string);
  308. $key = $matches[1][$i];
  309. $value = trim($matches[2][$i]);
  310. if(strtolower($value) == "false") {
  311. $value = FALSE;
  312. }
  313. if (!strncmp($value,'@',1)) {
  314. # var_dump();
  315. if (array_key_exists($key,$f3->get('DATA'))) {
  316. $entries = explode("@",$value);
  317. array_shift($entries); // first entry is always empty
  318. $DATA = $f3->get('DATA.'.$key);
  319. $conf = array($DATA['type'],$DATA['dir']);
  320. $relation = new \Modules\TOC($conf,$f3->get('CONTENT'),$entries);
  321. $relation->dispatch();
  322. if(/*count($entries) >*/ 1) {
  323. $this->config[$key]= new CMultiple($relation->entries);
  324. } else {
  325. $this->config[$key]=array_shift($relation->entries);
  326. }
  327. } else {
  328. $this->config[$key]=$value;
  329. }
  330. } else {
  331. $this->config[$key]=$value;
  332. }
  333. }
  334. return $string;
  335. }
  336. function content_element_dispatcher($string) {
  337. $f3 = \Base::instance();
  338. $md = new \freaParsedown();
  339. $md->deactivate_ol();
  340. $f0 = 0;
  341. // find occorances of {| keyword |}
  342. $pattern = "/\{\|(.+?)\|\}/s";
  343. $f = preg_match_all($pattern, $string,$matches,PREG_PATTERN_ORDER);
  344. for ($i=0;$i<$f;$i++) {
  345. $body = preg_split("/\R/",trim($matches[1][$i]));
  346. $request = explode(":", trim(array_shift($body)));
  347. $new="";
  348. switch($request[0]) {
  349. case 'test':
  350. $new="seems to work";
  351. break;
  352. case ';':
  353. $new="";
  354. break;
  355. case 'path':
  356. $new="/".$this->folder;
  357. break;
  358. case 'space':
  359. $new=sprintf("<div style=\"height:%s;\"></div>",
  360. $request[1]
  361. );
  362. break;
  363. case 'span':
  364. $new=sprintf("<span class=\"%s\">%s</span>",
  365. $request[1],
  366. $request[2] ? : implode("\n",$body)
  367. );
  368. break;
  369. case 'small-text':
  370. if(count($body)) {
  371. $new=sprintf("<div class=\"smalltext\">%s</div>",
  372. $md->text(implode("\n",$body))
  373. );
  374. } else {
  375. $new=sprintf("<span class=\"smalltext\">%s</span>",
  376. $request[1]
  377. );
  378. }
  379. break;
  380. case 'CE':
  381. switch($request[1]) {
  382. case 'publication':
  383. $CE = new \Modules\CPublication($this->config,['path'=>$this->folder]);
  384. if(count($request)>2) {
  385. $CE->set_layout($request[2]);
  386. }
  387. $new = $CE;
  388. break;
  389. }
  390. break;
  391. case 'TOC':
  392. // throw away TOC part of request, we don't need it
  393. array_shift($request);
  394. $toc = new \Modules\TOC($request,$this->folder,$body);
  395. $toc->dispatch();
  396. $new=sprintf("<div class=\"TOC %s\">%s</div>",
  397. array_shift($request),
  398. $toc);
  399. break;
  400. case 'sql':
  401. //array_shift($request);
  402. switch ($request[1]) {
  403. case 'sqlite':
  404. $array = [];
  405. $db = new \DB\SQL('sqlite:' . $this->folder . $request[2]);
  406. $sql = implode(" ", $body);
  407. if ( strpos($sql,'insert')===false &&
  408. strpos($sql,'update')===false &&
  409. strpos($sql,'drop')===false) {
  410. $rows = $db->exec($sql);
  411. foreach ($rows as $res) {
  412. switch (count($res)) {
  413. case 1:
  414. $keys=array_keys($res);
  415. $array[] = $res[$keys[0]];
  416. break;
  417. case 2:
  418. $keys=array_keys($res);
  419. $array[$res[$keys[0]]] = $res[$keys[1]];
  420. break;
  421. }
  422. }
  423. }
  424. $new = sprintf("<ul><li>%s</li></ul>",
  425. implode("</li><li>",$array));
  426. unset($array);
  427. break;
  428. }
  429. break;
  430. case 'form':
  431. $token_db = $f3->get('TEMP') . "CEform/";
  432. $form_config_file = sprintf("%s%s.cfg",
  433. ROOT.$this->folder,
  434. $request[1]);
  435. $db = new \DB\Jig($token_db,\DB\Jig::FORMAT_JSON);
  436. $formcall = new \DB\Jig\Mapper($db,'form_calls');
  437. $timestamp = time();
  438. $token = md5($timestamp . $form_config_file . rand(100,999));
  439. $f3->config($form_config_file);
  440. $fields = $f3->get('fields');
  441. foreach ($fields as $k => $v) {
  442. if ($v['type'] == 'custom') {
  443. $fields[$k]['template'] = sprintf(
  444. "%s%s",
  445. substr($this->folder,strlen($f3->get('CONTENT_BASE'))),
  446. $v['template']
  447. );
  448. }
  449. if (array_key_exists('db',$v)) {
  450. switch ($v['db']['type']) {
  451. case 'sqlite':
  452. $array = [];
  453. $db = new \DB\SQL('sqlite:' . $this->folder . $v['db']['file']);
  454. $sql = $v['db']['sql'];
  455. if ( strpos($sql,'insert')===false &&
  456. strpos($sql,'update')===false &&
  457. strpos($sql,'drop')===false) {
  458. $rows = $db->exec($sql);
  459. foreach ($rows as $res) {
  460. switch (count($res)) {
  461. case 2:
  462. $keys=array_keys($res);
  463. $array[$res[$keys[0]]] = $res[$keys[1]];
  464. break;
  465. }
  466. }
  467. }
  468. $fields[$k]['el'] = $array;
  469. unset($array);
  470. break;
  471. }
  472. }
  473. }
  474. $f3->set('fields',
  475. array_merge(
  476. $fields,
  477. ['xss-token'=>[
  478. 'type'=>'hidden',
  479. 'value'=>$token,
  480. 'length'=>strlen($token)
  481. ]]
  482. ));
  483. $formcall->token = $token;
  484. $formcall->timestamp = $timestamp;
  485. $formcall->form = $form_config_file;
  486. $formcall->path = ROOT.$this->folder;
  487. $formcall->save();
  488. $form_view = new \Template;
  489. $new=$form_view->render('form.htm');
  490. break;
  491. case 'box':
  492. array_shift($request); //get rid of identifier
  493. $type = array_shift($request);
  494. $pics = explode(":",array_shift($body));
  495. $pic = $pics[0];
  496. $pic_hover = count($pics) > 1 ? $pics[1] : $pic;
  497. if (count($body) >= 3) {
  498. $caption = ['normal'=>['cap1' => array_shift($body),
  499. 'cap2' => array_shift($body)],
  500. 'hover'=> ['cap1' => array_shift($body),
  501. 'cap2' => array_shift($body)]];
  502. $caption_html=[];
  503. foreach ($caption as $state => $set) {
  504. if(!$set['cap2']) {
  505. $caption_html[$state] = [
  506. sprintf('<span class="first">&nbsp;</span>'),
  507. sprintf('<span class="first">%s</span>',$set['cap1'])
  508. ];
  509. } else if (!$set['cap1'] && $set['cap2']) {
  510. $caption_html[$state] = [
  511. sprintf('<span class="second">%s</span>',$set['cap2'])
  512. ];
  513. } else {
  514. $caption_html[$state] = [
  515. sprintf('<span class="first">%s</span>',$set['cap1']?:"&nbsp;"),
  516. sprintf('<span class="second">%s</span>',$set['cap2'])
  517. ];
  518. }
  519. }
  520. $has_caption = TRUE;
  521. } else {
  522. $has_caption = FALSE;
  523. }
  524. if (file_exists($this->folder.$pic)) {
  525. $pic = $this->folder.$pic;
  526. } else {
  527. $pic = $f3->get('RESOURCES')."img/default_img.png";
  528. }
  529. if (file_exists($this->folder.$pic_hover)) {
  530. $pic_hover = $this->folder.$pic_hover;
  531. } else {
  532. $pic_hover = $pic;
  533. }
  534. if(0) {
  535. $PIC = new \Image($pic);
  536. $orientation = $PIC->width() > $PIC->height()
  537. ? 'landscape'
  538. : 'portrait'
  539. ;
  540. unset($PIC);
  541. } else {
  542. list($wwidth, $hheight) = getimagesize($pic);
  543. $orientation = $wwidth > $hheight ? 'landscape' : 'portrait';
  544. }
  545. $pic = new CachedImage($pic);
  546. $pic_hover = new CachedImage($pic_hover);
  547. $class="";
  548. $add="";
  549. switch($type) {
  550. case 'plain':
  551. $link=false;
  552. break;
  553. case 'download':
  554. $file = "/".$this->folder.implode(":",$request);
  555. $link='href="'.$file.'" download ';
  556. break;
  557. case 'lightbox':
  558. $body = implode("\n",$body);
  559. if (count($request) % 2) {
  560. $class = array_pop($request);
  561. }
  562. if (count($request) >= 2) {
  563. $body=str_replace([$request[0],$request[1]],["{|","|}"],$body);
  564. $body=$this->content_element_dispatcher($body);
  565. }
  566. $hash=md5($body);
  567. $add=sprintf("<div id=\"%s\" class=\"content_elment_box_body\">\n%s\n</div>",
  568. $hash,
  569. $md->text($body));
  570. $link='href="#" data-featherlight="#'.$hash.'" ';
  571. break;
  572. case 'internal':
  573. $dest=implode(":",$request);
  574. $data = [];
  575. $base = substr($dest,0,strpos($dest,'?') ? : strlen($dest));
  576. parse_str(parse_url($dest,PHP_URL_QUERY),$data);
  577. $fragment = parse_url($dest,PHP_URL_FRAGMENT);
  578. if ($f3->get('LANG') != $f3->get('default_lang')) {
  579. if (!array_key_exists('lang',$data)) {
  580. $data['lang'] = $f3->get('LANG');
  581. }
  582. }
  583. $new_dest = $base;
  584. if (count($data) > 0) {
  585. $new_dest .= "?" . http_build_query($data);
  586. }
  587. if ($fragment) {
  588. $new_dest .= "#" . $fragment;
  589. }
  590. //if ($f3->get('LANG') != $f3->get('default_lang')) {
  591. // $dest .= "?lang=".$f3->get('LANG');
  592. //}
  593. $link=sprintf('href="%s" ',$f3->get('SITE_URL')."/".$new_dest);
  594. break;
  595. case 'external':
  596. $dest=implode(":",$request);
  597. $target = $f3->get('external_links_open_in_new_window')
  598. ? 'target="_blank"'
  599. : ''
  600. ;
  601. $link=sprintf('href="%s" %s',$dest, $target);
  602. break;
  603. default:
  604. $link='href="#"';
  605. break;
  606. }
  607. $new=sprintf("<div class=\"brick %s\">\n<a class=\"content_element_box\" %s>\n<div class=\"content_element_box\">
  608. <div class=\"image\">
  609. <img class=\"standard\" src=\"%s\" /><img class=\"hover\" src=\"%s\" />
  610. </div>
  611. %s
  612. %s
  613. \n</div>\n</a>\n%s\n</div>",
  614. implode(" ",[$orientation,$class,$type]),
  615. $link,
  616. $pic->get_src(1600),
  617. $pic_hover->get_src(1600),
  618. ($has_caption ? "<div class=\"caption standard\">".implode("<br>",$caption_html['normal'])."</div>": " "),
  619. ($has_caption ? "<div class=\"caption hover\">".implode("<br>",$caption_html['hover'])."</div>" : " " ),
  620. $add
  621. );
  622. break;
  623. case 'brick':
  624. array_shift($request);
  625. $class = array_shift($request);
  626. $new = sprintf("<div class=\"content_element brick %s\">\n%s\n</div>",
  627. $class,
  628. $md->text(implode("\n",$body))
  629. );
  630. break;
  631. case 'calendar':
  632. array_shift($request);
  633. $conf = array('path', $this->folder);
  634. $v = $this->read_config();
  635. $cal = new \Modules\CCalendar($v,$conf);
  636. $new=sprintf("<div class=\"calendar\">\n%s\n</div>",
  637. $cal);
  638. break;
  639. case 'header':
  640. array_shift($request);
  641. $conf = array('path', $this->folder);
  642. $v = $this->read_config();
  643. switch (array_shift($request)) {
  644. case 'event':
  645. $el = new CEvent($v,$conf);
  646. $el->set_layout('archive');
  647. $new = $el;
  648. break;
  649. case 'concert':
  650. $el = new CConcert($v,$conf);
  651. $el->set_layout('header');
  652. $new = $el;
  653. break;
  654. }
  655. break;
  656. case 'data':
  657. $method = strtoupper($request[1]);
  658. //$keys = [];
  659. if (in_array($method,['POST','GET','SESSION'])) {
  660. foreach ($body as $line) {
  661. $key = explode("=",$line);
  662. $raw = $f3->get($method.'.'.$key[0]);
  663. if (count($key) >= 2) {
  664. $type=$key[1];
  665. } else {
  666. $type = false;
  667. }
  668. switch ($type) {
  669. case 'base64':
  670. $new = urlsafe_b64decode($raw);
  671. break;
  672. default:
  673. $new = $raw;
  674. }
  675. }
  676. //var_dump($new);
  677. }
  678. break;
  679. case 'buy':
  680. $new = '';
  681. if(count($request)>=2) {
  682. $name=$request[1];
  683. } else {
  684. $name ="item";
  685. }
  686. if(count($request)>=3) {
  687. $price=$request[2];
  688. } else {
  689. $price=1.0;
  690. }
  691. $fields = [
  692. 'caller' => $f3->get('page'),
  693. 'name'=>$name,
  694. 'price'=>$price,
  695. 'amount'=>1
  696. ];
  697. $hidden_inputs = [];
  698. foreach ($fields as $k=>$v) {
  699. $hidden_inputs[] = sprintf('<input type="hidden" name="%s" value="%s" />',$k,$v);
  700. }
  701. $new = sprintf('<form method="post" action="%s">%s<button action="submit" >BUY</button><span class="price"> %s</span></form>',
  702. '/api/cart/add',
  703. implode("\n",$hidden_inputs),
  704. $price ."€"
  705. );
  706. break;
  707. case 'checkout':
  708. //first argument, if present, is a path to folder containing order database
  709. $path = '';
  710. if (count($request) > 1) {
  711. $add_path = $request[1];
  712. if (strncmp($add_path,"/",1)) {
  713. $path = $this->folder.$add_path;
  714. } else {
  715. $path = $add_path;
  716. }
  717. } else {
  718. $path = $this->folder;
  719. }
  720. $checkout = new \Controller\Checkout($path);
  721. $new = $checkout->index();
  722. break;
  723. case 'only_cart':
  724. $checkout = new \Controller\Checkout($this->folder);
  725. $new = $checkout->html_cart();
  726. break;
  727. case 'image':
  728. $module = new CEimage($request, $body, $this->structs, $this->content);
  729. $new = $module->index();
  730. unset($module);
  731. break;
  732. case 'devide':
  733. $contents = explode($request[1],implode("\n",$body));
  734. $c=count($contents);
  735. $str="";
  736. for ($iiii=0;$iiii<$c;$iiii++) {
  737. $str .= sprintf(" %f%%",100/$c);
  738. }
  739. $template = sprintf('grid-template-columns:%s;',
  740. $str);
  741. $counter=0;
  742. $new = sprintf('<div class="content_element_devided" style="%s">',$template);
  743. foreach($contents as $part) {
  744. $counter++;
  745. if (count($request) >= 4) {
  746. $part=str_replace([$request[2],$request[3]],["{|","|}"],$part);
  747. $part=$this->content_element_dispatcher($part);
  748. }
  749. $new .= sprintf("<div>\n%s\n</div>",
  750. $md->text($part)
  751. );
  752. }
  753. $new.="</div>";
  754. break;
  755. case 'page':
  756. array_shift($request);
  757. $target = array_shift($request);
  758. $class = array_shift($request);
  759. $folder = $this->folder.$target."/";
  760. $anchor_name=array_pop(explode("/",$target));
  761. $fff = new \Modules\FilesInFolders(
  762. $folder,
  763. ['content'=>[
  764. 'secondary'=>'secondary',
  765. 'zzz'=>'hidden',
  766. 'unpublish'=>'hidden'],
  767. 'keyfiles'=>[
  768. 'banner'=>[
  769. 'until'=>$folder,
  770. 'type'=>'pic']]]
  771. );
  772. $fff->prepare_files();
  773. foreach ($body as $line) {
  774. $ccc = explode(":",$line);
  775. if (count($ccc) == 2) {
  776. if ($ccc[1] == 'false') {
  777. $ccc[1] = false;
  778. }
  779. $fff->config[$ccc[0]] = $ccc[1];
  780. }
  781. }
  782. $fff->fill_content();
  783. //var_dump($fff->config);
  784. $banner = "";
  785. if ($fff->extras['banner']) {
  786. $banner=sprintf("<img class=\"banner\" src=\"%s\" alt=\"section banner\"/>",
  787. $fff->extras['banner']);
  788. }
  789. $new = sprintf("<div class=\"content_element_page %s\">"
  790. ."<a name=\"%s\">%s</a>\n%s\n</div>",
  791. $class,
  792. $anchor_name,
  793. $banner,
  794. implode("\n",$fff->content['default']));
  795. break;
  796. case 'youtube':
  797. $vid=array_shift($request);
  798. $pos= array_shift($request);
  799. if( in_array($pos,array('left','right','full'))) {
  800. $class = $pos;
  801. } else {
  802. $class = 'left';
  803. }
  804. $video=sprintf("<iframe width=\"700\" height=\"394\" class=\"ytvideo\" "
  805. ."src=\"https://www.youtube.com/embed/%s\"></iframe>",
  806. $vid);
  807. $thumbnail = sprintf("<div class=\"video-thumbnail\"><a href=\"%s\" data-featherlight=\"#%s\">"
  808. ."<img class=\"thumbnail\" src=\"https://img.youtube.com/vi/%s/mqdefault.jpg\" alt=\"video-preview\"/>"
  809. ."<img class=\"play-button\" src=\"%s\" alt=\"play-button\" />"
  810. ."</a></div><div class=\"lightbox\" id=\"%s\" >%s</div>",
  811. "https://www.youtube.com/watch?v=".$vid,
  812. $vid,
  813. $vid,
  814. "/rsc/img/play-button.png",
  815. $vid,
  816. $video
  817. );
  818. foreach ($body as $k=>$line) {
  819. if (strpos($line,"©") !== FALSE
  820. || strpos($line,"&copy;") !== FALSE) {
  821. $body[$k] = sprintf("<span class=\"copyright\">%s</span>",$line);
  822. }
  823. }
  824. $new=sprintf("<div class='video-container %s'>"
  825. ."<div class=\"media\">%s</div>"
  826. ."<div class=\"caption\">%s</div>"
  827. ."</div>",
  828. $class,
  829. $thumbnail,
  830. $md->text(implode("\n",$body)));
  831. break;
  832. default:
  833. $new=self::warn("Content Module \"".$request[0]."\" unknown");
  834. break;
  835. }
  836. $string = str_replace($matches[0][$i],$new,$string);
  837. }
  838. return $string;
  839. }
  840. function warn($message) {
  841. return sprintf("<div class=\"warning\">%s</div>",$message);
  842. }
  843. }
  844. class CEimage
  845. {
  846. var $r;
  847. var $b;
  848. var $structs;
  849. var $content;
  850. function __construct($request,$body=[],$structs=false,$content=false) {
  851. $this->r = $request;
  852. $this->b = $body;
  853. $this->structs = &$structs;
  854. $this->content = &$content;
  855. }
  856. function is_width($string) {
  857. $pattern="/^[0-9]+%$/";
  858. if (preg_match($pattern,$string)) {
  859. return true;
  860. } else {
  861. return false;
  862. }
  863. }
  864. function index() {
  865. $md = new \freaParsedown();
  866. $request = $this->r;
  867. $body = $this->b;
  868. $key=$request[1];
  869. $image="";
  870. $new="";
  871. // see if we can find image
  872. if ( is_file($request[1])) {
  873. $image= $request[1];
  874. } else if ($this->structs) {
  875. foreach($this->structs as $domain=>$destination) {
  876. if(array_key_exists($key, $this->structs[$domain]['pic'])) {
  877. $image = $this->structs[$domain]['pic'][$key];
  878. unset($this->structs[$domain]['pic'][$key]);
  879. unset($this->content[$this->domains[$domain]][$key]);
  880. break;
  881. }
  882. }
  883. }
  884. if ($image) {
  885. // image positioning
  886. if( in_array($request[2],array('left','right','full','auto'))) {
  887. $class = $request[2];
  888. } else {
  889. $class = 'full';
  890. }
  891. if (isset($request[3])) {
  892. $width=self::is_width($request[3]) ? $request[3] : false;
  893. }
  894. $gallery = "gallery";
  895. // image orientation?
  896. $img = new \Image($image);
  897. // $ratio = "landscape";
  898. $ratio = ($img->width() >= $img->height())
  899. ? "landscape"
  900. : "portrait"
  901. ;
  902. unset($img);
  903. $cached = new CachedImage($image);
  904. // identify if caption contains a copyright note
  905. // if so, indicate with a class
  906. foreach ($body as $k=>$line) {
  907. if (strpos($line,"©") !== FALSE
  908. || strpos($line,"&copy;") !== FALSE) {
  909. $body[$k] = sprintf("<span class=\"copyright\">%s</span>",$line);
  910. }
  911. }
  912. $new=sprintf("<div class='content_element_image %s'>"
  913. ."<div class=\"media %s\" %s><a href=\"%s\" class=\"$gallery\"><img src=\"%s\" alt=\"user supplied image\" /></a></div>"
  914. ."<img src=\"%s\" style=\"display:none;\" alt=\"user supplied image\" />"
  915. ."<div class=\"caption\">%s</div>"
  916. ."</div>",
  917. $class,
  918. $ratio,
  919. ($width ? "style=\"flex-basis:$width;\"" : ''),
  920. $cached->get_src(1600),
  921. $cached->get_src(1600),
  922. $cached->get_src(1600),
  923. $md->text(implode("\n",$body))
  924. );
  925. unset($cached);
  926. } else {
  927. // image not found
  928. $new=sprintf("<div class='content_element_image %s'>\n"
  929. ."<div class=\"media %s\">\n"
  930. ."<div class=\"caption\">\n%s\n</div>\n"
  931. ."</div>\n",
  932. $class,
  933. $ratio,
  934. $md->text(implode("\n",$body))
  935. );
  936. }
  937. return $new;
  938. }
  939. }