Browse Source

initial commit after server failure

poi-dev
Léo 6 years ago
commit
a14390f8f5
  1. 5
      .gitignore
  2. 9
      .htaccess
  3. 58
      controllers/d.admin.php
  4. 204
      controllers/d.blog.php
  5. 77
      controllers/d.contact.php
  6. 20
      controllers/d.map.php
  7. 237
      controllers/d.users.php
  8. 77
      controllers/d.wiki.php
  9. 65
      includes/config.example.php
  10. 42
      includes/images.php
  11. 71
      includes/routes.php
  12. 23
      includes/session.php
  13. 6
      index.php
  14. 6
      info.php
  15. 487
      models/d.blog.php
  16. 410
      models/d.users.php
  17. 215
      models/d.wiki.php
  18. 48
      src/Mercator-Mountain1.svg
  19. 119
      src/exportpgsql.backup
  20. 6
      src/logo.min.svg
  21. 217
      src/logo.svg
  22. 102
      src/logo2.svg
  23. 104
      src/logo3.svg
  24. BIN
      src/logo3_black.png
  25. 1
      src/wiki.backup
  26. 10
      third/Md/Markdown.inc.php
  27. 1616
      third/Md/Markdown.php
  28. 11
      third/Md/MarkdownExtra.inc.php
  29. 1625
      third/Md/MarkdownExtra.php
  30. 9
      third/Md/MarkdownInterface.inc.php
  31. 34
      third/Md/MarkdownInterface.php
  32. 7
      views/blocks/d.footer.html
  33. 46
      views/blocks/d.head.html
  34. 52
      views/blocks/d.nav.html
  35. 240
      views/css/d.blog.css
  36. 341
      views/css/d.index.css
  37. 173
      views/css/d.map.css
  38. 219
      views/css/d.user.css
  39. 66
      views/css/d.wiki.css
  40. 23
      views/d.admin.git-pull.html
  41. 24
      views/d.admin.html
  42. 41
      views/d.admin.logs.html
  43. 72
      views/d.blog.edit.html
  44. 55
      views/d.blog.list.html
  45. 45
      views/d.blog.list.rss
  46. 125
      views/d.blog.view.html
  47. 58
      views/d.contact.html
  48. 33
      views/d.index.html
  49. 25
      views/d.map.html
  50. 34
      views/d.user.login.html
  51. 70
      views/d.user.member_list.html
  52. 24
      views/d.user.password_lost.html
  53. 74
      views/d.user.profile.edit.html
  54. 66
      views/d.user.profile.html
  55. 41
      views/d.user.signin.html
  56. 30
      views/d.wiki.edit.html
  57. 56
      views/d.wiki.view.html
  58. BIN
      views/fonts/FiraMono-Bold.eot
  59. BIN
      views/fonts/FiraMono-Bold.otf
  60. BIN
      views/fonts/FiraSans-Bold.ttf
  61. BIN
      views/fonts/FiraSans-ExtraLight.eot
  62. BIN
      views/fonts/FiraSans-ExtraLight.otf
  63. BIN
      views/fonts/FiraSans-ExtraLight.ttf
  64. BIN
      views/fonts/FiraSans-Light.eot
  65. BIN
      views/fonts/FiraSans-Light.otf
  66. BIN
      views/fonts/FiraSans-Light.ttf
  67. BIN
      views/fonts/FiraSans-Medium.eot
  68. BIN
      views/fonts/FiraSans-Medium.otf
  69. BIN
      views/fonts/FiraSans-Medium.ttf
  70. BIN
      views/fonts/FiraSans-Regular.eot
  71. BIN
      views/fonts/FiraSans-Regular.otf
  72. BIN
      views/fonts/FiraSans-Regular.ttf
  73. BIN
      views/img/aside.jpg
  74. BIN
      views/img/favicon.png
  75. 104
      views/img/header.svg
  76. 104
      views/img/header_rss.svg
  77. BIN
      views/img/lstronic.png
  78. BIN
      views/img/thumb1.jpg
  79. BIN
      views/img/thumb2.jpg
  80. BIN
      views/img/thumb3.jpg
  81. 40
      views/js/d.avatar.js
  82. 22
      views/js/d.captcha.js
  83. 81
      views/js/d.header.js
  84. 64
      views/js/d.map.js
  85. 2337
      views/third/font-awesome-4.7.0/css/font-awesome.css
  86. 4
      views/third/font-awesome-4.7.0/css/font-awesome.min.css
  87. BIN
      views/third/font-awesome-4.7.0/fonts/FontAwesome.otf
  88. BIN
      views/third/font-awesome-4.7.0/fonts/fontawesome-webfont.eot
  89. 2671
      views/third/font-awesome-4.7.0/fonts/fontawesome-webfont.svg
  90. BIN
      views/third/font-awesome-4.7.0/fonts/fontawesome-webfont.ttf
  91. BIN
      views/third/font-awesome-4.7.0/fonts/fontawesome-webfont.woff
  92. BIN
      views/third/font-awesome-4.7.0/fonts/fontawesome-webfont.woff2
  93. 4
      views/third/jquery-3.1.1.min.js
  94. 56
      views/third/leaflet-easybutton/easy-button.css
  95. 379
      views/third/leaflet-easybutton/easy-button.js
  96. 152
      views/third/leaflet-fullscreen/Leaflet.fullscreen.js
  97. 1
      views/third/leaflet-fullscreen/Leaflet.fullscreen.min.js
  98. BIN
      views/third/leaflet-fullscreen/fullscreen.png
  99. BIN
      views/third/leaflet-fullscreen/fullscreen@2x.png
  100. 40
      views/third/leaflet-fullscreen/leaflet.fullscreen.css

5
.gitignore

