Browse Source

initial commit after server failure

Léo 1 year ago
commit
a14390f8f5
100 changed files with 13973 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. 0
    0
      views/third/leaflet-fullscreen/leaflet.fullscreen.css

+ 5
- 0
.gitignore View File

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

+ 9
- 0
.htaccess View File

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

+ 58
- 0
controllers/d.admin.php View File

@@ -0,0 +1,58 @@
1
+<?
2
+
3
+if(isset($controller->splitted_url[1]) && $user->role >= 800) {
4
+	switch ($controller->splitted_url[1]) {
5
+		case '': case 'admin':
6
+			$head['title'] = "Administration";
7
+			include ($config['views_folder']."d.admin.html");
8
+			break;
9
+		case 'git-pull':
10
+			if ($user->role >= 1000) {
11
+				$head['title'] = "Mise à jour";
12
+
13
+				$output = array();
14
+				chdir($config['abs_root_folder']);
15
+				exec("git pull origin master", $output);
16
+
17
+				include ($config['views_folder']."d.admin.git-pull.html");
18
+			}
19
+			else {
20
+				$notfound = 1;
21
+			}
22
+			break;
23
+		case 'logs':
24
+			if ($user->role >= 800) {
25
+				$head['title'] = "Logs";
26
+
27
+				$files_list = scandir($config['logs_folder']);
28
+
29
+				if (isset($controller->splitted_url[2]) && is_numeric($controller->splitted_url[2]) && intval($controller->splitted_url[2]) < count($files_list)-2) {
30
+					$filenb = $controller->splitted_url[2];
31
+				}
32
+				else {
33
+					$filenb = 0;
34
+				}
35
+
36
+				chdir($config['logs_folder']);
37
+				exec("tail -n 200 ".$files_list[$filenb+2]." | tac", $output);
38
+
39
+				include ($config['views_folder']."d.admin.logs.html");
40
+			}
41
+			else {
42
+				$notfound = 1;
43
+			}
44
+			break;
45
+		default:
46
+			$notfound = 1;
47
+			break;
48
+	}
49
+}
50
+else if($user->role >= 800) {
51
+	$head['title'] = "Administration";
52
+	include ($config['views_folder']."d.admin.html");
53
+}
54
+else {
55
+	$notfound = 1;
56
+}
57
+
58
+?>

+ 204
- 0
controllers/d.blog.php View File

@@ -0,0 +1,204 @@
1
+<?
2
+
3
+require_once($config['models_folder']."d.blog.php");
4
+require_once($config['models_folder']."d.users.php");
5
+
6
+$head['css'] = "d.index.css;d.blog.css";
7
+
8
+$blogArticle = new BlogArticle();
9
+
10
+// In case we are in the list of articles, we set url to switch with according parameters
11
+if (!isset($controller->splitted_url[1]) OR $controller->splitted_url[1]=="" OR is_numeric($controller->splitted_url[1])) {
12
+	$head['title'] = "Blog";
13
+
14
+	// Get the correct page number
15
+	if (!isset($controller->splitted_url[1]) OR $controller->splitted_url[1]=="") {
16
+		$page = 0;
17
+	} else {
18
+		$page = $controller->splitted_url[1] - 1;
19
+	}
20
+
21
+	$controller->splitted_url[1] = "list";
22
+	$list = "html";
23
+	$articles_per_pages = 5;
24
+}
25
+
26
+switch ($controller->splitted_url[1]) {
27
+	case "rss":
28
+		$page = 0;
29
+		$list = "rss";
30
+		$articles_per_pages = 20;
31
+	case "list":
32
+		$blogArticles = new BlogArticles();
33
+
34
+		$blogArticles->number(($user->role >= 600));
35
+
36
+		// In case the wanted page is too big
37
+		if($articles_per_pages * $page >= $blogArticles->number)
38
+			$page = 0;
39
+
40
+		$blogArticles->listArticles($page*$articles_per_pages,$articles_per_pages,($user->role >= 600));
41
+
42
+		$i = 0;
43
+		$blogArticles_list = array();
44
+		foreach ($blogArticles->ids as $row) {
45
+			$blogArticles_list[$i] = new BlogArticle();
46
+			$blogArticles_list[$i]->id = $row;
47
+			$blogArticles_list[$i]->populate();
48
+			$blogArticles_list[$i]->md2txt();
49
+			$tempUser = new User();
50
+			$tempUser->id = $blogArticles_list[$i]->author;
51
+			$tempUser->populate();
52
+			$blogArticles_list[$i]->author_name = $tempUser->name;
53
+			unset($tempUser);
54
+			$i++;
55
+		}
56
+
57
+		$first = $page*$articles_per_pages+1;
58
+		$last = (($page+1)*$articles_per_pages > $blogArticles->number ? $blogArticles->number : ($page+1)*$articles_per_pages);
59
+
60
+		if ($list == "rss") {
61
+			include ($config['views_folder']."d.blog.list.rss");
62
+		} else {
63
+			include ($config['views_folder']."d.blog.list.html");
64
+		}
65
+		break;
66
+	case "new":
67
+		if($user->role >= 800) {
68
+			if(isset($_POST['submit'])) {
69
+				$blogArticle->content = $_POST['content'];
70
+				$blogArticle->locale = $_POST['locale'];
71
+				$blogArticle->title = $_POST['title'];
72
+				$blogArticle->comments = isset($_POST['comments'])?'t':'f';
73
+				$blogArticle->author = $user->id;
74
+				if(!$blogArticle->checkUrl($_POST['url'],1)) {
75
+					$blogArticle->insert();
76
+					header('Location: '.$config['rel_root_folder']."blog/".$blogArticle->url);
77
+				}
78
+				else {
79
+					$head['title'] = $blogArticle->title;
80
+					$error = "url";
81
+					$new = 1;
82
+					include ($config['views_folder']."d.blog.edit.html");
83
+				}
84
+			}
85
+			else {
86
+				$head['title'] = "Nouvel article";
87
+				$new = 1;
88
+				include ($config['views_folder']."d.blog.edit.html");
89
+			}
90
+			break;
91
+		}
92
+	default:
93
+		// If the page exists
94
+		if ($blogArticle->checkUrl($controller->splitted_url[1],$user->role >= 600)) {
95
+			if (isset($controller->splitted_url[2]) && $controller->splitted_url[2] == "delete" && $user->role >= 800) {
96
+				$blogArticle->delete();
97
+				header('Location: '.$config['rel_root_folder']."blog/".$blogArticle->url);
98
+			}
99
+			else if (isset($controller->splitted_url[2]) && $controller->splitted_url[2] == "edit" && $user->role >= 800) {
100
+				if(isset($_POST['submit'])) {
101
+					$blogArticle->content = $_POST['content'];
102
+					$blogArticle->locale = $_POST['locale'];
103
+					$blogArticle->title = $_POST['title'];
104
+					$blogArticle->comments = isset($_POST['comments'])?'t':'f';
105
+					$blogArticle->author = $user->id;
106
+					$blogArticle->update();
107
+					header('Location: '.$config['rel_root_folder']."blog/".$blogArticle->url);
108
+				}
109
+				else {
110
+					$blogArticle->populate();
111
+					$head['title'] = $blogArticle->title;
112
+					include ($config['views_folder']."d.blog.edit.html");
113
+				}
114
+			}
115
+			else {
116
+				// Manage history of an article
117
+				if($user->role >= 600) {
118
+					$blogArticles_history = new BlogArticles();
119
+					$blogArticles_history->getHistory($controller->splitted_url[1]);
120
+
121
+					$i = 0;
122
+					foreach ($blogArticles_history->ids as $row) {
123
+						$blogArticles_history_list[$i] = new BlogArticle();
124
+						$blogArticles_history_list[$i]->id = $row;
125
+						$blogArticles_history_list[$i]->populate();
126
+						$i++;
127
+					}
128
+				}
129
+				if (isset($controller->splitted_url[2]) && is_numeric($controller->splitted_url[2]))
130
+					$blogArticle->checkUrl($controller->splitted_url[1],$user->role>=600,$controller->splitted_url[2]);
131
+
132
+				// Manage comment creation
133
+				if (isset($controller->splitted_url[2]) && $controller->splitted_url[2]=="new_comment") {
134
+					if (isset($_POST['submit']) && $user->role > 0) {
135
+						$blogComment = new BlogComment();
136
+						$blogComment->locale = $user->locale;
137
+						$blogComment->author = $user->id;
138
+						$blogComment->article = $blogArticle->id;
139
+						$blogComment->content = $_POST['comment'];
140
+						$blogComment->insert();
141
+					}
142
+				}
143
+
144
+				// Manage comment deletion
145
+				if (isset($controller->splitted_url[2]) && $controller->splitted_url[2]=="delete_comment") {
146
+					if (isset($controller->splitted_url[3]) && is_numeric($controller->splitted_url[3])) {
147
+						$blogComment = new BlogComment();
148
+						$blogComment->id = $controller->splitted_url[3];
149
+						$blogComment->populate();
150
+						if ($user->role >= 800 || $user->id == $blogComment->author)
151
+							$blogComment->delete();
152
+					}
153
+				}
154
+
155
+				// Manage comment undeletion
156
+				if (isset($controller->splitted_url[2]) && $controller->splitted_url[2]=="undelete_comment") {
157
+					if (isset($controller->splitted_url[3]) && is_numeric($controller->splitted_url[3])) {
158
+						$blogComment = new BlogComment();
159
+						$blogComment->id = $controller->splitted_url[3];
160
+						$blogComment->populate();
161
+						if ($user->role >= 800 || $user->id == $blogComment->author)
162
+							$blogComment->undelete();
163
+					}
164
+				}
165
+
166
+				$blogArticle->populate();
167
+				$blogArticle->md2html();
168
+
169
+				// Manage comments
170
+				if ($blogArticle->comments == "t") {
171
+					$blogArticles_comments = new BlogComments();
172
+					$blogArticles_comments->listComments($blogArticle->id, ($user->role>400));
173
+
174
+					$i = 0;
175
+					foreach ($blogArticles_comments->ids as $row) {
176
+						$blogArticles_comments_list[$i] = new BlogComment();
177
+						$blogArticles_comments_list[$i]->id = $row;
178
+						$blogArticles_comments_list[$i]->populate();
179
+						$blogArticles_comments_list[$i]->md2html();
180
+						$blogArticles_comments_list[$i]->author_obj = new User();
181
+						$blogArticles_comments_list[$i]->author_obj->id = $blogArticles_comments_list[$i]->author;
182
+						$blogArticles_comments_list[$i]->author_obj->populate();
183
+						$i++;
184
+					}
185
+				}
186
+
187
+
188
+				$tempUser = new User();
189
+				$tempUser->id = $blogArticle->author;
190
+				$tempUser->populate();
191
+				$blogArticle->author_name = $tempUser->name;
192
+				unset($tempUser);
193
+
194
+				$head['title'] = $blogArticle->title;
195
+				include ($config['views_folder']."d.blog.view.html");
196
+			}
197
+		}
198
+		else {
199
+			$notfound = 1;	
200
+		}
201
+		break;
202
+}
203
+
204
+?>

+ 77
- 0
controllers/d.contact.php View File

@@ -0,0 +1,77 @@
1
+<?
2
+
3
+function post($index) {
4
+	return isset($_POST[$index]) ? $_POST[$index] : '';
5
+}
6
+
7
+$error = "no";
8
+
9
+if(isset($_POST['submit'])) {
10
+	$message = "Message reçu depuis Kabano par ".post('name').".<br>\r\n";
11
+	$message .= "<hr>\r\n";
12
+	$message .= "<pre style='padding: 10px; background: #ccc;'>".strip_tags(post('message'))."</pre><br>\r\n";
13
+
14
+	$headers = 'From: '. post('mail') . "\r\n" .
15
+	'Reply-To: '. post('mail') . "\r\n" .
16
+	'X-Mailer: PHP/' . phpversion() . "\r\n" .
17
+	'MIME-Version: 1.0' . "\r\n" .
18
+	'Content-type: text/html; charset=UTF-8' . "\r\n"; 
19
+
20
+	if(post('ns') == '' && $_POST['captcha'] == -2) {
21
+		$send = true;
22
+		if(post('name') == '') {
23
+			$error = "name";
24
+			$send = false;
25
+		}
26
+		if(post('subject') == '') {
27
+			$error = "subject";
28
+			$send = false;
29
+		}
30
+		if(post('mail') == '') {
31
+			$error = "mail";
32
+			$send = false;
33
+		}
34
+		if(post('message') == '') {
35
+			$error = "message";
36
+			$send = false;
37
+		}
38
+		if($send) {
39
+			if(mail($config['admin_mail'], "Kabano :: ".post('subject'), $message, $headers)) {
40
+				$error = "none";
41
+			} else {
42
+				$error = "unknown";
43
+			}
44
+		}
45
+	}
46
+	else {
47
+		$error = "spam";
48
+	}
49
+}
50
+
51
+if(post('name') != '')
52
+	$contact['name'] = post('name');
53
+else if($user->role > 0)
54
+	$contact['name'] = $user->name;
55
+else
56
+	$contact['name'] = '';
57
+
58
+if(post('mail') != '')
59
+	$contact['mail'] = post('mail');
60
+else if($user->role > 0)
61
+	$contact['mail'] = $user->mail;
62
+else
63
+	$contact['mail'] = '';
64
+
65
+$contact['subject'] = post('subject');
66
+$contact['message'] = post('message');
67
+$contact['ns'] = post('ns');
68
+
69
+
70
+$head['css'] = "d.index.css;d.user.css";
71
+$head['js'] = "d.captcha.js";
72
+$head['title'] = "Contact";
73
+
74
+include ($config['views_folder']."d.contact.html");
75
+
76
+
77
+?>

