central_columns.lib.php 49 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408
  1. <?php
  2. /* vim: set expandtab sw=4 ts=4 sts=4: */
  3. /**
  4. * Functions for displaying user preferences pages
  5. *
  6. * @package PhpMyAdmin
  7. */
  8. if (! defined('PHPMYADMIN')) {
  9. exit;
  10. }
  11. require_once './libraries/Template.class.php';
  12. /**
  13. * Defines the central_columns parameters for the current user
  14. *
  15. * @return array the central_columns parameters for the current user
  16. * @access public
  17. */
  18. function PMA_centralColumnsGetParams()
  19. {
  20. static $cfgCentralColumns = null;
  21. if (null !== $cfgCentralColumns) {
  22. return $cfgCentralColumns;
  23. }
  24. $cfgRelation = PMA_getRelationsParam();
  25. if ($cfgRelation['centralcolumnswork']) {
  26. $cfgCentralColumns = array(
  27. 'user' => $GLOBALS['cfg']['Server']['user'],
  28. 'db' => $cfgRelation['db'],
  29. 'table' => $cfgRelation['central_columns'],
  30. );
  31. } else {
  32. $cfgCentralColumns = false;
  33. }
  34. return $cfgCentralColumns;
  35. }
  36. /**
  37. * get $num columns of given database from central columns list
  38. * starting at offset $from
  39. *
  40. * @param string $db selected database
  41. * @param int $from starting offset of first result
  42. * @param int $num maximum number of results to return
  43. *
  44. * @return array list of $num columns present in central columns list
  45. * starting at offset $from for the given database
  46. */
  47. function PMA_getColumnsList($db, $from=0, $num=25)
  48. {
  49. $cfgCentralColumns = PMA_centralColumnsGetParams();
  50. if (empty($cfgCentralColumns)) {
  51. return array();
  52. }
  53. $pmadb = $cfgCentralColumns['db'];
  54. $GLOBALS['dbi']->selectDb($pmadb, $GLOBALS['controllink']);
  55. $central_list_table = $cfgCentralColumns['table'];
  56. //get current values of $db from central column list
  57. if ($num == 0) {
  58. $query = 'SELECT * FROM ' . PMA_Util::backquote($central_list_table) . ' '
  59. . 'WHERE db_name = \'' . $db . '\';';
  60. } else {
  61. $query = 'SELECT * FROM ' . PMA_Util::backquote($central_list_table) . ' '
  62. . 'WHERE db_name = \'' . $db . '\' '
  63. . 'LIMIT ' . $from . ', ' . $num . ';';
  64. }
  65. $has_list = (array) $GLOBALS['dbi']->fetchResult(
  66. $query, null, null, $GLOBALS['controllink']
  67. );
  68. PMA_handleColumnExtra($has_list);
  69. return $has_list;
  70. }
  71. /**
  72. * get the number of columns present in central list for given db
  73. *
  74. * @param string $db current database
  75. *
  76. * @return int number of columns in central list of columns for $db
  77. */
  78. function PMA_getCentralColumnsCount($db)
  79. {
  80. $cfgCentralColumns = PMA_centralColumnsGetParams();
  81. if (empty($cfgCentralColumns)) {
  82. return 0;
  83. }
  84. $pmadb = $cfgCentralColumns['db'];
  85. $GLOBALS['dbi']->selectDb($pmadb, $GLOBALS['controllink']);
  86. $central_list_table = $cfgCentralColumns['table'];
  87. $query = 'SELECT count(db_name) FROM ' .
  88. PMA_Util::backquote($central_list_table) . ' '
  89. . 'WHERE db_name = \'' . $db . '\';';
  90. $res = $GLOBALS['dbi']->fetchResult(
  91. $query, null, null, $GLOBALS['controllink']
  92. );
  93. if (isset($res[0])) {
  94. return $res[0];
  95. } else {
  96. return 0;
  97. }
  98. }
  99. /**
  100. * return the existing columns in central list among the given list of columns
  101. *
  102. * @param string $db the selected database
  103. * @param string $cols comma separated list of given columns
  104. * @param boolean $allFields set if need all the fields of existing columns,
  105. * otherwise only column_name is returned
  106. *
  107. * @return array list of columns in central columns among given set of columns
  108. */
  109. function PMA_findExistingColNames($db, $cols, $allFields=false)
  110. {
  111. $cfgCentralColumns = PMA_centralColumnsGetParams();
  112. if (empty($cfgCentralColumns)) {
  113. return array();
  114. }
  115. $pmadb = $cfgCentralColumns['db'];
  116. $GLOBALS['dbi']->selectDb($pmadb, $GLOBALS['controllink']);
  117. $central_list_table = $cfgCentralColumns['table'];
  118. if ($allFields) {
  119. $query = 'SELECT * FROM ' . PMA_Util::backquote($central_list_table) . ' '
  120. . 'WHERE db_name = \'' . $db . '\' AND col_name IN (' . $cols . ');';
  121. $has_list = (array) $GLOBALS['dbi']->fetchResult(
  122. $query, null, null, $GLOBALS['controllink']
  123. );
  124. PMA_handleColumnExtra($has_list);
  125. } else {
  126. $query = 'SELECT col_name FROM '
  127. . PMA_Util::backquote($central_list_table) . ' '
  128. . 'WHERE db_name = \'' . $db . '\' AND col_name IN (' . $cols . ');';
  129. $has_list = (array) $GLOBALS['dbi']->fetchResult(
  130. $query, null, null, $GLOBALS['controllink']
  131. );
  132. }
  133. return $has_list;
  134. }
  135. /**
  136. * return error message to be displayed if central columns
  137. * configuration storage is not completely configured
  138. *
  139. * @return PMA_Message
  140. */
  141. function PMA_configErrorMessage()
  142. {
  143. return PMA_Message::error(
  144. __(
  145. 'The configuration storage is not ready for the central list'
  146. . ' of columns feature.'
  147. )
  148. );
  149. }
  150. /**
  151. * build the insert query for central columns list given PMA storage
  152. * db, central_columns table, column name and corresponding definition to be added
  153. *
  154. * @param string $column column to add into central list
  155. * @param array $def list of attributes of the column being added
  156. * @param string $db PMA configuration storage database name
  157. * @param string $central_list_table central columns configuration storage table name
  158. *
  159. * @return string query string to insert the given column
  160. * with definition into central list
  161. */
  162. function PMA_getInsertQuery($column, $def, $db, $central_list_table)
  163. {
  164. $type = "";
  165. $length = 0;
  166. $attribute = "";
  167. if (isset($def['Type'])) {
  168. $extracted_columnspec = PMA_Util::extractColumnSpec($def['Type']);
  169. $attribute = trim($extracted_columnspec[ 'attribute']);
  170. $type = $extracted_columnspec['type'];
  171. $length = $extracted_columnspec['spec_in_brackets'];
  172. }
  173. if (isset($def['Attribute'])) {
  174. $attribute = $def['Attribute'];
  175. };
  176. $collation = isset($def['Collation'])?$def['Collation']:"";
  177. $isNull = ($def['Null'] == "NO")?0:1;
  178. $extra = isset($def['Extra'])?$def['Extra']:"";
  179. $default = isset($def['Default'])?$def['Default']:"";
  180. $insQuery = 'INSERT INTO '
  181. . PMA_Util::backquote($central_list_table) . ' '
  182. . 'VALUES ( \'' . PMA_Util::sqlAddSlashes($db) . '\' ,'
  183. . '\'' . PMA_Util::sqlAddSlashes($column) . '\',\''
  184. . PMA_Util::sqlAddSlashes($type) . '\','
  185. . '\'' . PMA_Util::sqlAddSlashes($length) . '\',\''
  186. . PMA_Util::sqlAddSlashes($collation) . '\','
  187. . '\'' . PMA_Util::sqlAddSlashes($isNull) . '\','
  188. . '\'' . implode(',', array($extra, $attribute))
  189. . '\',\'' . PMA_Util::sqlAddSlashes($default) . '\');';
  190. return $insQuery;
  191. }
  192. /**
  193. * If $isTable is true then unique columns from given tables as $field_select
  194. * are added to central list otherwise the $field_select is considered as
  195. * list of columns and these columns are added to central list if not already added
  196. *
  197. * @param array $field_select if $isTable is true selected tables list
  198. * otherwise selected columns list
  199. * @param bool $isTable if passed array is of tables or columns
  200. * @param string $table if $isTable is false,
  201. * then table name to which columns belong
  202. *
  203. * @return true|PMA_Message
  204. */
  205. function PMA_syncUniqueColumns($field_select, $isTable=true, $table=null)
  206. {
  207. $cfgCentralColumns = PMA_centralColumnsGetParams();
  208. if (empty($cfgCentralColumns)) {
  209. return PMA_configErrorMessage();
  210. }
  211. $db = $_REQUEST['db'];
  212. $pmadb = $cfgCentralColumns['db'];
  213. $central_list_table = $cfgCentralColumns['table'];
  214. $GLOBALS['dbi']->selectDb($db, $GLOBALS['userlink']);
  215. $existingCols = array();
  216. $cols = "";
  217. $insQuery = array();
  218. $fields = array();
  219. $message = true;
  220. if ($isTable) {
  221. foreach ($field_select as $table) {
  222. $fields[$table] = (array) $GLOBALS['dbi']->getColumns(
  223. $db, $table, null, true, $GLOBALS['userlink']
  224. );
  225. foreach ($fields[$table] as $field => $def) {
  226. $cols .= "'" . PMA_Util::sqlAddSlashes($field) . "',";
  227. }
  228. }
  229. $has_list = PMA_findExistingColNames($db, trim($cols, ','));
  230. foreach ($field_select as $table) {
  231. foreach ($fields[$table] as $field => $def) {
  232. if (!in_array($field, $has_list)) {
  233. $has_list[] = $field;
  234. $insQuery[] = PMA_getInsertQuery(
  235. $field, $def, $db, $central_list_table
  236. );
  237. } else {
  238. $existingCols[] = "'" . $field . "'";
  239. }
  240. }
  241. }
  242. } else {
  243. if ($table === null) {
  244. $table = $_REQUEST['table'];
  245. }
  246. foreach ($field_select as $column) {
  247. $cols .= "'" . PMA_Util::sqlAddSlashes($column) . "',";
  248. }
  249. $has_list = PMA_findExistingColNames($db, trim($cols, ','));
  250. foreach ($field_select as $column) {
  251. if (!in_array($column, $has_list)) {
  252. $has_list[] = $column;
  253. $field = (array) $GLOBALS['dbi']->getColumns(
  254. $db, $table, $column,
  255. true, $GLOBALS['userlink']
  256. );
  257. $insQuery[] = PMA_getInsertQuery(
  258. $column, $field, $db, $central_list_table
  259. );
  260. } else {
  261. $existingCols[] = "'" . $column . "'";
  262. }
  263. }
  264. }
  265. if (! empty($existingCols)) {
  266. $existingCols = implode(",", array_unique($existingCols));
  267. $message = PMA_Message::notice(
  268. sprintf(
  269. __(
  270. 'Could not add %1$s as they already exist in central list!'
  271. ), htmlspecialchars($existingCols)
  272. )
  273. );
  274. $message->addMessage(
  275. PMA_Message::notice(
  276. "Please remove them first "
  277. . "from central list if you want to update above columns"
  278. )
  279. );
  280. }
  281. $GLOBALS['dbi']->selectDb($pmadb, $GLOBALS['controllink']);
  282. if (! empty($insQuery)) {
  283. foreach ($insQuery as $query) {
  284. if (!$GLOBALS['dbi']->tryQuery($query, $GLOBALS['controllink'])) {
  285. $message = PMA_Message::error(__('Could not add columns!'));
  286. $message->addMessage(
  287. PMA_Message::rawError(
  288. $GLOBALS['dbi']->getError($GLOBALS['controllink'])
  289. )
  290. );
  291. break;
  292. }
  293. }
  294. }
  295. return $message;
  296. }
  297. /**
  298. * if $isTable is true it removes all columns of given tables as $field_select from
  299. * central columns list otherwise $field_select is columns list and it removes
  300. * given columns if present in central list
  301. *
  302. * @param array $field_select if $isTable selected list of tables otherwise
  303. * selected list of columns to remove from central list
  304. * @param bool $isTable if passed array is of tables or columns
  305. *
  306. * @return true|PMA_Message
  307. */
  308. function PMA_deleteColumnsFromList($field_select, $isTable=true)
  309. {
  310. $cfgCentralColumns = PMA_centralColumnsGetParams();
  311. if (empty($cfgCentralColumns)) {
  312. return PMA_configErrorMessage();
  313. }
  314. $db = $_REQUEST['db'];
  315. $pmadb = $cfgCentralColumns['db'];
  316. $central_list_table = $cfgCentralColumns['table'];
  317. $GLOBALS['dbi']->selectDb($db, $GLOBALS['userlink']);
  318. $message = true;
  319. $colNotExist = array();
  320. $fields = array();
  321. if ($isTable) {
  322. $cols = '';
  323. foreach ($field_select as $table) {
  324. $fields[$table] = (array) $GLOBALS['dbi']->getColumnNames(
  325. $db, $table, $GLOBALS['userlink']
  326. );
  327. foreach ($fields[$table] as $col_select) {
  328. $cols .= '\'' . PMA_Util::sqlAddSlashes($col_select) . '\',';
  329. }
  330. }
  331. $cols = trim($cols, ',');
  332. $has_list = PMA_findExistingColNames($db, $cols);
  333. foreach ($field_select as $table) {
  334. foreach ($fields[$table] as $column) {
  335. if (!in_array($column, $has_list)) {
  336. $colNotExist[] = "'" . $column . "'";
  337. }
  338. }
  339. }
  340. } else {
  341. $cols = '';
  342. foreach ($field_select as $col_select) {
  343. $cols .= '\'' . PMA_Util::sqlAddSlashes($col_select) . '\',';
  344. }
  345. $cols = trim($cols, ',');
  346. $has_list = PMA_findExistingColNames($db, $cols);
  347. foreach ($field_select as $column) {
  348. if (!in_array($column, $has_list)) {
  349. $colNotExist[] = "'" . $column . "'";
  350. }
  351. }
  352. }
  353. if (!empty($colNotExist)) {
  354. $colNotExist = implode(",", array_unique($colNotExist));
  355. $message = PMA_Message::notice(
  356. sprintf(
  357. __(
  358. 'Couldn\'t remove Column(s) %1$s '
  359. . 'as they don\'t exist in central columns list!'
  360. ), htmlspecialchars($colNotExist)
  361. )
  362. );
  363. }
  364. $GLOBALS['dbi']->selectDb($pmadb, $GLOBALS['controllink']);
  365. $query = 'DELETE FROM ' . PMA_Util::backquote($central_list_table) . ' '
  366. . 'WHERE db_name = \'' . $db . '\' AND col_name IN (' . $cols . ');';
  367. if (!$GLOBALS['dbi']->tryQuery($query, $GLOBALS['controllink'])) {
  368. $message = PMA_Message::error(__('Could not remove columns!'));
  369. $message->addMessage('<br />' . htmlspecialchars($cols) . '<br />');
  370. $message->addMessage(
  371. PMA_Message::rawError(
  372. $GLOBALS['dbi']->getError($GLOBALS['controllink'])
  373. )
  374. );
  375. }
  376. return $message;
  377. }
  378. /**
  379. * make the columns of given tables consistent with central list of columns.
  380. * Updates only those columns which are not being referenced.
  381. *
  382. * @param string $db current database
  383. * @param array $selected_tables list of selected tables.
  384. *
  385. * @return true|PMA_Message
  386. */
  387. function PMA_makeConsistentWithList($db, $selected_tables)
  388. {
  389. $message = true;
  390. foreach ($selected_tables as $table) {
  391. $query = 'ALTER TABLE ' . PMA_Util::backquote($table);
  392. $has_list = PMA_getCentralColumnsFromTable($db, $table, true);
  393. $GLOBALS['dbi']->selectDb($db, $GLOBALS['userlink']);
  394. foreach ($has_list as $column) {
  395. $column_status = PMA_checkChildForeignReferences(
  396. $db, $table, $column['col_name']
  397. );
  398. //column definition can only be changed if
  399. //it is not referenced by another column
  400. if ($column_status['isEditable']) {
  401. $query .= ' MODIFY ' . PMA_Util::backquote($column['col_name']) . ' '
  402. . PMA_Util::sqlAddSlashes($column['col_type']);
  403. if ($column['col_length']) {
  404. $query .= '(' . $column['col_length'] . ')';
  405. }
  406. $query .= ' ' . $column['col_attribute'];
  407. if ($column['col_isNull']) {
  408. $query .= ' NULL';
  409. } else {
  410. $query .= ' NOT NULL';
  411. }
  412. $query .= ' ' . $column['col_extra'];
  413. if ($column['col_default']) {
  414. if ($column['col_default'] != 'CURRENT_TIMESTAMP') {
  415. $query .= ' DEFAULT \'' . PMA_Util::sqlAddSlashes(
  416. $column['col_default']
  417. ) . '\'';
  418. } else {
  419. $query .= ' DEFAULT ' . PMA_Util::sqlAddSlashes(
  420. $column['col_default']
  421. );
  422. }
  423. }
  424. $query .= ',';
  425. }
  426. }
  427. $query = trim($query, " ,") . ";";
  428. if (!$GLOBALS['dbi']->tryQuery($query, $GLOBALS['userlink'])) {
  429. if ($message === true) {
  430. $message = PMA_Message::error(
  431. $GLOBALS['dbi']->getError($GLOBALS['userlink'])
  432. );
  433. } else {
  434. $message->addMessage('<br />');
  435. $message->addMessage(
  436. $GLOBALS['dbi']->getError($GLOBALS['userlink'])
  437. );
  438. }
  439. }
  440. }
  441. return $message;
  442. }
  443. /**
  444. * return the columns present in central list of columns for a given
  445. * table of a given database
  446. *
  447. * @param string $db given database
  448. * @param string $table given table
  449. * @param boolean $allFields set if need all the fields of existing columns,
  450. * otherwise only column_name is returned
  451. *
  452. * @return array columns present in central list from given table of given db.
  453. */
  454. function PMA_getCentralColumnsFromTable($db, $table, $allFields=false)
  455. {
  456. $cfgCentralColumns = PMA_centralColumnsGetParams();
  457. if (empty($cfgCentralColumns)) {
  458. return array();
  459. }
  460. $GLOBALS['dbi']->selectDb($db, $GLOBALS['userlink']);
  461. $fields = (array) $GLOBALS['dbi']->getColumnNames(
  462. $db, $table, $GLOBALS['userlink']
  463. );
  464. $cols = '';
  465. foreach ($fields as $col_select) {
  466. $cols .= '\'' . PMA_Util::sqlAddSlashes($col_select) . '\',';
  467. }
  468. $cols = trim($cols, ',');
  469. $has_list = PMA_findExistingColNames($db, $cols, $allFields);
  470. if (! empty($has_list)) {
  471. return (array)$has_list;
  472. } else {
  473. return array();
  474. }
  475. }
  476. /**
  477. * update a column in central columns list if a edit is requested
  478. *
  479. * @param string $db current database
  480. * @param string $orig_col_name original column name before edit
  481. * @param string $col_name new column name
  482. * @param string $col_type new column type
  483. * @param string $col_attribute new column attribute
  484. * @param string $col_length new column length
  485. * @param int $col_isNull value 1 if new column isNull is true, 0 otherwise
  486. * @param string $collation new column collation
  487. * @param string $col_extra new column extra property
  488. * @param string $col_default new column default value
  489. *
  490. * @return true|PMA_Message
  491. */
  492. function PMA_updateOneColumn($db, $orig_col_name, $col_name, $col_type,
  493. $col_attribute,$col_length, $col_isNull, $collation, $col_extra, $col_default
  494. ) {
  495. $cfgCentralColumns = PMA_centralColumnsGetParams();
  496. if (empty($cfgCentralColumns)) {
  497. return PMA_configErrorMessage();
  498. }
  499. $centralTable = $cfgCentralColumns['table'];
  500. $GLOBALS['dbi']->selectDb($cfgCentralColumns['db'], $GLOBALS['controllink']);
  501. if ($orig_col_name == "") {
  502. $def = array();
  503. $def['Type'] = $col_type;
  504. if ($col_length) {
  505. $def['Type'] .= '(' . $col_length . ')';
  506. }
  507. $def['Collation'] = $collation;
  508. $def['Null'] = $col_isNull?__('YES'):__('NO');
  509. $def['Extra'] = $col_extra;
  510. $def['Attribute'] = $col_attribute;
  511. $def['Default'] = $col_default;
  512. $query = PMA_getInsertQuery($col_name, $def, $db, $centralTable);
  513. } else {
  514. $query = 'UPDATE ' . PMA_Util::backquote($centralTable)
  515. . ' SET col_type = \'' . PMA_Util::sqlAddSlashes($col_type) . '\''
  516. . ', col_name = \'' . PMA_Util::sqlAddSlashes($col_name) . '\''
  517. . ', col_length = \'' . PMA_Util::sqlAddSlashes($col_length) . '\''
  518. . ', col_isNull = ' . $col_isNull
  519. . ', col_collation = \'' . PMA_Util::sqlAddSlashes($collation) . '\''
  520. . ', col_extra = \''
  521. . implode(',', array($col_extra, $col_attribute)) . '\''
  522. . ', col_default = \'' . PMA_Util::sqlAddSlashes($col_default) . '\''
  523. . ' WHERE db_name = \'' . PMA_Util::sqlAddSlashes($db) . '\' '
  524. . 'AND col_name = \'' . PMA_Util::sqlAddSlashes($orig_col_name)
  525. . '\'';
  526. }
  527. if (!$GLOBALS['dbi']->tryQuery($query, $GLOBALS['controllink'])) {
  528. return PMA_Message::error(
  529. $GLOBALS['dbi']->getError($GLOBALS['controllink'])
  530. );
  531. }
  532. return true;
  533. }
  534. /**
  535. * Update Multiple column in central columns list if a chnage is requested
  536. *
  537. * @return true|PMA_Message
  538. */
  539. function PMA_updateMultipleColumn()
  540. {
  541. $db = $_POST['db'];
  542. $col_name = $_POST['field_name'];
  543. $orig_col_name = $_POST['orig_col_name'];
  544. $col_default = $_POST['field_default_type'];
  545. $col_length = $_POST['field_length'];
  546. $col_attribute = $_POST['field_attribute'];
  547. $col_type = $_POST['field_type'];
  548. $collation = $_POST['field_collation'];
  549. $col_isNull = array();
  550. $col_extra = array();
  551. $num_central_fields = count($orig_col_name);
  552. for ($i = 0; $i < $num_central_fields ; $i++) {
  553. $col_isNull[$i] = isset($_POST['field_null'][$i]) ? 1 : 0;
  554. $col_extra[$i] = isset($_POST['col_extra'][$i])
  555. ? $_POST['col_extra'][$i] : '';
  556. if ($col_default[$i] == 'NONE') {
  557. $col_default[$i] = "";
  558. } else if ($col_default[$i] == 'USER_DEFINED') {
  559. $col_default[$i] = $_POST['field_default_value'][$i];
  560. }
  561. $message = PMA_updateOneColumn(
  562. $db, $orig_col_name[$i], $col_name[$i], $col_type[$i],
  563. $col_attribute[$i], $col_length[$i], $col_isNull[$i], $collation[$i],
  564. $col_extra[$i], $col_default[$i]
  565. );
  566. if (!is_bool($message)) {
  567. return $message;
  568. }
  569. }
  570. return true;
  571. }
  572. /**
  573. * get the html for table navigation in Central columns page
  574. *
  575. * @param int $total_rows total number of rows in complete result set
  576. * @param int $pos offset of first result with complete result set
  577. * @param string $db current database
  578. *
  579. * @return string html for table navigation in Central columns page
  580. */
  581. function PMA_getHTMLforTableNavigation($total_rows, $pos, $db)
  582. {
  583. $max_rows = $GLOBALS['cfg']['MaxRows'];
  584. $pageNow = ($pos / $max_rows) + 1;
  585. $nbTotalPage = ceil($total_rows / $max_rows);
  586. $table_navigation_html = '<table style="display:inline-block;max-width:49%" '
  587. . 'class="navigation nospacing nopadding">'
  588. . '<tr>'
  589. . '<td class="navigation_separator"></td>';
  590. if ($pos - $max_rows >= 0) {
  591. $table_navigation_html .= '<td>'
  592. . '<form action="db_central_columns.php" method="post">'
  593. . PMA_URL_getHiddenInputs(
  594. $db
  595. )
  596. . '<input type="hidden" name="pos" value="' . ($pos - $max_rows) . '" />'
  597. . '<input type="hidden" name="total_rows" value="' . $total_rows . '"/>'
  598. . '<input type="submit" name="navig"'
  599. . ' class="ajax" '
  600. . 'value="&lt" />'
  601. . '</form>'
  602. . '</td>';
  603. }
  604. if ($nbTotalPage > 1) {
  605. $table_navigation_html .= '<td>';
  606. $table_navigation_html .= '<form action="db_central_columns.php'
  607. . '" method="post">'
  608. . PMA_URL_getHiddenInputs(
  609. $db
  610. )
  611. . '<input type="hidden" name="total_rows" value="' . $total_rows . '"/>';
  612. $table_navigation_html .= PMA_Util::pageselector(
  613. 'pos', $max_rows, $pageNow, $nbTotalPage
  614. );
  615. $table_navigation_html .= '</form>'
  616. . '</td>';
  617. }
  618. if ($pos + $max_rows < $total_rows) {
  619. $table_navigation_html .= '<td>'
  620. . '<form action="db_central_columns.php" method="post">'
  621. . PMA_URL_getHiddenInputs(
  622. $db
  623. )
  624. . '<input type="hidden" name="pos" value="' . ($pos + $max_rows) . '" />'
  625. . '<input type="hidden" name="total_rows" value="' . $total_rows . '"/>'
  626. . '<input type="submit" name="navig"'
  627. . ' class="ajax" '
  628. . 'value="&gt" />'
  629. . '</form>'
  630. . '</td>';
  631. }
  632. $table_navigation_html .= '</form>'
  633. . '</td>'
  634. . '<td class="navigation_separator"></td>'
  635. . '<td>'
  636. . '<span>' . __('Filter rows') . ':</span>'
  637. . '<input type="text" class="filter_rows" placeholder="'
  638. . __('Search this table') . '">'
  639. . '</td>'
  640. . '<td class="navigation_separator"></td>'
  641. . '</tr>'
  642. . '</table>';
  643. return $table_navigation_html;
  644. }
  645. /**
  646. * function generate and return the table header for central columns page
  647. *
  648. * @param string $class styling class of 'th' elements
  649. * @param string $title title of the 'th' elements
  650. * @param integer $actionCount number of actions
  651. *
  652. * @return string html for table header in central columns view/edit page
  653. */
  654. function PMA_getCentralColumnsTableHeader($class='', $title='', $actionCount=0)
  655. {
  656. $action = '';
  657. if ($actionCount > 0) {
  658. $action .= '<th class="column_action" colspan="' . $actionCount . '">'
  659. . __('Action') . '</th>';
  660. }
  661. $tableheader = '<thead>';
  662. $tableheader .= '<tr>'
  663. . '<th class="' . $class . '"></th>'
  664. . '<th class="" style="display:none"></th>'
  665. . $action
  666. . '<th class="' . $class . '" title="' . $title . '" data-column="name">'
  667. . __('Name') . '<div class="sorticon"></div></th>'
  668. . '<th class="' . $class . '" title="' . $title . '" data-column="type">'
  669. . __('Type') . '<div class="sorticon"></div></th>'
  670. . '<th class="' . $class . '" title="' . $title . '" data-column="length">'
  671. . __('Length/Values') . '<div class="sorticon"></div></th>'
  672. . '<th class="' . $class . '" title="' . $title . '" data-column="default">'
  673. . __('Default') . '<div class="sorticon"></div></th>'
  674. . '<th class="' . $class . '" title="' . $title . '" data-column="collation"'
  675. . '>' . __('Collation') . '<div class="sorticon"></div></th>'
  676. . '<th class="' . $class . '" title="' . $title
  677. . '" data-column="attribute">'
  678. . __('Attribute') . '<div class="sorticon"></div></th>'
  679. . '<th class="' . $class . '" title="' . $title . '" data-column="isnull">'
  680. . __('Null') . '<div class="sorticon"></div></th>'
  681. . '<th class="' . $class . '" title="' . $title . '" data-column="extra">'
  682. . __('A_I') . '<div class="sorticon"></div></th>'
  683. . '</tr>';
  684. $tableheader .= '</thead>';
  685. return $tableheader;
  686. }
  687. /**
  688. * Function generate and return the table header for
  689. * multiple edit central columns page
  690. *
  691. * @param array $header_cells headers list
  692. *
  693. * @return string html for table header in central columns multi edit page
  694. */
  695. function PMA_getCentralColumnsEditTableHeader($header_cells)
  696. {
  697. $html = '<table id="table_columns" class="noclick"'
  698. . ' style="min-width: 100%;">';
  699. $html .= '<caption class="tblHeaders">' . __('Structure');
  700. $html .= '<tr>';
  701. foreach ($header_cells as $header_val) {
  702. $html .= '<th>' . $header_val . '</th>';
  703. }
  704. $html .= '</tr>';
  705. return $html;
  706. }
  707. /**
  708. * build the dropdown select html for tables of given database
  709. *
  710. * @param string $db current database
  711. *
  712. * @return string html dropdown for selecting table
  713. */
  714. function PMA_getHTMLforTableDropdown($db)
  715. {
  716. $GLOBALS['dbi']->selectDb($db, $GLOBALS['userlink']);
  717. $tables = $GLOBALS['dbi']->getTables($db, $GLOBALS['userlink']);
  718. $selectHtml = '<select name="table-select" id="table-select">'
  719. . '<option value="" disabled="disabled" selected="selected">'
  720. . __('Select a table') . '</option>';
  721. foreach ($tables as $table) {
  722. $selectHtml .= '<option value="' . htmlspecialchars($table) . '">'
  723. . htmlspecialchars($table) . '</option>';
  724. }
  725. $selectHtml .= '</select>';
  726. return $selectHtml;
  727. }
  728. /**
  729. * build dropdown select html to select column in selected table,
  730. * include only columns which are not already in central list
  731. *
  732. * @param string $db current database to which selected table belongs
  733. * @param string $selected_tbl selected table
  734. *
  735. * @return string html to select column
  736. */
  737. function PMA_getHTMLforColumnDropdown($db, $selected_tbl)
  738. {
  739. $existing_cols = PMA_getCentralColumnsFromTable($db, $selected_tbl);
  740. $GLOBALS['dbi']->selectDb($db, $GLOBALS['userlink']);
  741. $columns = (array) $GLOBALS['dbi']->getColumnNames(
  742. $db, $selected_tbl, $GLOBALS['userlink']
  743. );
  744. $selectColHtml = "";
  745. foreach ($columns as $column) {
  746. if (!in_array($column, $existing_cols)) {
  747. $selectColHtml .= '<option value="' . htmlspecialchars($column) . '">'
  748. . htmlspecialchars($column)
  749. . '</option>';
  750. }
  751. }
  752. return $selectColHtml;
  753. }
  754. /**
  755. * html to display the form that let user to add a column on Central columns page
  756. *
  757. * @param int $total_rows total number of rows in complete result set
  758. * @param int $pos offset of first result with complete result set
  759. * @param string $db current database
  760. *
  761. * @return string html to add a column in the central list
  762. */
  763. function PMA_getHTMLforAddCentralColumn($total_rows, $pos, $db)
  764. {
  765. $columnAdd = '<table style="display:inline-block;margin-left:1%;max-width:50%" '
  766. . 'class="navigation nospacing nopadding">'
  767. . '<tr>'
  768. . '<td class="navigation_separator"></td>'
  769. . '<td style="padding:1.5% 0em">'
  770. . PMA_Util::getIcon(
  771. 'centralColumns_add.png',
  772. __('Add column')
  773. )
  774. . '<form id="add_column" action="db_central_columns.php" method="post">'
  775. . PMA_URL_getHiddenInputs(
  776. $db
  777. )
  778. . '<input type="hidden" name="add_column" value="add">'
  779. . '<input type="hidden" name="pos" value="' . $pos . '" />'
  780. . '<input type="hidden" name="total_rows" value="' . $total_rows . '"/>'
  781. . PMA_getHTMLforTableDropdown($db)
  782. . '<select name="column-select" id="column-select">'
  783. . '<option value="" selected="selected">'
  784. . __('Select a column.') . '</option>'
  785. . '</select></form>'
  786. . '</td>'
  787. . '<td class="navigation_separator"></td>'
  788. . '</tr>'
  789. . '</table>';
  790. return $columnAdd;
  791. }
  792. /**
  793. * build html for a row in central columns table
  794. *
  795. * @param array $row array contains complete information of
  796. * a particular row of central list table
  797. * @param boolean $odd_row set true if the row is at odd number position
  798. * @param int $row_num position the row in the table
  799. * @param string $db current database
  800. *
  801. * @return string html of a particular row in the central columns table.
  802. */
  803. function PMA_getHTMLforCentralColumnsTableRow($row, $odd_row, $row_num, $db)
  804. {
  805. $tableHtml = '<tr data-rownum="' . $row_num . '" id="f_' . $row_num . '" '
  806. . 'class="' . ($odd_row ? 'odd' : 'even') . '">'
  807. . PMA_URL_getHiddenInputs(
  808. $db
  809. )
  810. . '<input type="hidden" name="edit_save" value="save">'
  811. . '<td class="nowrap">'
  812. . '<input type="checkbox" class="checkall" name="selected_fld[]" '
  813. . 'value="' . htmlspecialchars($row['col_name']) . '" '
  814. . 'id="checkbox_row_' . $row_num . '"/>'
  815. . '</td>'
  816. . '<td id="edit_' . $row_num . '" class="edit center">'
  817. . '<a href="#">' . PMA_Util::getIcon('b_edit.png', __('Edit')) . '</a></td>'
  818. . '<td class="del_row" data-rownum = "' . $row_num . '">'
  819. . '<a hrf="#">' . PMA_Util::getIcon('b_drop.png', __('Delete')) . '</a>'
  820. . '<input type="submit" data-rownum = "' . $row_num . '"'
  821. . ' class="edit_cancel_form" value="Cancel"></td>'
  822. . '<td id="save_' . $row_num . '" style="display:none">'
  823. . '<input type="submit" data-rownum = "' . $row_num . '"'
  824. . ' class="edit_save_form" value="Save"></td>';
  825. $tableHtml .=
  826. '<td name="col_name" class="nowrap">'
  827. . '<span>' . htmlspecialchars($row['col_name']) . '</span>'
  828. . '<input name="orig_col_name" type="hidden" '
  829. . 'value="' . htmlspecialchars($row['col_name']) . '">'
  830. . PMA\Template::get('columns_definitions/column_name')
  831. ->render(
  832. array(
  833. 'columnNumber' => $row_num,
  834. 'ci' => 0,
  835. 'ci_offset' => 0,
  836. 'columnMeta' => array(
  837. 'Field'=>$row['col_name']
  838. ),
  839. 'cfgRelation' => array(
  840. 'centralcolumnswork' => false
  841. )
  842. )
  843. )
  844. . '</td>';
  845. $tableHtml .=
  846. '<td name = "col_type" class="nowrap"><span>'
  847. . htmlspecialchars($row['col_type']) . '</span>'
  848. . PMA\Template::get('columns_definitions/column_type')
  849. ->render(
  850. array(
  851. 'columnNumber' => $row_num,
  852. 'ci' => 1,
  853. 'ci_offset' => 0,
  854. 'type_upper' => /*overload*/mb_strtoupper($row['col_type']),
  855. 'columnMeta' => array()
  856. )
  857. )
  858. . '</td>';
  859. $tableHtml .=
  860. '<td class="nowrap" name="col_length">'
  861. . '<span>' . ($row['col_length']?htmlspecialchars($row['col_length']):"")
  862. . '</span>'
  863. . PMA\Template::get('columns_definitions/column_length')->render(
  864. array(
  865. 'columnNumber' => $row_num,
  866. 'ci' => 2,
  867. 'ci_offset' => 0,
  868. 'length_values_input_size' => 8,
  869. 'length_to_display' => $row['col_length']
  870. )
  871. )
  872. . '</td>';
  873. $meta = array();
  874. if (!isset($row['col_default']) || $row['col_default'] == '') {
  875. $meta['DefaultType'] = 'NONE';
  876. } else {
  877. if ($row['col_default'] == 'CURRENT_TIMESTAMP'
  878. || $row['col_default'] == 'NULL'
  879. ) {
  880. $meta['DefaultType'] = $row['col_default'];
  881. } else {
  882. $meta['DefaultType'] = 'USER_DEFINED';
  883. $meta['DefaultValue'] = $row['col_default'];
  884. }
  885. }
  886. $tableHtml .=
  887. '<td class="nowrap" name="col_default"><span>' . (isset($row['col_default'])
  888. ? htmlspecialchars($row['col_default']) : 'None')
  889. . '</span>'
  890. . PMA\Template::get('columns_definitions/column_default')
  891. ->render(
  892. array(
  893. 'columnNumber' => $row_num,
  894. 'ci' => 3,
  895. 'ci_offset' => 0,
  896. 'type_upper' => /*overload*/mb_strtoupper($row['col_type']),
  897. 'columnMeta' => $meta
  898. )
  899. )
  900. . '</td>';
  901. $tableHtml .=
  902. '<td name="collation" class="nowrap">'
  903. . '<span>' . htmlspecialchars($row['col_collation']) . '</span>'
  904. . PMA_generateCharsetDropdownBox(
  905. PMA_CSDROPDOWN_COLLATION, 'field_collation[' . $row_num . ']',
  906. 'field_' . $row_num . '_4', $row['col_collation'], false
  907. )
  908. . '</td>';
  909. $tableHtml .=
  910. '<td class="nowrap" name="col_attribute">'
  911. . '<span>' .
  912. ($row['col_attribute']
  913. ? htmlspecialchars($row['col_attribute']) : "" )
  914. . '</span>'
  915. . PMA\Template::get('columns_definitions/column_attribute')
  916. ->render(
  917. array(
  918. 'columnNumber' => $row_num,
  919. 'ci' => 5,
  920. 'ci_offset' => 0,
  921. 'extracted_columnspec' => array(),
  922. 'columnMeta' => $row['col_attribute'],
  923. 'submit_attribute' => false,
  924. )
  925. )
  926. . '</td>';
  927. $tableHtml .=
  928. '<td class="nowrap" name="col_isNull">'
  929. . '<span>' . ($row['col_isNull'] ? __('Yes') : __('No'))
  930. . '</span>'
  931. . PMA\Template::get('columns_definitions/column_null')
  932. ->render(
  933. array(
  934. 'columnNumber' => $row_num,
  935. 'ci' => 6,
  936. 'ci_offset' => 0,
  937. 'columnMeta' => array(
  938. 'Null' => $row['col_isNull']
  939. )
  940. )
  941. )
  942. . '</td>';
  943. $tableHtml .=
  944. '<td class="nowrap" name="col_extra"><span>'
  945. . htmlspecialchars($row['col_extra']) . '</span>'
  946. . PMA\Template::get('columns_definitions/column_extra')->render(
  947. array(
  948. 'columnNumber' => $row_num,
  949. 'ci' => 7,
  950. 'ci_offset' => 0,
  951. 'columnMeta' => array('Extra'=>$row['col_extra'])
  952. )
  953. )
  954. . '</td>';
  955. $tableHtml .= '</tr>';
  956. return $tableHtml;
  957. }
  958. /**
  959. * build html for editing a row in central columns table
  960. *
  961. * @param array $row array contains complete information of
  962. * a particular row of central list table
  963. * @param boolean $odd_row set true if the row is at odd number position
  964. * @param int $row_num position the row in the table
  965. *
  966. * @return string html of a particular row in the central columns table.
  967. */
  968. function PMA_getHTMLforCentralColumnsEditTableRow($row, $odd_row, $row_num)
  969. {
  970. $tableHtml = '<tr class="' . ($odd_row ? 'odd' : 'even') . '">'
  971. . '<input name="orig_col_name[' . $row_num . ']" type="hidden" '
  972. . 'value="' . htmlspecialchars($row['col_name']) . '">'
  973. . '<td name="col_name" class="nowrap">'
  974. . PMA\Template::get('columns_definitions/column_name')
  975. ->render(
  976. array(
  977. 'columnNumber' => $row_num,
  978. 'ci' => 0,
  979. 'ci_offset' => 0,
  980. 'columnMeta' => array(
  981. 'Field' => $row['col_name']
  982. ),
  983. 'cfgRelation' => array(
  984. 'centralcolumnswork' => false
  985. )
  986. )
  987. )
  988. . '</td>';
  989. $tableHtml .=
  990. '<td name = "col_type" class="nowrap">'
  991. . PMA\Template::get('columns_definitions/column_type')
  992. ->render(
  993. array(
  994. 'columnNumber' => $row_num,
  995. 'ci' => 1,
  996. 'ci_offset' => 0,
  997. 'type_upper' => /*overload*/mb_strtoupper($row['col_type']),
  998. 'columnMeta' => array()
  999. )
  1000. )
  1001. . '</td>';
  1002. $tableHtml .=
  1003. '<td class="nowrap" name="col_length">'
  1004. . PMA\Template::get('columns_definitions/column_length')->render(
  1005. array(
  1006. 'columnNumber' => $row_num,
  1007. 'ci' => 2,
  1008. 'ci_offset' => 0,
  1009. 'length_values_input_size' => 8,
  1010. 'length_to_display' => $row['col_length']
  1011. )
  1012. )
  1013. . '</td>';
  1014. $meta = array();
  1015. if (!isset($row['col_default']) || $row['col_default'] == '') {
  1016. $meta['DefaultType'] = 'NONE';
  1017. } else {
  1018. if ($row['col_default'] == 'CURRENT_TIMESTAMP'
  1019. || $row['col_default'] == 'NULL'
  1020. ) {
  1021. $meta['DefaultType'] = $row['col_default'];
  1022. } else {
  1023. $meta['DefaultType'] = 'USER_DEFINED';
  1024. $meta['DefaultValue'] = $row['col_default'];
  1025. }
  1026. }
  1027. $tableHtml .=
  1028. '<td class="nowrap" name="col_default">'
  1029. . PMA\Template::get('columns_definitions/column_default')
  1030. ->render(
  1031. array(
  1032. 'columnNumber' => $row_num,
  1033. 'ci' => 3,
  1034. 'ci_offset' => 0,
  1035. 'type_upper' => /*overload*/mb_strtoupper($row['col_default']),
  1036. 'columnMeta' => $meta
  1037. )
  1038. )
  1039. . '</td>';
  1040. $tableHtml .=
  1041. '<td name="collation" class="nowrap">'
  1042. . PMA_generateCharsetDropdownBox(
  1043. PMA_CSDROPDOWN_COLLATION, 'field_collation[' . $row_num . ']',
  1044. 'field_' . $row_num . '_4', $row['col_collation'], false
  1045. )
  1046. . '</td>';
  1047. $tableHtml .=
  1048. '<td class="nowrap" name="col_attribute">'
  1049. . PMA\Template::get('columns_definitions/column_attribute')
  1050. ->render(
  1051. array(
  1052. 'columnNumber' => $row_num,
  1053. 'ci' => 5,
  1054. 'ci_offset' => 0,
  1055. 'extracted_columnspec' => array(
  1056. 'attribute' => $row['col_attribute']
  1057. ),
  1058. 'columnMeta' => array(),
  1059. 'submit_attribute' => false,
  1060. )
  1061. )
  1062. . '</td>';
  1063. $tableHtml .=
  1064. '<td class="nowrap" name="col_isNull">'
  1065. . PMA\Template::get('columns_definitions/column_null')
  1066. ->render(
  1067. array(
  1068. 'columnNumber' => $row_num,
  1069. 'ci' => 6,
  1070. 'ci_offset' => 0,
  1071. 'columnMeta' => array(
  1072. 'Null' => $row['col_isNull']
  1073. )
  1074. )
  1075. )
  1076. . '</td>';
  1077. $tableHtml .=
  1078. '<td class="nowrap" name="col_extra">'
  1079. . PMA\Template::get('columns_definitions/column_extra')->render(
  1080. array(
  1081. 'columnNumber' => $row_num,
  1082. 'ci' => 7,
  1083. 'ci_offset' => 0,
  1084. 'columnMeta' => array('Extra' => $row['col_extra'])
  1085. )
  1086. )
  1087. . '</td>';
  1088. $tableHtml .= '</tr>';
  1089. return $tableHtml;
  1090. }
  1091. /**
  1092. * get the list of columns in given database excluding
  1093. * the columns present in current table
  1094. *
  1095. * @param string $db selected database
  1096. * @param string $table current table name
  1097. *
  1098. * @return string encoded list of columns present in central list for the given
  1099. * database
  1100. */
  1101. function PMA_getCentralColumnsListRaw($db, $table)
  1102. {
  1103. $cfgCentralColumns = PMA_centralColumnsGetParams();
  1104. if (empty($cfgCentralColumns)) {
  1105. return json_encode(array());
  1106. }
  1107. $centralTable = $cfgCentralColumns['table'];
  1108. if (empty($table) || $table == '') {
  1109. $query = 'SELECT * FROM ' . PMA_Util::backquote($centralTable) . ' '
  1110. . 'WHERE db_name = \'' . $db . '\';';
  1111. } else {
  1112. $GLOBALS['dbi']->selectDb($db, $GLOBALS['userlink']);
  1113. $columns = (array) $GLOBALS['dbi']->getColumnNames(
  1114. $db, $table, $GLOBALS['userlink']
  1115. );
  1116. $cols = '';
  1117. foreach ($columns as $col_select) {
  1118. $cols .= '\'' . PMA_Util::sqlAddSlashes($col_select) . '\',';
  1119. }
  1120. $cols = trim($cols, ',');
  1121. $query = 'SELECT * FROM ' . PMA_Util::backquote($centralTable) . ' '
  1122. . 'WHERE db_name = \'' . $db . '\'';
  1123. if ($cols) {
  1124. $query .= ' AND col_name NOT IN (' . $cols . ')';
  1125. }
  1126. $query .= ';';
  1127. }
  1128. $GLOBALS['dbi']->selectDb($cfgCentralColumns['db'], $GLOBALS['controllink']);
  1129. $columns_list = (array)$GLOBALS['dbi']->fetchResult(
  1130. $query, null, null, $GLOBALS['controllink']
  1131. );
  1132. PMA_handleColumnExtra($columns_list);
  1133. return json_encode($columns_list);
  1134. }
  1135. /**
  1136. * Get HTML for "check all" check box with "with selected" dropdown
  1137. *
  1138. * @param string $pmaThemeImage pma theme image url
  1139. * @param string $text_dir url for text directory
  1140. *
  1141. * @return string $html_output
  1142. */
  1143. function PMA_getCentralColumnsTableFooter($pmaThemeImage, $text_dir)
  1144. {
  1145. $html_output = PMA_Util::getWithSelected(
  1146. $pmaThemeImage, $text_dir, "tableslistcontainer"
  1147. );
  1148. $html_output .= PMA_Util::getButtonOrImage(
  1149. 'edit_central_columns', 'mult_submit change_central_columns',
  1150. 'submit_mult_change', __('Edit'), 'b_edit.png', 'edit central columns'
  1151. );
  1152. $html_output .= PMA_Util::getButtonOrImage(
  1153. 'delete_central_columns', 'mult_submit',
  1154. 'submit_mult_central_columns_remove',
  1155. __('Delete'), 'b_drop.png',
  1156. 'remove_from_central_columns'
  1157. );
  1158. return $html_output;
  1159. }
  1160. /**
  1161. * function generate and return the table footer for
  1162. * multiple edit central columns page
  1163. *
  1164. * @return string html for table footer in central columns multi edit page
  1165. */
  1166. function PMA_getCentralColumnsEditTableFooter()
  1167. {
  1168. $html_output = '<fieldset class="tblFooters">'
  1169. . '<input type="submit" '
  1170. . 'name="save_multi_central_column_edit" value="' . __('Save') . '" />'
  1171. . '</fieldset>';
  1172. return $html_output;
  1173. }
  1174. /**
  1175. * Column `col_extra` is used to store both extra and attributes for a column.
  1176. * This method separates them.
  1177. *
  1178. * @param array &$columns_list columns list
  1179. *
  1180. * @return void
  1181. */
  1182. function PMA_handleColumnExtra(&$columns_list)
  1183. {
  1184. foreach ($columns_list as &$row) {
  1185. $vals = explode(',', $row['col_extra']);
  1186. if (in_array('BINARY', $vals)) {
  1187. $row['col_attribute'] = 'BINARY';
  1188. } elseif (in_array('UNSIGNED', $vals)) {
  1189. $row['col_attribute'] = 'UNSIGNED';
  1190. } elseif (in_array('UNSIGNED ZEROFILL', $vals)) {
  1191. $row['col_attribute'] = 'UNSIGNED ZEROFILL';
  1192. } elseif (in_array('on update CURRENT_TIMESTAMP', $vals)) {
  1193. $row['col_attribute'] = 'on update CURRENT_TIMESTAMP';
  1194. } else {
  1195. $row['col_attribute'] = '';
  1196. }
  1197. if (in_array('auto_increment', $vals)) {
  1198. $row['col_extra'] = 'auto_increment';
  1199. } else {
  1200. $row['col_extra'] = '';
  1201. }
  1202. }
  1203. }
  1204. /**
  1205. * build html for adding a new user defined column to central list
  1206. *
  1207. * @param string $db current database
  1208. *
  1209. * @return string html of the form to let user add a new user defined column to the
  1210. * list
  1211. */
  1212. function PMA_getHTMLforAddNewColumn($db)
  1213. {
  1214. $addNewColumn = '<div id="add_col_div"><a href="#">'
  1215. . '<span>+</span> ' . __('Add new column') . '</a>'
  1216. . '<form id="add_new" style="min-width:100%;display:none" '
  1217. . 'method="post" action="db_central_columns.php">'
  1218. . PMA_URL_getHiddenInputs(
  1219. $db
  1220. )
  1221. . '<input type="hidden" name="add_new_column" value="add_new_column">'
  1222. . '<table>';
  1223. $addNewColumn .= PMA_getCentralColumnsTableHeader();
  1224. $addNewColumn .= '<tr>'
  1225. . '<td></td>'
  1226. . '<td name="col_name" class="nowrap">'
  1227. . PMA\Template::get('columns_definitions/column_name')
  1228. ->render(
  1229. array(
  1230. 'columnNumber' => 0,
  1231. 'ci' => 0,
  1232. 'ci_offset' => 0,
  1233. 'columnMeta' => array(),
  1234. 'cfgRelation' => array(
  1235. 'centralcolumnswork' => false
  1236. )
  1237. )
  1238. )
  1239. . '</td>'
  1240. . '<td name = "col_type" class="nowrap">'
  1241. . PMA\Template::get('columns_definitions/column_type')
  1242. ->render(
  1243. array(
  1244. 'columnNumber' => 0,
  1245. 'ci' => 1,
  1246. 'ci_offset' => 0,
  1247. 'type_upper' => '',
  1248. 'columnMeta' => array()
  1249. )
  1250. )
  1251. . '</td>'
  1252. . '<td class="nowrap" name="col_length">'
  1253. . PMA\Template::get('columns_definitions/column_length')->render(
  1254. array(
  1255. 'columnNumber' => 0,
  1256. 'ci' => 2,
  1257. 'ci_offset' => 0,
  1258. 'length_values_input_size' => 8,
  1259. 'length_to_display' => ''
  1260. )
  1261. )
  1262. . '</td>'
  1263. . '<td class="nowrap" name="col_default">'
  1264. . PMA\Template::get('columns_definitions/column_default')
  1265. ->render(
  1266. array(
  1267. 'columnNumber' => 0,
  1268. 'ci' => 3,
  1269. 'ci_offset' => 0,
  1270. 'type_upper' => '',
  1271. 'columnMeta' => array()
  1272. )
  1273. )
  1274. . '</td>'
  1275. . '<td name="collation" class="nowrap">'
  1276. . PMA_generateCharsetDropdownBox(
  1277. PMA_CSDROPDOWN_COLLATION, 'field_collation[0]',
  1278. 'field_0_4', null, false
  1279. )
  1280. . '</td>'
  1281. . '<td class="nowrap" name="col_attribute">'
  1282. . PMA\Template::get('columns_definitions/column_attribute')
  1283. ->render(
  1284. array(
  1285. 'columnNumber' => 0,
  1286. 'ci' => 5,
  1287. 'ci_offset' => 0,
  1288. 'extracted_columnspec' => array(),
  1289. 'columnMeta' => array(),
  1290. 'submit_attribute' => false,
  1291. )
  1292. )
  1293. . '</td>'
  1294. . '<td class="nowrap" name="col_isNull">'
  1295. . PMA\Template::get('columns_definitions/column_null')
  1296. ->render(
  1297. array(
  1298. 'columnNumber' => 0,
  1299. 'ci' => 6,
  1300. 'ci_offset' => 0,
  1301. 'columnMeta' => array()
  1302. )
  1303. )
  1304. . '</td>'
  1305. . '<td class="nowrap" name="col_extra">'
  1306. . PMA\Template::get('columns_definitions/column_extra')->render(
  1307. array(
  1308. 'columnNumber' => 0,
  1309. 'ci' => 7,
  1310. 'ci_offset' => 0,
  1311. 'columnMeta' => array()
  1312. )
  1313. )
  1314. . '</td>'
  1315. . ' <td>'
  1316. . '<input id="add_column_save" type="submit" '
  1317. . ' value="Save"/></td>'
  1318. . '</tr>';
  1319. $addNewColumn .= '</table></form></div>';
  1320. return $addNewColumn;
  1321. }
  1322. /**
  1323. * Get HTML for editing page central columns
  1324. *
  1325. * @param array $selected_fld Array containing the selected fields
  1326. * @param string $selected_db String containing the name of database
  1327. *
  1328. * @return string HTML for complete editing page for central columns
  1329. */
  1330. function PMA_getHTMLforEditingPage($selected_fld,$selected_db)
  1331. {
  1332. $html = '<form id="multi_edit_central_columns">';
  1333. $header_cells = array(
  1334. __('Name'), __('Type'), __('Length/Values'), __('Default'),
  1335. __('Collation'), __('Attributes'), __('Null'), __('A_I')
  1336. );
  1337. $html .= PMA_getCentralColumnsEditTableHeader($header_cells);
  1338. $selected_fld_safe = array();
  1339. foreach ($selected_fld as $key) {
  1340. $selected_fld_safe[] = PMA_Util::sqlAddSlashes($key);
  1341. }
  1342. $columns_list = implode("','", $selected_fld_safe);
  1343. $columns_list = "'" . $columns_list . "'";
  1344. $list_detail_cols = PMA_findExistingColNames($selected_db, $columns_list, true);
  1345. $odd_row = false;
  1346. $row_num = 0;
  1347. foreach ($list_detail_cols as $row) {
  1348. $tableHtmlRow = PMA_getHTMLforCentralColumnsEditTableRow(
  1349. $row, $odd_row, $row_num
  1350. );
  1351. $html .= $tableHtmlRow;
  1352. $odd_row = !$odd_row;
  1353. $row_num++;
  1354. }
  1355. $html .= '</table>';
  1356. $html .= PMA_getCentralColumnsEditTableFooter();
  1357. $html .= '</form>';
  1358. return $html;
  1359. }