@ -0,0 +1,5 @@
/includes/config.php
/medias/*
*.sublime-project
*.sublime-workspace
*.log

9
.htaccess

@ -0,0 +1,9 @@
AddDefaultCharset UTF-8
RewriteEngine On
# Everything uses the routing system
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-l
RewriteRule . %{ENV:BASE}index.php [L]

58
controllers/d.admin.php

@ -0,0 +1,58 @@
<?
if(isset($controller->splitted_url[1]) && $user->role >= 800) {
switch ($controller->splitted_url[1]) {
case '': case 'admin':
$head['title'] = "Administration";
include ($config['views_folder']."d.admin.html");
break;
case 'git-pull':
if ($user->role >= 1000) {
$head['title'] = "Mise à jour";
$output = array();
chdir($config['abs_root_folder']);
exec("git pull origin master", $output);
include ($config['views_folder']."d.admin.git-pull.html");
}
else {
$notfound = 1;
}
break;
case 'logs':
if ($user->role >= 800) {
$head['title'] = "Logs";
$files_list = scandir($config['logs_folder']);
if (isset($controller->splitted_url[2]) && is_numeric($controller->splitted_url[2]) && intval($controller->splitted_url[2]) < count($files_list)-2) {
$filenb = $controller->splitted_url[2];
}
else {
$filenb = 0;
}
chdir($config['logs_folder']);
exec("tail -n 200 ".$files_list[$filenb+2]." | tac", $output);
include ($config['views_folder']."d.admin.logs.html");
}
else {
$notfound = 1;
}
break;
default:
$notfound = 1;
break;
}
}
else if($user->role >= 800) {
$head['title'] = "Administration";
include ($config['views_folder']."d.admin.html");
}
else {
$notfound = 1;
}
?>

204
controllers/d.blog.php

@ -0,0 +1,204 @@
<?
require_once($config['models_folder']."d.blog.php");
require_once($config['models_folder']."d.users.php");
$head['css'] = "d.index.css;d.blog.css";
$blogArticle = new BlogArticle();
// In case we are in the list of articles, we set url to switch with according parameters
if (!isset($controller->splitted_url[1]) OR $controller->splitted_url[1]=="" OR is_numeric($controller->splitted_url[1])) {
$head['title'] = "Blog";
// Get the correct page number
if (!isset($controller->splitted_url[1]) OR $controller->splitted_url[1]=="") {
$page = 0;
} else {
$page = $controller->splitted_url[1] - 1;
}
$controller->splitted_url[1] = "list";
$list = "html";
$articles_per_pages = 5;
}
switch ($controller->splitted_url[1]) {
case "rss":
$page = 0;
$list = "rss";
$articles_per_pages = 20;
case "list":
$blogArticles = new BlogArticles();
$blogArticles->number(($user->role >= 600));
// In case the wanted page is too big
if($articles_per_pages * $page >= $blogArticles->number)
$page = 0;
$blogArticles->listArticles($page*$articles_per_pages,$articles_per_pages,($user->role >= 600));
$i = 0;
$blogArticles_list = array();
foreach ($blogArticles->ids as $row) {
$blogArticles_list[$i] = new BlogArticle();
$blogArticles_list[$i]->id = $row;
$blogArticles_list[$i]->populate();
$blogArticles_list[$i]->md2txt();
$tempUser = new User();
$tempUser->id = $blogArticles_list[$i]->author;
$tempUser->populate();
$blogArticles_list[$i]->author_name = $tempUser->name;
unset($tempUser);
$i++;
}
$first = $page*$articles_per_pages+1;
$last = (($page+1)*$articles_per_pages > $blogArticles->number ? $blogArticles->number : ($page+1)*$articles_per_pages);
if ($list == "rss") {
include ($config['views_folder']."d.blog.list.rss");
} else {
include ($config['views_folder']."d.blog.list.html");
}
break;
case "new":
if($user->role >= 800) {
if(isset($_POST['submit'])) {
$blogArticle->content = $_POST['content'];
$blogArticle->locale = $_POST['locale'];
$blogArticle->title = $_POST['title'];
$blogArticle->comments = isset($_POST['comments'])?'t':'f';
$blogArticle->author = $user->id;
if(!$blogArticle->checkUrl($_POST['url'],1)) {
$blogArticle->insert();
header('Location: '.$config['rel_root_folder']."blog/".$blogArticle->url);
}
else {
$head['title'] = $blogArticle->title;
$error = "url";
$new = 1;
include ($config['views_folder']."d.blog.edit.html");
}
}
else {
$head['title'] = "Nouvel article";
$new = 1;
include ($config['views_folder']."d.blog.edit.html");
}
break;
}
default:
// If the page exists
if ($blogArticle->checkUrl($controller->splitted_url[1],$user->role >= 600)) {
if (isset($controller->splitted_url[2]) && $controller->splitted_url[2] == "delete" && $user->role >= 800) {
$blogArticle->delete();
header('Location: '.$config['rel_root_folder']."blog/".$blogArticle->url);
}
else if (isset($controller->splitted_url[2]) && $controller->splitted_url[2] == "edit" && $user->role >= 800) {
if(isset($_POST['submit'])) {
$blogArticle->content = $_POST['content'];
$blogArticle->locale = $_POST['locale'];
$blogArticle->title = $_POST['title'];
$blogArticle->comments = isset($_POST['comments'])?'t':'f';
$blogArticle->author = $user->id;
$blogArticle->update();
header('Location: '.$config['rel_root_folder']."blog/".$blogArticle->url);
}
else {
$blogArticle->populate();
$head['title'] = $blogArticle->title;
include ($config['views_folder']."d.blog.edit.html");
}
}
else {
// Manage history of an article
if($user->role >= 600) {
$blogArticles_history = new BlogArticles();
$blogArticles_history->getHistory($controller->splitted_url[1]);
$i = 0;
foreach ($blogArticles_history->ids as $row) {
$blogArticles_history_list[$i] = new BlogArticle();
$blogArticles_history_list[$i]->id = $row;
$blogArticles_history_list[$i]->populate();
$i++;
}
}
if (isset($controller->splitted_url[2]) && is_numeric($controller->splitted_url[2]))
$blogArticle->checkUrl($controller->splitted_url[1],$user->role>=600,$controller->splitted_url[2]);
// Manage comment creation
if (isset($controller->splitted_url[2]) && $controller->splitted_url[2]=="new_comment") {
if (isset($_POST['submit']) && $user->role > 0) {
$blogComment = new BlogComment();
$blogComment->locale = $user->locale;
$blogComment->author = $user->id;
$blogComment->article = $blogArticle->id;
$blogComment->content = $_POST['comment'];
$blogComment->insert();
}
}
// Manage comment deletion
if (isset($controller->splitted_url[2]) && $controller->splitted_url[2]=="delete_comment") {
if (isset($controller->splitted_url[3]) && is_numeric($controller->splitted_url[3])) {
$blogComment = new BlogComment();
$blogComment->id = $controller->splitted_url[3];
$blogComment->populate();
if ($user->role >= 800 || $user->id == $blogComment->author)
$blogComment->delete();
}
}
// Manage comment undeletion
if (isset($controller->splitted_url[2]) && $controller->splitted_url[2]=="undelete_comment") {
if (isset($controller->splitted_url[3]) && is_numeric($controller->splitted_url[3])) {
$blogComment = new BlogComment();
$blogComment->id = $controller->splitted_url[3];
$blogComment->populate();
if ($user->role >= 800 || $user->id == $blogComment->author)
$blogComment->undelete();
}
}
$blogArticle->populate();
$blogArticle->md2html();
// Manage comments
if ($blogArticle->comments == "t") {
$blogArticles_comments = new BlogComments();
$blogArticles_comments->listComments($blogArticle->id, ($user->role>400));
$i = 0;
foreach ($blogArticles_comments->ids as $row) {
$blogArticles_comments_list[$i] = new BlogComment();
$blogArticles_comments_list[$i]->id = $row;
$blogArticles_comments_list[$i]->populate();
$blogArticles_comments_list[$i]->md2html();
$blogArticles_comments_list[$i]->author_obj = new User();
$blogArticles_comments_list[$i]->author_obj->id = $blogArticles_comments_list[$i]->author;
$blogArticles_comments_list[$i]->author_obj->populate();
$i++;
}
}
$tempUser = new User();
$tempUser->id = $blogArticle->author;
$tempUser->populate();
$blogArticle->author_name = $tempUser->name;
unset($tempUser);
$head['title'] = $blogArticle->title;
include ($config['views_folder']."d.blog.view.html");
}
}
else {
$notfound = 1;
}
break;
}
?>

77
controllers/d.contact.php

@ -0,0 +1,77 @@
<?
function post($index) {
return isset($_POST[$index]) ? $_POST[$index] : '';
}
$error = "no";
if(isset($_POST['submit'])) {
$message = "Message reçu depuis Kabano par ".post('name').".<br>\r\n";
$message .= "<hr>\r\n";
$message .= "<pre style='padding: 10px; background: #ccc;'>".strip_tags(post('message'))."</pre><br>\r\n";
$headers = 'From: '. post('mail') . "\r\n" .
'Reply-To: '. post('mail') . "\r\n" .
'X-Mailer: PHP/' . phpversion() . "\r\n" .
'MIME-Version: 1.0' . "\r\n" .
'Content-type: text/html; charset=UTF-8' . "\r\n";
if(post('ns') == '' && $_POST['captcha'] == -2) {
$send = true;
if(post('name') == '') {
$error = "name";
$send = false;
}
if(post('subject') == '') {
$error = "subject";
$send = false;
}
if(post('mail') == '') {
$error = "mail";
$send = false;
}
if(post('message') == '') {
$error = "message";
$send = false;
}
if($send) {
if(mail($config['admin_mail'], "Kabano :: ".post('subject'), $message, $headers)) {
$error = "none";
} else {
$error = "unknown";
}
}
}
else {
$error = "spam";
}
}
if(post('name') != '')
$contact['name'] = post('name');
else if($user->role > 0)
$contact['name'] = $user->name;
else
$contact['name'] = '';
if(post('mail') != '')
$contact['mail'] = post('mail');
else if($user->role > 0)
$contact['mail'] = $user->mail;
else
$contact['mail'] = '';
$contact['subject'] = post('subject');
$contact['message'] = post('message');
$contact['ns'] = post('ns');
$head['css'] = "d.index.css;d.user.css";
$head['js'] = "d.captcha.js";
$head['title'] = "Contact";
include ($config['views_folder']."d.contact.html");
?>

20
controllers/d.map.php

@ -0,0 +1,20 @@
<?
$head['css'] = "d.index.css";
if(isset($controller->splitted_url[1]) && $controller->splitted_url[1] != '') {
switch ($controller->splitted_url[1]) {
default:
$notfound = 1;
break;
}
}
else {
$head['title'] = "Carte";
$head['third'] = "leaflet/leaflet.js;leaflet-fullscreen/Leaflet.fullscreen.min.js;leaflet-easybutton/easy-button.js";
$head['css'] .= ";d.map.css;../third/leaflet/leaflet.css;../third/leaflet-fullscreen/leaflet.fullscreen.css;../third/leaflet-easybutton/easy-button.css";
$head['js'] = "d.map.js";
include ($config['views_folder']."d.map.html");
}
?>

237
controllers/d.users.php

@ -0,0 +1,237 @@
<?
require_once($config['models_folder']."d.users.php");
$head['css'] = "d.index.css;d.user.css";
if(isset($controller->splitted_url[1])) {
switch ($controller->splitted_url[1]) {
case 'login':
$head['title'] = "Connexion";
if ($user->role == 0) {
if (isset($_POST['submit'])) {
// PROCESS DATA FROM FORM
$user = new User();
$user->login($_POST['login'], $_POST['password']);
if($user->id != 0) {
// SUCESSFULL LOGIN
$_SESSION['userid'] = $user->id;
header('Location: '.$_SERVER['HTTP_REFERER']);
}
else {
header('Location: '.$config['rel_root_folder'].'user/login?error=1');
}
}
include ($config['views_folder']."d.user.login.html");
} else {
header('Location: '.$config['rel_root_folder']);
}
break;
case 'logout':
session_destroy();
header('Location: '.$_SERVER['HTTP_REFERER']);
break;
case 'signin':
$head['js'] = "d.captcha.js";
$head['title'] = "Création de compte";
if ($user->role == 0) {
if (isset($_POST['submit'])) {
// PROCESS DATA FROM FORM
$user = new User();
$user->password = sha1($_POST['password']);
$user->name = $_POST['login'];
$user->mail = strtolower($_POST['mail']);
$user->role = 400;
$user->avatar = 'f';
$user->locale = "fr";
if($_POST['captcha'] == -2) {
if($user->availableName()) {
if($user->availableMail()) {
if($user->password != "" AND $user->name != "" AND $user->mail != "") {
$user->create();
header('Location: '.$config['rel_root_folder'].'user/login?status=created');
}
else {
header('Location: '.$config['rel_root_folder'].'user/signin?error=empty');
}
}
else {
header('Location: '.$config['rel_root_folder'].'user/signin?error=mail');
}
}
else {
header('Location: '.$config['rel_root_folder'].'user/signin?error=name');
}
}
else {
header('Location: '.$config['rel_root_folder'].'user/signin?error=captcha');
}
}
include ($config['views_folder']."d.user.signin.html");
} else {
header('Location: '.$config['rel_root_folder']);
}
break;
case 'password_lost':
$head['title'] = "Récupération de mot de passe";
if ($user->role == 0) {
if (isset($_POST['submit'])) {
// PROCESS DATA FROM FORM
$user = new User();
$user->mail = strtolower($_POST['mail']);
if($user->availableMail()) {
header('Location: '.$config['rel_root_folder'].'user/password_lost?error=1');
}
else {
$user->sendPassword();
header('Location: '.$config['rel_root_folder'].'user/login?status=password_sent');
}
}
include ($config['views_folder']."d.user.password_lost.html");
} else {
header('Location: '.$config['rel_root_folder']);
}
break;
case 'p':
if ($user->role >= 200) {
$userProfile = new User();
if (!isset($controller->splitted_url[2]) OR $controller->splitted_url[2]=="") {
// WE DISPLAY THE CONNECTED USER PROFILE
$userProfile = $user;
} else {
// WE DISPLAY THE SELECTED USER PROFILE FROM ID
$userProfile->checkID(intval($controller->splitted_url[2]));
}
$head['title'] = "Profil inexistant";
if($userProfile->id != 0) {
$userProfile->populate();
$head['title'] = "Profil de ".$userProfile->name;
}
// If we are editing the profile
if(isset($controller->splitted_url[3]) && $controller->splitted_url[3]=="edit" && ($user->role >= 800 || $user->id == $userProfile->id)) {
$head['js'] = "d.avatar.js";
if (isset($_POST['submit'])) {
$receivedUser = new User();
$receivedUser->name = $_POST['name'];
if($receivedUser->name != $userProfile->name && $receivedUser->availableName())
$userProfile->name = $receivedUser->name;
else if($receivedUser->name != $userProfile->name)
$nameError=1;
$receivedUser->mail = strtolower($_POST['mail']);
if($receivedUser->mail != $userProfile->mail && $receivedUser->availableMail())
$userProfile->mail = $receivedUser->mail;
else if ($receivedUser->mail != $userProfile->mail)
$mailError=1;
if($_POST['password']!='')
$userProfile->password=sha1($_POST['password']);
$userProfile->locale=$_POST['locale'];
if($user->role>=1000)
$userProfile->role = $_POST['role'];
$userProfile->website=$_POST['website'];
// Is the file correctly sent to the server ?
$pathToFile = $config['medias_folder']."avatars/".$userProfile->id;
if(isset($_FILES['avatarfile']['tmp_name']) && $_FILES['avatarfile']['tmp_name']!='' && $_FILES['avatarfile']['size'] < 16000000 && isset($_POST['avatar'])) {
require_once($config['includes_folder']."images.php");
if(file_exists($pathToFile)) unlink($pathToFile);
move_uploaded_file($_FILES['avatarfile']['tmp_name'], $pathToFile);
if(file_exists($pathToFile."_p.jpg")) unlink($pathToFile."_p.jpg");
generate_image_thumbnail($pathToFile, $pathToFile."_p.jpg", 220, 240);
if(file_exists($pathToFile."_s.jpg")) unlink($pathToFile."_s.jpg");
generate_image_thumbnail($pathToFile, $pathToFile."_s.jpg", 28, 28);
$userProfile->avatar = 't';
}
elseif (!isset($_POST['avatar'])) {
if(file_exists($pathToFile)) unlink($pathToFile);
if(file_exists($pathToFile."_p.jpg")) unlink($pathToFile."_p.jpg");
if(file_exists($pathToFile."_s.jpg")) unlink($pathToFile."_s.jpg");
$userProfile->avatar = 'f';
}
$userProfile->update();
$updated = 1;
}
include ($config['views_folder']."d.user.profile.edit.html");
}
// If we are displaying the profile
else {
if (isset($_POST['submit']) && $user->role >= 400) {
// PROCESS DATA FROM CONTACT FORM
$message = $_POST['message'];
$userProfile->sendMail($message, $user);
$mailsent = 1;
}
include ($config['views_folder']."d.user.profile.html");
}
}
else {
header('Location: '.$config['rel_root_folder']);
}
break;
case 'member_list':
if ($user->role >= 200) {
$rows_per_pages = 50;
// Get the correct page number
if (!isset($controller->splitted_url[2]) OR $controller->splitted_url[2]=="" OR $controller->splitted_url[2]=="0" OR !is_numeric($controller->splitted_url[2])) {
$page = 0;
} else {
$page = $controller->splitted_url[2] - 1;
}
$head['title'] = "Liste des membres";
$users = new Users();
$users->number();
// In case the wanted page is too big
if($rows_per_pages * $page >= $users->number)
$page = 0;
if(isset($_GET['order']))
$order = $_GET['order'];
else
$order = 'ASC';
if(isset($_GET['orderby']))
$orderby = $_GET['orderby'];
else
$orderby = 'id';
$users->list_users($page*$rows_per_pages,$rows_per_pages,$orderby,$order);
$i = 0;
foreach ($users->ids as $row) {
$user_list[$i] = new User();
$user_list[$i]->id = $row;
$user_list[$i]->populate();
$i++;
}
$first = $page*$rows_per_pages+1;
$last = (($page+1)*$rows_per_pages > $users->number ? $users->number : ($page+1)*$rows_per_pages);
include ($config['views_folder']."d.user.member_list.html");
}
else {
header('Location: '.$config['rel_root_folder']);
}
break;
default:
$notfound = 1;
break;
}
}
else {
$notfound = 1;
}
?>

77
controllers/d.wiki.php

@ -0,0 +1,77 @@
<?
require_once($config['models_folder']."d.wiki.php");
$head['css'] = "d.index.css;d.wiki.css";
$wikiPage = new WikiPage();
// Page doesn't exists
if(isset($controller->splitted_url[1]) && !$wikiPage->checkUrl($controller->splitted_url[1],$user->role >= 600) && $controller->splitted_url[1]!="") {
if($user->role >= 800) {
// Create new page
if(isset($_POST['submit'])) {
$wikiPage->content = $_POST['content'];
$wikiPage->locale = $_POST['locale'];
$wikiPage->title = $_POST['title'];
$wikiPage->insert();
header('Location: '.$config['rel_root_folder']."wiki/".$wikiPage->url);
}
else {
$head['title'] = "Nouvelle page";
include ($config['views_folder']."d.wiki.edit.html");
}
}
else {
$notfound = 1;
}
}
// Page exists
else if(isset($controller->splitted_url[1]) && $wikiPage->checkUrl($controller->splitted_url[1],$user->role >= 600)) {
if (isset($controller->splitted_url[2]) && $controller->splitted_url[2]=="edit" && $user->role >= 800) {
// Edit page
if(isset($_POST['submit'])) {
$wikiPage->content = $_POST['content'];
$wikiPage->locale = $_POST['locale'];
$wikiPage->title = $_POST['title'];
$wikiPage->update();
header('Location: '.$config['rel_root_folder']."wiki/".$wikiPage->url);
}
else {
$wikiPage->populate();
$head['title'] = $wikiPage->title;
include ($config['views_folder']."d.wiki.edit.html");
}
} else if (isset($controller->splitted_url[2]) && $controller->splitted_url[2]=="delete" && $user->role >= 800) {
// Delete page
$wikiPage->delete();
header('Location: '.$config['rel_root_folder']."wiki/".$wikiPage->url);
} else {
// Display page
if($user->role >= 600) {
$wikiHistory = new WikiPages();
$wikiHistory->getHistory($controller->splitted_url[1]);
$i = 0;
foreach ($wikiHistory->ids as $row) {
$wikiHistory_list[$i] = new WikiPage();
$wikiHistory_list[$i]->id = $row;
$wikiHistory_list[$i]->populate();
$i++;
}
}
if (isset($controller->splitted_url[2]) && is_numeric($controller->splitted_url[2]))
$wikiPage->checkUrl($controller->splitted_url[1],$user->role>=600, $controller->splitted_url[2]);
$wikiPage->populate();
$wikiPage->md2html();
$head['title'] = $wikiPage->title;
include ($config['views_folder']."d.wiki.view.html");
}
}
else {
$notfound = 1;
}
?>

65
includes/config.example.php

@ -0,0 +1,65 @@
<?
ini_set('display_errors', 1);
ini_set('display_startup_errors', 1);
error_reporting(E_ALL);
/*****
** Management of folder names
*****/
// It is the include folder name
$config['include_folder']=basename(__DIR__);
// This is the absolute folder to the root of the website
$config['abs_root_folder']=str_replace($config['include_folder'],"",__DIR__);
// This is the relative folder to the root of the website from the DocumentRoot (can also be called subfolder)
$config['rel_root_folder']=str_replace($_SERVER['DOCUMENT_ROOT'],"",$config['abs_root_folder']);
if($config['rel_root_folder']=="") $config['rel_root_folder']="/";
// Here all the absolute paths to specific folders
$config['views_folder'] = $config['abs_root_folder']."views/";
$config['controllers_folder'] = $config['abs_root_folder']."controllers/";
$config['models_folder'] = $config['abs_root_folder']."models/";
$config['medias_folder'] = $config['abs_root_folder']."medias/";
$config['includes_folder'] = $config['abs_root_folder']."includes/";
$config['third_folder'] = $config['abs_root_folder']."third/";
$config['logs_folder'] = $config['abs_root_folder']."logs/";
// Here all the relative url to specific folders
$config['views_url'] = $config['rel_root_folder']."views/";
/*****
** SQL Database configuration
*****/
$config['SQL_host'] = "localhost";
$config['SQL_user'] = "kabano";
$config['SQL_pass'] = "PASSWORD";
$config['SQL_db'] = "postgres";
/*****
** Mail configuration
*****/
$config['admin_mail'] = "leo@lstronic.com";
$config['bot_mail'] = "robot@kabano.com";
/*****
** Locales configuration
*****/
$config['locales'] = array(
"fr" => array("fr","fr_FR.UTF8","french","fr_FR","fr_FR.UTF-8", "Français")
);
$config['roles'] = array(
1000 => array(1000,"Administrateur", "red"),
800 => array(800,"Modérateur", "orangered"),
600 => array(600,"Membre premium", "orange"),
400 => array(400,"Utilisateur", "green"),
200 => array(200,"Membre archivé", "#aaa"),
0 => array(0,"Visiteur", "black")
);
?>

