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 34KB

4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893
  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. private $EXT=array(
  11. 'txt'=>array( 'txt', 'text', 'md' ),
  12. 'pic'=>array( 'jpg', 'jpeg', 'png', 'svg' ),
  13. 'tpl'=>array( 'html', 'htm', 'tpl' ),
  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. $page,
  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. $page,
  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. $this->content[$domain][$key."10image"] = sprintf(
  153. "<img class=\"bulkImportedImage $bulkIncludePic\" src=\"/$file\" />"
  154. );
  155. }
  156. }
  157. $bulkIncludeAudio = array_key_exists('bulkIncludeAudio',$this->config)
  158. ? $this->config['bulkIncludeAudio']
  159. : $f3->get('bulkIncludeAudio') ? : FALSE
  160. ;
  161. if ($bulkIncludeAudio) {
  162. foreach ($this->structs[$domain_key]['audio'] as $key=>$file) {
  163. $this->content[$domain][$key."20audio"] = sprintf(
  164. '<a href="%s" class="audio">%s</a><br>',
  165. $file, $key
  166. );
  167. }
  168. }
  169. foreach($this->structs[$domain_key]['csv'] as $key=>$file) {
  170. $csv = new \Modules\Ography($file,TRUE);
  171. $str="<table>";
  172. foreach($csv->entries as $entry) {
  173. $tmp="";
  174. foreach($entry as $key=>$value) {
  175. $tmp .= sprintf("<td class=\"%s\">%s</td>", $key, $value);
  176. }
  177. $str .= sprintf("<tr>%s</tr>",$tmp);
  178. }
  179. $str.="</table>";
  180. $this->content[$domain][$key."30csv"] = $str;
  181. }
  182. }
  183. }
  184. //////////////////////
  185. // read config data //
  186. //////////////////////
  187. function read_config($domain=false) {
  188. foreach ($this->domains as $source=>$destination) {
  189. if (is_string($domain)) {
  190. if ($source != $domain) { continue; }
  191. } elseif (is_array($domain)) {
  192. if (!in_array($source,$domain)) { continue; }
  193. }
  194. foreach ($this->structs[$source]['txt'] as $key=>$file) {
  195. $this->read_textfile($file);
  196. }
  197. }
  198. return $this->config;
  199. }
  200. ////////////////
  201. // recursions //
  202. ////////////////
  203. function search_up($key,$paths,$ext) {
  204. $return = "";
  205. if(count($paths) == 2) {
  206. $current = $paths[0];
  207. $last_try = $paths[1];
  208. $ls=scandir($current);
  209. foreach($ls as $f) {
  210. if(!strncmp($f,'.',1)) continue; // ignore hidden files
  211. $ex=explode(".", $f);
  212. if(in_array(strtolower(end($ex)),$ext)) {
  213. if($ex[0]==$key) {
  214. $return = $current.$f;
  215. break;
  216. }
  217. }
  218. }
  219. }
  220. if ($return) {
  221. return $return;
  222. } elseif($current == $last_try) {
  223. return false;
  224. } else {
  225. $p = explode('/',$current);
  226. array_pop($p);
  227. array_pop($p);
  228. return self::search_up($key,array(implode("/",$p)."/",$last_try),$ext);
  229. }
  230. }
  231. ///////////////////////
  232. // Utility functions //
  233. ///////////////////////
  234. function read_textfile($file) {
  235. debug("about to read file: $file");
  236. $str = file_get_contents($file);
  237. debug("read file: $file");
  238. $str = self::linkify($str);
  239. $str = self::strip_comments($str);
  240. $str = self::get_config_from_content($str);
  241. debug("processed file: $file");
  242. return $str;
  243. }
  244. function strip_comments($str) {
  245. $single_line_comments = "/(^;.*\R)/m";
  246. $str = preg_replace($single_line_comments,"",$str);
  247. $multi_line_comments = "/\/\*.*?\*\//s";
  248. $str = preg_replace($multi_line_comments,"",$str);
  249. return $str;
  250. }
  251. function linkify($string) {
  252. $pattern = "/\s@(\w+)[=]([\w,]+)\s/";
  253. $count = 0;
  254. $new = preg_replace_callback
  255. ($pattern,
  256. function($m){
  257. $f3 = \Base::instance();
  258. return $f3->get('SITE_URL')
  259. .$f3->alias($m[1],self::$keyword."=".$m[2])
  260. ;},
  261. $string);
  262. return $new;
  263. }
  264. function get_config_from_content($string) {
  265. $f3 = \Base::instance();
  266. $f = 0;
  267. $pattern = "/#\+(\w+):\s?(.*)/";
  268. $f = preg_match_all($pattern, $string,$matches,PREG_PATTERN_ORDER);
  269. for ($i=0;$i<$f;$i++) {
  270. $string = str_replace($matches[0][$i],"",$string);
  271. $key = $matches[1][$i];
  272. $value = trim($matches[2][$i]);
  273. if(strtolower($value) == "false") {
  274. $value = FALSE;
  275. }
  276. if(!strncmp(trim($value),'@',1)) {
  277. //var_dump($f3->get('DATA'));
  278. if (array_key_exists($key,$f3->get('DATA'))) {
  279. $DATA = $f3->get('DATA.'.$key);
  280. $conf = array($DATA['type'],$DATA['dir']);
  281. $relation = new \Modules\TOC($conf,$f3->get('CONTENT'),substr($value,1));
  282. $relation->dispatch();
  283. $this->config[$key]=array_shift($relation->entries);
  284. } else {
  285. $this->config[$key]=$value;
  286. }
  287. } else {
  288. $this->config[$key]=$value;
  289. }
  290. }
  291. $pattern = "/§>\s*(\w+):(.*?)\R[\011\040]*\R/s";
  292. $f = preg_match_all($pattern, $string,$matches,PREG_PATTERN_ORDER);
  293. for ($i=0;$i<$f;$i++) {
  294. $string = str_replace($matches[0][$i],"",$string);
  295. $key = $matches[1][$i];
  296. $value = trim($matches[2][$i]);
  297. if(strtolower($value) == "false") {
  298. $value = FALSE;
  299. }
  300. if (!strncmp($value,'@',1)) {
  301. # var_dump();
  302. if (array_key_exists($key,$f3->get('DATA'))) {
  303. $entries = explode("@",$value);
  304. array_shift($entries); // first entry is always empty
  305. $DATA = $f3->get('DATA.'.$key);
  306. $conf = array($DATA['type'],$DATA['dir']);
  307. $relation = new \Modules\TOC($conf,$f3->get('CONTENT'),$entries);
  308. $relation->dispatch();
  309. if(/*count($entries) >*/ 1) {
  310. $this->config[$key]= new CMultiple($relation->entries);
  311. } else {
  312. $this->config[$key]=array_shift($relation->entries);
  313. }
  314. } else {
  315. $this->config[$key]=$value;
  316. }
  317. } else {
  318. $this->config[$key]=$value;
  319. }
  320. }
  321. return $string;
  322. }
  323. function content_element_dispatcher($string) {
  324. $f3 = \Base::instance();
  325. $md = new \freaParsedown();
  326. $md->deactivate_ol();
  327. $f0 = 0;
  328. // find occorances of {| keyword |}
  329. $pattern = "/\{\|(.+?)\|\}/s";
  330. $f = preg_match_all($pattern, $string,$matches,PREG_PATTERN_ORDER);
  331. for ($i=0;$i<$f;$i++) {
  332. $body = preg_split("/\R/",trim($matches[1][$i]));
  333. $request = explode(":", trim(array_shift($body)));
  334. $new="";
  335. switch($request[0]) {
  336. case 'test':
  337. $new="seems to work";
  338. break;
  339. case ';':
  340. $new="";
  341. break;
  342. case 'path':
  343. $new="/".$this->folder;
  344. break;
  345. case 'space':
  346. $new=sprintf("<div style=\"height:%s;\"></div>",
  347. $request[1]
  348. );
  349. break;
  350. case 'span':
  351. $new=sprintf("<span class=\"%s\">%s</span>",
  352. $request[1],
  353. $request[2] ? : implode("\n",$body)
  354. );
  355. break;
  356. case 'small-text':
  357. if(count($body)) {
  358. $new=sprintf("<div class=\"smalltext\">%s</div>",
  359. implode("\n",$body)
  360. );
  361. } else {
  362. $new=sprintf("<span class=\"smalltext\">%s</span>",
  363. $request[1]
  364. );
  365. }
  366. break;
  367. case 'TOC':
  368. // throw away TOC part of request, we don't need it
  369. array_shift($request);
  370. $toc = new \Modules\TOC($request,$this->folder,$body);
  371. $toc->dispatch();
  372. $new=sprintf("<div class=\"TOC %s\">%s</div>",
  373. array_shift($request),
  374. $toc);
  375. break;
  376. case 'sql':
  377. //array_shift($request);
  378. switch ($request[1]) {
  379. case 'sqlite':
  380. $array = [];
  381. $db = new \DB\SQL('sqlite:' . $this->folder . $request[2]);
  382. $sql = implode(" ", $body);
  383. if ( strpos($sql,'insert')===false &&
  384. strpos($sql,'update')===false &&
  385. strpos($sql,'drop')===false) {
  386. $rows = $db->exec($sql);
  387. foreach ($rows as $res) {
  388. switch (count($res)) {
  389. case 1:
  390. $keys=array_keys($res);
  391. $array[] = $res[$keys[0]];
  392. break;
  393. case 2:
  394. $keys=array_keys($res);
  395. $array[$res[$keys[0]]] = $res[$keys[1]];
  396. break;
  397. }
  398. }
  399. }
  400. $new = sprintf("<ul><li>%s</li></ul>",
  401. implode("</li><li>",$array));
  402. unset($array);
  403. break;
  404. }
  405. break;
  406. case 'form':
  407. $token_db = $f3->get('TEMP') . "CEform/";
  408. $form_config_file = sprintf("%s%s.cfg",
  409. ROOT.$this->folder,
  410. $request[1]);
  411. $db = new \DB\Jig($token_db,\DB\Jig::FORMAT_JSON);
  412. $formcall = new \DB\Jig\Mapper($db,'form_calls');
  413. $timestamp = time();
  414. $token = md5($timestamp . $form_config_file . rand(100,999));
  415. $f3->config($form_config_file);
  416. $fields = $f3->get('fields');
  417. foreach ($fields as $k => $v) {
  418. if ($v['type'] == 'custom') {
  419. $fields[$k]['template'] = sprintf(
  420. "%s%s",
  421. substr($this->folder,8), //assumens content folder is content
  422. $v['template']
  423. );
  424. }
  425. if (array_key_exists('db',$v)) {
  426. switch ($v['db']['type']) {
  427. case 'sqlite':
  428. $array = [];
  429. $db = new \DB\SQL('sqlite:' . $this->folder . $v['db']['file']);
  430. $sql = $v['db']['sql'];
  431. if ( strpos($sql,'insert')===false &&
  432. strpos($sql,'update')===false &&
  433. strpos($sql,'drop')===false) {
  434. $rows = $db->exec($sql);
  435. foreach ($rows as $res) {
  436. switch (count($res)) {
  437. case 2:
  438. $keys=array_keys($res);
  439. $array[$res[$keys[0]]] = $res[$keys[1]];
  440. break;
  441. }
  442. }
  443. }
  444. $fields[$k]['el'] = $array;
  445. unset($array);
  446. break;
  447. }
  448. }
  449. }
  450. $f3->set('fields',
  451. array_merge(
  452. $fields,
  453. ['xss-token'=>[
  454. 'type'=>'hidden',
  455. 'value'=>$token,
  456. 'length'=>strlen($token)
  457. ]]
  458. ));
  459. $formcall->token = $token;
  460. $formcall->timestamp = $timestamp;
  461. $formcall->form = $form_config_file;
  462. $formcall->path = ROOT.$this->folder;
  463. $formcall->save();
  464. $form_view = new \Template;
  465. $new=$form_view->render('form.htm');
  466. break;
  467. case 'box':
  468. array_shift($request); //get rid of identifier
  469. $type = array_shift($request);
  470. $pics = explode(":",array_shift($body));
  471. $pic = $pics[0];
  472. $pic_hover = count($pics) > 1 ? $pics[1] : $pic;
  473. if (count($body) >= 3) {
  474. $caption = ['normal'=>['cap1' => array_shift($body),
  475. 'cap2' => array_shift($body)],
  476. 'hover'=> ['cap1' => array_shift($body),
  477. 'cap2' => array_shift($body)]];
  478. $caption_html=[];
  479. foreach ($caption as $state => $set) {
  480. if(!$set['cap2']) {
  481. $caption_html[$state] = [
  482. sprintf('<span class="first">&nbsp;</span>'),
  483. sprintf('<span class="first">%s</span>',$set['cap1'])
  484. ];
  485. } else if (!$set['cap1'] && $set['cap2']) {
  486. $caption_html[$state] = [
  487. sprintf('<span class="second">%s</span>',$set['cap2'])
  488. ];
  489. } else {
  490. $caption_html[$state] = [
  491. sprintf('<span class="first">%s</span>',$set['cap1']?:"&nbsp;"),
  492. sprintf('<span class="second">%s</span>',$set['cap2'])
  493. ];
  494. }
  495. }
  496. $has_caption = TRUE;
  497. } else {
  498. $has_caption = FALSE;
  499. }
  500. if (file_exists($this->folder.$pic)) {
  501. $pic = $this->folder.$pic;
  502. } else {
  503. $pic = $f3->get('RESOURCES')."img/default_img.png";
  504. }
  505. if (file_exists($this->folder.$pic_hover)) {
  506. $pic_hover = $this->folder.$pic_hover;
  507. } else {
  508. $pic_hover = $pic;
  509. }
  510. if(0) {
  511. $PIC = new \Image($pic);
  512. $orientation = $PIC->width() > $PIC->height()
  513. ? 'landscape'
  514. : 'portrait'
  515. ;
  516. unset($PIC);
  517. } else {
  518. list($wwidth, $hheight) = getimagesize($pic);
  519. $orientation = $wwidth > $hheight ? 'landscape' : 'portrait';
  520. }
  521. $pic = new CachedImage($pic);
  522. $pic_hover = new CachedImage($pic_hover);
  523. $class="";
  524. $add="";
  525. switch($type) {
  526. case 'plain':
  527. $link=false;
  528. break;
  529. case 'download':
  530. $file = "/".$this->folder.implode(":",$request);
  531. $link='href="'.$file.'" download ';
  532. break;
  533. case 'lightbox':
  534. $body = implode("\n",$body);
  535. if (count($request) % 2) {
  536. $class = array_pop($request);
  537. }
  538. if (count($request) >= 2) {
  539. $body=str_replace([$request[0],$request[1]],["{|","|}"],$body);
  540. $body=$this->content_element_dispatcher($body);
  541. }
  542. $hash=md5($body);
  543. $add=sprintf("<div id=\"%s\" class=\"content_elment_box_body\">\n%s\n</div>",
  544. $hash,
  545. $md->text($body));
  546. $link='href="#" data-featherlight="#'.$hash.'" ';
  547. break;
  548. case 'internal':
  549. $dest=implode(":",$request);
  550. $data = [];
  551. $base = substr($dest,0,strpos($dest,'?') ? : strlen($dest));
  552. parse_str(parse_url($dest,PHP_URL_QUERY),$data);
  553. $fragment = parse_url($dest,PHP_URL_FRAGMENT);
  554. if ($f3->get('LANG') != $f3->get('default_lang')) {
  555. if (!array_key_exists('lang',$data)) {
  556. $data['lang'] = $f3->get('LANG');
  557. }
  558. }
  559. $new_dest = $base;
  560. if (count($data) > 0) {
  561. $new_dest .= "?" . http_build_query($data);
  562. }
  563. if ($fragment) {
  564. $new_dest .= "#" . $fragment;
  565. }
  566. //if ($f3->get('LANG') != $f3->get('default_lang')) {
  567. // $dest .= "?lang=".$f3->get('LANG');
  568. //}
  569. $link=sprintf('href="%s" ',$f3->get('SITE_URL')."/".$new_dest);
  570. break;
  571. case 'external':
  572. $dest=implode(":",$request);
  573. $target = $f3->get('external_links_open_in_new_window')
  574. ? 'target="_blank"'
  575. : ''
  576. ;
  577. $link=sprintf('href="%s" %s',$dest, $target);
  578. break;
  579. default:
  580. $link='href="#"';
  581. break;
  582. }
  583. $new=sprintf("<div class=\"brick %s\">\n<a class=\"content_element_box\" %s>\n<div class=\"content_element_box\">
  584. <div class=\"image\">
  585. <img class=\"standard\" src=\"%s\" /><img class=\"hover\" src=\"%s\" />
  586. </div>
  587. %s
  588. %s
  589. \n</div>\n</a>\n%s\n</div>",
  590. implode(" ",[$orientation,$class,$type]),
  591. $link,
  592. $pic->get_src(1600),
  593. $pic_hover->get_src(1600),
  594. ($has_caption ? "<div class=\"caption standard\">".implode("<br>",$caption_html['normal'])."</div>": " "),
  595. ($has_caption ? "<div class=\"caption hover\">".implode("<br>",$caption_html['hover'])."</div>" : " " ),
  596. $add
  597. );
  598. break;
  599. case 'brick':
  600. array_shift($request);
  601. $class = array_shift($request);
  602. $new = sprintf("<div class=\"content_element brick %s\">\n%s\n</div>",
  603. $class,
  604. $md->text(implode("\n",$body))
  605. );
  606. break;
  607. case 'calendar':
  608. array_shift($request);
  609. $conf = array('path', $this->folder);
  610. $v = $this->read_config();
  611. $cal = new \Modules\CCalendar($v,$conf);
  612. $new=sprintf("<div class=\"calendar\">\n%s\n</div>",
  613. $cal);
  614. break;
  615. case 'header':
  616. array_shift($request);
  617. $conf = array('path', $this->folder);
  618. $v = $this->read_config();
  619. switch (array_shift($request)) {
  620. case 'event':
  621. $el = new CEvent($v,$conf);
  622. $el->set_layout('archive');
  623. $new = $el;
  624. break;
  625. case 'concert':
  626. $el = new CConcert($v,$conf);
  627. $el->set_layout('header');
  628. $new = $el;
  629. break;
  630. }
  631. break;
  632. case 'image':
  633. $module = new CEimage($request, $body, $this->structs, $this->content);
  634. $new = $module->index();
  635. unset($module);
  636. break;
  637. case 'devide':
  638. $contents = explode($request[1],implode("\n",$body));
  639. $c=count($contents);
  640. $str="";
  641. for ($iiii=0;$iiii<$c;$iiii++) {
  642. $str .= sprintf(" %f%%",100/$c);
  643. }
  644. $template = sprintf('grid-template-columns:%s;',
  645. $str);
  646. $counter=0;
  647. $new = sprintf('<div class="content_element_devided" style="%s">',$template);
  648. foreach($contents as $part) {
  649. $counter++;
  650. if (count($request) >= 4) {
  651. $part=str_replace([$request[2],$request[3]],["{|","|}"],$part);
  652. $part=$this->content_element_dispatcher($part);
  653. }
  654. $new .= sprintf("<div>\n%s\n</div>",
  655. $md->text($part)
  656. );
  657. }
  658. $new.="</div>";
  659. break;
  660. case 'page':
  661. array_shift($request);
  662. $target = array_shift($request);
  663. $class = array_shift($request);
  664. $folder = $this->folder.$target."/";
  665. $anchor_name=array_pop(explode("/",$target));
  666. $fff = new \Modules\FilesInFolders(
  667. $folder,
  668. array(
  669. 'content'=>array(
  670. 'secondary'=>'secondary',
  671. 'zzz'=>'hidden',
  672. 'unpublish'=>'hidden'
  673. ))
  674. );
  675. $fff->prepare_files();
  676. $fff->fill_content();
  677. $new = sprintf("<div class=\"content_element_page %s\"><a name=\"%s\"></a>\n%s\n</div>",
  678. $class,
  679. $anchor_name,
  680. implode("\n",$fff->content['default']));
  681. break;
  682. case 'youtube':
  683. $vid=array_shift($request);
  684. $pos= array_shift($request);
  685. if( in_array($pos,array('left','right','full'))) {
  686. $class = $pos;
  687. } else {
  688. $class = 'left';
  689. }
  690. $video=sprintf("<iframe width=\"700\" height=\"394\" class=\"ytvideo\" "
  691. ."src=\"https://www.youtube.com/embed/%s\"></iframe>",
  692. $vid);
  693. $thumbnail = sprintf("<div class=\"video-thumbnail\"><a href=\"%s\" data-featherlight=\"#%s\">"
  694. ."<img class=\"thumbnail\" src=\"https://img.youtube.com/vi/%s/mqdefault.jpg\" alt=\"video-preview\"/>"
  695. ."<img class=\"play-button\" src=\"%s\" alt=\"play-button\" />"
  696. ."</a></div><div class=\"lightbox\" id=\"%s\" >%s</div>",
  697. "https://www.youtube.com/watch?v=".$vid,
  698. $vid,
  699. $vid,
  700. "/rsc/img/play-button.png",
  701. $vid,
  702. $video
  703. );
  704. foreach ($body as $k=>$line) {
  705. if (strpos($line,"©") !== FALSE
  706. || strpos($line,"&copy;") !== FALSE) {
  707. $body[$k] = sprintf("<span class=\"copyright\">%s</span>",$line);
  708. }
  709. }
  710. $new=sprintf("<div class='video-container %s'>"
  711. ."<div class=\"media\">%s</div>"
  712. ."<div class=\"caption\">%s</div>"
  713. ."</div>",
  714. $class,
  715. $thumbnail,
  716. $md->text(implode("\n",$body)));
  717. break;
  718. default:
  719. $new=self::warn("Content Module \"".$request[0]."\" unknown");
  720. break;
  721. }
  722. $string = str_replace($matches[0][$i],$new,$string);
  723. }
  724. return $string;
  725. }
  726. function warn($message) {
  727. return sprintf("<div class=\"warning\">%s</div>",$message);
  728. }
  729. }
  730. class CEimage
  731. {
  732. var $r;
  733. var $b;
  734. var $structs;
  735. var $content;
  736. function __construct($request,$body=[],$structs=false,$content=false) {
  737. $this->r = $request;
  738. $this->b = $body;
  739. $this->structs = &$structs;
  740. $this->content = &$content;
  741. }
  742. function index() {
  743. $md = new \freaParsedown();
  744. $request = $this->r;
  745. $body = $this->b;
  746. $key=$request[1];
  747. $image="";
  748. $new="";
  749. // see if we can find image
  750. if ( is_file($request[1])) {
  751. $image= $request[1];
  752. } else if ($this->structs) {
  753. foreach($this->structs as $domain=>$destination) {
  754. if(array_key_exists($key, $this->structs[$domain]['pic'])) {
  755. $image = $this->structs[$domain]['pic'][$key];
  756. unset($this->structs[$domain]['pic'][$key]);
  757. unset($this->content[$this->domains[$domain]][$key]);
  758. break;
  759. }
  760. }
  761. }
  762. if ($image) {
  763. // image positioning
  764. if( in_array($request[2],array('left','right','full'))) {
  765. $class = $request[2];
  766. } else {
  767. $class = 'full';
  768. }
  769. if (isset($request[3])) {
  770. $gallery = 'gallery';
  771. } else {
  772. $gallery = 'fl';
  773. }
  774. // image orientation?
  775. $img = new \Image($image);
  776. // $ratio = "landscape";
  777. $ratio = ($img->width() >= $img->height())
  778. ? "landscape"
  779. : "portrait"
  780. ;
  781. unset($img);
  782. $cached = new CachedImage($image);
  783. // identify if caption contains a copyright note
  784. // if so, indicate with a class
  785. foreach ($body as $k=>$line) {
  786. if (strpos($line,"©") !== FALSE
  787. || strpos($line,"&copy;") !== FALSE) {
  788. $body[$k] = sprintf("<span class=\"copyright\">%s</span>",$line);
  789. }
  790. }
  791. $new=sprintf("<div class='content_element_image %s'>"
  792. ."<div class=\"media %s\"><a href=\"%s\" class=\"$gallery\"><img src=\"%s\" alt=\"user supplied image\" /></a></div>"
  793. ."<img src=\"%s\" style=\"display:none;\" alt=\"user supplied image\" />"
  794. ."<div class=\"caption\">%s</div>"
  795. ."</div>",
  796. $class,
  797. $ratio,
  798. $cached->get_src(1600),
  799. $cached->get_src(1600),
  800. $cached->get_src(1600),
  801. $md->text(implode("\n",$body))
  802. );
  803. unset($cached);
  804. } else {
  805. // image not found
  806. $new=sprintf("<div class='content_element_image %s'>\n"
  807. ."<div class=\"media %s\">\n"
  808. ."<div class=\"caption\">\n%s\n</div>\n"
  809. ."</div>\n",
  810. $class,
  811. $ratio,
  812. $md->text(implode("\n",$body))
  813. );
  814. }
  815. return $new;
  816. }
  817. }