upgrade-functions.php 26 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765
  1. <?php
  2. trait UpgradeFunctions
  3. {
  4. public function upgradeCheck()
  5. {
  6. if ($this->hasDB()) {
  7. $tempLock = $this->config['dbLocation'] . 'DBLOCK.txt';
  8. $updateComplete = $this->config['dbLocation'] . 'completed.txt';
  9. $cleanup = dirname(__DIR__, 2) . DIRECTORY_SEPARATOR . 'upgrade' . DIRECTORY_SEPARATOR;
  10. if (file_exists($updateComplete)) {
  11. @unlink($updateComplete);
  12. @$this->rrmdir($cleanup);
  13. }
  14. if (file_exists($tempLock)) {
  15. die($this->showHTML('Upgrading', 'Please wait...'));
  16. }
  17. $updateDB = false;
  18. $updateSuccess = true;
  19. $compare = new Composer\Semver\Comparator;
  20. $oldVer = $this->config['configVersion'];
  21. // Upgrade check start for version below
  22. $versionCheck = '2.0.0-beta-200';
  23. if ($compare->lessThan($oldVer, $versionCheck)) {
  24. $updateDB = true;
  25. $oldVer = $versionCheck;
  26. }
  27. // End Upgrade check start for version above
  28. // Upgrade check start for version below
  29. $versionCheck = '2.0.0-beta-500';
  30. if ($compare->lessThan($oldVer, $versionCheck)) {
  31. $updateDB = true;
  32. $oldVer = $versionCheck;
  33. }
  34. // End Upgrade check start for version above
  35. // Upgrade check start for version below
  36. $versionCheck = '2.0.0-beta-800';
  37. if ($compare->lessThan($oldVer, $versionCheck)) {
  38. $updateDB = true;
  39. $oldVer = $versionCheck;
  40. }
  41. // End Upgrade check start for version above
  42. // Upgrade check start for version below
  43. $versionCheck = '2.1.0';
  44. if ($compare->lessThan($oldVer, $versionCheck)) {
  45. $updateDB = false;
  46. $oldVer = $versionCheck;
  47. $this->upgradeToVersion($versionCheck);
  48. }
  49. // End Upgrade check start for version above
  50. // Upgrade check start for version below
  51. $versionCheck = '2.1.400';
  52. if ($compare->lessThan($oldVer, $versionCheck)) {
  53. $updateDB = false;
  54. $oldVer = $versionCheck;
  55. $this->upgradeToVersion($versionCheck);
  56. }
  57. // End Upgrade check start for version above
  58. // Upgrade check start for version below
  59. $versionCheck = '2.1.525';
  60. if ($compare->lessThan($oldVer, $versionCheck)) {
  61. $updateDB = false;
  62. $oldVer = $versionCheck;
  63. $this->upgradeToVersion($versionCheck);
  64. }
  65. // End Upgrade check start for version above
  66. // Upgrade check start for version below
  67. $versionCheck = '2.1.860';
  68. if ($compare->lessThan($oldVer, $versionCheck)) {
  69. $updateDB = false;
  70. $oldVer = $versionCheck;
  71. $this->upgradeToVersion($versionCheck);
  72. }
  73. // End Upgrade check start for version above
  74. // Upgrade check start for version below
  75. $versionCheck = '2.1.1500';
  76. if ($compare->lessThan($oldVer, $versionCheck)) {
  77. $updateDB = false;
  78. $oldVer = $versionCheck;
  79. $this->upgradeToVersion($versionCheck);
  80. }
  81. // End Upgrade check start for version above
  82. // Upgrade check start for version below
  83. $versionCheck = '2.1.1860';
  84. if ($compare->lessThan($oldVer, $versionCheck)) {
  85. $updateDB = false;
  86. $oldVer = $versionCheck;
  87. $this->upgradeToVersion($versionCheck);
  88. }
  89. // End Upgrade check start for version above
  90. // Upgrade check start for version below
  91. $versionCheck = '2.1.2200';
  92. if ($compare->lessThan($oldVer, $versionCheck)) {
  93. $updateDB = false;
  94. $oldVer = $versionCheck;
  95. $this->upgradeToVersion($versionCheck);
  96. }
  97. // End Upgrade check start for version above
  98. if ($updateDB == true) {
  99. //return 'Upgraded Needed - Current Version '.$oldVer.' - New Version: '.$versionCheck;
  100. // Upgrade database to latest version
  101. $updateSuccess = $this->updateDB($oldVer);
  102. }
  103. // Update config.php version if different to the installed version
  104. if ($updateSuccess && $this->version !== $this->config['configVersion']) {
  105. $this->updateConfig(array('apply_CONFIG_VERSION' => $this->version));
  106. $this->setLoggerChannel('Update')->notice('Updated config version to ' . $this->version);
  107. }
  108. if ($updateSuccess == false) {
  109. die($this->showHTML('Database update failed', 'Please manually check logs and fix - Then reload this page'));
  110. }
  111. return true;
  112. }
  113. }
  114. public function dropColumnFromDatabase($table = '', $columnName = '')
  115. {
  116. if ($table == '' || $columnName == '') {
  117. return false;
  118. }
  119. if ($this->hasDB()) {
  120. $columnExists = $this->checkIfColumnExists($table, $columnName);
  121. if ($columnExists) {
  122. $columnAlter = [
  123. array(
  124. 'function' => 'query',
  125. 'query' => ['ALTER TABLE %n DROP %n',
  126. (string)$table,
  127. (string)$columnName,
  128. ]
  129. )
  130. ];
  131. $AlterQuery = $this->processQueries($columnAlter);
  132. return (boolean)($AlterQuery);
  133. }
  134. }
  135. return false;
  136. }
  137. public function checkIfColumnExists($table = '', $columnName = '')
  138. {
  139. if ($table == '' || $columnName == '') {
  140. return false;
  141. }
  142. if ($this->hasDB()) {
  143. if ($this->config['driver'] === 'sqlite3') {
  144. $term = 'SELECT COUNT(*) AS has_column FROM pragma_table_info(?) WHERE name=?';
  145. } else {
  146. $term = 'SELECT COUNT(*) FROM INFORMATION_SCHEMA.COLUMNS WHERE TABLE_SCHEMA = "' . $this->config['dbName'] . '" AND TABLE_NAME=? AND COLUMN_NAME=?';
  147. }
  148. $tableInfo = [
  149. array(
  150. 'function' => 'fetchSingle',
  151. 'query' => array(
  152. $term,
  153. (string)$table,
  154. (string)$columnName
  155. )
  156. )
  157. ];
  158. $query = $this->processQueries($tableInfo);
  159. return (boolean)($query);
  160. }
  161. }
  162. public function addColumnToDatabase($table = '', $columnName = '', $definition = 'TEXT')
  163. {
  164. if ($table == '' || $columnName == '' || $definition == '') {
  165. return false;
  166. }
  167. if ($this->hasDB()) {
  168. if ($this->config['driver'] === 'sqlite3') {
  169. $term = 'SELECT COUNT(*) AS has_column FROM pragma_table_info(?) WHERE name=?';
  170. } else {
  171. $term = 'SELECT COUNT(*) FROM INFORMATION_SCHEMA.COLUMNS WHERE TABLE_SCHEMA = "' . $this->config['dbName'] . '" AND TABLE_NAME=? AND COLUMN_NAME=?';
  172. }
  173. $tableInfo = [
  174. array(
  175. 'function' => 'fetchSingle',
  176. 'query' => array(
  177. $term,
  178. (string)$table,
  179. (string)$columnName
  180. )
  181. )
  182. ];
  183. $query = $this->processQueries($tableInfo);
  184. if (!$query) {
  185. $columnAlter = [
  186. array(
  187. 'function' => 'query',
  188. 'query' => ['ALTER TABLE %n ADD %n ' . (string)$definition,
  189. (string)$table,
  190. (string)$columnName,
  191. ]
  192. )
  193. ];
  194. $AlterQuery = $this->processQueries($columnAlter);
  195. if ($AlterQuery) {
  196. $query = $this->processQueries($tableInfo);
  197. if ($query) {
  198. return true;
  199. }
  200. }
  201. } else {
  202. return true;
  203. }
  204. }
  205. return false;
  206. }
  207. public function createMysqliDatabase($database, $migration = false)
  208. {
  209. $query = [
  210. array(
  211. 'function' => 'fetchAll',
  212. 'query' => array(
  213. 'DROP DATABASE IF EXISTS tempMigration'
  214. )
  215. ),
  216. array(
  217. 'function' => 'fetchAll',
  218. 'query' => array(
  219. 'CREATE DATABASE IF NOT EXISTS %n',
  220. $database
  221. )
  222. ),
  223. ];
  224. //$query = ['CREATE DB %n', $database];
  225. return $this->processQueries($query, $migration);
  226. }
  227. public function updateDB($oldVerNum = false)
  228. {
  229. $tempLock = $this->config['dbLocation'] . 'DBLOCK.txt';
  230. if (!file_exists($tempLock)) {
  231. touch($tempLock);
  232. $migrationDB = 'tempMigration.db';
  233. $pathDigest = pathinfo($this->config['dbLocation'] . $this->config['dbName']);
  234. // Delete old backup sqlite db if exists
  235. if (file_exists($this->config['dbLocation'] . $migrationDB)) {
  236. unlink($this->config['dbLocation'] . $migrationDB);
  237. }
  238. // Create Temp DB First
  239. $this->createNewDB('tempMigration', true);
  240. $this->connectOtherDB();
  241. if ($this->config['driver'] == 'sqlite3') {
  242. // Backup sqlite database
  243. $backupDB = $pathDigest['dirname'] . '/' . $pathDigest['filename'] . '[' . date('Y-m-d_H-i-s') . ']' . ($oldVerNum ? '[' . $oldVerNum . ']' : '') . '.bak.db';
  244. copy($this->config['dbLocation'] . $this->config['dbName'], $backupDB);
  245. }
  246. $success = $this->createDB($this->config['dbLocation'], true);
  247. if ($success) {
  248. switch ($this->config['driver']) {
  249. case 'sqlite3':
  250. $query = 'SELECT name FROM sqlite_master WHERE type="table"';
  251. break;
  252. case 'mysqli':
  253. $query = 'SELECT Table_name as name from information_schema.tables where table_schema = "tempMigration"';
  254. break;
  255. }
  256. $response = [
  257. array(
  258. 'function' => 'fetchAll',
  259. 'query' => array(
  260. $query
  261. )
  262. ),
  263. ];
  264. $tables = $this->processQueries($response);
  265. $defaultTables = $this->getDefaultTablesFormatted();
  266. foreach ($tables as $table) {
  267. if (in_array($table['name'], $defaultTables)) {
  268. $response = [
  269. array(
  270. 'function' => 'fetchAll',
  271. 'query' => array(
  272. 'SELECT * FROM %n', $table['name']
  273. )
  274. ),
  275. ];
  276. $data = $this->processQueries($response);
  277. $this->setLoggerChannel('Migration')->info('Obtained Table data', ['table' => $table['name']]);
  278. foreach ($data as $row) {
  279. $response = [
  280. array(
  281. 'function' => 'query',
  282. 'query' => array(
  283. 'INSERT into %n', $table['name'],
  284. $row
  285. )
  286. ),
  287. ];
  288. $this->processQueries($response, true);
  289. }
  290. $this->setLoggerChannel('Migration')->info('Wrote Table data', ['table' => $table['name']]);
  291. }
  292. }
  293. if ($this->config['driver'] == 'mysqli') {
  294. $response = [
  295. array(
  296. 'function' => 'query',
  297. 'query' => array(
  298. 'DROP DATABASE IF EXISTS %n', $this->config['dbName']
  299. )
  300. ),
  301. ];
  302. $data = $this->processQueries($response);
  303. if ($data) {
  304. $create = $this->createNewDB($this->config['dbName']);
  305. if ($create) {
  306. $structure = $this->createDB($this->config['dbLocation']);
  307. if ($structure) {
  308. foreach ($tables as $table) {
  309. if (in_array($table['name'], $defaultTables)) {
  310. $response = [
  311. array(
  312. 'function' => 'fetchAll',
  313. 'query' => array(
  314. 'SELECT * FROM %n', $table['name']
  315. )
  316. ),
  317. ];
  318. $data = $this->processQueries($response, true);
  319. $this->setLoggerChannel('Migration')->info('Obtained Table data', ['table' => $table['name']]);
  320. foreach ($data as $row) {
  321. $response = [
  322. array(
  323. 'function' => 'query',
  324. 'query' => array(
  325. 'INSERT into %n', $table['name'],
  326. $row
  327. )
  328. ),
  329. ];
  330. $this->processQueries($response);
  331. }
  332. $this->setLoggerChannel('Migration')->info('Wrote Table data', ['table' => $table['name']]);
  333. }
  334. }
  335. } else {
  336. $this->setLoggerChannel('Migration')->warning('Could not recreate Database structure');
  337. }
  338. } else {
  339. $this->setLoggerChannel('Migration')->warning('Could not recreate Database');
  340. }
  341. } else {
  342. $this->setLoggerChannel('Migration')->warning('Could not drop old tempMigration Database');
  343. }
  344. $this->setLoggerChannel('Migration')->info('All Table data converted');
  345. @unlink($tempLock);
  346. return true;
  347. }
  348. //$this->db->disconnect();
  349. //$this->otherDb->disconnect();
  350. // Remove Current Database
  351. if ($this->config['driver'] == 'sqlite3') {
  352. $this->setLoggerChannel('Migration')->info('All Table data converted');
  353. $this->setLoggerChannel('Migration')->info('Starting Database movement for sqlite3');
  354. if (file_exists($this->config['dbLocation'] . $migrationDB)) {
  355. $oldFileSize = filesize($this->config['dbLocation'] . $this->config['dbName']);
  356. $newFileSize = filesize($this->config['dbLocation'] . $migrationDB);
  357. if ($newFileSize > 0) {
  358. $this->setLoggerChannel('Migration')->info('New Table size has been verified');
  359. @unlink($this->config['dbLocation'] . $this->config['dbName']);
  360. copy($this->config['dbLocation'] . $migrationDB, $this->config['dbLocation'] . $this->config['dbName']);
  361. @unlink($this->config['dbLocation'] . $migrationDB);
  362. $this->setLoggerChannel('Migration')->info('Migrated Old Info to new Database');
  363. @unlink($tempLock);
  364. return true;
  365. } else {
  366. $this->setLoggerChannel('Migration')->warning('Database filesize is zero');
  367. }
  368. } else {
  369. $this->setLoggerChannel('Migration')->warning('Migration Database does not exist');
  370. }
  371. }
  372. @unlink($tempLock);
  373. return false;
  374. } else {
  375. $this->setLoggerChannel('Migration')->warning('Could not create migration Database');
  376. }
  377. @unlink($tempLock);
  378. return false;
  379. }
  380. return false;
  381. }
  382. public function resetUpdateFeature($feature = null)
  383. {
  384. if (!$feature) {
  385. $this->setResponse(409, 'Feature not supplied');
  386. return false;
  387. }
  388. $feature = strtolower($feature);
  389. switch ($feature) {
  390. case 'groupmax':
  391. case 'groupidmax':
  392. case 'group-max':
  393. case 'group-id-max':
  394. case 'group_id':
  395. case 'group_id_max':
  396. $columnExists = $this->checkIfColumnExists('tabs', 'group_id_max');
  397. if ($columnExists) {
  398. $query = [
  399. [
  400. 'function' => 'query',
  401. 'query' => [
  402. 'UPDATE tabs SET group_id_max=0'
  403. ]
  404. ],
  405. ];
  406. $tabs = $this->processQueries($query);
  407. if (!$tabs) {
  408. $this->setResponse(500, 'An error occurred');
  409. return false;
  410. }
  411. } else {
  412. $this->setResponse(500, 'group_id_max column does not exist');
  413. return false;
  414. }
  415. break;
  416. default:
  417. $this->setResponse(404, 'Feature not found in reset update');
  418. return false;
  419. }
  420. $this->setResponse(200, 'Ran reset update feature for ' . $feature);
  421. return true;
  422. }
  423. public function upgradeToVersion($version = '2.1.0')
  424. {
  425. $this->setLoggerChannel('Upgrade')->notice('Starting upgrade to version ' . $version);
  426. switch ($version) {
  427. case '2.1.0':
  428. $this->upgradeSettingsTabURL();
  429. $this->upgradeHomepageTabURL();
  430. break;
  431. case '2.1.400':
  432. $this->removeOldPluginDirectoriesAndFiles();
  433. break;
  434. case '2.1.525':
  435. $this->removeOldCustomHTML();
  436. break;
  437. case '2.1.860':
  438. $this->upgradeInstalledPluginsConfigItem();
  439. break;
  440. case '2.1.1500':
  441. $this->upgradeDataToFolder();
  442. break;
  443. case '2.1.1860':
  444. $this->upgradePluginsToDataFolder();
  445. break;
  446. case '2.1.2200':
  447. $this->backupOrganizr();
  448. $this->addGroupIdMaxToDatabase();
  449. $this->addAddToAdminToDatabase();
  450. break;
  451. }
  452. $this->setLoggerChannel('Upgrade')->notice('Finished upgrade to version ' . $version);
  453. $this->setAPIResponse('success', 'Ran update function for version: ' . $version, 200);
  454. return true;
  455. }
  456. public function removeOldCacheFolder()
  457. {
  458. $folder = $this->root . DIRECTORY_SEPARATOR . 'plugins' . DIRECTORY_SEPARATOR . 'images' . DIRECTORY_SEPARATOR . 'cache' . DIRECTORY_SEPARATOR;
  459. $this->setLoggerChannel('Migration');
  460. $this->logger->info('Running Old Cache folder migration');
  461. if (file_exists($folder)) {
  462. $this->rrmdir($folder);
  463. $this->logger->info('Old Cache folder found');
  464. $this->logger->info('Removed Old Cache folder');
  465. }
  466. return true;
  467. }
  468. public function upgradeDataToFolder()
  469. {
  470. if ($this->hasDB()) {
  471. // Make main data folder
  472. $rootFolderMade = $this->makeDir($this->root . DIRECTORY_SEPARATOR . 'data');
  473. // Make config folder child
  474. $this->makeDir($this->root . DIRECTORY_SEPARATOR . 'data' . DIRECTORY_SEPARATOR . 'config' . DIRECTORY_SEPARATOR);
  475. if ($rootFolderMade) {
  476. // Migrate over userTabs folder
  477. $this->makeDir($this->root . DIRECTORY_SEPARATOR . 'data' . DIRECTORY_SEPARATOR . 'userTabs');
  478. if ($this->rcopy($this->root . DIRECTORY_SEPARATOR . 'plugins' . DIRECTORY_SEPARATOR . 'images' . DIRECTORY_SEPARATOR . 'userTabs', $this->root . DIRECTORY_SEPARATOR . 'data' . DIRECTORY_SEPARATOR . 'userTabs')) {
  479. // Convert tabs over
  480. $query = [
  481. [
  482. 'function' => 'fetchAll',
  483. 'query' => [
  484. 'SELECT * FROM tabs WHERE image like "%userTabs%"'
  485. ]
  486. ],
  487. ];
  488. $tabs = $this->processQueries($query);
  489. if (count($tabs) > 0) {
  490. foreach ($tabs as $tab) {
  491. $newImage = str_replace('plugins/images/userTabs', 'data/userTabs', $tab['image']);
  492. $updateQuery = [
  493. [
  494. 'function' => 'query',
  495. 'query' => [
  496. 'UPDATE tabs SET',
  497. ['image' => $newImage],
  498. 'WHERE id = ?',
  499. $tab['id']
  500. ]
  501. ],
  502. ];
  503. $this->processQueries($updateQuery);
  504. }
  505. }
  506. $this->setLoggerChannel('Migration');
  507. $this->logger->info('The folder "userTabs" was migrated to new data folder');
  508. }
  509. // Migrate over custom cert
  510. if (file_exists($this->root . DIRECTORY_SEPARATOR . 'api' . DIRECTORY_SEPARATOR . 'functions' . DIRECTORY_SEPARATOR . 'cert' . DIRECTORY_SEPARATOR . 'custom.pem')) {
  511. // Make cert folder child
  512. $this->makeDir($this->root . DIRECTORY_SEPARATOR . 'data' . DIRECTORY_SEPARATOR . 'cert' . DIRECTORY_SEPARATOR);
  513. if ($this->rcopy($this->root . DIRECTORY_SEPARATOR . 'api' . DIRECTORY_SEPARATOR . 'functions' . DIRECTORY_SEPARATOR . 'cert' . DIRECTORY_SEPARATOR . 'custom.pem', $this->root . DIRECTORY_SEPARATOR . 'data' . DIRECTORY_SEPARATOR . 'cert' . DIRECTORY_SEPARATOR . 'custom.pem')) {
  514. $this->setLoggerChannel('Migration');
  515. $this->logger->info('Moved over custom cert file');
  516. }
  517. }
  518. // Migrate over favIcon
  519. $this->makeDir($this->root . DIRECTORY_SEPARATOR . 'data' . DIRECTORY_SEPARATOR . 'favicon');
  520. if ($this->rcopy($this->root . DIRECTORY_SEPARATOR . 'plugins' . DIRECTORY_SEPARATOR . 'images' . DIRECTORY_SEPARATOR . 'faviconCustom', $this->root . DIRECTORY_SEPARATOR . 'data' . DIRECTORY_SEPARATOR . 'favicon')) {
  521. if ($this->config['favIcon'] !== '') {
  522. $this->config['favIcon'] = str_replace('plugins/images/faviconCustom', 'data/favicon', $this->config['favIcon']);
  523. $this->updateConfig(array('favIcon' => $this->config['favIcon']));
  524. }
  525. $this->setLoggerChannel('Migration');
  526. $this->logger->info('Favicon was migrated over');
  527. }
  528. // Migrate over custom pages
  529. $this->makeDir($this->root . DIRECTORY_SEPARATOR . 'data' . DIRECTORY_SEPARATOR . 'pages');
  530. if (file_exists($this->root . DIRECTORY_SEPARATOR . 'api' . DIRECTORY_SEPARATOR . 'pages' . DIRECTORY_SEPARATOR . 'custom')) {
  531. if ($this->rcopy($this->root . DIRECTORY_SEPARATOR . 'api' . DIRECTORY_SEPARATOR . 'pages' . DIRECTORY_SEPARATOR . 'custom', $this->root . DIRECTORY_SEPARATOR . 'data' . DIRECTORY_SEPARATOR . 'pages')) {
  532. $this->rrmdir($this->root . DIRECTORY_SEPARATOR . 'api' . DIRECTORY_SEPARATOR . 'pages' . DIRECTORY_SEPARATOR . 'custom');
  533. $this->setLoggerChannel('Migration');
  534. $this->logger->info('Custom pages was migrated over');
  535. }
  536. }
  537. // Migrate over custom routes
  538. $this->makeDir($this->root . DIRECTORY_SEPARATOR . 'data' . DIRECTORY_SEPARATOR . 'routes');
  539. if (file_exists($this->root . DIRECTORY_SEPARATOR . 'api' . DIRECTORY_SEPARATOR . 'v2' . DIRECTORY_SEPARATOR . 'routes' . DIRECTORY_SEPARATOR . 'custom')) {
  540. if ($this->rcopy($this->root . DIRECTORY_SEPARATOR . 'api' . DIRECTORY_SEPARATOR . 'v2' . DIRECTORY_SEPARATOR . 'routes' . DIRECTORY_SEPARATOR . 'custom', $this->root . DIRECTORY_SEPARATOR . 'data' . DIRECTORY_SEPARATOR . 'routes')) {
  541. $this->rrmdir($this->root . DIRECTORY_SEPARATOR . 'api' . DIRECTORY_SEPARATOR . 'v2' . DIRECTORY_SEPARATOR . 'routes' . DIRECTORY_SEPARATOR . 'custom');
  542. $this->setLoggerChannel('Migration');
  543. $this->logger->info('Custom routes was migrated over');
  544. }
  545. }
  546. // Migrate over cache folder
  547. $this->removeOldCacheFolder();
  548. }
  549. return true;
  550. }
  551. return false;
  552. }
  553. public function upgradePluginsToDataFolder()
  554. {
  555. if ($this->hasDB()) {
  556. // Make main data folder
  557. $rootFolderMade = $this->makeDir($this->root . DIRECTORY_SEPARATOR . 'data');
  558. if ($rootFolderMade) {
  559. // Migrate over plugins folder
  560. $this->makeDir($this->root . DIRECTORY_SEPARATOR . 'data' . DIRECTORY_SEPARATOR . 'plugins');
  561. $plexLibraries = $this->root . DIRECTORY_SEPARATOR . 'api' . DIRECTORY_SEPARATOR . 'plugins' . DIRECTORY_SEPARATOR . 'plexLibraries';
  562. if (file_exists($plexLibraries)) {
  563. if (rename($plexLibraries, $this->root . DIRECTORY_SEPARATOR . 'data' . DIRECTORY_SEPARATOR . 'plugins' . DIRECTORY_SEPARATOR . 'plexLibraries')) {
  564. $this->setLoggerChannel('Migration');
  565. $this->logger->info('The plugin folder "plexLibraries" was migrated to new data folder');
  566. }
  567. }
  568. $test = $this->root . DIRECTORY_SEPARATOR . 'api' . DIRECTORY_SEPARATOR . 'plugins' . DIRECTORY_SEPARATOR . 'test';
  569. if (file_exists($test)) {
  570. if (rename($test, $this->root . DIRECTORY_SEPARATOR . 'data' . DIRECTORY_SEPARATOR . 'plugins' . DIRECTORY_SEPARATOR . 'test')) {
  571. $this->setLoggerChannel('Migration');
  572. $this->logger->info('The plugin folder "test" was migrated to new data folder');
  573. }
  574. }
  575. }
  576. return true;
  577. }
  578. return false;
  579. }
  580. public function upgradeSettingsTabURL()
  581. {
  582. $response = [
  583. array(
  584. 'function' => 'query',
  585. 'query' => array(
  586. 'UPDATE tabs SET',
  587. ['url' => 'api/v2/page/settings'],
  588. 'WHERE url = ?',
  589. 'api/?v1/settings/page'
  590. )
  591. ),
  592. ];
  593. return $this->processQueries($response);
  594. }
  595. public function upgradeHomepageTabURL()
  596. {
  597. $response = [
  598. array(
  599. 'function' => 'query',
  600. 'query' => array(
  601. 'UPDATE tabs SET',
  602. ['url' => 'api/v2/page/homepage'],
  603. 'WHERE url = ?',
  604. 'api/?v1/homepage/page'
  605. )
  606. ),
  607. ];
  608. return $this->processQueries($response);
  609. }
  610. public function upgradeInstalledPluginsConfigItem()
  611. {
  612. $oldConfigItem = $this->config['installedPlugins'];
  613. if (gettype($oldConfigItem) == 'string') {
  614. if ((strpos($oldConfigItem, '|') !== false)) {
  615. $newPlugins = [];
  616. $plugins = explode('|', $oldConfigItem);
  617. foreach ($plugins as $plugin) {
  618. $info = explode(':', $plugin);
  619. $newPlugins[$info[0]] = [
  620. 'name' => $info[0],
  621. 'version' => $info[1],
  622. 'repo' => 'organizr'
  623. ];
  624. }
  625. } else {
  626. $newPlugins = [];
  627. if ($oldConfigItem !== '') {
  628. $info = explode(':', $oldConfigItem);
  629. $newPlugins[$info[0]] = [
  630. 'name' => $info[0],
  631. 'version' => $info[1],
  632. 'repo' => 'https://github.com/Organizr/Organizr-Plugins'
  633. ];
  634. }
  635. }
  636. $this->updateConfig(['installedPlugins' => $newPlugins]);
  637. } elseif (gettype($oldConfigItem) == 'array') {
  638. $this->updateConfig(['installedPlugins' => $oldConfigItem]);
  639. }
  640. return true;
  641. }
  642. public function removeOldPluginDirectoriesAndFiles()
  643. {
  644. $folders = [
  645. $this->root . DIRECTORY_SEPARATOR . 'api' . DIRECTORY_SEPARATOR . 'plugins' . DIRECTORY_SEPARATOR . 'api',
  646. $this->root . DIRECTORY_SEPARATOR . 'api' . DIRECTORY_SEPARATOR . 'plugins' . DIRECTORY_SEPARATOR . 'config',
  647. $this->root . DIRECTORY_SEPARATOR . 'api' . DIRECTORY_SEPARATOR . 'plugins' . DIRECTORY_SEPARATOR . 'css',
  648. $this->root . DIRECTORY_SEPARATOR . 'api' . DIRECTORY_SEPARATOR . 'plugins' . DIRECTORY_SEPARATOR . 'js',
  649. $this->root . DIRECTORY_SEPARATOR . 'api' . DIRECTORY_SEPARATOR . 'plugins' . DIRECTORY_SEPARATOR . 'misc',
  650. ];
  651. $files = [
  652. $this->root . DIRECTORY_SEPARATOR . 'api' . DIRECTORY_SEPARATOR . 'plugins' . DIRECTORY_SEPARATOR . 'bookmark.php',
  653. $this->root . DIRECTORY_SEPARATOR . 'api' . DIRECTORY_SEPARATOR . 'plugins' . DIRECTORY_SEPARATOR . 'chat.php',
  654. $this->root . DIRECTORY_SEPARATOR . 'api' . DIRECTORY_SEPARATOR . 'plugins' . DIRECTORY_SEPARATOR . 'healthChecks.php',
  655. $this->root . DIRECTORY_SEPARATOR . 'api' . DIRECTORY_SEPARATOR . 'plugins' . DIRECTORY_SEPARATOR . 'invites.php',
  656. $this->root . DIRECTORY_SEPARATOR . 'api' . DIRECTORY_SEPARATOR . 'plugins' . DIRECTORY_SEPARATOR . 'php-mailer.php',
  657. $this->root . DIRECTORY_SEPARATOR . 'api' . DIRECTORY_SEPARATOR . 'plugins' . DIRECTORY_SEPARATOR . 'speedTest.php',
  658. ];
  659. foreach ($files as $file) {
  660. if (file_exists($file)) {
  661. @unlink($file);
  662. }
  663. }
  664. foreach ($folders as $folder) {
  665. if (file_exists($folder)) {
  666. @$this->rrmdir($folder);
  667. }
  668. }
  669. return true;
  670. }
  671. public function checkForConfigKeyAddToArray($keys)
  672. {
  673. $updateItems = [];
  674. foreach ($keys as $new => $old) {
  675. if (isset($this->config[$old])) {
  676. if ($this->config[$old] !== '') {
  677. $updateItemsNew = [$new => $this->config[$old]];
  678. $updateItems = array_merge($updateItems, $updateItemsNew);
  679. }
  680. }
  681. }
  682. return $updateItems;
  683. }
  684. public function removeOldCustomHTML()
  685. {
  686. $backup = $this->backupOrganizr();
  687. if ($backup) {
  688. $keys = [
  689. 'homepageCustomHTML01Enabled' => 'homepageCustomHTMLoneEnabled',
  690. 'homepageCustomHTML01Auth' => 'homepageCustomHTMLoneAuth',
  691. 'customHTML01' => 'customHTMLone',
  692. 'homepageCustomHTML02Enabled' => 'homepageCustomHTMLtwoEnabled',
  693. 'homepageCustomHTML02Auth' => 'homepageCustomHTMLtwoAuth',
  694. 'customHTML02' => 'customHTMLtwo',
  695. ];
  696. $updateItems = $this->checkForConfigKeyAddToArray($keys);
  697. $updateComplete = false;
  698. if (!empty($updateItems)) {
  699. $updateComplete = $this->updateConfig($updateItems);
  700. }
  701. if ($updateComplete) {
  702. $removeConfigItems = $this->removeConfigItem(['homepagCustomHTMLoneAuth', 'homepagCustomHTMLoneEnabled', 'homepagCustomHTMLtwoAuth', 'homepagCustomHTMLtwoEnabled', 'homepageOrdercustomhtml', 'homepageOrdercustomhtmlTwo', 'homepageCustomHTMLoneEnabled', 'homepageCustomHTMLoneAuth', 'customHTMLone', 'homepageCustomHTMLtwoEnabled', 'homepageCustomHTMLtwoAuth', 'customHTMLtwo']);
  703. if ($removeConfigItems) {
  704. return true;
  705. }
  706. }
  707. }
  708. return false;
  709. }
  710. public function addGroupIdMaxToDatabase()
  711. {
  712. $this->setLoggerChannel('Database Migration')->info('Starting database update');
  713. $hasOldColumn = $this->checkIfColumnExists('tabs', 'group_id_min');
  714. if ($hasOldColumn) {
  715. $this->setLoggerChannel('Database Migration')->info('Cleaning up database by removing old group_id_min');
  716. $removeColumn = $this->dropColumnFromDatabase('tabs', 'group_id_min');
  717. if ($removeColumn) {
  718. $this->setLoggerChannel('Database Migration')->info('Removed group_id_min from database');
  719. } else {
  720. $this->setLoggerChannel('Database Migration')->warning('Error removing group_id_min from database');
  721. }
  722. }
  723. $addColumn = $this->addColumnToDatabase('tabs', 'group_id_max', 'INTEGER DEFAULT \'0\'');
  724. if ($addColumn) {
  725. $this->setLoggerChannel('Database Migration')->notice('Added group_id_max to database');
  726. return true;
  727. } else {
  728. $this->setLoggerChannel('Database Migration')->warning('Could not update database');
  729. return false;
  730. }
  731. }
  732. public function addAddToAdminToDatabase()
  733. {
  734. $this->setLoggerChannel('Database Migration')->info('Starting database update');
  735. $addColumn = $this->addColumnToDatabase('tabs', 'add_to_admin', 'INTEGER DEFAULT \'0\'');
  736. if ($addColumn) {
  737. $this->setLoggerChannel('Database Migration')->notice('Added add_to_admin to database');
  738. return true;
  739. } else {
  740. $this->setLoggerChannel('Database Migration')->warning('Could not update database');
  741. return false;
  742. }
  743. }
  744. }