42
includes/images.php

@ -0,0 +1,42 @@
<?
function generate_image_thumbnail($source_image_path, $thumbnail_image_path, $width, $height)
{
list($source_image_width, $source_image_height, $source_image_type) = getimagesize($source_image_path);
switch ($source_image_type) {
case IMAGETYPE_GIF:
$source_gd_image = imagecreatefromgif($source_image_path);
break;
case IMAGETYPE_JPEG:
$source_gd_image = imagecreatefromjpeg($source_image_path);
break;
case IMAGETYPE_PNG:
$source_gd_image = imagecreatefrompng($source_image_path);
break;
}
if ($source_gd_image === false) {
return false;
}
$src_x = 0;
$src_y = 0;
$thumbnail_image_height = $height;
$thumbnail_image_width = $width;
// If the limitation is on the height (cuts on the width)
if($height*$source_image_width/$source_image_height > $width) {
$src_x = (int)(($source_image_width - $source_image_height * $width / $height) / 2);
$source_image_width = $source_image_height * $width / $height;
} else {
$src_y = (int)(($source_image_height - $source_image_width * $height / $width) / 2);
$source_image_height = $source_image_width * $height / $width;
}
$thumbnail_gd_image = imagecreatetruecolor($thumbnail_image_width, $thumbnail_image_height);
imagecopyresampled($thumbnail_gd_image, $source_gd_image, 0, 0, $src_x, $src_y, $thumbnail_image_width, $thumbnail_image_height, $source_image_width, $source_image_height);
imagejpeg($thumbnail_gd_image, $thumbnail_image_path, 90);
imagedestroy($source_gd_image);
imagedestroy($thumbnail_gd_image);
return true;
}
?>

