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

/www/admin/upgrade.php

http://wquiz.googlecode.com/
PHP | 346 lines | 185 code | 61 blank | 100 comment | 32 complexity | 7ca0017c511588a50ab827a0893176d1 MD5 | raw file
Possible License(s): GPL-3.0
  1. <?php
  2. /* Upgrade from version 0.3.* (from perl to PHP version) */
  3. /** Copyright Information (GPL 3)
  4. Copyright Stewart Watkiss 2012
  5. This file is part of wQuiz.
  6. wQuiz is free software: you can redistribute it and/or modify
  7. it under the terms of the GNU General Public License as published by
  8. the Free Software Foundation, either version 3 of the License, or
  9. (at your option) any later version.
  10. wQuiz is distributed in the hope that it will be useful,
  11. but WITHOUT ANY WARRANTY; without even the implied warranty of
  12. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  13. GNU General Public License for more details.
  14. You should have received a copy of the GNU General Public License
  15. along with wQuiz. If not, see <http://www.gnu.org/licenses/>.
  16. **/
  17. /*$debug = false;
  18. // Enable debugging
  19. error_reporting(E_ALL);
  20. ini_set('display_errors', true);*/
  21. // adminsetup is within the admin directory - this will load the main setup.php as well
  22. require_once ("adminsetup.php");
  23. // message is used to provide feedback to the user
  24. //eg. if we get here from an expired session
  25. $message = '';
  26. // Authentication class required for admin functions
  27. require_once($include_dir."SimpleAuth.php");
  28. // add this here as not required for some pages (which use Quiz.php instead)
  29. require_once ($include_dir."Quizzes.php");
  30. // must add this before we require the menu
  31. $admin_menu = 'home';
  32. /*** Authentication ***/
  33. // user must be logged in for any admin functions
  34. // this needs to be before we output anything as it uses sessions (cookies)
  35. $auth = new SimpleAuth ($settings->getSetting('admin_login_username'), $settings->getSetting('admin_login_password'), $settings->getSetting('admin_login_expirytime'));
  36. // if not logged in redirect to login page
  37. $status = $auth->checkLogin();
  38. if ($status != 1)
  39. {
  40. // no from as use default which goes back to this page
  41. header("Location: ".ADMIN_LOGIN_FILE."?status=$status&location=aupgrade");
  42. // header will redirect to a new page so we just close this script
  43. exit (0); //Important to stop script here
  44. }
  45. // If we reach here then login was successful
  46. $sessionUsername = $auth->getUser();
  47. // Have we get the filename of the old version in the post
  48. if (isset($_POST['oldfile']) && $_POST['oldfile']!="")
  49. {
  50. $oldfile = $_POST['oldfile'];
  51. // check that the file exists
  52. if (!file_exists($oldfile)) {printMenu("File does not exist - please try again"); exit(0);}
  53. // open file and read in appropriate entries
  54. if (!$ofh = fopen ($oldfile, "r")) {printMenu("Unable to read from file"); exit (0);}
  55. while ($this_line = fgets($ofh))
  56. {
  57. // get appropriate entries
  58. /**** WARNING - when reading below code perl variable names are used within php array
  59. /* this means $dbname (perl variable) is shown as a string '$dbname' ****/
  60. // database (previous version only supported mysql so look for the DBI string)
  61. if (preg_match ('/\$dbname\s?\=\s?"DBI:mysql:([\w_-]+):([\.\w_-]+)";/', $this_line, $matches))
  62. {
  63. // old entries are not used for database access - but are required for validation check
  64. $old_entries['$dbname'] = $matches[1];
  65. $old_entries['$dbhost'] = $matches[2];
  66. // database entries to access old db
  67. $old_db_entries['hostname'] = $matches[2];
  68. $old_db_entries['database'] = $matches[1];
  69. }
  70. elseif (preg_match ('/\$dbuser\s?=\s?"(\w+)";/', $this_line, $matches))
  71. {
  72. $old_entries['$dbuser'] = $matches[1];
  73. // database username
  74. $old_db_entries['username'] = $matches[1];
  75. }
  76. elseif (preg_match ('/\$dbpass\s?=\s?"(\w+)";/', $this_line, $matches))
  77. {
  78. $old_entries['$dbpass'] = $matches[1];
  79. // database password
  80. $old_db_entries['password'] = $matches[1];
  81. }
  82. elseif (preg_match ('/\$dbtable\s?=\s?"(\w+)";/', $this_line, $matches))
  83. {
  84. $old_entries['$dbtable'] = $matches[1];
  85. }
  86. // quizzes - all entries must be on a single line - may need to edit %quizintro line to reflect that
  87. elseif (preg_match ('/%quiznames\s?=\s?\(([^)]*)\);/', $this_line, $matches))
  88. {
  89. // don't breakout into individual entries at this stage
  90. $old_entries['%quiznames'] = $matches[1];
  91. }
  92. elseif (preg_match ('/%numquestions\s?=\s?\(([^)]*)\);/', $this_line, $matches))
  93. {
  94. // don't breakout into individual entries at this stage
  95. $old_entries['%numquestions'] = $matches[1];
  96. }
  97. elseif (preg_match ('/%quizintro\s?=\s?\((.*)\);/', $this_line, $matches))
  98. {
  99. // don't breakout into individual entries at this stage
  100. $old_entries['%quizintro'] = $matches[1];
  101. }
  102. // general settings
  103. elseif (preg_match ('/\$offlinequiz\s?=\s?(\d)\s?;/', $this_line, $matches))
  104. {
  105. $old_entries['$offlinequiz'] = $matches[1];
  106. }
  107. }
  108. //if ($debug) {print "Old dbname = ".$matches[1]."\n";}
  109. // check that we have all the important entries
  110. $db_entries_required = array('$dbname', '$dbhost', '$dbuser', '$dbpass', '$dbtable', '%quiznames', '%numquestions', '%quizintro');
  111. foreach ($db_entries_required as $this_db_entry)
  112. {
  113. if (!isset($old_entries[$this_db_entry]) || $old_entries[$this_db_entry] == '')
  114. {
  115. // %<variable> and $<variable> will be shown as $variable - minor bug
  116. printMenu ("Unable to find entry $this_db_entry in the old quiz.cfg file<br />\nPlease check it exists and is on a single line.");
  117. exit (0);
  118. }
  119. //if ($debug) {print "$this_db_entry is ".$old_entries[$this_db_entry]."\n";}
  120. }
  121. $quiznames = splitPerlHash ($old_entries['%quiznames']);
  122. //if ($debug) {print "Quiz names:<br />\n"; print_r ($quiznames);}
  123. $numquestions = splitPerlHash ($old_entries['%numquestions']);
  124. //if ($debug) {print "Num questions:<br />\n"; print_r ($numquestions);}
  125. $quizintro = splitPerlHash ($old_entries['%quizintro']);
  126. //if ($debug) {print "Quiz intro:<br />\n"; print_r ($quizintro);}
  127. // Finished reading the config file
  128. // Create quiz entries if don't already exist
  129. // Load existing quizzes
  130. $all_quizzes = new Quizzes();
  131. $quiz_array = $qdb->getQuizzesAll();
  132. // add this one to allQuizzes
  133. foreach ($quiz_array as $this_quiz_array)
  134. {
  135. $all_quizzes->addQuiz(new Quiz($this_quiz_array));
  136. }
  137. if ($debug) {print "Checking for new quizzes <br />\n";}
  138. // Now look at old quiznames and check if they exist
  139. // use the validateQuizname function on the $all_quizzes
  140. foreach ($quiznames as $key=>$value)
  141. {
  142. // not found so create
  143. if ($all_quizzes->validateQuizname($key) == false)
  144. {
  145. if ($debug) {print "New quiz found $key <br />\n";}
  146. $new_quiz = array();
  147. // use new_quizname as well as the array to make it easier to follow (rather than nesting arrays)
  148. $new_quizname = $new_quiz['quizname'] = $key;
  149. $new_quiz['title'] = $quiznames[$new_quizname];
  150. $new_quiz['numquestions'] = $numquestions[$new_quizname];
  151. // offline quiz was not set on a per quiz basis on old version
  152. // set the same as online and then use enable to turn on / off
  153. $new_quiz['numquestionsoffline'] = $new_quiz['numquestions'];
  154. $new_quiz['quizintro'] = $quizintro[$new_quizname];
  155. // priority is a new setting
  156. $new_quiz['priority'] = 1;
  157. // if offline previously enabled then set appropriate - otherwise set to disabled
  158. if (isset($old_entries['$offlinequiz']) && ($old_entries['$offlinequiz'] == 1))
  159. {
  160. $new_quiz['enableoffline'] = true;
  161. }
  162. else
  163. {
  164. $new_quiz['enableoffline'] = false;
  165. }
  166. // online is always enabled
  167. $new_quiz['enableonline'] = true;
  168. /* Save new entry */
  169. $qdb->addQuiz($new_quiz);
  170. // we do not add to the array instead we will reload the quizzes once complete
  171. }
  172. }
  173. // re initialise array by reloading entries
  174. $all_quizzes = new Quizzes();
  175. $quiz_array = array();
  176. $quiz_array = $qdb->getQuizzesAll();
  177. // add this one to allQuizzes
  178. foreach ($quiz_array as $this_quiz_array)
  179. {
  180. $all_quizzes->addQuiz(new Quiz($this_quiz_array));
  181. }
  182. /*** Load questions from old database and store in new database ***/
  183. // Connect to the old database
  184. $olddb = new Database($old_db_entries);
  185. if ($db->getStatus() != 1) {die ("Unable to connect to database ".$old_db_entries['hostname']." ".$old_db_entries['database']);}
  186. // create sql to load questions
  187. $old_sql = "SELECT * from ".$old_entries['$dbtable'];
  188. // Loads all questions - note that this requires a significant
  189. // amount of available memory - depending upon the number of questions and php settings
  190. // If this fails due to insufficient memory then check memory_limit in php.ini
  191. // Questions take up very little memory in the database so it would need to be a very large number of questions to be of concern
  192. $old_questions_array = $olddb->getRowsAll($old_sql);
  193. foreach ($old_questions_array as $this_question)
  194. {
  195. // create new question
  196. $this_questionid = $qdb->addQuestion($this_question);
  197. if ($debug) {print "Quizzes are ".$this_question['quiz']."<br />\n\n";}
  198. $this_question_quizzes = explode (',', $this_question['quiz']);
  199. if (!empty($this_question_quizzes))
  200. {
  201. foreach ($this_question_quizzes as $this_quiz)
  202. {
  203. if ($debug) {print "Adding $this_quiz<br />\n";}
  204. $qdb->addQuestionQuiz($this_quiz, $this_questionid);
  205. }
  206. }
  207. }
  208. //complete - confirm to user
  209. $templates->includeTemplate('header', 'admin');
  210. $admin_file = ADMIN_FILE;
  211. print <<< EOT
  212. <h1>Upgrade complete</h1>
  213. <p>The upgrade is complete. <a href="$admin_file">Go to admin index page</a>.</p>
  214. EOT;
  215. $templates->includeTemplate('footer', 'admin');
  216. }
  217. else
  218. {
  219. printMenu('');
  220. }
  221. function printMenu ($message)
  222. {
  223. global $templates;
  224. // header template
  225. $templates->includeTemplate('header', 'admin');
  226. if ($message != "") {$message = "<p>$message</p>";}
  227. $main_css = CSS_ID_ADMIN_MAIN;
  228. print <<< EOT
  229. <div id="$main_css">
  230. <h1>Administration</h1>
  231. <h2>Upgrade from 0.3.*</h2>
  232. $message
  233. <p>
  234. Please provide the full path on the local filesystem to the old config file<br />
  235. (eg. /var/www/cgi-bin/quiz/quiz.cfg)
  236. </p>
  237. <form method="post" action="">
  238. <input type="text" name="oldfile" value=""></input><br />
  239. <input type="submit" value="upgrade">
  240. </form>
  241. </div>
  242. EOT;
  243. // footer template
  244. $templates->includeTemplate('footer', 'admin');
  245. }
  246. // splits a perl hash array into indvidual components
  247. // recursive function
  248. // array must uses either '' or "" around the key and value (value if strings only)
  249. function splitPerlHash($in_array)
  250. {
  251. global $debug;
  252. $this_array = array();
  253. //if ($debug) {print "in entries : $in_array";}
  254. // make a temp substitution to get around the \" error (if that's included in the string then it matches on the regexp at the wrong point) - we then substitute back later
  255. // bit of a hack, but should not have these strings in normally
  256. $in_array = preg_replace ('/\\\"/', '##2', $in_array);
  257. $in_array = preg_replace ("/\\\'/", '##1', $in_array);
  258. // first look for string, second match looks for number (ie no quotes around it)
  259. // This will not work if the original quote marker is used within the string (even if escaped)
  260. // intentionally added an extra bracket set in the second as we don't need to use back references, but still need to have the same number of matches
  261. if (preg_match ('/(["\'])([^\1]+?)\1\s*=>\s*(["\'])([^\3]+?)\3\s*,?\s*(.*)/', $in_array, $matches) || preg_match ('/(["\'])([^\1]+?)\1\s*=>(\s*)(\d+)\s*,?\s*(.*)/', $in_array, $matches))
  262. {
  263. //if ($debug) {print "matches found : \n"; print_r ($matches);}
  264. $key = $matches[2];
  265. $value = $matches[4];
  266. $remaining = $matches[5];
  267. // substitute replacements back
  268. $value = preg_replace ("/##1/", "\\\'", $value);
  269. $value = preg_replace ("/##2/", '\\\"', $value);
  270. $this_array[$key] = $value;
  271. if ($remaining != '')
  272. {
  273. // Call self
  274. $returned_array = splitPerlHash($remaining);
  275. if (isset($returned_array) && !empty($returned_array)) {$this_array = array_merge ($this_array, $returned_array);}
  276. }
  277. }
  278. return $this_array;
  279. }
  280. ?>