PageRenderTime 25ms CodeModel.GetById 17ms RepoModel.GetById 1ms app.codeStats 0ms

/application/controllers/admin/upgrade.php

https://github.com/error10/Ushahidi_Web
PHP | 415 lines | 259 code | 83 blank | 73 comment | 32 complexity | 03d0934e39cfc290601cbbaa7a52f82a MD5 | raw file
  1. <?php defined('SYSPATH') or die('No direct script access.');
  2. /**
  3. * Messages Controller.
  4. * View SMS Messages Received Via FrontlineSMS
  5. *
  6. * PHP version 5
  7. * LICENSE: This source file is subject to LGPL license
  8. * that is available through the world-wide-web at the following URI:
  9. * http://www.gnu.org/copyleft/lesser.html
  10. * @author Ushahidi Team <team@ushahidi.com>
  11. * @package Ushahidi - http://source .ushahididev.com
  12. * @module Admin Messages Controller
  13. * @copyright Ushahidi - http://www.ushahidi.com
  14. * @license http://www.gnu.org/copyleft/lesser.html GNU Lesser General Public License (LGPL)
  15. */
  16. class Upgrade_Controller extends Admin_Controller
  17. {
  18. public $db;
  19. function __construct()
  20. {
  21. parent::__construct();
  22. $this->db = new Database();
  23. $this->template->this_page = 'upgrade';
  24. $upgrade = new Upgrade;
  25. $latest_version = $upgrade->_fetch_core_version();
  26. // limit access to only superadmin
  27. if(!$this->auth->logged_in('superadmin') && $latest_version != "" )
  28. {
  29. url::redirect('admin/dashboard');
  30. }
  31. }
  32. /**
  33. * Upgrade page.
  34. *
  35. */
  36. public function index()
  37. {
  38. $this->template->content = new View('admin/upgrade');
  39. $form_action = "";
  40. $this->template->content->title = Kohana::lang('ui_admin.upgrade_ushahidi');
  41. //check if form has been submitted
  42. if( $_POST ) {
  43. //$upgrade = $this->_do_upgrade();
  44. url::redirect('admin/upgrade/table');
  45. }
  46. $this->template->content->form_action = $form_action;
  47. }
  48. public function table()
  49. {
  50. $this->template->content = new View('admin/upgrade_table');
  51. $this->template->content->title = Kohana::lang('upgrade.upgrade_db_title');
  52. $this->template->content->db_version = Kohana::config('settings.db_version');
  53. //Setup and initialize form fields names
  54. $form = array
  55. (
  56. 'chk_db_backup_box' => ''
  57. );
  58. if( $_POST ) {
  59. // For sanity sake, validate the data received from users.
  60. $post = Validation::factory(array_merge($_POST,$_FILES));
  61. // Add some filters
  62. $post->pre_filter('trim', TRUE);
  63. $post->add_rules('chk_db_backup_box', 'between[0,1]');
  64. if($post->validate()) {
  65. $upgrade = new Upgrade;
  66. $this->template->content = new View('admin/upgrade_status');
  67. $this->template->content->title = Kohana::lang('ui_admin.upgrade_ushahidi_status');
  68. if($post->chk_db_backup_box == 1) {
  69. //uprade tables.
  70. $upgrade->log[] = sprintf("Upgrade table.");
  71. $this->_process_db_upgrade();
  72. $upgrade->log[] = sprintf("Table upgrade successful.");
  73. // backup database.
  74. //is gzip enabled ?
  75. $gzip = Kohana::config('config.output_compression');
  76. $error = $this->_do_db_backup( $gzip );
  77. $upgrade->log[] = sprintf("Database backup in progress");
  78. if( empty( $error ) ) {
  79. $upgrade->log[] = sprintf("Database backup went successful.");
  80. $this->template->content->logs = $upgrade->log;
  81. } else {
  82. $upgrade->errors[] = sprintf("Oops, database backup failed");
  83. $this->template->content->errors = $upgrade->errors;
  84. }
  85. } else {
  86. //uprade tables.
  87. $upgrade->log[] = sprintf("Upgrade table.");
  88. $this->_process_db_upgrade();
  89. $upgrade->log[] = sprintf("Table upgrade successful.");
  90. $this->template->content->logs = $upgrade->log;
  91. }
  92. }
  93. // No! We have validation errors, we need to show the form again, with the errors
  94. else
  95. {
  96. // repopulate the form fields
  97. $form = arr::overwrite($form, $post->as_array());
  98. // populate the error fields, if any
  99. $errors = arr::overwrite($errors, $post->errors('upgrade'));
  100. $form_error = TRUE;
  101. }
  102. }
  103. }
  104. public function status()
  105. {
  106. $this->template->content = new View('admin/upgrade_status');
  107. $this->template->cntent = Kohana::lang('upgrade.upgrade_status');
  108. if( count( $upgrade->errors ) == 0 ) {
  109. $this->template->content->title = Kohana::lang('ui_admin.upgrade_ushahidi_status');
  110. $this->template->content->logs = $upgrade->log;
  111. }else{
  112. $this->template->content->title = Kohana::lang('ui_admin.upgrade_ushahidi_status');
  113. $this->template->content->errors = $upgrade->errors;
  114. }
  115. }
  116. private function _upgrade_tables() {
  117. $db_schema = file_get_contents( 'sql/upgrade.sql' );
  118. $result = "";
  119. // get individual sql statement
  120. $sql_statements = explode( ';',$db_schema );
  121. foreach( $sql_statements as $sql_statement ) {
  122. $result = $this->db->query( $sql_statement );
  123. }
  124. return $result;
  125. }
  126. /**
  127. *
  128. * Downloads the latest ushahidi file.
  129. * Extracts the compressed folder.
  130. * Delete the folders that needs to be preserved.
  131. * Delete the downloaded ushahidi file.
  132. * Delete the extracted ushahidi folder.
  133. *
  134. */
  135. private function _do_upgrade()
  136. {
  137. $upgrade = new Upgrade;
  138. $url = "http://download.ushahidi.com/ushahidi.zip";
  139. $working_dir = Kohana::config('upload.relative_directory')."/";
  140. $zip_file = Kohana::config('upload.relative_directory')."/ushahidi.zip";
  141. //download the latest ushahidi
  142. $latest_ushahidi = $upgrade->download_ushahidi($url);
  143. //download went successful
  144. if( $upgrade->success ) {
  145. $upgrade->write_to_file($latest_ushahidi, $zip_file);
  146. }
  147. //extract compressed file
  148. if( $upgrade->success ) {
  149. $upgrade->unzip_ushahidi($zip_file, $working_dir);
  150. }
  151. if( $upgrade->success ) {
  152. //remove delete database.php and config.php files. we don't want to overwrite them.
  153. unlink($working_dir."ushahidi/application/config/database.php");
  154. unlink($working_dir."ushahidi/application/config/config.php");
  155. $upgrade->remove_recursively($working_dir."ushahidi/application/cache");
  156. $upgrade->remove_recursively($working_dir."ushahidi/application/logs");
  157. $upgrade->remove_recursively($working_dir."ushahidi/".Kohana::config('upload.relative_directory'));
  158. }
  159. if( $upgrade->success ) {
  160. $upgrade->log[] = sprintf("Copying files...");
  161. $upgrade->copy_recursively($working_dir."ushahidi",".");
  162. $upgrade->log[] = sprintf("Successfully copied files");
  163. }
  164. if( $upgrade->success ) {
  165. $upgrade->log[] = sprintf("Upgrading tables...");
  166. if( $this->_upgrade_tables() ) {
  167. $upgrade->log[] = sprintf("Tables upgrade went successful");
  168. } else {
  169. $upgrade->errors[] = sprintf("Tables upgrade failed");
  170. }
  171. }
  172. if( $upgrade->success ) {
  173. $upgrade->remove_recursively( $working_dir."ushahidi" );
  174. unlink($zip_file);
  175. $upgrade->log[] = sprintf( "Upgrade went successful." );
  176. }
  177. return $upgrade;
  178. }
  179. /**
  180. * Execute SQL statement to upgrade the necessary tables.
  181. *
  182. * @param string - upgrade_sql - upgrade sql file
  183. */
  184. private function _execute_upgrade_script( $upgrade_sql )
  185. {
  186. $upgrade_schema = @file_get_contents( 'sql/'.$upgrade_sql );
  187. // If a table prefix is specified, add it to sql
  188. $db_config = Kohana::config('database.default');
  189. $table_prefix = $db_config['table_prefix'];
  190. if ( $table_prefix )
  191. {
  192. $find = array(
  193. 'CREATE TABLE IF NOT EXISTS `',
  194. 'INSERT INTO `',
  195. 'ALTER TABLE `',
  196. 'UPDATE `'
  197. );
  198. $replace = array(
  199. 'CREATE TABLE IF NOT EXISTS `'.$table_prefix.'_',
  200. 'INSERT INTO `'.$table_prefix.'_',
  201. 'ALTER TABLE `'.$table_prefix.'_',
  202. 'UPDATE `'.$table_prefix.'_'
  203. );
  204. $upgrade_schema = str_replace($find, $replace, $upgrade_schema);
  205. }
  206. // Split by ; to get the sql statement for creating individual tables.
  207. $queries = explode( ';',$upgrade_schema );
  208. // get the database object.
  209. foreach ( $queries as $query )
  210. {
  211. $result = $this->db->query( $query );
  212. }
  213. // Delete cache
  214. $cache = Cache::instance();
  215. $cache->delete(Kohana::config('settings.subdomain').'_settings');
  216. }
  217. /**
  218. * Get the available sql update scripts from the
  219. * sql folder then upgrade necessary tables.
  220. */
  221. private function _process_db_upgrade()
  222. {
  223. $dir_path = 'sql';
  224. $upgrade_sql = '';
  225. $files = scandir($dir_path);
  226. foreach( $files as $file ) {
  227. $upgrade_sql = $this->_get_db_version();
  228. if( $upgrade_sql == $file ) {
  229. $this->_execute_upgrade_script( $upgrade_sql );
  230. }
  231. }
  232. return "";
  233. }
  234. /**
  235. * Gets the current db version of the ushahidi deployment.
  236. *
  237. * @return the db version.
  238. */
  239. private function _get_db_version()
  240. {
  241. // get the db version from the settings page
  242. $db = new Database();
  243. $sql = 'SELECT db_version from '.Kohana::config('database.default.table_prefix').'settings';
  244. $settings = $db->query($sql);
  245. $version_in_db = $settings[0]->db_version;
  246. // Update DB
  247. $db_version = $version_in_db;
  248. $upgrade_to = $db_version + 1;
  249. return 'upgrade'.$db_version.'-'.$upgrade_to.'.sql';
  250. }
  251. /**
  252. * See if mysqldump exist, then detect its installed path.
  253. *
  254. * Most of the code here were borrowed from
  255. * @return (array) $paths - include mysql and mysqldump application's path.
  256. */
  257. private function _detect_mysql()
  258. {
  259. $paths = array('mysql' => '', 'mysqldump' => '');
  260. //check for platform
  261. if(substr(PHP_OS,0,3) == 'WIN') {
  262. $result = mysql_query("SHOW VARIABLES LIKE 'basedir'");
  263. $mysql_install = mysql_fetch_array($result);
  264. if( is_array($mysql_install) && sizeof($mysql_install)>0 ) {
  265. $install_path = str_replace('\\', '/', $mysql_install[0]->Value);
  266. $paths['mysql'] = $install_path.'bin/mysql.exe';
  267. $paths['mysqldump'] = $install_path.'bin/mysqldump.exe';
  268. } else {
  269. $paths['mysql'] = 'mysql.exe';
  270. $paths['mysqldump'] = 'mysqldump.exe';
  271. }
  272. } else {
  273. if(function_exists('exec')) {
  274. $paths['mysql'] = @exec('which mysql');
  275. $paths['mysqldump'] = @exec('which mysqldump');
  276. } else {
  277. $paths['mysql'] = 'mysql';
  278. $paths['mysqldump'] = 'mysqldump';
  279. }
  280. return $paths;
  281. }
  282. }
  283. /**
  284. * Backup database
  285. *
  286. * @param boolean - gzip - set to false by default
  287. *
  288. * @return void or error message
  289. */
  290. private function _do_db_backup( $gzip=FALSE )
  291. {
  292. $mysql_path = $this->_detect_mysql();
  293. $backup = array();
  294. $backup += $mysql_path;
  295. $backup['user'] = Kohana::config('database.default.connection.user');
  296. $backup['host'] = Kohana::config('database.default.connection.host');
  297. $backup['database'] = Kohana::config('database.default.connection.database');
  298. $backup['password'] = Kohana::config('database.default.connection.password');
  299. $backup['date'] = time();
  300. $backup['filepath'] = preg_replace('/\//', '/', Kohana::config('upload.relative_directory'));
  301. $backup['filename'] = $backup['filepath'].'/'.$backup['date'].'_-_'.'backup.sql';
  302. if ( $gzip ) {
  303. $backup['filename'] = $backup['filename'].'.gz';
  304. $command = $backup['mysqldump'].' --host="'.$backup['host'].'" --user="'.$backup['user'].'" --password="'.$backup['password'].'" --add-drop-table --skip-lock-tables '.$backup['database'].' | gzip > '.$backup['filename'];
  305. }
  306. else
  307. {
  308. $backup['filename'] = $backup['filename'];
  309. $command = $backup['mysqldump'].' --host="'.$backup['host'].'" --user="'.$backup['user'].'" --password="'.$backup['password'].'" --add-drop-table --skip-lock-tables '.$backup['database'].' > '.$backup['filename'];
  310. }
  311. //Execute mysqldump command
  312. if(substr(PHP_OS, 0, 3) == 'WIN') {
  313. $writable_dir = $backup['filepath'];
  314. $tmpnam = $writable_dir.'/backup_script.sql';
  315. $fp = fopen($tmpnam, 'w');
  316. fwrite($fp, $command);
  317. fclose($fp);
  318. system($tmpnam.' > NUL', $error);
  319. unlink($tmpnam);
  320. } else {
  321. passthru($command, $error);
  322. }
  323. return $error;
  324. }
  325. }