PageRenderTime 60ms CodeModel.GetById 23ms RepoModel.GetById 0ms app.codeStats 0ms

/wiki/wiki.php

https://bitbucket.org/eithansmith/waka-wiki
PHP | 499 lines | 401 code | 95 blank | 3 comment | 41 complexity | 3c02f45a6ae6e78070fa2c1dcbd6cf75 MD5 | raw file
  1. <?php
  2. Class Wiki
  3. {
  4. public function __construct($config_parms)
  5. {
  6. session_start();
  7. $this->_set_config_parms($config_parms);
  8. require_once 'loader.php';
  9. $this->_loader = new Loader($this->_template);
  10. }
  11. public function view($page = '')
  12. {
  13. $data = $this->_load_wiki_page_data($page);
  14. $data['wiki_categories'] = $this->_get_categories();
  15. $this->_loader->load('header', $data);
  16. $this->_loader->load('menu', $data);
  17. $this->_loader->load('view', $data);
  18. $this->_loader->load('footer');
  19. exit;
  20. }
  21. public function viewall($category = '')
  22. {
  23. $config = $this->_get_config_parms();
  24. $config['wiki_categories'] = $this->_get_categories();
  25. $data['all_wiki'] = $this->_load_all_wiki_page_data($category);
  26. $this->_loader->load('header', $config);
  27. $this->_loader->load('menu', $config);
  28. $this->_loader->load('viewall', $data);
  29. $this->_loader->load('footer');
  30. exit;
  31. }
  32. public function edit($page = '')
  33. {
  34. $data = $this->_load_wiki_page_data($page);
  35. $data['wiki_categories'] = $this->_get_categories();
  36. if ($this->_save_state)
  37. {
  38. $data['text'] = $this->_save_state['text'];
  39. $data['page_display'] = str_replace('_', ' ', $this->_save_state['name']);
  40. $data['page_display'] = ucwords($data['page_display']);
  41. }
  42. $this->_loader->load('header', $data);
  43. $this->_loader->load('menu', $data);
  44. $this->_loader->load('edit', $data);
  45. $this->_loader->load('footer');
  46. exit;
  47. }
  48. public function update($page = '')
  49. {
  50. $data = $this->_load_wiki_page_data($page);
  51. if (!$this->_post())
  52. $this->display_error("No post data found");
  53. $name = $this->_post('name');
  54. $name_display = $name;
  55. $name = str_replace(' ', '_', $name);
  56. $name = strtolower($name);
  57. $category = $this->_post('category');
  58. $category = str_replace(' ', '_', $category);
  59. $category = strtolower($category);
  60. $text = $this->_post('text');
  61. $password = $this->_post('password');
  62. $rev = $this->_post('rev') + 1;
  63. $created = $data['created'];
  64. $modified = time();
  65. if (!$this->_authenticate($password))
  66. {
  67. $this->_save_state = $this->_post();
  68. $this->_set_message('Password entered is incorrect');
  69. $this->edit($page);
  70. }
  71. if (!$this->_post('name'))
  72. {
  73. $this->_save_state = $this->_post();
  74. $this->_set_message('A name is required', 'warning');
  75. $this->edit($page);
  76. }
  77. if (!$this->_post('category'))
  78. {
  79. $this->_save_state = $this->_post();
  80. $this->_set_message('A category is required', 'warning');
  81. $this->edit($page);
  82. }
  83. if ($name != $page)
  84. {
  85. if ($page == $this->_default_page)
  86. {
  87. $this->_save_state = $this->_post();
  88. $this->_save_state['name'] = $this->_default_page;
  89. $this->_set_message('You cannot rename the default wiki page.');
  90. $this->edit($page);
  91. }
  92. else
  93. $this->_delete_file("wiki/pages/$page.waka");
  94. }
  95. $file = array(
  96. 'name' => $name,
  97. 'category' => $category,
  98. 'rev' => $rev,
  99. 'created' => $created,
  100. 'modified' => $modified,
  101. 'text' => $text
  102. );
  103. $json = json_encode($file, TRUE);
  104. file_put_contents("wiki/pages/$name.waka", $json);
  105. $this->_set_message("Wiki page $name_display updated.", 'success');
  106. $this->view($name);
  107. }
  108. public function newpage()
  109. {
  110. $data = $this->_get_config_parms();
  111. $data['wiki_categories'] = $this->_get_categories();
  112. if ($this->_save_state)
  113. {
  114. $data['text'] = $this->_save_state['text'];
  115. $data['page_display'] = str_replace('_', ' ', $this->_save_state['name']);
  116. $data['page_display'] = ucwords($data['page_display']);
  117. }
  118. else
  119. {
  120. $data['text'] = '';
  121. $data['page_display'] = '';
  122. }
  123. $this->_loader->load('header', $data);
  124. $this->_loader->load('menu', $data);
  125. $this->_loader->load('newpage', $data);
  126. $this->_loader->load('footer');
  127. exit;
  128. }
  129. public function create()
  130. {
  131. if (!$this->_post())
  132. $this->display_error("No post data found");
  133. $data = array();
  134. $name = $this->_post('name');
  135. $name_display = $name;
  136. $name = str_replace(' ', '_', $name);
  137. $name = strtolower($name);
  138. $category = $this->_post('category');
  139. $category_display = $category;
  140. $category = str_replace(' ', '_', $category);
  141. $category = strtolower($category);
  142. $text = $this->_post('text');
  143. $password = $this->_post('password');
  144. $rev = 0;
  145. $created = time();
  146. $modified = $created;
  147. if (!$this->_authenticate($password))
  148. {
  149. $this->_save_state = $this->_post();
  150. $this->_set_message('Password entered is incorrect');
  151. $this->newpage();
  152. }
  153. if (!$this->_post('name'))
  154. {
  155. $this->_save_state = $this->_post();
  156. $this->_set_message('A name is required', 'warning');
  157. $this->newpage();
  158. }
  159. if (!$this->_post('category'))
  160. {
  161. $this->_save_state = $this->_post();
  162. $this->_set_message('A category is required', 'warning');
  163. $this->newpage();
  164. }
  165. if (@file_get_contents("wiki/pages/$name.waka"))
  166. {
  167. $this->_save_state = $this->_post();
  168. $this->_set_message("File $name_display already exists.");
  169. $this->newpage();
  170. }
  171. $file = array(
  172. 'name' => $name,
  173. 'category' => $category,
  174. 'rev' => $rev,
  175. 'created' => $created,
  176. 'modified' => $modified,
  177. 'text' => $text
  178. );
  179. $json = json_encode($file, TRUE);
  180. file_put_contents("wiki/pages/$name.waka", $json);
  181. $this->_set_message("Wiki page $name_display created.", 'success');
  182. $this->view($name);
  183. }
  184. public function delete($page = '')
  185. {
  186. if (!$this->_post())
  187. $this->display_error("No post data found");
  188. $data = $this->_load_wiki_page_data($page);
  189. $password = $this->_post('password');
  190. if (!$this->_authenticate($password))
  191. {
  192. $this->_save_state = $this->_post();
  193. $this->_set_message('Password entered is incorrect');
  194. $this->edit($page);
  195. }
  196. if ($page == $this->_default_page)
  197. {
  198. $this->_set_message('You cannot delete the default wiki page.');
  199. $this->edit($page);
  200. }
  201. $this->_delete_file("wiki/pages/$page.waka");
  202. $this->_set_message("Wiki page {$data['page_display']} deleted.", 'warning');
  203. $this->view();
  204. }
  205. public function display_error($message = 'An error occurred')
  206. {
  207. $data = $this->_get_config_parms();
  208. $this->_set_message($message, 'error');
  209. $this->_loader->load('header', $data);
  210. $this->_loader->load('menu', $data);
  211. $this->_loader->load('blank', $data);
  212. $this->_loader->load('footer');
  213. exit;
  214. }
  215. private function _load_wiki_page_data($page = '')
  216. {
  217. if ($page == '')
  218. $page = $this->_default_page;
  219. $file = @file_get_contents("wiki/pages/$page.waka");
  220. if (!$file)
  221. $this->display_error("Wiki page \"$page\" not found");
  222. $json = json_decode($file, TRUE);
  223. $config = $this->_get_config_parms();
  224. $data = array_merge($json, $config);
  225. $data['created_display'] = date('F j, Y, g:i a', $data['created']);
  226. $data['modified_display'] = date('F j, Y, g:i a', $data['modified']);
  227. $data['page_display'] = str_replace('_', ' ', $page);
  228. $data['page_display'] = ucwords($data['page_display']);
  229. $data['category_display'] = str_replace('_', ' ', $data['category']);
  230. $data['category_display'] = ucwords($data['category_display']);
  231. if ($this->_authenticate(''))
  232. $data['password_required'] = FALSE;
  233. else
  234. $data['password_required'] = TRUE;
  235. $data['text_translated'] = $this->_decode_wiki_text($data['text']);
  236. return $data;
  237. }
  238. private function _load_all_wiki_page_data($category = '')
  239. {
  240. $all_wiki = array();
  241. $files = scandir('wiki/pages/');
  242. foreach($files as $file)
  243. {
  244. $data = @file_get_contents("wiki/pages/$file");
  245. if ($data)
  246. {
  247. $json = json_decode($data, TRUE);
  248. $config = $this->_get_config_parms();
  249. $data = array_merge($json, $config);
  250. $data['created_display'] = date('F j, Y, g:i a', $data['created']);
  251. $data['modified_display'] = date('F j, Y, g:i a', $data['modified']);
  252. $data['page_display'] = str_replace('_', ' ', $data['name']);
  253. $data['page_display'] = ucwords($data['page_display']);
  254. $data['category_display'] = str_replace('_', ' ', $data['category']);
  255. $data['category_display'] = ucwords($data['category_display']);
  256. if ($category == '' || $category == $data['category'])
  257. $all_wiki[] = $data;
  258. }
  259. }
  260. return $all_wiki;
  261. }
  262. private function _get_categories()
  263. {
  264. $categories = array();
  265. $files = scandir('wiki/pages/');
  266. foreach($files as $file)
  267. {
  268. $data = @file_get_contents("wiki/pages/$file");
  269. if ($data)
  270. {
  271. $json = json_decode($data, TRUE);
  272. if (array_key_exists('category', $json))
  273. {
  274. $category = $json['category'];
  275. $category_display = str_replace('_', ' ', $category);
  276. $category_display = ucwords($category_display);
  277. $categories[$category] = $category_display;
  278. }
  279. }
  280. }
  281. asort($categories);
  282. //print '<pre>';
  283. //print_r($categories);
  284. //die();
  285. return $categories;
  286. }
  287. private function _post($item = '', $sanitize = TRUE)
  288. {
  289. if ($item == '')
  290. {
  291. if(is_array($_POST))
  292. {
  293. $post = array();
  294. foreach($_POST as $key => $value)
  295. {
  296. if ($sanitize)
  297. $post[$key] = $this->_santitize_string($value);
  298. else
  299. $post[$key] = $value;
  300. }
  301. return $post;
  302. }
  303. else
  304. return FALSE;
  305. }
  306. else
  307. {
  308. if (is_array($_POST) && isset($_POST[$item]))
  309. {
  310. if ($sanitize)
  311. return $this->_santitize_string($_POST[$item]);
  312. else
  313. return $_POST[$item];
  314. }
  315. else
  316. return FALSE;
  317. }
  318. }
  319. private function _santitize_string($string)
  320. {
  321. $string = stripslashes($string);
  322. $string = htmlentities($string);
  323. $string = strip_tags($string);
  324. $string = trim($string);
  325. return $string;
  326. }
  327. private function _set_message($message, $message_class = 'error')
  328. {
  329. $_SESSION['message'] = $message;
  330. $_SESSION['message_class'] = $message_class;
  331. }
  332. private function _set_config_parms($config_parms)
  333. {
  334. $this->_wiki_title = $config_parms['wiki_title'];
  335. $this->_password = crypt($config_parms['password'], $this->_salt);
  336. $this->_template = $config_parms['template'];
  337. $this->_default_page = $config_parms['default_page'];
  338. $this->_base_url = $config_parms['base_url'];
  339. $this->_header_logo = $config_parms['header_logo'];
  340. $this->_default_page_display = str_replace('_', ' ', $config_parms['default_page']);
  341. $this->_default_page_display = ucwords($this->_default_page_display);
  342. }
  343. private function _get_config_parms()
  344. {
  345. $data['wiki_title'] = $this->_wiki_title;
  346. $data['template'] = $this->_template;
  347. $data['default_page'] = $this->_default_page;
  348. $data['default_page_display'] = $this->_default_page_display;
  349. $data['base_url'] = $this->_base_url;
  350. $data['header_logo'] = $this->_header_logo;
  351. if ($this->_authenticate(''))
  352. $data['password_required'] = FALSE;
  353. else
  354. $data['password_required'] = TRUE;
  355. return $data;
  356. }
  357. private function _authenticate($password)
  358. {
  359. $password = crypt($password, $this->_salt);
  360. if ($password == $this->_password)
  361. return TRUE;
  362. else
  363. return FALSE;
  364. }
  365. private function _decode_wiki_text($text)
  366. {
  367. $text .= "\n";
  368. $text = preg_replace("/======(.*)======/Um", '<h5>$1</h5>', $text);
  369. $text = preg_replace("/=====(.*)=====/Um", '<h4>$1</h4>', $text);
  370. $text = preg_replace("/====(.*)====/Um", '<h3>$1</h3>', $text);
  371. $text = preg_replace("/===(.*)===/Um", '<h2>$1</h2>', $text);
  372. $text = preg_replace("/==(.*)==/Um", '<h1>$1</h1>', $text);
  373. $text = preg_replace("/''''(.*)''''/Um", '<s>$1</s>', $text);
  374. $text = preg_replace("/'''(.*)'''/Um", '<b>$1</b>', $text);
  375. $text = preg_replace("/''(.*)''/Um", '<i>$1</i>', $text);
  376. $text = preg_replace('/\[\[Image:(.*?)\|(.*?)\]\]/', '<img src="$1" alt="$2" title="$2" />', $text);
  377. $text = preg_replace('/\[(.*?) (.*?)\]/', '<a target="_blank" href="$1" title="$2">$2</a>', $text);
  378. $text = preg_replace('/\*\* (.*?)\n/', '<ul><li>$1</li></ul>', $text);
  379. $text = preg_replace('/<\/ul><ul>/', '', $text);
  380. $text = preg_replace('/## (.*?)\n/', '<ol><li>$1</li></ol>', $text);
  381. $text = preg_replace('/<\/ol><ol>/', '', $text);
  382. $text = nl2br($text);
  383. return $text;
  384. }
  385. private function _delete_file($file)
  386. {
  387. while(is_file($file) == TRUE)
  388. {
  389. chmod($file, 0666);
  390. unlink($file);
  391. }
  392. }
  393. private $_wiki_title = '';
  394. private $_password = '';
  395. private $_salt = '54XCc22hR3d197d'; // feel free to change this
  396. private $_template = '';
  397. private $_default_page = '';
  398. private $_default_page_display = '';
  399. private $_base_url = '';
  400. private $_data = array();
  401. private $_loader = '';
  402. private $_save_state = FALSE;
  403. private $_header_logo = '';
  404. }