From c98515883097467896a3f46b755c8cb892fe8961 Mon Sep 17 00:00:00 2001 From: Ludovic Pouzenc Date: Tue, 29 Oct 2013 18:42:08 +0100 Subject: Import initial avec une arbrescence éclatée MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- code/admin/add.php | 55 ++++++++++++ code/admin/admin.css | 15 ++++ code/admin/admin.js | 123 +++++++++++++++++++++++++++ code/admin/ajax.php | 63 ++++++++++++++ code/admin/auth.php | 53 ++++++++++++ code/admin/editor-bind-code.html | 71 ++++++++++++++++ code/admin/index.php | 111 ++++++++++++++++++++++++ code/admin/render.php | 59 +++++++++++++ code/admin/utils.php | 179 +++++++++++++++++++++++++++++++++++++++ code/index.php | 9 ++ 10 files changed, 738 insertions(+) create mode 100644 code/admin/add.php create mode 100644 code/admin/admin.css create mode 100644 code/admin/admin.js create mode 100644 code/admin/ajax.php create mode 100644 code/admin/auth.php create mode 100644 code/admin/editor-bind-code.html create mode 100644 code/admin/index.php create mode 100644 code/admin/render.php create mode 100644 code/admin/utils.php create mode 100644 code/index.php (limited to 'code') diff --git a/code/admin/add.php b/code/admin/add.php new file mode 100644 index 0000000..c839e0a --- /dev/null +++ b/code/admin/add.php @@ -0,0 +1,55 @@ + + + + + + + + +<?=($kind=='media')?_('Add media'):_('Add page')?> + + +
+ +
+ +
+ +
+
+ +
+ + +
+ + + + + + + +
+ +
+ + diff --git a/code/admin/admin.css b/code/admin/admin.css new file mode 100644 index 0000000..f01a35d --- /dev/null +++ b/code/admin/admin.css @@ -0,0 +1,15 @@ +fieldset { + display:inline-block; + vertical-align: top; + margin: 0.5em; + width:45%; +} +fieldset>label { + display:inline-block; + text-align:right; + width: 12em; +} +.tree_add { + display:block; + float:right; +} diff --git a/code/admin/admin.js b/code/admin/admin.js new file mode 100644 index 0000000..3d0125d --- /dev/null +++ b/code/admin/admin.js @@ -0,0 +1,123 @@ +// Helpers +function gEBId(id) { return document.getElementById(id) }; + +function microAjaxJSON(query,callback) { + microAjax(query,function (res) { + var parsed_json; + try { + parsed_json = JSON.parse(res); + } catch(err) { + alert(res); + return; + } + callback(parsed_json); + }); +} + +// Admin simple actions +function select_fold(path) { + gEBId("fold_path").value=path; +} + +// Admin AJAX actions +function load_page_props(path) { + gEBId("page_path").value=path; + var url = "ajax.php?action=load_page_props&path=" + encodeURIComponent(path); + microAjaxJSON(url, function (parsed_json) { + gEBId("page_title").value = parsed_json.page_title; + gEBId("page_description").value = parsed_json.page_description; + gEBId("page_keywords").value = parsed_json.page_keywords; + }); +} + +function load_media_props(path) { + gEBId("media_path").value=path; + var url = "ajax.php?action=load_media_props&path=" + encodeURIComponent(path); + microAjaxJSON(url, function (parsed_json) { + gEBId("media_title").value = parsed_json.media_title; + gEBId("media_description").value = parsed_json.media_description; + //gEBId("media_keywords").value = parsed_json.media_keywords; + }); +} + +function save_page_props() { + var path = gEBId("page_path").value; + var page_title = gEBId("page_title").value; + var page_description = gEBId("page_description").value; + var page_keywords = gEBId("page_keywords").value; + + //TODO : check against regex + + var url = "ajax.php?action=save_page_props" + + "&path=" + encodeURIComponent(path) + + "&page_title=" + encodeURIComponent(page_title) + + "&page_description=" + encodeURIComponent(page_description) + + "&page_keywords=" + encodeURIComponent(page_keywords); + + microAjaxJSON(url, function (parsed_json) { + if ( parsed_json.result != "OK" ) { + alert("Error\nResult: " + parsed_json.result + "\nRequest: " + url); + return; + } + //TODO : says to user that the work is done + }); +} + +function save_media_props() { + var path = gEBId("media_path").value; + var title = gEBId("media_title").value; + var description = gEBId("media_description").value; + //var keywords = gEBId("media_keywords").value; + + //TODO : check against regex + + var url = "ajax.php?action=save_media_props" + + "&path=" + encodeURIComponent(path) + + "&title=" + encodeURIComponent(title) + + "&description=" + encodeURIComponent(description); + // + "&keywords=" + encodeURIComponent(keywords); + + microAjaxJSON(url, function (parsed_json) { + if ( parsed_json.result != "OK" ) { + alert("Error\nResult: " + parsed_json.result + "\nRequest: " + url); + return; + } + //TODO : says to user that the work is done + }); +} + +function save_site_props() { + //TODO +} + +// Admin other actions (with page change or refresh) +function go_add_form(kind) { + document.location = 'add.php?kind=' + encodeURIComponent(kind); +} + +function go_add(kind,type) { + var path = gEBId("fold_path").value; + var name = gEBId("fold_add_name").value; + // TODO : check name and path against regex + var url = 'add.php?kind=' + encodeURIComponent(kind) + + '&action=add_' + encodeURIComponent(type) + + '&path=' + encodeURIComponent(path) + + '&name=' + encodeURIComponent(name); + document.location = url; +} + +function go_edit_page() { + var path = gEBId("page_path").value; + document.location = 'render.php?action=edit&page=' + encodeURIComponent(path); +} + +function go_delete_page() { + var path = gEBId("page_path").value; + //TODO : confirmation, ajax query, if OK, confirm then refresh +} + +function go_delete_media() { + var path = gEBId("page_path").value; + //TODO : confirmation, ajax query, if OK, confirm then refresh +} + diff --git a/code/admin/ajax.php b/code/admin/ajax.php new file mode 100644 index 0000000..0893843 --- /dev/null +++ b/code/admin/ajax.php @@ -0,0 +1,63 @@ + 'test title', + 'media_description' => 'test descr', + 'media_keywords' => 'test, keyword', + ); + } + + function save_page_props($path) { + //TODO : Should validate props here also... + $props=load_page_props($path); + + foreach ( array('page_title', 'page_description', 'page_keywords') as $k ) { + if ( array_key_exists($k,$_GET) ) $props[$k]=$_GET[$k]; + } + + $ini_path="content/$path/props.ini"; + return write_ini_file($props, $ini_path, false); + } + + function save_media_props($path) { + return FALSE; + } + + // URL params clean-up + $action=sanitize($_GET, 'action', '/[^a-z_]+/', 'none'); /* Could be : load_page_props, load_media_props... */ + $path=sanitize($_GET, 'path', '/[^a-z0-9\/]+/', ''); // Never put \. in this regex + + switch($action) { + case 'load_page_props': + $res = load_page_props($path); + break; + case 'load_media_props': + $res = load_media_props($path); + break; + case 'save_page_props': + if ( save_page_props($path) ) { + $res=array('result' => 'OK'); + } else { + $res=array('result' => 'FAILED'); + } + break; + case 'save_media_props': + if ( save_media_props($path) ) { + $res=array('result' => 'OK'); + } else { + $res=array('result' => 'FAILED'); + } + break; + default: + $res = array('result' => 'ERROR', 'error'=>'invalid action'); + break; + } + echo json_encode($res); +?> diff --git a/code/admin/auth.php b/code/admin/auth.php new file mode 100644 index 0000000..f4afee0 --- /dev/null +++ b/code/admin/auth.php @@ -0,0 +1,53 @@ + 0) ) { + header('Location: ' . $_SESSION['auth_return']); + } + echo "Authenticated\n"; + exit(); + } else { + $auth_fail=TRUE; + } + } +?> + + + + +Authentification + + +
+
+ Authentification + + + + + + + + + + + + +
+ + +
+
+
+ + diff --git a/code/admin/editor-bind-code.html b/code/admin/editor-bind-code.html new file mode 100644 index 0000000..d6a9825 --- /dev/null +++ b/code/admin/editor-bind-code.html @@ -0,0 +1,71 @@ + + + + + + + + + diff --git a/code/admin/index.php b/code/admin/index.php new file mode 100644 index 0000000..ddb95b3 --- /dev/null +++ b/code/admin/index.php @@ -0,0 +1,111 @@ + + + + + + + + + +<?=_('Admin')?> + + +
+ +
+ + +
+' . print_r($page_tree,true) . '' . "\n"; + php_array_to_tree($page_tree, '', 'load_page_props', '', 'pagedir-0'); +?> +
+
+ +
+ + +
+ + + + + +

