Browse Source

initial commit after server failure

master
Léo 2 years ago
commit
a14390f8f5
100 changed files with 14013 additions and 0 deletions
  1. +5
    -0
      .gitignore
  2. +9
    -0
      .htaccess
  3. +58
    -0
      controllers/d.admin.php
  4. +204
    -0
      controllers/d.blog.php
  5. +77
    -0
      controllers/d.contact.php
  6. +20
    -0
      controllers/d.map.php
  7. +237
    -0
      controllers/d.users.php
  8. +77
    -0
      controllers/d.wiki.php
  9. +65
    -0
      includes/config.example.php
  10. +42
    -0
      includes/images.php
  11. +71
    -0
      includes/routes.php
  12. +23
    -0
      includes/session.php
  13. +6
    -0
      index.php
  14. +6
    -0
      info.php
  15. +487
    -0
      models/d.blog.php
  16. +410
    -0
      models/d.users.php
  17. +215
    -0
      models/d.wiki.php
  18. +48
    -0
      src/Mercator-Mountain1.svg
  19. +119
    -0
      src/exportpgsql.backup
  20. +6
    -0
      src/logo.min.svg
  21. +217
    -0
      src/logo.svg
  22. +102
    -0
      src/logo2.svg
  23. +104
    -0
      src/logo3.svg
  24. BIN
      src/logo3_black.png
  25. +1
    -0
      src/wiki.backup
  26. +10
    -0
      third/Md/Markdown.inc.php
  27. +1616
    -0
      third/Md/Markdown.php
  28. +11
    -0
      third/Md/MarkdownExtra.inc.php
  29. +1625
    -0
      third/Md/MarkdownExtra.php
  30. +9
    -0
      third/Md/MarkdownInterface.inc.php
  31. +34
    -0
      third/Md/MarkdownInterface.php
  32. +7
    -0
      views/blocks/d.footer.html
  33. +46
    -0
      views/blocks/d.head.html
  34. +52
    -0
      views/blocks/d.nav.html
  35. +240
    -0
      views/css/d.blog.css
  36. +341
    -0
      views/css/d.index.css
  37. +173
    -0
      views/css/d.map.css
  38. +219
    -0
      views/css/d.user.css
  39. +66
    -0
      views/css/d.wiki.css
  40. +23
    -0
      views/d.admin.git-pull.html
  41. +24
    -0
      views/d.admin.html
  42. +41
    -0
      views/d.admin.logs.html
  43. +72
    -0
      views/d.blog.edit.html
  44. +55
    -0
      views/d.blog.list.html
  45. +45
    -0
      views/d.blog.list.rss
  46. +125
    -0
      views/d.blog.view.html
  47. +58
    -0
      views/d.contact.html
  48. +33
    -0
      views/d.index.html
  49. +25
    -0
      views/d.map.html
  50. +34
    -0
      views/d.user.login.html
  51. +70
    -0
      views/d.user.member_list.html
  52. +24
    -0
      views/d.user.password_lost.html
  53. +74
    -0
      views/d.user.profile.edit.html
  54. +66
    -0
      views/d.user.profile.html
  55. +41
    -0
      views/d.user.signin.html
  56. +30
    -0
      views/d.wiki.edit.html
  57. +56
    -0
      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
    -0
      views/img/header.svg
  76. +104
    -0
      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
    -0
      views/js/d.avatar.js
  82. +22
    -0
      views/js/d.captcha.js
  83. +81
    -0
      views/js/d.header.js
  84. +64
    -0
      views/js/d.map.js
  85. +2337
    -0
      views/third/font-awesome-4.7.0/css/font-awesome.css
  86. +4
    -0
      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
    -0
      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
    -0
      views/third/jquery-3.1.1.min.js
  94. +56
    -0
      views/third/leaflet-easybutton/easy-button.css
  95. +379
    -0
      views/third/leaflet-easybutton/easy-button.js
  96. +152
    -0
      views/third/leaflet-fullscreen/Leaflet.fullscreen.js
  97. +1
    -0
      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
    -0
      views/third/leaflet-fullscreen/leaflet.fullscreen.css

+ 5
- 0
.gitignore View File

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

+ 9
- 0
.htaccess View File

@@ -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
- 0
controllers/d.admin.php View File

