replication_gui.lib.php 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401
  1. <?php
  2. /* vim: set expandtab sw=4 ts=4 sts=4: */
  3. /**
  4. *
  5. * @package PhpMyAdmin
  6. */
  7. if (! defined('PHPMYADMIN')) {
  8. exit;
  9. }
  10. /**
  11. * returns code for selecting databases
  12. *
  13. * @return String HTML code
  14. */
  15. function PMA_replication_db_multibox()
  16. {
  17. $multi_values = '';
  18. $multi_values .= '<select name="db_select[]" size="6" multiple="multiple" id="db_select">';
  19. foreach ($GLOBALS['pma']->databases as $current_db) {
  20. if (PMA_is_system_schema($current_db)) {
  21. continue;
  22. }
  23. if (! empty($selectall) || (isset($tmp_select) && strpos(' ' . $tmp_select, '|' . $current_db . '|'))) {
  24. $is_selected = ' selected="selected"';
  25. } else {
  26. $is_selected = '';
  27. }
  28. $current_db = htmlspecialchars($current_db);
  29. $multi_values .= ' <option value="' . $current_db . '" ' . $is_selected . '>' . $current_db . '</option>';
  30. } // end while
  31. $multi_values .= '</select>';
  32. $multi_values .= '<br /><a href="#" id="db_reset_href">' . __('Uncheck All') . '</a>';
  33. return $multi_values;
  34. }
  35. /**
  36. * prints out code for changing master
  37. *
  38. * @param String $submitname - submit button name
  39. *
  40. * @return void
  41. */
  42. function PMA_replication_gui_changemaster($submitname)
  43. {
  44. list($username_length, $hostname_length) = PMA_replication_get_username_hostname_length();
  45. echo '<form method="post" action="server_replication.php">';
  46. echo PMA_generate_common_hidden_inputs('', '');
  47. echo ' <fieldset id="fieldset_add_user_login">';
  48. echo ' <legend>' . __('Slave configuration') . ' - ' . __('Change or reconfigure master server') . '</legend>';
  49. echo __('Make sure, you have unique server-id in your configuration file (my.cnf). If not, please add the following line into [mysqld] section:') . '<br />';
  50. echo '<pre>server-id=' . time() . '</pre>';
  51. echo ' <div class="item">';
  52. echo ' <label for="text_username">' . __('User name') . ':</label>';
  53. echo ' <input type="text" name="username" id="text_username" maxlength="'. $username_length . '" title="' . __('User name') . '" />';
  54. echo ' </div>';
  55. echo ' <div class="item">';
  56. echo ' <label for="text_pma_pw">' . __('Password') .' :</label>';
  57. echo ' <input type="password" id="text_pma_pw" name="pma_pw" title="' . __('Password') . '" />';
  58. echo ' </div>';
  59. echo ' <div class="item">';
  60. echo ' <label for="text_hostname">' . __('Host') . ' :</label>';
  61. echo ' <input type="text" id="text_hostname" name="hostname" maxlength="' . $hostname_length . '" value="" />';
  62. echo ' </div>';
  63. echo ' <div class="item">';
  64. echo ' <label for="text_port">' . __('Port') . ':</label>';
  65. echo ' <input type="text" id="text_port" name="port" maxlength="6" value="3306" />';
  66. echo ' </div>';
  67. echo ' </fieldset>';
  68. echo ' <fieldset id="fieldset_user_privtable_footer" class="tblFooters">';
  69. echo ' <input type="hidden" name="sr_take_action" value="true" />';
  70. echo ' <input type="hidden" name="' . $submitname . '" value="1" />';
  71. echo ' <input type="submit" id="confslave_submit" value="' . __('Go') . '" />';
  72. echo ' </fieldset>';
  73. echo '</form>';
  74. }
  75. /**
  76. * This function prints out table with replication status.
  77. *
  78. * @param string $type either master or slave
  79. * @param boolean $hidden if true, then default style is set to hidden, default value false
  80. * @param boolen $title if true, then title is displayed, default true
  81. *
  82. * @return void
  83. */
  84. function PMA_replication_print_status_table($type, $hidden = false, $title = true)
  85. {
  86. global ${"{$type}_variables"};
  87. global ${"{$type}_variables_alerts"};
  88. global ${"{$type}_variables_oks"};
  89. global ${"server_{$type}_replication"};
  90. global ${"strReplicationStatus_{$type}"};
  91. // TODO check the Masters server id?
  92. // seems to default to '1' when queried via SHOW VARIABLES , but resulted in error on the master when slave connects
  93. // [ERROR] Error reading packet from server: Misconfigured master - server id was not set ( server_errno=1236)
  94. // [ERROR] Got fatal error 1236: 'Misconfigured master - server id was not set' from master when reading data from binary log
  95. //
  96. //$server_id = PMA_DBI_fetch_value("SHOW VARIABLES LIKE 'server_id'", 0, 1);
  97. echo '<div id="replication_' . $type . '_section" style="' . ($hidden ? 'display: none;' : '') . '"> ';
  98. if ($title) {
  99. if ($type == 'master') {
  100. echo '<h4><a name="replication_' . $type . '"></a>' . __('Master status') . '</h4>';
  101. } else {
  102. echo '<h4><a name="replication_' . $type . '"></a>' . __('Slave status') . '</h4>';
  103. }
  104. } else {
  105. echo '<br />';
  106. }
  107. echo ' <table id="server' . $type . 'replicationsummary" class="data"> ';
  108. echo ' <thead>';
  109. echo ' <tr>';
  110. echo ' <th>' . __('Variable') . '</th>';
  111. echo ' <th>' . __('Value') . '</th>';
  112. echo ' </tr>';
  113. echo ' </thead>';
  114. echo ' <tbody>';
  115. $odd_row = true;
  116. foreach (${"{$type}_variables"} as $variable) {
  117. echo ' <tr class="' . ($odd_row ? 'odd' : 'even') . '">';
  118. echo ' <td class="name">';
  119. echo htmlspecialchars($variable);
  120. echo ' </td>';
  121. echo ' <td class="value">';
  122. // TODO change to regexp or something, to allow for negative match
  123. if (isset(${"{$type}_variables_alerts"}[$variable])
  124. && ${"{$type}_variables_alerts"}[$variable] == ${"server_{$type}_replication"}[0][$variable]
  125. ) {
  126. echo '<span class="attention">';
  127. } elseif (isset(${"{$type}_variables_oks"}[$variable])
  128. && ${"{$type}_variables_oks"}[$variable] == ${"server_{$type}_replication"}[0][$variable]
  129. ) {
  130. echo '<span class="allfine">';
  131. } else {
  132. echo '<span>';
  133. }
  134. // allow wrapping long table lists into multiple lines
  135. static $variables_wrap = array(
  136. 'Replicate_Do_DB', 'Replicate_Ignore_DB',
  137. 'Replicate_Do_Table', 'Replicate_Ignore_Table',
  138. 'Replicate_Wild_Do_Table', 'Replicate_Wild_Ignore_Table');
  139. if (in_array($variable, $variables_wrap)) {
  140. echo htmlspecialchars(str_replace(',', ', ', ${"server_{$type}_replication"}[0][$variable]));
  141. } else {
  142. echo htmlspecialchars(${"server_{$type}_replication"}[0][$variable]);
  143. }
  144. echo '</span>';
  145. echo ' </td>';
  146. echo ' </tr>';
  147. $odd_row = ! $odd_row;
  148. }
  149. echo ' </tbody>';
  150. echo ' </table>';
  151. echo ' <br />';
  152. echo '</div>';
  153. }
  154. /**
  155. * Prints table with slave users connected to this master
  156. *
  157. * @param boolean $hidden - if true, then default style is set to hidden, default value false
  158. *
  159. * @return void
  160. */
  161. function PMA_replication_print_slaves_table($hidden = false)
  162. {
  163. // Fetch data
  164. $data = PMA_DBI_fetch_result('SHOW SLAVE HOSTS', null, null);
  165. echo ' <br />';
  166. echo ' <div id="replication_slaves_section" style="' . ($hidden ? 'display: none;' : '') . '"> ';
  167. echo ' <table class="data">';
  168. echo ' <thead>';
  169. echo ' <tr>';
  170. echo ' <th>' . __('Server ID') . '</th>';
  171. echo ' <th>' . __('Host') . '</th>';
  172. echo ' </tr>';
  173. echo ' </thead>';
  174. echo ' <tbody>';
  175. $odd_row = true;
  176. foreach ($data as $slave) {
  177. echo ' <tr class="' . ($odd_row ? 'odd' : 'even') . '">';
  178. echo ' <td class="value">' . $slave['Server_id'] . '</td>';
  179. echo ' <td class="value">' . $slave['Host'] . '</td>';
  180. echo ' </tr>';
  181. $odd_row = ! $odd_row;
  182. }
  183. echo ' </tbody>';
  184. echo ' </table>';
  185. echo ' <br />';
  186. PMA_Message::notice(__('Only slaves started with the --report-host=host_name option are visible in this list.'))->display();
  187. echo ' <br />';
  188. echo ' </div>';
  189. }
  190. /**
  191. * get the correct username and hostname lengths for this MySQL server
  192. *
  193. * @return array username length, hostname length
  194. */
  195. function PMA_replication_get_username_hostname_length()
  196. {
  197. $fields_info = PMA_DBI_get_columns('mysql', 'user');
  198. $username_length = 16;
  199. $hostname_length = 41;
  200. foreach ($fields_info as $val) {
  201. if ($val['Field'] == 'User') {
  202. strtok($val['Type'], '()');
  203. $v = strtok('()');
  204. if (is_int($v)) {
  205. $username_length = $v;
  206. }
  207. } elseif ($val['Field'] == 'Host') {
  208. strtok($val['Type'], '()');
  209. $v = strtok('()');
  210. if (is_int($v)) {
  211. $hostname_length = $v;
  212. }
  213. }
  214. }
  215. return array($username_length, $hostname_length);
  216. }
  217. /**
  218. * Print code to add a replication slave user to the master
  219. *
  220. * @return void
  221. */
  222. function PMA_replication_gui_master_addslaveuser()
  223. {
  224. list($username_length, $hostname_length) = PMA_replication_get_username_hostname_length();
  225. if (isset($GLOBALS['username']) && strlen($GLOBALS['username']) === 0) {
  226. $GLOBALS['pred_username'] = 'any';
  227. }
  228. echo '<div id="master_addslaveuser_gui">';
  229. echo '<form autocomplete="off" method="post" action="server_privileges.php" onsubmit="return checkAddUser(this);">';
  230. echo PMA_generate_common_hidden_inputs('', '');
  231. echo '<fieldset id="fieldset_add_user_login">'
  232. . '<legend>'.__('Add slave replication user').'</legend>'
  233. . '<input type="hidden" name="grant_count" value="25" />'
  234. . '<input type="hidden" name="createdb" id="createdb_0" value="0" />'
  235. . '<input id="checkbox_Repl_slave_priv" type="hidden" title="Needed for the replication slaves." value="Y" name="Repl_slave_priv"/>'
  236. . '<input id="checkbox_Repl_client_priv" type="hidden" title="Needed for the replication slaves." value="Y" name="Repl_client_priv"/>'
  237. . ''
  238. . '<input type="hidden" name="sr_take_action" value="true" />'
  239. . '<div class="item">'
  240. . '<label for="select_pred_username">'
  241. . ' ' . __('User name') . ':'
  242. . '</label>'
  243. . '<span class="options">'
  244. . ' <select name="pred_username" id="select_pred_username" title="' . __('User name') . '"'
  245. . ' onchange="if (this.value == \'any\') { username.value = \'\'; } else if (this.value == \'userdefined\') { username.focus(); username.select(); }">'
  246. . ' <option value="any"' . ((isset($GLOBALS['pred_username']) && $GLOBALS['pred_username'] == 'any') ? ' selected="selected"' : '') . '>' . __('Any user') . '</option>'
  247. . ' <option value="userdefined"' . ((! isset($GLOBALS['pred_username']) || $GLOBALS['pred_username'] == 'userdefined') ? ' selected="selected"' : '') . '>' . __('Use text field') . ':</option>'
  248. . ' </select>'
  249. . '</span>'
  250. . '<input type="text" name="username" maxlength="'
  251. . $username_length . '" title="' . __('User name') . '"'
  252. . (empty($GLOBALS['username'])
  253. ? ''
  254. : ' value="' . (isset($GLOBALS['new_username'])
  255. ? $GLOBALS['new_username']
  256. : htmlspecialchars($GLOBALS['username'])) . '"')
  257. . ' onchange="pred_username.value = \'userdefined\';" />'
  258. . '</div>'
  259. . '<div class="item">'
  260. . '<label for="select_pred_hostname">'
  261. . ' ' . __('Host') . ':'
  262. . '</label>'
  263. . '<span class="options">'
  264. . ' <select name="pred_hostname" id="select_pred_hostname" title="' . __('Host') . '"';
  265. $_current_user = PMA_DBI_fetch_value('SELECT USER();');
  266. if (! empty($_current_user)) {
  267. $thishost = str_replace("'", '', substr($_current_user, (strrpos($_current_user, '@') + 1)));
  268. if ($thishost == 'localhost' || $thishost == '127.0.0.1') {
  269. unset($thishost);
  270. }
  271. }
  272. echo ' onchange="if (this.value == \'any\') { hostname.value = \'%\'; } else if (this.value == \'localhost\') { hostname.value = \'localhost\'; } '
  273. . (empty($thishost) ? '' : 'else if (this.value == \'thishost\') { hostname.value = \'' . addslashes(htmlspecialchars($thishost)) . '\'; } ')
  274. . 'else if (this.value == \'hosttable\') { hostname.value = \'\'; } else if (this.value == \'userdefined\') { hostname.focus(); hostname.select(); }">' . "\n";
  275. unset($_current_user);
  276. // when we start editing a user, $GLOBALS['pred_hostname'] is not defined
  277. if (! isset($GLOBALS['pred_hostname']) && isset($GLOBALS['hostname'])) {
  278. switch (strtolower($GLOBALS['hostname'])) {
  279. case 'localhost':
  280. case '127.0.0.1':
  281. $GLOBALS['pred_hostname'] = 'localhost';
  282. break;
  283. case '%':
  284. $GLOBALS['pred_hostname'] = 'any';
  285. break;
  286. default:
  287. $GLOBALS['pred_hostname'] = 'userdefined';
  288. break;
  289. }
  290. }
  291. echo ' <option value="any"'
  292. . ((isset($GLOBALS['pred_hostname']) && $GLOBALS['pred_hostname'] == 'any')
  293. ? ' selected="selected"' : '') . '>' . __('Any host')
  294. . '</option>'
  295. . ' <option value="localhost"'
  296. . ((isset($GLOBALS['pred_hostname']) && $GLOBALS['pred_hostname'] == 'localhost')
  297. ? ' selected="selected"' : '') . '>' . __('Local')
  298. . '</option>';
  299. if (!empty($thishost)) {
  300. echo ' <option value="thishost"'
  301. . ((isset($GLOBALS['pred_hostname']) && $GLOBALS['pred_hostname'] == 'thishost')
  302. ? ' selected="selected"' : '') . '>' . __('This Host')
  303. . '</option>';
  304. }
  305. unset($thishost);
  306. echo ' <option value="hosttable"'
  307. . ((isset($GLOBALS['pred_hostname']) && $GLOBALS['pred_hostname'] == 'hosttable')
  308. ? ' selected="selected"' : '') . '>' . __('Use Host Table')
  309. . '</option>'
  310. . ' <option value="userdefined"'
  311. . ((isset($GLOBALS['pred_hostname']) && $GLOBALS['pred_hostname'] == 'userdefined')
  312. ? ' selected="selected"' : '')
  313. . '>' . __('Use text field') . ':</option>'
  314. . ' </select>'
  315. . '</span>'
  316. . '<input type="text" name="hostname" maxlength="'
  317. . $hostname_length . '" value="'
  318. . (isset($GLOBALS['hostname']) ? htmlspecialchars($GLOBALS['hostname']) : '')
  319. . '" title="' . __('Host')
  320. . '" onchange="pred_hostname.value = \'userdefined\';" />'
  321. . PMA_Util::showHint(
  322. __('When Host table is used, this field is ignored and values stored in Host table are used instead.')
  323. )
  324. . '</div>'
  325. . '<div class="item">'
  326. . '<label for="select_pred_password">'
  327. . ' ' . __('Password') . ':'
  328. . '</label>'
  329. . '<span class="options">'
  330. . ' <select name="pred_password" id="select_pred_password" title="'
  331. . __('Password') . '"'
  332. . ' onchange="if (this.value == \'none\') { pma_pw.value = \'\'; pma_pw2.value = \'\'; } else if (this.value == \'userdefined\') { pma_pw.focus(); pma_pw.select(); }">'
  333. . ' <option value="none"';
  334. if (isset($GLOBALS['username'])) {
  335. echo ' selected="selected"';
  336. }
  337. echo '>' . __('No Password') . '</option>'
  338. . ' <option value="userdefined"' . (isset($GLOBALS['username']) ? '' : ' selected="selected"') . '>' . __('Use text field') . ':</option>'
  339. . ' </select>'
  340. . '</span>'
  341. . '<input type="password" id="text_pma_pw" name="pma_pw" title="' . __('Password') . '" onchange="pred_password.value = \'userdefined\';" />'
  342. . '</div>'
  343. . '<div class="item">'
  344. . '<label for="text_pma_pw2">'
  345. . ' ' . __('Re-type') . ':'
  346. . '</label>'
  347. . '<span class="options">&nbsp;</span>'
  348. . '<input type="password" name="pma_pw2" id="text_pma_pw2" title="' . __('Re-type') . '" onchange="pred_password.value = \'userdefined\';" />'
  349. . '</div>'
  350. . '<div class="item">'
  351. . '<label for="button_generate_password">'
  352. . ' ' . __('Generate Password') . ':'
  353. . '</label>'
  354. . '<span class="options">'
  355. . ' <input type="button" class="button" id="button_generate_password" value="' . __('Generate') . '" onclick="suggestPassword(this.form)" />'
  356. . '</span>'
  357. . '<input type="text" name="generated_pw" id="generated_pw" />'
  358. . '</div>'
  359. . '</fieldset>';
  360. echo '<fieldset id="fieldset_user_privtable_footer" class="tblFooters">'
  361. . ' <input type="hidden" name="adduser_submit" value="1" />'
  362. . ' <input type="submit" id="adduser_submit" value="' . __('Go') . '" />'
  363. . '</fieldset>';
  364. echo '</form>';
  365. echo '</div>';
  366. }
  367. ?>