= 4.3.0 */ define("VERSION_MAJOR", "1"); define("VERSION_MINOR", "1"); define("VERSION_GIT", "65"); // Definice vytvářených adresářů pro ukládání dat. // Zde jsou uloženy texty, ze kterých je generováno HTML define("TXT", "./txt"); // Zde jsou uloženy datové soubory, cokoliv binárního mimo obrázků define("DAT", "./dat"); // Zde jsou uloženy obrázky define("IMG", "./img"); // Zde jsou uloženy zálohy upravovaných textů z adresáře TXT define("BKP", "./bkp"); // Zde jsou uložena data generovaná z obsahu stránek - štítky,... define("TDB", "./tdb"); // Zde jsou uloženy vygenerované kalendáře ve formátu iCAL define("CAL", "./cal"); // Zde jsou generovány HTML soubory (standardně kořenový adresář) define("HTM", "./"); // Definice hashe/hesla pro přegenerování stránek např. z CRONu atp. // toto heslo neumožňuje jakkoliv měnit data, pouze spustí přegenerování // HTML souborů define("CRONSHA","8e534152e86891617d36a44e4878d078dea38533"); // Definice maximálního počtu stránek v menu s danou váhou define("MAXPGSPERWEIGHT", 100); define("IS_CRON_PRESENT", isset($_GET["CRON"])); define("IS_UPLOAD_PRESENT", isset($_POST["upload_file"])); // Definice textů define("LOGTO", "Přihlášení do redakčního systému μCMS"); define("ENTERPASS", "Zadejte heslo:"); define("LOGFAIL", "Přihlášení se bohužel nezdařilo. Zkuste zadat heslo znovu."); define("HASHPASS", "Pro změnu hesla využijte následující řetězec se zašifrovaným heslem:
"); define("LOGOUT", "Odhlásit se"); define("DEL", "Smazat"); define("STITKY", "Štítky:"); define("EXSTITKY", "Existující štítky:"); define("TEXT", "Text:"); define("STRANKU", "Stránku (soubor) "); define("NAHRANSOUBOR", "Nahrán soubor "); define("SOUBOR", " Vyberte soubor na disku: "); define("NEBO", " nebo "); define("SAVE", "Uložení změn, generování stránek"); define("UPDCRT", "Jen uložit či vytvořit stránku"); define("CLEAR", "Vyčistit"); define("DEFINICE", "Definice:"); define("ULOGOUT", "Byli jste odhlášeni!"); define("FASESS", "FATAL ERROR: Can't terminate session!"); define("FAODIR", "FATAL ERROR: Can't open directory: "); define("FACDIR", "FATAL ERROR: Can't create directory: "); define("FACFILE", "FATAL ERROR: Can't create file: "); define("FAWDIR", "FATAL ERROR: Can't write to directory: "); define("PTFM", "Please try to fix this manually (e.g. using FTP client)."); define("FRDIR", "Fixed rights for writing to directory: "); define("CDIR", "Automaticky vytvořen adresář: "); define("NOTLOG", "Not logged in or login not valid! Please log in!"); define("IPCHANGE", "Vaše IP adresa se změnila, z bezpečnostních důvodů se, prosím, přihlašte se znovu!"); define("TIMEXC", "Z důvodu dlouhé neaktivity jste byli odhlášeni, prosím, přihlašte se znovu!"); define("LOAD", "Nahrát"); define("MANDATORY_FILE_NAME", "Název souboru [povinný]:"); define("NS", "Titulek stránky:"); define("MENU", "Název položky v menu:"); define("DATUM", "Datum vytvoření článku:"); define("VAHA", "Váha (v menu):"); define("NADS", "Nadřazený soubor (v menu):"); //define("NAV", "
Name in menu:\n Menu weight:\n Parent menu:\n  Page title:\n        Date:\n        Body:
"); define("LOWERCASE", "Název souboru se může skládat jen z malých písmen a-z (bez diakritiky), čísel a rozdělovníků (-), musí být vyplněn."); define("GENERATE", "Uložit stránku + Vygenerovat obsah stránek"); define("GENERATED", "HTML stránky vygenerovány. "); define("DELETED", "File was successfully deleted (moved to bkp dir)!"); define("CANTWRITE", "Can't save the file, check permissions (directory/upload size iin PHP, web server, MAX_FILE_SIZE in this form)."); define("CANTDEL", "Can't delete the file, check permissions."); define("FILESAVED", "Obsah byl uložen do souboru "); define("SHOW", "Zobrazit "); define("MOT", "Menu on top"); define("MOL", "Menu on left"); define("UPLOADFILE", "nahrát jako datový soubor"); define("UPLOADIMG", "nahrát jako obrázek"); define("UPLOADED", " was uploaded."); define("SHOWIMG", "Obrázky"); define("SHOWDAT", "Datové soubory"); define("FILELISTED", "Seznam datových souborů resp. obrázků byl vygenerován dole na stránce."); define("CHECK", "Kontrola integrity μCMS"); define("DEFAULTCSS", "Vrat CSS do vychoziho stavu"); define("CHECKFINISHED", "Kontrola integrity μCMS provedena."); define("CSSDEFAULTED", "CSS obnoveno do vychoziho stavu."); define("MANAGECSS", "Spravuj CSS"); define("LOGO", "μCMS".VERSION_MAJOR.".".VERSION_MINOR.".".VERSION_GIT.""); // PHP konfigurace - kvůli hloupoučkému iconv setlocale(LC_CTYPE, 'cs_CZ.UTF-8'); define("_cb", '
'); define("_nl", "
\n"); define("_htmlnl", "\n"); define("DOWNLOAD_URL", "http://www.klikva.cz/ucms/"); // HTML hlavička pro všechny stránky vyjma μCMS define("HTML_HEAD", ''._htmlnl.''._htmlnl.''._htmlnl.'%GEN_TITLE%'._htmlnl.' '._htmlnl.''._htmlnl.''._htmlnl.''._htmlnl.''._htmlnl); // HTML patička pro všechny stránky define("HTML_FOOTER", _htmlnl.""._htmlnl.""); define("SECTION_END", _cb.""); error_reporting(E_ERROR | E_PARSE); // --------------- nesmyslna zaloha // Následující řádek začínající define("SHA","..."); obsahuje zašifrované heslo // (hash). // Dlouhý řeťezec mezi závorkami (v příkladu nahoře tečky) je třeba nahradit // tím, které se vygeneruje při přihlášení do μCMS. // // // //define("SHA", "82c1720eb8199e070e684587d4b1fdb47a9fcf30"); // //// Definice vytvářených adresářů pro ukládání dat. // //// Zde jsou uloženy texty, ze kterých je generováno HTML //define("TXT", "./txt"); // //// Zde jsou uloženy datové soubory, cokoliv binárního mimo obrázků //define("DAT", "./dat"); // //// Zde jsou uloženy obrázky //define("IMG", "./img"); // //// Zde jsou uloženy zálohy upravovaných textů z adresáře TXT //define("BKP", "./bkp"); // //// Zde jsou uložena data generovaná z obsahu stránek - štítky,... //define("TDB", "./tdb"); // //// Zde jsou uloženy vygenerované kalendáře ve formátu iCAL //define("CAL", "./cal"); // //// Zde jsou generovány HTML soubory (standardně kořenový adresář) //define("HTM", "./"); // //// Definice hashe/hesla pro přegenerování stránek např. z CRONu atp. //// toto heslo neumožňuje jakkoliv měnit data, pouze spustí přegenerování //// HTML souborů //define("CRONSHA", "8e534152e86891617d36a44e4878d078dea38533"); //define("IS_CRON_PRESENT", isset($_GET["CRON"])); //define("IS_UPLOAD_PRESENT", isset($_POST["upload_file"])); // // //// Definice maximálního počtu stránek v menu s danou váhou //define("MAXPGSPERWEIGHT", 100); // //// Definice textů //define("LOGTO", "Přihlášení do redakčního systému μCMS"); //define("ENTERPASS", "Zadejte heslo:"); //define("LOGFAIL", "Přihlášení se bohužel nezdařilo. Zkuste zadat heslo znovu."); //define("HASHPASS", "Pro změnu hesla využijte následující řetězec se zašifrovaným heslem:
"); //define("LOGOUT", "Odhlásit se"); //define("DELETE", "Smazat"); //define("STITKY", "Štítky:"); //define("EXSTITKY", "Existující štítky:"); //define("TEXT", "Text:"); //define("STRANKU", "Stránku (soubor) "); //define("NAHRANSOUBOR", "Nahrán soubor "); //define("SOUBOR", " Vyberte soubor na disku: "); //define("NEBO", " nebo "); //define("SAVE", "Uložení změn, generování stránek"); //define("UPDCRT", "Jen uložit či vytvořit stránku"); //define("CLEAR", "Vyčistit"); //define("DEFINICE", "Definice:"); //define("ULOGOUT", "Byli jste odhlášeni!"); //define("FASESS", "FATAL ERROR: Can't terminate session!"); //define("FAODIR", "FATAL ERROR: Can't open directory: "); //define("FACDIR", "FATAL ERROR: Can't create directory: "); //define("FACFILE", "FATAL ERROR: Can't create file: "); //define("FAWDIR", "FATAL ERROR: Can't write to directory: "); //define("PTFM", "Please try to fix this manually (e.g. using FTP client)."); //define("FRDIR", "Fixed rights for writing to directory: "); //define("CDIR", "Automaticky vytvořen adresář: "); //define("NOTLOG", "Not logged in or login not valid! Please log in!"); //define("IPCHANGE", "Vaše IP adresa se změnila, z bezpečnostních důvodů se, prosím, přihlašte se znovu!"); //define("TIMEXC", "Z důvodu dlouhé neaktivity jste byli odhlášeni, prosím, přihlašte se znovu!"); //define("LOAD", "Nahrát"); //define("NÁZEV_SOUBORU_POVINNÝ", "Název souboru [povinný]:"); //define("NS", "Titulek stránky:"); //define("MENU", "Název položky v menu:"); //define("DATUM", "Datum vytvoření článku:"); //define("VAHA", "Váha (v menu):"); //define("NADS", "Nadřazený soubor (v menu):"); ////define("NAV", "
Name in menu:\n Menu weight:\n Parent menu:\n  Page title:\n        Date:\n        Body:
"); //define("LOWERCASE", "Název souboru se může skládat jen z malých písmen a-z (bez diakritiky), čísel a rozdělovníků (-), musí být vyplněn."); //define("GENERATE", "Uložit stránku + Vygenerovat obsah stránek"); //define("GENERATED", "HTML stránky vygenerovány. "); //define("DELETED", "File was successfully deleted (moved to bkp dir)!"); //define("CANTWRITE", "Can't save the file, check permissions (directory/upload size iin PHP, web server, MAX_FILE_SIZE in this form)."); //define("CANTDEL", "Can't delete the file, check permissions."); //define("FILESAVED", "Obsah byl uložen do souboru "); //define("MOT", "Menu on top"); //define("MOL", "Menu on left"); //define("UPLOADFILE", "nahrát jako datový soubor"); //define("UPLOADIMG", "nahrát jako obrázek"); //define("UPLOADED", " was uploaded."); //define("SHOWIMG", "Obrázky"); //define("SHOWDAT", "Datové soubory"); //define("FILELISTED", "Seznam datových souborů resp. obrázků byl vygenerován dole na stránce."); //define("CHECK", "Kontrola integrity μCMS"); //define("MANAGECSS", "Spravuj CSS"); //define("CHECKFINISHED", "Kontrola integrity μCMS provedena."); //define("CSSDEFAULTED", "CSS obnoveno do vychoziho stavu."); // //// PHP konfigurace - kvůli hloupoučkému iconv //setlocale(LC_CTYPE, 'cs_CZ.UTF-8'); //define("_cb", '
'); //define("_nl", "
\n"); //define("_htmlnl", "\n"); // //define("DOWNLOAD_URL", "http://www.fialovyzajic.cz/ucms/"); // //// HTML hlavička pro všechny stránky vyjma μCMS //define("HTML_HEAD", ''._htmlnl.''._htmlnl.''._htmlnl.'%GEN_TITLE%'._htmlnl.' '._htmlnl.''._htmlnl.''._htmlnl.''._htmlnl.''._htmlnl); // //// LOGO //define("LOGO", '