+ 20
- 0
controllers/d.map.php View File

@@ -0,0 +1,20 @@
1
+<?
2
+
3
+$head['css'] = "d.index.css";
4
+
5
+if(isset($controller->splitted_url[1]) && $controller->splitted_url[1] != '') {
6
+	switch ($controller->splitted_url[1]) {
7
+		default:
8
+			$notfound = 1;
9
+			break;
10
+	}
11
+}
12
+else {
13
+	$head['title'] = "Carte";
14
+	$head['third'] = "leaflet/leaflet.js;leaflet-fullscreen/Leaflet.fullscreen.min.js;leaflet-easybutton/easy-button.js";
15
+	$head['css'] .= ";d.map.css;../third/leaflet/leaflet.css;../third/leaflet-fullscreen/leaflet.fullscreen.css;../third/leaflet-easybutton/easy-button.css";
16
+	$head['js'] = "d.map.js";
17
+	include ($config['views_folder']."d.map.html");
18
+}
19
+
20
+?>

+ 237
- 0
controllers/d.users.php View File

@@ -0,0 +1,237 @@
1
+<?
2
+
3
+require_once($config['models_folder']."d.users.php");
4
+
5
+$head['css'] = "d.index.css;d.user.css";
6
+
7
+if(isset($controller->splitted_url[1])) {
8
+	switch ($controller->splitted_url[1]) {
9
+		case 'login':
10
+			$head['title'] = "Connexion";
11
+			if ($user->role == 0) {
12
+				if (isset($_POST['submit'])) {
13
+					// PROCESS DATA FROM FORM
14
+					$user = new User();
15
+					$user->login($_POST['login'], $_POST['password']);
16
+
17
+					if($user->id != 0) {
18
+						// SUCESSFULL LOGIN
19
+						$_SESSION['userid'] = $user->id;
20
+						header('Location: '.$_SERVER['HTTP_REFERER']);
21
+					}
22
+					else {
23
+						header('Location: '.$config['rel_root_folder'].'user/login?error=1');
24
+					}
25
+				}
26
+				include ($config['views_folder']."d.user.login.html");
27
+			} else {
28
+				header('Location: '.$config['rel_root_folder']);
29
+			}
30
+			break;
31
+		case 'logout':
32
+			session_destroy();
33
+			header('Location: '.$_SERVER['HTTP_REFERER']);
34
+			break;
35
+		case 'signin':
36
+			$head['js'] = "d.captcha.js";
37
+			$head['title'] = "Création de compte";
38
+			if ($user->role == 0) {
39
+				if (isset($_POST['submit'])) {
40
+					// PROCESS DATA FROM FORM
41
+					$user = new User();
42
+					$user->password = sha1($_POST['password']);
43
+					$user->name = $_POST['login'];
44
+					$user->mail = strtolower($_POST['mail']);
45
+					$user->role = 400;
46
+					$user->avatar = 'f';
47
+					$user->locale = "fr";
48
+
49
+					if($_POST['captcha'] == -2) {
50
+						if($user->availableName()) {
51
+							if($user->availableMail()) {
52
+								if($user->password != "" AND $user->name != "" AND $user->mail != "") {
53
+									$user->create();
54
+									header('Location: '.$config['rel_root_folder'].'user/login?status=created');
55
+								}
56
+								else {
57
+									header('Location: '.$config['rel_root_folder'].'user/signin?error=empty');
58
+								}
59
+							}
60
+							else {
61
+								header('Location: '.$config['rel_root_folder'].'user/signin?error=mail');
62
+							}
63
+						}
64
+						else {
65
+							header('Location: '.$config['rel_root_folder'].'user/signin?error=name');
66
+						}
67
+					}
68
+					else {
69
+						header('Location: '.$config['rel_root_folder'].'user/signin?error=captcha');
70
+					}
71
+				}
72
+				include ($config['views_folder']."d.user.signin.html");
73
+			} else {
74
+				header('Location: '.$config['rel_root_folder']);
75
+			}
76
+			break;
77
+		case 'password_lost':
78
+			$head['title'] = "Récupération de mot de passe";
79
+			if ($user->role == 0) {
80
+				if (isset($_POST['submit'])) {
81
+					// PROCESS DATA FROM FORM
82
+					$user = new User();
83
+					$user->mail = strtolower($_POST['mail']);
84
+
85
+					if($user->availableMail()) {
86
+						header('Location: '.$config['rel_root_folder'].'user/password_lost?error=1');
87
+					}
88
+					else {
89
+						$user->sendPassword();
90
+						header('Location: '.$config['rel_root_folder'].'user/login?status=password_sent');
91
+					}
92
+				}
93
+				include ($config['views_folder']."d.user.password_lost.html");
94
+			} else {
95
+				header('Location: '.$config['rel_root_folder']);
96
+			}
97
+			break;
98
+		case 'p':
99
+			if ($user->role >= 200) {
100
+				$userProfile = new User();
101
+				if (!isset($controller->splitted_url[2]) OR $controller->splitted_url[2]=="") {
102
+					// WE DISPLAY THE CONNECTED USER PROFILE
103
+					$userProfile = $user;
104
+				} else {
105
+					// WE DISPLAY THE SELECTED USER PROFILE FROM ID
106
+					$userProfile->checkID(intval($controller->splitted_url[2]));
107
+				}
108
+				$head['title'] = "Profil inexistant";
109
+				if($userProfile->id != 0) {
110
+					$userProfile->populate();
111
+					$head['title'] = "Profil de ".$userProfile->name;
112
+				}
113
+
114
+				// If we are editing the profile
115
+				if(isset($controller->splitted_url[3]) && $controller->splitted_url[3]=="edit" && ($user->role >= 800 || $user->id == $userProfile->id)) {
116
+					$head['js'] = "d.avatar.js";
117
+					if (isset($_POST['submit'])) {
118
+						$receivedUser = new User();
119
+						$receivedUser->name = $_POST['name'];
120
+						if($receivedUser->name != $userProfile->name && $receivedUser->availableName())
121
+							$userProfile->name = $receivedUser->name;
122
+						else if($receivedUser->name != $userProfile->name)
123
+							$nameError=1;
124
+						$receivedUser->mail = strtolower($_POST['mail']);
125
+						if($receivedUser->mail != $userProfile->mail && $receivedUser->availableMail())
126
+							$userProfile->mail = $receivedUser->mail;
127
+						else if ($receivedUser->mail != $userProfile->mail)
128
+							$mailError=1;
129
+						if($_POST['password']!='')
130
+							$userProfile->password=sha1($_POST['password']);
131
+						$userProfile->locale=$_POST['locale'];
132
+						if($user->role>=1000)
133
+							$userProfile->role = $_POST['role'];
134
+						$userProfile->website=$_POST['website'];
135
+
136
+						// Is the file correctly sent to the server ?
137
+						$pathToFile = $config['medias_folder']."avatars/".$userProfile->id;
138
+						if(isset($_FILES['avatarfile']['tmp_name']) && $_FILES['avatarfile']['tmp_name']!='' && $_FILES['avatarfile']['size'] < 16000000 && isset($_POST['avatar'])) {
139
+
140
+							require_once($config['includes_folder']."images.php");
141
+
142
+							if(file_exists($pathToFile)) unlink($pathToFile);
143
+							move_uploaded_file($_FILES['avatarfile']['tmp_name'], $pathToFile);
144
+
145
+							if(file_exists($pathToFile."_p.jpg")) unlink($pathToFile."_p.jpg");
146
+							generate_image_thumbnail($pathToFile, $pathToFile."_p.jpg", 220, 240);
147
+							if(file_exists($pathToFile."_s.jpg")) unlink($pathToFile."_s.jpg");
148
+							generate_image_thumbnail($pathToFile, $pathToFile."_s.jpg", 28, 28);
149
+
150
+							$userProfile->avatar = 't';
151
+						}
152
+						elseif (!isset($_POST['avatar'])) {
153
+							if(file_exists($pathToFile)) unlink($pathToFile);
154
+							if(file_exists($pathToFile."_p.jpg")) unlink($pathToFile."_p.jpg");
155
+							if(file_exists($pathToFile."_s.jpg")) unlink($pathToFile."_s.jpg");
156
+							$userProfile->avatar = 'f';
157
+						}
158
+
159
+						$userProfile->update();
160
+
161
+						$updated = 1;
162
+					}
163
+					include ($config['views_folder']."d.user.profile.edit.html");
164
+
165
+				}
166
+				// If we are displaying the profile
167
+				else {
168
+					if (isset($_POST['submit']) && $user->role >= 400) {
169
+						// PROCESS DATA FROM CONTACT FORM
170
+						$message = $_POST['message'];
171
+						
172
+						$userProfile->sendMail($message, $user);
173
+						$mailsent = 1;
174
+					}
175
+					include ($config['views_folder']."d.user.profile.html");
176
+				}
177
+			}
178
+			else {
179
+				header('Location: '.$config['rel_root_folder']);
180
+			}
181
+			break;
182
+		case 'member_list':
183
+			if ($user->role >= 200) {
184
+				$rows_per_pages = 50;
185
+				// Get the correct page number
186
+				if (!isset($controller->splitted_url[2]) OR $controller->splitted_url[2]=="" OR $controller->splitted_url[2]=="0" OR !is_numeric($controller->splitted_url[2])) {
187
+					$page = 0;
188
+				} else {
189
+					$page = $controller->splitted_url[2] - 1;
190
+				}
191
+				$head['title'] = "Liste des membres";
192
+
193
+				$users = new Users();
194
+				$users->number();
195
+
196
+				// In case the wanted page is too big
197
+				if($rows_per_pages * $page >= $users->number)
198
+					$page = 0;
199
+
200
+				if(isset($_GET['order']))
201
+					$order = $_GET['order'];
202
+				else
203
+					$order = 'ASC';
204
+				if(isset($_GET['orderby']))
205
+					$orderby = $_GET['orderby'];
206
+				else
207
+					$orderby = 'id';
208
+
209
+				$users->list_users($page*$rows_per_pages,$rows_per_pages,$orderby,$order);
210
+
211
+				$i = 0;
212
+				foreach ($users->ids as $row) {
213
+					$user_list[$i] = new User();
214
+					$user_list[$i]->id = $row;
215
+					$user_list[$i]->populate();
216
+					$i++;
217
+				}
218
+
219
+				$first = $page*$rows_per_pages+1;
220
+				$last = (($page+1)*$rows_per_pages > $users->number ? $users->number : ($page+1)*$rows_per_pages);
221
+				
222
+				include ($config['views_folder']."d.user.member_list.html");
223
+			}
224
+			else {
225
+				header('Location: '.$config['rel_root_folder']);
226
+			}
227
+			break;
228
+		default:
229
+			$notfound = 1;
230
+			break;
231
+	}
232
+}
233
+else {
234
+	$notfound = 1;
235
+}
236
+
237
+?>

+ 77
- 0
controllers/d.wiki.php View File

@@ -0,0 +1,77 @@
1
+<?
2
+
3
+require_once($config['models_folder']."d.wiki.php");
4
+
5
+$head['css'] = "d.index.css;d.wiki.css";
6
+
7
+$wikiPage = new WikiPage();
8
+// Page doesn't exists
9
+if(isset($controller->splitted_url[1]) && !$wikiPage->checkUrl($controller->splitted_url[1],$user->role >= 600) && $controller->splitted_url[1]!="") {
10
+	if($user->role >= 800) {
11
+		// Create new page
12
+		if(isset($_POST['submit'])) {
13
+			$wikiPage->content = $_POST['content'];
14
+			$wikiPage->locale = $_POST['locale'];
15
+			$wikiPage->title = $_POST['title'];
16
+			$wikiPage->insert();
17
+
18
+			header('Location: '.$config['rel_root_folder']."wiki/".$wikiPage->url);
19
+		}
20
+		else {
21
+			$head['title'] = "Nouvelle page";
22
+			include ($config['views_folder']."d.wiki.edit.html");
23
+		}
24
+	}
25
+	else {
26
+		$notfound = 1;
27
+	}
28
+}
29
+// Page exists
30
+else if(isset($controller->splitted_url[1]) && $wikiPage->checkUrl($controller->splitted_url[1],$user->role >= 600)) {
31
+	if (isset($controller->splitted_url[2]) && $controller->splitted_url[2]=="edit" && $user->role >= 800) {
32
+		// Edit page
33
+		if(isset($_POST['submit'])) {
34
+			$wikiPage->content = $_POST['content'];
35
+			$wikiPage->locale = $_POST['locale'];
36
+			$wikiPage->title = $_POST['title'];
37
+			$wikiPage->update();
38
+
39
+			header('Location: '.$config['rel_root_folder']."wiki/".$wikiPage->url);
40
+		}
41
+		else {
42
+			$wikiPage->populate();
43
+			$head['title'] = $wikiPage->title;
44
+			include ($config['views_folder']."d.wiki.edit.html");
45
+		}
46
+	} else if (isset($controller->splitted_url[2]) && $controller->splitted_url[2]=="delete" && $user->role >= 800) {
47
+		// Delete page
48
+		$wikiPage->delete();
49
+		header('Location: '.$config['rel_root_folder']."wiki/".$wikiPage->url);
50
+	} else {
51
+		// Display page
52
+		if($user->role >= 600) {
53
+			$wikiHistory = new WikiPages();
54
+			$wikiHistory->getHistory($controller->splitted_url[1]);
55
+
56
+			$i = 0;
57
+			foreach ($wikiHistory->ids as $row) {
58
+				$wikiHistory_list[$i] = new WikiPage();
59
+				$wikiHistory_list[$i]->id = $row;
60
+				$wikiHistory_list[$i]->populate();
61
+				$i++;
62
+			}
63
+		}
64
+		if (isset($controller->splitted_url[2]) && is_numeric($controller->splitted_url[2]))
65
+			$wikiPage->checkUrl($controller->splitted_url[1],$user->role>=600, $controller->splitted_url[2]);
66
+
67
+		$wikiPage->populate();
68
+		$wikiPage->md2html();
69
+		$head['title'] = $wikiPage->title;
70
+		include ($config['views_folder']."d.wiki.view.html");
71
+	}
72
+}
73
+else {
74
+	$notfound = 1;
75
+}
76
+
77
+?>