+ + +
+ + +
+ + +
+ + +
+
+ +
+ + +
+' . print_r($media_tree,true) . '' . "\n"; + php_array_to_tree($media_tree, '', 'load_media_props', '', 'mediadir-0'); +?> +
+
+ +
+ + +
+ + + + + +

+ + +
+ + +
+ + +
+
+ +
+ + +
+ + +
+ + +
+
+ +
+ + diff --git a/code/admin/render.php b/code/admin/render.php new file mode 100644 index 0000000..9d4175e --- /dev/null +++ b/code/admin/render.php @@ -0,0 +1,59 @@ + + + + + +<?=$page_props['page_title']?> + + +screen.css"> + + + + + +'ok', 'size' => $size)); + } + } +?> diff --git a/code/admin/utils.php b/code/admin/utils.php new file mode 100644 index 0000000..f02146a --- /dev/null +++ b/code/admin/utils.php @@ -0,0 +1,179 @@ + $v ) { + if ( array_key_exists($k, $array_entry_props) + && array_key_exists('replace_chars_re', $array_entry_props[$k]) + && array_key_exists('default_value', $array_entry_props[$k]) + ) { + $array_ini[$k] = sanitize($array_ini, $k, + $array_entry_props[$k]['replace_chars_re'], + $array_entry_props[$k]['default_value'] ); + } else { + unset($array_ini[$k]); + } + } + // Set default value for all missing ini entries (if default value exists) + foreach ( $array_entry_props as $k => $v ) { + if ( !array_key_exists($k, $array_ini) && array_key_exists('default_value', $array_entry_props[$k]) ) { + $array_ini[$k] = $array_entry_props[$k]['default_value']; + } + } + } + return $array_ini; + } + + function load_ini_site_conf($ini_path) { + $sanitize_site_conf = array( + 'site_admin_lang' => array( 'replace_chars_re' => '/[^a-zA-Z\/\_-]+/', 'default_value' => 'C' ), + 'site_default_page' => array( 'replace_chars_re' => '/[^a-z0-9\/]+/', 'default_value' => 'en/index' ), + ); + return sanitize_ini($ini_path, $sanitize_site_conf); + } + + function load_ini_page_props($page) { + $sanitize_page_props = array( + //FIXME : title regex : all but html special chars ? + 'page_title' => array( 'replace_chars_re' => '/[^\w !_,.-]+/', 'default_value' => '(missing title in props.ini)' ), + 'page_template' => array( 'replace_chars_re' => '/[^a-z0-9]+/', 'default_value' => 'default' ), + 'page_layout' => array( 'replace_chars_re' => '/[^a-z0-9]+/', 'default_value' => 'article' ), + 'page_description' => array( 'replace_chars_re' => '/[^\w !_,.-]+/', 'default_value' => '(missing description in props.ini)' ), + 'page_keywords' => array( 'replace_chars_re' => '/[^\w !_,.-]+/', 'default_value' => '(missing keywords in props.ini)' ), + ); + $ini_path="content/$page/props.ini"; + return sanitize_ini($ini_path, $sanitize_page_props); + } + + function l10n_init($lang) { + setlocale(LC_MESSAGES, "$lang.utf8"); + $base = bindtextdomain('editablesite', './locale'); + $domain = textdomain('editablesite'); + bind_textdomain_codeset('editablesite', 'UTF-8'); + //echo "
l10n file is '$base/$lang.utf8/LC_MESSAGES/$domain.mo'
\n"; + } + + function need_auth() { + session_start(); + if ( ! array_key_exists('auth_user', $_SESSION) || $_SESSION['auth_user'] !== TRUE ) { + $_SESSION['auth_return'] = $_SERVER['REQUEST_URI']; + header('Location: auth.php'); + exit(); + } + } + + function is_ress($kind, $path) { + switch ($kind) { + case 'page': return is_file($path.'/props.ini'); + case 'media': return substr($path, -4)=='.jpg' && is_file($path); + default : return FALSE; + } + } + + function strcmp_tree($a,$b) { + if (is_array($a) || is_array($b) ) return 0; + return strnatcasecmp($a,$b); + } + + function find_all($path, $kind) { + $result=array(); + if ( $handle = opendir($path) ) { + while (FALSE !== ($entry = readdir($handle))) { + if ( array_search($entry, array('.','..')) !== FALSE ) continue; + $childpath=$path.'/'.$entry; + if ( is_ress($kind, $childpath) ) $result[] = $entry; + else if ( is_dir($childpath) ) $result[$entry]=find_all($childpath,$kind); + } + closedir($handle); + } + uasort($result, 'strcmp_tree'); + return $result; + } + + function php_array_to_tree($page_tree, $node_cb, $leaf_cb='', $path='', $itemid="item-0") { + if ( ! is_array($page_tree) ) return; + echo "\n"; + } + + function safe_put_file($path, $content) { + //FIXME : if exists, then mktemp, put in it then rm and mv. Right preservation problems ? + if ($handle = fopen($path, 'w')) { + $res = fwrite($handle, $content); + fclose($handle); + } + } + + function _write_ini_file_r(&$content, $assoc_arr, $has_sections) + { + foreach ($assoc_arr as $key => $val) { + if (is_array($val)) { + if($has_sections) { + $content .= "[$key]\n"; + _write_ini_file_r($content, $val, false); + } else { + foreach($val as $iKey => $iVal) { + if (is_int($iKey)) + $content .= $key ."[] = $iVal\n"; + else + $content .= $key ."[$iKey] = $iVal\n"; + } + } + } else { + if ( preg_match('/^\w+$/',$val)===1 ) + $content .= "$key = $val\n"; + else + $content .= "$key = \"" . str_replace('"', '\"', $val) . "\"\n"; + } + } + } + + function write_ini_file($assoc_arr, $path, $has_sections) { + $res=FALSE; + $content = ''; + _write_ini_file_r($content, $assoc_arr, $has_sections); + if (is_string($content) && strlen($content) > 0) { + safe_put_file($path, $content); + } + + return $res; + } + diff --git a/code/index.php b/code/index.php new file mode 100644 index 0000000..b07f778 --- /dev/null +++ b/code/index.php @@ -0,0 +1,9 @@ +