upgrade-functions.php 26 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758
  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. $query = [
  397. [
  398. 'function' => 'query',
  399. 'query' => [
  400. 'UPDATE tabs SET group_id_max=0'
  401. ]
  402. ],
  403. ];
  404. $tabs = $this->processQueries($query);
  405. if (!$tabs) {
  406. $this->setResponse(500, 'An error occurred');
  407. return false;
  408. }
  409. break;
  410. default:
  411. $this->setResponse(404, 'Feature not found in reset update');
  412. return false;
  413. }
  414. $this->setResponse(200, 'Ran reset update feature for ' . $feature);
  415. return true;
  416. }
  417. public function upgradeToVersion($version = '2.1.0')
  418. {
  419. $this->setLoggerChannel('Upgrade')->notice('Starting upgrade to version ' . $version);
  420. switch ($version) {
  421. case '2.1.0':
  422. $this->upgradeSettingsTabURL();
  423. $this->upgradeHomepageTabURL();
  424. break;
  425. case '2.1.400':
  426. $this->removeOldPluginDirectoriesAndFiles();
  427. break;
  428. case '2.1.525':
  429. $this->removeOldCustomHTML();
  430. break;
  431. case '2.1.860':
  432. $this->upgradeInstalledPluginsConfigItem();
  433. break;
  434. case '2.1.1500':
  435. $this->upgradeDataToFolder();
  436. break;
  437. case '2.1.1860':
  438. $this->upgradePluginsToDataFolder();
  439. break;
  440. case '2.1.2200':
  441. $this->backupOrganizr();
  442. $this->addGroupIdMaxToDatabase();
  443. $this->addAddToAdminToDatabase();
  444. break;
  445. }
  446. $this->setLoggerChannel('Upgrade')->notice('Finished upgrade to version ' . $version);
  447. $this->setAPIResponse('success', 'Ran update function for version: ' . $version, 200);
  448. return true;
  449. }
  450. public function removeOldCacheFolder()
  451. {
  452. $folder = $this->root . DIRECTORY_SEPARATOR . 'plugins' . DIRECTORY_SEPARATOR . 'images' . DIRECTORY_SEPARATOR . 'cache' . DIRECTORY_SEPARATOR;
  453. $this->setLoggerChannel('Migration');
  454. $this->logger->info('Running Old Cache folder migration');
  455. if (file_exists($folder)) {
  456. $this->rrmdir($folder);
  457. $this->logger->info('Old Cache folder found');
  458. $this->logger->info('Removed Old Cache folder');
  459. }
  460. return true;
  461. }
  462. public function upgradeDataToFolder()
  463. {
  464. if ($this->hasDB()) {
  465. // Make main data folder
  466. $rootFolderMade = $this->makeDir($this->root . DIRECTORY_SEPARATOR . 'data');
  467. // Make config folder child
  468. $this->makeDir($this->root . DIRECTORY_SEPARATOR . 'data' . DIRECTORY_SEPARATOR . 'config' . DIRECTORY_SEPARATOR);
  469. if ($rootFolderMade) {
  470. // Migrate over userTabs folder
  471. $this->makeDir($this->root . DIRECTORY_SEPARATOR . 'data' . DIRECTORY_SEPARATOR . 'userTabs');
  472. if ($this->rcopy($this->root . DIRECTORY_SEPARATOR . 'plugins' . DIRECTORY_SEPARATOR . 'images' . DIRECTORY_SEPARATOR . 'userTabs', $this->root . DIRECTORY_SEPARATOR . 'data' . DIRECTORY_SEPARATOR . 'userTabs')) {
  473. // Convert tabs over
  474. $query = [
  475. [
  476. 'function' => 'fetchAll',
  477. 'query' => [
  478. 'SELECT * FROM tabs WHERE image like "%userTabs%"'
  479. ]
  480. ],
  481. ];
  482. $tabs = $this->processQueries($query);
  483. if (count($tabs) > 0) {
  484. foreach ($tabs as $tab) {
  485. $newImage = str_replace('plugins/images/userTabs', 'data/userTabs', $tab['image']);
  486. $updateQuery = [
  487. [
  488. 'function' => 'query',
  489. 'query' => [
  490. 'UPDATE tabs SET',
  491. ['image' => $newImage],
  492. 'WHERE id = ?',
  493. $tab['id']
  494. ]
  495. ],
  496. ];
  497. $this->processQueries($updateQuery);
  498. }
  499. }
  500. $this->setLoggerChannel('Migration');
  501. $this->logger->info('The folder "userTabs" was migrated to new data folder');
  502. }
  503. // Migrate over custom cert
  504. if (file_exists($this->root . DIRECTORY_SEPARATOR . 'api' . DIRECTORY_SEPARATOR . 'functions' . DIRECTORY_SEPARATOR . 'cert' . DIRECTORY_SEPARATOR . 'custom.pem')) {
  505. // Make cert folder child
  506. $this->makeDir($this->root . DIRECTORY_SEPARATOR . 'data' . DIRECTORY_SEPARATOR . 'cert' . DIRECTORY_SEPARATOR);
  507. 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')) {
  508. $this->setLoggerChannel('Migration');
  509. $this->logger->info('Moved over custom cert file');
  510. }
  511. }
  512. // Migrate over favIcon
  513. $this->makeDir($this->root . DIRECTORY_SEPARATOR . 'data' . DIRECTORY_SEPARATOR . 'favicon');
  514. if ($this->rcopy($this->root . DIRECTORY_SEPARATOR . 'plugins' . DIRECTORY_SEPARATOR . 'images' . DIRECTORY_SEPARATOR . 'faviconCustom', $this->root . DIRECTORY_SEPARATOR . 'data' . DIRECTORY_SEPARATOR . 'favicon')) {
  515. if ($this->config['favIcon'] !== '') {
  516. $this->config['favIcon'] = str_replace('plugins/images/faviconCustom', 'data/favicon', $this->config['favIcon']);
  517. $this->updateConfig(array('favIcon' => $this->config['favIcon']));
  518. }
  519. $this->setLoggerChannel('Migration');
  520. $this->logger->info('Favicon was migrated over');
  521. }
  522. // Migrate over custom pages
  523. $this->makeDir($this->root . DIRECTORY_SEPARATOR . 'data' . DIRECTORY_SEPARATOR . 'pages');
  524. if (file_exists($this->root . DIRECTORY_SEPARATOR . 'api' . DIRECTORY_SEPARATOR . 'pages' . DIRECTORY_SEPARATOR . 'custom')) {
  525. if ($this->rcopy($this->root . DIRECTORY_SEPARATOR . 'api' . DIRECTORY_SEPARATOR . 'pages' . DIRECTORY_SEPARATOR . 'custom', $this->root . DIRECTORY_SEPARATOR . 'data' . DIRECTORY_SEPARATOR . 'pages')) {
  526. $this->rrmdir($this->root . DIRECTORY_SEPARATOR . 'api' . DIRECTORY_SEPARATOR . 'pages' . DIRECTORY_SEPARATOR . 'custom');
  527. $this->setLoggerChannel('Migration');
  528. $this->logger->info('Custom pages was migrated over');
  529. }
  530. }
  531. // Migrate over custom routes
  532. $this->makeDir($this->root . DIRECTORY_SEPARATOR . 'data' . DIRECTORY_SEPARATOR . 'routes');
  533. if (file_exists($this->root . DIRECTORY_SEPARATOR . 'api' . DIRECTORY_SEPARATOR . 'v2' . DIRECTORY_SEPARATOR . 'routes' . DIRECTORY_SEPARATOR . 'custom')) {
  534. 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')) {
  535. $this->rrmdir($this->root . DIRECTORY_SEPARATOR . 'api' . DIRECTORY_SEPARATOR . 'v2' . DIRECTORY_SEPARATOR . 'routes' . DIRECTORY_SEPARATOR . 'custom');
  536. $this->setLoggerChannel('Migration');
  537. $this->logger->info('Custom routes was migrated over');
  538. }
  539. }
  540. // Migrate over cache folder
  541. $this->removeOldCacheFolder();
  542. }
  543. return true;
  544. }
  545. return false;
  546. }
  547. public function upgradePluginsToDataFolder()
  548. {
  549. if ($this->hasDB()) {
  550. // Make main data folder
  551. $rootFolderMade = $this->makeDir($this->root . DIRECTORY_SEPARATOR . 'data');
  552. if ($rootFolderMade) {
  553. // Migrate over plugins folder
  554. $this->makeDir($this->root . DIRECTORY_SEPARATOR . 'data' . DIRECTORY_SEPARATOR . 'plugins');
  555. $plexLibraries = $this->root . DIRECTORY_SEPARATOR . 'api' . DIRECTORY_SEPARATOR . 'plugins' . DIRECTORY_SEPARATOR . 'plexLibraries';
  556. if (file_exists($plexLibraries)) {
  557. if (rename($plexLibraries, $this->root . DIRECTORY_SEPARATOR . 'data' . DIRECTORY_SEPARATOR . 'plugins' . DIRECTORY_SEPARATOR . 'plexLibraries')) {
  558. $this->setLoggerChannel('Migration');
  559. $this->logger->info('The plugin folder "plexLibraries" was migrated to new data folder');
  560. }
  561. }
  562. $test = $this->root . DIRECTORY_SEPARATOR . 'api' . DIRECTORY_SEPARATOR . 'plugins' . DIRECTORY_SEPARATOR . 'test';
  563. if (file_exists($test)) {
  564. if (rename($test, $this->root . DIRECTORY_SEPARATOR . 'data' . DIRECTORY_SEPARATOR . 'plugins' . DIRECTORY_SEPARATOR . 'test')) {
  565. $this->setLoggerChannel('Migration');
  566. $this->logger->info('The plugin folder "test" was migrated to new data folder');
  567. }
  568. }
  569. }
  570. return true;
  571. }
  572. return false;
  573. }
  574. public function upgradeSettingsTabURL()
  575. {
  576. $response = [
  577. array(
  578. 'function' => 'query',
  579. 'query' => array(
  580. 'UPDATE tabs SET',
  581. ['url' => 'api/v2/page/settings'],
  582. 'WHERE url = ?',
  583. 'api/?v1/settings/page'
  584. )
  585. ),
  586. ];
  587. return $this->processQueries($response);
  588. }
  589. public function upgradeHomepageTabURL()
  590. {
  591. $response = [
  592. array(
  593. 'function' => 'query',
  594. 'query' => array(
  595. 'UPDATE tabs SET',
  596. ['url' => 'api/v2/page/homepage'],
  597. 'WHERE url = ?',
  598. 'api/?v1/homepage/page'
  599. )
  600. ),
  601. ];
  602. return $this->processQueries($response);
  603. }
  604. public function upgradeInstalledPluginsConfigItem()
  605. {
  606. $oldConfigItem = $this->config['installedPlugins'];
  607. if (gettype($oldConfigItem) == 'string') {
  608. if ((strpos($oldConfigItem, '|') !== false)) {
  609. $newPlugins = [];
  610. $plugins = explode('|', $oldConfigItem);
  611. foreach ($plugins as $plugin) {
  612. $info = explode(':', $plugin);
  613. $newPlugins[$info[0]] = [
  614. 'name' => $info[0],
  615. 'version' => $info[1],
  616. 'repo' => 'organizr'
  617. ];
  618. }
  619. } else {
  620. $newPlugins = [];
  621. if ($oldConfigItem !== '') {
  622. $info = explode(':', $oldConfigItem);
  623. $newPlugins[$info[0]] = [
  624. 'name' => $info[0],
  625. 'version' => $info[1],
  626. 'repo' => 'https://github.com/Organizr/Organizr-Plugins'
  627. ];
  628. }
  629. }
  630. $this->updateConfig(['installedPlugins' => $newPlugins]);
  631. } elseif (gettype($oldConfigItem) == 'array') {
  632. $this->updateConfig(['installedPlugins' => $oldConfigItem]);
  633. }
  634. return true;
  635. }
  636. public function removeOldPluginDirectoriesAndFiles()
  637. {
  638. $folders = [
  639. $this->root . DIRECTORY_SEPARATOR . 'api' . DIRECTORY_SEPARATOR . 'plugins' . DIRECTORY_SEPARATOR . 'api',
  640. $this->root . DIRECTORY_SEPARATOR . 'api' . DIRECTORY_SEPARATOR . 'plugins' . DIRECTORY_SEPARATOR . 'config',
  641. $this->root . DIRECTORY_SEPARATOR . 'api' . DIRECTORY_SEPARATOR . 'plugins' . DIRECTORY_SEPARATOR . 'css',
  642. $this->root . DIRECTORY_SEPARATOR . 'api' . DIRECTORY_SEPARATOR . 'plugins' . DIRECTORY_SEPARATOR . 'js',
  643. $this->root . DIRECTORY_SEPARATOR . 'api' . DIRECTORY_SEPARATOR . 'plugins' . DIRECTORY_SEPARATOR . 'misc',
  644. ];
  645. $files = [
  646. $this->root . DIRECTORY_SEPARATOR . 'api' . DIRECTORY_SEPARATOR . 'plugins' . DIRECTORY_SEPARATOR . 'bookmark.php',
  647. $this->root . DIRECTORY_SEPARATOR . 'api' . DIRECTORY_SEPARATOR . 'plugins' . DIRECTORY_SEPARATOR . 'chat.php',
  648. $this->root . DIRECTORY_SEPARATOR . 'api' . DIRECTORY_SEPARATOR . 'plugins' . DIRECTORY_SEPARATOR . 'healthChecks.php',
  649. $this->root . DIRECTORY_SEPARATOR . 'api' . DIRECTORY_SEPARATOR . 'plugins' . DIRECTORY_SEPARATOR . 'invites.php',
  650. $this->root . DIRECTORY_SEPARATOR . 'api' . DIRECTORY_SEPARATOR . 'plugins' . DIRECTORY_SEPARATOR . 'php-mailer.php',
  651. $this->root . DIRECTORY_SEPARATOR . 'api' . DIRECTORY_SEPARATOR . 'plugins' . DIRECTORY_SEPARATOR . 'speedTest.php',
  652. ];
  653. foreach ($files as $file) {
  654. if (file_exists($file)) {
  655. @unlink($file);
  656. }
  657. }
  658. foreach ($folders as $folder) {
  659. if (file_exists($folder)) {
  660. @$this->rrmdir($folder);
  661. }
  662. }
  663. return true;
  664. }
  665. public function checkForConfigKeyAddToArray($keys)
  666. {
  667. $updateItems = [];
  668. foreach ($keys as $new => $old) {
  669. if (isset($this->config[$old])) {
  670. if ($this->config[$old] !== '') {
  671. $updateItemsNew = [$new => $this->config[$old]];
  672. $updateItems = array_merge($updateItems, $updateItemsNew);
  673. }
  674. }
  675. }
  676. return $updateItems;
  677. }
  678. public function removeOldCustomHTML()
  679. {
  680. $backup = $this->backupOrganizr();
  681. if ($backup) {
  682. $keys = [
  683. 'homepageCustomHTML01Enabled' => 'homepageCustomHTMLoneEnabled',
  684. 'homepageCustomHTML01Auth' => 'homepageCustomHTMLoneAuth',
  685. 'customHTML01' => 'customHTMLone',
  686. 'homepageCustomHTML02Enabled' => 'homepageCustomHTMLtwoEnabled',
  687. 'homepageCustomHTML02Auth' => 'homepageCustomHTMLtwoAuth',
  688. 'customHTML02' => 'customHTMLtwo',
  689. ];
  690. $updateItems = $this->checkForConfigKeyAddToArray($keys);
  691. $updateComplete = false;
  692. if (!empty($updateItems)) {
  693. $updateComplete = $this->updateConfig($updateItems);
  694. }
  695. if ($updateComplete) {
  696. $removeConfigItems = $this->removeConfigItem(['homepagCustomHTMLoneAuth', 'homepagCustomHTMLoneEnabled', 'homepagCustomHTMLtwoAuth', 'homepagCustomHTMLtwoEnabled', 'homepageOrdercustomhtml', 'homepageOrdercustomhtmlTwo', 'homepageCustomHTMLoneEnabled', 'homepageCustomHTMLoneAuth', 'customHTMLone', 'homepageCustomHTMLtwoEnabled', 'homepageCustomHTMLtwoAuth', 'customHTMLtwo']);
  697. if ($removeConfigItems) {
  698. return true;
  699. }
  700. }
  701. }
  702. return false;
  703. }
  704. public function addGroupIdMaxToDatabase()
  705. {
  706. $this->setLoggerChannel('Database Migration')->info('Starting database update');
  707. $hasOldColumn = $this->checkIfColumnExists('tabs', 'group_id_min');
  708. if ($hasOldColumn) {
  709. $this->setLoggerChannel('Database Migration')->info('Cleaning up database by removing old group_id_min');
  710. $removeColumn = $this->dropColumnFromDatabase('tabs', 'group_id_min');
  711. if ($removeColumn) {
  712. $this->setLoggerChannel('Database Migration')->info('Removed group_id_min from database');
  713. } else {
  714. $this->setLoggerChannel('Database Migration')->warning('Error removing group_id_min from database');
  715. }
  716. }
  717. $addColumn = $this->addColumnToDatabase('tabs', 'group_id_max', 'INTEGER DEFAULT \'0\'');
  718. if ($addColumn) {
  719. $this->setLoggerChannel('Database Migration')->notice('Added group_id_max to database');
  720. return true;
  721. } else {
  722. $this->setLoggerChannel('Database Migration')->warning('Could not update database');
  723. return false;
  724. }
  725. }
  726. public function addAddToAdminToDatabase()
  727. {
  728. $this->setLoggerChannel('Database Migration')->info('Starting database update');
  729. $addColumn = $this->addColumnToDatabase('tabs', 'add_to_admin', 'INTEGER DEFAULT \'0\'');
  730. if ($addColumn) {
  731. $this->setLoggerChannel('Database Migration')->notice('Added add_to_admin to database');
  732. return true;
  733. } else {
  734. $this->setLoggerChannel('Database Migration')->warning('Could not update database');
  735. return false;
  736. }
  737. }
  738. }