+ 65
- 0
includes/config.example.php View File

@@ -0,0 +1,65 @@
1
+<?
2
+
3
+ini_set('display_errors', 1);
4
+ini_set('display_startup_errors', 1);
5
+error_reporting(E_ALL);
6
+
7
+
8
+/*****
9
+** Management of folder names
10
+*****/
11
+
12
+// It is the include folder name
13
+$config['include_folder']=basename(__DIR__);
14
+// This is the absolute folder to the root of the website
15
+$config['abs_root_folder']=str_replace($config['include_folder'],"",__DIR__);
16
+// This is the relative folder to the root of the website from the DocumentRoot (can also be called subfolder)
17
+$config['rel_root_folder']=str_replace($_SERVER['DOCUMENT_ROOT'],"",$config['abs_root_folder']);
18
+if($config['rel_root_folder']=="") $config['rel_root_folder']="/";
19
+
20
+// Here all the absolute paths to specific folders
21
+$config['views_folder'] = $config['abs_root_folder']."views/";
22
+$config['controllers_folder'] = $config['abs_root_folder']."controllers/";
23
+$config['models_folder'] = $config['abs_root_folder']."models/";
24
+$config['medias_folder'] = $config['abs_root_folder']."medias/";
25
+$config['includes_folder'] = $config['abs_root_folder']."includes/";
26
+$config['third_folder'] = $config['abs_root_folder']."third/";
27
+$config['logs_folder'] = $config['abs_root_folder']."logs/";
28
+
29
+// Here all the relative url to specific folders
30
+$config['views_url'] = $config['rel_root_folder']."views/";
31
+
32
+
33
+/*****
34
+** SQL Database configuration
35
+*****/
36
+
37
+$config['SQL_host'] = "localhost";
38
+$config['SQL_user'] = "kabano";
39
+$config['SQL_pass'] = "PASSWORD";
40
+$config['SQL_db'] = "postgres";
41
+
42
+/*****
43
+** Mail configuration
44
+*****/
45
+
46
+$config['admin_mail'] = "leo@lstronic.com";
47
+$config['bot_mail'] = "robot@kabano.com";
48
+
49
+/*****
50
+** Locales configuration
51
+*****/
52
+
53
+$config['locales'] = array(
54
+	"fr" => array("fr","fr_FR.UTF8","french","fr_FR","fr_FR.UTF-8", "Français")
55
+	);
56
+$config['roles'] = array(
57
+	1000 => array(1000,"Administrateur", "red"),
58
+	800 => array(800,"Modérateur", "orangered"),
59
+	600 => array(600,"Membre premium", "orange"),
60
+	400 => array(400,"Utilisateur", "green"),
61
+	200 => array(200,"Membre archivé", "#aaa"),
62
+	0 => array(0,"Visiteur", "black")
63
+	);
64
+
65
+?>

+ 42
- 0
includes/images.php View File

@@ -0,0 +1,42 @@
1
+<?
2
+
3
+function generate_image_thumbnail($source_image_path, $thumbnail_image_path, $width, $height)
4
+{
5
+	list($source_image_width, $source_image_height, $source_image_type) = getimagesize($source_image_path);
6
+	switch ($source_image_type) {
7
+		case IMAGETYPE_GIF:
8
+			$source_gd_image = imagecreatefromgif($source_image_path);
9
+			break;
10
+		case IMAGETYPE_JPEG:
11
+			$source_gd_image = imagecreatefromjpeg($source_image_path);
12
+			break;
13
+		case IMAGETYPE_PNG:
14
+			$source_gd_image = imagecreatefrompng($source_image_path);
15
+			break;
16
+	}
17
+	if ($source_gd_image === false) {
18
+		return false;
19
+	}
20
+
21
+	$src_x = 0;
22
+	$src_y = 0;
23
+	$thumbnail_image_height = $height;
24
+	$thumbnail_image_width = $width;
25
+	// If the limitation is on the height (cuts on the width)
26
+	if($height*$source_image_width/$source_image_height > $width) {
27
+		$src_x = (int)(($source_image_width - $source_image_height * $width / $height) / 2);
28
+		$source_image_width = $source_image_height * $width / $height;
29
+	} else {
30
+		$src_y = (int)(($source_image_height - $source_image_width * $height / $width) / 2);
31
+		$source_image_height = $source_image_width * $height / $width;
32
+	}
33
+
34
+	$thumbnail_gd_image = imagecreatetruecolor($thumbnail_image_width, $thumbnail_image_height);
35
+	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);
36
+	imagejpeg($thumbnail_gd_image, $thumbnail_image_path, 90);
37
+	imagedestroy($source_gd_image);
38
+	imagedestroy($thumbnail_gd_image);
39
+	return true;
40
+}
41
+
42
+?>

+ 71
- 0
includes/routes.php View File

@@ -0,0 +1,71 @@
1
+<?
2
+
3
+/*****
4
+** This file contains the routing from any request to the correct view and controller
5
+*****/
6
+
7
+$controller = new stdClass;
8
+$view = new stdClass;
9
+
10
+$controller->full_url = $_SERVER['REQUEST_URI'];
11
+$controller->url_no_param = explode('?',$controller->full_url);
12
+
13
+// URL without ?parameters and /subfolder/
14
+$controller->base_url=str_replace('RACINE'.$config['rel_root_folder'],'','RACINE'.$controller->url_no_param[0]);
15
+$controller->splitted_url = explode ('/',$controller->base_url);
16
+
17
+// By default we use the desktop 
18
+$view->prefix = "d.";
19
+$controller->prefix = "d.";
20
+$notfound = 0;
21
+$session = 1;
22
+
23
+// Routing to the correct page from the correct link
24
+switch ($controller->splitted_url[0])
25
+{
26
+    case "index": case "" :
27
+        $controller->name="";
28
+        $view->name="index";
29
+        break;
30
+    case "user" :
31
+        $controller->name="users";
32
+        $view->name="";
33
+        break;
34
+    case "contact" :
35
+    case "wiki" :
36
+    case "blog" :
37
+    case "map" :
38
+    case "admin" :
39
+        $controller->name=$controller->splitted_url[0];
40
+        $view->name="";
41
+        break;
42
+    default : 
43
+        $controller->name="";
44
+        $view->name="";
45
+		$notfound = 1;
46
+        break;
47
+}
48
+
49
+if($session==1) {
50
+	require_once('session.php');
51
+}
52
+if($controller->name != "") {
53
+	include ($config['controllers_folder'].$controller->prefix.$controller->name.".php");
54
+}
55
+if($view->name != "") {
56
+	include ($config['views_folder'].$view->prefix.$view->name.".html");
57
+}
58
+
59
+if($notfound) {
60
+    require_once('session.php');
61
+    require_once($config['models_folder']."d.wiki.php");
62
+    $wikiPage = new WikiPage();
63
+    $wikiPage->checkUrl('404');
64
+    $wikiPage->populate();
65
+    $wikiPage->md2html();
66
+    $head['css'] = "d.index.css;d.wiki.css";
67
+    $head['title'] = $wikiPage->title;
68
+    include ($config['views_folder']."d.wiki.view.html");
69
+}
70
+
71
+?>

+ 23
- 0
includes/session.php View File

@@ -0,0 +1,23 @@
1
+<?
2
+
3
+require_once($config['models_folder']."d.users.php");
4
+
5
+ini_set("session.cookie_lifetime",60*60*24*30);
6
+session_start();
7
+
8
+$user = new User();
9
+$user->role == 0; // All users are visitors
10
+
11
+if(isset($_SESSION['userid'])) {
12
+	$user->checkID($_SESSION['userid']);
13
+	if ($user->id != 0) {
14
+		$user->updateLoginDate();
15
+		$user->populate();
16
+		setlocale(LC_ALL, $config['locales'][$user->locale][4]);
17
+	}
18
+	else {
19
+		session_destroy();
20
+	}
21
+}
22
+
23
+?>

+ 6
- 0
index.php View File

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

+ 6
- 0
info.php View File

@@ -0,0 +1,6 @@
1
+<?
2
+
3
+phpinfo();
4
+exit();
5
+
6
+?>

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