@@ -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
- 0
controllers/d.blog.php View File

@@ -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
- 0
controllers/d.contact.php View File

@@ -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
- 0
controllers/d.map.php View File

@@ -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
- 0
controllers/d.users.php View File

@@ -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
- 0
controllers/d.wiki.php View File

@@ -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
- 0
includes/config.example.php View File

@@ -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
- 0
includes/images.php View File

@@ -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
- 0
includes/routes.php View File

@@ -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
- 0
includes/session.php View File

@@ -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
- 0
index.php View File

@@ -0,0 +1,6 @@
<?

require_once('includes/config.php');
require_once('includes/routes.php');

?>

+ 6
- 0
info.php View File

@@ -0,0 +1,6 @@
<?

phpinfo();
exit();

?>

+ 487
- 0
models/d.blog.php View File

@@ -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
- 0
models/d.users.php View File

@@ -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'])
or die ("Could not connect to server\n");

$query = "SELECT * FROM users 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);

$user = pg_fetch_assoc($result);

$this->name = $user['name'];
$this->avatar = $user['avatar'];
$this->locale = $user['locale'];
$this->role = $user['role'];
$this->lastlogin = $user['lastlogin'];
$this->mail = $user['mail'];
$this->website = $user['website'];
$this->registered = $user['registered'];
}
else {
die("Cannot populate an User without ID");
}
}
/*****
** Checks if the user's name is available or not
*****/
public function availableName() {
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 lower(name)=$1";

pg_prepare($con, "prepare1", $query)
or die ("Cannot prepare statement\n");
$result = pg_execute($con, "prepare1", array(strtolower($this->name)))
or die ("Cannot execute statement\n");

pg_close($con);

if(pg_num_rows($result) < 1) {
return 1;
}
else {
if(pg_num_rows($result)==1) {
$user = pg_fetch_assoc($result);
$this->id = $user['id'];
}
return 0;
}
}
/*****
** Checks if the user's mail address exists in the database
*****/
public function availableMail() {
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 lower(mail)=$1";

pg_prepare($con, "prepare1", $query)
or die ("Cannot prepare statement\n");
$result = pg_execute($con, "prepare1", array(strtolower($this->mail)))
or die ("Cannot execute statement\n");

pg_close($con);

if(pg_num_rows($result) < 1) {
return 1;
}
else {
if(pg_num_rows($result)==1) {
$user = pg_fetch_assoc($result);
$this->id = $user['id'];
}
return 0;
}
}
/*****
** Creates a new user.
*****/
public function create() {
global $config;

$regex = '/^(https?:\/\/)/';
if (!preg_match($regex, $this->website) && $this->website!="")
$this->website = "http://".$this->website;
$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 users (name, password, avatar, locale, role, lastlogin, mail, website, registered) VALUES
($1, $2, $3, $4, $5, $6, $7, $8, $9)";

pg_prepare($con, "prepare1", $query)
or die ("Cannot prepare statement\n");
pg_execute($con, "prepare1", array($this->name, $this->password, $this->avatar, $this->locale, $this->role, $this->lastlogin, $this->mail, $this->website, date('r')))
or die ("Cannot execute statement\n");

pg_close($con);
$this->updateLoginDate();
}
/*****
** Update the user profile
*****/
public function update() {
global $config;
global $user;

$regex = '/^(https?:\/\/)/';
if (!preg_match($regex, $this->website) && $this->website!="")
$this->website = "http://".$this->website;

$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($this->password=='') {
$query = "UPDATE users SET name = $1, avatar = $2, locale = $3, role = $4, mail = $5, website = $6 WHERE id = $7";
pg_prepare($con, "prepare1", $query)
or die ("Cannot prepare statement\n");
pg_execute($con, "prepare1", array($this->name, $this->avatar, $this->locale, $this->role, $this->mail, $this->website, $this->id))
or die ("Cannot execute statement\n");
}
else {
$query = "UPDATE users SET name = $1, avatar = $2, locale = $3, role = $4, mail = $5, website = $6, password = $7 WHERE id = $8";
pg_prepare($con, "prepare1", $query)
or die ("Cannot prepare statement\n");
pg_execute($con, "prepare1", array($this->name, $this->avatar, $this->locale, $this->role, $this->mail, $this->website, $this->password, $this->id))
or die ("Cannot execute statement\n");
}

pg_close($con);

error_log(
date('r')." \t".$user->name." (".$user->id.") \tUPDATE \tEdit user ".$this->name." (".$this->id.")\r\n",
3,
$config['logs_folder'].'users.log');
}
/*****
** Generates a random passwords, update the base and send the new password by mail.
*****/
public function sendPassword() {
global $config;

$newPass = randomPassword();
$this->password = sha1($newPass);

$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 users SET password = $1 WHERE mail = $2";

pg_prepare($con, "prepare1", $query)
or die ("Cannot prepare statement\n");
pg_execute($con, "prepare1", array($this->password, $this->mail))
or die ("Cannot execute statement\n");

pg_close($con);

$this->availableMail();
$this->populate();

$url = "http://".$_SERVER['SERVER_NAME'].$config['rel_root_folder'];

$message = "Bonjour ".$this->name.",<br>\r\n";
$message .= "<br>\r\n";
$message .= "Voici votre nouveau mot de passe <a href='".$url."'>Kabano</a> : <b>".$newPass."</b><br>\r\n";
$message .= "<br>\r\n";
$message .= "Cordialement,<br>\r\n";
$message .= "<br>\r\n";
$message .= "L'équipe Kabano.<br>\r\n";
$message .= "<small style='color:#777;'><i>Fait avec ♥ depuis Toulouse.</i></small><br>\r\n";

$headers = 'From: '. $config['bot_mail'] . "\r\n" .
'Reply-To: '. $config['bot_mail'] . "\r\n" .
'X-Mailer: PHP/' . phpversion() . "\r\n" .
'MIME-Version: 1.0' . "\r\n" .
'Content-type: text/html; charset=UTF-8' . "\r\n";

mail($this->mail, 'Kabano - Nouveau mot de passe', $message, $headers);
}
/*****
** Update the last login date
*****/
public function updateLoginDate() {
global $config;

$this->lastlogin = date('r');

$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 users SET lastlogin = $1 WHERE id = $2";

pg_prepare($con, "prepare1", $query)
or die ("Cannot prepare statement\n");
pg_execute($con, "prepare1", array($this->lastlogin, $this->id))
or die ("Cannot execute statement\n");

pg_close($con);
}
/*****
** Outputs the role of the user
*****/
public function role() {
global $config;
return '<span class="userrole" style="color: '.$config['roles'][$this->role][2].';">'.$config['roles'][$this->role][1].'</span>';
}
/*****
** Sends an email to the user from an other user
*****/
public function sendMail($content, $from) {
global $config;
global $user;

$this->populate();
$url = "http://".$_SERVER['SERVER_NAME'].$config['rel_root_folder'];

$message = "Bonjour ".$this->name.",<br>\r\n";
$message .= "<br>\r\n";
$message .= "Vous venez de recevoir un message de <b>".$from->name."</b> envoyé depuis <a href='".$url."'>Kabano</a>.<br>\r\n";
$message .= "<br>\r\n";
$message .= "<pre style='padding: 10px; background: #ccc;'>".strip_tags($content)."</pre><br>\r\n";
$message .= "<br>\r\n";
$message .= "Vous pouvez simplement répondre à cet email.<br>\r\n";
$message .= "<br>\r\n";
$message .= "L'équipe Kabano.<br>\r\n";
$message .= "<small style='color:#777;'><i>Fait avec ♥ depuis Toulouse.</i></small><br>\r\n";

$headers = 'From: '. $from->mail . "\r\n" .
'Reply-To: '. $from->mail . "\r\n" .
'X-Mailer: PHP/' . phpversion() . "\r\n" .
'MIME-Version: 1.0' . "\r\n" .
'Content-type: text/html; charset=UTF-8' . "\r\n";

mail($this->mail, 'Kabano - Nouveau message privé', $message, $headers);

error_log(
date('r')." \t".$user->name." (".$user->id.") \tMAIL \tMail sent to ".$this->name." (".$this->id.")\r\n",
3,
$config['logs_folder'].'users.log');
}
}

