PageRenderTime 24ms CodeModel.GetById 22ms RepoModel.GetById 1ms app.codeStats 0ms

/wigit/index.php

https://bitbucket.org/gopchu/gopchu.org
PHP | 421 lines | 315 code | 55 blank | 51 comment | 92 complexity | 18f78265e49ff5adc11d16393df4af8f MD5 | raw file
Possible License(s): BSD-3-Clause
  1. <?php
  2. /*
  3. * WiGit
  4. * (c) Remko Tronçon (http://el-tramo.be)
  5. * See COPYING for details
  6. *
  7. * Modifications: Stephen Ierodiaconou 2010
  8. */
  9. session_start();
  10. //require_once('markdown.php');
  11. // --------------------------------------------------------------------------
  12. // Configuration
  13. // --------------------------------------------------------------------------
  14. if (file_exists('config.php')) {
  15. require_once('config.php');
  16. }
  17. if (!isset($GIT)) { $GIT = "git"; }
  18. if (!isset($BASE_URL)) { $BASE_URL = "/wigit"; }
  19. if (!isset($SCRIPT_URL)) { $SCRIPT_URL = "$BASE_URL/index.php?r="; }
  20. if (!isset($TITLE)) { $TITLE = "WiGit"; }
  21. if (!isset($DATA_DIR)) { $DATA_DIR = "data"; }
  22. if (!isset($DEFAULT_PAGE)) { $DEFAULT_PAGE = "Home"; }
  23. if (!isset($DEFAULT_AUTHOR)) { $DEFAULT_AUTHOR = 'Anonymous <anonymous@wigit>'; }
  24. if (!isset($AUTHORS)) { $AUTHORS = array(); }
  25. if (!isset($THEME)) { $THEME = "default"; }
  26. // --------------------------------------------------------------------------
  27. // Helpers
  28. // --------------------------------------------------------------------------
  29. function getGitHistory($file = "") {
  30. $output = array();
  31. // FIXME: Find a better way to find the files that changed than --name-only
  32. git("log --name-only --pretty=format:'%H>%T>%an>%ae>%aD>%s' -- $file", $output);
  33. $history = array();
  34. $historyItem = array();
  35. foreach ($output as $line) {
  36. $logEntry = explode(">", $line, 6);
  37. if (sizeof($logEntry) > 1) {
  38. // Populate history structure
  39. $historyItem = array(
  40. "author" => $logEntry[2],
  41. "email" => $logEntry[3],
  42. "linked-author" => (
  43. $logEntry[3] == "" ?
  44. $logEntry[2]
  45. : "<a href=\"mailto:$logEntry[3]\">$logEntry[2]</a>"),
  46. "date" => $logEntry[4],
  47. "message" => $logEntry[5],
  48. "commit" => $logEntry[0]
  49. );
  50. }
  51. else if (!isset($historyItem["page"])) {
  52. $historyItem["page"] = $line;
  53. $history[] = $historyItem;
  54. }
  55. }
  56. return $history;
  57. }
  58. function getAuthorForUser($user) {
  59. global $AUTHORS, $DEFAULT_AUTHOR;
  60. if (isset($AUTHORS[$user])) {
  61. return $AUTHORS[$user];
  62. }
  63. else if ($user != "") {
  64. return "$user <$user@wiggit>";
  65. }
  66. return $DEFAULT_AUTHOR;
  67. }
  68. function getHTTPUser() {
  69. // This code is copied from phpMyID. Thanks to the phpMyID dev(s).
  70. if (function_exists('apache_request_headers') && ini_get('safe_mode') == false) {
  71. $arh = apache_request_headers();
  72. $hdr = $arh['Authorization'];
  73. } elseif (isset($_SERVER['PHP_AUTH_DIGEST'])) {
  74. $hdr = $_SERVER['PHP_AUTH_DIGEST'];
  75. } elseif (isset($_SERVER['HTTP_AUTHORIZATION'])) {
  76. $hdr = $_SERVER['HTTP_AUTHORIZATION'];
  77. } elseif (isset($_ENV['PHP_AUTH_DIGEST'])) {
  78. $hdr = $_ENV['PHP_AUTH_DIGEST'];
  79. } elseif (isset($_REQUEST['auth'])) {
  80. $hdr = stripslashes(urldecode($_REQUEST['auth']));
  81. } else {
  82. $hdr = null;
  83. }
  84. $digest = substr($hdr,0,7) == 'Digest '
  85. ? substr($hdr, strpos($hdr, ' ') + 1)
  86. : $hdr;
  87. if (!is_null($digest)) {
  88. $hdr = array();
  89. preg_match_all('/(\w+)=(?:"([^"]+)"|([^\s,]+))/', $digest, $mtx, PREG_SET_ORDER);
  90. foreach ($mtx as $m) {
  91. if ($m[1] == "username") {
  92. return $m[2] ? $m[2] : str_replace("\\\"", "", $m[3]);
  93. }
  94. }
  95. }
  96. return $_SERVER['PHP_AUTH_USER'];
  97. }
  98. function git($command, &$output = "") {
  99. global $GIT, $DATA_DIR;
  100. $gitDir = dirname(__FILE__) . "/$DATA_DIR/.git";
  101. $gitWorkTree = dirname(__FILE__) . "/$DATA_DIR";
  102. //$gitCommand = "$GIT --work-tree=$gitWorkTree --git-dir=$gitDir $command";
  103. $gitCommand = "cd $gitWorkTree; $GIT $command";
  104. $output = array();
  105. $result;
  106. // FIXME: Only do the escaping and the 2>&1 if we're not in safe mode
  107. // (otherwise it will be escaped anyway).
  108. // FIXME: Removed escapeShellCmd because it clashed with author.
  109. $oldUMask = umask(0022);
  110. exec($gitCommand . " 2>&1", $output, $result);
  111. $umask = $oldUMask;
  112. // FIXME: The -1 is a hack to avoid 'commit' on an unchanged repo to
  113. // fail.
  114. if ($result != 0) {
  115. // FIXME: HTMLify these strings
  116. print "<h1>Error</h1>\n<pre>\n";
  117. print "$" . $gitCommand . "\n";
  118. print join("\n", $output) . "\n";
  119. //print "Error code: " . $result . "\n";
  120. print "</pre>";
  121. return 0;
  122. }
  123. return 1;
  124. }
  125. function sanitizeName($name) {
  126. return ereg_replace("[^A-Za-z0-9]", "_", $name);
  127. }
  128. function parseResource($resource) {
  129. global $DEFAULT_PAGE;
  130. $matches = array();
  131. $page = "";
  132. $type = "";
  133. if (ereg("(.*)/(.*)", $resource, $matches)) {
  134. $page = sanitizeName($matches[1]);
  135. $type = $matches[2];
  136. }
  137. else if (ereg("(.*)", $resource, $matches)) {
  138. $page = sanitizeName($matches[1]);
  139. }
  140. if ($page == "") {
  141. $page = $DEFAULT_PAGE;
  142. }
  143. if ($type == "") {
  144. $type = "view";
  145. }
  146. return array("page" => $page, "type" => $type);
  147. }
  148. // --------------------------------------------------------------------------
  149. // Wikify
  150. // --------------------------------------------------------------------------
  151. function wikify($text) {
  152. global $SCRIPT_URL;
  153. $text = ($text);
  154. return $text;
  155. }
  156. // --------------------------------------------------------------------------
  157. // Utility functions (for use inside templates)
  158. // --------------------------------------------------------------------------
  159. function getViewURL($page, $version = null) {
  160. global $SCRIPT_URL;
  161. if ($version) {
  162. return "$SCRIPT_URL$page/$version";
  163. }
  164. else {
  165. return "$SCRIPT_URL$page";
  166. }
  167. }
  168. function getPostURL() {
  169. global $SCRIPT_URL;
  170. $page = getPage();
  171. return "$SCRIPT_URL$page";
  172. }
  173. function getEditURL() {
  174. global $SCRIPT_URL;
  175. $page = getPage();
  176. return "$SCRIPT_URL$page/edit";
  177. }
  178. function getHistoryURL() {
  179. global $SCRIPT_URL;
  180. $page = getPage();
  181. return "$SCRIPT_URL$page/history";
  182. }
  183. function getGlobalHistoryURL() {
  184. global $SCRIPT_URL;
  185. return "$SCRIPT_URL/history";
  186. }
  187. function getRemoteRepoPullURL() {
  188. global $SCRIPT_URL;
  189. $page = getPage();
  190. return "$SCRIPT_URL$page/remoterepopull";
  191. }
  192. function getHomeURL() {
  193. global $SCRIPT_URL;
  194. return "$SCRIPT_URL";
  195. }
  196. function getUser() {
  197. global $wikiUser;
  198. return $wikiUser;
  199. }
  200. function getTitle() {
  201. global $TITLE;
  202. return $TITLE;
  203. }
  204. function getPage() {
  205. global $wikiPage;
  206. return $wikiPage;
  207. }
  208. function getCSSURL() {
  209. global $BASE_URL;
  210. return "$BASE_URL/" . getThemeDir() . "/style.css";
  211. }
  212. function getThemeDir() {
  213. global $THEME;
  214. return "themes/$THEME";
  215. }
  216. function getFile() {
  217. global $wikiFile;
  218. return $wikiFile;
  219. }
  220. function getContent() {
  221. global $wikiContent;
  222. return $wikiContent;
  223. }
  224. function getRawData() {
  225. global $wikiData;
  226. return $wikiData;
  227. }
  228. function getMetaTags() {
  229. global $META_TAGS;
  230. return $META_TAGS;
  231. }
  232. function getFooterTags() {
  233. global $FOOTER_TAGS;
  234. return $FOOTER_TAGS;
  235. }
  236. // --------------------------------------------------------------------------
  237. // Initialize globals
  238. // --------------------------------------------------------------------------
  239. $wikiUser = getHTTPUser();
  240. $resource = parseResource($_GET['r']);
  241. $wikiPage = $resource["page"];
  242. $wikiSubPage = $resource["type"];
  243. $wikiFile = $DATA_DIR . "/" . $wikiPage;
  244. // --------------------------------------------------------------------------
  245. // Process request
  246. // --------------------------------------------------------------------------
  247. if (isset($_POST['data'])) {
  248. $string = strtoupper($_SESSION['capstring']);
  249. $userstring = strtoupper($_POST['capuserstring']);
  250. if (($string == $userstring) && (strlen($string) > 4))
  251. {
  252. if (trim($_POST['data']) == "") {
  253. // Delete
  254. if (file_exists($wikiFile)) {
  255. if (!git("rm $wikiPage")) { return; }
  256. $commitMessage = addslashes("Deleted $wikiPage");
  257. $author = addslashes(getAuthorForUser(getUser()));
  258. if (!git("commit --allow-empty --no-verify --message='$commitMessage' --author='$author'")) { return; }
  259. if (!git("gc")) { return; }
  260. if (isset($REMOTE_REPO))
  261. {
  262. if (isset($_POST['pushChanges']) && $_POST['pushChanges'] == 'on')
  263. if (!git("push origin master")) { return; }
  264. }
  265. }
  266. header("Location: $wikiHome");
  267. return;
  268. }
  269. else {
  270. // Save
  271. $handle = fopen($wikiFile, "w");
  272. fputs($handle, stripslashes($_POST['data']));
  273. fclose($handle);
  274. $commitMessage = addslashes("Changed $wikiPage");
  275. $author = addslashes(getAuthorForUser(getUser()));
  276. if (!file_exists(dirname(__FILE__) . "/$DATA_DIR/.git"))
  277. {
  278. // Create repo and initialise
  279. if (!git("init")) { return; }
  280. $handle = fopen(dirname(__FILE__) . "/$DATA_DIR/README", "w");
  281. fputs($handle, "Wigit Pages Git Repo for '$TITLE'");
  282. fclose($handle);
  283. if (!git("add README")) { return; }
  284. if (!git("commit -m 'first commit'")) { return; }
  285. if (isset($REMOTE_REPO))
  286. {
  287. if (!git("remote add origin $REMOTE_REPO")) { return; }
  288. if (!git("push origin master", $out)) { return; }
  289. }
  290. }
  291. if (!git("add $wikiPage")) { return; }
  292. if (!git("commit --allow-empty --no-verify --message='$commitMessage' --author='$author'")) { return; }
  293. if (!git("gc")) { return; }
  294. if (isset($REMOTE_REPO))
  295. {
  296. if (isset($_POST['pushChanges']) && $_POST['pushChanges'] == 'on')
  297. if (!git("push origin master")) { return; }
  298. }
  299. header("Location: " . getViewURL($wikiPage));
  300. return;
  301. }
  302. } else {
  303. // go back to edit
  304. $wikiData = $_POST['data'];
  305. include(getThemeDir() . "/edit.php");
  306. }
  307. }
  308. // Get operation
  309. else {
  310. // remote repo pull
  311. if ($wikiSubPage == "remoterepopull") {
  312. if (isset($REMOTE_REPO)) {
  313. if (!git("pull origin master")) { return; }
  314. header("Location: " . $SCRIPT_URL . $resource["page"] . "/edit");
  315. return;
  316. }
  317. }
  318. // Global history
  319. if ($wikiPage == "history") {
  320. $wikiHistory = getGitHistory();
  321. $wikiPage = "";
  322. include(getThemeDir() . "/history.php");
  323. }
  324. // Viewing
  325. else if ($wikiSubPage == "view") {
  326. if (!file_exists($wikiFile)) {
  327. header("Location: " . $SCRIPT_URL . $resource["page"] . "/edit");
  328. return;
  329. }
  330. // Open the file
  331. $handle = fopen($wikiFile, "r");
  332. $data = fread($handle, filesize($wikiFile));
  333. fclose($handle);
  334. // Put in template
  335. $wikiContent = wikify($data);
  336. include(getThemeDir() . "/view.php");
  337. }
  338. // Editing
  339. else if ($wikiSubPage == "edit") {
  340. if (file_exists($wikiFile)) {
  341. $handle = fopen($wikiFile, "r");
  342. $data = fread($handle, filesize($wikiFile));
  343. }
  344. // Put in template
  345. $wikiData = $data;
  346. include(getThemeDir() . "/edit.php");
  347. }
  348. // History
  349. else if ($wikiSubPage == "history") {
  350. $wikiHistory = getGitHistory($wikiPage);
  351. include(getThemeDir() . "/history.php");
  352. }
  353. // Specific version
  354. else if (eregi("[0-9A-F]{20,20}", $wikiSubPage)) {
  355. $output = array();
  356. if (!git("cat-file -p " . $wikiSubPage . ":$wikiPage", $output)) {
  357. return;
  358. }
  359. $wikiContent = wikify(join("\n", $output));
  360. include(getThemeDir() . "/view.php");
  361. }
  362. else {
  363. print "Unknow subpage: " . $wikiSubPage;
  364. }
  365. }
  366. ?>