@@ -0,0 +1,487 @@
1
+<?
2
+
3
+/**********************************************************
4
+***********************************************************
5
+**  
6
+**  This class is to manage a blog article object
7
+**  
8
+***********************************************************
9
+**********************************************************/
10
+
11
+require_once($config['third_folder']."Md/MarkdownExtra.inc.php");
12
+
13
+class BlogArticle
14
+{
15
+	public $id = 0;
16
+	public $title = NULL;
17
+	public $url = NULL;
18
+	public $locale = NULL;
19
+	public $lastedit = NULL;
20
+	public $archive = NULL;
21
+	public $content = NULL;
22
+	public $author = NULL;
23
+	public $comments = NULL;
24
+
25
+	/*****
26
+	** Checks if a page at this URL exists and return the ID
27
+	*****/
28
+	public function checkUrl($url, $withArchive=0, $elementNb=0) {
29
+		global $config;
30
+		
31
+		$con = pg_connect("host=".$config['SQL_host']." dbname=".$config['SQL_db']." user=".$config['SQL_user']." password=".$config['SQL_pass'])
32
+			or die ("Could not connect to server\n");
33
+
34
+		$query = "SELECT id FROM blog_articles WHERE url=$1";
35
+		if($withArchive==0) {
36
+			$query .= " AND archive=FALSE";
37
+		}
38
+		$query .= " ORDER BY lastedit DESC LIMIT 1 OFFSET $2";
39
+
40
+		pg_prepare($con, "prepare1", $query) 
41
+			or die ("Cannot prepare statement\n");
42
+		$result = pg_execute($con, "prepare1", array($url, $elementNb))
43
+			or die ("Cannot execute statement\n");
44
+
45
+		pg_close($con);
46
+
47
+		if(pg_num_rows($result) == 1) {
48
+			$article = pg_fetch_assoc($result);
49
+			$this->id = $article['id'];
50
+			$this->url = $url;
51
+			return 1;
52
+		}
53
+		else {
54
+			$this->url = $url;
55
+			return 0;
56
+		}
57
+	}
58
+
59
+	/*****
60
+	** Populate the object using its ID
61
+	*****/
62
+	public function populate() {
63
+		global $config;
64
+		
65
+		if($this->id != 0) {
66
+			$con = pg_connect("host=".$config['SQL_host']." dbname=".$config['SQL_db']." user=".$config['SQL_user']." password=".$config['SQL_pass'])
67
+				or die ("Could not connect to server\n");
68
+
69
+			$query = "SELECT * FROM blog_articles WHERE id=$1";
70
+
71
+			pg_prepare($con, "prepare1", $query) 
72
+				or die ("Cannot prepare statement\n");
73
+			$result = pg_execute($con, "prepare1", array($this->id))
74
+				or die ("Cannot execute statement\n");
75
+
76
+			pg_close($con);
77
+
78
+			$blog_article = pg_fetch_assoc($result);
79
+
80
+			$this->title = $blog_article['title'];
81
+			$this->url = $blog_article['url'];
82
+			$this->locale = $blog_article['locale'];
83
+			$this->lastedit = $blog_article['lastedit'];
84
+			$this->archive = $blog_article['archive'];
85
+			$this->content = $blog_article['content'];
86
+			$this->author = $blog_article['author'];
87
+			$this->comments = $blog_article['comments'];
88
+		}
89
+		else {
90
+			die("Cannot populate a blog article without ID");
91
+		}
92
+	}
93
+
94
+	/*****
95
+	** Edit a page by archiving the current one and inserting a new one ID
96
+	*****/
97
+	public function update() {
98
+		global $config;
99
+		global $user;
100
+		
101
+		$con = pg_connect("host=".$config['SQL_host']." dbname=".$config['SQL_db']." user=".$config['SQL_user']." password=".$config['SQL_pass'])
102
+			or die ("Could not connect to server\n");
103
+
104
+		// Archive previous article
105
+		$query = "UPDATE blog_articles SET archive = TRUE WHERE url = $1";
106
+
107
+		pg_prepare($con, "prepare1", $query) 
108
+			or die ("Cannot prepare statement\n");
109
+		$result = pg_execute($con, "prepare1", array($this->url))
110
+			or die ("Cannot execute statement\n");
111
+
112
+		// Publish the new one
113
+		$query = "INSERT INTO blog_articles (url, title, content, lastedit, archive, locale, author, comments) VALUES
114
+			($1, $2, $3, $4, FALSE, $5, $6, $7) RETURNING id";
115
+
116
+		pg_prepare($con, "prepare2", $query) 
117
+			or die ("Cannot prepare statement\n");
118
+		$result = pg_execute($con, "prepare2", array($this->url, $this->title, $this->content, date('r'), $this->locale, $this->author, $this->comments))
119
+			or die ("Cannot execute statement\n");
120
+
121
+		$this->id = pg_fetch_assoc($result)['id'];
122
+
123
+		// Move all comments to the new one
124
+
125
+		$query = "UPDATE blog_comments bc SET article = $1 FROM blog_articles ba WHERE bc.article = ba.id AND ba.url = $2";
126
+
127
+		pg_prepare($con, "prepare3", $query) 
128
+			or die ("Cannot prepare statement\n");
129
+		$result = pg_execute($con, "prepare3", array($this->id, $this->url))
130
+			or die ("Cannot execute statement\n");
131
+
132
+
133
+		pg_close($con);
134
+
135
+		error_log(
136
+			date('r')." \t".$user->name." (".$user->id.") \tUPDATE \tEdit blog article '".$this->url."'\r\n",
137
+			3,
138
+			$config['logs_folder'].'blog.articles.log');
139
+	}
140
+
141
+	/*****
142
+	** Delete an article by archiving it
143
+	*****/
144
+	public function delete() {
145
+		global $config;
146
+		global $user;
147
+		
148
+		$con = pg_connect("host=".$config['SQL_host']." dbname=".$config['SQL_db']." user=".$config['SQL_user']." password=".$config['SQL_pass'])
149
+			or die ("Could not connect to server\n");
150
+
151
+		$query = "UPDATE blog_articles SET archive = TRUE WHERE url = $1";
152
+
153
+		pg_prepare($con, "prepare1", $query) 
154
+			or die ("Cannot prepare statement\n");
155
+		$result = pg_execute($con, "prepare1", array($this->url))
156
+			or die ("Cannot execute statement\n");
157
+
158
+		pg_close($con);
159
+
160
+		error_log(
161
+			date('r')." \t".$user->name." (".$user->id.") \tDELETE \tArchive blog article '".$this->url."'\r\n",
162
+			3,
163
+			$config['logs_folder'].'blog.articles.log');
164
+	}
165
+
166
+	/*****
167
+	** Create an article
168
+	*****/
169
+	public function insert() {
170
+		global $config;
171
+		global $user;
172
+		
173
+		$con = pg_connect("host=".$config['SQL_host']." dbname=".$config['SQL_db']." user=".$config['SQL_user']." password=".$config['SQL_pass'])
174
+			or die ("Could not connect to server\n");
175
+
176
+		$query = "INSERT INTO blog_articles (url, title, content, lastedit, archive, locale, author, comments) VALUES
177
+			($1, $2, $3, $4, FALSE, $5, $6, $7)";
178
+
179
+		pg_prepare($con, "prepare2", $query) 
180
+			or die ("Cannot prepare statement\n");
181
+		$result = pg_execute($con, "prepare2", array($this->url, $this->title, $this->content, date('r'), $this->locale, $this->author, $this->comments))
182
+			or die ("Cannot execute statement\n");
183
+
184
+		pg_close($con);
185
+
186
+		error_log(
187
+			date('r')." \t".$user->name." (".$user->id.") \tINSERT \tCreate new blog article '".$this->url."'\r\n",
188
+			3,
189
+			$config['logs_folder'].'blog.articles.log');
190
+	}
191
+
192
+	/*****
193
+	** Converts the Markdown content to HTML
194
+	*****/
195
+	public function md2html() {
196
+		$this->content_html = \Michelf\MarkdownExtra::defaultTransform($this->content);
197
+	}
198
+
199
+	/*****
200
+	** Converts the Markdown content to text
201
+	*****/
202
+	public function md2txt() {
203
+		$this->md2html();
204
+		$this->content_txt = strip_tags($this->content_html);
205
+	}
206
+}
207
+
208
+
209
+/**********************************************************
210
+***********************************************************
211
+**  
212
+**  This class is to manage a list of blog articles
213
+**  
214
+***********************************************************
215
+**********************************************************/
216
+
217
+class BlogArticles
218
+{
219
+	public $ids = array();
220
+	public $number = NULL;
221
+
222
+	/*****
223
+	** Return the list of different articles
224
+	*****/
225
+	public function listArticles($first, $count, $archive=0) {
226
+		global $config;
227
+
228
+		$con = pg_connect("host=".$config['SQL_host']." dbname=".$config['SQL_db']." user=".$config['SQL_user']." password=".$config['SQL_pass'])
229
+			or die ("Could not connect to server\n");
230
+
231
+		if ($archive == 1) {
232
+			// You just want one per url and the criteria is ORDER BY archives = true, time DES=C
233
+			$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";
234
+		}
235
+		else {
236
+			$query = "SELECT id FROM blog_articles WHERE archive IS NOT TRUE ORDER BY lastedit DESC";
237
+		}
238
+		$query .= " LIMIT $1 OFFSET $2";
239
+
240
+		pg_prepare($con, "prepare1", $query) 
241
+			or die ("Cannot prepare statement\n");
242
+		$result = pg_execute($con, "prepare1", array($count, $first))
243
+				or die ("Cannot execute statement\n");
244
+		
245
+		pg_close($con);
246
+
247
+		for($i = 0; $i < pg_num_rows($result); $i++) {
248
+			$row = pg_fetch_assoc($result, $i);
249
+			$this->ids[$i] = $row['id'];
250
+		}
251
+	}
252
+	/*****
253
+	** Return the number of articles
254
+	*****/
255
+	public function number($archive=0) {
256
+		global $config;
257
+
258
+		$con = pg_connect("host=".$config['SQL_host']." dbname=".$config['SQL_db']." user=".$config['SQL_user']." password=".$config['SQL_pass'])
259
+			or die ("Could not connect to server\n");
260
+
261
+		if ($archive == 1) {
262
+			// You just want one per url and the criteria is ORDER BY archives = true, time DES=C
263
+			$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";
264
+		}
265
+		else {
266
+			$query = "SELECT id FROM blog_articles WHERE archive IS NOT TRUE ORDER BY lastedit DESC";
267
+		}
268
+
269
+		pg_prepare($con, "prepare1", $query) 
270
+			or die ("Cannot prepare statement\n");
271
+		$result = pg_execute($con, "prepare1", array())
272
+				or die ("Cannot execute statement\n");
273
+		
274
+		pg_close($con);
275
+
276
+		$this->number = pg_num_rows($result);
277
+	}
278
+	/*****
279
+	** Return the list of archived version of a blog article
280
+	*****/
281
+	public function getHistory($url) {
282
+		global $config;
283
+		
284
+		$con = pg_connect("host=".$config['SQL_host']." dbname=".$config['SQL_db']." user=".$config['SQL_user']." password=".$config['SQL_pass'])
285
+			or die ("Could not connect to server\n");
286
+
287
+		$query = "SELECT id FROM blog_articles WHERE url=$1 ORDER BY lastedit DESC";
288
+
289
+		pg_prepare($con, "prepare1", $query) 
290
+			or die ("Cannot prepare statement\n");
291
+		$result = pg_execute($con, "prepare1", array($url))
292
+			or die ("Cannot execute statement\n");
293
+
294
+		pg_close($con);
295
+
296
+		$this->number = pg_num_rows($result);
297
+
298
+		for($i = 0; $i < $this->number; $i++) {
299
+			$row = pg_fetch_assoc($result, $i);
300
+			$this->ids[$i] = $row['id'];
301
+		}
302
+	}
303
+}
304
+
305
+
306
+/**********************************************************
307
+***********************************************************
308
+**  
309
+**  This class is to manage a blog comment object
310
+**  
311
+***********************************************************
312
+**********************************************************/
313
+
314
+class BlogComment
315
+{
316
+	public $id = 0;
317
+	public $locale = NULL;
318
+	public $lastedit = NULL;
319
+	public $archive = NULL;
320
+	public $content = NULL;
321
+	public $author = NULL;
322
+	public $article = NULL;
323
+
324
+	/*****
325
+	** Populate the object using its ID
326
+	*****/
327
+	public function populate() {
328
+		global $config;
329
+		
330
+		if($this->id != 0) {
331
+			$con = pg_connect("host=".$config['SQL_host']." dbname=".$config['SQL_db']." user=".$config['SQL_user']." password=".$config['SQL_pass'])
332
+				or die ("Could not connect to server\n");
333
+
334
+			$query = "SELECT * FROM blog_comments WHERE id=$1";
335
+
336
+			pg_prepare($con, "prepare1", $query) 
337
+				or die ("Cannot prepare statement\n");
338
+			$result = pg_execute($con, "prepare1", array($this->id))
339
+				or die ("Cannot execute statement\n");
340
+
341
+			pg_close($con);
342
+
343
+			$blog_comment = pg_fetch_assoc($result);
344
+
345
+			$this->locale = $blog_comment['locale'];
346
+			$this->lastedit = $blog_comment['lastedit'];
347
+			$this->archive = $blog_comment['archive'];
348
+			$this->content = $blog_comment['content'];
349
+			$this->author = $blog_comment['author'];
350
+			$this->article = $blog_comment['article'];
351
+		}
352
+		else {
353
+			die("Cannot populate a blog article without ID");
354
+		}
355
+	}
356
+
357
+	/*****
358
+	** Create a new comment
359
+	*****/
360
+	public function insert() {
361
+		global $config;
362
+		
363
+		$con = pg_connect("host=".$config['SQL_host']." dbname=".$config['SQL_db']." user=".$config['SQL_user']." password=".$config['SQL_pass'])
364
+			or die ("Could not connect to server\n");
365
+
366
+		$query = "INSERT INTO blog_comments (content, lastedit, archive, locale, author, article) VALUES
367
+			($1, $2, FALSE, $3, $4, $5)";
368
+
369
+		pg_prepare($con, "prepare2", $query) 
370
+			or die ("Cannot prepare statement\n");
371
+		$result = pg_execute($con, "prepare2", array($this->content, date('r'), $this->locale, $this->author, $this->article))
372
+			or die ("Cannot execute statement\n");
373
+
374
+		pg_close($con);
375
+	}
376
+
377
+	/*****
378
+	** Archive a comment
379
+	*****/
380
+	public function delete() {
381
+		global $config;
382
+		global $user;
383
+		
384
+		$con = pg_connect("host=".$config['SQL_host']." dbname=".$config['SQL_db']." user=".$config['SQL_user']." password=".$config['SQL_pass'])
385
+			or die ("Could not connect to server\n");
386
+
387
+		$query = "UPDATE blog_comments SET archive = TRUE WHERE id = $1";
388
+
389
+		pg_prepare($con, "prepare2", $query) 
390
+			or die ("Cannot prepare statement\n");
391
+		$result = pg_execute($con, "prepare2", array($this->id))
392
+			or die ("Cannot execute statement\n");
393
+
394
+		pg_close($con);
395
+
396
+		error_log(
397
+			date('r')." \t".$user->name." (".$user->id.") \tDELETE  \tArchive comment ".$this->id."\r\n",
398
+			3,
399
+			$config['logs_folder'].'blog.comments.log');
400
+	}
401
+
402
+	/*****
403
+	** DeArchive a comment
404
+	*****/
405
+	public function undelete() {
406
+		global $config;
407
+		global $user;
408
+		
409
+		$con = pg_connect("host=".$config['SQL_host']." dbname=".$config['SQL_db']." user=".$config['SQL_user']." password=".$config['SQL_pass'])
410
+			or die ("Could not connect to server\n");
411
+
412
+		$query = "UPDATE blog_comments SET archive = FALSE WHERE id = $1";
413
+
414
+		pg_prepare($con, "prepare2", $query) 
415
+			or die ("Cannot prepare statement\n");
416
+		$result = pg_execute($con, "prepare2", array($this->id))
417
+			or die ("Cannot execute statement\n");
418
+
419
+		pg_close($con);
420
+
421
+		error_log(
422
+			date('r')." \t".$user->name." (".$user->id.") \tPUBLISH \tUn archive comment ".$this->id."\r\n",
423
+			3,
424
+			$config['logs_folder'].'blog.comments.log');
425
+	}
426
+
427
+	/*****
428
+	** Converts the Markdown content to HTML
429
+	*****/
430
+	public function md2html() {
431
+		$this->content_html = \Michelf\MarkdownExtra::defaultTransform($this->content);
432
+	}
433
+
434
+	/*****
435
+	** Converts the Markdown content to text
436
+	*****/
437
+	public function md2txt() {
438
+		$this->md2html();
439
+		$this->content_txt = strip_tags($this->content_html);
440
+	}
441
+}
442
+
443
+
444
+/**********************************************************
445
+***********************************************************
446
+**  
447
+**  This class is to manage a list of blog comments
448
+**  
449
+***********************************************************
450
+**********************************************************/
451
+
452
+class BlogComments
453
+{
454
+	public $ids = array();
455
+	public $number = NULL;
456
+
457
+	/*****
458
+	** Return the list of different articles
459
+	*****/
460
+	public function listComments($id, $archive=0) {
461
+		global $config;
462
+
463
+		$con = pg_connect("host=".$config['SQL_host']." dbname=".$config['SQL_db']." user=".$config['SQL_user']." password=".$config['SQL_pass'])
464
+			or die ("Could not connect to server\n");
465
+
466
+		$query = "SELECT id FROM blog_comments WHERE article = $1 ";
467
+		if ($archive == 0)
468
+			$query .= "AND archive IS FALSE ";
469
+		$query .= "ORDER BY lastedit DESC";
470
+
471
+		pg_prepare($con, "prepare1", $query) 
472
+			or die ("Cannot prepare statement\n");
473
+		$result = pg_execute($con, "prepare1", array($id))
474
+				or die ("Cannot execute statement\n");
475
+		
476
+		pg_close($con);
477
+
478
+		$this->number = pg_num_rows($result);
479
+
480
+		for($i = 0; $i < pg_num_rows($result); $i++) {
481
+			$row = pg_fetch_assoc($result, $i);
482
+			$this->ids[$i] = $row['id'];
483
+		}
484
+	}
485
+}
486
+
487
+?>

