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

/web/concrete/core/controllers/single_pages/upgrade.php

https://github.com/binaryfold4/concrete5
PHP | 329 lines | 278 code | 47 blank | 4 comment | 79 complexity | 777637a3c48ca54da767bab9b0422c8f MD5 | raw file
  1. <?php
  2. defined('C5_EXECUTE') or die("Access Denied.");
  3. ini_set('display_errors', 1);
  4. if (!ini_get('safe_mode')) {
  5. set_time_limit(0);
  6. ini_set("max_execution_time", 0);
  7. }
  8. date_default_timezone_set(@date_default_timezone_get());
  9. class Concrete5_Controller_Upgrade extends Controller {
  10. private $notes = array();
  11. private $upgrades = array();
  12. private $site_version = null;
  13. public $upgrade_db = true;
  14. public function on_start() {
  15. $this->secCheck();
  16. // if you just reverted, but didn't manually clear out your files - cache would be a prob here.
  17. Cache::disableLocalCache();
  18. $this->site_version = Config::get('SITE_APP_VERSION');
  19. Database::ensureEncoding();
  20. }
  21. public function secCheck() {
  22. $fh = Loader::helper('file');
  23. $updates = $fh->getDirectoryContents(DIR_APP_UPDATES);
  24. foreach($updates as $upd) {
  25. if (is_dir(DIR_APP_UPDATES . '/' . $upd) && is_writable(DIR_APP_UPDATES . '/' . $upd)) {
  26. if (file_exists(DIR_APP_UPDATES . '/' . $upd . '/' . DISPATCHER_FILENAME) && is_writable(DIR_APP_UPDATES . '/' . $upd . '/' . DISPATCHER_FILENAME)) {
  27. unlink(DIR_APP_UPDATES . '/' . $upd . '/' . DISPATCHER_FILENAME);
  28. }
  29. if (!file_exists(DIR_APP_UPDATES . '/' . $upd . '/index.html')) {
  30. touch(DIR_APP_UPDATES . '/' . $upd . '/index.html');
  31. }
  32. }
  33. }
  34. }
  35. public function view() {
  36. if ($this->get('force') == 1 || $this->get('source') == 'dashboard_update') {
  37. $this->do_upgrade();
  38. } else {
  39. $sav = $this->site_version;
  40. if (!$sav) {
  41. $message = t('Unable to determine your current version of concrete5. Upgrading cannot continue.');
  42. } else if (version_compare($sav, APP_VERSION, '>')) {
  43. $message = t('Upgrading from <b>%s</b>', $sav) . '<br/>';
  44. $message .= t('Upgrading to <b>%s</b>', APP_VERSION) . '<br/><br/>';
  45. $message .= t('Your current website uses a version of concrete5 greater than this one. You cannot upgrade.');
  46. $this->set('message', $message);
  47. } else if (version_compare($sav, APP_VERSION, '=')) {
  48. $message = t('Your site is already up to date!');
  49. if(defined('APP_VERSION_DISPLAY_IN_HEADER') && APP_VERSION_DISPLAY_IN_HEADER) {
  50. $message .= ' ' . t('The current version of concrete5 is %s.', sprintf('<b>%s</b>', APP_VERSION));
  51. }
  52. $message .= ' ' . t('You should remove this file for security.');
  53. $this->set('message', $message);
  54. } else {
  55. if ($this->post('do_upgrade')) {
  56. $this->do_upgrade();
  57. } elseif(version_compare($sav, '5.4.2.2', '<')) {
  58. $this->set('hide_force',true);
  59. $this->set('message',t('You must first upgrade your site to version 5.4.2.2'));
  60. } else {
  61. // do the upgrade
  62. $this->set_upgrades();
  63. $allnotes = array();
  64. foreach($this->upgrades as $ugh) {
  65. if (method_exists($ugh, 'notes')) {
  66. $notes = $ugh->notes();
  67. if ($notes != '') {
  68. if (is_array($notes)) {
  69. $allnotes = array_merge($allnotes, $notes);
  70. } else {
  71. $allnotes[] = $notes;
  72. }
  73. }
  74. }
  75. }
  76. $message = '';
  77. $message .= t('Upgrading from <b>%s</b>', $sav) . '<br/>';
  78. $message .= t('Upgrading to <b>%s</b>', APP_VERSION) . '<br/><br/>';
  79. if (count($allnotes) > 0) {
  80. $message .= '<ul>';
  81. foreach($allnotes as $n) {
  82. $message .= '<li>' . $n . '</li>';
  83. }
  84. $message .= '</ul><br/>';
  85. }
  86. $this->set('do_upgrade', true);
  87. $this->set('message', $message);
  88. }
  89. }
  90. }
  91. }
  92. private function set_upgrades() {
  93. $ugvs = array();
  94. $sav = $this->site_version;
  95. if (version_compare($sav, '5.0.0b1', '<')) {
  96. $ugvs[] = "version_500a1";
  97. }
  98. if (version_compare($sav, '5.0.0b2', '<')) {
  99. $ugvs[] = "version_500b1";
  100. }
  101. if (version_compare($sav, '5.0.0', '<')) {
  102. $ugvs[] = "version_500b2";
  103. }
  104. if (version_compare($sav, '5.1.0', '<')) {
  105. $ugvs[] = "version_500";
  106. }
  107. if (version_compare($sav, '5.2.0', '<')) {
  108. $ugvs[] = "version_510";
  109. }
  110. if (version_compare($sav, '5.3.0', '<')) {
  111. $ugvs[] = "version_520";
  112. }
  113. if (version_compare($sav, '5.3.2', '<')) {
  114. $ugvs[] = "version_530";
  115. }
  116. if (version_compare($sav, '5.3.3', '<')) {
  117. $ugvs[] = "version_532";
  118. }
  119. if (version_compare($sav, '5.3.3.1', '<')) {
  120. $ugvs[] = "version_533";
  121. }
  122. if (version_compare($sav, '5.4.0', '<')) {
  123. $ugvs[] = "version_5331";
  124. $ugvs[] = "version_540";
  125. }
  126. if (version_compare($sav, '5.4.1', '<')) {
  127. $ugvs[] = "version_5406";
  128. $ugvs[] = "version_541";
  129. }
  130. if (version_compare($sav, '5.4.2', '<')) {
  131. $ugvs[] = "version_5411";
  132. $ugvs[] = "version_542";
  133. }
  134. if (version_compare($sav, '5.4.2.1', '<')) {
  135. $ugvs[] = "version_5421";
  136. }
  137. if (version_compare($sav, '5.5.0', '<')) {
  138. $ugvs[] = "version_550";
  139. }
  140. if (version_compare($sav, '5.5.1', '<')) {
  141. $ugvs[] = "version_551";
  142. }
  143. if (version_compare($sav, '5.5.2', '<')) {
  144. $ugvs[] = "version_552";
  145. }
  146. if (version_compare($sav, '5.6.0', '<')) {
  147. $ugvs[] = "version_560";
  148. }
  149. if (version_compare($sav, '5.6.0.1', '<')) {
  150. $ugvs[] = "version_5601";
  151. }
  152. if (version_compare($sav, '5.6.0.2', '<')) {
  153. $ugvs[] = "version_5602";
  154. }
  155. if (version_compare($sav, '5.6.1', '<')) {
  156. $ugvs[] = "version_561";
  157. }
  158. if (version_compare($sav, '5.6.2', '<')) {
  159. $ugvs[] = "version_562";
  160. }
  161. if (version_compare($sav, '5.6.3', '<')) {
  162. $ugvs[] = "version_563";
  163. }
  164. if (version_compare($sav, '5.6.3.1', '<')) {
  165. $ugvs[] = "version_5631";
  166. }
  167. if (version_compare($sav, '5.6.3.2', '<')) {
  168. $ugvs[] = "version_5632";
  169. }
  170. if (version_compare($sav, '5.6.3.3', '<')) {
  171. $ugvs[] = "version_5633";
  172. }
  173. foreach($ugvs as $ugh) {
  174. $this->upgrades[] = Loader::helper('concrete/upgrade/' . $ugh);
  175. }
  176. }
  177. public function refresh_schema() {
  178. if ($this->upgrade_db) {
  179. $installDirectory = DIR_BASE_CORE . '/config';
  180. $file = $installDirectory . '/db.xml';
  181. if (!file_exists($file)) {
  182. throw new Exception(t('Unable to locate database import file.'));
  183. }
  184. $err = Package::installDB($file);
  185. // now we refresh the block schema
  186. $btl = new BlockTypeList();
  187. $btArray = $btl->getInstalledList();
  188. foreach($btArray as $bt) {
  189. $bt->refresh();
  190. }
  191. $this->upgrade_db = false;
  192. }
  193. }
  194. protected function refreshDatabaseTables($tables) {
  195. $dbxml = simplexml_load_file(DIR_BASE_CORE . '/config/db.xml');
  196. $output = new SimpleXMLElement("<schema></schema>");
  197. $output->addAttribute('version', '0.3');
  198. $th = Loader::helper("text");
  199. foreach($dbxml->table as $t) {
  200. $name = (string) $t['name'];
  201. if (in_array($name, $tables)) {
  202. $th->appendXML($output, $t);
  203. }
  204. }
  205. $xml = $output->asXML();
  206. if ($xml) {
  207. $file = Loader::helper('file')->getTemporaryDirectory() . '/tmpupgrade_' . time() . '.xml';
  208. @file_put_contents($file, $xml);
  209. if (file_exists($file)) {
  210. Package::installDB($file);
  211. @unlink($file);
  212. } else {
  213. throw new Exception(t('Unable to create temporary db xml file: %s', $file));
  214. }
  215. }
  216. }
  217. private function do_upgrade() {
  218. $runMessages = array();
  219. $prepareMessages = array();
  220. $currentLocale = Localization::activeLocale();
  221. if ($currentLocale != 'en_US') {
  222. // Prevent the database records being stored in wrong language
  223. Localization::changeLocale('en_US');
  224. }
  225. try {
  226. Cache::flush();
  227. $this->set_upgrades();
  228. foreach($this->upgrades as $ugh) {
  229. if (method_exists($ugh, 'prepare')) {
  230. $prepareMessages[] =$ugh->prepare($this);
  231. }
  232. if (isset($ugh->dbRefreshTables) && count($ugh->dbRefreshTables) > 0) {
  233. $this->refreshDatabaseTables($ugh->dbRefreshTables);
  234. }
  235. if (method_exists($ugh, 'run')) {
  236. $runMessages[] = $ugh->run();
  237. }
  238. }
  239. $message = '';
  240. if(is_array($prepareMessages) && count($prepareMessages)) {
  241. foreach($prepareMessages as $m) {
  242. if(is_array($m)) {
  243. $message .= implode("<br/>",$m);
  244. }
  245. }
  246. }
  247. if(is_array($runMessages) && count($runMessages)) {
  248. foreach($runMessages as $m) {
  249. if(is_array($m)) {
  250. $message .= implode("<br/>",$m);
  251. }
  252. }
  253. if(strlen($message)) {
  254. $this->set('had_failures',true);
  255. }
  256. }
  257. $upgrade = true;
  258. if ($currentLocale != 'en_US') {
  259. Localization::changeLocale($currentLocale);
  260. }
  261. } catch(Exception $e) {
  262. $upgrade = false;
  263. if ($currentLocale != 'en_US') {
  264. Localization::changeLocale($currentLocale);
  265. }
  266. $message .= '<div class="alert-message block-message error"><p>' . t('An Unexpected Error occurred while upgrading: %s', $e->getTraceAsString()) . '</p></div>';
  267. }
  268. if ($upgrade) {
  269. $completeMessage .= '<div class="alert-message block-message success"><p>';
  270. if(defined('APP_VERSION_DISPLAY_IN_HEADER') && APP_VERSION_DISPLAY_IN_HEADER) {
  271. $completeMessage .= t(/*i18n: %s is the concrete5 version number*/'Upgrade to %s complete!', sprintf('<b>%s</b>', APP_VERSION));
  272. }
  273. else {
  274. $completeMessage .= t('Upgrade to latest version complete!');
  275. }
  276. $completeMessage .= '</p></div>';
  277. Config::save('SITE_APP_VERSION', APP_VERSION);
  278. }
  279. $this->set('completeMessage',$completeMessage);
  280. $this->set('message', $message);
  281. }
  282. }