Merge branch 'QA_5_0'
[phpmyadmin.git] / test / classes / Display / ResultsTest.php
blob7d098bd9fb3241a14c78c3939de151ce26cee304
1 <?php
2 /**
3 * Tests for displaying results
4 */
5 declare(strict_types=1);
7 namespace PhpMyAdmin\Tests\Display;
9 use PhpMyAdmin\Config;
10 use PhpMyAdmin\Core;
11 use PhpMyAdmin\Display\Results as DisplayResults;
12 use PhpMyAdmin\Plugins\Transformations\Text_Plain_Link;
13 use PhpMyAdmin\SqlParser\Parser;
14 use PhpMyAdmin\SqlParser\Utils\Query;
15 use PhpMyAdmin\Tests\PmaTestCase;
16 use PhpMyAdmin\Transformations;
17 use ReflectionClass;
18 use stdClass;
19 use function count;
20 use function hex2bin;
22 /**
23 * Test cases for displaying results.
25 class ResultsTest extends PmaTestCase
27 /** @access protected */
28 protected $object;
30 /**
31 * Sets up the fixture, for example, opens a network connection.
32 * This method is called before a test is executed.
34 * @access protected
36 protected function setUp(): void
38 $GLOBALS['server'] = 0;
39 $GLOBALS['db'] = 'db';
40 $GLOBALS['table'] = 'table';
41 $GLOBALS['PMA_PHP_SELF'] = 'index.php';
42 $this->object = new DisplayResults('as', '', 0, '', '');
43 $GLOBALS['PMA_Config'] = new Config();
44 $GLOBALS['PMA_Config']->enableBc();
45 $GLOBALS['text_dir'] = 'ltr';
46 $GLOBALS['cfg']['Server']['DisableIS'] = false;
47 $_SESSION[' HMAC_secret '] = 'test';
49 $dbi = $this->getMockBuilder('PhpMyAdmin\DatabaseInterface')
50 ->disableOriginalConstructor()
51 ->getMock();
53 $dbi->expects($this->any())->method('fieldFlags')
54 ->will($this->returnArgument(1));
56 $GLOBALS['dbi'] = $dbi;
59 /**
60 * Tears down the fixture, for example, closes a network connection.
61 * This method is called after a test is executed.
63 * @access protected
65 protected function tearDown(): void
67 unset($this->object);
70 /**
71 * Call private functions by setting visibility to public.
73 * @param string $name method name
74 * @param array $params parameters for the invocation
76 * @return mixed the output from the private method.
78 private function _callPrivateFunction($name, array $params)
80 $class = new ReflectionClass(DisplayResults::class);
81 $method = $class->getMethod($name);
82 $method->setAccessible(true);
83 return $method->invokeArgs($this->object, $params);
86 /**
87 * Test for _isSelect function
89 * @return void
91 public function testisSelect()
93 $parser = new Parser('SELECT * FROM pma');
94 $this->assertTrue(
95 $this->_callPrivateFunction(
96 '_isSelect',
99 'statement' => $parser->statements[0],
100 'select_from' => true,
108 * Test for navigation buttons
110 * @param string $caption iconic caption for button
111 * @param string $title text for button
112 * @param int $pos position for next query
113 * @param string $html_sql_query query ready for display
115 * @return void
117 * @dataProvider providerForTestGetTableNavigationButton
119 public function testGetTableNavigationButton(
120 $caption,
121 $title,
122 $pos,
123 $html_sql_query
125 $GLOBALS['cfg']['TableNavigationLinksMode'] = 'icons';
126 $_SESSION[' PMA_token '] = 'token';
128 $actual = $this->_callPrivateFunction(
129 '_getTableNavigationButton',
131 &$caption,
132 $title,
133 $pos,
134 $html_sql_query,
135 true,
139 $this->assertStringContainsString(
140 '<form action="index.php?route=/sql',
141 $actual
143 $this->assertStringContainsString(
144 '" method="post">',
145 $actual
147 $this->assertStringContainsString(
148 'name="sql_query" value="SELECT * FROM `pma_bookmark` WHERE 1"',
149 $actual
151 $this->assertStringContainsString(
152 'name="pos" value="1"',
153 $actual
155 $this->assertStringContainsString(
156 'value="btn" title="Submit"',
157 $actual
162 * Provider for testGetTableNavigationButton
164 * @return array array data for testGetTableNavigationButton
166 public function providerForTestGetTableNavigationButton()
168 return [
170 'btn',
171 'Submit',
173 'SELECT * FROM `pma_bookmark` WHERE 1',
179 * Provider for testing table navigation
181 * @return array data for testGetTableNavigation
183 public function providerForTestGetTableNavigation()
185 return [
189 false,
190 '310',
196 * Data provider for testGetClassesForColumn
198 * @return array parameters and output
200 public function dataProviderForTestGetClassesForColumn()
202 return [
204 'grid_edit',
205 'not_null',
209 'data grid_edit not_null ',
215 * Test for _getClassesForColumn
217 * @param string $grid_edit_class the class for all editable columns
218 * @param string $not_null_class the class for not null columns
219 * @param string $relation_class the class for relations in a column
220 * @param string $hide_class the class for visibility of a column
221 * @param string $field_type_class the class related to type of the field
222 * @param string $output output of__getResettedClassForInlineEdit
224 * @return void
226 * @dataProvider dataProviderForTestGetClassesForColumn
228 public function testGetClassesForColumn(
229 $grid_edit_class,
230 $not_null_class,
231 $relation_class,
232 $hide_class,
233 $field_type_class,
234 $output
236 $GLOBALS['cfg']['BrowsePointerEnable'] = true;
237 $GLOBALS['cfg']['BrowseMarkerEnable'] = true;
239 $this->assertEquals(
240 $output,
241 $this->_callPrivateFunction(
242 '_getClassesForColumn',
244 $grid_edit_class,
245 $not_null_class,
246 $relation_class,
247 $hide_class,
248 $field_type_class,
255 * Test for _getClassForDateTimeRelatedFields - case 1
257 * @return void
259 public function testGetClassForDateTimeRelatedFieldsCase1()
261 $this->assertEquals(
262 'datetimefield',
263 $this->_callPrivateFunction(
264 '_getClassForDateTimeRelatedFields',
265 [DisplayResults::DATETIME_FIELD]
271 * Test for _getClassForDateTimeRelatedFields - case 2
273 * @return void
275 public function testGetClassForDateTimeRelatedFieldsCase2()
277 $this->assertEquals(
278 'datefield',
279 $this->_callPrivateFunction(
280 '_getClassForDateTimeRelatedFields',
281 [DisplayResults::DATE_FIELD]
287 * Test for _getClassForDateTimeRelatedFields - case 3
289 * @return void
291 public function testGetClassForDateTimeRelatedFieldsCase3()
293 $this->assertEquals(
294 'text',
295 $this->_callPrivateFunction(
296 '_getClassForDateTimeRelatedFields',
297 [DisplayResults::STRING_FIELD]
303 * Test for _getOffsets - case 1
305 * @return void
307 public function testGetOffsetsCase1()
309 $_SESSION['tmpval']['max_rows'] = DisplayResults::ALL_ROWS;
310 $this->assertEquals(
315 $this->_callPrivateFunction('_getOffsets', [])
320 * Test for _getOffsets - case 2
322 * @return void
324 public function testGetOffsetsCase2()
326 $_SESSION['tmpval']['max_rows'] = 5;
327 $_SESSION['tmpval']['pos'] = 4;
328 $this->assertEquals(
333 $this->_callPrivateFunction('_getOffsets', [])
338 * Data provider for testGetCheckboxForMultiRowSubmissions
340 * @return array parameters and output
342 public function dataProviderForGetCheckboxForMultiRowSubmissions()
344 return [
346 'index.php?route=/sql&amp;db=data&amp;table=new&amp;sql_query=DELETE+FROM+%60data%60'
347 . '.%60new%60+WHERE+%60new%60.%60id%60+%3D+1&amp;message_to_show='
348 . 'The+row+has+been+deleted&amp;goto=index.php%3Froute%3D%2Fsql%26db%3Ddata%26table%3D'
349 . 'new%26sql_query%3DSELECT%2B%252A%2BFROM%2B%2560new%2560%26message'
350 . '_to_show%3DThe%2Brow%2Bhas%2Bbeen%2Bdeleted%26goto%3Dindex.php%253Froute%253D%252Ftable%252Fstructure',
352 'edit_lnk' => 'ur',
353 'del_lnk' => 'dr',
354 'sort_lnk' => '0',
355 'nav_bar' => '1',
356 'bkm_form' => '1',
357 'text_btn' => '1',
358 'pview_lnk' => '1',
361 '%60new%60.%60id%60+%3D+1',
362 ['`new`.`id`' => '= 1'],
363 '[%_PMA_CHECKBOX_DIR_%]',
364 'klass',
365 '<td class="klass" class="text-center print_ignore"><input type'
366 . '="checkbox" id="id_rows_to_delete0[%_PMA_CHECKBOX_DIR_%]" name='
367 . '"rows_to_delete[0]" class="multi_checkbox checkall" value="%60'
368 . 'new%60.%60id%60+%3D+1"><input type="hidden" class="condition_'
369 . 'array" value="{&quot;`new`.`id`&quot;:&quot;= 1&quot;}"> '
370 . '</td>',
376 * Test for _getCheckboxForMultiRowSubmissions
378 * @param string $del_url delete url
379 * @param array $displayParts array with explicit indexes for all
380 * the display elements
381 * @param string $row_no the row number
382 * @param string $where_clause_html url encoded where clause
383 * @param array $condition_array array of conditions in the where clause
384 * @param string $id_suffix suffix for the id
385 * @param string $class css classes for the td element
386 * @param string $output output of _getCheckboxForMultiRowSubmissions
388 * @return void
390 * @dataProvider dataProviderForGetCheckboxForMultiRowSubmissions
392 public function testGetCheckboxForMultiRowSubmissions(
393 $del_url,
394 $displayParts,
395 $row_no,
396 $where_clause_html,
397 $condition_array,
398 $id_suffix,
399 $class,
400 $output
402 $this->assertEquals(
403 $output,
404 $this->_callPrivateFunction(
405 '_getCheckboxForMultiRowSubmissions',
407 $del_url,
408 $displayParts,
409 $row_no,
410 $where_clause_html,
411 $condition_array,
412 $id_suffix,
413 $class,
420 * Data provider for testGetEditLink
422 * @return array parameters and output
424 public function dataProviderForGetEditLink()
426 return [
428 'index.php?route=/table/change&db=Data&amp;table=customer&amp;where_clause=%60'
429 . 'customer%60.%60id%60+%3D+1&amp;clause_is_unique=1&amp;sql_query='
430 . 'SELECT+%2A+FROM+%60customer%60&amp;goto=index.php%3Froute%3D%2Fsql&amp;default_'
431 . 'action=update',
432 'klass edit_row_anchor',
433 '<span class="nowrap"><img src="themes/dot.gif" title="Edit" alt='
434 . '"Edit" class="icon ic_b_edit"> Edit</span>',
435 '`customer`.`id` = 1',
436 '%60customer%60.%60id%60+%3D+1',
437 '<td class="klass edit_row_anchor text-center print_ignore">'
438 . '<span class="nowrap">'
439 . '<a href="index.php" data-post="route=/table/change&db=Data&amp;table=customer&amp;where_'
440 . 'clause=%60customer%60.%60id%60+%3D+1&amp;clause_is_unique=1&amp;'
441 . 'sql_query=SELECT+%2A+FROM+%60customer%60&amp;goto=index.php%3Froute%3D%2Fsql&amp;'
442 . 'default_action=update"'
443 . '><span class="nowrap"><img src="themes/dot.gif" title="Edit" '
444 . 'alt="Edit" class="icon ic_b_edit"> Edit</span></a>'
445 . '<input type="hidden" class="where_clause" value ="%60customer'
446 . '%60.%60id%60+%3D+1"></span></td>',
452 * Test for _getEditLink
454 * @param string $edit_url edit url
455 * @param string $class css classes for td element
456 * @param string $edit_str text for the edit link
457 * @param string $where_clause where clause
458 * @param string $where_clause_html url encoded where clause
459 * @param string $output output of _getEditLink
461 * @return void
463 * @dataProvider dataProviderForGetEditLink
465 public function testGetEditLink(
466 $edit_url,
467 $class,
468 $edit_str,
469 $where_clause,
470 $where_clause_html,
471 $output
473 $GLOBALS['cfg']['ActionLinksMode'] = 'both';
474 $GLOBALS['cfg']['LinkLengthLimit'] = 1000;
476 $this->assertEquals(
477 $output,
478 $this->_callPrivateFunction(
479 '_getEditLink',
481 $edit_url,
482 $class,
483 $edit_str,
484 $where_clause,
485 $where_clause_html,
492 * Data provider for testGetCopyLink
494 * @return array parameters and output
496 public function dataProviderForGetCopyLink()
498 return [
500 'index.php?route=/table/change&db=Data&amp;table=customer&amp;where_clause=%60cust'
501 . 'omer%60.%60id%60+%3D+1&amp;clause_is_unique=1&amp;sql_query='
502 . 'SELECT+%2A+FROM+%60customer%60&amp;goto=index.php%3Froute%3D%2Fsql&amp;default_'
503 . 'action=insert',
504 '<span class="nowrap"><img src="themes/dot.gif" title="Copy" alt'
505 . '="Copy" class="icon ic_b_insrow"> Copy</span>',
506 '`customer`.`id` = 1',
507 '%60customer%60.%60id%60+%3D+1',
508 'klass',
509 '<td class="klass text-center print_ignore"><span class='
510 . '"nowrap">'
511 . '<a href="index.php" data-post="route=/table/change&db=Data&amp;table=customer&amp;where_'
512 . 'clause=%60customer%60.%60id%60+%3D+1&amp;clause_is_unique=1&amp;'
513 . 'sql_query=SELECT+%2A+FROM+%60customer%60&amp;goto=index.php%3Froute%3D%2Fsql&amp;'
514 . 'default_action=insert"'
515 . '><span class="nowrap"><img src="themes/dot.gif" title="Copy" '
516 . 'alt="Copy" class="icon ic_b_insrow"> Copy</span></a>'
517 . '<input type="hidden" class="where_clause" value="%60customer%60'
518 . '.%60id%60+%3D+1"></span></td>',
524 * Test for _getCopyLink
526 * @param string $copy_url copy url
527 * @param string $copy_str text for the copy link
528 * @param string $where_clause where clause
529 * @param string $where_clause_html url encoded where clause
530 * @param string $class css classes for the td element
531 * @param string $output output of _getCopyLink
533 * @return void
535 * @dataProvider dataProviderForGetCopyLink
537 public function testGetCopyLink(
538 $copy_url,
539 $copy_str,
540 $where_clause,
541 $where_clause_html,
542 $class,
543 $output
545 $GLOBALS['cfg']['ActionLinksMode'] = 'both';
546 $GLOBALS['cfg']['LinkLengthLimit'] = 1000;
548 $this->assertEquals(
549 $output,
550 $this->_callPrivateFunction(
551 '_getCopyLink',
553 $copy_url,
554 $copy_str,
555 $where_clause,
556 $where_clause_html,
557 $class,
564 * Data provider for testGetDeleteLink
566 * @return array parameters and output
568 public function dataProviderForGetDeleteLink()
570 return [
572 'index.php?route=/sql&amp;db=Data&amp;table=customer&amp;sql_query=DELETE+FROM+%60'
573 . 'Data%60.%60customer%60+WHERE+%60customer%60.%60id%60+%3D+1&amp;'
574 . 'message_to_show=The+row+has+been+deleted&amp;goto=index.php%3Froute%3D%2Fsql%26db'
575 . '%3DData%26table%3Dcustomer%26sql_query%3DSELECT%2B%252A%2BFROM'
576 . '%2B%2560customer%2560%26message_to_show%3DThe%2Brow%2Bhas%2Bbeen'
577 . '%2Bdeleted%26goto%3Dindex.php%253Froute%253D%252Ftable%252Fstructure',
578 '<span class="nowrap"><img src="themes/dot.gif" title="Delete" '
579 . 'alt="Delete" class="icon ic_b_drop"> Delete</span>',
580 'DELETE FROM `Data`.`customer` WHERE `customer`.`id` = 1',
581 'klass',
582 '<td class="klass text-center print_ignore">'
583 . '<a href="index.php" data-post="route=/sql&amp;db=Data&amp;table=customer&amp;sql_query=DELETE'
584 . '+FROM+%60Data%60.%60customer%60+WHERE+%60customer%60.%60id%60+%3D'
585 . '+1&amp;message_to_show=The+row+has+been+deleted&amp;goto=index.php%3Froute%3D%2Fsql'
586 . '%26db%3DData%26table%3Dcustomer%26sql_query%3DSELECT%2B%252A%2B'
587 . 'FROM%2B%2560customer%2560%26message_to_show%3DThe%2Brow%2Bhas%2B'
588 . 'been%2Bdeleted%26goto%3Dindex.php%253Froute%253D%252Ftable%252Fstructure" '
589 . 'class="delete_row requireConfirm"><span class="nowrap"><img src="themes/dot.'
590 . 'gif" title="Delete" alt="Delete" class="icon ic_b_drop"> '
591 . 'Delete</span></a>'
592 . '<div class="hide">DELETE FROM `Data`.`customer` WHERE '
593 . '`customer`.`id` = 1</div></td>',
599 * Test for _getDeleteLink
601 * @param string $del_url delete url
602 * @param string $del_str text for the delete link
603 * @param string $js_conf text for the JS confirmation
604 * @param string $class css classes for the td element
605 * @param string $output output of _getDeleteLink
607 * @return void
609 * @dataProvider dataProviderForGetDeleteLink
611 public function testGetDeleteLink(
612 $del_url,
613 $del_str,
614 $js_conf,
615 $class,
616 $output
618 $GLOBALS['cfg']['ActionLinksMode'] = 'both';
619 $GLOBALS['cfg']['LinkLengthLimit'] = 1000;
621 $this->assertEquals(
622 $output,
623 $this->_callPrivateFunction(
624 '_getDeleteLink',
626 $del_url,
627 $del_str,
628 $js_conf,
629 $class,
636 * Data provider for testGetCheckboxAndLinks
638 * @return array parameters and output
640 public function dataProviderForGetCheckboxAndLinks()
642 return [
644 DisplayResults::POSITION_LEFT,
645 'index.php?route=/sql&amp;db=data&amp;table=new&amp;sql_query=DELETE+FROM+%60data'
646 . '%60.%60new%60+WHERE+%60new%60.%60id%60+%3D+1&amp;message_to_show='
647 . 'The+row+has+been+deleted&amp;goto=index.php%3Froute%3D%2Fsql%26db%3Ddata%26table%3D'
648 . 'new%26sql_query%3DSELECT%2B%252A%2BFROM%2B%2560new%2560%26'
649 . 'message_to_show%3DThe%2Brow%2Bhas%2Bbeen%2Bdeleted%26goto%3D'
650 . 'index.php%253Froute%253D%252Ftable%252Fstructure',
652 'edit_lnk' => 'ur',
653 'del_lnk' => 'dr',
654 'sort_lnk' => '0',
655 'nav_bar' => '1',
656 'bkm_form' => '1',
657 'text_btn' => '1',
658 'pview_lnk' => '1',
661 '`new`.`id` = 1',
662 '%60new%60.%60id%60+%3D+1',
664 '`new`.`id`' => '= 1',
666 'index.php?route=/table/change&db=data&amp;table=new&amp;where_clause=%60new%60.'
667 . '%60id%60+%3D+1&amp;clause_is_unique=1&amp;sql_query=SELECT+%2A+'
668 . 'FROM+%60new%60&amp;goto=index.php%3Froute%3D%2Fsql&amp;default_action=update',
669 'index.php?route=/table/change&db=data&amp;table=new&amp;where_clause=%60new%60.'
670 . '%60id%60+%3D+1&amp;clause_is_unique=1&amp;sql_query=SELECT+%2A+'
671 . 'FROM+%60new%60&amp;goto=index.php%3Froute%3D%2Fsql&amp;default_action=insert',
672 'edit_row_anchor',
673 '<span class="nowrap"><img src="themes/dot.gif" title="Edit" '
674 . 'alt="Edit" class="icon ic_b_edit"> Edit</span>',
675 '<span class="nowrap"><img src="themes/dot.gif" title="Copy" '
676 . 'alt="Copy" class="icon ic_b_insrow"> Copy</span>',
677 '<span class="nowrap"><img src="themes/dot.gif" title="Delete" '
678 . 'alt="Delete" class="icon ic_b_drop"> Delete</span>',
679 'DELETE FROM `data`.`new` WHERE `new`.`id` = 1',
680 '<td class="text-center print_ignore"><input type="checkbox" id="id_rows_to_delete0_'
681 . 'left" name="rows_to_delete[0]" class="multi_checkbox checkall" '
682 . 'value="%60new%60.%60id%60+%3D+1"><input type="hidden" class='
683 . '"condition_array" value="{&quot;`new`.`id`&quot;:&quot;= 1&quot;'
684 . '}"> </td><td class="edit_row_anchor text-center print_ignore"><span class='
685 . '"nowrap">'
686 . '<a href="index.php" data-post="route=/table/change&db=data&amp;table=new&amp;where_'
687 . 'clause=%60new%60.%60id%60+%3D+1&amp;clause_is_unique=1&amp;'
688 . 'sql_query=SELECT+%2A+FROM+%60new%60&amp;goto=index.php%3Froute%3D%2Fsql&amp;default'
689 . '_action=update">'
690 . '<span class="nowrap"><img src="themes/dot.gif" title="Edit" '
691 . 'alt="Edit" class="icon ic_b_edit"> Edit</span></a>'
692 . '<input type="hidden" class="where_clause" value ="%60new%60.%60'
693 . 'id%60+%3D+1"></span></td><td class="text-center print_ignore"><span class'
694 . '="nowrap">'
695 . '<a href="index.php" data-post="route=/table/change&db=data&amp;table=new&amp;where_clause'
696 . '=%60new%60.%60id%60+%3D+1&amp;clause_is_unique=1&amp;sql_query='
697 . 'SELECT+%2A+FROM+%60new%60&amp;goto=index.php%3Froute%3D%2Fsql&amp;default_action='
698 . 'insert"><span class'
699 . '="nowrap"><img src="themes/dot.gif" title="Copy" alt="Copy" '
700 . 'class="icon ic_b_insrow"> Copy</span></a>'
701 . '<input type="hidden" class="where_clause" value="%60new%60.%60id'
702 . '%60+%3D+1"></span></td><td class="text-center print_ignore">'
703 . '<a href="index.php" data-post="route=/sql&amp;db=data&amp;table=new&amp;sql_query=DELETE+'
704 . 'FROM+%60data%60.%60new%60+WHERE+%60new%60.%60id%60+%3D+1&amp;'
705 . 'message_to_show=The+row+has+been+deleted&amp;goto=index.php%3Froute%3D%2Fsql%26'
706 . 'db%3Ddata%26table%3Dnew%26sql_query%3DSELECT%2B%252A%2BFROM%2B'
707 . '%2560new%2560%26message_to_show%3DThe%2Brow%2Bhas%2Bbeen%2B'
708 . 'deleted%26goto%3Dindex.php%253Froute%253D%252Ftable%252Fstructure" '
709 . 'class="delete_row requireConfirm"><span class="nowrap"><img src="themes/dot.'
710 . 'gif" title="Delete" alt="Delete" class="icon ic_b_drop"> '
711 . 'Delete</span></a>'
712 . '<div class="hide">DELETE FROM `data`.`new` WHERE `new`.`id` = 1'
713 . '</div></td>',
716 DisplayResults::POSITION_RIGHT,
717 'index.php?route=/sql&amp;db=data&amp;table=new&amp;sql_query=DELETE+FROM+%60data%60'
718 . '.%60new%60+WHERE+%60new%60.%60id%60+%3D+1&amp;message_to_show='
719 . 'The+row+has+been+deleted&amp;goto=index.php%3Froute%3D%2Fsql%26db%3Ddata%26table%3D'
720 . 'new%26sql_query%3DSELECT%2B%252A%2BFROM%2B%2560new%2560%26message'
721 . '_to_show%3DThe%2Brow%2Bhas%2Bbeen%2Bdeleted%26goto%3D'
722 . 'index.php%253Froute%253D%252Ftable%252Fstructure',
724 'edit_lnk' => 'ur',
725 'del_lnk' => 'dr',
726 'sort_lnk' => '0',
727 'nav_bar' => '1',
728 'bkm_form' => '1',
729 'text_btn' => '1',
730 'pview_lnk' => '1',
733 '`new`.`id` = 1',
734 '%60new%60.%60id%60+%3D+1',
736 '`new`.`id`' => '= 1',
738 'index.php?route=/table/change&amp;db=data&amp;table=new&amp;where_clause=%60new%60.'
739 . '%60id%60+%3D+1&amp;clause_is_unique=1&amp;sql_query=SELECT+%2A+'
740 . 'FROM+%60new%60&amp;goto=index.php%3Froute%3D%2Fsql&amp;default_action=update',
741 'index.php?route=/table/change&amp;db=data&amp;table=new&amp;where_clause=%60new%60.'
742 . '%60id%60+%3D+1&amp;clause_is_unique=1&amp;sql_query=SELECT+%2A+'
743 . 'FROM+%60new%60&amp;goto=index.php%3Froute%3D%2Fsql&amp;default_action=insert',
744 'edit_row_anchor',
745 '<span class="nowrap"><img src="themes/dot.gif" title="Edit" '
746 . 'alt="Edit" class="icon ic_b_edit"> Edit</span>',
747 '<span class="nowrap"><img src="themes/dot.gif" title="Copy" '
748 . 'alt="Copy" class="icon ic_b_insrow"> Copy</span>',
749 '<span class="nowrap"><img src="themes/dot.gif" title="Delete" '
750 . 'alt="Delete" class="icon ic_b_drop"> Delete</span>',
751 'DELETE FROM `data`.`new` WHERE `new`.`id` = 1',
752 '<td class="text-center print_ignore">'
753 . '<a href="index.php" data-post="route=/sql&amp;db=data&amp;table=new&amp;sql_query=DELETE+'
754 . 'FROM+%60data%60.%60new%60+WHERE+%60new%60.%60id%60+%3D+1&amp;'
755 . 'message_to_show=The+row+has+been+deleted&amp;goto=index.php%3Froute%3D%2Fsql%26db'
756 . '%3Ddata%26table%3Dnew%26sql_query%3DSELECT%2B%252A%2BFROM%2B%25'
757 . '60new%2560%26message_to_show%3DThe%2Brow%2Bhas%2Bbeen%2Bdeleted'
758 . '%26goto%3Dindex.php%253Froute%253D%252Ftable%252Fstructure" class="delete'
759 . '_row requireConfirm"><span class="nowrap"><img src="themes/dot.gif" title='
760 . '"Delete" alt="Delete" class="icon ic_b_drop"> Delete</span></a>'
761 . '<div class="hide">DELETE FROM `data`.`new` WHERE `new`.'
762 . '`id` = 1</div></td><td class="text-center print_ignore"><span class="nowrap">'
763 . '<a href="index.php" data-post="route=/table/change&amp;db=data&amp;table=new&amp;where_'
764 . 'clause=%60new%60.%60id%60+%3D+1&amp;clause_is_unique=1&amp;sql_'
765 . 'query=SELECT+%2A+FROM+%60new%60&amp;goto=index.php%3Froute%3D%2Fsql&amp;default_'
766 . 'action=insert"><span '
767 . 'class="nowrap"><img src="themes/dot.gif" title="Copy" alt="Copy" '
768 . 'class="icon ic_b_insrow"> Copy</span></a>'
769 . '<input type="hidden" class="where_clause" value="%60new%60.%60id'
770 . '%60+%3D+1"></span></td><td class="edit_row_anchor text-center print_ignore">'
771 . '<span class="nowrap">'
772 . '<a href="index.php" data-post="route=/table/change&amp;db=data&amp;table=new&amp;where_clause'
773 . '=%60new%60.%60id%60+%3D+1&amp;clause_is_unique=1&amp;sql_query='
774 . 'SELECT+%2A+FROM+%60new%60&amp;goto=index.php%3Froute%3D%2Fsql&amp;default_action='
775 . 'update"><span class='
776 . '"nowrap"><img src="themes/dot.gif" title="Edit" alt="Edit" class'
777 . '="icon ic_b_edit"> Edit</span></a>'
778 . '<input type="hidden" class="where_clause" value ="%60new%60.%60'
779 . 'id%60+%3D+1"></span></td><td class="text-center print_ignore"><input type='
780 . '"checkbox" id="id_rows_to_delete0_right" name="rows_to_delete'
781 . '[0]" class="multi_checkbox checkall" value="%60new%60.%60id%60'
782 . '+%3D+1"><input type="hidden" class="condition_array" value="'
783 . '{&quot;`new`.`id`&quot;:&quot;= 1&quot;}"> </td>',
786 DisplayResults::POSITION_NONE,
787 'index.php?route=/sql&amp;db=data&amp;table=new&amp;sql_query=DELETE+FROM+%60data%60.'
788 . '%60new%60+WHERE+%60new%60.%60id%60+%3D+1&amp;message_to_show=The+'
789 . 'row+has+been+deleted&amp;goto=index.php%3Froute%3D%2Fsql%26db%3Ddata%26table%3Dnew'
790 . '%26sql_query%3DSELECT%2B%252A%2BFROM%2B%2560new%2560%26message_'
791 . 'to_show%3DThe%2Brow%2Bhas%2Bbeen%2Bdeleted%26goto%3Dindex.php%253Froute%253D%252Ftable%252Fstructure',
793 'edit_lnk' => 'ur',
794 'del_lnk' => 'dr',
795 'sort_lnk' => '0',
796 'nav_bar' => '1',
797 'bkm_form' => '1',
798 'text_btn' => '1',
799 'pview_lnk' => '1',
802 '`new`.`id` = 1',
803 '%60new%60.%60id%60+%3D+1',
805 '`new`.`id`' => '= 1',
807 'index.php?route=/table/change&db=data&amp;table=new&amp;where_clause=%60new%60.%60'
808 . 'id%60+%3D+1&amp;clause_is_unique=1&amp;sql_query=SELECT+%2A+FROM+'
809 . '%60new%60&amp;goto=index.php%3Froute%3D%2Fsql&amp;default_action=update',
810 'index.php?route=/table/change&db=data&amp;table=new&amp;where_clause=%60new%60.%60'
811 . 'id%60+%3D+1&amp;clause_is_unique=1&amp;sql_query=SELECT+%2A+FROM+'
812 . '%60new%60&amp;goto=index.php%3Froute%3D%2Fsql&amp;default_action=insert',
813 'edit_row_anchor',
814 '<span class="nowrap"><img src="themes/dot.gif" title="Edit" '
815 . 'alt="Edit" class="icon ic_b_edit"> Edit</span>',
816 '<span class="nowrap"><img src="themes/dot.gif" title="Copy" '
817 . 'alt="Copy" class="icon ic_b_insrow"> Copy</span>',
818 '<span class="nowrap"><img src="themes/dot.gif" title="Delete" '
819 . 'alt="Delete" class="icon ic_b_drop"> Delete</span>',
820 'DELETE FROM `data`.`new` WHERE `new`.`id` = 1',
821 '<td class="text-center print_ignore"><input type="checkbox" id="id_rows_to_'
822 . 'delete0_left" name="rows_to_delete[0]" class="multi_checkbox '
823 . 'checkall" value="%60new%60.%60id%60+%3D+1"><input type='
824 . '"hidden" class="condition_array" value="{&quot;`new`.`id`&quot;:'
825 . '&quot;= 1&quot;}"> </td>',
831 * Test for _getCheckboxAndLinks
833 * @param string $position the position of the checkbox and links
834 * @param string $del_url delete url
835 * @param array $displayParts array with explicit indexes for all the
836 * display elements
837 * @param string $row_no row number
838 * @param string $where_clause where clause
839 * @param string $where_clause_html url encoded where clause
840 * @param array $condition_array array of conditions in the where clause
841 * @param string $edit_url edit url
842 * @param string $copy_url copy url
843 * @param string $class css classes for the td elements
844 * @param string $edit_str text for the edit link
845 * @param string $copy_str text for the copy link
846 * @param string $del_str text for the delete link
847 * @param string $js_conf text for the JS confirmation
848 * @param string $output output of _getCheckboxAndLinks
850 * @return void
852 * @dataProvider dataProviderForGetCheckboxAndLinks
854 public function testGetCheckboxAndLinks(
855 $position,
856 $del_url,
857 $displayParts,
858 $row_no,
859 $where_clause,
860 $where_clause_html,
861 $condition_array,
862 $edit_url,
863 $copy_url,
864 $class,
865 $edit_str,
866 $copy_str,
867 $del_str,
868 $js_conf,
869 $output
871 $this->assertEquals(
872 $output,
873 $this->_callPrivateFunction(
874 '_getCheckboxAndLinks',
876 $position,
877 $del_url,
878 $displayParts,
879 $row_no,
880 $where_clause,
881 $where_clause_html,
882 $condition_array,
883 $edit_url,
884 $copy_url,
885 $class,
886 $edit_str,
887 $copy_str,
888 $del_str,
889 $js_conf,
896 * Data provider for testGetPlacedLinks
898 * @return array parameters and output
900 public function dataProviderForGetPlacedLinks()
902 return [
904 DisplayResults::POSITION_NONE,
905 'index.php?route=/sql&amp;db=data&amp;table=new&amp;sql_query=DELETE+FROM+%60data%60.'
906 . '%60new%60+WHERE+%60new%60.%60id%60+%3D+1&amp;message_to_show=The+'
907 . 'row+has+been+deleted&amp;goto=index.php%3Froute%3D%2Fsql%26db%3Ddata%26table%3Dnew'
908 . '%26sql_query%3DSELECT%2B%252A%2BFROM%2B%2560new%2560%26message_'
909 . 'to_show%3DThe%2Brow%2Bhas%2Bbeen%2Bdeleted%26goto%3Dtbl_structure'
910 . '.php',
912 'edit_lnk' => 'ur',
913 'del_lnk' => 'dr',
914 'sort_lnk' => '0',
915 'nav_bar' => '1',
916 'bkm_form' => '1',
917 'text_btn' => '1',
918 'pview_lnk' => '1',
921 '`new`.`id` = 1',
922 '%60new%60.%60id%60+%3D+1',
924 '`new`.`id`' => '= 1',
926 'index.php?route=/table/change&db=data&amp;table=new&amp;where_clause=%60new%60.%60'
927 . 'id%60+%3D+1&amp;clause_is_unique=1&amp;sql_query=SELECT+%2A+FROM+'
928 . '%60new%60&amp;goto=index.php%3Froute%3D%2Fsql&amp;default_action=update',
929 '/index.php?route=/table/change&db=data&amp;table=new&amp;where_clause=%60new%60.%60'
930 . 'id%60+%3D+1&amp;clause_is_unique=1&amp;sql_query=SELECT+%2A+FROM+'
931 . '%60new%60&amp;goto=index.php%3Froute%3D%2Fsql&amp;default_action=insert',
932 'edit_row_anchor',
933 '<span class="nowrap"><img src="themes/dot.gif" title="Edit" '
934 . 'alt="Edit" class="icon ic_b_edit"> Edit</span>',
935 '<span class="nowrap"><img src="themes/dot.gif" title="Copy" '
936 . 'alt="Copy" class="icon ic_b_insrow"> Copy</span>',
937 '<span class="nowrap"><img src="themes/dot.gif" title="Delete" '
938 . 'alt="Delete" class="icon ic_b_drop"> Delete</span>',
939 null,
940 '<td class="text-center print_ignore"><input type="checkbox" id="id_rows_to_'
941 . 'delete0_left" name="rows_to_delete[0]" class="multi_checkbox '
942 . 'checkall" value="%60new%60.%60id%60+%3D+1"><input type='
943 . '"hidden" class="condition_array" value="{&quot;`new`.`id`&quot;:'
944 . '&quot;= 1&quot;}"> </td>',
950 * Test for _getPlacedLinks
952 * @param string $dir the direction of links should place
953 * @param string $del_url the url for delete row
954 * @param array $displayParts which elements to display
955 * @param int $row_no the index of current row
956 * @param string $where_clause the where clause of the sql
957 * @param string $where_clause_html the html encoded where clause
958 * @param array $condition_array array of keys (primary, unique, condition)
959 * @param string $edit_url the url for edit row
960 * @param string $copy_url the url for copy row
961 * @param string $edit_anchor_class the class for html element for edit
962 * @param string $edit_str the label for edit row
963 * @param string $copy_str the label for copy row
964 * @param string $del_str the label for delete row
965 * @param string $js_conf text for the JS confirmation
966 * @param string $output output of _getPlacedLinks
968 * @return void
970 * @dataProvider dataProviderForGetPlacedLinks
972 public function testGetPlacedLinks(
973 $dir,
974 $del_url,
975 $displayParts,
976 $row_no,
977 $where_clause,
978 $where_clause_html,
979 $condition_array,
980 $edit_url,
981 $copy_url,
982 $edit_anchor_class,
983 $edit_str,
984 $copy_str,
985 $del_str,
986 $js_conf,
987 $output
989 $this->assertEquals(
990 $output,
991 $this->_callPrivateFunction(
992 '_getPlacedLinks',
994 $dir,
995 $del_url,
996 $displayParts,
997 $row_no,
998 $where_clause,
999 $where_clause_html,
1000 $condition_array,
1001 $edit_url,
1002 $copy_url,
1003 $edit_anchor_class,
1004 $edit_str,
1005 $copy_str,
1006 $del_str,
1007 $js_conf,
1014 * Data provider for testGetSpecialLinkUrl
1016 * @return array parameters and output
1018 public function dataProviderForTestGetSpecialLinkUrl()
1020 return [
1022 'information_schema',
1023 'routines',
1024 'circumference',
1026 'routine_name' => 'circumference',
1027 'routine_schema' => 'data',
1028 'routine_type' => 'FUNCTION',
1030 'routine_name',
1031 'index.php?route=/database/routines&item_name=circumference&db=data'
1032 . '&item_type=FUNCTION&server=0&lang=en',
1035 'information_schema',
1036 'routines',
1037 'area',
1039 'routine_name' => 'area',
1040 'routine_schema' => 'data',
1041 'routine_type' => 'PROCEDURE',
1043 'routine_name',
1044 'index.php?route=/database/routines&item_name=area&db=data'
1045 . '&item_type=PROCEDURE&server=0&lang=en',
1048 'information_schema',
1049 'columns',
1050 'CHARACTER_SET_NAME',
1052 'table_schema' => 'information_schema',
1053 'table_name' => 'CHARACTER_SETS',
1055 'column_name',
1056 'index.php?sql_query=SELECT+%60CHARACTER_SET_NAME%60+FROM+%60info'
1057 . 'rmation_schema%60.%60CHARACTER_SETS%60&db=information_schema'
1058 . '&test_name=value&server=0&lang=en',
1064 * Test _getSpecialLinkUrl
1066 * @param string $db the database name
1067 * @param string $table the table name
1068 * @param string $column_value column value
1069 * @param array $row_info information about row
1070 * @param string $field_name column name
1071 * @param bool $output output of _getSpecialLinkUrl
1073 * @return void
1075 * @dataProvider dataProviderForTestGetSpecialLinkUrl
1077 public function testGetSpecialLinkUrl(
1078 $db,
1079 $table,
1080 $column_value,
1081 $row_info,
1082 $field_name,
1083 $output
1085 $specialSchemaLinks = [
1086 'information_schema' => [
1087 'routines' => [
1088 'routine_name' => [
1089 'link_param' => 'item_name',
1090 'link_dependancy_params' => [
1091 0 => [
1092 'param_info' => 'db',
1093 'column_name' => 'routine_schema',
1095 1 => [
1096 'param_info' => 'item_type',
1097 'column_name' => 'routine_type',
1100 'default_page' => 'index.php?route=/database/routines',
1103 'columns' => [
1104 'column_name' => [
1105 'link_param' => [
1106 'sql_query',
1107 'table_schema',
1108 'table_name',
1110 'link_dependancy_params' => [
1111 0 => [
1112 'param_info' => 'db',
1113 'column_name' => 'table_schema',
1115 1 => [
1116 'param_info' => [
1117 'test_name',
1118 'value',
1122 'default_page' => 'index.php',
1128 $this->object->__set('db', $db);
1129 $this->object->__set('table', $table);
1131 $this->assertEquals(
1132 $output,
1133 $this->_callPrivateFunction(
1134 '_getSpecialLinkUrl',
1136 $specialSchemaLinks,
1137 $column_value,
1138 $row_info,
1139 $field_name,
1146 * Data provider for testGetRowInfoForSpecialLinks
1148 * @return array parameters and output
1150 public function dataProviderForTestGetRowInfoForSpecialLinks()
1152 $column_names = [
1153 'host',
1154 'db',
1155 'user',
1156 'select_privilages',
1158 $fields_mata = [];
1160 foreach ($column_names as $column_name) {
1161 $field_meta = new stdClass();
1162 $field_meta->orgname = $column_name;
1163 $fields_mata[] = $field_meta;
1166 return [
1168 $fields_mata,
1169 count($fields_mata),
1171 0 => 'localhost',
1172 1 => 'phpmyadmin',
1173 2 => 'pmauser',
1174 3 => 'Y',
1177 0 => '0',
1178 1 => '3',
1179 2 => '1',
1180 3 => '2',
1183 'host' => 'localhost',
1184 'select_privilages' => 'Y',
1185 'db' => 'phpmyadmin',
1186 'user' => 'pmauser',
1193 * Test _getRowInfoForSpecialLinks
1195 * @param array $fields_meta meta information about fields
1196 * @param int $fields_count number of fields
1197 * @param array $row current row data
1198 * @param array $col_order the column order
1199 * @param bool $output output of _getRowInfoForSpecialLinks
1201 * @return void
1203 * @dataProvider dataProviderForTestGetRowInfoForSpecialLinks
1205 public function testGetRowInfoForSpecialLinks(
1206 $fields_meta,
1207 $fields_count,
1208 $row,
1209 $col_order,
1210 $output
1212 $this->object->__set('fields_meta', $fields_meta);
1213 $this->object->__set('fields_cnt', $fields_count);
1215 $this->assertEquals(
1216 $output,
1217 $this->_callPrivateFunction(
1218 '_getRowInfoForSpecialLinks',
1220 $row,
1221 $col_order,
1228 * Data provider for testSetHighlightedColumnGlobalField
1230 * @return array parameters and output
1232 public function dataProviderForTestSetHighlightedColumnGlobalField()
1234 $parser = new Parser(
1235 'SELECT * FROM db_name WHERE `db_name`.`tbl`.id > 0 AND `id` < 10'
1237 return [
1239 ['statement' => $parser->statements[0]],
1241 'db_name' => 'true',
1242 'tbl' => 'true',
1243 'id' => 'true',
1250 * Test _setHighlightedColumnGlobalField
1252 * @param array $analyzed_sql the analyzed query
1253 * @param array $output setting value of _setHighlightedColumnGlobalField
1255 * @dataProvider dataProviderForTestSetHighlightedColumnGlobalField
1257 public function testSetHighlightedColumnGlobalField($analyzed_sql, $output): void
1259 $this->_callPrivateFunction(
1260 '_setHighlightedColumnGlobalField',
1261 [$analyzed_sql]
1264 $this->assertEquals(
1265 $output,
1266 $this->object->__get('highlight_columns')
1271 * Data provider for testGetPartialText
1273 * @return array parameters and output
1275 public function dataProviderForTestGetPartialText()
1277 return [
1279 'P',
1281 'foo',
1283 false,
1284 'foo',
1289 'P',
1291 'foo',
1293 true,
1294 'f...',
1299 'F',
1301 'foo',
1303 false,
1304 'foo',
1309 'F',
1311 'foo',
1313 false,
1314 'foo',
1322 * Test _getPartialText
1324 * @param string $pftext Partial or Full text
1325 * @param int $limitChars Partial or Full text
1326 * @param string $str the string to be tested
1327 * @param bool $output return value of _getPartialText
1329 * @dataProvider dataProviderForTestGetPartialText
1331 public function testGetPartialText($pftext, $limitChars, $str, $output): void
1333 $_SESSION['tmpval']['pftext'] = $pftext;
1334 $GLOBALS['cfg']['LimitChars'] = $limitChars;
1335 $this->assertEquals(
1336 $output,
1337 $this->_callPrivateFunction(
1338 '_getPartialText',
1339 [$str]
1345 * Data provider for testHandleNonPrintableContents
1347 * @return array parameters and output
1349 public function dataProviderForTestHandleNonPrintableContents()
1351 $transformation_plugin = new Text_Plain_Link();
1352 $meta = new stdClass();
1353 $meta->type = 'BLOB';
1354 $meta->orgtable = 'bar';
1355 $url_params = [
1356 'db' => 'foo',
1357 'table' => 'bar',
1358 'where_clause' => 'where_clause',
1361 return [
1363 true,
1364 true,
1365 'BLOB',
1366 '1001',
1368 Core::class,
1369 'mimeDefaultFunction',
1373 Core::class,
1374 'mimeDefaultFunction',
1376 $meta,
1377 $url_params,
1378 null,
1379 'class="disableAjax">1001</a>'
1382 true,
1383 true,
1384 'BLOB',
1385 hex2bin('123456'),
1387 Core::class,
1388 'mimeDefaultFunction',
1392 Core::class,
1393 'mimeDefaultFunction',
1395 $meta,
1396 $url_params,
1397 null,
1398 'class="disableAjax">0x123456</a>'
1401 true,
1402 false,
1403 'BLOB',
1404 '1001',
1406 Core::class,
1407 'mimeDefaultFunction',
1411 Core::class,
1412 'mimeDefaultFunction',
1414 $meta,
1415 $url_params,
1416 null,
1417 'class="disableAjax">[BLOB - 4 B]</a>'
1420 false,
1421 false,
1422 'BINARY',
1423 '1001',
1424 $transformation_plugin,
1427 Core::class,
1428 'mimeDefaultFunction',
1430 $meta,
1431 $url_params,
1432 null,
1433 '1001',
1436 false,
1437 true,
1438 'GEOMETRY',
1439 null,
1443 Core::class,
1444 'mimeDefaultFunction',
1446 $meta,
1447 $url_params,
1448 null,
1449 '[GEOMETRY - NULL]',
1455 * Test _handleNonPrintableContents
1457 * @param bool $display_binary show binary contents?
1458 * @param bool $display_blob show blob contents?
1459 * @param string $category BLOB|BINARY|GEOMETRY
1460 * @param string $content the binary content
1461 * @param string $transformation_plugin transformation plugin.
1462 * Can also be the default function:
1463 * PhpMyAdmin\Core::mimeDefaultFunction
1464 * @param array $transform_options transformation parameters
1465 * @param string $default_function default transformation function
1466 * @param object $meta the meta-information about the field
1467 * @param array $url_params parameters that should go to the
1468 * download link
1469 * @param bool $is_truncated the result is truncated or not
1470 * @param string $output the output of this function
1472 * @return void
1474 * @dataProvider dataProviderForTestHandleNonPrintableContents
1476 public function testHandleNonPrintableContents(
1477 $display_binary,
1478 $display_blob,
1479 $category,
1480 $content,
1481 $transformation_plugin,
1482 array $transform_options,
1483 $default_function,
1484 $meta,
1485 $url_params,
1486 $is_truncated,
1487 $output
1489 $_SESSION['tmpval']['display_binary'] = $display_binary;
1490 $_SESSION['tmpval']['display_blob'] = $display_blob;
1491 $GLOBALS['cfg']['LimitChars'] = 50;
1492 $this->assertContains(
1493 $output,
1494 $this->_callPrivateFunction(
1495 '_handleNonPrintableContents',
1497 $category,
1498 $content,
1499 $transformation_plugin,
1500 $transform_options,
1501 $default_function,
1502 $meta,
1503 $url_params,
1504 &$is_truncated,
1511 * Data provider for testGetDataCellForNonNumericColumns
1513 * @return array parameters and output
1515 public function dataProviderForTestGetDataCellForNonNumericColumns()
1517 $transformation_plugin = new Text_Plain_Link();
1518 $meta = new stdClass();
1519 $meta->db = 'foo';
1520 $meta->table = 'tbl';
1521 $meta->orgtable = 'tbl';
1522 $meta->type = 'BLOB';
1523 $meta->flags = 'blob binary';
1524 $meta->name = 'tblob';
1525 $meta->orgname = 'tblob';
1527 $meta2 = new stdClass();
1528 $meta2->db = 'foo';
1529 $meta2->table = 'tbl';
1530 $meta2->orgtable = 'tbl';
1531 $meta2->type = 'string';
1532 $meta2->flags = '';
1533 $meta2->decimals = 0;
1534 $meta2->name = 'varchar';
1535 $meta2->orgname = 'varchar';
1536 $url_params = [
1537 'db' => 'foo',
1538 'table' => 'tbl',
1539 'where_clause' => 'where_clause',
1542 return [
1544 'all',
1545 '1001',
1546 'grid_edit',
1547 $meta,
1549 $url_params,
1550 false,
1552 Core::class,
1553 'mimeDefaultFunction',
1556 Core::class,
1557 'mimeDefaultFunction',
1559 ['https://www.example.com/'],
1560 false,
1563 'binary',
1564 'class="disableAjax">[BLOB - 4 B]</a>' . PHP_EOL
1565 . '</td>' . PHP_EOL
1568 'noblob',
1569 '1001',
1570 'grid_edit',
1571 $meta,
1573 $url_params,
1574 false,
1575 $transformation_plugin,
1577 Core::class,
1578 'mimeDefaultFunction',
1581 false,
1584 'binary',
1585 '<td class="left grid_edit transformed hex">' . "\n"
1586 . ' 1001' . "\n"
1587 . '</td>' . "\n",
1590 'noblob',
1591 null,
1592 'grid_edit',
1593 $meta2,
1595 $url_params,
1596 false,
1597 $transformation_plugin,
1599 Core::class,
1600 'mimeDefaultFunction',
1603 false,
1607 '<td ' . "\n"
1608 . ' data-decimals="0"' . "\n"
1609 . ' data-type="string"' . "\n"
1610 . ' class="grid_edit null">' . "\n"
1611 . ' <em>NULL</em>' . "\n"
1612 . '</td>' . "\n",
1615 'all',
1616 'foo bar baz',
1617 'grid_edit',
1618 $meta2,
1620 $url_params,
1621 false,
1623 Core::class,
1624 'mimeDefaultFunction',
1627 Core::class,
1628 'mimeDefaultFunction',
1631 false,
1635 '<td data-decimals="0" data-type="string" '
1636 . 'data-originallength="11" '
1637 . 'class="grid_edit ">foo bar baz</td>' . "\n",
1643 * Test _getDataCellForNonNumericColumns
1645 * @param bool $protectBinary all|blob|noblob|no
1646 * @param string $column the relevant column in data row
1647 * @param string $class the html class for column
1648 * @param object $meta the meta-information about the field
1649 * @param array $map the list of relations
1650 * @param array $_url_params the parameters for generate url
1651 * @param bool $condition_field the column should highlighted
1652 * or not
1653 * @param string $transformation_plugin the name of transformation function
1654 * @param string $default_function the default transformation function
1655 * @param array $transform_options the transformation parameters
1656 * @param bool $is_field_truncated is data truncated due to LimitChars
1657 * @param array $analyzed_sql_results the analyzed query
1658 * @param int $dt_result the link id associated to the query
1659 * which results have to be displayed
1660 * @param int $col_index the column index
1661 * @param string $output the output of this function
1663 * @return void
1665 * @dataProvider dataProviderForTestGetDataCellForNonNumericColumns
1667 public function testGetDataCellForNonNumericColumns(
1668 $protectBinary,
1669 $column,
1670 $class,
1671 $meta,
1672 $map,
1673 $_url_params,
1674 $condition_field,
1675 $transformation_plugin,
1676 $default_function,
1677 array $transform_options,
1678 $is_field_truncated,
1679 $analyzed_sql_results,
1680 $dt_result,
1681 $col_index,
1682 $output
1684 $_SESSION['tmpval']['display_binary'] = true;
1685 $_SESSION['tmpval']['display_blob'] = false;
1686 $_SESSION['tmpval']['relational_display'] = false;
1687 $GLOBALS['cfg']['LimitChars'] = 50;
1688 $GLOBALS['cfg']['ProtectBinary'] = $protectBinary;
1689 $this->assertContains(
1690 $output,
1691 $this->_callPrivateFunction(
1692 '_getDataCellForNonNumericColumns',
1694 $column,
1695 $class,
1696 $meta,
1697 $map,
1698 $_url_params,
1699 $condition_field,
1700 $transformation_plugin,
1701 $default_function,
1702 $transform_options,
1703 $is_field_truncated,
1704 $analyzed_sql_results,
1705 &$dt_result,
1706 $col_index,
1713 * Simple output transformation test
1715 * It mocks data needed to display two transformations and asserts
1716 * they are rendered.
1718 * @return void
1720 public function testOutputTransformations()
1722 // Fake relation settings
1723 $_SESSION['tmpval']['relational_display'] = 'K';
1724 $_SESSION['relation'][$GLOBALS['server']]['PMA_VERSION'] = PMA_VERSION;
1725 $_SESSION['relation'][$GLOBALS['server']]['mimework'] = true;
1726 $_SESSION['relation'][$GLOBALS['server']]['column_info'] = 'column_info';
1727 $GLOBALS['cfg']['BrowseMIME'] = true;
1729 // Basic data
1730 $result = 0;
1731 $query = 'SELECT 1';
1732 $this->object->__set('db', 'db');
1733 $this->object->__set('fields_cnt', 2);
1735 // Field meta information
1736 $meta = new stdClass();
1737 $meta->db = 'db';
1738 $meta->table = 'table';
1739 $meta->orgtable = 'table';
1740 $meta->type = 'INT';
1741 $meta->flags = '';
1742 $meta->name = '1';
1743 $meta->orgname = '1';
1744 $meta->not_null = true;
1745 $meta->numeric = true;
1746 $meta->primary_key = false;
1747 $meta->unique_key = false;
1748 $meta2 = new stdClass();
1749 $meta2->db = 'db';
1750 $meta2->table = 'table';
1751 $meta2->orgtable = 'table';
1752 $meta2->type = 'INT';
1753 $meta2->flags = '';
1754 $meta2->name = '2';
1755 $meta2->orgname = '2';
1756 $meta2->not_null = true;
1757 $meta2->numeric = true;
1758 $meta2->primary_key = false;
1759 $meta2->unique_key = false;
1760 $fields_meta = [
1761 $meta,
1762 $meta2,
1764 $this->object->__set('fields_meta', $fields_meta);
1766 $dbi = $this->getMockBuilder('PhpMyAdmin\DatabaseInterface')
1767 ->disableOriginalConstructor()
1768 ->getMock();
1770 $dbi->expects($this->any())->method('fieldFlags')
1771 ->willReturn('');
1773 // MIME transformations
1774 $dbi->expects($this->exactly(1))
1775 ->method('fetchResult')
1776 ->willReturn(
1778 'db.table.1' => [
1779 'mimetype' => '',
1780 'transformation' => 'output/text_plain_dateformat.php',
1782 'db.table.2' => [
1783 'mimetype' => '',
1784 'transformation' => 'output/text_plain_bool2text.php',
1789 $GLOBALS['dbi'] = $dbi;
1791 $transformations = new Transformations();
1792 $this->object->__set(
1793 'mime_map',
1794 $transformations->getMime('db', 'table')
1797 // Actually invoke tested method
1798 $output = $this->_callPrivateFunction(
1799 '_getRowValues',
1801 &$result,
1803 3600,
1804 true,
1807 false,
1810 false,
1811 $query,
1812 Query::getAll($query),
1816 // Dateformat
1817 $this->assertStringContainsString(
1818 'Jan 01, 1970 at 01:00 AM',
1819 $output
1821 // Bool2Text
1822 $this->assertStringContainsString(
1823 '>T<',
1824 $output
1826 unset($_SESSION['tmpval']);
1827 unset($_SESSION['relation']);