+ 410
- 0
models/d.users.php View File

@@ -0,0 +1,410 @@
1
+<?
2
+
3
+/**********************************************************
4
+***********************************************************
5
+**  
6
+**  This class is to manage User object
7
+**  
8
+***********************************************************
9
+**********************************************************/
10
+
11
+class User
12
+{
13
+	public $id = 0;
14
+	public $name = NULL;
15
+	public $avatar = NULL;
16
+	public $locale = NULL;
17
+	public $role = NULL;
18
+	public $lastlogin = NULL;
19
+	public $mail = NULL;
20
+	public $website = NULL;
21
+	public $password = NULL;
22
+	public $registered = NULL;
23
+
24
+	/*****
25
+	** Connect to correct account using ID and stores its ID
26
+	*****/
27
+	public function checkID($id) {
28
+		global $config;
29
+		
30
+		$con = pg_connect("host=".$config['SQL_host']." dbname=".$config['SQL_db']." user=".$config['SQL_user']." password=".$config['SQL_pass'])
31
+			or die ("Could not connect to server\n");
32
+
33
+		$query = "SELECT id FROM users WHERE id=$1";
34
+
35
+		pg_prepare($con, "prepare1", $query) 
36
+			or die ("Cannot prepare statement\n");
37
+		$result = pg_execute($con, "prepare1", array($id))
38
+			or die ("Cannot execute statement\n");
39
+
40
+		pg_close($con);
41
+
42
+		if(pg_num_rows($result) == 1) {
43
+			$this->id = $id;
44
+			return 1;
45
+		}
46
+		else {
47
+			return 0;
48
+		}
49
+	}
50
+	/*****
51
+	** Connect to correct account using user/pass and stores its ID
52
+	*****/
53
+	public function login($login, $pass) {
54
+		global $config;
55
+		
56
+		$con = pg_connect("host=".$config['SQL_host']." dbname=".$config['SQL_db']." user=".$config['SQL_user']." password=".$config['SQL_pass'])
57
+			or die ("Could not connect to server\n");
58
+
59
+		$query = "SELECT id FROM users WHERE name=$1 AND password=$2";
60
+
61
+		pg_prepare($con, "prepare1", $query) 
62
+			or die ("Cannot prepare statement\n");
63
+		$result = pg_execute($con, "prepare1", array($login, sha1($pass)))
64
+			or die ("Cannot execute statement\n");
65
+
66
+		pg_close($con); 
67
+
68
+		if(pg_num_rows($result) == 1) {
69
+			$user = pg_fetch_assoc($result);
70
+			$this->id = $user['id'];
71
+		}
72
+	}
73
+	/*****
74
+	** Populate the object using its ID
75
+	*****/
76
+	public function populate() {
77
+		global $config;
78
+		
79
+		if($this->id != 0) {
80
+			$con = pg_connect("host=".$config['SQL_host']." dbname=".$config['SQL_db']." user=".$config['SQL_user']." password=".$config['SQL_pass'])
81
+				or die ("Could not connect to server\n");
82
+
83
+			$query = "SELECT * FROM users WHERE id=$1";
84
+
85
+			pg_prepare($con, "prepare1", $query) 
86
+				or die ("Cannot prepare statement\n");
87
+			$result = pg_execute($con, "prepare1", array($this->id))
88
+				or die ("Cannot execute statement\n");
89
+
90
+			pg_close($con);
91
+
92
+			$user = pg_fetch_assoc($result);
93
+
94
+			$this->name = $user['name'];
95
+			$this->avatar = $user['avatar'];
96
+			$this->locale = $user['locale'];
97
+			$this->role = $user['role'];
98
+			$this->lastlogin = $user['lastlogin'];
99
+			$this->mail = $user['mail'];
100
+			$this->website = $user['website'];
101
+			$this->registered = $user['registered'];
102
+		}
103
+		else {
104
+			die("Cannot populate an User without ID");
105
+		}
106
+	}
107
+	/*****
108
+	** Checks if the user's name is available or not
109
+	*****/
110
+	public function availableName() {
111
+		global $config;
112
+		
113
+		$con = pg_connect("host=".$config['SQL_host']." dbname=".$config['SQL_db']." user=".$config['SQL_user']." password=".$config['SQL_pass'])
114
+			or die ("Could not connect to server\n");
115
+
116
+		$query = "SELECT id FROM users WHERE lower(name)=$1";
117
+
118
+		pg_prepare($con, "prepare1", $query) 
119
+			or die ("Cannot prepare statement\n");
120
+		$result = pg_execute($con, "prepare1", array(strtolower($this->name)))
121
+			or die ("Cannot execute statement\n");
122
+
123
+		pg_close($con);
124
+
125
+		if(pg_num_rows($result) < 1) {
126
+			return 1;
127
+		}
128
+		else {
129
+			if(pg_num_rows($result)==1) {
130
+				$user = pg_fetch_assoc($result);
131
+				$this->id = $user['id'];
132
+			}
133
+			return 0;
134
+		}
135
+	}
136
+	/*****
137
+	** Checks if the user's mail address exists in the database
138
+	*****/
139
+	public function availableMail() {
140
+		global $config;
141
+		
142
+		$con = pg_connect("host=".$config['SQL_host']." dbname=".$config['SQL_db']." user=".$config['SQL_user']." password=".$config['SQL_pass'])
143
+			or die ("Could not connect to server\n");
144
+
145
+		$query = "SELECT id FROM users WHERE lower(mail)=$1";
146
+
147
+		pg_prepare($con, "prepare1", $query) 
148
+			or die ("Cannot prepare statement\n");
149
+		$result = pg_execute($con, "prepare1", array(strtolower($this->mail)))
150
+			or die ("Cannot execute statement\n");
151
+
152
+		pg_close($con);
153
+
154
+		if(pg_num_rows($result) < 1) {
155
+			return 1;
156
+		}
157
+		else {
158
+			if(pg_num_rows($result)==1) {
159
+				$user = pg_fetch_assoc($result);
160
+				$this->id = $user['id'];
161
+			}
162
+			return 0;
163
+		}
164
+	}
165
+	/*****
166
+	** Creates a new user.
167
+	*****/
168
+	public function create() {
169
+		global $config;
170
+
171
+		$regex = '/^(https?:\/\/)/';
172
+		if (!preg_match($regex, $this->website) && $this->website!="")
173
+			$this->website = "http://".$this->website;
174
+		
175
+		$con = pg_connect("host=".$config['SQL_host']." dbname=".$config['SQL_db']." user=".$config['SQL_user']." password=".$config['SQL_pass'])
176
+			or die ("Could not connect to server\n");
177
+
178
+		$query = "INSERT INTO users (name, password, avatar, locale, role, lastlogin, mail, website, registered) VALUES
179
+			($1, $2, $3, $4, $5, $6, $7, $8, $9)";
180
+
181
+		pg_prepare($con, "prepare1", $query) 
182
+			or die ("Cannot prepare statement\n");
183
+		pg_execute($con, "prepare1", array($this->name, $this->password, $this->avatar, $this->locale, $this->role, $this->lastlogin, $this->mail, $this->website, date('r')))
184
+			or die ("Cannot execute statement\n");
185
+
186
+		pg_close($con);
187
+	
188
+		$this->updateLoginDate();
189
+	}
190
+	/*****
191
+	** Update the user profile
192
+	*****/
193
+	public function update() {
194
+		global $config;
195
+		global $user;
196
+
197
+		$regex = '/^(https?:\/\/)/';
198
+		if (!preg_match($regex, $this->website) && $this->website!="")
199
+			$this->website = "http://".$this->website;
200
+
201
+		$con = pg_connect("host=".$config['SQL_host']." dbname=".$config['SQL_db']." user=".$config['SQL_user']." password=".$config['SQL_pass'])
202
+			or die ("Could not connect to server\n");
203
+
204
+		if($this->password=='') {
205
+			$query = "UPDATE users SET name = $1, avatar = $2, locale = $3, role = $4, mail = $5, website = $6 WHERE id = $7";
206
+			pg_prepare($con, "prepare1", $query) 
207
+				or die ("Cannot prepare statement\n");
208
+			pg_execute($con, "prepare1", array($this->name, $this->avatar, $this->locale, $this->role, $this->mail, $this->website, $this->id))
209
+				or die ("Cannot execute statement\n");
210
+		}
211
+		else {
212
+			$query = "UPDATE users SET name = $1, avatar = $2, locale = $3, role = $4, mail = $5, website = $6, password = $7 WHERE id = $8";
213
+			pg_prepare($con, "prepare1", $query) 
214
+				or die ("Cannot prepare statement\n");
215
+			pg_execute($con, "prepare1", array($this->name, $this->avatar, $this->locale, $this->role, $this->mail, $this->website, $this->password, $this->id))
216
+				or die ("Cannot execute statement\n");
217
+		}
218
+
219
+		pg_close($con);
220
+
221
+		error_log(
222
+			date('r')." \t".$user->name." (".$user->id.") \tUPDATE \tEdit user ".$this->name." (".$this->id.")\r\n",
223
+			3,
224
+			$config['logs_folder'].'users.log');
225
+	}
226
+	/*****
227
+	** Generates a random passwords, update the base and send the new password by mail.
228
+	*****/
229
+	public function sendPassword() {
230
+		global $config;
231
+
232
+		$newPass = randomPassword();
233
+		$this->password = sha1($newPass);
234
+
235
+		$con = pg_connect("host=".$config['SQL_host']." dbname=".$config['SQL_db']." user=".$config['SQL_user']." password=".$config['SQL_pass'])
236
+			or die ("Could not connect to server\n");
237
+
238
+		$query = "UPDATE users SET password = $1 WHERE mail = $2";
239
+
240
+		pg_prepare($con, "prepare1", $query) 
241
+			or die ("Cannot prepare statement\n");
242
+		pg_execute($con, "prepare1", array($this->password, $this->mail))
243
+			or die ("Cannot execute statement\n");
244
+
245
+		pg_close($con);
246
+
247
+		$this->availableMail();
248
+		$this->populate();
249
+
250
+		$url = "http://".$_SERVER['SERVER_NAME'].$config['rel_root_folder'];
251
+
252
+		$message = "Bonjour ".$this->name.",<br>\r\n";
253
+		$message .= "<br>\r\n";
254
+		$message .= "Voici votre nouveau mot de passe <a href='".$url."'>Kabano</a> : <b>".$newPass."</b><br>\r\n";
255
+		$message .= "<br>\r\n";
256
+		$message .= "Cordialement,<br>\r\n";
257
+		$message .= "<br>\r\n";
258
+		$message .= "L'équipe Kabano.<br>\r\n";
259
+		$message .= "<small style='color:#777;'><i>Fait avec ♥ depuis Toulouse.</i></small><br>\r\n";
260
+
261
+		$headers = 'From: '. $config['bot_mail'] . "\r\n" .
262
+		'Reply-To: '. $config['bot_mail'] . "\r\n" .
263
+		'X-Mailer: PHP/' . phpversion() . "\r\n" .
264
+		'MIME-Version: 1.0' . "\r\n" .
265
+		'Content-type: text/html; charset=UTF-8' . "\r\n"; 
266
+
267
+		mail($this->mail, 'Kabano - Nouveau mot de passe', $message, $headers);
268
+	}
269
+	/*****
270
+	** Update the last login date
271
+	*****/
272
+	public function updateLoginDate() {
273
+		global $config;
274
+
275
+		$this->lastlogin = date('r');
276
+
277
+		$con = pg_connect("host=".$config['SQL_host']." dbname=".$config['SQL_db']." user=".$config['SQL_user']." password=".$config['SQL_pass'])
278
+			or die ("Could not connect to server\n");
279
+
280
+		$query = "UPDATE users SET lastlogin = $1 WHERE id = $2";
281
+
282
+		pg_prepare($con, "prepare1", $query) 
283
+			or die ("Cannot prepare statement\n");
284
+		pg_execute($con, "prepare1", array($this->lastlogin, $this->id))
285
+			or die ("Cannot execute statement\n");
286
+
287
+		pg_close($con);
288
+	}
289
+	/*****
290
+	** Outputs the role of the user
291
+	*****/
292
+	public function role() {
293
+		global $config;
294
+		return '<span class="userrole" style="color: '.$config['roles'][$this->role][2].';">'.$config['roles'][$this->role][1].'</span>';
295
+	}
296
+	/*****
297
+	** Sends an email to the user from an other user
298
+	*****/
299
+	public function sendMail($content, $from) {
300
+		global $config;
301
+		global $user;
302
+
303
+		$this->populate();
304
+		$url = "http://".$_SERVER['SERVER_NAME'].$config['rel_root_folder'];
305
+
306
+		$message = "Bonjour ".$this->name.",<br>\r\n";
307
+		$message .= "<br>\r\n";
308
+		$message .= "Vous venez de recevoir un message de <b>".$from->name."</b> envoyé depuis <a href='".$url."'>Kabano</a>.<br>\r\n";
309
+		$message .= "<br>\r\n";
310
+		$message .= "<pre style='padding: 10px; background: #ccc;'>".strip_tags($content)."</pre><br>\r\n";
311
+		$message .= "<br>\r\n";
312
+		$message .= "Vous pouvez simplement répondre à cet email.<br>\r\n";
313
+		$message .= "<br>\r\n";
314
+		$message .= "L'équipe Kabano.<br>\r\n";
315
+		$message .= "<small style='color:#777;'><i>Fait avec ♥ depuis Toulouse.</i></small><br>\r\n";
316
+
317
+		$headers = 'From: '. $from->mail . "\r\n" .
318
+		'Reply-To: '. $from->mail . "\r\n" .
319
+		'X-Mailer: PHP/' . phpversion() . "\r\n" .
320
+		'MIME-Version: 1.0' . "\r\n" .
321
+		'Content-type: text/html; charset=UTF-8' . "\r\n"; 
322
+
323
+		mail($this->mail, 'Kabano - Nouveau message privé', $message, $headers);
324
+
325
+		error_log(
326
+			date('r')." \t".$user->name." (".$user->id.") \tMAIL \tMail sent to ".$this->name." (".$this->id.")\r\n",
327
+			3,
328
+			$config['logs_folder'].'users.log');
329
+	}
330
+}
331
+
332
+function randomPassword() {
333
+    $alphabet = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890';
334
+    $pass = array(); //remember to declare $pass as an array
335
+    $alphaLength = strlen($alphabet) - 1; //put the length -1 in cache
336
+    for ($i = 0; $i < 8; $i++) {
337
+        $n = rand(0, $alphaLength);
338
+        $pass[] = $alphabet[$n];
339
+    }
340
+    return implode($pass); //turn the array into a string
341
+}
342
+
343
+/**********************************************************
344
+***********************************************************
345
+**  
346
+**  This class is to manage Users list object
347
+**  
348
+***********************************************************
349
+**********************************************************/
350
+
351
+class Users
352
+{
353
+	public $ids = array();
354
+	public $number = NULL;
355
+
356
+	/*****
357
+	** Get the users number and return the value
358
+	*****/
359
+	public function number() {
360
+		global $config;
361
+		
362
+		$con = pg_connect("host=".$config['SQL_host']." dbname=".$config['SQL_db']." user=".$config['SQL_user']." password=".$config['SQL_pass'])
363
+			or die ("Could not connect to server\n");
364
+
365
+		$query = "SELECT id FROM users";
366
+
367
+		pg_prepare($con, "prepare1", $query) 
368
+			or die ("Cannot prepare statement\n");
369
+		$result = pg_execute($con, "prepare1", array())
370
+			or die ("Cannot execute statement\n");
371
+
372
+		pg_close($con);
373
+
374
+		$this->number = pg_num_rows($result);
375
+	}
376
+
377
+	/*****
378
+	** Get a list of users if according to the arguments
379
+	*****/
380
+	public function list_users($first, $count, $orderby = "id", $order = "ASC") {
381
+		global $config;
382
+		
383
+		$con = pg_connect("host=".$config['SQL_host']." dbname=".$config['SQL_db']." user=".$config['SQL_user']." password=".$config['SQL_pass'])
384
+			or die ("Could not connect to server\n");
385
+
386
+		$orders=array("id","name","lastlogin","registered","website","role");
387
+		$key=array_search($orderby,$orders);
388
+		$orderbysafe=$orders[$key];
389
+
390
+		if ($order == 'ASC')
391
+			$query = "SELECT id FROM users ORDER BY $orderbysafe ASC LIMIT $1 OFFSET $2";
392
+		else
393
+			$query = "SELECT id FROM users ORDER BY $orderbysafe DESC LIMIT $1 OFFSET $2";
394
+		
395
+
396
+		pg_prepare($con, "prepare1", $query) 
397
+			or die ("Cannot prepare statement\n");
398
+		$result = pg_execute($con, "prepare1", array($count, $first))
399
+			or die ("Cannot execute statement\n");
400
+
401
+		pg_close($con);
402
+
403
+		for($i = 0; $i < pg_num_rows($result); $i++) {
404
+			$row = pg_fetch_assoc($result, $i);
405
+			$this->ids[$i] = $row['id'];
406
+		}
407
+	}
408
+}
409
+
410
+?>

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