μCMS('.VERSION_MAJOR.'.'.VERSION_MINOR.'.'.VERSION_GIT.')

'); //// HTML patička pro všechny stránky //define("HTML_FOOTER", ""); // // //error_reporting(E_ERROR | E_PARSE); // ****************************************************** HELPER FUNCTIONS /** * Zkontroluje nazev souboru nebo adresare jestli neobsahuje nepovolene znaky * * @param {string} $filename - jmeno kontrolovane entity * @return bool - true pokud je jmeno v poradku, false kdyz ne */ function isPathValid($filename) { return !preg_match('/\//', $filename); } /** * Nahradi nepovolene znaky v nazvu adresare nebo souboru, pokud je to treba */ function sanitizePath($filename){ if(!isPathValid($filename)){ return preg_replace('/\//', '_', $filename); } return $filename; } /** * Overi, ze jmeno souboru obsahuje jen povolene znaky * @param {string} $filename - jmeno kontrolovaneho souboru * @return bool - true kdyz je jmeno souboru v poradku, jinak false */ function isFilenameValid($filename) { $filename = trim($filename); return preg_match("/^[a-z0-9\-]*$/", $filename); } /** * Funkce vyprodukuje pole s daty z formuláře pro uložení na disk. * * @return mixed */ function post2arr() { $data["headers"]["soubor"] = $_POST["soubor"]; $data["headers"]["menu"] = $_POST["menu"]; $data["headers"]["titulek"] = $_POST["titulek"]; $data["headers"]["vaha"] = $_POST["vaha"]; $data["headers"]["datum"] = $_POST["datum"]; $data["headers"]["aktualizace"] = date('d.m.Y'); $data["headers"]["rodic"] = $_POST["rodic"]; $stitky = ''; foreach (explode("\n", ($_POST["stitky"])) as $stitek) { $stitky .= trim($stitek).'#'; $stitky = preg_replace("/#+/", "#", $stitky); } //echo "|".$_POST["definice"]."|"; foreach (explode("\n", (trim($_POST["definice"]))) as $value) { $definice = explode(":", "$value"); if (isFileNameValid($definice[0]) && count($definice) > 1 && $definice[0] !== "menu" && !in_array($definice[0], array("soubor", "titulek", "vaha", "datum", "rodic", "stitky", "aktualizace"))) { $data["headers"][trim($definice[0])] = trim($definice[1]); } } //$data["headers"]["stitky"]=implode('#',explode("\n",trim($_POST["stitky"]))); $data["headers"]["stitky"] = $stitky; $data["data"] = explode("\r", $_POST["text"]); return $data; } /** * @param $type * @param $name * @param $val * @param $label * @param bool $cb * @param bool $disabled */ function singleField($type, $name, $val, $label, $cb = FALSE, $disabled = FALSE) { echo '
'._htmlnl.'
'.$label.'
'._htmlnl.'
'._htmlnl.' '._htmlnl.'
'._htmlnl.'
'._htmlnl; echo $cb ? _cb : ''; // clear both } /** * @param $label * @param $id * @param $name * @param $rows * @param $cols * @param $content */ function singleArea($label, $id, $name, $rows, $cols, $content) { echo '
'.$label.'
'._htmlnl.' '._htmlnl; } /** * Funkce generující formulář pro editaci/vytváření obsahu * * @param $mess * @param $text */ function text_form($mess, $text) { echo '
'; echo "
"; echo "
".LOGO."
"; echo ""._htmlnl; // integrita + sprava css echo "
"._htmlnl; echo ""._htmlnl; echo ""._htmlnl; // generovani/ukladni stranek echo "
"._htmlnl; echo ""._htmlnl; echo ""._htmlnl; // LOAD nebo DELETE stranky echo "
"._htmlnl; echo "
".STRANKU."
"; arr2sel(preg_replace('/.txt$/', '', dir2arr(TXT, 'FILE')), "file_list", $text["headers"]["soubor"]); echo ""._htmlnl; echo ""._htmlnl; echo "
"._htmlnl; echo ""._htmlnl; if ($mess) { echo 'Info: '.$mess; } echo "
"; echo "
\n"; singleField('text', 'soubor', $text["headers"]["soubor"], MANDATORY_FILE_NAME); singleField('text', 'menu', $text["headers"]["menu"], MENU); singleField('text', 'titulek', $text["headers"]["titulek"], NS); echo _cb; singleField('text', 'vaha', $text["headers"]["vaha"], VAHA); singleField('text', 'datum', $text["headers"]["datum"], DATUM); if ($text["headers"]["soubor"] === "index") { singleField('text', 'rodicc', $text["headers"]["rodic"], NADS, FALSE, TRUE); singleField('hidden', 'rodic', $text["headers"]["rodic"], ''); } else { singleField('text', 'rodic', $text["headers"]["rodic"], NADS); } echo _cb; echo "
"._htmlnl; singleArea(TEXT, 'text', 'text', 30, 80, implode($text["data"])); echo "
"._htmlnl; echo "
"._htmlnl; singleArea(STITKY, 'stitky', 'stitky', 7, 30, implode("\n", explode('#', $text["headers"]["stitky"]))); singleArea(EXSTITKY, 'exstitky', 'exstitky', 10, 30, (file_exists(BKP.'/stitky') === TRUE) ? (implode("\n", explode('#', file_get_contents(BKP.'/stitky')))) : ('')); $defCont = ''; $fieldsArray = array("menu", "soubor", "titulek", "vaha", "datum", "rodic", "stitky", "aktualizace"); foreach ($text["headers"] as $header => $value) { if (!in_array($header, $fieldsArray)) { $defCont .= $header.":".$value."\n"; } } singleArea(DEFINICE, 'definice', 'definice', 10, 30, $defCont); echo "
"._htmlnl; echo _cb; echo "
".SOUBOR.""._htmlnl; echo ''._htmlnl; echo ''._htmlnl; echo ''._htmlnl; echo NEBO._htmlnl; echo ''._htmlnl; echo "
"._htmlnl; echo "
Vypsat z adresáře"._htmlnl; echo ''._htmlnl; arr2sel(dir2arr(IMG, 'DIR'), "img_dir_list", ""); echo _nl.''._htmlnl; arr2sel(dir2arr(DAT, 'DIR'), "dat_dir_list", ""); echo "
"._htmlnl; echo _cb._nl; echo ''._htmlnl; } /** * */ function check_session() { session_start(); if ($_SESSION["auth"] !== "admin") { // sleep(4); destroy_session(NOTLOG); } if ($_SESSION["ip"] !== $_SERVER["REMOTE_ADDR"]) { // sleep(4); destroy_session(IPCHANGE); } if (($_SESSION["time"] + 432000) < time()) { // sleep(4); destroy_session(TIMEXC); } session_regenerate_id(TRUE); } /** * Overi zda je uzivatel prihlasen * @return {bool} True pokud je uzvatel prihlasen, false kdyz neni. */ function isLogged() { check_session(); return $_SESSION["auth"] === "admin"; } /** * * * @param $mess */ function destroy_session($mess) { $_SESSION = array(); session_destroy(); if (isset($_SESSION["auth"]) && $_SESSION["auth"]) { htmlHead(); echo FASESS; htmlFooter(); exit; } htmlHead(); login_form(); htmlFooter(); exit; } /** * HTML hlavička pro μCMS */ function htmlHead() { echo "\n"; echo "\t\n"; echo "\tμCMS\n"; echo "\t\t\n"; echo "\n"; echo "\t\t\n"; echo "\t\n\n"; echo "\n"; } /** * HTML patička pro μCMS */ function htmlFooter() { echo "\n
\n\n"; } function getFileContent($url) { if (ini_get('allow_url_fopen')) { return file_get_contents($url); } if (function_exists('curl_init')) { $ch = curl_init(); curl_setopt($ch, CURLOPT_URL, $url); curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 5); curl_setopt($ch, CURLOPT_RETURNTRANSFER, TRUE); return curl_exec($ch); } } /** * Stahne soubor z DOWNLOAD_URL. * * @param $dstFile * @param string $srcFile * @param {boolean} write - Whether the file should be written to disk. * @return string|false - Vrati obsah souboru, nebo NULL kdyz je nedostupny. */ function downloadFile($dstFile, $srcFile = "") { // TODO prohnat nazvy obou souboru kontrolou na nezadouci znaky :) if ($srcFile === "") { $srcFile = $dstFile.".default"; } if (file_exists(HTM.$dstFile) === FALSE) { $data = getFileContent(DOWNLOAD_URL.$srcFile); if ((!$handle = fopen(HTM.$dstFile, "wb+")) || fwrite($handle, $data) === FALSE) { return CANTWRITE.HTM.$dstFile; } fclose($handle); return $data; } return FALSE; } /** * Kontrola, zda existují životně důležité adresáře. Pokud neexistují, snažíme se je vytvořit. * Dále se kontroluje, zda existuje minimální obsah. Pokud ne, je automaticky vytvořen. **/ function self_check() { $status = TRUE; foreach (array(TXT, DAT, BKP, IMG, TDB, CAL) as $dir) { // HTM tu nema co delat ... if (!is_dir($dir)) { if (!mkdir($dir, 0775) && !is_dir($dir)) { echo FACDIR.$dir._nl.PTFM._nl; $status = FALSE; } else { echo CDIR.$dir._nl; } } if (is_writable($dir) === FALSE) { chmod($dir, 0775); if (is_writable($dir)) { echo FRDIR.$dir._nl; } else { echo FAWDIR.$dir._nl.PTFM._nl; $status = FALSE; } } } if ($status !== TRUE) { return $status; } $file = TXT.'/index.txt'; if (file_exists($file) === FALSE) { $data["data"][0] = "Stránky se připravují...."; $data["headers"]["soubor"] = "index"; $data["headers"]["titulek"] = "Vítejte!"; $data["headers"]["rodic"] = ""; $data["headers"]["vaha"] = "1"; $data["headers"]["menu"] = "Úvod"; $data["headers"]["datum"] = date('d.m.Y'); $data["headers"]["stitky"] = ''; echo arr2disk($data); $data["data"][0] = "Stránka se připravuje..."; $data["headers"]["soubor"] = "kontakt"; $data["headers"]["titulek"] = "Kontaktní adresa"; $data["headers"]["rodic"] = "index"; $data["headers"]["vaha"] = "0"; $data["headers"]["menu"] = "Kontakt"; $data["headers"]["datum"] = date('d.m.Y'); $data["headers"]["stitky"] = ''; echo arr2disk($data); } $status .= downloadFile('ucms.css'); $status .= downloadFile('screen.default.css', 'screen.default.css'); return $status; } /** * Funkce vrací pole souborů či adresářů (dle volby $type) v daném adresáři ($dir). * * @param {string} $dir - Nazev prohledavaneho adresare. * @param {string} $type - Type hledaneho zaznamu (FILE|DIR). * @return array */ function dir2arr($dir, $type, $filename = "") { $files = array(); if ($handle = opendir($dir)) { while (FALSE !== ($file = readdir($handle))) { if ($file === "..") { continue; } switch ($type) { case 'FILE': if ($file !== "." && is_file("$dir/$file")) { if ($filename === "") { $files[] = $file; break; } if (preg_match('/'.$filename.'/', $file)) { $files[] = $file; } } break; case 'DIR': if (is_dir($dir."/".$file)) { $files[] = $file; } break; } } closedir($handle); sort($files); return $files; } echo FAODIR.$dir._nl; } /** * Funkce načte hlavičky ze souboru $soubor v adresáři TXT uvozené ### a * převede je na pole s jednotlivými hlavičkami * např. ###menu###index se stane $headers["menu"]="index". * * @param $soubor * @return array */ function text_headers($soubor) { $headers = array(); if (file_exists(TXT.'/'.$soubor) === TRUE) { $text = file(TXT.'/'.$soubor); $line = 0; $regs = ""; $headers["soubor"] = preg_replace('/.txt$/', '', $soubor); $length = count($text); while ($line < $length && preg_match("/^###([a-zA-Z0-9_]*)###(.*)/", trim($text[$line]), $regs)) { $headers["$regs[1]"] = $regs[2]; $line++; $regs = ""; } } return $headers; } /** Funkce odstraní řádky souboru $soubor v adresáři TXT uvozené ### * a vrátí vše jako $data * * @param string $soubor - Jmeno souboru s daty * @return array - vycistene pole radek ze souboru, pokud existuje, null pokud neexistuje. **/ function clean_headers($soubor) { if (file_exists(TXT.'/'.$soubor) === TRUE) { $text = file(TXT.'/'.$soubor); $line = 0; $length = count($text); while ($line < $length && preg_match("/^###/", $text[$line], $regs)) { $line++; } return array_slice($text, $line); } } /** * @param $data * @return string */ function arr2disk($data) { $bkp = BKP.'/'.$data["headers"]["soubor"].'.'.time().'.bak'; $file = TXT.'/'.$data["headers"]["soubor"].'.txt'; if (is_file($file)) { copy($file, $bkp); } $file_content = ''; foreach ($data["headers"] as $header => $content) { $file_content .= "###$header###$content\n"; } $file_content .= implode($data["data"]); if ((!$handle = fopen($file, "wb+")) || fwrite($handle, $file_content) === FALSE) { $error = CANTWRITE; } else { fclose($handle); $error = FILESAVED.$data["headers"]["soubor"]." ($file). '.SHOW.$data["headers"]["soubor"].'.html' ; } return $error; } /** * Overi, ze soubor neni systemovy * * @param string $filename - Jmeno souboru k overeni. * @return boolean true, kdyz je soubor v seznamu chranenych jmen, false kdyz ne. **/ function isFileProtected($filename = "") { $PROTECTED_FILE_NAMES = array("header", "favico", "footer", "nomenu"); return in_array($filename, $PROTECTED_FILE_NAMES); } /** * Funkce generování menu v HTML * Pracuje rekursivně - volá sebe samu * */ function gen_html_menu($menu, $text, $level, &$html) { if (isset($menu[$level])) { ksort($menu[$level]); $html .= ''._htmlnl; } } /** * Vytvori SELECT se seznamem souboru k vyberu uzivatelem. * * @param {array} $file_arr - Seznam souboru - polozek selectu. * @param {string} $name - Nazev selectu. * @param {string} $selected - Jmeno aktualne vybrane polozky. */ function arr2sel($file_arr, $name, $selected) { echo _htmlnl.''._htmlnl; } /** * Vysype prihlasovaci formular */ function login_form() { echo '
'.LOGTO.'
'.ENTERPASS.'
 
