upgrade-functions.php 25 KB

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