@@ -0,0 +1,215 @@
1
+<?
2
+
3
+/**********************************************************
4
+***********************************************************
5
+**  
6
+**  This class is to manage a wiki page object
7
+**  
8
+***********************************************************
9
+**********************************************************/
10
+
11
+require_once($config['third_folder']."Md/MarkdownExtra.inc.php");
12
+
13
+class WikiPage
14
+{
15
+	public $id = 0;
16
+	public $title = NULL;
17
+	public $url = NULL;
18
+	public $locale = NULL;
19
+	public $lastedit = NULL;
20
+	public $archive = NULL;
21
+	public $content = NULL;
22
+
23
+	/*****
24
+	** Checks if a page at this URL exists and return the ID
25
+	*****/
26
+	public function checkUrl($url, $withArchive=0, $elementNb=0) {
27
+		global $config;
28
+		
29
+		$con = pg_connect("host=".$config['SQL_host']." dbname=".$config['SQL_db']." user=".$config['SQL_user']." password=".$config['SQL_pass'])
30
+			or die ("Could not connect to server\n");
31
+
32
+		$query = "SELECT id FROM wiki WHERE url=$1";
33
+		if($withArchive==0) {
34
+			$query .= " AND archive=FALSE";
35
+		}
36
+		$query .= " ORDER BY lastedit DESC LIMIT 1 OFFSET $2";
37
+
38
+		pg_prepare($con, "prepare1", $query) 
39
+			or die ("Cannot prepare statement\n");
40
+		$result = pg_execute($con, "prepare1", array($url, $elementNb))
41
+			or die ("Cannot execute statement\n");
42
+
43
+		pg_close($con);
44
+
45
+		if(pg_num_rows($result) == 1) {
46
+			$wiki = pg_fetch_assoc($result);
47
+			$this->id = $wiki['id'];
48
+			$this->url = $url;
49
+			return 1;
50
+		}
51
+		else {
52
+			$this->url = $url;
53
+			return 0;
54
+		}
55
+	}
56
+
57
+	/*****
58
+	** Populate the object using its ID
59
+	*****/
60
+	public function populate() {
61
+		global $config;
62
+		
63
+		if($this->id != 0) {
64
+			$con = pg_connect("host=".$config['SQL_host']." dbname=".$config['SQL_db']." user=".$config['SQL_user']." password=".$config['SQL_pass'])
65
+				or die ("Could not connect to server\n");
66
+
67
+			$query = "SELECT * FROM wiki WHERE id=$1";
68
+
69
+			pg_prepare($con, "prepare1", $query) 
70
+				or die ("Cannot prepare statement\n");
71
+			$result = pg_execute($con, "prepare1", array($this->id))
72
+				or die ("Cannot execute statement\n");
73
+
74
+			pg_close($con);
75
+
76
+			$wiki = pg_fetch_assoc($result);
77
+
78
+			$this->title = $wiki['title'];
79
+			$this->url = $wiki['url'];
80
+			$this->locale = $wiki['locale'];
81
+			$this->lastedit = $wiki['lastedit'];
82
+			$this->archive = $wiki['archive'];
83
+			$this->content = $wiki['content'];
84
+		}
85
+		else {
86
+			die("Cannot populate a wiki page without ID");
87
+		}
88
+	}
89
+
90
+	/*****
91
+	** Edit a page by archiving the current one and inserting a new one ID
92
+	*****/
93
+	public function update() {
94
+		global $config;
95
+		global $user;
96
+		
97
+		$con = pg_connect("host=".$config['SQL_host']." dbname=".$config['SQL_db']." user=".$config['SQL_user']." password=".$config['SQL_pass'])
98
+			or die ("Could not connect to server\n");
99
+
100
+		$query = "UPDATE wiki SET archive = TRUE WHERE url = $1";
101
+
102
+		pg_prepare($con, "prepare1", $query) 
103
+			or die ("Cannot prepare statement\n");
104
+		$result = pg_execute($con, "prepare1", array($this->url))
105
+			or die ("Cannot execute statement\n");
106
+
107
+
108
+		$query = "INSERT INTO wiki (url, title, content, lastedit, archive, locale) VALUES
109
+			($1, $2, $3, $4, FALSE, $5)";
110
+
111
+		pg_prepare($con, "prepare2", $query) 
112
+			or die ("Cannot prepare statement\n");
113
+		$result = pg_execute($con, "prepare2", array($this->url, $this->title, $this->content, date('r'), $this->locale))
114
+			or die ("Cannot execute statement\n");
115
+
116
+		pg_close($con);
117
+
118
+		error_log(
119
+			date('r')." \t".$user->name." (".$user->id.") \tUPDATE \tEdit wiki page '".$this->url."'\r\n",
120
+			3,
121
+			$config['logs_folder'].'wiki.log');
122
+	}
123
+
124
+	/*****
125
+	** Delete a page by archiving it
126
+	*****/
127
+	public function delete() {
128
+		global $config;
129
+		global $user;
130
+		
131
+		$con = pg_connect("host=".$config['SQL_host']." dbname=".$config['SQL_db']." user=".$config['SQL_user']." password=".$config['SQL_pass'])
132
+			or die ("Could not connect to server\n");
133
+
134
+		$query = "UPDATE wiki SET archive = TRUE WHERE url = $1";
135
+
136
+		pg_prepare($con, "prepare1", $query) 
137
+			or die ("Cannot prepare statement\n");
138
+		$result = pg_execute($con, "prepare1", array($this->url))
139
+			or die ("Cannot execute statement\n");
140
+
141
+		pg_close($con);
142
+
143
+		error_log(
144
+			date('r')." \t".$user->name." (".$user->id.") \tDELETE \tArchive wiki page '".$this->url."'\r\n",
145
+			3,
146
+			$config['logs_folder'].'wiki.log');
147
+	}
148
+
149
+	/*****
150
+	** Create a page by archiving the current one and inserting a new one ID
151
+	*****/
152
+	public function insert() {
153
+		global $config;
154
+		global $user;
155
+		
156
+		$con = pg_connect("host=".$config['SQL_host']." dbname=".$config['SQL_db']." user=".$config['SQL_user']." password=".$config['SQL_pass'])
157
+			or die ("Could not connect to server\n");
158
+
159
+		$query = "INSERT INTO wiki (url, title, content, lastedit, archive, locale) VALUES
160
+			($1, $2, $3, $4, FALSE, $5)";
161
+
162
+		pg_prepare($con, "prepare2", $query) 
163
+			or die ("Cannot prepare statement\n");
164
+		$result = pg_execute($con, "prepare2", array($this->url, $this->title, $this->content, date('r'), $this->locale))
165
+			or die ("Cannot execute statement\n");
166
+
167
+		pg_close($con);
168
+
169
+		error_log(
170
+			date('r')." \t".$user->name." (".$user->id.") \tINSERT \tCreate new wiki page '".$this->url."'\r\n",
171
+			3,
172
+			$config['logs_folder'].'wiki.log');
173
+	}
174
+
175
+	/*****
176
+	** Converts the Markdown content to HTML
177
+	*****/
178
+	public function md2html() {
179
+		$this->content_html = \Michelf\MarkdownExtra::defaultTransform($this->content);
180
+	}
181
+}
182
+
183
+class WikiPages
184
+{
185
+	public $ids = array();
186
+	public $number = NULL;
187
+
188
+	/*****
189
+	** Checks if a page at this URL exists and return the ID
190
+	*****/
191
+	public function getHistory($url) {
192
+		global $config;
193
+		
194
+		$con = pg_connect("host=".$config['SQL_host']." dbname=".$config['SQL_db']." user=".$config['SQL_user']." password=".$config['SQL_pass'])
195
+			or die ("Could not connect to server\n");
196
+
197
+		$query = "SELECT id FROM wiki WHERE url=$1 ORDER BY lastedit DESC";
198
+
199
+		pg_prepare($con, "prepare1", $query) 
200
+			or die ("Cannot prepare statement\n");
201
+		$result = pg_execute($con, "prepare1", array($url))
202
+			or die ("Cannot execute statement\n");
203
+
204
+		pg_close($con);
205
+
206
+		$this->number = pg_num_rows($result);
207
+
208
+		for($i = 0; $i < $this->number; $i++) {
209
+			$row = pg_fetch_assoc($result, $i);
210
+			$this->ids[$i] = $row['id'];
211
+		}
212
+	}
213
+}
214
+
215
+?>