71
includes/routes.php

@ -0,0 +1,71 @@
<?
/*****
** This file contains the routing from any request to the correct view and controller
*****/
$controller = new stdClass;
$view = new stdClass;
$controller->full_url = $_SERVER['REQUEST_URI'];
$controller->url_no_param = explode('?',$controller->full_url);
// URL without ?parameters and /subfolder/
$controller->base_url=str_replace('RACINE'.$config['rel_root_folder'],'','RACINE'.$controller->url_no_param[0]);
$controller->splitted_url = explode ('/',$controller->base_url);
// By default we use the desktop
$view->prefix = "d.";
$controller->prefix = "d.";
$notfound = 0;
$session = 1;
// Routing to the correct page from the correct link
switch ($controller->splitted_url[0])
{
case "index": case "" :
$controller->name="";
$view->name="index";
break;
case "user" :
$controller->name="users";
$view->name="";
break;
case "contact" :
case "wiki" :
case "blog" :
case "map" :
case "admin" :
$controller->name=$controller->splitted_url[0];
$view->name="";
break;
default :
$controller->name="";
$view->name="";
$notfound = 1;
break;
}
if($session==1) {
require_once('session.php');
}
if($controller->name != "") {
include ($config['controllers_folder'].$controller->prefix.$controller->name.".php");
}
if($view->name != "") {
include ($config['views_folder'].$view->prefix.$view->name.".html");
}
if($notfound) {
require_once('session.php');
require_once($config['models_folder']."d.wiki.php");
$wikiPage = new WikiPage();
$wikiPage->checkUrl('404');
$wikiPage->populate();
$wikiPage->md2html();
$head['css'] = "d.index.css;d.wiki.css";
$head['title'] = $wikiPage->title;
include ($config['views_folder']."d.wiki.view.html");
}
?>

