PageRenderTime 38ms CodeModel.GetById 14ms RepoModel.GetById 1ms app.codeStats 0ms

/application/libraries/Upgrade.php

https://github.com/yamamoto123/Ushahidi_Web
PHP | 553 lines | 453 code | 42 blank | 58 comment | 46 complexity | 999ff85b01a4a354a734386968c40b0d MD5 | raw file
  1. <?php defined('SYSPATH') OR die('No direct access allowed.');
  2. /**
  3. * Upgrading Library
  4. * Provides the necessary functions to do the automatic upgrade
  5. *
  6. * @package Upgrade
  7. * @author Ushahidi Team
  8. * @copyright (c) 2008 Ushahidi Team
  9. * @license http://www.ushahidi.com/license.html
  10. */
  11. class Upgrade
  12. {
  13. public $notices;
  14. public $errors;
  15. public $success;
  16. public $error_level;
  17. public $session;
  18. public $ftp;
  19. public $ftp_server;
  20. public $ftp_user_name;
  21. public $ftp_user_pass;
  22. public function __construct()
  23. {
  24. $this->log = array();
  25. $this->errors = array();
  26. $this->error_level = ini_get('error_reporting');
  27. $this->session = Session::instance();
  28. if ( ! $this->session->get('upgrade_session'))
  29. {
  30. $this->session->set('upgrade_session', date("Y_m_d-H_i_s"));
  31. }
  32. }
  33. /**
  34. * Fetches ushahidi from download.ushahidi.com
  35. *
  36. * @param String url-- download URL
  37. */
  38. public function download_ushahidi($url) {
  39. $snoopy = new Snoopy();
  40. $snoopy->agent = Kohana::lang('libraries.upgrade_title');
  41. $snoopy->read_timeout = 30;
  42. $snoopy->gzip = false;
  43. $snoopy->fetch($url);
  44. $this->log[] = "Starting to download the latest ushahidi build...";
  45. if ( $snoopy->status == '200' )
  46. {
  47. $this->log[] = "Download of latest ushahidi went successful.";
  48. $this->success = true;
  49. return $snoopy->results;
  50. }
  51. else
  52. {
  53. $this->errors[] = sprintf(Kohana::lang('libraries.upgrade_failed').": %d", $snoopy->status);
  54. $this->success = false;
  55. return $snoopy;
  56. }
  57. }
  58. /**
  59. * FTP files recursively.
  60. *
  61. * @param String source-- the source directory.
  62. * @param String dest -- the destination directory.
  63. * @param $options //folderPermission,filePermission
  64. * @return boolean
  65. */
  66. function ftp_recursively($source, $dest, $options=array('folderPermission'=>0775,'filePermission'=>0664))
  67. {
  68. if ( ! $this->ftp_connect() )
  69. {
  70. $this->success = false;
  71. return false;
  72. }
  73. if ( ! $ftp_base_path = $this->ftp_base_path())
  74. {
  75. $this->success = false;
  76. return false;
  77. }
  78. $this->ftp->chdir($ftp_base_path);
  79. if (is_file($source))
  80. {
  81. $__dest=$dest;
  82. // Turn off error reporting temporarily
  83. error_reporting(0);
  84. $result = $this->ftp_copy($source, $__dest, $options);
  85. if ($result)
  86. {
  87. $this->success = true;
  88. $this->logger("Copied to ".$__dest);
  89. //Turn on error reporting again
  90. error_reporting($this->error_level);
  91. }
  92. else
  93. {
  94. $this->success = false;
  95. $this->logger("** Failed writing ".$__dest);
  96. //Turn on error reporting again
  97. error_reporting($this->error_level);
  98. return false;
  99. }
  100. }
  101. elseif(is_dir($source))
  102. {
  103. if ($dest[strlen($dest)-1] == '/')
  104. {
  105. if ($source[strlen($source)-1] == '/')
  106. {
  107. //Copy only contents
  108. }
  109. else
  110. {
  111. //Change parent itself and its contents
  112. $dest = $dest.basename($source);
  113. if ( ! $this->ftp->mkdir(str_replace(DOCROOT,"",$dest)))
  114. {
  115. $this->logger("** Failed creating directory ".$dest.". It might already exist.");
  116. }
  117. else
  118. {
  119. $this->logger("Created directory ".$dest);
  120. }
  121. $this->ftp->chmod(str_replace(DOCROOT,"",$dest),$options['folderPermission']);
  122. }
  123. }
  124. else
  125. {
  126. if ($source[strlen($source)-1] == '/')
  127. {
  128. //Copy parent directory with new name and all its content
  129. if ( ! $this->ftp->mkdir(str_replace(DOCROOT,"",$dest)))
  130. {
  131. $this->logger("** Failed creating directory ".$dest.". It might already exist.");
  132. }
  133. else
  134. {
  135. $this->logger("Created directory ".$dest);
  136. }
  137. $this->ftp->chmod(str_replace(DOCROOT,"",$dest),$options['folderPermission']);
  138. }
  139. else
  140. {
  141. //Copy parent directory with new name and all its content
  142. if ( ! $this->ftp->mkdir(str_replace(DOCROOT,"",$dest)))
  143. {
  144. $this->logger("** Failed creating directory ".$dest.". It might already exist.");
  145. }
  146. else
  147. {
  148. $this->logger("Created directory ".$dest);
  149. }
  150. $this->ftp->chmod(str_replace(DOCROOT,"",$dest),$options['folderPermission']);
  151. }
  152. }
  153. $dirHandle=opendir($source);
  154. while($file=readdir($dirHandle))
  155. {
  156. if($file != "." AND $file != ".." AND substr($file, 0, 1) != '.')
  157. {
  158. if( ! is_dir($source."/".$file))
  159. {
  160. $__dest=$dest."/".$file;
  161. $__dest=str_replace("//", "/", $__dest);
  162. }
  163. else
  164. {
  165. $__dest=$dest."/".$file;
  166. $__dest=str_replace("//", "/", $__dest);
  167. }
  168. $source_file = $source."/".$file;
  169. $source_file = str_replace("//", "/", $source_file);
  170. $result = $this->ftp_recursively($source_file, $__dest, $options);
  171. }
  172. }
  173. closedir($dirHandle);
  174. }
  175. }
  176. function ftp_connect()
  177. {
  178. //** temporary
  179. $this->ftp_server = $this->session->get('ftp_server');
  180. $this->ftp_user_name = $this->session->get('ftp_user_name');
  181. $this->ftp_user_pass = $this->session->get('ftp_user_pass');
  182. // Turn off error reporting temporarily
  183. //error_reporting(0);
  184. $ftp_init = new PemFtp();
  185. $this->ftp = new ftp();
  186. if ( ! $this->ftp_server OR
  187. ! $this->ftp_user_name OR
  188. ! $this->ftp_user_pass)
  189. {
  190. // Failed Connecting
  191. $this->logger("** Can't connect to FTP Server. Server, Username and/or Password not specified.");
  192. error_reporting($this->error_level);
  193. return false;
  194. }
  195. // Set FTP Server
  196. if ( ! $this->ftp->SetServer($this->ftp_server))
  197. {
  198. // Failed Connecting
  199. $this->logger("** Can't connect to FTP Server");
  200. error_reporting($this->error_level);
  201. return false;
  202. }
  203. // Connect to FTP Server
  204. if ( ! $this->ftp->connect() )
  205. {
  206. // Failed Connecting
  207. $this->logger("** Can't connect to FTP Server");
  208. error_reporting($this->error_level);
  209. return false;
  210. }
  211. // Authenticate at FTP Server
  212. if ( ! $this->ftp->login($this->ftp_user_name, $this->ftp_user_pass) )
  213. {
  214. // Failed Connecting
  215. $this->logger("** Can't connect to FTP Server - Incorrect Username or Password");
  216. error_reporting($this->error_level);
  217. return false;
  218. }
  219. $this->ftp->setTimeout(30);
  220. $this->ftp->SetType(-1);
  221. $this->ftp->Passive(true);
  222. error_reporting($this->error_level);
  223. return true;
  224. }
  225. function ftp_base_path()
  226. {
  227. $absolute_parts = explode('/', DOCROOT);
  228. $ushahidi_folder = end($absolute_parts);
  229. $ftp_parts = $this->ftp->nlist();
  230. // Are we already in the Ushahidi directory?
  231. if ($this->ftp->is_exists("application/config/config.php"))
  232. {
  233. return "./";
  234. }
  235. // We'll cycle through both to find out which
  236. // part of the DOCROOT we're in
  237. $ftp_base = "";
  238. foreach ($absolute_parts as $part)
  239. {
  240. foreach ($ftp_parts as $key => $value)
  241. {
  242. if ($value == $part)
  243. {
  244. $ftp_base .= $value."/";
  245. if ($this->ftp->is_exists($ftp_base."application/config/config.php"))
  246. { // We've arrived at the right folder
  247. break;
  248. }
  249. }
  250. }
  251. }
  252. // Verify once again that we're in the right directory
  253. if ($this->ftp->is_exists($ftp_base."application/config/config.php"))
  254. { // We've arrived at the right folder
  255. return $ftp_base;
  256. }
  257. else
  258. {
  259. return false;
  260. }
  261. }
  262. function ftp_copy($source, $dest, $options)
  263. {
  264. $dest = str_replace(DOCROOT,"",$dest);
  265. if ( ! $this->ftp->put($source, $dest) )
  266. {
  267. return false;
  268. }
  269. $this->ftp->chmod($dest,$options['filePermission']);
  270. return true;
  271. }
  272. /**
  273. * Copy files recursively.
  274. *
  275. * @param String source-- the source directory.
  276. * @param String dest -- the destination directory.
  277. * @param $options //folderPermission,filePermission
  278. * @return boolean
  279. */
  280. function copy_recursively($source, $dest, $options=array('folderPermission'=>0755,'filePermission'=>0755))
  281. {
  282. if (is_file($source)) {
  283. if ($dest[strlen($dest)-1]=='/')
  284. {
  285. if (!file_exists($dest))
  286. {
  287. cmfcDirectory::makeAll($dest,$options['folderPermission'],true);
  288. }
  289. $__dest = $dest."/".basename($source);
  290. }
  291. else
  292. {
  293. $__dest=$dest;
  294. }
  295. // Turn off error reporting temporarily
  296. error_reporting(0);
  297. $result = copy($source, $__dest);
  298. if ($result)
  299. {
  300. chmod($__dest,$options['filePermission']);
  301. $this->success = true;
  302. $this->logger("Copied to ".$__dest);
  303. //Turn on error reporting again
  304. error_reporting($this->error_level);
  305. }
  306. else
  307. {
  308. $this->success = false;
  309. $this->logger("** Failed writing ".$__dest);
  310. //Turn on error reporting again
  311. error_reporting($this->error_level);
  312. return false;
  313. }
  314. }
  315. elseif(is_dir($source))
  316. {
  317. if ($dest[strlen($dest)-1] == '/')
  318. {
  319. if ($source[strlen($source)-1] == '/')
  320. {
  321. //Copy only contents
  322. }
  323. else
  324. {
  325. //Change parent itself and its contents
  326. $dest = $dest.basename($source);
  327. if ( ! is_writable($dest))
  328. {
  329. $this->success = false;
  330. $this->logger("** Can't write to ".$dest);
  331. return false;
  332. }
  333. @mkdir($dest);
  334. chmod($dest,$options['filePermission']);
  335. }
  336. }
  337. else
  338. {
  339. if ( ! is_writable($dest))
  340. {
  341. $this->success = false;
  342. $this->logger("** Can't write to ".$dest);
  343. return false;
  344. }
  345. if ($source[strlen($source)-1] == '/')
  346. {
  347. //Copy parent directory with new name and all its content
  348. @mkdir($dest,$options['folderPermission']);
  349. chmod($dest,$options['filePermission']);
  350. }
  351. else
  352. {
  353. //Copy parent directory with new name and all its content
  354. @mkdir($dest,$options['folderPermission']);
  355. chmod($dest,$options['filePermission']);
  356. }
  357. }
  358. $dirHandle=opendir($source);
  359. while($file=readdir($dirHandle))
  360. {
  361. if($file!="." AND $file!=".." AND substr($file, 0, 1) != '.')
  362. {
  363. if(!is_dir($source."/".$file))
  364. {
  365. $__dest=$dest."/".$file;
  366. }
  367. else
  368. {
  369. $__dest=$dest."/".$file;
  370. }
  371. //echo "$source/$file ||| $__dest<br />";
  372. if ( ! is_writable($__dest))
  373. {
  374. $this->success = false;
  375. $this->logger("** Can't write to - ".$__dest);
  376. return false;
  377. }
  378. $result = $this->copy_recursively($source."/".$file, $__dest, $options);
  379. }
  380. }
  381. closedir($dirHandle);
  382. }
  383. }
  384. /**
  385. * Remove files recursively.
  386. *
  387. * @param String dir-- the directory to delete.
  388. */
  389. public function remove_recursively($dir)
  390. {
  391. if (empty($dir) || !is_dir($dir))
  392. return false;
  393. if (substr($dir,-1) != "/")
  394. $dir .= "/";
  395. if (($dh = opendir($dir)) !== false) {
  396. while (($entry = readdir($dh)) !== false) {
  397. if ($entry != "." && $entry != "..") {
  398. if ( is_file($dir . $entry) ) {
  399. if ( !@unlink($dir . $entry) ) {
  400. $this->errors[] = sprintf(Kohana::lang('libraries.upgrade_file_not_deleted'), $dir.$entry );
  401. $this->success = false;
  402. }
  403. } elseif (is_dir($dir . $entry)) {
  404. $this->remove_recursively($dir . $entry);
  405. $this->success = true;
  406. }
  407. }
  408. }
  409. closedir($dh);
  410. if ( !@rmdir($dir) ) {
  411. $this->errors[] = sprintf(Kohana::lang('libraries.upgrade_directory_not_deleted'), $dir.$entry);
  412. $this->success = false;
  413. }
  414. $this->success = true;
  415. return true;
  416. }
  417. return false;
  418. }
  419. /**
  420. * Unzip the file.
  421. *
  422. * @param String zip_file-- the zip file to be extracted.
  423. * @param String destdir-- destination directory
  424. */
  425. public function unzip_ushahidi($zip_file, $destdir)
  426. {
  427. $archive = new Pclzip($zip_file);
  428. $this->log[] = sprintf("Unpacking %s ",$zip_file);
  429. if (@$archive->extract(PCLZIP_OPT_PATH, $destdir) == 0)
  430. {
  431. $this->errors[] = sprintf(Kohana::lang('libraries.upgrade_extracting_error'),$archive->errorInfo(true) ) ;
  432. return false;
  433. }
  434. $this->log[] = sprintf("Unpacking went successful");
  435. $this->success = true;
  436. return true;
  437. }
  438. /**
  439. * Write the zile file to a file.
  440. *
  441. * @param String zip_file-- the zip file to be written.
  442. * @param String dest_file-- the file to write.
  443. */
  444. public function write_to_file($zip_file, $dest_file)
  445. {
  446. $handler = fopen( $dest_file,'w');
  447. $fwritten = fwrite($handler,$zip_file);
  448. $this->log[] = sprintf("Writting to a file ");
  449. if( !$fwritten ) {
  450. $this->errors[] = sprintf(Kohana::lang('libraries.upgrade_zip_error'),$dest_file);
  451. $this->success = false;
  452. return false;
  453. }
  454. fclose($handler);
  455. $this->success = true;
  456. $this->log[] = sprintf("Zip file successfully written to a file ");
  457. return true;
  458. }
  459. /**
  460. * Fetch latest ushahidi version from a remote instance then
  461. * compare it with local instance version number.
  462. */
  463. public function _fetch_core_release()
  464. {
  465. // Current Version
  466. $current = urlencode(Kohana::config('settings.ushahidi_version'));
  467. // Extra Stats
  468. $url = urlencode(preg_replace("/^https?:\/\/(.+)$/i","\\1",
  469. url::base()));
  470. $ip_address = (isset($_SERVER['REMOTE_ADDR'])) ?
  471. urlencode($_SERVER['REMOTE_ADDR']) : "";
  472. $version_url = "http://version.ushahidi.com/2/?v=".$current.
  473. "&u=".$url."&ip=".$ip_address;
  474. $version_json_string = @file_get_contents($version_url);
  475. // If we didn't get anything back...
  476. if ( ! $version_json_string )
  477. {
  478. return "";
  479. }
  480. $version_details = json_decode($version_json_string);
  481. return $version_details;
  482. }
  483. /**
  484. * Log Messages To File
  485. */
  486. public function logger($message)
  487. {
  488. $message = date("Y-m-d H:i:s")." : ".$message;
  489. $message .= "\n";
  490. $logfile = DOCROOT."application/logs/upgrade_".$this->session->get('upgrade_session').".txt";
  491. $logfile = fopen($logfile, 'a+');
  492. fwrite($logfile, $message);
  493. fclose($logfile);
  494. }
  495. }
  496. ?>