+ 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 @@
1
+COMMENT ON DATABASE kabano IS 'Kabano database';
2
+
3
+
4
+
5
+-- SEQUENCES
6
+
7
+CREATE SEQUENCE blog_articles_id_seq
8
+    START WITH 1
9
+    INCREMENT BY 1
10
+    NO MINVALUE
11
+    NO MAXVALUE
12
+    CACHE 1;
13
+ALTER TABLE blog_articles_id_seq OWNER TO kabano;
14
+
15
+
16
+CREATE SEQUENCE blog_comments_id_seq
17
+    START WITH 1
18
+    INCREMENT BY 1
19
+    NO MINVALUE
20
+    NO MAXVALUE
21
+    CACHE 1;
22
+ALTER TABLE blog_comments_id_seq OWNER TO kabano;
23
+
24
+
25
+CREATE SEQUENCE users_id_seq
26
+    START WITH 1
27
+    INCREMENT BY 1
28
+    NO MINVALUE
29
+    NO MAXVALUE
30
+    CACHE 1;
31
+ALTER TABLE users_id_seq OWNER TO kabano;
32
+
33
+
34
+CREATE SEQUENCE wiki_id_seq
35
+    START WITH 5
36
+    INCREMENT BY 1
37
+    NO MINVALUE
38
+    NO MAXVALUE
39
+    CACHE 1;
40
+ALTER TABLE wiki_id_seq OWNER TO kabano;
41
+
42
+
43
+
44
+-- TABLES
45
+
46
+CREATE TABLE blog_articles (
47
+    id integer DEFAULT nextval('blog_articles_id_seq'::regclass) NOT NULL,
48
+    url text,
49
+    title text,
50
+    content text,
51
+    lastedit timestamp without time zone,
52
+    archive boolean DEFAULT false NOT NULL,
53
+    locale text,
54
+    comments boolean DEFAULT true NOT NULL,
55
+    author integer
56
+);
57
+ALTER TABLE blog_articles OWNER TO kabano;
58
+COMMENT ON TABLE blog_articles IS 'This table contains all archived and visible blog articles';
59
+ALTER TABLE ONLY blog_articles
60
+    ADD CONSTRAINT blog_articles_pkey PRIMARY KEY (id);
61
+
62
+
63
+CREATE TABLE blog_comments (
64
+    id integer DEFAULT nextval('blog_comments_id_seq'::regclass) NOT NULL,
65
+    article integer,
66
+    lastedit timestamp without time zone,
67
+    author integer,
68
+    locale text,
69
+    content text,
70
+    archive boolean DEFAULT false NOT NULL
71
+);
72
+ALTER TABLE blog_comments OWNER TO kabano;
73
+COMMENT ON TABLE blog_comments IS 'This table contains all blog comments';
74
+ALTER TABLE ONLY blog_comments
75
+    ADD CONSTRAINT blog_comments_pkey PRIMARY KEY (id);
76
+
77
+
78
+CREATE TABLE users (
79
+    id integer DEFAULT nextval('users_id_seq'::regclass) NOT NULL,
80
+    name text,
81
+    password text,
82
+    locale text,
83
+    lastlogin timestamp without time zone,
84
+    mail text,
85
+    website text,
86
+    role integer DEFAULT 400 NOT NULL,
87
+    avatar boolean DEFAULT false NOT NULL
88
+);
89
+ALTER TABLE users OWNER TO kabano;
90
+COMMENT ON TABLE users IS 'This user database contains all users informations';
91
+ALTER TABLE ONLY users
92
+    ADD CONSTRAINT users_pkey PRIMARY KEY (id);
93
+
94
+
95
+CREATE TABLE wiki (
96
+    id integer DEFAULT nextval('wiki_id_seq'::regclass) NOT NULL,
97
+    url text,
98
+    title text,
99
+    content text,
100
+    lastedit timestamp without time zone,
101
+    archive boolean DEFAULT false NOT NULL,
102
+    locale text
103
+);
104
+ALTER TABLE wiki OWNER TO kabano;
105
+COMMENT ON TABLE wiki IS 'This wiki database contains all archived and displayed wiki pages';
106
+ALTER TABLE ONLY wiki
107
+    ADD CONSTRAINT wiki_pkey PRIMARY KEY (id);
108
+
109
+
110
+
111
+-- Foreign keys
112
+
113
+ALTER TABLE ONLY blog_articles
114
+    ADD CONSTRAINT blog_articles_author_fkey FOREIGN KEY (author) REFERENCES users(id);
115
+ALTER TABLE ONLY blog_comments
116
+    ADD CONSTRAINT blog_comments_article_fkey FOREIGN KEY (article) REFERENCES blog_articles(id);
117
+ALTER TABLE ONLY blog_comments
118
+    ADD CONSTRAINT blog_comments_author_fkey FOREIGN KEY (author) REFERENCES users(id);
119
+

+ 6
- 0
src/logo.min.svg View File

@@ -0,0 +1,6 @@
1
+<svg xmlns="http://www.w3.org/2000/svg" width="140" height="46" viewBox="0 0 140 46">
2
+  <path id="kabanologomount" d="M40.652.398l-16.007 25.19 2.832-8.63-5.274-9.612L0 46h67.363l-4.455-7.607h-2.32L63.873 44H3.457l18.707-32.568 3.143 5.728-5.06 15.402.948.313.846.537L40.585 4.236l10.238 17.48v-3.954L40.652.398z" fill="#fff"/>
3
+  <path id="kabanologomountbgtext" d="M50.822 17.762v3.955l9.766 16.676h2.32l-12.086-20.63z" fill="#fff"/>
4
+  <path id="kabanologotext" d="M58.31 16.105h-2.375V33.33h2.375V16.105zm9.375 0h-2.7l-6.55 8.025 6.8 9.2h2.925l-7-9.35 6.525-7.875zM79.284 30.255V24.23c0-2.75-1.45-4.375-4.625-4.375-1.476 0-2.926.3-4.55.9l.574 1.675c1.35-.45 2.575-.7 3.55-.7 1.825 0 2.75.7 2.75 2.6v.975H74.96c-3.676 0-5.8 1.525-5.8 4.35 0 2.35 1.574 3.975 4.2 3.975 1.6 0 3-.6 3.924-1.975.4 1.3 1.25 1.825 2.575 1.975l.524-1.6c-.675-.25-1.1-.625-1.1-1.775zm-5.4 1.65c-1.5 0-2.275-.825-2.275-2.375 0-1.8 1.224-2.7 3.65-2.7h1.724v3.025c-.75 1.375-1.75 2.05-3.1 2.05zM90.057 19.855c-1.6 0-2.825.725-3.725 1.95V14.58l-2.3.275V33.33h2.025l.225-1.45c.9 1.1 2.05 1.75 3.5 1.75 3.2 0 5.175-2.775 5.175-6.9 0-4.4-1.925-6.875-4.9-6.875zm-.825 11.95c-1.175 0-2.225-.725-2.9-1.775v-6.3c.675-1.05 1.625-2.05 3.075-2.05 1.85 0 3.075 1.3 3.075 5.05 0 3.6-1.325 5.075-3.25 5.075zM107.75 30.255V24.23c0-2.75-1.45-4.375-4.624-4.375-1.475 0-2.925.3-4.55.9l.575 1.675c1.35-.45 2.576-.7 3.55-.7 1.826 0 2.75.7 2.75 2.6v.975h-2.024c-3.675 0-5.8 1.525-5.8 4.35 0 2.35 1.575 3.975 4.2 3.975 1.6 0 3-.6 3.925-1.975.4 1.3 1.25 1.825 2.576 1.975l.525-1.6c-.674-.25-1.1-.625-1.1-1.775zm-5.4 1.65c-1.5 0-2.274-.825-2.274-2.375 0-1.8 1.225-2.7 3.65-2.7h1.725v3.025c-.75 1.375-1.75 2.05-3.1 2.05zM118.7 19.855c-1.726 0-3.126.9-4.026 2.25l-.2-1.95H112.5V33.33h2.3v-9.35c.874-1.4 1.874-2.325 3.35-2.325 1.274 0 2.074.575 2.074 2.55v9.125h2.3v-9.45c0-2.5-1.4-4.025-3.825-4.025zM132.097 19.855c-3.75 0-5.9 2.825-5.9 6.9 0 4.175 2.125 6.875 5.875 6.875 3.725 0 5.875-2.825 5.875-6.9 0-4.175-2.1-6.875-5.85-6.875zm0 1.85c2.175 0 3.375 1.6 3.375 5.025 0 3.45-1.2 5.05-3.4 5.05s-3.4-1.6-3.4-5.025c0-3.45 1.225-5.05 3.425-5.05z" fill="#fff"/>
5
+  <path id="kabanologobase" d="M67.364 46l-2.344-4H2.3L0 46z" fill="#fff"/>
6
+</svg>

+ 217
- 0
src/logo.svg View File