23
includes/session.php

@ -0,0 +1,23 @@
<?
require_once($config['models_folder']."d.users.php");
ini_set("session.cookie_lifetime",60*60*24*30);
session_start();
$user = new User();
$user->role == 0; // All users are visitors
if(isset($_SESSION['userid'])) {
$user->checkID($_SESSION['userid']);
if ($user->id != 0) {
$user->updateLoginDate();
$user->populate();
setlocale(LC_ALL, $config['locales'][$user->locale][4]);
}
else {
session_destroy();
}
}
?>

6
index.php

@ -0,0 +1,6 @@
<?
require_once('includes/config.php');
require_once('includes/routes.php');
?>

6
info.php

@ -0,0 +1,6 @@
<?
phpinfo();
exit();
?>

487
models/d.blog.php

@ -0,0 +1,487 @@
<?
/**********************************************************
***********************************************************
**
** This class is to manage a blog article object
**
***********************************************************
**********************************************************/
require_once($config['third_folder']."Md/MarkdownExtra.inc.php");
class BlogArticle
{
public $id = 0;
public $title = NULL;
public $url = NULL;
public $locale = NULL;
public $lastedit = NULL;
public $archive = NULL;
public $content = NULL;
public $author = NULL;
public $comments = NULL;
/*****
** Checks if a page at this URL exists and return the ID
*****/
public function checkUrl($url, $withArchive=0, $elementNb=0) {
global $config;
$con = pg_connect("host=".$config['SQL_host']." dbname=".$config['SQL_db']." user=".$config['SQL_user']." password=".$config['SQL_pass'])
or die ("Could not connect to server\n");
$query = "SELECT id FROM blog_articles WHERE url=$1";
if($withArchive==0) {
$query .= " AND archive=FALSE";
}
$query .= " ORDER BY lastedit DESC LIMIT 1 OFFSET $2";
pg_prepare($con, "prepare1", $query)
or die ("Cannot prepare statement\n");
$result = pg_execute($con, "prepare1", array($url, $elementNb))
or die ("Cannot execute statement\n");
pg_close($con);
if(pg_num_rows($result) == 1) {
$article = pg_fetch_assoc($result);
$this->id = $article['id'];
$this->url = $url;
return 1;
}
else {
$this->url = $url;
return 0;
}
}
/*****
** Populate the object using its ID
*****/
public function populate() {
global $config;
if($this->id != 0) {
$con = pg_connect("host=".$config['SQL_host']." dbname=".$config['SQL_db']." user=".$config['SQL_user']." password=".$config['SQL_pass'])
or die ("Could not connect to server\n");
$query = "SELECT * FROM blog_articles WHERE id=$1";
pg_prepare($con, "prepare1", $query)
or die ("Cannot prepare statement\n");
$result = pg_execute($con, "prepare1", array($this->id))
or die ("Cannot execute statement\n");
pg_close($con);
$blog_article = pg_fetch_assoc($result);
$this->title = $blog_article['title'];
$this->url = $blog_article['url'];
$this->locale = $blog_article['locale'];
$this->lastedit = $blog_article['lastedit'];
$this->archive = $blog_article['archive'];
$this->content = $blog_article['content'];
$this->author = $blog_article['author'];
$this->comments = $blog_article['comments'];
}
else {
die("Cannot populate a blog article without ID");
}
}
/*****
** Edit a page by archiving the current one and inserting a new one ID
*****/
public function update() {
global $config;
global $user;
$con = pg_connect("host=".$config['SQL_host']." dbname=".$config['SQL_db']." user=".$config['SQL_user']." password=".$config['SQL_pass'])
or die ("Could not connect to server\n");
// Archive previous article
$query = "UPDATE blog_articles SET archive = TRUE WHERE url = $1";
pg_prepare($con, "prepare1", $query)
or die ("Cannot prepare statement\n");
$result = pg_execute($con, "prepare1", array($this->url))
or die ("Cannot execute statement\n");
// Publish the new one
$query = "INSERT INTO blog_articles (url, title, content, lastedit, archive, locale, author, comments) VALUES
($1, $2, $3, $4, FALSE, $5, $6, $7) RETURNING id";
pg_prepare($con, "prepare2", $query)
or die ("Cannot prepare statement\n");
$result = pg_execute($con, "prepare2", array($this->url, $this->title, $this->content, date('r'), $this->locale, $this->author, $this->comments))
or die ("Cannot execute statement\n");
$this->id = pg_fetch_assoc($result)['id'];
// Move all comments to the new one
$query = "UPDATE blog_comments bc SET article = $1 FROM blog_articles ba WHERE bc.article = ba.id AND ba.url = $2";
pg_prepare($con, "prepare3", $query)
or die ("Cannot prepare statement\n");
$result = pg_execute($con, "prepare3", array($this->id, $this->url))
or die ("Cannot execute statement\n");
pg_close($con);
error_log(
date('r')." \t".$user->name." (".$user->id.") \tUPDATE \tEdit blog article '".$this->url."'\r\n",
3,
$config['logs_folder'].'blog.articles.log');
}
/*****
** Delete an article by archiving it
*****/
public function delete() {
global $config;
global $user;
$con = pg_connect("host=".$config['SQL_host']." dbname=".$config['SQL_db']." user=".$config['SQL_user']." password=".$config['SQL_pass'])
or die ("Could not connect to server\n");
$query = "UPDATE blog_articles SET archive = TRUE WHERE url = $1";
pg_prepare($con, "prepare1", $query)
or die ("Cannot prepare statement\n");
$result = pg_execute($con, "prepare1", array($this->url))
or die ("Cannot execute statement\n");
pg_close($con);
error_log(
date('r')." \t".$user->name." (".$user->id.") \tDELETE \tArchive blog article '".$this->url."'\r\n",
3,
$config['logs_folder'].'blog.articles.log');
}
/*****
** Create an article
*****/
public function insert() {
global $config;
global $user;
$con = pg_connect("host=".$config['SQL_host']." dbname=".$config['SQL_db']." user=".$config['SQL_user']." password=".$config['SQL_pass'])
or die ("Could not connect to server\n");
$query = "INSERT INTO blog_articles (url, title, content, lastedit, archive, locale, author, comments) VALUES
($1, $2, $3, $4, FALSE, $5, $6, $7)";
pg_prepare($con, "prepare2", $query)
or die ("Cannot prepare statement\n");
$result = pg_execute($con, "prepare2", array($this->url, $this->title, $this->content, date('r'), $this->locale, $this->author, $this->comments))
or die ("Cannot execute statement\n");
pg_close($con);
error_log(
date('r')." \t".$user->name." (".$user->id.") \tINSERT \tCreate new blog article '".$this->url."'\r\n",
3,
$config['logs_folder'].'blog.articles.log');
}
/*****
** Converts the Markdown content to HTML
*****/
public function md2html() {
$this->content_html = \Michelf\MarkdownExtra::defaultTransform($this->content);
}
/*****
** Converts the Markdown content to text
*****/
public function md2txt() {
$this->md2html();
$this->content_txt = strip_tags($this->content_html);
}
}
/**********************************************************
***********************************************************
**
** This class is to manage a list of blog articles
**
***********************************************************
**********************************************************/
class BlogArticles
{
public $ids = array();
public $number = NULL;
/*****
** Return the list of different articles
*****/
public function listArticles($first, $count, $archive=0) {
global $config;
$con = pg_connect("host=".$config['SQL_host']." dbname=".$config['SQL_db']." user=".$config['SQL_user']." password=".$config['SQL_pass'])
or die ("Could not connect to server\n");
if ($archive == 1) {
// You just want one per url and the criteria is ORDER BY archives = true, time DES=C
$query = "SELECT id FROM (SELECT a.id, a.lastedit , ROW_NUMBER() OVER (PARTITION BY a.url ORDER BY CASE WHEN a.archive IS TRUE THEN 1 ELSE 0 END, a.lastedit DESC) AS r FROM blog_articles AS a) AS b WHERE r = 1 ORDER BY lastedit DESC";
}
else {
$query = "SELECT id FROM blog_articles WHERE archive IS NOT TRUE ORDER BY lastedit DESC";
}
$query .= " LIMIT $1 OFFSET $2";
pg_prepare($con, "prepare1", $query)
or die ("Cannot prepare statement\n");
$result = pg_execute($con, "prepare1", array($count, $first))
or die ("Cannot execute statement\n");
pg_close($con);
for($i = 0; $i < pg_num_rows($result); $i++) {
$row = pg_fetch_assoc($result, $i);
$this->ids[$i] = $row['id'];
}
}
/*****
** Return the number of articles
*****/
public function number($archive=0) {
global $config;
$con = pg_connect("host=".$config['SQL_host']." dbname=".$config['SQL_db']." user=".$config['SQL_user']." password=".$config['SQL_pass'])
or die ("Could not connect to server\n");
if ($archive == 1) {
// You just want one per url and the criteria is ORDER BY archives = true, time DES=C
$query = "SELECT id FROM (SELECT a.id, a.lastedit , ROW_NUMBER() OVER (PARTITION BY a.url ORDER BY CASE WHEN a.archive IS TRUE THEN 1 ELSE 0 END, a.lastedit DESC) AS r FROM blog_articles AS a) AS b WHERE r = 1 ORDER BY lastedit DESC";
}
else {
$query = "SELECT id FROM blog_articles WHERE archive IS NOT TRUE ORDER BY lastedit DESC";
}
pg_prepare($con, "prepare1", $query)
or die ("Cannot prepare statement\n");
$result = pg_execute($con, "prepare1", array())
or die ("Cannot execute statement\n");
pg_close($con);
$this->number = pg_num_rows($result);
}
/*****
** Return the list of archived version of a blog article
*****/
public function getHistory($url) {
global $config;
$con = pg_connect("host=".$config['SQL_host']." dbname=".$config['SQL_db']." user=".$config['SQL_user']." password=".$config['SQL_pass'])
or die ("Could not connect to server\n");
$query = "SELECT id FROM blog_articles WHERE url=$1 ORDER BY lastedit DESC";
pg_prepare($con, "prepare1", $query)
or die ("Cannot prepare statement\n");
$result = pg_execute($con, "prepare1", array($url))
or die ("Cannot execute statement\n");
pg_close($con);
$this->number = pg_num_rows($result);
for($i = 0; $i < $this->number; $i++) {
$row = pg_fetch_assoc($result, $i);
$this->ids[$i] = $row['id'];
}
}
}
/**********************************************************
***********************************************************
**
** This class is to manage a blog comment object
**
***********************************************************
**********************************************************/
class BlogComment
{
public $id = 0;
public $locale = NULL;
public $lastedit = NULL;
public $archive = NULL;
public $content = NULL;
public $author = NULL;
public $article = NULL;
/*****
** Populate the object using its ID
*****/
public function populate() {
global $config;
if($this->id != 0) {
$con = pg_connect("host=".$config['SQL_host']." dbname=".$config['SQL_db']." user=".$config['SQL_user']." password=".$config['SQL_pass'])
or die ("Could not connect to server\n");
$query = "SELECT * FROM blog_comments WHERE id=$1";
pg_prepare($con, "prepare1", $query)
or die ("Cannot prepare statement\n");
$result = pg_execute($con, "prepare1", array($this->id))
or die ("Cannot execute statement\n");
pg_close($con);
$blog_comment = pg_fetch_assoc($result);
$this->locale = $blog_comment['locale'];
$this->lastedit = $blog_comment['lastedit'];
$this->archive = $blog_comment['archive'];
$this->content = $blog_comment['content'];
$this->author = $blog_comment['author'];
$this->article = $blog_comment['article'];
}
else {
die("Cannot populate a blog article without ID");
}
}
/*****
** Create a new comment
*****/
public function insert() {
global $config;
$con = pg_connect("host=".$config['SQL_host']." dbname=".$config['SQL_db']." user=".$config['SQL_user']." password=".$config['SQL_pass'])
or die ("Could not connect to server\n");
$query = "INSERT INTO blog_comments (content, lastedit, archive, locale, author, article) VALUES
($1, $2, FALSE, $3, $4, $5)";
pg_prepare($con, "prepare2", $query)
or die ("Cannot prepare statement\n");
$result = pg_execute($con, "prepare2", array($this->content, date('r'), $this->locale, $this->author, $this->article))
or die ("Cannot execute statement\n");
pg_close($con);
}
/*****
** Archive a comment
*****/
public function delete() {
global $config;
global $user;
$con = pg_connect("host=".$config['SQL_host']." dbname=".$config['SQL_db']." user=".$config['SQL_user']." password=".$config['SQL_pass'])
or die ("Could not connect to server\n");
$query = "UPDATE blog_comments SET archive = TRUE WHERE id = $1";
pg_prepare($con, "prepare2", $query)
or die ("Cannot prepare statement\n");
$result = pg_execute($con, "prepare2", array($this->id))
or die ("Cannot execute statement\n");
pg_close($con);
error_log(
date('r')." \t".$user->name." (".$user->id.") \tDELETE \tArchive comment ".$this->id."\r\n",
3,
$config['logs_folder'].'blog.comments.log');
}
/*****
** DeArchive a comment
*****/
public function undelete() {
global $config;
global $user;
$con = pg_connect("host=".$config['SQL_host']." dbname=".$config['SQL_db']." user=".$config['SQL_user']." password=".$config['SQL_pass'])
or die ("Could not connect to server\n");
$query = "UPDATE blog_comments SET archive = FALSE WHERE id = $1";
pg_prepare($con, "prepare2", $query)
or die ("Cannot prepare statement\n");
$result = pg_execute($con, "prepare2", array($this->id))
or die ("Cannot execute statement\n");
pg_close($con);
error_log(
date('r')." \t".$user->name." (".$user->id.") \tPUBLISH \tUn archive comment ".$this->id."\r\n",
3,
$config['logs_folder'].'blog.comments.log');
}
/*****
** Converts the Markdown content to HTML
*****/
public function md2html() {
$this->content_html = \Michelf\MarkdownExtra::defaultTransform($this->content);
}
/*****
** Converts the Markdown content to text
*****/
public function md2txt() {
$this->md2html();
$this->content_txt = strip_tags($this->content_html);
}
}
/**********************************************************
***********************************************************
**
** This class is to manage a list of blog comments
**
***********************************************************
**********************************************************/
class BlogComments
{
public $ids = array();
public $number = NULL;
/*****
** Return the list of different articles
*****/
public function listComments($id, $archive=0) {
global $config;
$con = pg_connect("host=".$config['SQL_host']." dbname=".$config['SQL_db']." user=".$config['SQL_user']." password=".$config['SQL_pass'])
or die ("Could not connect to server\n");
$query = "SELECT id FROM blog_comments WHERE article = $1 ";
if ($archive == 0)
$query .= "AND archive IS FALSE ";
$query .= "ORDER BY lastedit DESC";
pg_prepare($con, "prepare1", $query)
or die ("Cannot prepare statement\n");
$result = pg_execute($con, "prepare1", array($id))
or die ("Cannot execute statement\n");
pg_close($con);
$this->number = pg_num_rows($result);
for($i = 0; $i < pg_num_rows($result); $i++) {
$row = pg_fetch_assoc($result, $i);
$this->ids[$i] = $row['id'];
}
}
}
?>