'; //echo '
'; } /** * Vypise SHA1 hesh zaslaneho stringu(hesla). * @param {string} $pass - String, ktery bude zahashovan. */ function gen_hash($pass) { echo HASHPASS; echo sha1($pass); } //translate wiki syntax to html // TODO předat kompletní hlavičky stránky /** * @param $text_array * @param $headers_array * @return mixed */ function wiki2html($text_array, $headers_array) { $ul = 0; //unordered list $pr = 0; //preformated text/code $tb = 0; //table $simple_replace = array('/==== (.*) ====/' => '

\1

', '/=== (.*) ===/' => '

\1

', '/== (.*) ==/' => '

\1

', '/= (.*) =/' => '

\1

', "/'''(.+?)'''/" => '\1', "/''(.+?)''/" => '\1', "/(\s|^)(www\.\S+)/" => '\2', "/(\s|^)(http:\/\/\S+)/" => '\2', "/(\s|^)(https:\/\/\S+)/" => '\2', "/\[(http:\/\/\S+)\]/" => '\1', "/\[(https:\/\/\S+)\]/" => '\1', "/\[(http:\/\/\S+)\s+([^\]]+)\]/" => '\2', "/\[(https:\/\/\S+)\s+([^\]]+)\]/" => '\2', "/\[link:(\S+)\]/" => '\1', "/\[link:(\S+)\s+([^\]]+)\]/" => '\2', "/\[dat:(\S+)\]/" => '\1', "/\[dat:(\S+)\s+([^\]]+)\]/" => '\2', "/\[img:(.+){(.+)}\]/" => '\1', "/\[img:(\S+)\]/" => '\1', "/\[img:(\S+)\s+([^\{}]]+)\]/" => '

\2

', "/^\s*$/" => '
', "/^{\|/" => '', "/^\|\-/" => '', "/^\|}/" => '
', "/^\|(.*)/" => '\1', '/---+/' => '
', '/--/' => '–'); // $simple_replace = array(); // $simple_replace[] = array('/==== (.*) ====/' => '

\1

'); // $simple_replace[] = array('/=== (.*) ===/' => '

\1

'); // $simple_replace[] = array('/== (.*) ==/' => '

\1

'); // $simple_replace[] = array('/= (.*) =/' => '

\1

'); // $simple_replace[] = array("/'''(.+?)'''/" => '\1'); // $simple_replace[] = array("/''(.+?)''/" => '\1'); // $simple_replace[] = array("/(\s|^)(www\.\S+)/" => '\2'); // $simple_replace[] = array("/(\s|^)(http:\/\/\S+)/" => '\2'); // $simple_replace[] = array("/(\s|^)(https:\/\/\S+)/" => '\2'); // $simple_replace[] = array("/\[(http:\/\/\S+)\]/" => '\1'); // $simple_replace[] = array("/\[(https:\/\/\S+)\]/" => '\1'); // $simple_replace[] = array("/\[(http:\/\/\S+)\s+([^\]]+)\]/" => '\2'); // $simple_replace[] = array("/\[(https:\/\/\S+)\s+([^\]]+)\]/" => '\2'); // $simple_replace[] = array("/\[link:(\S+)\]/" => '\1'); // $simple_replace[] = array("/\[link:(\S+)\s+([^\]]+)\]/" => '\2'); // $simple_replace[] = array("/\[dat:(\S+)\]/" => '\1'); // $simple_replace[] = array("/\[dat:(\S+)\s+([^\]]+)\]/" => '\2'); // $simple_replace[] = array("/\[img:(.+){(.+)}\]/" => '\1'); // $simple_replace[] = array("/\[img:(\S+)\]/" => '\1'); // $simple_replace[] = array("/\[img:(\S+)\s+([^\{}]]+)\]/" => '

\2

'); // $simple_replace[] = array("/^\s*$/" => '
'); // $simple_replace[] = array("/^{\|/" => ''); // $simple_replace[] = array("/^\|\-/" => '', "/^\|}/" => '
'); // $simple_replace[] = array("/^\|(.*)/" => '\1'); // $simple_replace[] = array('/---+/' => '
'); // $simple_replace[] = array('/--/' => '–'); //TODO rychlý hack, nahradit statický lookup dynamickým foreach ($headers_array as $header => $value) { $simple_replace += ["/\[def:$header\]/" => "$value"]; } //stitky $stitky = '|'; foreach (explode("#", $headers_array["stitky"]) as $stitek) { if (!empty($stitek)) { $stitek_bez_dia = iconv("UTF-8", "ASCII//TRANSLIT", $stitek); $stitky .= " $stitek |"; } } if ($stitky == '|') { $stitky = ''; } $simple_replace += ["/\[stitky\]/" => "$stitky"]; //TODO v této části kódu je chyba, pokud jsou na jedné stránce dva // elemetny (csv,box,csvcal), tak pak se vloží pouze jeden. // To je potřeba doladit. // Souvisí to s řádkováním, pokud je element na konci stránky, // tak to funguje. foreach ($text_array as $line_number => &$line) { // box - ramecek, ktery vlozi jinou html stranku if (preg_match('/(.*)\[box:(\S+)\s*([^\]]*)](.*)/', $line, $match) === 1) { $line = $match[1]; $soubor = $match[2]; $nadpis = $match[3]; $lineend = $match[4]; if (file_exists(TXT.'/'.$soubor.'.txt') === TRUE) { $limit=NULL; if ($nadpis != "") { if (preg_match('/(.*):limit:([-0-9]+)/', $nadpis, $match) === 1) { $nadpis = $match[1]; $limit = $match[2]; if ($nadpis != "") { $nadpis="

$nadpis

"; } if (is_numeric($limit )) { $limit=$limit; } else { $limit=NULL; } } else { $nadpis="

$nadpis

"; } } $incl_text = array_merge(array("
$nadpis"), array_slice(clean_headers($soubor.'.txt'),0,$limit), array('
')); } else { $incl_text = ""; } $line_slice = $line_number + 1; array_splice($text_array, $line_slice, 0, $lineend); array_splice($text_array, $line_slice, 0, $incl_text); // pre_print($text_array); } // vlozeni souboru if (preg_match('/(.*)\[inc:(\S+)\](.*)/', $line, $match) === 1) { $line = $match[1]; $soubor = $match[2]; $lineend = $match[3]; if (file_exists(DAT.'/'.$soubor) === TRUE) { $incl_text = file(DAT.'/'.$soubor); } else { if (file_exists(TXT.'/'.$soubor.'.txt') === TRUE) { $incl_text = clean_headers($soubor.'.txt'); } else { $incl_text = ""; } } $line_slice = $line_number + 1; array_splice($text_array, $line_slice, 0, $lineend); array_splice($text_array, $line_slice, 0, $incl_text); } // vlozeni CSV souboru // TODO osefovat kdyz inc a csv je na jednom radku if (preg_match('/(.*)\[csv:(\S+)\](.*)/', $line, $match) === 1) { $line = $match[1]."\n"; $soubor = $match[2]; $lineend = "
\n".$match[3]; if (file_exists(DAT.'/'.$soubor) === TRUE) { $incl_text = file(DAT.'/'.$soubor); $csv_line_no = 0; foreach ($incl_text as &$csv_line) { if ($csv_line_no == 0) { $csv_line = "".preg_replace('/;/', '', $csv_line).""; } else { $csv_line = "".preg_replace('/;/', '', $csv_line).""; } $csv_line_no = $csv_line_no + 1; } } else { $incl_text = ""; } $line_slice = $line_number + 1; array_splice($text_array, $line_slice, 0, $lineend); array_splice($text_array, $line_slice, 0, $incl_text); } // vlozeni specialnicho CSV souboru s kalendarem akci // ve formatu: // datum ; popis akce ; + libovolne dalsi sloupce // TODO osefovat kdyz inc a csvcal je na jednom radku if (preg_match('/(.*)\[csvcal:(\S+)\s*([^\]]*)\](.*)/', $line, $match) === 1) { $line = $match[1]."
\n"; $soubor = $match[2]; $nadpis = $match[3]; $lineend = "
\n".$match[4]; if (file_exists(DAT.'/'.$soubor) === TRUE) { $incl_text = ""; $csv_lines = file(DAT.'/'.$soubor); $csv=array(); $csvline=0; foreach ($csv_lines as $csv_line) { $csv[] = str_getcsv($csv_line,";"); if ((strtotime($csv[$csvline][0]) > 1000000)) { $csv[$csvline][0] = strtotime($csv[$csvline][0]); } $csvline++; } sort($csv); // pokud je pripojen parametr :aktualni: vypíší se jen termíny ode dneška dále if (preg_match('/:aktualni:/', $nadpis, $match) === 1) { $timestamp=time(); } else { $timestamp=1000000; } $pristirok=strtotime("1.1.".date('Y', strtotime('+1 year'))); // Při generování HTML vygenerujeme i iCAL $file=CAL.'/'.basename($soubor,'.csv').'.ics'; $ical="BEGIN:VCALENDAR\r\nVERSION:2.0\r\nPRODID:-//www.klikva.cz/ucms//NONSGML v1.0//EN\r\n"; for ($radek = 0; $radek < count($csv); $radek++) { if (is_numeric($csv[$radek][0]) && $csv[$radek][0] < $timestamp) { continue; } $incl_text=$incl_text.""; $ical=$ical."BEGIN:VEVENT\r\n"; for ($sloupec = 0; $sloupec < count($csv[$radek]); $sloupec++) { if ($sloupec == 0 && date("Y",$csv[$radek][$sloupec])>1970) { if ($csv[$radek][$sloupec] > $pristirok) { $rok=date(" Y ",$csv[$radek][$sloupec]); } else { $rok=""; } $ical=$ical."DTSTAMP:".date('Ymd\THis', time())."\r\n"; $ical=$ical."UID:".date('Ymd\THis', $csv[$radek][$sloupec])."-".$radek.$sloupec."@ucms\r\n"; // pokud neni specifikovana hodina, tj. zacatek je o pulnoci if (date("G",$csv[$radek][$sloupec])==0) { $ical=$ical."DTSTART:".date('Ymd', $csv[$radek][$sloupec])."\r\n"; $ical=$ical."DTEND:".date('Ymd', $csv[$radek][$sloupec])."\r\n"; $ical=$ical."SUMMARY:"; $incl_text=$incl_text."".date("j.",$csv[$radek][$sloupec]).mesic(date("n",$csv[$radek][$sloupec])).$rok.""; } else { $ical=$ical."DTSTART:".date('Ymd\THis', $csv[$radek][$sloupec])."\r\n"; $ical=$ical."DTEND:".date('Ymd\THis', ($csv[$radek][$sloupec]+7200))."\r\n"; $ical=$ical."SUMMARY:"; $incl_text=$incl_text."".date("j.",$csv[$radek][$sloupec]).mesic(date("n",$csv[$radek][$sloupec])).$rok.date(" G:i",$csv[$radek][$sloupec]).""; } } else { $incl_text=$incl_text."".$csv[$radek][$sloupec].""; $ical=$ical.$csv[$radek][$sloupec]." "; } } $incl_text=$incl_text."\n"; $ical=$ical."\r\nEND:VEVENT\r\n"; } $ical=$ical."END:VCALENDAR"; file_put_contents($file,$ical); } else { $incl_text = ""; } $line_slice = $line_number + 1; array_splice($text_array, $line_slice, 0, $lineend); array_splice($text_array, $line_slice, 0, $incl_text); } } // end foreach foreach ($text_array as &$line) { if ($pr === 0 && str_replace('{{{', '
', $line) != $line) {
            $line = str_replace('{{{', '
', $line);
            $pr = 1;
        } else {
            if ($pr === 1 && str_replace('}}}', '
', $line) != $line) { $line = str_replace('}}}', '
', $line); $pr = 0; } else { if ($pr == 0) { if (preg_replace('/^ \*/', '
  • ', $line) != $line) { if ($ul == 0) { $ul = 1; $line = preg_replace('/^ \*/', ' ".$line; $ul = 0; } } if (preg_replace('/^\|\|/', '', $line) != $line) { if ($tb === 0) { $tb = 1; $line = preg_replace('/^\|\|/', '', $line); $line = preg_replace('/\|\|/', '', $line); $line = preg_replace('/\|\|/', '
    ', $line); $line = preg_replace('/\|\|\s*$/', '
    ', $line); } else { if ($tb === 1) { $line = preg_replace('/^\|\|/', '
    ', $line); $line = preg_replace('/\|\|\s*$/', '
    ', $line); } } } else { if ($tb === 1) { $line = "
    ".$line; $tb = 0; } } // Nahrazení hlavičkových proměnných // TODO toto predelat tak, aby se nahrazovalo v jednom pruchodu polem foreach ($simple_replace as $pattern => $replacement) { $line = preg_replace($pattern, $replacement, $line); } //$line=$line."
    "; } } } //echo $line; } return ($text_array); } /** * Vypise zadanou hodnotu * @param {Variant} $msg - Hodnota k vypsani (string|array). */ function pre_print($msg) { echo "
    ";
        print_r($msg);
        echo "
    "; } /** * @param $filename * @return string */ function loadAndCleanFile($filename) { if (file_exists(TXT.'/'.$filename)) { return implode(wiki2html(clean_headers($filename), array())); } return ''; } /** * Pri zavolani uCMS s GET parametrem "VERSION" bude vracena aktualni verze uCMS a ukoncen chod app. */ if (isset($_GET["VERSION"])) { $tmp = array(); $tmp["VERSION_MAJOR"] = VERSION_MAJOR; $tmp["VERSION_MINOR"] = VERSION_MINOR; $tmp["VERSION_GIT"] = VERSION_GIT; echo json_encode($tmp); exit; } /** * Uvodni natazeni souboru index, kdyz jsem prihlasen a neposilam zadny paramtery - * napr. pri vynucenem reloadu. */ function firstLoad(){ session_start(); $_SESSION["auth"] = "admin"; $_SESSION["ip"] = $_SERVER['REMOTE_ADDR']; $_SESSION["time"] = time(); header("Cache-control: private"); htmlHead(); if (self_check()) { $file = 'index'; $text["headers"] = text_headers($file.'.txt'); $text["data"] = clean_headers($file.'.txt'); text_form(NAHRANSOUBOR.$file.". ".SHOW."$file.html.", $text); } htmlFooter(); exit; } /** * Funkce generující slovo vyskloňovaného měsíce * @param int 1-12 * @return string */ function mesic($month) { static $mesice = array(1 => 'ledna', 'února', 'března', 'dubna', 'května', 'června', 'červenece', 'srpna', 'září', 'října', 'listopadu', 'prosince'); return $mesice[$month]; } // Následující řádek začínající define("SHA","..."); obsahuje zašifrované heslo (hash). // Dlouhý řeťezec mezi závorkami (v příkladu nahoře tečky) je třeba nahradit // tím, které se vygeneruje při přihlášení do μCMS. define("SHA", "82c1720eb8199e070e684587d4b1fdb47a9fcf30"); /** * second round of login - credentials are already filled in, check them */ if (isset($_POST["login"]) || (!$_POST && !$_GET)) { if (sha1($_POST["pass"]) === SHA) { firstLoad(); } if (!$_POST && !$_GET && isLogged()) { firstLoad(); } sleep(4); // ????? htmlHead(); //login_form(); // pre_print($_POST); echo '

    ' . LOGFAIL . _nl; gen_hash($_POST["pass"]); echo '

    '; htmlFooter(); exit; } if (isset($_POST["logout"])) { session_start(); destroy_session(ULOGOUT); exit(); } /** * Flag, ktery rika, zda uz probehlo zpracovani $_POST pozadavku. Pokud ne, je na konci generovan login form. * TODO - prosim o dokumentaci kazde jednotlive sekce :D */ $PROCESSED = FALSE; /** * Vypise seznam souboru v danem adresari/podadresari * * @param {string} $folder - adresar, kde se bude hledat seznam souboru * @param {string} $subfolder - podadresar, kde se bude hledat * @param {string} $pseudoTag - pseudotag, ktery bude generovan (napr. "dat" => [dat:jmeno_souboru_z_adresare]) */ function outputListOfFiles($folder, $subfolder, $pseudoTag) { check_session(); htmlHead(); text_form(FILELISTED, post2arr()); $content = dir2arr($folder . '/' . $subfolder, 'FILE'); $prepend = ($subfolder !== '.') ? $subfolder . "/" : ""; foreach ($content as $file) { echo "[" . $pseudoTag . ":" . $prepend . $file . "]" . _nl; } } /** * Vypise seznam priloh */ if (isset($_POST["dat_list"]) && isPathValid($_POST["dat_dir_list"])) { outputListOfFiles(DAT, $_POST["dat_dir_list"], 'dat'); $PROCESSED = TRUE; } /** * Vypise seznam obrazku */ if (isset($_POST["img_list"]) && isPathValid($_POST["img_dir_list"])) { outputListOfFiles(IMG, $_POST["img_dir_list"], 'img'); $PROCESSED = TRUE; } /** * Nahraje vybrany soubor */ if (isset($_POST["load"])) { check_session(); htmlHead(); if (!isFilenameValid($_POST["file_list"])) { text_form(LOWERCASE, post2arr()); } else { $filetxt = $_POST["file_list"] . '.txt'; $data["headers"] = text_headers($filetxt); $data["data"] = clean_headers($filetxt); text_form(NAHRANSOUBOR . $_POST["file_list"] . ".", $data); } $PROCESSED = TRUE; } /** * Ulozi ci vytvori stranku */ if (isset($_POST["update"])) { check_session(); htmlHead(); // pre_print($_POST); if (!isFilenameValid($_POST["soubor"])) { text_form(LOWERCASE, post2arr()); } else { text_form(arr2disk(post2arr()), post2arr()); } $PROCESSED = TRUE; } if (isset($_POST["clear"])) { check_session(); htmlHead(); $data["data"][0] = "= [def:titulek] =\n\nVytvořeno: ''[def:datum]''\n\nAktualizováno: ''[def:aktualizace]''\n\n[stitky]"; $data["headers"]["soubor"] = ""; $data["headers"]["titulek"] = ""; $data["headers"]["rodic"] = ""; $data["headers"]["vaha"] = ""; $data["headers"]["menu"] = ""; $data["headers"]["stitky"] = ""; $data["headers"]["datum"] = date('d.m.Y'); text_form('', $data); $PROCESSED = TRUE; } if (isset($_POST["check"])) { check_session(); htmlHead(); self_check(); text_form(CHECKFINISHED, post2arr()); $PROCESSED = TRUE; } if (isset($_POST["delete"])) { check_session(); htmlHead(); $file = TXT . '/' . $_POST["file_list"] . '.txt'; $bkp = BKP . '/' . $_POST["file_list"] . '.bak'; $htm = HTM . '/' . $_POST["file_list"] . '.html'; $bhtm = BKP . '/' . $_POST["file_list"] . '.html'; $DELETED = FALSE; if (rename($file, $bkp)) { //clean the html (without testing) rename($htm, $bhtm); $DELETED = TRUE; } text_form($DELETED ? DELETED : CANTDEL, post2arr()); $PROCESSED = TRUE; } /** * Nahraje obrazek nebo datovy soubor. * Obrazek je nahran do podslozky ktera odpovida aktualni strance. */ if (IS_UPLOAD_PRESENT || isset($_POST["upload_image"])) { check_session(); htmlHead(); if (IS_UPLOAD_PRESENT) { $upload_dir = DAT; } else { $upload_dir = IMG."/".sanitizePath($_POST["soubor"]); if(is_dir(IMG) && !file_exists($upload_dir) && !mkdir($upload_dir, 0700) && !is_dir($upload_dir)) { throw new \RuntimeException(sprintf('Directory "%s" was not created', $upload_dir)); } } $FILE_NAME = $_FILES['file_uploaded']['name']; $SRC_FILE_NAME = $_FILES['file_uploaded']['tmp_name']; $TARGET_FILE_NAME = $upload_dir . '/' . basename($FILE_NAME); if (is_dir($upload_dir)) { if (move_uploaded_file($SRC_FILE_NAME, $TARGET_FILE_NAME)) { text_form($FILE_NAME . UPLOADED . " [".$upload_dir."]", post2arr()); } else { text_form(CANTWRITE . "- PHP error" . $_FILES['file_uploaded']['error'], post2arr()); } } else { text_form(FAODIR . $upload_dir, post2arr); } $PROCESSED = TRUE; } /** * Vrati nazev stranky ze vstupniho pole. Pokud existuje dany prvek je vracen jako nazevStranky. * Postupuje se v poradi titulek, menu, soubor. * * @param $headers */ function getNazevStranky($headers) { $notMenuValue = $headers["menu"] ?: $headers["soubor"]; return $headers["titulek"] ?: $notMenuValue; } /** * GENEROVANI OBSAHU WEBU */ if (isset($_POST["generate"]) || IS_CRON_PRESENT) { // pokud jsme volani pomoci GET parametru CRON a zvlastniho hesla pouze za ucelem pregenerovani webu // musime heslo zkontrolovat a nasledne potlacit nektere vystupy if (IS_CRON_PRESENT) { if (sha1($_GET["CRON"]) !== CRONSHA) { sleep(4); // TODO clarify sleep die (LOGFAIL); } echo GENERATED; } else { check_session(); htmlHead(); //nejprve ulozime if (!isFilenameValid($_POST["soubor"])) { $save_mess = LOWERCASE; } else { $save_mess = arr2disk(post2arr()); } $err_mess = ''; } //Načteme hlavičku stránek ze souboru header.txt $header = loadAndCleanFile('header.txt'); //Načteme patičku stránek ze souboru footer.txt $footer = ''; $text = array(); $stitky = array(); foreach (dir2arr(TXT, 'FILE') as $filenum => $filetxt) { $file = preg_replace('/.txt$/', '', $filetxt); $text[$file]["filename"] = $filetxt; $text[$file]["headers"] = text_headers($filetxt); $text[$file]["data"] = clean_headers($filetxt); //Generování pole se štítky foreach (explode('#', $text[$file]["headers"]["stitky"]) as $stitek) { $nazev = getNazevStranky($text[$file]["headers"]); if (!empty($stitek)) { $stitky[$stitek][$nazev] = $text[$file]["headers"]["soubor"]; } } // Nastavení váhy článku v menu if (is_numeric($text[$file]["headers"]["vaha"])) { $weight = MAXPGSPERWEIGHT * $text[$file]["headers"]["vaha"] + $filenum; } else { $weight = $filenum; } // Určení rodiče v menu (pokud není, je rodičem 'main' if ($text[$file]["headers"]["rodic"] == '') { $menu["main"][$weight] = $file; } else { $menu[$text[$file]["headers"]["rodic"]][$weight] = $file; } } $menu_html = ''; //rekurzivni funkce na generovani menu gen_html_menu($menu, $text, 'main', $menu_html); //generování štítků a stránek štítků if (!empty($stitky)) { ksort($stitky); $page = ''; $sumpage = '