@@ -0,0 +1,217 @@
1
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
2
+<!-- Created with Inkscape (http://www.inkscape.org/) -->
3
+
4
+<svg
5
+   xmlns:osb="http://www.openswatchbook.org/uri/2009/osb"
6
+   xmlns:dc="http://purl.org/dc/elements/1.1/"
7
+   xmlns:cc="http://creativecommons.org/ns#"
8
+   xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
9
+   xmlns:svg="http://www.w3.org/2000/svg"
10
+   xmlns="http://www.w3.org/2000/svg"
11
+   xmlns:xlink="http://www.w3.org/1999/xlink"
12
+   xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
13
+   xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
14
+   width="180"
15
+   height="50"
16
+   viewBox="0 0 180 50.000001"
17
+   id="svg2"
18
+   version="1.1"
19
+   inkscape:version="0.91 r13725"
20
+   sodipodi:docname="logo.svg"
21
+   inkscape:export-filename="/home/leo/public_html/Kabano/views/img/header3.png"
22
+   inkscape:export-xdpi="84.599998"
23
+   inkscape:export-ydpi="84.599998">
24
+  <defs
25
+     id="defs4">
26
+    <linearGradient
27
+       id="linearGradient4272"
28
+       osb:paint="solid">
29
+      <stop
30
+         style="stop-color:#ffffff;stop-opacity:1;"
31
+         offset="0"
32
+         id="stop4274" />
33
+    </linearGradient>
34
+    <filter
35
+       style="color-interpolation-filters:sRGB"
36
+       inkscape:label="Invert"
37
+       id="filter4242">
38
+      <feColorMatrix
39
+         type="hueRotate"
40
+         values="180"
41
+         result="color1"
42
+         id="feColorMatrix4244" />
43
+      <feColorMatrix
44
+         values="-1 0 0 0 1 0 -1 0 0 1 0 0 -1 0 1 -0.21 -0.72 -0.07 2 0 "
45
+         result="fbSourceGraphic"
46
+         id="feColorMatrix4246" />
47
+      <feColorMatrix
48
+         result="fbSourceGraphicAlpha"
49
+         in="fbSourceGraphic"
50
+         values="0 0 0 -1 0 0 0 0 -1 0 0 0 0 -1 0 0 0 0 1 0"
51
+         id="feColorMatrix4248" />
52
+      <feColorMatrix
53
+         id="feColorMatrix4250"
54
+         type="hueRotate"
55
+         values="180"
56
+         result="color1"
57
+         in="fbSourceGraphic" />
58
+      <feColorMatrix
59
+         id="feColorMatrix4252"
60
+         values="-1 0 0 0 1 0 -1 0 0 1 0 0 -1 0 1 -0.21 -0.72 -0.07 2 0 "
61
+         result="fbSourceGraphic" />
62
+      <feColorMatrix
63
+         result="fbSourceGraphicAlpha"
64
+         in="fbSourceGraphic"
65
+         values="0 0 0 -1 0 0 0 0 -1 0 0 0 0 -1 0 0 0 0 1 0"
66
+         id="feColorMatrix4254" />
67
+      <feColorMatrix
68
+         id="feColorMatrix4256"
69
+         type="hueRotate"
70
+         values="180"
71
+         result="color1"
72
+         in="fbSourceGraphic" />
73
+      <feColorMatrix
74
+         id="feColorMatrix4258"
75
+         values="-1 0 0 0 1 0 -1 0 0 1 0 0 -1 0 1 -0.21 -0.72 -0.07 2 0 "
76
+         result="color2" />
77
+    </filter>
78
+    <linearGradient
79
+       inkscape:collect="always"
80
+       xlink:href="#linearGradient4272"
81
+       id="linearGradient4276"
82
+       x1="463.53574"
83
+       y1="598.1972"
84
+       x2="579.35376"
85
+       y2="598.1972"
86
+       gradientUnits="userSpaceOnUse" />
87
+    <filter
88
+       style="color-interpolation-filters:sRGB"
89
+       inkscape:label="Invert"
90
+       id="filter4278">
91
+      <feColorMatrix
92
+         type="hueRotate"
93
+         values="180"
94
+         result="color1"
95
+         id="feColorMatrix4280" />
96
+      <feColorMatrix
97
+         values="-1 0 0 0 1 0 -1 0 0 1 0 0 -1 0 1 -0.21 -0.72 -0.07 2 0 "
98
+         result="color2"
99
+         id="feColorMatrix4282" />
100
+    </filter>
101
+    <filter
102
+       style="color-interpolation-filters:sRGB"
103
+       inkscape:label="Invert"
104
+       id="filter4284">
105
+      <feColorMatrix
106
+         type="hueRotate"
107
+         values="180"
108
+         result="color1"
109
+         id="feColorMatrix4286" />
110
+      <feColorMatrix
111
+         values="-1 0 0 0 1 0 -1 0 0 1 0 0 -1 0 1 -0.21 -0.72 -0.07 2 0 "
112
+         result="color2"
113
+         id="feColorMatrix4288" />
114
+    </filter>
115
+    <filter
116
+       style="color-interpolation-filters:sRGB"
117
+       inkscape:label="Invert"
118
+       id="filter4290">
119
+      <feColorMatrix
120
+         type="hueRotate"
121
+         values="180"
122
+         result="color1"
123
+         id="feColorMatrix4292" />
124
+      <feColorMatrix
125
+         values="-1 0 0 0 1 0 -1 0 0 1 0 0 -1 0 1 -0.21 -0.72 -0.07 2 0 "
126
+         result="color2"
127
+         id="feColorMatrix4294" />
128
+    </filter>
129
+    <filter
130
+       style="color-interpolation-filters:sRGB"
131
+       inkscape:label="Invert"
132
+       id="filter4296">
133
+      <feColorMatrix
134
+         type="hueRotate"
135
+         values="180"
136
+         result="color1"
137
+         id="feColorMatrix4298" />
138
+      <feColorMatrix
139
+         values="-1 0 0 0 1 0 -1 0 0 1 0 0 -1 0 1 -0.21 -0.72 -0.07 2 0 "
140
+         result="color2"
141
+         id="feColorMatrix4300" />
142
+    </filter>
143
+  </defs>
144
+  <sodipodi:namedview
145
+     id="base"
146
+     pagecolor="#8d9894"
147
+     bordercolor="#666666"
148
+     borderopacity="1.0"
149
+     inkscape:pageopacity="0"
150
+     inkscape:pageshadow="2"
151
+     inkscape:zoom="2.8"
152
+     inkscape:cx="67.921239"
153
+     inkscape:cy="36.484649"
154
+     inkscape:document-units="px"
155
+     inkscape:current-layer="layer1"
156
+     showgrid="false"
157
+     inkscape:window-width="1366"
158
+     inkscape:window-height="745"
159
+     inkscape:window-x="0"
160
+     inkscape:window-y="23"
161
+     inkscape:window-maximized="1"
162
+     units="px" />
163
+  <metadata
164
+     id="metadata7">
165
+    <rdf:RDF>
166
+      <cc:Work
167
+         rdf:about="">
168
+        <dc:format>image/svg+xml</dc:format>
169
+        <dc:type
170
+           rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
171
+        <dc:title></dc:title>
172
+      </cc:Work>
173
+    </rdf:RDF>
174
+  </metadata>
175
+  <g
176
+     inkscape:label="Calque 1"
177
+     inkscape:groupmode="layer"
178
+     id="layer1"
179
+     transform="translate(0,-1002.3622)">
180
+    <g
181
+       id="g4356"
182
+       transform="matrix(1.1515318,0,0,1.1657795,-6.3342807,-170.57805)">
183
+      <path
184
+         sodipodi:nodetypes="cccccc"
185
+         inkscape:connector-curvature="0"
186
+         id="path4260"
187
+         d="m 6.4114189,1048.2461 21.0000001,-34.6129 7,11.2258 12.00019,-17.7743 24.114,41.161 z"
188
+         style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:#ffffff;stroke-width:1.72617102;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;filter:url(#filter4278)" />
189
+      <path
190
+         sodipodi:nodetypes="cc"
191
+         inkscape:connector-curvature="0"
192
+         id="path4264"
193
+         d="m 34.411419,1024.859 -14,23.3871"
194
+         style="fill:none;fill-rule:evenodd;stroke:#ffffff;stroke-width:1.72617102;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;filter:url(#filter4284)" />
195
+      <path
196
+         sodipodi:nodetypes="cccc"
197
+         inkscape:connector-curvature="0"
198
+         id="path4335"
199
+         d="m 46.411609,1007.0847 0,41.161 24.114,0 z"
200
+         style="opacity:0.65;fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" />
201
+    </g>
202
+    <text
203
+       xml:space="preserve"
204
+       style="font-style:normal;font-weight:normal;font-size:40px;line-height:125%;font-family:Sans;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:0;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;filter:url(#filter4296)"
205
+       x="54.34478"
206
+       y="1041.3604"
207
+       id="text4268"
208
+       sodipodi:linespacing="125%"><tspan
209
+         sodipodi:role="line"
210
+         id="tspan4270"
211
+         x="54.34478"
212
+         y="1041.3604"
213
+         style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:35px;font-family:'Fira Sans';-inkscape-font-specification:'Fira Sans';stroke:none;stroke-width:0;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"><tspan
214
+   style="font-weight:bold"
215
+   id="tspan4333">K</tspan>abano</tspan></text>
216
+  </g>
217
+</svg>

+ 102
- 0
src/logo2.svg View File

@@ -0,0 +1,102 @@
1
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
2
+<!-- Created with Inkscape (http://www.inkscape.org/) -->
3
+
4
+<svg
5
+   xmlns:dc="http://purl.org/dc/elements/1.1/"
6
+   xmlns:cc="http://creativecommons.org/ns#"
7
+   xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
8
+   xmlns:svg="http://www.w3.org/2000/svg"
9
+   xmlns="http://www.w3.org/2000/svg"
10
+   xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
11
+   xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
12
+   width="140"
13
+   height="46"
14
+   viewBox="0 0 140 46.000001"
15
+   id="svg4170"
16
+   version="1.1"
17
+   inkscape:version="0.91 r13725"
18
+   sodipodi:docname="logo2.svg">
19
+  <defs
20
+     id="defs4172" />
21
+  <sodipodi:namedview
22
+     id="base"
23
+     pagecolor="#ffffff"
24
+     bordercolor="#666666"
25
+     borderopacity="1.0"
26
+     inkscape:pageopacity="0.0"
27
+     inkscape:pageshadow="2"
28
+     inkscape:zoom="5.6568543"
29
+     inkscape:cx="63.834622"
30
+     inkscape:cy="18.257409"
31
+     inkscape:document-units="px"
32
+     inkscape:current-layer="layer1"
33
+     showgrid="false"
34
+     units="px"
35
+     inkscape:window-width="1366"
36
+     inkscape:window-height="745"
37
+     inkscape:window-x="1280"
38
+     inkscape:window-y="23"
39
+     inkscape:window-maximized="1" />
40
+  <metadata
41
+     id="metadata4175">
42
+    <rdf:RDF>
43
+      <cc:Work
44
+         rdf:about="">
45
+        <dc:format>image/svg+xml</dc:format>
46
+        <dc:type
47
+           rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
48
+        <dc:title></dc:title>
49
+      </cc:Work>
50
+    </rdf:RDF>
51
+  </metadata>
52
+  <g
53
+     inkscape:label="Calque 1"
54
+     inkscape:groupmode="layer"
55
+     id="layer1"
56
+     transform="translate(0,-1006.3622)">
57
+    <path
58
+       style="color:#000000;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:medium;line-height:normal;font-family:sans-serif;text-indent:0;text-align:start;text-decoration:none;text-decoration-line:none;text-decoration-style:solid;text-decoration-color:#000000;letter-spacing:normal;word-spacing:normal;text-transform:none;direction:ltr;block-progression:tb;writing-mode:lr-tb;baseline-shift:baseline;text-anchor:start;white-space:normal;clip-rule:nonzero;display:inline;overflow:visible;visibility:visible;opacity:1;isolation:auto;mix-blend-mode:normal;color-interpolation:sRGB;color-interpolation-filters:linearRGB;solid-color:#000000;solid-opacity:1;fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:2;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;color-rendering:auto;image-rendering:auto;shape-rendering:auto;text-rendering:auto;enable-background:accumulate"
59
+       d="M 50.822266 17.761719 L 50.822266 21.716797 L 60.587891 38.392578 L 62.908203 38.392578 L 50.822266 17.761719 z "
60
+       id="path4884"
61
+       transform="translate(0,1006.3622)" />
62
+    <path
63
+       style="color:#000000;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:medium;line-height:normal;font-family:sans-serif;text-indent:0;text-align:start;text-decoration:none;text-decoration-line:none;text-decoration-style:solid;text-decoration-color:#000000;letter-spacing:normal;word-spacing:normal;text-transform:none;direction:ltr;block-progression:tb;writing-mode:lr-tb;baseline-shift:baseline;text-anchor:start;white-space:normal;clip-rule:nonzero;display:inline;overflow:visible;visibility:visible;opacity:1;isolation:auto;mix-blend-mode:normal;color-interpolation:sRGB;color-interpolation-filters:linearRGB;solid-color:#000000;solid-opacity:1;fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:2;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;color-rendering:auto;image-rendering:auto;shape-rendering:auto;text-rendering:auto;enable-background:accumulate"
64
+       d="M 40.652344 0.3984375 L 24.644531 25.587891 L 27.476562 16.958984 L 22.203125 7.3457031 L 0 46 L 67.363281 46 L 62.908203 38.392578 L 60.587891 38.392578 L 63.873047 44 L 3.4570312 44 L 22.164062 11.431641 L 25.306641 17.160156 L 20.248047 32.5625 L 21.195312 32.875 L 22.041016 33.412109 L 40.583984 4.2363281 L 50.822266 21.716797 L 50.822266 17.761719 L 40.652344 0.3984375 z "
65
+       id="path3349"
66
+       transform="translate(0,1006.3622)" />
67
+    <g
68
+       style="font-style:normal;font-weight:normal;font-size:40px;line-height:125%;font-family:Sans;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
69
+       id="text4151">
70
+      <path
71
+         d="m 58.309608,1022.4674 -2.375,0 0,17.225 2.375,0 0,-17.225 z m 9.375,0 -2.7,0 -6.55,8.025 6.8,9.2 2.925,0 -7,-9.35 6.525,-7.875 z"
72
+         style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:25px;font-family:'Fira Sans';-inkscape-font-specification:'Fira Sans';fill:#ffffff;fill-opacity:1"
73
+         id="path4887" />
74
+      <path
75
+         d="m 79.284218,1036.6174 0,-6.025 c 0,-2.75 -1.45,-4.375 -4.625,-4.375 -1.475,0 -2.925,0.3 -4.55,0.9 l 0.575,1.675 c 1.35,-0.45 2.575,-0.7 3.55,-0.7 1.825,0 2.75,0.7 2.75,2.6 l 0,0.975 -2.025,0 c -3.675,0 -5.8,1.525 -5.8,4.35 0,2.35 1.575,3.975 4.2,3.975 1.6,0 3,-0.6 3.925,-1.975 0.4,1.3 1.25,1.825 2.575,1.975 l 0.525,-1.6 c -0.675,-0.25 -1.1,-0.625 -1.1,-1.775 z m -5.4,1.65 c -1.5,0 -2.275,-0.825 -2.275,-2.375 0,-1.8 1.225,-2.7 3.65,-2.7 l 1.725,0 0,3.025 c -0.75,1.375 -1.75,2.05 -3.1,2.05 z"
76
+         style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:25px;font-family:'Fira Sans';-inkscape-font-specification:'Fira Sans';fill:#ffffff;fill-opacity:1"
77
+         id="path4889" />
78
+      <path
79
+         d="m 90.057265,1026.2174 c -1.6,0 -2.825,0.725 -3.725,1.95 l 0,-7.225 -2.3,0.275 0,18.475 2.025,0 0.225,-1.45 c 0.9,1.1 2.05,1.75 3.5,1.75 3.2,0 5.175,-2.775 5.175,-6.9 0,-4.4 -1.925,-6.875 -4.9,-6.875 z m -0.825,11.95 c -1.175,0 -2.225,-0.725 -2.9,-1.775 l 0,-6.3 c 0.675,-1.05 1.625,-2.05 3.075,-2.05 1.85,0 3.075,1.3 3.075,5.05 0,3.6 -1.325,5.075 -3.25,5.075 z"
80
+         style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:25px;font-family:'Fira Sans';-inkscape-font-specification:'Fira Sans';fill:#ffffff;fill-opacity:1"
81
+         id="path4891" />
82
+      <path
83
+         d="m 107.75101,1036.6174 0,-6.025 c 0,-2.75 -1.45,-4.375 -4.625,-4.375 -1.475,0 -2.925,0.3 -4.549995,0.9 l 0.575,1.675 c 1.349995,-0.45 2.574995,-0.7 3.549995,-0.7 1.825,0 2.75,0.7 2.75,2.6 l 0,0.975 -2.025,0 c -3.674995,0 -5.799995,1.525 -5.799995,4.35 0,2.35 1.575,3.975 4.199995,3.975 1.6,0 3,-0.6 3.925,-1.975 0.4,1.3 1.25,1.825 2.575,1.975 l 0.525,-1.6 c -0.675,-0.25 -1.1,-0.625 -1.1,-1.775 z m -5.4,1.65 c -1.5,0 -2.275,-0.825 -2.275,-2.375 0,-1.8 1.225,-2.7 3.65,-2.7 l 1.725,0 0,3.025 c -0.75,1.375 -1.75,2.05 -3.1,2.05 z"
84
+         style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:25px;font-family:'Fira Sans';-inkscape-font-specification:'Fira Sans';fill:#ffffff;fill-opacity:1"
85
+         id="path4893" />
86
+      <path
87
+         d="m 118.69906,1026.2174 c -1.725,0 -3.125,0.9 -4.025,2.25 l -0.2,-1.95 -1.975,0 0,13.175 2.3,0 0,-9.35 c 0.875,-1.4 1.875,-2.325 3.35,-2.325 1.275,0 2.075,0.575 2.075,2.55 l 0,9.125 2.3,0 0,-9.45 c 0,-2.5 -1.4,-4.025 -3.825,-4.025 z"
88
+         style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:25px;font-family:'Fira Sans';-inkscape-font-specification:'Fira Sans';fill:#ffffff;fill-opacity:1"
89
+         id="path4895" />
90
+      <path
91
+         d="m 132.0975,1026.2174 c -3.75,0 -5.9,2.825 -5.9,6.9 0,4.175 2.125,6.875 5.875,6.875 3.725,0 5.875,-2.825 5.875,-6.9 0,-4.175 -2.1,-6.875 -5.85,-6.875 z m 0,1.85 c 2.175,0 3.375,1.6 3.375,5.025 0,3.45 -1.2,5.05 -3.4,5.05 -2.2,0 -3.4,-1.6 -3.4,-5.025 0,-3.45 1.225,-5.05 3.425,-5.05 z"
92
+         style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:25px;font-family:'Fira Sans';-inkscape-font-specification:'Fira Sans';fill:#ffffff;fill-opacity:1"
93
+         id="path4897" />
94
+    </g>
95
+    <path
96
+       style="fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
97
+       d="m 67.364,1052.3622 -2.344,-4 -62.72,0 -2.3,4 z"
98
+       id="path4820"
99
+       inkscape:connector-curvature="0"
100
+       sodipodi:nodetypes="ccccc" />
101
+  </g>
102
+</svg>

+ 104
- 0
src/logo3.svg View File

@@ -0,0 +1,104 @@
1
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>