410
models/d.users.php

@ -0,0 +1,410 @@
<?
/**********************************************************
***********************************************************
**
** This class is to manage User object
**
***********************************************************
**********************************************************/
class User
{
public $id = 0;
public $name = NULL;
public $avatar = NULL;
public $locale = NULL;
public $role = NULL;
public $lastlogin = NULL;
public $mail = NULL;
public $website = NULL;
public $password = NULL;
public $registered = NULL;
/*****
** Connect to correct account using ID and stores its ID
*****/
public function checkID($id) {
global $config;
$con = pg_connect("host=".$config['SQL_host']." dbname=".$config['SQL_db']." user=".$config['SQL_user']." password=".$config['SQL_pass'])
or die ("Could not connect to server\n");
$query = "SELECT id FROM users WHERE id=$1";
pg_prepare($con, "prepare1", $query)
or die ("Cannot prepare statement\n");
$result = pg_execute($con, "prepare1", array($id))
or die ("Cannot execute statement\n");
pg_close($con);
if(pg_num_rows($result) == 1) {
$this->id = $id;
return 1;
}
else {
return 0;
}
}
/*****
** Connect to correct account using user/pass and stores its ID
*****/
public function login($login, $pass) {
global $config;
$con = pg_connect("host=".$config['SQL_host']." dbname=".$config['SQL_db']." user=".$config['SQL_user']." password=".$config['SQL_pass'])
or die ("Could not connect to server\n");
$query = "SELECT id FROM users WHERE name=$1 AND password=$2";
pg_prepare($con, "prepare1", $query)
or die ("Cannot prepare statement\n");
$result = pg_execute($con, "prepare1", array($login, sha1($pass)))
or die ("Cannot execute statement\n");
pg_close($con);
if(pg_num_rows($result) == 1) {
$user = pg_fetch_assoc($result);
$this->id = $user['id'];
}
}
/*****
** Populate the object using its ID
*****/
public function populate() {
global $config;
if($this->id != 0) {
$con = pg_connect("host=".$config['SQL_host']." dbname=".$config['SQL_db']." user=".$config['SQL_user']." password=".$config['SQL_pass'])