function randomPassword() {
$alphabet = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890';
$pass = array(); //remember to declare $pass as an array
$alphaLength = strlen($alphabet) - 1; //put the length -1 in cache
for ($i = 0; $i < 8; $i++) {
$n = rand(0, $alphaLength);
$pass[] = $alphabet[$n];
}
return implode($pass); //turn the array into a string
}

/**********************************************************
***********************************************************
**
** This class is to manage Users list object
**
***********************************************************
**********************************************************/

class Users
{
public $ids = array();
public $number = NULL;

/*****
** Get the users number and return the value
*****/
public function number() {
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";

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);
}

/*****
** Get a list of users if according to the arguments
*****/
public function list_users($first, $count, $orderby = "id", $order = "ASC") {
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");

$orders=array("id","name","lastlogin","registered","website","role");
$key=array_search($orderby,$orders);
$orderbysafe=$orders[$key];

if ($order == 'ASC')
$query = "SELECT id FROM users ORDER BY $orderbysafe ASC LIMIT $1 OFFSET $2";
else
$query = "SELECT id FROM users ORDER BY $orderbysafe DESC 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'];
}
}
}

?>

+ 215
- 0
models/d.wiki.php View File

@@ -0,0 +1,215 @@
<?

/**********************************************************
***********************************************************
**
** This class is to manage a wiki page object
**
***********************************************************
**********************************************************/

