insert_edit.lib.php 107 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082208320842085208620872088208920902091209220932094209520962097209820992100210121022103210421052106210721082109211021112112211321142115211621172118211921202121212221232124212521262127212821292130213121322133213421352136213721382139214021412142214321442145214621472148214921502151215221532154215521562157215821592160216121622163216421652166216721682169217021712172217321742175217621772178217921802181218221832184218521862187218821892190219121922193219421952196219721982199220022012202220322042205220622072208220922102211221222132214221522162217221822192220222122222223222422252226222722282229223022312232223322342235223622372238223922402241224222432244224522462247224822492250225122522253225422552256225722582259226022612262226322642265226622672268226922702271227222732274227522762277227822792280228122822283228422852286228722882289229022912292229322942295229622972298229923002301230223032304230523062307230823092310231123122313231423152316231723182319232023212322232323242325232623272328232923302331233223332334233523362337233823392340234123422343234423452346234723482349235023512352235323542355235623572358235923602361236223632364236523662367236823692370237123722373237423752376237723782379238023812382238323842385238623872388238923902391239223932394239523962397239823992400240124022403240424052406240724082409241024112412241324142415241624172418241924202421242224232424242524262427242824292430243124322433243424352436243724382439244024412442244324442445244624472448244924502451245224532454245524562457245824592460246124622463246424652466246724682469247024712472247324742475247624772478247924802481248224832484248524862487248824892490249124922493249424952496249724982499250025012502250325042505250625072508250925102511251225132514251525162517251825192520252125222523252425252526252725282529253025312532253325342535253625372538253925402541254225432544254525462547254825492550255125522553255425552556255725582559256025612562256325642565256625672568256925702571257225732574257525762577257825792580258125822583258425852586258725882589259025912592259325942595259625972598259926002601260226032604260526062607260826092610261126122613261426152616261726182619262026212622262326242625262626272628262926302631263226332634263526362637263826392640264126422643264426452646264726482649265026512652265326542655265626572658265926602661266226632664266526662667266826692670267126722673267426752676267726782679268026812682268326842685268626872688268926902691269226932694269526962697269826992700270127022703270427052706270727082709271027112712271327142715271627172718271927202721272227232724272527262727272827292730273127322733273427352736273727382739274027412742274327442745274627472748274927502751275227532754275527562757275827592760276127622763276427652766276727682769277027712772277327742775277627772778277927802781278227832784278527862787278827892790279127922793279427952796279727982799280028012802280328042805280628072808280928102811281228132814281528162817281828192820282128222823282428252826282728282829283028312832283328342835283628372838283928402841284228432844284528462847284828492850285128522853285428552856285728582859286028612862286328642865286628672868286928702871287228732874287528762877287828792880288128822883288428852886288728882889289028912892289328942895289628972898289929002901290229032904290529062907290829092910291129122913291429152916
  1. <?php
  2. /* vim: set expandtab sw=4 ts=4 sts=4: */
  3. /**
  4. * set of functions with the insert/edit features in pma
  5. *
  6. * @package PhpMyAdmin
  7. */
  8. if (! defined('PHPMYADMIN')) {
  9. exit;
  10. }
  11. /**
  12. * Retrieve form parameters for insert/edit form
  13. *
  14. * @param string $db name of the database
  15. * @param string $table name of the table
  16. * @param array $where_clauses where clauses
  17. * @param array $where_clause_array array of where clauses
  18. * @param string $err_url error url
  19. *
  20. * @return array $_form_params array of insert/edit form parameters
  21. */
  22. function PMA_getFormParametersForInsertForm($db, $table, $where_clauses,
  23. $where_clause_array, $err_url
  24. ) {
  25. $_form_params = array(
  26. 'db' => $db,
  27. 'table' => $table,
  28. 'goto' => $GLOBALS['goto'],
  29. 'err_url' => $err_url,
  30. 'sql_query' => $_REQUEST['sql_query'],
  31. );
  32. if (isset($where_clauses)) {
  33. foreach ($where_clause_array as $key_id => $where_clause) {
  34. $_form_params['where_clause[' . $key_id . ']'] = trim($where_clause);
  35. }
  36. }
  37. if (isset($_REQUEST['clause_is_unique'])) {
  38. $_form_params['clause_is_unique'] = $_REQUEST['clause_is_unique'];
  39. }
  40. return $_form_params;
  41. }
  42. /**
  43. * Creates array of where clauses
  44. *
  45. * @param array $where_clause where clause
  46. *
  47. * @return array|void whereClauseArray array of where clauses
  48. */
  49. function PMA_getWhereClauseArray($where_clause)
  50. {
  51. if (!isset($where_clause)) {
  52. return;
  53. }
  54. if (is_array($where_clause)) {
  55. return $where_clause;
  56. }
  57. return array(0 => $where_clause);
  58. }
  59. /**
  60. * Analysing where clauses array
  61. *
  62. * @param array $where_clause_array array of where clauses
  63. * @param string $table name of the table
  64. * @param string $db name of the database
  65. *
  66. * @return array $where_clauses, $result, $rows
  67. */
  68. function PMA_analyzeWhereClauses(
  69. $where_clause_array, $table, $db
  70. ) {
  71. $rows = array();
  72. $result = array();
  73. $where_clauses = array();
  74. $found_unique_key = false;
  75. foreach ($where_clause_array as $key_id => $where_clause) {
  76. $local_query = 'SELECT * FROM '
  77. . PMA_Util::backquote($db) . '.'
  78. . PMA_Util::backquote($table)
  79. . ' WHERE ' . $where_clause . ';';
  80. $result[$key_id] = $GLOBALS['dbi']->query(
  81. $local_query, null, PMA_DatabaseInterface::QUERY_STORE
  82. );
  83. $rows[$key_id] = $GLOBALS['dbi']->fetchAssoc($result[$key_id]);
  84. $where_clauses[$key_id] = str_replace('\\', '\\\\', $where_clause);
  85. $has_unique_condition = PMA_showEmptyResultMessageOrSetUniqueCondition(
  86. $rows, $key_id, $where_clause_array, $local_query, $result
  87. );
  88. if ($has_unique_condition) {
  89. $found_unique_key = true;
  90. }
  91. }
  92. return array($where_clauses, $result, $rows, $found_unique_key);
  93. }
  94. /**
  95. * Show message for empty result or set the unique_condition
  96. *
  97. * @param array $rows MySQL returned rows
  98. * @param string $key_id ID in current key
  99. * @param array $where_clause_array array of where clauses
  100. * @param string $local_query query performed
  101. * @param array $result MySQL result handle
  102. *
  103. * @return boolean $has_unique_condition
  104. */
  105. function PMA_showEmptyResultMessageOrSetUniqueCondition($rows, $key_id,
  106. $where_clause_array, $local_query, $result
  107. ) {
  108. $has_unique_condition = false;
  109. // No row returned
  110. if (! $rows[$key_id]) {
  111. unset($rows[$key_id], $where_clause_array[$key_id]);
  112. PMA_Response::getInstance()->addHtml(
  113. PMA_Util::getMessage(
  114. __('MySQL returned an empty result set (i.e. zero rows).'),
  115. $local_query
  116. )
  117. );
  118. /**
  119. * @todo not sure what should be done at this point, but we must not
  120. * exit if we want the message to be displayed
  121. */
  122. } else {// end if (no row returned)
  123. $meta = $GLOBALS['dbi']->getFieldsMeta($result[$key_id]);
  124. list($unique_condition, $tmp_clause_is_unique)
  125. = PMA_Util::getUniqueCondition(
  126. $result[$key_id], count($meta), $meta, $rows[$key_id], true
  127. );
  128. if (! empty($unique_condition)) {
  129. $has_unique_condition = true;
  130. }
  131. unset($unique_condition, $tmp_clause_is_unique);
  132. }
  133. return $has_unique_condition;
  134. }
  135. /**
  136. * No primary key given, just load first row
  137. *
  138. * @param string $table name of the table
  139. * @param string $db name of the database
  140. *
  141. * @return array containing $result and $rows arrays
  142. */
  143. function PMA_loadFirstRow($table, $db)
  144. {
  145. $result = $GLOBALS['dbi']->query(
  146. 'SELECT * FROM ' . PMA_Util::backquote($db)
  147. . '.' . PMA_Util::backquote($table) . ' LIMIT 1;',
  148. null,
  149. PMA_DatabaseInterface::QUERY_STORE
  150. );
  151. $rows = array_fill(0, $GLOBALS['cfg']['InsertRows'], false);
  152. return array($result, $rows);
  153. }
  154. /**
  155. * Add some url parameters
  156. *
  157. * @param array $url_params containing $db and $table as url parameters
  158. * @param array $where_clause_array where clauses array
  159. * @param string $where_clause where clause
  160. *
  161. * @return array Add some url parameters to $url_params array and return it
  162. */
  163. function PMA_urlParamsInEditMode($url_params, $where_clause_array, $where_clause)
  164. {
  165. if (isset($where_clause)) {
  166. foreach ($where_clause_array as $where_clause) {
  167. $url_params['where_clause'] = trim($where_clause);
  168. }
  169. }
  170. if (! empty($_REQUEST['sql_query'])) {
  171. $url_params['sql_query'] = $_REQUEST['sql_query'];
  172. }
  173. return $url_params;
  174. }
  175. /**
  176. * Show function fields in data edit view in pma
  177. *
  178. * @param array $url_params containing url parameters
  179. * @param boolean $showFuncFields whether to show function field
  180. *
  181. * @return string an html snippet
  182. */
  183. function PMA_showFunctionFieldsInEditMode($url_params, $showFuncFields)
  184. {
  185. $params = array();
  186. if (! $showFuncFields) {
  187. $params['ShowFunctionFields'] = 1;
  188. } else {
  189. $params['ShowFunctionFields'] = 0;
  190. }
  191. $params['ShowFieldTypesInDataEditView']
  192. = $GLOBALS['cfg']['ShowFieldTypesInDataEditView'];
  193. $params['goto'] = 'sql.php';
  194. $this_url_params = array_merge($url_params, $params);
  195. if (! $showFuncFields) {
  196. return ' : <a href="tbl_change.php'
  197. . PMA_URL_getCommon($this_url_params) . '">'
  198. . __('Function')
  199. . '</a>' . "\n";
  200. }
  201. return '<th><a href="tbl_change.php'
  202. . PMA_URL_getCommon($this_url_params)
  203. . '" title="' . __('Hide') . '">'
  204. . __('Function')
  205. . '</a></th>' . "\n";
  206. }
  207. /**
  208. * Show field types in data edit view in pma
  209. *
  210. * @param array $url_params containing url parameters
  211. * @param boolean $showColumnType whether to show column type
  212. *
  213. * @return string an html snippet
  214. */
  215. function PMA_showColumnTypesInDataEditView($url_params, $showColumnType)
  216. {
  217. $params = array();
  218. if (! $showColumnType) {
  219. $params['ShowFieldTypesInDataEditView'] = 1;
  220. } else {
  221. $params['ShowFieldTypesInDataEditView'] = 0;
  222. }
  223. $params['ShowFunctionFields'] = $GLOBALS['cfg']['ShowFunctionFields'];
  224. $params['goto'] = 'sql.php';
  225. $this_other_url_params = array_merge($url_params, $params);
  226. if (! $showColumnType) {
  227. return ' : <a href="tbl_change.php'
  228. . PMA_URL_getCommon($this_other_url_params) . '">'
  229. . __('Type') . '</a>' . "\n";
  230. }
  231. return '<th><a href="tbl_change.php'
  232. . PMA_URL_getCommon($this_other_url_params)
  233. . '" title="' . __('Hide') . '">' . __('Type') . '</a></th>' . "\n";
  234. }
  235. /**
  236. * Retrieve the default for datetime data type
  237. *
  238. * @param array $column containing column type, Default and null
  239. *
  240. * @return void
  241. */
  242. function PMA_getDefaultForDatetime($column)
  243. {
  244. // d a t e t i m e
  245. //
  246. // Current date should not be set as default if the field is NULL
  247. // for the current row, but do not put here the current datetime
  248. // if there is a default value (the real default value will be set
  249. // in the Default value logic below)
  250. // Note: (tested in MySQL 4.0.16): when lang is some UTF-8,
  251. // $column['Default'] is not set if it contains NULL:
  252. // Array ([Field] => d [Type] => datetime [Null] => YES [Key] =>
  253. // [Extra] => [True_Type] => datetime)
  254. // but, look what we get if we switch to iso: (Default is NULL)
  255. // Array ([Field] => d [Type] => datetime [Null] => YES [Key] =>
  256. // [Default] => [Extra] => [True_Type] => datetime)
  257. // so I force a NULL into it (I don't think it's possible
  258. // to have an empty default value for DATETIME)
  259. // then, the "if" after this one will work
  260. if ($column['Type'] == 'datetime'
  261. && ! isset($column['Default'])
  262. && isset($column['Null'])
  263. && $column['Null'] == 'YES'
  264. ) {
  265. $column['Default'] = null;
  266. }
  267. }
  268. /**
  269. * Analyze the table column array
  270. *
  271. * @param array $column description of column in given table
  272. * @param array $comments_map comments for every column that has a comment
  273. * @param boolean $timestamp_seen whether a timestamp has been seen
  274. *
  275. * @return array description of column in given table
  276. */
  277. function PMA_analyzeTableColumnsArray($column, $comments_map, $timestamp_seen)
  278. {
  279. $column['Field_html'] = htmlspecialchars($column['Field']);
  280. $column['Field_md5'] = md5($column['Field']);
  281. // True_Type contains only the type (stops at first bracket)
  282. $column['True_Type'] = preg_replace('@\(.*@s', '', $column['Type']);
  283. PMA_getDefaultForDatetime($column);
  284. $column['len'] = preg_match('@float|double@', $column['Type']) ? 100 : -1;
  285. $column['Field_title'] = PMA_getColumnTitle($column, $comments_map);
  286. $column['is_binary'] = PMA_isColumnBinary($column);
  287. $column['is_blob'] = PMA_isColumnBlob($column);
  288. $column['is_char'] = PMA_isColumnChar($column);
  289. list($column['pma_type'], $column['wrap'], $column['first_timestamp'])
  290. = PMA_getEnumSetAndTimestampColumns($column, $timestamp_seen);
  291. return $column;
  292. }
  293. /**
  294. * Retrieve the column title
  295. *
  296. * @param array $column description of column in given table
  297. * @param array $comments_map comments for every column that has a comment
  298. *
  299. * @return string column title
  300. */
  301. function PMA_getColumnTitle($column, $comments_map)
  302. {
  303. if (isset($comments_map[$column['Field']])) {
  304. return '<span style="border-bottom: 1px dashed black;" title="'
  305. . htmlspecialchars($comments_map[$column['Field']]) . '">'
  306. . $column['Field_html'] . '</span>';
  307. } else {
  308. return $column['Field_html'];
  309. }
  310. }
  311. /**
  312. * check whether the column is a bainary
  313. *
  314. * @param array $column description of column in given table
  315. *
  316. * @return boolean If check to ensure types such as "enum('one','two','binary',..)"
  317. * or "enum('one','two','varbinary',..)" are not categorized as
  318. * binary.
  319. */
  320. function PMA_isColumnBinary($column)
  321. {
  322. // The type column.
  323. // Fix for bug #3152931 'ENUM and SET cannot have "Binary" option'
  324. if (stripos($column['Type'], 'binary') === 0
  325. || stripos($column['Type'], 'varbinary') === 0
  326. ) {
  327. return stristr($column['Type'], 'binary');
  328. } else {
  329. return false;
  330. }
  331. }
  332. /**
  333. * check whether the column is a blob
  334. *
  335. * @param array $column description of column in given table
  336. *
  337. * @return boolean If check to ensure types such as "enum('one','two','blob',..)"
  338. * or "enum('one','two','tinyblob',..)" etc. are not categorized
  339. * as blob.
  340. */
  341. function PMA_isColumnBlob($column)
  342. {
  343. if (stripos($column['Type'], 'blob') === 0
  344. || stripos($column['Type'], 'tinyblob') === 0
  345. || stripos($column['Type'], 'mediumblob') === 0
  346. || stripos($column['Type'], 'longblob') === 0
  347. ) {
  348. return stristr($column['Type'], 'blob');
  349. } else {
  350. return false;
  351. }
  352. }
  353. /**
  354. * check is table column char
  355. *
  356. * @param array $column description of column in given table
  357. *
  358. * @return boolean If check to ensure types such as "enum('one','two','char',..)" or
  359. * "enum('one','two','varchar',..)" are not categorized as char.
  360. */
  361. function PMA_isColumnChar($column)
  362. {
  363. if (stripos($column['Type'], 'char') === 0
  364. || stripos($column['Type'], 'varchar') === 0
  365. ) {
  366. return stristr($column['Type'], 'char');
  367. } else {
  368. return false;
  369. }
  370. }
  371. /**
  372. * Retrieve set, enum, timestamp table columns
  373. *
  374. * @param array $column description of column in given table
  375. * @param boolean $timestamp_seen whether a timestamp has been seen
  376. *
  377. * @return array $column['pma_type'], $column['wrap'], $column['first_timestamp']
  378. */
  379. function PMA_getEnumSetAndTimestampColumns($column, $timestamp_seen)
  380. {
  381. $column['first_timestamp'] = false;
  382. switch ($column['True_Type']) {
  383. case 'set':
  384. $column['pma_type'] = 'set';
  385. $column['wrap'] = '';
  386. break;
  387. case 'enum':
  388. $column['pma_type'] = 'enum';
  389. $column['wrap'] = '';
  390. break;
  391. case 'timestamp':
  392. if (! $timestamp_seen) { // can only occur once per table
  393. $timestamp_seen = true;
  394. $column['first_timestamp'] = true;
  395. }
  396. $column['pma_type'] = $column['Type'];
  397. $column['wrap'] = ' nowrap';
  398. break;
  399. default:
  400. $column['pma_type'] = $column['Type'];
  401. $column['wrap'] = ' nowrap';
  402. break;
  403. }
  404. return array($column['pma_type'], $column['wrap'], $column['first_timestamp']);
  405. }
  406. /**
  407. * The function column
  408. * We don't want binary data to be destroyed
  409. * Note: from the MySQL manual: "BINARY doesn't affect how the column is
  410. * stored or retrieved" so it does not mean that the contents is binary
  411. *
  412. * @param array $column description of column in given table
  413. * @param boolean $is_upload upload or no
  414. * @param string $column_name_appendix the name atttibute
  415. * @param string $unnullify_trigger validation string
  416. * @param array $no_support_types list of datatypes that are not (yet)
  417. * handled by PMA
  418. * @param integer $tabindex_for_function +3000
  419. * @param integer $tabindex tab index
  420. * @param integer $idindex id index
  421. * @param boolean $insert_mode insert mode or edit mode
  422. *
  423. * @return string an html sippet
  424. */
  425. function PMA_getFunctionColumn($column, $is_upload, $column_name_appendix,
  426. $unnullify_trigger, $no_support_types, $tabindex_for_function,
  427. $tabindex, $idindex, $insert_mode
  428. ) {
  429. $html_output = '';
  430. if (($GLOBALS['cfg']['ProtectBinary'] && $column['is_blob'] && ! $is_upload)
  431. || ($GLOBALS['cfg']['ProtectBinary'] === 'all' && $column['is_binary'])
  432. || ($GLOBALS['cfg']['ProtectBinary'] === 'noblob' && ! $column['is_blob'])
  433. ) {
  434. $html_output .= '<td class="center">' . __('Binary') . '</td>' . "\n";
  435. } elseif (strstr($column['True_Type'], 'enum')
  436. || strstr($column['True_Type'], 'set')
  437. || in_array($column['pma_type'], $no_support_types)
  438. ) {
  439. $html_output .= '<td class="center">--</td>' . "\n";
  440. } else {
  441. $html_output .= '<td>' . "\n";
  442. $html_output .= '<select name="funcs' . $column_name_appendix . '"'
  443. . ' ' . $unnullify_trigger
  444. . ' tabindex="' . ($tabindex + $tabindex_for_function) . '"'
  445. . ' id="field_' . $idindex . '_1">';
  446. $html_output .= PMA_Util::getFunctionsForField($column, $insert_mode) . "\n";
  447. $html_output .= '</select>' . "\n";
  448. $html_output .= '</td>' . "\n";
  449. }
  450. return $html_output;
  451. }
  452. /**
  453. * The null column
  454. *
  455. * @param array $column description of column in given table
  456. * @param string $column_name_appendix the name atttibute
  457. * @param array $real_null_value is column value null or not null
  458. * @param integer $tabindex tab index
  459. * @param integer $tabindex_for_null +6000
  460. * @param integer $idindex id index
  461. * @param string $vkey [multi_edit]['row_id']
  462. * @param array $foreigners keys into foreign fields
  463. * @param array $foreignData data about the foreign keys
  464. *
  465. * @return string an html snippet
  466. */
  467. function PMA_getNullColumn($column, $column_name_appendix, $real_null_value,
  468. $tabindex, $tabindex_for_null, $idindex, $vkey, $foreigners, $foreignData
  469. ) {
  470. if ($column['Null'] != 'YES') {
  471. return "<td></td>\n";
  472. }
  473. $html_output = '';
  474. $html_output .= '<td>' . "\n";
  475. $html_output .= '<input type="hidden" name="fields_null_prev'
  476. . $column_name_appendix . '"';
  477. if ($real_null_value && !$column['first_timestamp']) {
  478. $html_output .= ' value="on"';
  479. }
  480. $html_output .= ' />' . "\n";
  481. $html_output .= '<input type="checkbox" class="checkbox_null" tabindex="'
  482. . ($tabindex + $tabindex_for_null) . '"'
  483. . ' name="fields_null' . $column_name_appendix . '"';
  484. if ($real_null_value) {
  485. $html_output .= ' checked="checked"';
  486. }
  487. $html_output .= ' id="field_' . ($idindex) . '_2" />';
  488. // nullify_code is needed by the js nullify() function
  489. $nullify_code = PMA_getNullifyCodeForNullColumn(
  490. $column, $foreigners, $foreignData
  491. );
  492. // to be able to generate calls to nullify() in jQuery
  493. $html_output .= '<input type="hidden" class="nullify_code" name="nullify_code'
  494. . $column_name_appendix . '" value="' . $nullify_code . '" />';
  495. $html_output .= '<input type="hidden" class="hashed_field" name="hashed_field'
  496. . $column_name_appendix . '" value="' . $column['Field_md5'] . '" />';
  497. $html_output .= '<input type="hidden" class="multi_edit" name="multi_edit'
  498. . $column_name_appendix . '" value="' . PMA_escapeJsString($vkey) . '" />';
  499. $html_output .= '</td>' . "\n";
  500. return $html_output;
  501. }
  502. /**
  503. * Retrieve the nullify code for the null column
  504. *
  505. * @param array $column description of column in given table
  506. * @param array $foreigners keys into foreign fields
  507. * @param array $foreignData data about the foreign keys
  508. *
  509. * @return integer $nullify_code
  510. */
  511. function PMA_getNullifyCodeForNullColumn($column, $foreigners, $foreignData)
  512. {
  513. if (strstr($column['True_Type'], 'enum')) {
  514. if (strlen($column['Type']) > 20) {
  515. $nullify_code = '1';
  516. } else {
  517. $nullify_code = '2';
  518. }
  519. } elseif (strstr($column['True_Type'], 'set')) {
  520. $nullify_code = '3';
  521. } elseif ($foreigners
  522. && isset($foreigners[$column['Field']])
  523. && $foreignData['foreign_link'] == false
  524. ) {
  525. // foreign key in a drop-down
  526. $nullify_code = '4';
  527. } elseif ($foreigners
  528. && isset($foreigners[$column['Field']])
  529. && $foreignData['foreign_link'] == true
  530. ) {
  531. // foreign key with a browsing icon
  532. $nullify_code = '6';
  533. } else {
  534. $nullify_code = '5';
  535. }
  536. return $nullify_code;
  537. }
  538. /**
  539. * Get the HTML elements for value column in insert form
  540. * (here, "column" is used in the sense of HTML column in HTML table)
  541. *
  542. * @param array $column description of column in given table
  543. * @param string $backup_field hidden input field
  544. * @param string $column_name_appendix the name atttibute
  545. * @param string $unnullify_trigger validation string
  546. * @param integer $tabindex tab index
  547. * @param integer $tabindex_for_value offset for the values tabindex
  548. * @param integer $idindex id index
  549. * @param array $data description of the column field
  550. * @param string $special_chars special characters
  551. * @param array $foreignData data about the foreign keys
  552. * @param boolean $odd_row whether row is odd
  553. * @param array $paramTableDbArray array containing $table and $db
  554. * @param int $rownumber the row number
  555. * @param array $titles An HTML IMG tag for a particular icon from
  556. * a theme, which may be an actual file or
  557. * an icon from a sprite
  558. * @param string $text_dir text direction
  559. * @param string $special_chars_encoded replaced char if the string starts
  560. * with a \r\n pair (0x0d0a) add an extra \n
  561. * @param string $vkey [multi_edit]['row_id']
  562. * @param boolean $is_upload is upload or not
  563. * @param integer $biggest_max_file_size 0 intger
  564. * @param string $default_char_editing default char editing mode which is stroe
  565. * in the config.inc.php script
  566. * @param array $no_support_types list of datatypes that are not (yet)
  567. * handled by PMA
  568. * @param array $gis_data_types list of GIS data types
  569. * @param array $extracted_columnspec associative array containing type,
  570. * spec_in_brackets and possibly
  571. * enum_set_values (another array)
  572. *
  573. * @return string an html snippet
  574. */
  575. function PMA_getValueColumn($column, $backup_field, $column_name_appendix,
  576. $unnullify_trigger, $tabindex, $tabindex_for_value, $idindex, $data,
  577. $special_chars, $foreignData, $odd_row, $paramTableDbArray, $rownumber,
  578. $titles, $text_dir, $special_chars_encoded, $vkey,
  579. $is_upload, $biggest_max_file_size,
  580. $default_char_editing, $no_support_types, $gis_data_types, $extracted_columnspec
  581. ) {
  582. $html_output = '';
  583. if ($foreignData['foreign_link'] == true) {
  584. $html_output .= PMA_getForeignLink(
  585. $column, $backup_field, $column_name_appendix,
  586. $unnullify_trigger, $tabindex, $tabindex_for_value, $idindex, $data,
  587. $paramTableDbArray, $rownumber, $titles
  588. );
  589. } elseif (is_array($foreignData['disp_row'])) {
  590. $html_output .= PMA_dispRowForeignData(
  591. $backup_field, $column_name_appendix,
  592. $unnullify_trigger, $tabindex, $tabindex_for_value,
  593. $idindex, $data, $foreignData
  594. );
  595. } elseif ($GLOBALS['cfg']['LongtextDoubleTextarea']
  596. && strstr($column['pma_type'], 'longtext')
  597. ) {
  598. $html_output = '&nbsp;</td>';
  599. $html_output .= '</tr>';
  600. $html_output .= '<tr class="' . ($odd_row ? 'odd' : 'even') . '">'
  601. . '<td colspan="5" class="right">';
  602. $html_output .= PMA_getTextarea(
  603. $column, $backup_field, $column_name_appendix, $unnullify_trigger,
  604. $tabindex, $tabindex_for_value, $idindex, $text_dir,
  605. $special_chars_encoded
  606. );
  607. } elseif (strstr($column['pma_type'], 'text')) {
  608. $html_output .= PMA_getTextarea(
  609. $column, $backup_field, $column_name_appendix, $unnullify_trigger,
  610. $tabindex, $tabindex_for_value, $idindex, $text_dir,
  611. $special_chars_encoded
  612. );
  613. $html_output .= "\n";
  614. if (strlen($special_chars) > 32000) {
  615. $html_output .= "</td>\n";
  616. $html_output .= '<td>' . __(
  617. 'Because of its length,<br /> this column might not be editable.'
  618. );
  619. }
  620. } elseif ($column['pma_type'] == 'enum') {
  621. $html_output .= PMA_getPmaTypeEnum(
  622. $column, $backup_field, $column_name_appendix, $extracted_columnspec,
  623. $unnullify_trigger, $tabindex, $tabindex_for_value, $idindex, $data
  624. );
  625. } elseif ($column['pma_type'] == 'set') {
  626. $html_output .= PMA_getPmaTypeSet(
  627. $column, $extracted_columnspec, $backup_field,
  628. $column_name_appendix, $unnullify_trigger, $tabindex,
  629. $tabindex_for_value, $idindex, $data
  630. );
  631. } elseif ($column['is_binary'] || $column['is_blob']) {
  632. $html_output .= PMA_getBinaryAndBlobColumn(
  633. $column, $data, $special_chars, $biggest_max_file_size,
  634. $backup_field, $column_name_appendix, $unnullify_trigger, $tabindex,
  635. $tabindex_for_value, $idindex, $text_dir, $special_chars_encoded,
  636. $vkey, $is_upload
  637. );
  638. } elseif (! in_array($column['pma_type'], $no_support_types)) {
  639. $html_output .= PMA_getValueColumnForOtherDatatypes(
  640. $column, $default_char_editing, $backup_field,
  641. $column_name_appendix, $unnullify_trigger, $tabindex, $special_chars,
  642. $tabindex_for_value, $idindex, $text_dir, $special_chars_encoded,
  643. $data, $extracted_columnspec
  644. );
  645. }
  646. if (in_array($column['pma_type'], $gis_data_types)) {
  647. $html_output .= PMA_getHTMLforGisDataTypes();
  648. }
  649. return $html_output;
  650. }
  651. /**
  652. * Get HTML for foreign link in insert form
  653. *
  654. * @param array $column description of column in given table
  655. * @param string $backup_field hidden input field
  656. * @param string $column_name_appendix the name atttibute
  657. * @param string $unnullify_trigger validation string
  658. * @param integer $tabindex tab index
  659. * @param integer $tabindex_for_value offset for the values tabindex
  660. * @param integer $idindex id index
  661. * @param string $data data to edit
  662. * @param array $paramTableDbArray array containing $table and $db
  663. * @param int $rownumber the row number
  664. * @param array $titles An HTML IMG tag for a particular icon from
  665. * a theme, which may be an actual file or
  666. * an icon from a sprite
  667. *
  668. * @return string an html snippet
  669. */
  670. function PMA_getForeignLink($column, $backup_field, $column_name_appendix,
  671. $unnullify_trigger, $tabindex, $tabindex_for_value, $idindex, $data,
  672. $paramTableDbArray, $rownumber, $titles
  673. ) {
  674. list($table, $db) = $paramTableDbArray;
  675. $html_output = '';
  676. $html_output .= $backup_field . "\n";
  677. $html_output .= '<input type="hidden" name="fields_type'
  678. . $column_name_appendix . '" value="foreign" />';
  679. $html_output .= '<input type="text" name="fields' . $column_name_appendix . '" '
  680. . 'class="textfield" '
  681. . $unnullify_trigger . ' '
  682. . 'tabindex="' . ($tabindex + $tabindex_for_value) . '" '
  683. . 'id="field_' . ($idindex) . '_3" '
  684. . 'value="' . htmlspecialchars($data) . '" />';
  685. $html_output .= '<a class="foreign_values_anchor" target="_blank" '
  686. . 'onclick="window.open(this.href,\'foreigners\', \'width=640,height=240,'
  687. . 'scrollbars=yes,resizable=yes\'); return false;" '
  688. . 'href="browse_foreigners.php'
  689. . PMA_URL_getCommon(
  690. array(
  691. 'db' => $db,
  692. 'table' => $table,
  693. 'field' => $column['Field'],
  694. 'rownumber' => $rownumber,
  695. 'data' => $data
  696. )
  697. ) . '">'
  698. . str_replace("'", "\'", $titles['Browse']) . '</a>';
  699. return $html_output;
  700. }
  701. /**
  702. * Get HTML to display foreign data
  703. *
  704. * @param string $backup_field hidden input field
  705. * @param string $column_name_appendix the name atttibute
  706. * @param string $unnullify_trigger validation string
  707. * @param integer $tabindex tab index
  708. * @param integer $tabindex_for_value offset for the values tabindex
  709. * @param integer $idindex id index
  710. * @param string $data data to edit
  711. * @param array $foreignData data about the foreign keys
  712. *
  713. * @return string an html snippet
  714. */
  715. function PMA_dispRowForeignData($backup_field, $column_name_appendix,
  716. $unnullify_trigger, $tabindex, $tabindex_for_value, $idindex, $data,
  717. $foreignData
  718. ) {
  719. $html_output = '';
  720. $html_output .= $backup_field . "\n";
  721. $html_output .= '<input type="hidden"'
  722. . ' name="fields_type' . $column_name_appendix . '"'
  723. . ' value="foreign" />';
  724. $html_output .= '<select name="fields' . $column_name_appendix . '"'
  725. . ' ' . $unnullify_trigger
  726. . ' class="textfield"'
  727. . ' tabindex="' . ($tabindex + $tabindex_for_value) . '"'
  728. . ' id="field_' . $idindex . '_3">';
  729. $html_output .= PMA_foreignDropdown(
  730. $foreignData['disp_row'], $foreignData['foreign_field'],
  731. $foreignData['foreign_display'], $data,
  732. $GLOBALS['cfg']['ForeignKeyMaxLimit']
  733. );
  734. $html_output .= '</select>';
  735. return $html_output;
  736. }
  737. /**
  738. * Get HTML textarea for insert form
  739. *
  740. * @param array $column column information
  741. * @param string $backup_field hidden input field
  742. * @param string $column_name_appendix the name atttibute
  743. * @param string $unnullify_trigger validation string
  744. * @param integer $tabindex tab index
  745. * @param integer $tabindex_for_value offset for the values tabindex
  746. * @param integer $idindex id index
  747. * @param array $text_dir text direction
  748. * @param string $special_chars_encoded replaced char if the string starts
  749. * with a \r\n pair (0x0d0a) add an extra \n
  750. *
  751. * @return string an html snippet
  752. */
  753. function PMA_getTextarea($column, $backup_field, $column_name_appendix,
  754. $unnullify_trigger,
  755. $tabindex, $tabindex_for_value, $idindex, $text_dir, $special_chars_encoded
  756. ) {
  757. $the_class = '';
  758. $textAreaRows = $GLOBALS['cfg']['TextareaRows'];
  759. $textareaCols = $GLOBALS['cfg']['TextareaCols'];
  760. if ($column['is_char']) {
  761. /**
  762. * @todo clarify the meaning of the "textfield" class and explain
  763. * why character columns have the "char" class instead
  764. */
  765. $the_class = 'char';
  766. $textAreaRows = $GLOBALS['cfg']['CharTextareaRows'];
  767. $textareaCols = $GLOBALS['cfg']['CharTextareaCols'];
  768. $extracted_columnspec = PMA_Util::extractColumnSpec($column['Type']);
  769. $maxlength = $extracted_columnspec['spec_in_brackets'];
  770. } elseif ($GLOBALS['cfg']['LongtextDoubleTextarea']
  771. && strstr($column['pma_type'], 'longtext')
  772. ) {
  773. $textAreaRows = $GLOBALS['cfg']['TextareaRows'] * 2;
  774. $textareaCols = $GLOBALS['cfg']['TextareaCols'] * 2;
  775. }
  776. $html_output = $backup_field . "\n"
  777. . '<textarea name="fields' . $column_name_appendix . '"'
  778. . ' class="' . $the_class . '"'
  779. . (isset($maxlength) ? ' maxlength="' . $maxlength . '"' : '')
  780. . ' rows="' . $textAreaRows . '"'
  781. . ' cols="' . $textareaCols . '"'
  782. . ' dir="' . $text_dir . '"'
  783. . ' id="field_' . ($idindex) . '_3"'
  784. . ' ' . $unnullify_trigger
  785. . ' tabindex="' . ($tabindex + $tabindex_for_value) . '">'
  786. . $special_chars_encoded
  787. . '</textarea>';
  788. return $html_output;
  789. }
  790. /**
  791. * Get HTML for enum type
  792. *
  793. * @param array $column description of column in given table
  794. * @param string $backup_field hidden input field
  795. * @param string $column_name_appendix the name atttibute
  796. * @param array $extracted_columnspec associative array containing type,
  797. * spec_in_brackets and possibly
  798. * enum_set_values (another array)
  799. * @param string $unnullify_trigger validation string
  800. * @param int $tabindex tab index
  801. * @param int $tabindex_for_value offset for the values tabindex
  802. * @param int $idindex id index
  803. * @param array $data data to edit
  804. *
  805. * @return string an html snippet
  806. */
  807. function PMA_getPmaTypeEnum($column, $backup_field, $column_name_appendix,
  808. $extracted_columnspec, $unnullify_trigger, $tabindex, $tabindex_for_value,
  809. $idindex, $data
  810. ) {
  811. $html_output = '';
  812. if (! isset($column['values'])) {
  813. $column['values'] = PMA_getColumnEnumValues(
  814. $column, $extracted_columnspec
  815. );
  816. }
  817. $column_enum_values = $column['values'];
  818. $html_output .= '<input type="hidden" name="fields_type'
  819. . $column_name_appendix . '" value="enum" />';
  820. $html_output .= '<input type="hidden" name="fields'
  821. . $column_name_appendix . '" value="" />';
  822. $html_output .= "\n" . ' ' . $backup_field . "\n";
  823. if (strlen($column['Type']) > 20) {
  824. $html_output .= PMA_getDropDownDependingOnLength(
  825. $column, $column_name_appendix, $unnullify_trigger,
  826. $tabindex, $tabindex_for_value, $idindex, $data, $column_enum_values
  827. );
  828. } else {
  829. $html_output .= PMA_getRadioButtonDependingOnLength(
  830. $column_name_appendix, $unnullify_trigger,
  831. $tabindex, $column, $tabindex_for_value,
  832. $idindex, $data, $column_enum_values
  833. );
  834. }
  835. return $html_output;
  836. }
  837. /**
  838. * Get column values
  839. *
  840. * @param array $column description of column in given table
  841. * @param array $extracted_columnspec associative array containing type,
  842. * spec_in_brackets and possibly enum_set_values
  843. * (another array)
  844. *
  845. * @return array column values as an associative array
  846. */
  847. function PMA_getColumnEnumValues($column, $extracted_columnspec)
  848. {
  849. $column['values'] = array();
  850. foreach ($extracted_columnspec['enum_set_values'] as $val) {
  851. $column['values'][] = array(
  852. 'plain' => $val,
  853. 'html' => htmlspecialchars($val),
  854. );
  855. }
  856. return $column['values'];
  857. }
  858. /**
  859. * Get HTML drop down for more than 20 string length
  860. *
  861. * @param array $column description of column in given table
  862. * @param string $column_name_appendix the name atttibute
  863. * @param string $unnullify_trigger validation string
  864. * @param integer $tabindex tab index
  865. * @param integer $tabindex_for_value offset for the values tabindex
  866. * @param integer $idindex id index
  867. * @param array $data data to edit
  868. * @param array $column_enum_values $column['values']
  869. *
  870. * @return string an html snippet
  871. */
  872. function PMA_getDropDownDependingOnLength(
  873. $column, $column_name_appendix, $unnullify_trigger,
  874. $tabindex, $tabindex_for_value, $idindex, $data, $column_enum_values
  875. ) {
  876. $html_output = '<select name="fields' . $column_name_appendix . '"'
  877. . ' ' . $unnullify_trigger
  878. . ' class="textfield"'
  879. . ' tabindex="' . ($tabindex + $tabindex_for_value) . '"'
  880. . ' id="field_' . ($idindex) . '_3">';
  881. $html_output .= '<option value="">&nbsp;</option>' . "\n";
  882. foreach ($column_enum_values as $enum_value) {
  883. $html_output .= '<option value="' . $enum_value['html'] . '"';
  884. if ($data == $enum_value['plain']
  885. || ($data == ''
  886. && (! isset($_REQUEST['where_clause']) || $column['Null'] != 'YES')
  887. && isset($column['Default'])
  888. && $enum_value['plain'] == $column['Default'])
  889. ) {
  890. $html_output .= ' selected="selected"';
  891. }
  892. $html_output .= '>' . $enum_value['html'] . '</option>' . "\n";
  893. }
  894. $html_output .= '</select>';
  895. return $html_output;
  896. }
  897. /**
  898. * Get HTML radio button for less than 20 string length
  899. *
  900. * @param string $column_name_appendix the name atttibute
  901. * @param string $unnullify_trigger validation string
  902. * @param integer $tabindex tab index
  903. * @param array $column description of column in given table
  904. * @param integer $tabindex_for_value offset for the values tabindex
  905. * @param integer $idindex id index
  906. * @param array $data data to edit
  907. * @param array $column_enum_values $column['values']
  908. *
  909. * @return string an html snippet
  910. */
  911. function PMA_getRadioButtonDependingOnLength(
  912. $column_name_appendix, $unnullify_trigger,
  913. $tabindex, $column, $tabindex_for_value, $idindex, $data, $column_enum_values
  914. ) {
  915. $j = 0;
  916. $html_output = '';
  917. foreach ($column_enum_values as $enum_value) {
  918. $html_output .= ' '
  919. . '<input type="radio" name="fields' . $column_name_appendix . '"'
  920. . ' class="textfield"'
  921. . ' value="' . $enum_value['html'] . '"'
  922. . ' id="field_' . ($idindex) . '_3_' . $j . '"'
  923. . ' ' . $unnullify_trigger;
  924. if ($data == $enum_value['plain']
  925. || ($data == ''
  926. && (! isset($_REQUEST['where_clause']) || $column['Null'] != 'YES')
  927. && isset($column['Default'])
  928. && $enum_value['plain'] == $column['Default'])
  929. ) {
  930. $html_output .= ' checked="checked"';
  931. }
  932. $html_output .= ' tabindex="' . ($tabindex + $tabindex_for_value) . '" />';
  933. $html_output .= '<label for="field_' . $idindex . '_3_' . $j . '">'
  934. . $enum_value['html'] . '</label>' . "\n";
  935. $j++;
  936. }
  937. return $html_output;
  938. }
  939. /**
  940. * Get the HTML for 'set' pma type
  941. *
  942. * @param array $column description of column in given table
  943. * @param array $extracted_columnspec associative array containing type,
  944. * spec_in_brackets and possibly
  945. * enum_set_values (another array)
  946. * @param string $backup_field hidden input field
  947. * @param string $column_name_appendix the name atttibute
  948. * @param string $unnullify_trigger validation string
  949. * @param integer $tabindex tab index
  950. * @param integer $tabindex_for_value offset for the values tabindex
  951. * @param integer $idindex id index
  952. * @param string $data description of the column field
  953. *
  954. * @return string an html snippet
  955. */
  956. function PMA_getPmaTypeSet(
  957. $column, $extracted_columnspec, $backup_field,
  958. $column_name_appendix, $unnullify_trigger, $tabindex,
  959. $tabindex_for_value, $idindex, $data
  960. ) {
  961. list($column_set_values, $select_size) = PMA_getColumnSetValueAndSelectSize(
  962. $column, $extracted_columnspec
  963. );
  964. $vset = array_flip(explode(',', $data));
  965. $html_output = $backup_field . "\n";
  966. $html_output .= '<input type="hidden" name="fields_type'
  967. . $column_name_appendix . '" value="set" />';
  968. $html_output .= '<select name="fields' . $column_name_appendix . '[]' . '"'
  969. . ' class="textfield"'
  970. . ' size="' . $select_size . '"'
  971. . ' multiple="multiple"'
  972. . ' ' . $unnullify_trigger
  973. . ' tabindex="' . ($tabindex + $tabindex_for_value) . '"'
  974. . ' id="field_' . ($idindex) . '_3">';
  975. foreach ($column_set_values as $column_set_value) {
  976. $html_output .= '<option value="' . $column_set_value['html'] . '"';
  977. if (isset($vset[$column_set_value['plain']])) {
  978. $html_output .= ' selected="selected"';
  979. }
  980. $html_output .= '>' . $column_set_value['html'] . '</option>' . "\n";
  981. }
  982. $html_output .= '</select>';
  983. return $html_output;
  984. }
  985. /**
  986. * Retrieve column 'set' value and select size
  987. *
  988. * @param array $column description of column in given table
  989. * @param array $extracted_columnspec associative array containing type,
  990. * spec_in_brackets and possibly enum_set_values
  991. * (another array)
  992. *
  993. * @return array $column['values'], $column['select_size']
  994. */
  995. function PMA_getColumnSetValueAndSelectSize($column, $extracted_columnspec)
  996. {
  997. if (! isset($column['values'])) {
  998. $column['values'] = array();
  999. foreach ($extracted_columnspec['enum_set_values'] as $val) {
  1000. $column['values'][] = array(
  1001. 'plain' => $val,
  1002. 'html' => htmlspecialchars($val),
  1003. );
  1004. }
  1005. $column['select_size'] = min(4, count($column['values']));
  1006. }
  1007. return array($column['values'], $column['select_size']);
  1008. }
  1009. /**
  1010. * Get HTML for binary and blob column
  1011. *
  1012. * @param array $column description of column in given table
  1013. * @param string $data data to edit
  1014. * @param string $special_chars special characters
  1015. * @param integer $biggest_max_file_size biggest max file size for uploading
  1016. * @param string $backup_field hidden input field
  1017. * @param string $column_name_appendix the name atttibute
  1018. * @param string $unnullify_trigger validation string
  1019. * @param integer $tabindex tab index
  1020. * @param integer $tabindex_for_value offset for the values tabindex
  1021. * @param integer $idindex id index
  1022. * @param string $text_dir text direction
  1023. * @param string $special_chars_encoded replaced char if the string starts
  1024. * with a \r\n pair (0x0d0a) add an extra \n
  1025. * @param string $vkey [multi_edit]['row_id']
  1026. * @param boolean $is_upload is upload or not
  1027. *
  1028. * @return string an html snippet
  1029. */
  1030. function PMA_getBinaryAndBlobColumn(
  1031. $column, $data, $special_chars, $biggest_max_file_size,
  1032. $backup_field, $column_name_appendix, $unnullify_trigger, $tabindex,
  1033. $tabindex_for_value, $idindex, $text_dir, $special_chars_encoded,
  1034. $vkey, $is_upload
  1035. ) {
  1036. $html_output = '';
  1037. if (($GLOBALS['cfg']['ProtectBinary'] === 'blob' && $column['is_blob'])
  1038. || ($GLOBALS['cfg']['ProtectBinary'] === 'all')
  1039. || ($GLOBALS['cfg']['ProtectBinary'] === 'noblob' && !$column['is_blob'])
  1040. ) {
  1041. $html_output .= __('Binary - do not edit');
  1042. if (isset($data)) {
  1043. $data_size = PMA_Util::formatByteDown(
  1044. strlen(stripslashes($data)), 3, 1
  1045. );
  1046. $html_output .= ' (' . $data_size[0] . ' ' . $data_size[1] . ')';
  1047. unset($data_size);
  1048. }
  1049. $html_output .= '<input type="hidden" name="fields_type'
  1050. . $column_name_appendix . '" value="protected" />'
  1051. . '<input type="hidden" name="fields'
  1052. . $column_name_appendix . '" value="" />';
  1053. } elseif ($column['is_blob']
  1054. || ($column['len'] > $GLOBALS['cfg']['LimitChars'])
  1055. ) {
  1056. $html_output .= "\n" . PMA_getTextarea(
  1057. $column, $backup_field, $column_name_appendix, $unnullify_trigger,
  1058. $tabindex, $tabindex_for_value, $idindex, $text_dir,
  1059. $special_chars_encoded
  1060. );
  1061. } else {
  1062. // field size should be at least 4 and max $GLOBALS['cfg']['LimitChars']
  1063. $fieldsize = min(max($column['len'], 4), $GLOBALS['cfg']['LimitChars']);
  1064. $html_output .= "\n" . $backup_field . "\n" . PMA_getHTMLinput(
  1065. $column, $column_name_appendix, $special_chars, $fieldsize,
  1066. $unnullify_trigger, $tabindex, $tabindex_for_value, $idindex
  1067. );
  1068. }
  1069. if ($is_upload && $column['is_blob']) {
  1070. $html_output .= '<br />'
  1071. . '<input type="file"'
  1072. . ' name="fields_upload' . $vkey . '[' . $column['Field_md5'] . ']"'
  1073. . ' class="textfield" id="field_' . $idindex . '_3" size="10"'
  1074. . ' ' . $unnullify_trigger . '/>&nbsp;';
  1075. list($html_out, $biggest_max_file_size) = PMA_getMaxUploadSize(
  1076. $column, $biggest_max_file_size
  1077. );
  1078. $html_output .= $html_out;
  1079. }
  1080. if (!empty($GLOBALS['cfg']['UploadDir'])) {
  1081. $html_output .= PMA_getSelectOptionForUpload($vkey, $column);
  1082. }
  1083. return $html_output;
  1084. }
  1085. /**
  1086. * Get HTML input type
  1087. *
  1088. * @param array $column description of column in given table
  1089. * @param string $column_name_appendix the name attribute
  1090. * @param string $special_chars special characters
  1091. * @param integer $fieldsize html field size
  1092. * @param string $unnullify_trigger validation string
  1093. * @param integer $tabindex tab index
  1094. * @param integer $tabindex_for_value offset for the values tabindex
  1095. * @param integer $idindex id index
  1096. *
  1097. * @return string an html snippet
  1098. */
  1099. function PMA_getHTMLinput($column, $column_name_appendix, $special_chars,
  1100. $fieldsize, $unnullify_trigger, $tabindex, $tabindex_for_value, $idindex
  1101. ) {
  1102. $input_type = 'text';
  1103. // do not use the 'date' or 'time' types here; they have no effect on some
  1104. // browsers and create side effects (see bug #4218)
  1105. $the_class = 'textfield';
  1106. // verify True_Type which does not contain the parentheses and length
  1107. if ($column['True_Type'] === 'date') {
  1108. $the_class .= ' datefield';
  1109. } else if ($column['True_Type'] === 'time') {
  1110. $the_class .= ' timefield';
  1111. } else if ($column['True_Type'] === 'datetime'
  1112. || $column['True_Type'] === 'timestamp'
  1113. ) {
  1114. $the_class .= ' datetimefield';
  1115. }
  1116. $input_min_max = false;
  1117. if (!$GLOBALS['cfg']['ShowFunctionFields']) {
  1118. if (in_array(
  1119. $column['True_Type'],
  1120. $GLOBALS['PMA_Types']->getIntegerTypes()
  1121. )) {
  1122. $input_type = 'number';
  1123. $is_unsigned = substr($column['pma_type'], -9) === ' unsigned';
  1124. $min_max_values = $GLOBALS['PMA_Types']->getIntegerRange(
  1125. $column['True_Type'], ! $is_unsigned
  1126. );
  1127. $input_min_max = 'min="' . $min_max_values[0] . '" '
  1128. . 'max="' . $min_max_values[1] . '" ';
  1129. }
  1130. }
  1131. return '<input type="' . $input_type . '"'
  1132. . ' name="fields' . $column_name_appendix . '"'
  1133. . ' value="' . $special_chars . '" size="' . $fieldsize . '"'
  1134. . ((isset($column['is_char']) && $column['is_char']) ? ' maxlength="' . $fieldsize . '"' : '')
  1135. . ($input_min_max !== false ? ' ' . $input_min_max : '')
  1136. . ($input_type === 'time' ? ' step="1"' : '')
  1137. . ' class="' . $the_class . '" ' . $unnullify_trigger
  1138. . ' tabindex="' . ($tabindex + $tabindex_for_value) . '"'
  1139. . ' id="field_' . ($idindex) . '_3" />';
  1140. }
  1141. /**
  1142. * Get HTML select option for upload
  1143. *
  1144. * @param string $vkey [multi_edit]['row_id']
  1145. * @param array $column description of column in given table
  1146. *
  1147. * @return string|void an html snippet
  1148. */
  1149. function PMA_getSelectOptionForUpload($vkey, $column)
  1150. {
  1151. $files = PMA_getFileSelectOptions(
  1152. PMA_Util::userDir($GLOBALS['cfg']['UploadDir'])
  1153. );
  1154. if ($files === false) {
  1155. return '<font color="red">' . __('Error') . '</font><br />' . "\n"
  1156. . __('The directory you set for upload work cannot be reached.') . "\n";
  1157. } elseif (!empty($files)) {
  1158. return "<br />\n"
  1159. . '<i>' . __('Or') . '</i>' . ' '
  1160. . __('web server upload directory:') . '<br />' . "\n"
  1161. . '<select size="1" name="fields_uploadlocal'
  1162. . $vkey . '[' . $column['Field_md5'] . ']">' . "\n"
  1163. . '<option value="" selected="selected"></option>' . "\n"
  1164. . $files
  1165. . '</select>' . "\n";
  1166. }
  1167. }
  1168. /**
  1169. * Retrieve the maximum upload file size
  1170. *
  1171. * @param array $column description of column in given table
  1172. * @param integer $biggest_max_file_size biggest max file size for uploading
  1173. *
  1174. * @return array an html snippet and $biggest_max_file_size
  1175. */
  1176. function PMA_getMaxUploadSize($column, $biggest_max_file_size)
  1177. {
  1178. // find maximum upload size, based on field type
  1179. /**
  1180. * @todo with functions this is not so easy, as you can basically
  1181. * process any data with function like MD5
  1182. */
  1183. global $max_upload_size;
  1184. $max_field_sizes = array(
  1185. 'tinyblob' => '256',
  1186. 'blob' => '65536',
  1187. 'mediumblob' => '16777216',
  1188. 'longblob' => '4294967296' // yeah, really
  1189. );
  1190. $this_field_max_size = $max_upload_size; // from PHP max
  1191. if ($this_field_max_size > $max_field_sizes[$column['pma_type']]) {
  1192. $this_field_max_size = $max_field_sizes[$column['pma_type']];
  1193. }
  1194. $html_output
  1195. = PMA_Util::getFormattedMaximumUploadSize(
  1196. $this_field_max_size
  1197. ) . "\n";
  1198. // do not generate here the MAX_FILE_SIZE, because we should
  1199. // put only one in the form to accommodate the biggest field
  1200. if ($this_field_max_size > $biggest_max_file_size) {
  1201. $biggest_max_file_size = $this_field_max_size;
  1202. }
  1203. return array($html_output, $biggest_max_file_size);
  1204. }
  1205. /**
  1206. * Get HTML for the Value column of other datatypes
  1207. * (here, "column" is used in the sense of HTML column in HTML table)
  1208. *
  1209. * @param array $column description of column in given table
  1210. * @param string $default_char_editing default char editing mode which is stroe
  1211. * in the config.inc.php script
  1212. * @param string $backup_field hidden input field
  1213. * @param string $column_name_appendix the name atttibute
  1214. * @param string $unnullify_trigger validation string
  1215. * @param integer $tabindex tab index
  1216. * @param array $special_chars special characters
  1217. * @param integer $tabindex_for_value offset for the values tabindex
  1218. * @param integer $idindex id index
  1219. * @param string $text_dir text direction
  1220. * @param array $special_chars_encoded replaced char if the string starts
  1221. * with a \r\n pair (0x0d0a) add an extra \n
  1222. * @param strign $data data to edit
  1223. * @param array $extracted_columnspec associative array containing type,
  1224. * spec_in_brackets and possibly
  1225. * enum_set_values (another array)
  1226. *
  1227. * @return string an html snippet
  1228. */
  1229. function PMA_getValueColumnForOtherDatatypes($column, $default_char_editing,
  1230. $backup_field,
  1231. $column_name_appendix, $unnullify_trigger, $tabindex, $special_chars,
  1232. $tabindex_for_value, $idindex, $text_dir, $special_chars_encoded, $data,
  1233. $extracted_columnspec
  1234. ) {
  1235. $fieldsize = PMA_getColumnSize($column, $extracted_columnspec);
  1236. $html_output = $backup_field . "\n";
  1237. if ($column['is_char']
  1238. && ($GLOBALS['cfg']['CharEditing'] == 'textarea'
  1239. || strpos($data, "\n") !== false)
  1240. ) {
  1241. $html_output .= "\n";
  1242. $GLOBALS['cfg']['CharEditing'] = $default_char_editing;
  1243. $html_output .= PMA_getTextarea(
  1244. $column, $backup_field, $column_name_appendix, $unnullify_trigger,
  1245. $tabindex, $tabindex_for_value, $idindex, $text_dir,
  1246. $special_chars_encoded
  1247. );
  1248. } else {
  1249. $html_output .= PMA_getHTMLinput(
  1250. $column, $column_name_appendix, $special_chars,
  1251. $fieldsize, $unnullify_trigger, $tabindex, $tabindex_for_value, $idindex
  1252. );
  1253. if ($column['Extra'] == 'auto_increment') {
  1254. $html_output .= '<input type="hidden" name="auto_increment'
  1255. . $column_name_appendix . '" value="1" />';
  1256. }
  1257. if (substr($column['pma_type'], 0, 9) == 'timestamp') {
  1258. $html_output .= '<input type="hidden" name="fields_type'
  1259. . $column_name_appendix . '" value="timestamp" />';
  1260. }
  1261. if (substr($column['pma_type'], 0, 8) == 'datetime') {
  1262. $html_output .= '<input type="hidden" name="fields_type'
  1263. . $column_name_appendix . '" value="datetime" />';
  1264. }
  1265. if ($column['True_Type'] == 'bit') {
  1266. $html_output .= '<input type="hidden" name="fields_type'
  1267. . $column_name_appendix . '" value="bit" />';
  1268. }
  1269. if ($column['pma_type'] == 'date'
  1270. || $column['pma_type'] == 'datetime'
  1271. || substr($column['pma_type'], 0, 9) == 'timestamp'
  1272. ) {
  1273. // the _3 suffix points to the date field
  1274. // the _2 suffix points to the corresponding NULL checkbox
  1275. // in dateFormat, 'yy' means the year with 4 digits
  1276. }
  1277. }
  1278. return $html_output;
  1279. }
  1280. /**
  1281. * Get the field size
  1282. *
  1283. * @param array $column description of column in given table
  1284. * @param array $extracted_columnspec associative array containing type,
  1285. * spec_in_brackets and possibly enum_set_values
  1286. * (another array)
  1287. *
  1288. * @return integer field size
  1289. */
  1290. function PMA_getColumnSize($column, $extracted_columnspec)
  1291. {
  1292. if ($column['is_char']) {
  1293. $fieldsize = $extracted_columnspec['spec_in_brackets'];
  1294. if ($fieldsize > $GLOBALS['cfg']['MaxSizeForInputField']) {
  1295. /**
  1296. * This case happens for CHAR or VARCHAR columns which have
  1297. * a size larger than the maximum size for input field.
  1298. */
  1299. $GLOBALS['cfg']['CharEditing'] = 'textarea';
  1300. }
  1301. } else {
  1302. /**
  1303. * This case happens for example for INT or DATE columns;
  1304. * in these situations, the value returned in $column['len']
  1305. * seems appropriate.
  1306. */
  1307. $fieldsize = $column['len'];
  1308. }
  1309. return min(
  1310. max($fieldsize, $GLOBALS['cfg']['MinSizeForInputField']),
  1311. $GLOBALS['cfg']['MaxSizeForInputField']
  1312. );
  1313. }
  1314. /**
  1315. * Get HTML for gis data types
  1316. *
  1317. * @return string an html snippet
  1318. */
  1319. function PMA_getHTMLforGisDataTypes()
  1320. {
  1321. $edit_str = PMA_Util::getIcon('b_edit.png', __('Edit/Insert'));
  1322. return '<span class="open_gis_editor">'
  1323. . PMA_Util::linkOrButton(
  1324. '#', $edit_str, array(), false, false, '_blank'
  1325. )
  1326. . '</span>';
  1327. }
  1328. /**
  1329. * get html for continue insertion form
  1330. *
  1331. * @param string $table name of the table
  1332. * @param string $db name of the database
  1333. * @param array $where_clause_array array of where clauses
  1334. * @param string $err_url error url
  1335. *
  1336. * @return string an html snippet
  1337. */
  1338. function PMA_getContinueInsertionForm($table, $db, $where_clause_array, $err_url)
  1339. {
  1340. $html_output = '<form id="continueForm" method="post"'
  1341. . ' action="tbl_replace.php" name="continueForm">'
  1342. . PMA_URL_getHiddenInputs($db, $table)
  1343. . '<input type="hidden" name="goto"'
  1344. . ' value="' . htmlspecialchars($GLOBALS['goto']) . '" />'
  1345. . '<input type="hidden" name="err_url"'
  1346. . ' value="' . htmlspecialchars($err_url) . '" />'
  1347. . '<input type="hidden" name="sql_query"'
  1348. . ' value="' . htmlspecialchars($_REQUEST['sql_query']) . '" />';
  1349. if (isset($_REQUEST['where_clause'])) {
  1350. foreach ($where_clause_array as $key_id => $where_clause) {
  1351. $html_output .= '<input type="hidden"'
  1352. . ' name="where_clause[' . $key_id . ']"'
  1353. . ' value="' . htmlspecialchars(trim($where_clause)) . '" />' . "\n";
  1354. }
  1355. }
  1356. $tmp = '<select name="insert_rows" id="insert_rows">' . "\n";
  1357. $option_values = array(1, 2, 5, 10, 15, 20, 30, 40);
  1358. foreach ($option_values as $value) {
  1359. $tmp .= '<option value="' . $value . '"';
  1360. if ($value == $GLOBALS['cfg']['InsertRows']) {
  1361. $tmp .= ' selected="selected"';
  1362. }
  1363. $tmp .= '>' . $value . '</option>' . "\n";
  1364. }
  1365. $tmp .= '</select>' . "\n";
  1366. $html_output .= "\n" . sprintf(__('Continue insertion with %s rows'), $tmp);
  1367. unset($tmp);
  1368. $html_output .= '</form>' . "\n";
  1369. return $html_output;
  1370. }
  1371. /**
  1372. * Get action panel
  1373. *
  1374. * @param array $where_clause where clause
  1375. * @param string $after_insert insert mode, e.g. new_insert, same_insert
  1376. * @param integer $tabindex tab index
  1377. * @param integer $tabindex_for_value offset for the values tabindex
  1378. * @param boolean $found_unique_key boolean variable for unique key
  1379. *
  1380. * @return string an html snippet
  1381. */
  1382. function PMA_getActionsPanel($where_clause, $after_insert, $tabindex,
  1383. $tabindex_for_value, $found_unique_key
  1384. ) {
  1385. $html_output = '<fieldset id="actions_panel">'
  1386. . '<table cellpadding="5" cellspacing="0">'
  1387. . '<tr>'
  1388. . '<td class="nowrap vmiddle">'
  1389. . PMA_getSubmitTypeDropDown($where_clause, $tabindex, $tabindex_for_value)
  1390. . "\n";
  1391. $html_output .= '</td>'
  1392. . '<td class="vmiddle">'
  1393. . '&nbsp;&nbsp;&nbsp;<strong>'
  1394. . __('and then') . '</strong>&nbsp;&nbsp;&nbsp;'
  1395. . '</td>'
  1396. . '<td class="nowrap vmiddle">'
  1397. . PMA_getAfterInsertDropDown(
  1398. $where_clause, $after_insert, $found_unique_key
  1399. )
  1400. . '</td>'
  1401. . '</tr>';
  1402. $html_output .='<tr>'
  1403. . PMA_getSumbitAndResetButtonForActionsPanel($tabindex, $tabindex_for_value)
  1404. . '</tr>'
  1405. . '</table>'
  1406. . '</fieldset>';
  1407. return $html_output;
  1408. }
  1409. /**
  1410. * Get a HTML drop down for submit types
  1411. *
  1412. * @param array $where_clause where clause
  1413. * @param integer $tabindex tab index
  1414. * @param integer $tabindex_for_value offset for the values tabindex
  1415. *
  1416. * @return string an html snippet
  1417. */
  1418. function PMA_getSubmitTypeDropDown($where_clause, $tabindex, $tabindex_for_value)
  1419. {
  1420. $html_output = '<select name="submit_type" class="control_at_footer" tabindex="'
  1421. . ($tabindex + $tabindex_for_value + 1) . '">';
  1422. if (isset($where_clause)) {
  1423. $html_output .= '<option value="save">' . __('Save') . '</option>';
  1424. }
  1425. $html_output .= '<option value="insert">'
  1426. . __('Insert as new row')
  1427. . '</option>'
  1428. . '<option value="insertignore">'
  1429. . __('Insert as new row and ignore errors')
  1430. . '</option>'
  1431. . '<option value="showinsert">'
  1432. . __('Show insert query')
  1433. . '</option>'
  1434. . '</select>';
  1435. return $html_output;
  1436. }
  1437. /**
  1438. * Get HTML drop down for after insert
  1439. *
  1440. * @param array $where_clause where clause
  1441. * @param string $after_insert insert mode, e.g. new_insert, same_insert
  1442. * @param boolean $found_unique_key boolean variable for unique key
  1443. *
  1444. * @return string an html snippet
  1445. */
  1446. function PMA_getAfterInsertDropDown($where_clause, $after_insert, $found_unique_key)
  1447. {
  1448. $html_output = '<select name="after_insert" class="control_at_footer">'
  1449. . '<option value="back" '
  1450. . ($after_insert == 'back' ? 'selected="selected"' : '') . '>'
  1451. . __('Go back to previous page') . '</option>'
  1452. . '<option value="new_insert" '
  1453. . ($after_insert == 'new_insert' ? 'selected="selected"' : '') . '>'
  1454. . __('Insert another new row') . '</option>';
  1455. if (isset($where_clause)) {
  1456. $html_output .= '<option value="same_insert" '
  1457. . ($after_insert == 'same_insert' ? 'selected="selected"' : '') . '>'
  1458. . __('Go back to this page') . '</option>';
  1459. // If we have just numeric primary key, we can also edit next
  1460. // in 2.8.2, we were looking for `field_name` = numeric_value
  1461. //if (preg_match('@^[\s]*`[^`]*` = [0-9]+@', $where_clause)) {
  1462. // in 2.9.0, we are looking for `table_name`.`field_name` = numeric_value
  1463. $is_numeric = false;
  1464. if (! is_array($where_clause)) {
  1465. $where_clause = array($where_clause);
  1466. }
  1467. for ($i = 0, $nb = count($where_clause); $i < $nb; $i++) {
  1468. $is_numeric = preg_match(
  1469. '@^[\s]*`[^`]*`[\.]`[^`]*` = [0-9]+@',
  1470. $where_clause[$i]
  1471. );
  1472. if ($is_numeric == true) {
  1473. break;
  1474. }
  1475. }
  1476. if ($found_unique_key && $is_numeric) {
  1477. $html_output .= '<option value="edit_next" '
  1478. . ($after_insert == 'edit_next' ? 'selected="selected"' : '') . '>'
  1479. . __('Edit next row') . '</option>';
  1480. }
  1481. }
  1482. $html_output .= '</select>';
  1483. return $html_output;
  1484. }
  1485. /**
  1486. * get Submit button and Reset button for action panel
  1487. *
  1488. * @param integer $tabindex tab index
  1489. * @param integer $tabindex_for_value offset for the values tabindex
  1490. *
  1491. * @return string an html snippet
  1492. */
  1493. function PMA_getSumbitAndResetButtonForActionsPanel($tabindex, $tabindex_for_value)
  1494. {
  1495. return '<td>'
  1496. . PMA_Util::showHint(
  1497. __(
  1498. 'Use TAB key to move from value to value,'
  1499. . ' or CTRL+arrows to move anywhere'
  1500. )
  1501. )
  1502. . '</td>'
  1503. . '<td colspan="3" class="right vmiddle">'
  1504. . '<input type="submit" class="control_at_footer" value="' . __('Go') . '"'
  1505. . ' tabindex="' . ($tabindex + $tabindex_for_value + 6) . '" id="buttonYes" />'
  1506. . '<input type="reset" class="control_at_footer" value="' . __('Reset') . '"'
  1507. . ' tabindex="' . ($tabindex + $tabindex_for_value + 7) . '" />'
  1508. . '</td>';
  1509. }
  1510. /**
  1511. * Get table head and table foot for insert row table
  1512. *
  1513. * @param array $url_params url parameters
  1514. *
  1515. * @return string an html snippet
  1516. */
  1517. function PMA_getHeadAndFootOfInsertRowTable($url_params)
  1518. {
  1519. $html_output = '<table class="insertRowTable">'
  1520. . '<thead>'
  1521. . '<tr>'
  1522. . '<th>' . __('Column') . '</th>';
  1523. if ($GLOBALS['cfg']['ShowFieldTypesInDataEditView']) {
  1524. $html_output .= PMA_showColumnTypesInDataEditView($url_params, true);
  1525. }
  1526. if ($GLOBALS['cfg']['ShowFunctionFields']) {
  1527. $html_output .= PMA_showFunctionFieldsInEditMode($url_params, true);
  1528. }
  1529. $html_output .= '<th>' . __('Null') . '</th>'
  1530. . '<th>' . __('Value') . '</th>'
  1531. . '</tr>'
  1532. . '</thead>'
  1533. . ' <tfoot>'
  1534. . '<tr>'
  1535. . '<th colspan="5" class="tblFooters right">'
  1536. . '<input type="submit" value="' . __('Go') . '" />'
  1537. . '</th>'
  1538. . '</tr>'
  1539. . '</tfoot>';
  1540. return $html_output;
  1541. }
  1542. /**
  1543. * Prepares the field value and retrieve special chars, backup field and data array
  1544. *
  1545. * @param array $current_row a row of the table
  1546. * @param array $column description of column in given table
  1547. * @param array $extracted_columnspec associative array containing type,
  1548. * spec_in_brackets and possibly
  1549. * enum_set_values (another array)
  1550. * @param boolean $real_null_value whether column value null or not null
  1551. * @param array $gis_data_types list of GIS data types
  1552. * @param string $column_name_appendix string to append to column name in input
  1553. *
  1554. * @return array $real_null_value, $data, $special_chars, $backup_field,
  1555. * $special_chars_encoded
  1556. */
  1557. function PMA_getSpecialCharsAndBackupFieldForExistingRow(
  1558. $current_row, $column, $extracted_columnspec,
  1559. $real_null_value, $gis_data_types, $column_name_appendix
  1560. ) {
  1561. $special_chars_encoded = '';
  1562. $data = null;
  1563. // (we are editing)
  1564. if (is_null($current_row[$column['Field']])) {
  1565. $real_null_value = true;
  1566. $current_row[$column['Field']] = '';
  1567. $special_chars = '';
  1568. $data = $current_row[$column['Field']];
  1569. } elseif ($column['True_Type'] == 'bit') {
  1570. $special_chars = PMA_Util::printableBitValue(
  1571. $current_row[$column['Field']], $extracted_columnspec['spec_in_brackets']
  1572. );
  1573. } elseif ((substr($column['True_Type'], 0, 9) == 'timestamp'
  1574. || $column['True_Type'] == 'datetime'
  1575. || $column['True_Type'] == 'time')
  1576. && (strpos($current_row[$column['Field']], ".") === true)
  1577. ) {
  1578. $current_row[$column['Field']] = PMA_Util::addMicroseconds(
  1579. $current_row[$column['Field']]
  1580. );
  1581. $special_chars = htmlspecialchars($current_row[$column['Field']]);
  1582. } elseif (in_array($column['True_Type'], $gis_data_types)) {
  1583. // Convert gis data to Well Know Text format
  1584. $current_row[$column['Field']] = PMA_Util::asWKT(
  1585. $current_row[$column['Field']], true
  1586. );
  1587. $special_chars = htmlspecialchars($current_row[$column['Field']]);
  1588. } else {
  1589. // special binary "characters"
  1590. if ($column['is_binary']
  1591. || ($column['is_blob'] && ! $GLOBALS['cfg']['ProtectBinary'])
  1592. ) {
  1593. if ($_SESSION['tmpval']['display_binary_as_hex']
  1594. && $GLOBALS['cfg']['ShowFunctionFields']
  1595. ) {
  1596. $current_row[$column['Field']] = bin2hex(
  1597. $current_row[$column['Field']]
  1598. );
  1599. $column['display_binary_as_hex'] = true;
  1600. } else {
  1601. $current_row[$column['Field']]
  1602. = PMA_Util::replaceBinaryContents(
  1603. $current_row[$column['Field']]
  1604. );
  1605. }
  1606. } // end if
  1607. $special_chars = htmlspecialchars($current_row[$column['Field']]);
  1608. //We need to duplicate the first \n or otherwise we will lose
  1609. //the first newline entered in a VARCHAR or TEXT column
  1610. $special_chars_encoded
  1611. = PMA_Util::duplicateFirstNewline($special_chars);
  1612. $data = $current_row[$column['Field']];
  1613. } // end if... else...
  1614. //when copying row, it is useful to empty auto-increment column
  1615. // to prevent duplicate key error
  1616. if (isset($_REQUEST['default_action'])
  1617. && $_REQUEST['default_action'] === 'insert'
  1618. ) {
  1619. if ($column['Key'] === 'PRI'
  1620. && strpos($column['Extra'], 'auto_increment') !== false
  1621. ) {
  1622. $data = $special_chars_encoded = $special_chars = null;
  1623. }
  1624. }
  1625. // If a timestamp field value is not included in an update
  1626. // statement MySQL auto-update it to the current timestamp;
  1627. // however, things have changed since MySQL 4.1, so
  1628. // it's better to set a fields_prev in this situation
  1629. $backup_field = '<input type="hidden" name="fields_prev'
  1630. . $column_name_appendix . '" value="'
  1631. . htmlspecialchars($current_row[$column['Field']]) . '" />';
  1632. return array(
  1633. $real_null_value,
  1634. $special_chars_encoded,
  1635. $special_chars,
  1636. $data,
  1637. $backup_field
  1638. );
  1639. }
  1640. /**
  1641. * display default values
  1642. *
  1643. * @param array $column description of column in given table
  1644. * @param boolean $real_null_value whether column value null or not null
  1645. *
  1646. * @return array $real_null_value, $data, $special_chars,
  1647. * $backup_field, $special_chars_encoded
  1648. */
  1649. function PMA_getSpecialCharsAndBackupFieldForInsertingMode(
  1650. $column, $real_null_value
  1651. ) {
  1652. if (! isset($column['Default'])) {
  1653. $column['Default'] = '';
  1654. $real_null_value = true;
  1655. $data = '';
  1656. } else {
  1657. $data = $column['Default'];
  1658. }
  1659. if ($column['True_Type'] == 'bit') {
  1660. $special_chars = PMA_Util::convertBitDefaultValue($column['Default']);
  1661. } elseif (substr($column['True_Type'], 0, 9) == 'timestamp'
  1662. || $column['True_Type'] == 'datetime'
  1663. || $column['True_Type'] == 'time'
  1664. ) {
  1665. $special_chars = PMA_Util::addMicroseconds($column['Default']);
  1666. } else {
  1667. $special_chars = htmlspecialchars($column['Default']);
  1668. }
  1669. $backup_field = '';
  1670. $special_chars_encoded = PMA_Util::duplicateFirstNewline($special_chars);
  1671. // this will select the UNHEX function while inserting
  1672. if (($column['is_binary']
  1673. || ($column['is_blob'] && ! $GLOBALS['cfg']['ProtectBinary']))
  1674. && (isset($_SESSION['tmpval']['display_binary_as_hex'])
  1675. && $_SESSION['tmpval']['display_binary_as_hex'])
  1676. && $GLOBALS['cfg']['ShowFunctionFields']
  1677. ) {
  1678. $column['display_binary_as_hex'] = true;
  1679. }
  1680. return array(
  1681. $real_null_value, $data, $special_chars,
  1682. $backup_field, $special_chars_encoded
  1683. );
  1684. }
  1685. /**
  1686. * Prepares the update/insert of a row
  1687. *
  1688. * @return array $loop_array, $using_key, $is_insert, $is_insertignore
  1689. */
  1690. function PMA_getParamsForUpdateOrInsert()
  1691. {
  1692. if (isset($_REQUEST['where_clause'])) {
  1693. // we were editing something => use the WHERE clause
  1694. $loop_array = is_array($_REQUEST['where_clause'])
  1695. ? $_REQUEST['where_clause']
  1696. : array($_REQUEST['where_clause']);
  1697. $using_key = true;
  1698. $is_insert = $_REQUEST['submit_type'] == 'insert'
  1699. || $_REQUEST['submit_type'] == 'showinsert'
  1700. || $_REQUEST['submit_type'] == 'insertignore';
  1701. } else {
  1702. // new row => use indexes
  1703. $loop_array = array();
  1704. foreach ($_REQUEST['fields']['multi_edit'] as $key => $dummy) {
  1705. $loop_array[] = $key;
  1706. }
  1707. $using_key = false;
  1708. $is_insert = true;
  1709. }
  1710. $is_insertignore = $_REQUEST['submit_type'] == 'insertignore';
  1711. return array($loop_array, $using_key, $is_insert, $is_insertignore);
  1712. }
  1713. /**
  1714. * Check wether insert row mode and if so include tbl_changen script and set
  1715. * global variables.
  1716. *
  1717. * @return void
  1718. */
  1719. function PMA_isInsertRow()
  1720. {
  1721. if (isset($_REQUEST['insert_rows'])
  1722. && is_numeric($_REQUEST['insert_rows'])
  1723. && $_REQUEST['insert_rows'] != $GLOBALS['cfg']['InsertRows']
  1724. ) {
  1725. $GLOBALS['cfg']['InsertRows'] = $_REQUEST['insert_rows'];
  1726. $response = PMA_Response::getInstance();
  1727. $header = $response->getHeader();
  1728. $scripts = $header->getScripts();
  1729. $scripts->addFile('tbl_change.js');
  1730. if (!defined('TESTSUITE')) {
  1731. include 'tbl_change.php';
  1732. exit;
  1733. }
  1734. }
  1735. }
  1736. /**
  1737. * set $_SESSION for edit_next
  1738. *
  1739. * @param string $one_where_clause one where clause from where clauses array
  1740. *
  1741. * @return void
  1742. */
  1743. function PMA_setSessionForEditNext($one_where_clause)
  1744. {
  1745. $local_query = 'SELECT * FROM ' . PMA_Util::backquote($GLOBALS['db'])
  1746. . '.' . PMA_Util::backquote($GLOBALS['table']) . ' WHERE '
  1747. . str_replace('` =', '` >', $one_where_clause) . ' LIMIT 1;';
  1748. $res = $GLOBALS['dbi']->query($local_query);
  1749. $row = $GLOBALS['dbi']->fetchRow($res);
  1750. $meta = $GLOBALS['dbi']->getFieldsMeta($res);
  1751. // must find a unique condition based on unique key,
  1752. // not a combination of all fields
  1753. list($unique_condition, $clause_is_unique)
  1754. = PMA_Util::getUniqueCondition(
  1755. $res, count($meta), $meta, $row, true
  1756. );
  1757. if (! empty($unique_condition)) {
  1758. $_SESSION['edit_next'] = $unique_condition;
  1759. }
  1760. unset($unique_condition, $clause_is_unique);
  1761. }
  1762. /**
  1763. * set $goto_include variable for different cases and retrieve like,
  1764. * if $GLOBALS['goto'] empty, if $goto_include previously not defined
  1765. * and new_insert, same_insert, edit_next
  1766. *
  1767. * @param string $goto_include store some script for include, otherwise it is
  1768. * boolean false
  1769. *
  1770. * @return string $goto_include
  1771. */
  1772. function PMA_getGotoInclude($goto_include)
  1773. {
  1774. $valid_options = array('new_insert', 'same_insert', 'edit_next');
  1775. if (isset($_REQUEST['after_insert'])
  1776. && in_array($_REQUEST['after_insert'], $valid_options)
  1777. ) {
  1778. $goto_include = 'tbl_change.php';
  1779. } elseif (! empty($GLOBALS['goto'])) {
  1780. if (! preg_match('@^[a-z_]+\.php$@', $GLOBALS['goto'])) {
  1781. // this should NOT happen
  1782. //$GLOBALS['goto'] = false;
  1783. $goto_include = false;
  1784. } else {
  1785. $goto_include = $GLOBALS['goto'];
  1786. }
  1787. if ($GLOBALS['goto'] == 'db_sql.php' && strlen($GLOBALS['table'])) {
  1788. $GLOBALS['table'] = '';
  1789. }
  1790. }
  1791. if (! $goto_include) {
  1792. if (! strlen($GLOBALS['table'])) {
  1793. $goto_include = 'db_sql.php';
  1794. } else {
  1795. $goto_include = 'tbl_sql.php';
  1796. }
  1797. }
  1798. return $goto_include;
  1799. }
  1800. /**
  1801. * Defines the url to return in case of failure of the query
  1802. *
  1803. * @param array $url_params url parameters
  1804. *
  1805. * @return string error url for query failure
  1806. */
  1807. function PMA_getErrorUrl($url_params)
  1808. {
  1809. if (isset($_REQUEST['err_url'])) {
  1810. return $_REQUEST['err_url'];
  1811. } else {
  1812. return 'tbl_change.php' . PMA_URL_getCommon($url_params);
  1813. }
  1814. }
  1815. /**
  1816. * Builds the sql query
  1817. *
  1818. * @param boolean $is_insertignore $_REQUEST['submit_type'] == 'insertignore'
  1819. * @param array $query_fields column names array
  1820. * @param array $value_sets array of query values
  1821. *
  1822. * @return string a query
  1823. */
  1824. function PMA_buildSqlQuery($is_insertignore, $query_fields, $value_sets)
  1825. {
  1826. if ($is_insertignore) {
  1827. $insert_command = 'INSERT IGNORE ';
  1828. } else {
  1829. $insert_command = 'INSERT ';
  1830. }
  1831. $query = array(
  1832. $insert_command . 'INTO '
  1833. . PMA_Util::backquote($GLOBALS['db']) . '.'
  1834. . PMA_Util::backquote($GLOBALS['table'])
  1835. . ' (' . implode(', ', $query_fields) . ') VALUES ('
  1836. . implode('), (', $value_sets) . ')'
  1837. );
  1838. unset($insert_command, $query_fields);
  1839. return $query;
  1840. }
  1841. /**
  1842. * Executes the sql query and get the result, then move back to the calling page
  1843. *
  1844. * @param array $url_params url parameters array
  1845. * @param array $query built query from PMA_buildSqlQuery()
  1846. *
  1847. * @return array $url_params, $total_affected_rows, $last_messages
  1848. * $warning_messages, $error_messages, $return_to_sql_query
  1849. */
  1850. function PMA_executeSqlQuery($url_params, $query)
  1851. {
  1852. $return_to_sql_query = '';
  1853. if (! empty($GLOBALS['sql_query'])) {
  1854. $url_params['sql_query'] = $GLOBALS['sql_query'];
  1855. $return_to_sql_query = $GLOBALS['sql_query'];
  1856. }
  1857. $GLOBALS['sql_query'] = implode('; ', $query) . ';';
  1858. // to ensure that the query is displayed in case of
  1859. // "insert as new row" and then "insert another new row"
  1860. $GLOBALS['display_query'] = $GLOBALS['sql_query'];
  1861. $total_affected_rows = 0;
  1862. $last_messages = array();
  1863. $warning_messages = array();
  1864. $error_messages = array();
  1865. foreach ($query as $single_query) {
  1866. if ($_REQUEST['submit_type'] == 'showinsert') {
  1867. $last_messages[] = PMA_Message::notice(__('Showing SQL query'));
  1868. continue;
  1869. }
  1870. if ($GLOBALS['cfg']['IgnoreMultiSubmitErrors']) {
  1871. $result = $GLOBALS['dbi']->tryQuery($single_query);
  1872. } else {
  1873. $result = $GLOBALS['dbi']->query($single_query);
  1874. }
  1875. if (! $result) {
  1876. $error_messages[] = PMA_Message::sanitize($GLOBALS['dbi']->getError());
  1877. } else {
  1878. // The next line contains a real assignment, it's not a typo
  1879. if ($tmp = @$GLOBALS['dbi']->affectedRows()) {
  1880. $total_affected_rows += $tmp;
  1881. }
  1882. unset($tmp);
  1883. $insert_id = $GLOBALS['dbi']->insertId();
  1884. if ($insert_id != 0) {
  1885. // insert_id is id of FIRST record inserted in one insert, so if we
  1886. // inserted multiple rows, we had to increment this
  1887. if ($total_affected_rows > 0) {
  1888. $insert_id = $insert_id + $total_affected_rows - 1;
  1889. }
  1890. $last_message = PMA_Message::notice(__('Inserted row id: %1$d'));
  1891. $last_message->addParam($insert_id);
  1892. $last_messages[] = $last_message;
  1893. }
  1894. $GLOBALS['dbi']->freeResult($result);
  1895. }
  1896. $warning_messages = PMA_getWarningMessages();
  1897. }
  1898. return array(
  1899. $url_params,
  1900. $total_affected_rows,
  1901. $last_messages,
  1902. $warning_messages,
  1903. $error_messages,
  1904. $return_to_sql_query
  1905. );
  1906. }
  1907. /**
  1908. * get the warning messages array
  1909. *
  1910. * @return array $warning_essages
  1911. */
  1912. function PMA_getWarningMessages()
  1913. {
  1914. $warning_essages = array();
  1915. foreach ($GLOBALS['dbi']->getWarnings() as $warning) {
  1916. $warning_essages[] = PMA_Message::sanitize(
  1917. $warning['Level'] . ': #' . $warning['Code'] . ' ' . $warning['Message']
  1918. );
  1919. }
  1920. return $warning_essages;
  1921. }
  1922. /**
  1923. * Column to display from the foreign table?
  1924. *
  1925. * @param string $where_comparison string that contain relation field value
  1926. * @param string $relation_field_value relation field value
  1927. * @param array $map all Relations to foreign tables for a given
  1928. * table or optionally a given column in a table
  1929. * @param string $relation_field relation field
  1930. *
  1931. * @return string $dispval display value from the foreign table
  1932. */
  1933. function PMA_getDisplayValueForForeignTableColumn($where_comparison,
  1934. $relation_field_value, $map, $relation_field
  1935. ) {
  1936. $display_field = PMA_getDisplayField(
  1937. $map[$relation_field]['foreign_db'],
  1938. $map[$relation_field]['foreign_table']
  1939. );
  1940. // Field to display from the foreign table?
  1941. if (isset($display_field) && strlen($display_field)) {
  1942. $dispsql = 'SELECT ' . PMA_Util::backquote($display_field)
  1943. . ' FROM ' . PMA_Util::backquote($map[$relation_field]['foreign_db'])
  1944. . '.' . PMA_Util::backquote($map[$relation_field]['foreign_table'])
  1945. . ' WHERE ' . PMA_Util::backquote($map[$relation_field]['foreign_field'])
  1946. . $where_comparison;
  1947. $dispresult = $GLOBALS['dbi']->tryQuery(
  1948. $dispsql, null, PMA_DatabaseInterface::QUERY_STORE
  1949. );
  1950. if ($dispresult && $GLOBALS['dbi']->numRows($dispresult) > 0) {
  1951. list($dispval) = $GLOBALS['dbi']->fetchRow($dispresult, 0);
  1952. }
  1953. @$GLOBALS['dbi']->freeResult($dispresult);
  1954. return $dispval;
  1955. }
  1956. return '';
  1957. }
  1958. /**
  1959. * Display option in the cell according to user choises
  1960. *
  1961. * @param array $map all Relations to foreign tables for a given
  1962. * table or optionally a given column in a table
  1963. * @param string $relation_field relation field
  1964. * @param string $where_comparison string that contain relation field value
  1965. * @param string $dispval display value from the foreign table
  1966. * @param string $relation_field_value relation field value
  1967. *
  1968. * @return string $output HTML <a> tag
  1969. */
  1970. function PMA_getLinkForRelationalDisplayField($map, $relation_field,
  1971. $where_comparison, $dispval, $relation_field_value
  1972. ) {
  1973. if ('K' == $_SESSION['tmpval']['relational_display']) {
  1974. // user chose "relational key" in the display options, so
  1975. // the title contains the display field
  1976. $title = (! empty($dispval))
  1977. ? ' title="' . htmlspecialchars($dispval) . '"'
  1978. : '';
  1979. } else {
  1980. $title = ' title="' . htmlspecialchars($relation_field_value) . '"';
  1981. }
  1982. $_url_params = array(
  1983. 'db' => $map[$relation_field]['foreign_db'],
  1984. 'table' => $map[$relation_field]['foreign_table'],
  1985. 'pos' => '0',
  1986. 'sql_query' => 'SELECT * FROM '
  1987. . PMA_Util::backquote($map[$relation_field]['foreign_db'])
  1988. . '.' . PMA_Util::backquote($map[$relation_field]['foreign_table'])
  1989. . ' WHERE ' . PMA_Util::backquote($map[$relation_field]['foreign_field'])
  1990. . $where_comparison
  1991. );
  1992. $output = '<a href="sql.php'
  1993. . PMA_URL_getCommon($_url_params) . '"' . $title . '>';
  1994. if ('D' == $_SESSION['tmpval']['relational_display']) {
  1995. // user chose "relational display field" in the
  1996. // display options, so show display field in the cell
  1997. $output .= (!empty($dispval)) ? htmlspecialchars($dispval) : '';
  1998. } else {
  1999. // otherwise display data in the cell
  2000. $output .= htmlspecialchars($relation_field_value);
  2001. }
  2002. $output .= '</a>';
  2003. return $output;
  2004. }
  2005. /**
  2006. * Transform edited values
  2007. *
  2008. * @param string $db db name
  2009. * @param string $table table name
  2010. * @param array $transformation mimetypes for all columns of a table
  2011. * [field_name][field_key]
  2012. * @param array $edited_values transform columns list and new values
  2013. * @param string $file file containing the transformation plugin
  2014. * @param string $column_name column name
  2015. * @param array $extra_data extra data array
  2016. *
  2017. * @return array $extra_data
  2018. */
  2019. function PMA_transformEditedValues($db, $table,
  2020. $transformation, $edited_values, $file, $column_name, $extra_data
  2021. ) {
  2022. foreach ($edited_values as $cell_index => $curr_cell_edited_values) {
  2023. if (isset($curr_cell_edited_values[$column_name])) {
  2024. $column_data = $curr_cell_edited_values[$column_name];
  2025. $_url_params = array(
  2026. 'db' => $db,
  2027. 'table' => $table,
  2028. 'where_clause' => $_REQUEST['where_clause'],
  2029. 'transform_key' => $column_name
  2030. );
  2031. $include_file = 'libraries/plugins/transformations/' . $file;
  2032. if (file_exists($include_file)) {
  2033. include_once $include_file;
  2034. $transform_options = PMA_Transformation_getOptions(
  2035. isset($transformation['transformation_options'])
  2036. ? $transformation['transformation_options']
  2037. : ''
  2038. );
  2039. $transform_options['wrapper_link']
  2040. = PMA_URL_getCommon($_url_params);
  2041. $class_name = str_replace('.class.php', '', $file);
  2042. $plugin_manager = null;
  2043. $transformation_plugin = new $class_name(
  2044. $plugin_manager
  2045. );
  2046. }
  2047. $extra_data['transformations'][$cell_index]
  2048. = $transformation_plugin->applyTransformation(
  2049. $column_data,
  2050. $transform_options,
  2051. ''
  2052. );
  2053. }
  2054. } // end of loop for each transformation cell
  2055. return $extra_data;
  2056. }
  2057. /**
  2058. * Get current value in multi edit mode
  2059. *
  2060. * @param array $multi_edit_colummns multiple edit column array
  2061. * @param array $multi_edit_columns_name multiple edit columns name array
  2062. * @param array $multi_edit_funcs multiple edit functions array
  2063. * @param array $multi_edit_salt multiple edit array with encryption salt
  2064. * @param array $gis_from_text_functions array that contains gis from text functions
  2065. * @param string $current_value current value in the column
  2066. * @param array $gis_from_wkb_functions initialy $val is $multi_edit_colummns[$key]
  2067. * @param array $func_optional_param array('RAND','UNIX_TIMESTAMP')
  2068. * @param array $func_no_param array of set of string
  2069. * @param string $key an md5 of the column name
  2070. *
  2071. * @return array $cur_value
  2072. */
  2073. function PMA_getCurrentValueAsAnArrayForMultipleEdit($multi_edit_colummns,
  2074. $multi_edit_columns_name, $multi_edit_funcs, $multi_edit_salt,
  2075. $gis_from_text_functions, $current_value, $gis_from_wkb_functions,
  2076. $func_optional_param, $func_no_param, $key
  2077. ) {
  2078. if (empty($multi_edit_funcs[$key])) {
  2079. return $current_value;
  2080. } elseif ('UUID' === $multi_edit_funcs[$key]) {
  2081. /* This way user will know what UUID new row has */
  2082. $uuid = $GLOBALS['dbi']->fetchValue('SELECT UUID()');
  2083. return "'" . $uuid . "'";
  2084. } elseif ((in_array($multi_edit_funcs[$key], $gis_from_text_functions)
  2085. && substr($current_value, 0, 3) == "'''")
  2086. || in_array($multi_edit_funcs[$key], $gis_from_wkb_functions)
  2087. ) {
  2088. // Remove enclosing apostrophes
  2089. $current_value = substr($current_value, 1, strlen($current_value) - 2);
  2090. // Remove escaping apostrophes
  2091. $current_value = str_replace("''", "'", $current_value);
  2092. return $multi_edit_funcs[$key] . '(' . $current_value . ')';
  2093. } elseif (! in_array($multi_edit_funcs[$key], $func_no_param)
  2094. || ($current_value != "''"
  2095. && in_array($multi_edit_funcs[$key], $func_optional_param))
  2096. ) {
  2097. if (isset($multi_edit_salt[$key])
  2098. && ($multi_edit_funcs[$key] == "AES_ENCRYPT" || $multi_edit_funcs[$key] == "AES_DECRYPT")
  2099. ) {
  2100. return $multi_edit_funcs[$key] . '(' . $current_value . ",'"
  2101. . PMA_Util::sqlAddSlashes($multi_edit_salt[$key]) . "')";
  2102. } else {
  2103. return $multi_edit_funcs[$key] . '(' . $current_value . ')';
  2104. }
  2105. } else {
  2106. return $multi_edit_funcs[$key] . '()';
  2107. }
  2108. }
  2109. /**
  2110. * Get query values array and query fields array for insert and update in multi edit
  2111. *
  2112. * @param array $multi_edit_columns_name multiple edit columns name array
  2113. * @param array $multi_edit_columns_null multiple edit columns null array
  2114. * @param string $current_value current value in the column in loop
  2115. * @param array $multi_edit_columns_prev multiple edit previous columns array
  2116. * @param array $multi_edit_funcs multiple edit functions array
  2117. * @param boolean $is_insert boolean value whether insert or not
  2118. * @param array $query_values SET part of the sql query
  2119. * @param array $query_fields array of query fields
  2120. * @param string $current_value_as_an_array current value in the column
  2121. * as an array
  2122. * @param array $value_sets array of valu sets
  2123. * @param string $key an md5 of the column name
  2124. * @param array $multi_edit_columns_null_prev array of multiple edit columns
  2125. * null previous
  2126. *
  2127. * @return array ($query_values, $query_fields)
  2128. */
  2129. function PMA_getQueryValuesForInsertAndUpdateInMultipleEdit($multi_edit_columns_name,
  2130. $multi_edit_columns_null, $current_value, $multi_edit_columns_prev,
  2131. $multi_edit_funcs,$is_insert, $query_values, $query_fields,
  2132. $current_value_as_an_array, $value_sets, $key, $multi_edit_columns_null_prev
  2133. ) {
  2134. // i n s e r t
  2135. if ($is_insert) {
  2136. // no need to add column into the valuelist
  2137. if (strlen($current_value_as_an_array)) {
  2138. $query_values[] = $current_value_as_an_array;
  2139. // first inserted row so prepare the list of fields
  2140. if (empty($value_sets)) {
  2141. $query_fields[] = PMA_Util::backquote(
  2142. $multi_edit_columns_name[$key]
  2143. );
  2144. }
  2145. }
  2146. } elseif (! empty($multi_edit_columns_null_prev[$key])
  2147. && ! isset($multi_edit_columns_null[$key])
  2148. ) {
  2149. // u p d a t e
  2150. // field had the null checkbox before the update
  2151. // field no longer has the null checkbox
  2152. $query_values[]
  2153. = PMA_Util::backquote($multi_edit_columns_name[$key])
  2154. . ' = ' . $current_value_as_an_array;
  2155. } elseif (empty($multi_edit_funcs[$key])
  2156. && isset($multi_edit_columns_prev[$key])
  2157. && ("'" . PMA_Util::sqlAddSlashes($multi_edit_columns_prev[$key]) . "'"
  2158. == $current_value)
  2159. ) {
  2160. // No change for this column and no MySQL function is used -> next column
  2161. } elseif (! empty($current_value)) {
  2162. // avoid setting a field to NULL when it's already NULL
  2163. // (field had the null checkbox before the update
  2164. // field still has the null checkbox)
  2165. if (empty($multi_edit_columns_null_prev[$key])
  2166. || empty($multi_edit_columns_null[$key])
  2167. ) {
  2168. $query_values[]
  2169. = PMA_Util::backquote($multi_edit_columns_name[$key])
  2170. . ' = ' . $current_value_as_an_array;
  2171. }
  2172. }
  2173. return array($query_values, $query_fields);
  2174. }
  2175. /**
  2176. * Get the current column value in the form for different data types
  2177. *
  2178. * @param string $possibly_uploaded_val uploaded file content
  2179. * @param string $key an md5 of the column name
  2180. * @param array $multi_edit_columns_type array of multi edit column types
  2181. * @param string $current_value current column value in the form
  2182. * @param array $multi_edit_auto_increment multi edit auto increment
  2183. * @param string $rownumber index of where clause array
  2184. * @param array $multi_edit_columns_name multi edit column names array
  2185. * @param array $multi_edit_columns_null multi edit columns null array
  2186. * @param array $multi_edit_columns_null_prev multi edit columns previous null
  2187. * @param boolean $is_insert whether insert or not
  2188. * @param boolean $using_key whether editing or new row
  2189. * @param array $where_clause where clauses
  2190. * @param string $table table name
  2191. *
  2192. * @return string $current_value current column value in the form
  2193. */
  2194. function PMA_getCurrentValueForDifferentTypes($possibly_uploaded_val, $key,
  2195. $multi_edit_columns_type, $current_value, $multi_edit_auto_increment,
  2196. $rownumber, $multi_edit_columns_name, $multi_edit_columns_null,
  2197. $multi_edit_columns_null_prev, $is_insert, $using_key, $where_clause, $table
  2198. ) {
  2199. // Fetch the current values of a row to use in case we have a protected field
  2200. if ($is_insert
  2201. && $using_key && isset($multi_edit_columns_type)
  2202. && is_array($multi_edit_columns_type) && isset($where_clause)
  2203. ) {
  2204. $protected_row = $GLOBALS['dbi']->fetchSingleRow(
  2205. 'SELECT * FROM ' . PMA_Util::backquote($table)
  2206. . ' WHERE ' . $where_clause . ';'
  2207. );
  2208. }
  2209. if (false !== $possibly_uploaded_val) {
  2210. $current_value = $possibly_uploaded_val;
  2211. } else {
  2212. // c o l u m n v a l u e i n t h e f o r m
  2213. if (isset($multi_edit_columns_type[$key])) {
  2214. $type = $multi_edit_columns_type[$key];
  2215. } else {
  2216. $type = '';
  2217. }
  2218. if ($type != 'protected' && $type != 'set' && 0 === strlen($current_value)) {
  2219. // best way to avoid problems in strict mode
  2220. // (works also in non-strict mode)
  2221. if (isset($multi_edit_auto_increment)
  2222. && isset($multi_edit_auto_increment[$key])
  2223. ) {
  2224. $current_value = 'NULL';
  2225. } else {
  2226. $current_value = "''";
  2227. }
  2228. } elseif ($type == 'set') {
  2229. if (! empty($_REQUEST['fields']['multi_edit'][$rownumber][$key])) {
  2230. $current_value = implode(
  2231. ',', $_REQUEST['fields']['multi_edit'][$rownumber][$key]
  2232. );
  2233. $current_value = "'" . PMA_Util::sqlAddSlashes($current_value) . "'";
  2234. } else {
  2235. $current_value = "''";
  2236. }
  2237. } elseif ($type == 'protected') {
  2238. // here we are in protected mode (asked in the config)
  2239. // so tbl_change has put this special value in the
  2240. // columns array, so we do not change the column value
  2241. // but we can still handle column upload
  2242. // when in UPDATE mode, do not alter field's contents. When in INSERT
  2243. // mode, insert empty field because no values were submitted.
  2244. // If protected blobs where set, insert original fields content.
  2245. if (! empty($protected_row[$multi_edit_columns_name[$key]])) {
  2246. $current_value = '0x'
  2247. . bin2hex($protected_row[$multi_edit_columns_name[$key]]);
  2248. } else {
  2249. $current_value = '';
  2250. }
  2251. } elseif ($type == 'bit') {
  2252. $current_value = preg_replace('/[^01]/', '0', $current_value);
  2253. $current_value = "b'" . PMA_Util::sqlAddSlashes($current_value) . "'";
  2254. } elseif (! ($type == 'datetime' || $type == 'timestamp')
  2255. || $current_value != 'CURRENT_TIMESTAMP'
  2256. ) {
  2257. $current_value = "'" . PMA_Util::sqlAddSlashes($current_value) . "'";
  2258. }
  2259. // Was the Null checkbox checked for this field?
  2260. // (if there is a value, we ignore the Null checkbox: this could
  2261. // be possible if Javascript is disabled in the browser)
  2262. if (! empty($multi_edit_columns_null[$key])
  2263. && ($current_value == "''" || $current_value == '')
  2264. ) {
  2265. $current_value = 'NULL';
  2266. }
  2267. // The Null checkbox was unchecked for this field
  2268. if (empty($current_value)
  2269. && ! empty($multi_edit_columns_null_prev[$key])
  2270. && ! isset($multi_edit_columns_null[$key])
  2271. ) {
  2272. $current_value = "''";
  2273. }
  2274. } // end else (column value in the form)
  2275. return $current_value;
  2276. }
  2277. /**
  2278. * Check whether inline edited value can be truncated or not,
  2279. * and add additional parameters for extra_data array if needed
  2280. *
  2281. * @param string $db Database name
  2282. * @param string $table Table name
  2283. * @param string $column_name Column name
  2284. * @param array &$extra_data Extra data for ajax response
  2285. *
  2286. * @return void
  2287. */
  2288. function PMA_verifyWhetherValueCanBeTruncatedAndAppendExtraData(
  2289. $db, $table, $column_name, &$extra_data
  2290. ) {
  2291. $extra_data['isNeedToRecheck'] = true;
  2292. $sql_for_real_value = 'SELECT ' . PMA_Util::backquote($table) . '.'
  2293. . PMA_Util::backquote($column_name)
  2294. . ' FROM ' . PMA_Util::backquote($db) . '.'
  2295. . PMA_Util::backquote($table)
  2296. . ' WHERE ' . $_REQUEST['where_clause'][0];
  2297. $result = $GLOBALS['dbi']->tryQuery($sql_for_real_value);
  2298. $fields_meta = $GLOBALS['dbi']->getFieldsMeta($result);
  2299. $meta = $fields_meta[0];
  2300. $new_value = $GLOBALS['dbi']->fetchValue($result);
  2301. if ($new_value !== false) {
  2302. if ((substr($meta->type, 0, 9) == 'timestamp')
  2303. || ($meta->type == 'datetime')
  2304. || ($meta->type == 'time')
  2305. ) {
  2306. $new_value = PMA_Util::addMicroseconds($new_value);
  2307. }
  2308. $extra_data['truncatableFieldValue'] = $new_value;
  2309. } else {
  2310. $extra_data['isNeedToRecheck'] = false;
  2311. }
  2312. }
  2313. /**
  2314. * Function to get the columns of a table
  2315. *
  2316. * @param string $db current db
  2317. * @param string $table current table
  2318. *
  2319. * @return array
  2320. */
  2321. function PMA_getTableColumns($db, $table)
  2322. {
  2323. $GLOBALS['dbi']->selectDb($db);
  2324. return array_values($GLOBALS['dbi']->getColumns($db, $table));
  2325. }
  2326. /**
  2327. * Function to determine Insert/Edit rows
  2328. *
  2329. * @param string $where_clause where clause
  2330. * @param string $db current database
  2331. * @param string $table current table
  2332. *
  2333. * @return mixed
  2334. */
  2335. function PMA_determineInsertOrEdit($where_clause, $db, $table)
  2336. {
  2337. if (isset($_REQUEST['where_clause'])) {
  2338. $where_clause = $_REQUEST['where_clause'];
  2339. }
  2340. if (isset($_SESSION['edit_next'])) {
  2341. $where_clause = $_SESSION['edit_next'];
  2342. unset($_SESSION['edit_next']);
  2343. $after_insert = 'edit_next';
  2344. }
  2345. if (isset($_REQUEST['ShowFunctionFields'])) {
  2346. $GLOBALS['cfg']['ShowFunctionFields'] = $_REQUEST['ShowFunctionFields'];
  2347. }
  2348. if (isset($_REQUEST['ShowFieldTypesInDataEditView'])) {
  2349. $GLOBALS['cfg']['ShowFieldTypesInDataEditView']
  2350. = $_REQUEST['ShowFieldTypesInDataEditView'];
  2351. }
  2352. if (isset($_REQUEST['after_insert'])) {
  2353. $after_insert = $_REQUEST['after_insert'];
  2354. }
  2355. if (isset($where_clause)) {
  2356. // we are editing
  2357. $insert_mode = false;
  2358. $where_clause_array = PMA_getWhereClauseArray($where_clause);
  2359. list($where_clauses, $result, $rows, $found_unique_key)
  2360. = PMA_analyzeWhereClauses(
  2361. $where_clause_array, $table, $db
  2362. );
  2363. } else {
  2364. // we are inserting
  2365. $insert_mode = true;
  2366. $where_clause = null;
  2367. list($result, $rows) = PMA_loadFirstRow($table, $db);
  2368. $where_clauses = null;
  2369. $where_clause_array = null;
  2370. $found_unique_key = false;
  2371. }
  2372. // Copying a row - fetched data will be inserted as a new row,
  2373. // therefore the where clause is needless.
  2374. if (isset($_REQUEST['default_action'])
  2375. && $_REQUEST['default_action'] === 'insert'
  2376. ) {
  2377. $where_clause = $where_clauses = null;
  2378. }
  2379. return array(
  2380. $insert_mode, $where_clause, $where_clause_array, $where_clauses,
  2381. $result, $rows, $found_unique_key,
  2382. isset($after_insert) ? $after_insert : null
  2383. );
  2384. }
  2385. /**
  2386. * Function to get comments for the table columns
  2387. *
  2388. * @param string $db current database
  2389. * @param string $table current table
  2390. *
  2391. * @return array $comments_map comments for columns
  2392. */
  2393. function PMA_getCommentsMap($db, $table)
  2394. {
  2395. /**
  2396. * get table information
  2397. * @todo should be done by a Table object
  2398. */
  2399. include 'libraries/tbl_info.inc.php';
  2400. /**
  2401. * Get comments for table fields/columns
  2402. */
  2403. $comments_map = array();
  2404. if ($GLOBALS['cfg']['ShowPropertyComments']) {
  2405. $comments_map = PMA_getComments($db, $table);
  2406. }
  2407. return $comments_map;
  2408. }
  2409. /**
  2410. * Function to get URL parameters
  2411. *
  2412. * @param string $db current database
  2413. * @param string $table current table
  2414. *
  2415. * @return array $url_params url parameters
  2416. */
  2417. function PMA_getUrlParameters($db, $table)
  2418. {
  2419. /**
  2420. * @todo check if we could replace by "db_|tbl_" - please clarify!?
  2421. */
  2422. $url_params = array(
  2423. 'db' => $db,
  2424. 'sql_query' => $_REQUEST['sql_query']
  2425. );
  2426. if (preg_match('@^tbl_@', $GLOBALS['goto'])) {
  2427. $url_params['table'] = $table;
  2428. }
  2429. return $url_params;
  2430. }
  2431. /**
  2432. * Function to get html for the gis editor div
  2433. *
  2434. * @return string
  2435. */
  2436. function PMA_getHtmlForGisEditor()
  2437. {
  2438. return '<div id="gis_editor"></div>'
  2439. . '<div id="popup_background"></div>'
  2440. . '<br />';
  2441. }
  2442. /**
  2443. * Function to get html for the ignore option in insert mode
  2444. *
  2445. * @param int $row_id row id
  2446. *
  2447. * @return string
  2448. */
  2449. function PMA_getHtmlForIgnoreOption($row_id)
  2450. {
  2451. return '<input type="checkbox" checked="checked"'
  2452. . ' name="insert_ignore_' . $row_id . '"'
  2453. . ' id="insert_ignore_' . $row_id . '" />'
  2454. . '<label for="insert_ignore_' . $row_id . '">'
  2455. . __('Ignore')
  2456. . '</label><br />' . "\n";
  2457. }
  2458. /**
  2459. * Function to get html for the function option
  2460. *
  2461. * @param bool $odd_row whether odd row or not
  2462. * @param array $column column
  2463. * @param string $column_name_appendix column name appendix
  2464. *
  2465. * @return String
  2466. */
  2467. function PMA_getHtmlForFunctionOption($odd_row, $column, $column_name_appendix)
  2468. {
  2469. $longDoubleTextArea = $GLOBALS['cfg']['LongtextDoubleTextarea'];
  2470. return '<tr class="noclick ' . ($odd_row ? 'odd' : 'even' ) . '">'
  2471. . '<td '
  2472. . ($longDoubleTextArea && strstr($column['True_Type'], 'longtext')
  2473. ? 'rowspan="2"'
  2474. : ''
  2475. )
  2476. . 'class="center">'
  2477. . $column['Field_title']
  2478. . '<input type="hidden" name="fields_name' . $column_name_appendix
  2479. . '" value="' . $column['Field_html'] . '"/>'
  2480. . '</td>';
  2481. }
  2482. /**
  2483. * Function to get html for the column type
  2484. *
  2485. * @param array $column column
  2486. *
  2487. * @return string
  2488. */
  2489. function PMA_getHtmlForInsertEditColumnType($column)
  2490. {
  2491. return '<td class="center' . $column['wrap'] . '">'
  2492. . '<span class="column_type">' . $column['pma_type'] . '</span>'
  2493. . '</td>';
  2494. }
  2495. /**
  2496. * Function to get html for the insert edit form header
  2497. *
  2498. * @param bool $has_blob_field whether has blob field
  2499. * @param bool $is_upload whether is upload
  2500. *
  2501. * @return string
  2502. */
  2503. function PMA_getHtmlForInsertEditFormHeader($has_blob_field, $is_upload)
  2504. {
  2505. $html_output ='<form id="insertForm" ';
  2506. if ($has_blob_field && $is_upload) {
  2507. $html_output .='class="disableAjax" ';
  2508. }
  2509. $html_output .='method="post" action="tbl_replace.php" name="insertForm" ';
  2510. if ($is_upload) {
  2511. $html_output .= ' enctype="multipart/form-data"';
  2512. }
  2513. $html_output .= '>';
  2514. return $html_output;
  2515. }
  2516. /**
  2517. * Function to get html for each insert/edit column
  2518. *
  2519. * @param array $table_columns table columns
  2520. * @param int $i row counter
  2521. * @param array $column column
  2522. * @param array $comments_map comments map
  2523. * @param bool $timestamp_seen whether timestamp seen
  2524. * @param array $current_result current result
  2525. * @param string $chg_evt_handler javascript change event handler
  2526. * @param string $jsvkey javascript validation key
  2527. * @param string $vkey validation key
  2528. * @param bool $insert_mode whether insert mode
  2529. * @param array $current_row current row
  2530. * @param bool $odd_row whether odd row
  2531. * @param int &$o_rows row offset
  2532. * @param int &$tabindex tab index
  2533. * @param int $columns_cnt columns count
  2534. * @param bool $is_upload whether upload
  2535. * @param int $tabindex_for_function tab index offset for function
  2536. * @param array $foreigners foreigners
  2537. * @param int $tabindex_for_null tab index offset for null
  2538. * @param int $tabindex_for_value tab index offset for value
  2539. * @param string $table table
  2540. * @param string $db database
  2541. * @param int $row_id row id
  2542. * @param array $titles titles
  2543. * @param int $biggest_max_file_size biggest max file size
  2544. * @param string $default_char_editing default char editing mode which is stroe
  2545. * in the config.inc.php script
  2546. * @param string $text_dir text direction
  2547. *
  2548. * @return string
  2549. */
  2550. function PMA_getHtmlForInsertEditFormColumn($table_columns, $i, $column,
  2551. $comments_map, $timestamp_seen, $current_result, $chg_evt_handler,
  2552. $jsvkey, $vkey, $insert_mode, $current_row, $odd_row, &$o_rows,
  2553. &$tabindex, $columns_cnt, $is_upload, $tabindex_for_function,
  2554. $foreigners, $tabindex_for_null, $tabindex_for_value,
  2555. $table, $db, $row_id, $titles, $biggest_max_file_size,
  2556. $default_char_editing, $text_dir
  2557. ) {
  2558. if (! isset($table_columns[$i]['processed'])) {
  2559. $column = $table_columns[$i];
  2560. $column = PMA_analyzeTableColumnsArray(
  2561. $column, $comments_map, $timestamp_seen
  2562. );
  2563. }
  2564. $extracted_columnspec
  2565. = PMA_Util::extractColumnSpec($column['Type']);
  2566. if (-1 === $column['len']) {
  2567. $column['len'] = $GLOBALS['dbi']->fieldLen($current_result, $i);
  2568. // length is unknown for geometry fields,
  2569. // make enough space to edit very simple WKTs
  2570. if (-1 === $column['len']) {
  2571. $column['len'] = 30;
  2572. }
  2573. }
  2574. //Call validation when the form submitted...
  2575. $unnullify_trigger = $chg_evt_handler
  2576. . "=\"return verificationsAfterFieldChange('"
  2577. . PMA_escapeJsString($column['Field_md5']) . "', '"
  2578. . PMA_escapeJsString($jsvkey) . "','" . $column['pma_type'] . "')\"";
  2579. // Use an MD5 as an array index to avoid having special characters
  2580. // in the name atttibute (see bug #1746964 )
  2581. $column_name_appendix = $vkey . '[' . $column['Field_md5'] . ']';
  2582. if ($column['Type'] == 'datetime'
  2583. && ! isset($column['Default'])
  2584. && ! is_null($column['Default'])
  2585. && ($insert_mode || ! isset($current_row[$column['Field']]))
  2586. ) {
  2587. // INSERT case or
  2588. // UPDATE case with an NULL value
  2589. $current_row[$column['Field']] = date('Y-m-d H:i:s', time());
  2590. }
  2591. $html_output = PMA_getHtmlForFunctionOption(
  2592. $odd_row, $column, $column_name_appendix
  2593. );
  2594. if ($GLOBALS['cfg']['ShowFieldTypesInDataEditView']) {
  2595. $html_output .= PMA_getHtmlForInsertEditColumnType($column);
  2596. } //End if
  2597. // Get a list of GIS data types.
  2598. $gis_data_types = PMA_Util::getGISDatatypes();
  2599. // Prepares the field value
  2600. $real_null_value = false;
  2601. $special_chars_encoded = '';
  2602. if (isset($current_row)) {
  2603. // (we are editing)
  2604. list(
  2605. $real_null_value, $special_chars_encoded, $special_chars,
  2606. $data, $backup_field
  2607. )
  2608. = PMA_getSpecialCharsAndBackupFieldForExistingRow(
  2609. $current_row, $column, $extracted_columnspec,
  2610. $real_null_value, $gis_data_types, $column_name_appendix
  2611. );
  2612. } else {
  2613. // (we are inserting)
  2614. // display default values
  2615. list($real_null_value, $data, $special_chars, $backup_field,
  2616. $special_chars_encoded
  2617. )
  2618. = PMA_getSpecialCharsAndBackupFieldForInsertingMode(
  2619. $column, $real_null_value
  2620. );
  2621. }
  2622. $idindex = ($o_rows * $columns_cnt) + $i + 1;
  2623. $tabindex = $idindex;
  2624. // Get a list of data types that are not yet supported.
  2625. $no_support_types = PMA_Util::unsupportedDatatypes();
  2626. // The function column
  2627. // -------------------
  2628. if ($GLOBALS['cfg']['ShowFunctionFields']) {
  2629. $html_output .= PMA_getFunctionColumn(
  2630. $column, $is_upload, $column_name_appendix,
  2631. $unnullify_trigger, $no_support_types, $tabindex_for_function,
  2632. $tabindex, $idindex, $insert_mode
  2633. );
  2634. }
  2635. // The null column
  2636. // ---------------
  2637. $foreignData = PMA_getForeignData(
  2638. $foreigners, $column['Field'], false, '', ''
  2639. );
  2640. $html_output .= PMA_getNullColumn(
  2641. $column, $column_name_appendix, $real_null_value,
  2642. $tabindex, $tabindex_for_null, $idindex, $vkey, $foreigners,
  2643. $foreignData
  2644. );
  2645. // The value column (depends on type)
  2646. // ----------------
  2647. // See bug #1667887 for the reason why we don't use the maxlength
  2648. // HTML attribute
  2649. //add data attributes "no of decimals" and "data type"
  2650. $no_decimals=0;
  2651. $type = current(explode("(", $column['pma_type']));
  2652. if (preg_match('/\(([^()]+)\)/', $column['pma_type'], $match)) {
  2653. $match[0] = trim($match[0], '()');
  2654. $no_decimals=$match[0];
  2655. }
  2656. $html_output .= '<td' . ' data-type="' . $type . '"' . ' data-decimals="'
  2657. . $no_decimals . '">' . "\n";
  2658. // Will be used by js/tbl_change.js to set the default value
  2659. // for the "Continue insertion" feature
  2660. $html_output .= '<span class="default_value hide">'
  2661. . $special_chars . '</span>';
  2662. $html_output .= PMA_getValueColumn(
  2663. $column, $backup_field, $column_name_appendix, $unnullify_trigger,
  2664. $tabindex, $tabindex_for_value, $idindex, $data, $special_chars,
  2665. $foreignData, $odd_row, array($table, $db), $row_id, $titles,
  2666. $text_dir, $special_chars_encoded, $vkey, $is_upload,
  2667. $biggest_max_file_size, $default_char_editing,
  2668. $no_support_types, $gis_data_types, $extracted_columnspec
  2669. );
  2670. $html_output .= '</td>'
  2671. . '</tr>';
  2672. return $html_output;
  2673. }
  2674. /**
  2675. * Function to get html for each insert/edit row
  2676. *
  2677. * @param array $url_params url parameters
  2678. * @param array $table_columns table columns
  2679. * @param array $column column
  2680. * @param array $comments_map comments map
  2681. * @param bool $timestamp_seen whether timestamp seen
  2682. * @param array $current_result current result
  2683. * @param string $chg_evt_handler javascript change event handler
  2684. * @param string $jsvkey javascript validation key
  2685. * @param string $vkey validation key
  2686. * @param bool $insert_mode whether insert mode
  2687. * @param array $current_row current row
  2688. * @param int &$o_rows row offset
  2689. * @param int &$tabindex tab index
  2690. * @param int $columns_cnt columns count
  2691. * @param bool $is_upload whether upload
  2692. * @param int $tabindex_for_function tab index offset for function
  2693. * @param array $foreigners foreigners
  2694. * @param int $tabindex_for_null tab index offset for null
  2695. * @param int $tabindex_for_value tab index offset for value
  2696. * @param string $table table
  2697. * @param string $db database
  2698. * @param int $row_id row id
  2699. * @param array $titles titles
  2700. * @param int $biggest_max_file_size biggest max file size
  2701. * @param string $text_dir text direction
  2702. *
  2703. * @return string
  2704. */
  2705. function PMA_getHtmlForInsertEditRow($url_params, $table_columns,
  2706. $column, $comments_map, $timestamp_seen, $current_result, $chg_evt_handler,
  2707. $jsvkey, $vkey, $insert_mode, $current_row, &$o_rows, &$tabindex, $columns_cnt,
  2708. $is_upload, $tabindex_for_function, $foreigners, $tabindex_for_null,
  2709. $tabindex_for_value, $table, $db, $row_id, $titles,
  2710. $biggest_max_file_size, $text_dir
  2711. ) {
  2712. $html_output = PMA_getHeadAndFootOfInsertRowTable($url_params)
  2713. . '<tbody>';
  2714. //store the default value for CharEditing
  2715. $default_char_editing = $GLOBALS['cfg']['CharEditing'];
  2716. $odd_row = true;
  2717. for ($i = 0; $i < $columns_cnt; $i++) {
  2718. $html_output .= PMA_getHtmlForInsertEditFormColumn(
  2719. $table_columns, $i, $column, $comments_map, $timestamp_seen,
  2720. $current_result, $chg_evt_handler, $jsvkey, $vkey, $insert_mode,
  2721. $current_row, $odd_row, $o_rows, $tabindex, $columns_cnt, $is_upload,
  2722. $tabindex_for_function, $foreigners, $tabindex_for_null,
  2723. $tabindex_for_value, $table, $db, $row_id, $titles,
  2724. $biggest_max_file_size, $default_char_editing, $text_dir
  2725. );
  2726. $odd_row = !$odd_row;
  2727. } // end for
  2728. $o_rows++;
  2729. $html_output .= ' </tbody>'
  2730. . '</table><br />'
  2731. . '<div class="clearfloat"></div>';
  2732. return $html_output;
  2733. }
  2734. ?>