manage.php 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350
  1. <?php
  2. /**
  3. * Copyright (c) UNA, Inc - https://una.io
  4. * MIT License - https://opensource.org/licenses/MIT
  5. *
  6. * @defgroup UnaManageCmd UNA Manage command line script
  7. * @{
  8. */
  9. $GLOBALS['bx_profiler_disable'] = true;
  10. define('BX_DOL_CRON_EXECUTE', '1');
  11. /**
  12. * UNA command line interface
  13. */
  14. class BxDolManageCmd
  15. {
  16. protected $_sCmd;
  17. protected $_sCmdOptions;
  18. protected $_sPathToUna;
  19. protected $_aSiteConfig;
  20. protected $_isQuiet = false;
  21. protected $_aReturnCodes = array(
  22. 'success' => array ('code' => 0, 'msg' => 'Success.'),
  23. 'una not found' => array ('code' => 1, 'msg' => 'UNA wasn\'t found in the specified path: '),
  24. 'unknown cmd' => array ('code' => 2, 'msg' => 'Unknown command.'),
  25. 'db connect failed' => array ('code' => 3, 'msg' => 'Database connection failed: '),
  26. 'system update failed' => array ('code' => 4, 'msg' => 'System update failed: '),
  27. 'module operation failed' => array ('code' => 5, 'msg' => 'Module operation failed: '),
  28. 'error' => array ('code' => 9, 'msg' => 'Error occured.'),
  29. );
  30. public function __construct()
  31. {
  32. $this->_aSiteConfig = array (
  33. 'db_host' => '',
  34. 'db_port' => '',
  35. 'db_sock' => '',
  36. 'db_name' => '',
  37. 'db_user' => '',
  38. 'db_password' => '',
  39. );
  40. }
  41. public function main()
  42. {
  43. // set neccessary options
  44. $a = getopt('hqc:u:p:o:', $this->getOptions());
  45. if (isset($a['h']))
  46. $this->finish($this->_aReturnCodes['success']['code'], $this->getHelp());
  47. if (isset($a['q']))
  48. $this->_isQuiet = true;
  49. if (isset($a['u']))
  50. $this->_sPathToUna = $a['u'];
  51. if (isset($a['c']))
  52. $this->_sCmd = $a['c'];
  53. if (isset($a['o']))
  54. $this->_sCmdOptions = $a['o'];
  55. $this->_aSiteConfig = array_merge($this->_aSiteConfig, $a);
  56. // initialize environment
  57. $this->init();
  58. // run command
  59. $sMethod = $this->_sCmd ? 'cmd' . bx_gen_method_name($this->_sCmd) : 'cmdDefault';
  60. if (!method_exists($this, $sMethod))
  61. $this->finish($this->_aReturnCodes['unknown cmd']['code'], $this->_aReturnCodes['unknown cmd']['msg']);
  62. $this->$sMethod();
  63. $this->finish($this->_aReturnCodes['success']['code'], $this->_aReturnCodes['success']['msg']);
  64. }
  65. protected function getOptions()
  66. {
  67. $a = array ();
  68. foreach ($this->_aSiteConfig as $sKey => $sValue)
  69. if ('site_config' != $sKey)
  70. $a[] = "$sKey::";
  71. return $a;
  72. }
  73. protected function getHelp()
  74. {
  75. $s = "Usage: php manage.php [params]\n";
  76. $s .= str_pad("\t -h", 35) . "Print this help\n";
  77. $s .= str_pad("\t -q", 35) . "Quiet\n";
  78. $s .= str_pad("\t -u", 35) . "Path to UNA\n";
  79. $s .= str_pad("\t -c", 35) . "Command to run:\n";
  80. $s .= str_pad("\t", 39) . "- update - options:\n";
  81. $s .= str_pad("\t", 43) . "'ignore_version_check' to ignore version comparison in DB and files\n";
  82. $s .= str_pad("\t", 43) . "'skip_files_op' skip files oprations, such copying and deleting\n";
  83. $s .= str_pad("\t", 39) . "- check_update - no options\n";
  84. $s .= str_pad("\t", 39) . "- update_modules - options:\n";
  85. $s .= str_pad("\t", 43) . "comma separated list of modules paths (ex: 'boonex/ads,boonex/wiki')\n";
  86. $s .= str_pad("\t", 39) . "- check_modules_updates - no options\n";
  87. $s .= str_pad("\t", 39) . "- install_modules - options:\n";
  88. $s .= str_pad("\t", 43) . "comma separated list of modules paths (ex: 'boonex/ads,boonex/wiki')\n";
  89. $s .= str_pad("\t", 39) . "- uninstall_modules - options:\n";
  90. $s .= str_pad("\t", 43) . "comma separated list of modules paths (ex: 'boonex/ads,boonex/wiki')\n";
  91. $s .= str_pad("\t", 39) . "- disable_modules - options:\n";
  92. $s .= str_pad("\t", 43) . "comma separated list of modules paths (ex: 'boonex/ads,boonex/wiki')\n";
  93. $s .= str_pad("\t", 39) . "- enable_modules - options:\n";
  94. $s .= str_pad("\t", 43) . "comma separated list of modules paths (ex: 'boonex/ads,boonex/wiki')\n";
  95. $s .= str_pad("\t -o", 35) . "Command options\n";
  96. foreach ($this->_aSiteConfig as $sKey => $sVal)
  97. if ('site_config' != $sKey)
  98. $s .= str_pad("\t --{$sKey}=<value>", 35) . "Database connection params\n";
  99. $s .= "\nIf DB params aren't specified then UNA DB params from header.inc.php are used.\n\n";
  100. $s .= "Examples:\n";
  101. $s .= "\tCheck if update is available:\n";
  102. $s .= "\tphp ./manage.php -u ../../unafolder --db_name=unadb --db_user=root --db_host=mysql --db_password=root -c check_update\n\n";
  103. $s .= "\tCheck if updates for modules are available:\n";
  104. $s .= "\tphp ./manage.php -u ../../unafolder --db_name=unadb --db_user=root --db_host=mysql --db_password=root -c check_modules_updates\n\n";
  105. $s .= "\tInstall Ads and Albums modules:\n";
  106. $s .= "\tphp ./manage.php -u ../../unafolder --db_name=unadb --db_user=root --db_host=mysql --db_password=root -c install_modules -o boonex/ads,boonex/albums\n\n";
  107. $s .= "Return codes:\n";
  108. foreach ($this->_aReturnCodes as $r) {
  109. $s .= str_pad("\t {$r['code']}", 5) . $r['msg'] . (mb_substr(trim($r['msg']), -1) == ':' ? 'message' : '') . "\n";
  110. }
  111. return $s;
  112. }
  113. protected function finish($iCode, $sMsg)
  114. {
  115. if (!$this->_isQuiet)
  116. fwrite($iCode ? STDERR : STDOUT, $sMsg . "\n");
  117. exit($iCode);
  118. }
  119. protected function init()
  120. {
  121. $this->_sPathToUna = trim($this->_sPathToUna);
  122. if ('.' == $this->_sPathToUna)
  123. $this->_sPathToUna = '';
  124. if (!$this->_sPathToUna || '/' !== $this->_sPathToUna[0]) {
  125. $aPathInfo = pathinfo(__FILE__);
  126. $this->_sPathToUna = $aPathInfo['dirname'] . '/' . $this->_sPathToUna;
  127. }
  128. $this->_sPathToUna = rtrim($this->_sPathToUna, '/');
  129. // include header.inc.php
  130. $sHeaderPath = $this->_sPathToUna . '/inc/header.inc.php';
  131. if (!file_exists($sHeaderPath))
  132. $this->finish($this->_aReturnCodes['una not found']['code'], $this->_aReturnCodes['una not found']['msg'] . $sHeaderPath);
  133. require_once($sHeaderPath);
  134. // db connection
  135. if (!empty($this->_aSiteConfig['db_name'])) {
  136. BxDolDb::getInstance()->cacheParamsClear();
  137. BxDolDb::getInstance()->disconnect();
  138. unset($GLOBALS['bxDolClasses']['BxDolDb']);
  139. $sErr = null;
  140. try {
  141. $oDb = BxDolDb::getInstanceWithConf(array(
  142. 'host' => $this->_aSiteConfig['db_host'],
  143. 'port' => $this->_aSiteConfig['db_port'],
  144. 'sock' => $this->_aSiteConfig['db_sock'],
  145. 'name' => $this->_aSiteConfig['db_name'],
  146. 'user' => $this->_aSiteConfig['db_user'],
  147. 'pwd' => $this->_aSiteConfig['db_password'],
  148. ), $sErr);
  149. } catch (Exception $e) {
  150. $this->finish($this->_aReturnCodes['db connect failed']['code'], $this->_aReturnCodes['db connect failed']['msg'] . $e->getMessage());
  151. }
  152. }
  153. }
  154. function cmdCheckUpdate()
  155. {
  156. $oUpgrader = bx_instance('BxDolUpgrader');
  157. $aUpdateInfo = $oUpgrader->getVersionUpdateInfo();
  158. if (!isset($aUpdateInfo['patch']))
  159. $this->finish($this->_aReturnCodes['success']['code'], 'No system update available');
  160. $s = str_pad(bx_get_ver(), 12) . str_pad($aUpdateInfo['patch']['ver'], 12) . $aUpdateInfo['latest_version'];
  161. $this->finish($this->_aReturnCodes['success']['code'], $s);
  162. }
  163. function cmdUpdate()
  164. {
  165. $aOptions = $this->_parseOptions($this->_sCmdOptions);
  166. $oCronDb = BxDolCronQuery::getInstance();
  167. $aCronJobs = $oCronDb->getTransientJobs();
  168. if (!isset($aCronJobs['sys_perform_upgrade'])) {
  169. $oUpgrader = bx_instance('BxDolUpgrader');
  170. $aUpdateInfo = $oUpgrader->getVersionUpdateInfo();
  171. $bUpgrade = $oUpgrader->isUpgradeAvailable($aUpdateInfo);
  172. if (!$bUpgrade)
  173. $this->finish($this->_aReturnCodes['system update failed']['code'], $this->_aReturnCodes['system update failed']['msg'] . 'you have up to date version');
  174. if(!$oUpgrader->prepare(false, in_array('ignore_version_check', $aOptions)))
  175. $this->finish($this->_aReturnCodes['system update failed']['code'], $this->_aReturnCodes['system update failed']['msg'] . $oUpgrader->getError());
  176. }
  177. $aCronJobs = $oCronDb->getTransientJobs();
  178. if (empty($aCronJobs['sys_perform_upgrade']))
  179. $this->finish($this->_aReturnCodes['system update failed']['code'], $this->_aReturnCodes['system update failed']['msg'] . 'no cron job with patch path was found');
  180. $sPatchDir = BX_DIRECTORY_PATH_ROOT . $aCronJobs['sys_perform_upgrade']['file'];
  181. $sPatchDir = str_replace('BxDolUpgradeCron.php', '', $sPatchDir);
  182. define ('BX_UPGRADE_DIR_UPGRADES', $sPatchDir . 'files/');
  183. require_once($sPatchDir . 'classes/BxDolUpgradeController.php');
  184. require_once($sPatchDir . 'classes/BxDolUpgradeUtil.php');
  185. require_once($sPatchDir . 'classes/BxDolUpgradeDb.php');
  186. $oController = new BxDolUpgradeController();
  187. if ($oController->setMaintenanceMode(true)) {
  188. $sFolder = $oController->getAvailableUpgrade();
  189. if ($sFolder && $oController->runUpgrade($sFolder, in_array('ignore_version_check', $aOptions), in_array('skip_files_op', $aOptions))) {
  190. setParam('sys_revision', getParam('sys_revision') + 1);
  191. @bx_rrmdir($sUpgradeDir);
  192. }
  193. $oController->setMaintenanceMode(false);
  194. }
  195. $oCronDb->deleteTransientJobs();
  196. if ($sErrorMsg = $oController->getErrorMsg()) {
  197. $this->finish($this->_aReturnCodes['system update failed']['code'], $this->_aReturnCodes['system update failed']['msg'] . $sErrorMsg);
  198. }
  199. }
  200. function cmdCheckModulesUpdates()
  201. {
  202. $aDownloaded = BxDolStudioInstallerUtils::getInstance()->getUpdates();
  203. $a = BxDolStudioInstallerUtils::getInstance()->checkUpdates();
  204. if (!$a)
  205. $this->finish($this->_aReturnCodes['success']['code'], 'No modules updates available');
  206. $s = '';
  207. foreach ($a as $r) {
  208. $s .= str_pad($r['name'], 20) . str_pad($r['file_version'], 12) . str_pad($r['file_version_to'], 12);
  209. foreach ($aDownloaded as $j) {
  210. if ($j['module_name'] == $r['name'])
  211. $s .= $j['dir'];
  212. }
  213. $s .= "\n";
  214. }
  215. $this->finish($this->_aReturnCodes['success']['code'], trim($s));
  216. }
  217. function cmdUpdateModules()
  218. {
  219. // TODO: option to disable files operations
  220. $aModules = $this->_parseOptions($this->_sCmdOptions);
  221. if (!$aModules)
  222. $this->finish($this->_aReturnCodes['module operation failed']['code'], 'No modules were provided');
  223. $bErr = false;
  224. $s = "";
  225. $a = BxDolStudioInstallerUtils::getInstance()->getUpdates();
  226. if (!$a)
  227. $this->finish($this->_aReturnCodes['success']['code'], 'No modules updates available');
  228. foreach ($a as $r) {
  229. if (!in_array($r['module_name'], $aModules) && !in_array($r['module_dir'], $aModules))
  230. continue;
  231. $aRes = BxDolStudioInstallerUtils::getInstance()->perform($r['dir'], 'update', ['module_name' => $r['module_name']]);
  232. $s .= str_pad($r['module_name'], 20);
  233. if (!isset($aRes['code']) || $aRes['code'] !== BX_DOL_STUDIO_IU_RC_SUCCESS) {
  234. $bErr = true;
  235. $s .= "ERROR " . html_entity_decode($aRes['message']) . "\n";
  236. } else {
  237. $s .= "OK\n";
  238. }
  239. }
  240. $iCode = $bErr ? $this->_aReturnCodes['module operation failed']['code'] : $this->_aReturnCodes['success']['code'];
  241. $this->finish($iCode, trim($s));
  242. /*
  243. BxDolStudioInstallerUtils::getInstance()->performModulesUpgrade(array(
  244. 'directly' => true,
  245. 'transient' => false,
  246. 'autoupdate' => true
  247. ));
  248. */
  249. }
  250. function cmdInstallModules()
  251. {
  252. $this->_cmdModules('install', ['auto_enable' => true, 'html_response' => false]);
  253. }
  254. function cmdUninstallModules()
  255. {
  256. $this->_cmdModules('uninstall', ['html_response' => false]);
  257. }
  258. function cmdEnableModules()
  259. {
  260. $this->_cmdModules('enable', ['html_response' => false]);
  261. }
  262. function cmdDisableModules()
  263. {
  264. $this->_cmdModules('disable', ['html_response' => false]);
  265. }
  266. function _parseOptions($s)
  267. {
  268. if (!$s)
  269. return [];
  270. $a = explode(',', trim($s));
  271. foreach ($a as $k => $v)
  272. $a[$k] = trim($v);
  273. return $a;
  274. }
  275. function _cmdModules($sOperation, $aOptions = [])
  276. {
  277. $aModules = $this->_parseOptions($this->_sCmdOptions);
  278. foreach ($aModules as $sModule) {
  279. $sModule = trim($sModule, '/') . '/';
  280. $a = BxDolStudioInstallerUtils::getInstance()->perform($sModule, $sOperation, array('auto_enable' => true, 'html_response' => false));
  281. if (!isset($a['code']) || $a['code'] !== BX_DOL_STUDIO_IU_RC_SUCCESS)
  282. $this->finish($this->_aReturnCodes['module operation failed']['code'], $this->_aReturnCodes['module operation failed']['msg'] . (!empty($a['message']) ? $a['message'] : 'Error occured.') . ' (' . $sOperation . ': ' . $sModule . ')');
  283. }
  284. }
  285. }
  286. $o = new BxDolManageCmd();
  287. $o->main();
  288. /** @} */