require_once($config['third_folder']."Md/MarkdownExtra.inc.php");

class WikiPage
{
public $id = 0;
public $title = NULL;
public $url = NULL;
public $locale = NULL;
public $lastedit = NULL;
public $archive = NULL;
public $content = 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 wiki 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) {
$wiki = pg_fetch_assoc($result);
$this->id = $wiki['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 wiki 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);

$wiki = pg_fetch_assoc($result);

$this->title = $wiki['title'];
$this->url = $wiki['url'];
$this->locale = $wiki['locale'];
$this->lastedit = $wiki['lastedit'];
$this->archive = $wiki['archive'];
$this->content = $wiki['content'];
}
else {
die("Cannot populate a wiki page 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");

$query = "UPDATE wiki 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");


$query = "INSERT INTO wiki (url, title, content, lastedit, archive, locale) VALUES
($1, $2, $3, $4, FALSE, $5)";

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))
or die ("Cannot execute statement\n");

pg_close($con);

error_log(
date('r')." \t".$user->name." (".$user->id.") \tUPDATE \tEdit wiki page '".$this->url."'\r\n",
3,
$config['logs_folder'].'wiki.log');
}

/*****
** Delete a page 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 wiki 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 wiki page '".$this->url."'\r\n",
3,
$config['logs_folder'].'wiki.log');
}

/*****
** Create a page by archiving the current one and inserting a new one ID
*****/
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 wiki (url, title, content, lastedit, archive, locale) VALUES
($1, $2, $3, $4, FALSE, $5)";

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))
or die ("Cannot execute statement\n");

pg_close($con);

error_log(
date('r')." \t".$user->name." (".$user->id.") \tINSERT \tCreate new wiki page '".$this->url."'\r\n",
3,
$config['logs_folder'].'wiki.log');
}

/*****
** Converts the Markdown content to HTML
*****/
public function md2html() {
$this->content_html = \Michelf\MarkdownExtra::defaultTransform($this->content);
}
}

class WikiPages
{
public $ids = array();
public $number = NULL;

/*****
** Checks if a page at this URL exists and return the ID
*****/
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 wiki 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'];
}
}
}

?>

+ 48
- 0
src/Mercator-Mountain1.svg
File diff suppressed because it is too large
View File


+ 119
- 0
src/exportpgsql.backup View File

@@ -0,0 +1,119 @@
COMMENT ON DATABASE kabano IS 'Kabano database';



-- SEQUENCES

CREATE SEQUENCE blog_articles_id_seq
START WITH 1
INCREMENT BY 1
NO MINVALUE
NO MAXVALUE
CACHE 1;
ALTER TABLE blog_articles_id_seq OWNER TO kabano;


CREATE SEQUENCE blog_comments_id_seq
START WITH 1
INCREMENT BY 1
NO MINVALUE
NO MAXVALUE
CACHE 1;
ALTER TABLE blog_comments_id_seq OWNER TO kabano;


CREATE SEQUENCE users_id_seq
START WITH 1
INCREMENT BY 1
NO MINVALUE