PageRenderTime 51ms CodeModel.GetById 24ms RepoModel.GetById 0ms app.codeStats 0ms

/my_view_inc.php

https://github.com/markkimsal/mantisbt
PHP | 537 lines | 446 code | 41 blank | 50 comment | 25 complexity | 54f4c288137474dfb4a9a5b48cb5f7fe MD5 | raw file
Possible License(s): GPL-2.0, LGPL-2.1
  1. <?php
  2. # MantisBT - A PHP based bugtracking system
  3. # MantisBT is free software: you can redistribute it and/or modify
  4. # it under the terms of the GNU General Public License as published by
  5. # the Free Software Foundation, either version 2 of the License, or
  6. # (at your option) any later version.
  7. #
  8. # MantisBT is distributed in the hope that it will be useful,
  9. # but WITHOUT ANY WARRANTY; without even the implied warranty of
  10. # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  11. # GNU General Public License for more details.
  12. #
  13. # You should have received a copy of the GNU General Public License
  14. # along with MantisBT. If not, see <http://www.gnu.org/licenses/>.
  15. /**
  16. * @copyright Copyright (C) 2000 - 2002 Kenzaburo Ito - kenito@300baud.org
  17. * @copyright Copyright (C) 2002 - 2010 MantisBT Team - mantisbt-dev@lists.sourceforge.net
  18. * @link http://www.mantisbt.org
  19. * @package MantisBT
  20. *
  21. * @uses access_api.php
  22. * @uses bug_api.php
  23. * @uses category_api.php
  24. * @uses config_api.php
  25. * @uses constant_inc.php
  26. * @uses current_user_api.php
  27. * @uses file_api.php
  28. * @uses filter_api.php
  29. * @uses filter_constants_inc.php
  30. * @uses helper_api.php
  31. * @uses icon_api.php
  32. * @uses lang_api.php
  33. * @uses print_api.php
  34. * @uses project_api.php
  35. * @uses string_api.php
  36. */
  37. if ( !defined( 'MY_VIEW_INC_ALLOW' ) ) {
  38. return;
  39. }
  40. require_api( 'access_api.php' );
  41. require_api( 'bug_api.php' );
  42. require_api( 'category_api.php' );
  43. require_api( 'config_api.php' );
  44. require_api( 'constant_inc.php' );
  45. require_api( 'current_user_api.php' );
  46. require_api( 'file_api.php' );
  47. require_api( 'filter_api.php' );
  48. require_api( 'filter_constants_inc.php' );
  49. require_api( 'helper_api.php' );
  50. require_api( 'icon_api.php' );
  51. require_api( 'lang_api.php' );
  52. require_api( 'print_api.php' );
  53. require_api( 'project_api.php' );
  54. require_api( 'string_api.php' );
  55. $t_filter = current_user_get_bug_filter();
  56. if( $t_filter === false ) {
  57. $t_filter = filter_get_default();
  58. }
  59. $t_sort = $t_filter['sort'];
  60. $t_dir = $t_filter['dir'];
  61. $t_icon_path = config_get( 'icon_path' );
  62. $t_update_bug_threshold = config_get( 'update_bug_threshold' );
  63. $t_bug_resolved_status_threshold = config_get( 'bug_resolved_status_threshold' );
  64. $t_hide_status_default = config_get( 'hide_status_default' );
  65. $t_default_show_changed = config_get( 'default_show_changed' );
  66. $c_filter['assigned'] = array(
  67. FILTER_PROPERTY_CATEGORY_ID => Array(
  68. '0' => META_FILTER_ANY,
  69. ),
  70. FILTER_PROPERTY_SEVERITY => Array(
  71. '0' => META_FILTER_ANY,
  72. ),
  73. FILTER_PROPERTY_STATUS => Array(
  74. '0' => META_FILTER_ANY,
  75. ),
  76. FILTER_PROPERTY_HIGHLIGHT_CHANGED => $t_default_show_changed,
  77. FILTER_PROPERTY_REPORTER_ID => Array(
  78. '0' => META_FILTER_ANY,
  79. ),
  80. FILTER_PROPERTY_HANDLER_ID => Array(
  81. '0' => $t_current_user_id,
  82. ),
  83. FILTER_PROPERTY_RESOLUTION => Array(
  84. '0' => META_FILTER_ANY,
  85. ),
  86. FILTER_PROPERTY_BUILD => Array(
  87. '0' => META_FILTER_ANY,
  88. ),
  89. FILTER_PROPERTY_VERSION => Array(
  90. '0' => META_FILTER_ANY,
  91. ),
  92. FILTER_PROPERTY_HIDE_STATUS => Array(
  93. '0' => $t_bug_resolved_status_threshold,
  94. ),
  95. FILTER_PROPERTY_MONITOR_USER_ID => Array(
  96. '0' => META_FILTER_ANY,
  97. ),
  98. );
  99. $url_link_parameters['assigned'] = FILTER_PROPERTY_HANDLER_ID . '=' . $t_current_user_id . '&' . FILTER_PROPERTY_HIDE_STATUS . '=' . $t_bug_resolved_status_threshold;
  100. $c_filter['recent_mod'] = array(
  101. FILTER_PROPERTY_CATEGORY_ID => Array(
  102. '0' => META_FILTER_ANY,
  103. ),
  104. FILTER_PROPERTY_SEVERITY => Array(
  105. '0' => META_FILTER_ANY,
  106. ),
  107. FILTER_PROPERTY_STATUS => Array(
  108. '0' => META_FILTER_ANY,
  109. ),
  110. FILTER_PROPERTY_HIGHLIGHT_CHANGED => $t_default_show_changed,
  111. FILTER_PROPERTY_REPORTER_ID => Array(
  112. '0' => META_FILTER_ANY,
  113. ),
  114. FILTER_PROPERTY_HANDLER_ID => Array(
  115. '0' => META_FILTER_ANY,
  116. ),
  117. FILTER_PROPERTY_RESOLUTION => Array(
  118. '0' => META_FILTER_ANY,
  119. ),
  120. FILTER_PROPERTY_BUILD => Array(
  121. '0' => META_FILTER_ANY,
  122. ),
  123. FILTER_PROPERTY_VERSION => Array(
  124. '0' => META_FILTER_ANY,
  125. ),
  126. FILTER_PROPERTY_HIDE_STATUS => Array(
  127. '0' => META_FILTER_NONE,
  128. ),
  129. FILTER_PROPERTY_MONITOR_USER_ID => Array(
  130. '0' => META_FILTER_ANY,
  131. ),
  132. );
  133. $url_link_parameters['recent_mod'] = FILTER_PROPERTY_HIDE_STATUS . '=none';
  134. $c_filter['reported'] = array(
  135. FILTER_PROPERTY_CATEGORY_ID => Array(
  136. '0' => META_FILTER_ANY,
  137. ),
  138. FILTER_PROPERTY_SEVERITY => Array(
  139. '0' => META_FILTER_ANY,
  140. ),
  141. FILTER_PROPERTY_STATUS => Array(
  142. '0' => META_FILTER_ANY,
  143. ),
  144. FILTER_PROPERTY_HIGHLIGHT_CHANGED => $t_default_show_changed,
  145. FILTER_PROPERTY_REPORTER_ID => Array(
  146. '0' => $t_current_user_id,
  147. ),
  148. FILTER_PROPERTY_HANDLER_ID => Array(
  149. '0' => META_FILTER_ANY,
  150. ),
  151. FILTER_PROPERTY_SORT_FIELD_NAME => 'last_updated',
  152. FILTER_PROPERTY_RESOLUTION => Array(
  153. '0' => META_FILTER_ANY,
  154. ),
  155. FILTER_PROPERTY_BUILD => Array(
  156. '0' => META_FILTER_ANY,
  157. ),
  158. FILTER_PROPERTY_VERSION => Array(
  159. '0' => META_FILTER_ANY,
  160. ),
  161. FILTER_PROPERTY_HIDE_STATUS => Array(
  162. '0' => $t_hide_status_default,
  163. ),
  164. FILTER_PROPERTY_MONITOR_USER_ID => Array(
  165. '0' => META_FILTER_ANY,
  166. ),
  167. );
  168. $url_link_parameters['reported'] = FILTER_PROPERTY_REPORTER_ID . '=' . $t_current_user_id . '&' . FILTER_PROPERTY_HIDE_STATUS . '=' . $t_hide_status_default;
  169. $c_filter['resolved'] = array(
  170. FILTER_PROPERTY_CATEGORY_ID => Array(
  171. '0' => META_FILTER_ANY,
  172. ),
  173. FILTER_PROPERTY_SEVERITY => Array(
  174. '0' => META_FILTER_ANY,
  175. ),
  176. FILTER_PROPERTY_STATUS => Array(
  177. '0' => $t_bug_resolved_status_threshold,
  178. ),
  179. FILTER_PROPERTY_HIGHLIGHT_CHANGED => $t_default_show_changed,
  180. FILTER_PROPERTY_REPORTER_ID => Array(
  181. '0' => META_FILTER_ANY,
  182. ),
  183. FILTER_PROPERTY_HANDLER_ID => Array(
  184. '0' => META_FILTER_ANY,
  185. ),
  186. FILTER_PROPERTY_RESOLUTION => Array(
  187. '0' => META_FILTER_ANY,
  188. ),
  189. FILTER_PROPERTY_BUILD => Array(
  190. '0' => META_FILTER_ANY,
  191. ),
  192. FILTER_PROPERTY_VERSION => Array(
  193. '0' => META_FILTER_ANY,
  194. ),
  195. FILTER_PROPERTY_HIDE_STATUS => Array(
  196. '0' => $t_hide_status_default,
  197. ),
  198. FILTER_PROPERTY_MONITOR_USER_ID => Array(
  199. '0' => META_FILTER_ANY,
  200. ),
  201. );
  202. $url_link_parameters['resolved'] = FILTER_PROPERTY_STATUS . '=' . $t_bug_resolved_status_threshold . '&' . FILTER_PROPERTY_HIDE_STATUS . '=' . $t_bug_resolved_status_threshold;
  203. $c_filter['unassigned'] = array(
  204. FILTER_PROPERTY_CATEGORY_ID => Array(
  205. '0' => META_FILTER_ANY,
  206. ),
  207. FILTER_PROPERTY_SEVERITY => Array(
  208. '0' => META_FILTER_ANY,
  209. ),
  210. FILTER_PROPERTY_STATUS => Array(
  211. '0' => META_FILTER_ANY,
  212. ),
  213. FILTER_PROPERTY_HIGHLIGHT_CHANGED => $t_default_show_changed,
  214. FILTER_PROPERTY_REPORTER_ID => Array(
  215. '0' => META_FILTER_ANY,
  216. ),
  217. FILTER_PROPERTY_HANDLER_ID => Array(
  218. '0' => META_FILTER_NONE,
  219. ),
  220. FILTER_PROPERTY_RESOLUTION => Array(
  221. '0' => META_FILTER_ANY,
  222. ),
  223. FILTER_PROPERTY_BUILD => Array(
  224. '0' => META_FILTER_ANY,
  225. ),
  226. FILTER_PROPERTY_VERSION => Array(
  227. '0' => META_FILTER_ANY,
  228. ),
  229. FILTER_PROPERTY_HIDE_STATUS => Array(
  230. '0' => $t_hide_status_default,
  231. ),
  232. FILTER_PROPERTY_MONITOR_USER_ID => Array(
  233. '0' => META_FILTER_ANY,
  234. ),
  235. );
  236. $url_link_parameters['unassigned'] = FILTER_PROPERTY_HANDLER_ID . '=[none]' . '&' . FILTER_PROPERTY_HIDE_STATUS . '=' . $t_hide_status_default;
  237. # TODO: check. handler value looks wrong
  238. $c_filter['monitored'] = array(
  239. FILTER_PROPERTY_CATEGORY_ID => Array(
  240. '0' => META_FILTER_ANY,
  241. ),
  242. FILTER_PROPERTY_SEVERITY => Array(
  243. '0' => META_FILTER_ANY,
  244. ),
  245. FILTER_PROPERTY_STATUS => Array(
  246. '0' => META_FILTER_ANY,
  247. ),
  248. FILTER_PROPERTY_HIGHLIGHT_CHANGED => $t_default_show_changed,
  249. FILTER_PROPERTY_REPORTER_ID => Array(
  250. '0' => META_FILTER_ANY,
  251. ),
  252. FILTER_PROPERTY_HANDLER_ID => Array(
  253. '0' => META_FILTER_ANY,
  254. ),
  255. FILTER_PROPERTY_RESOLUTION => Array(
  256. '0' => META_FILTER_ANY,
  257. ),
  258. FILTER_PROPERTY_BUILD => Array(
  259. '0' => META_FILTER_ANY,
  260. ),
  261. FILTER_PROPERTY_VERSION => Array(
  262. '0' => META_FILTER_ANY,
  263. ),
  264. FILTER_PROPERTY_HIDE_STATUS => Array(
  265. '0' => $t_hide_status_default,
  266. ),
  267. FILTER_PROPERTY_MONITOR_USER_ID => Array(
  268. '0' => $t_current_user_id,
  269. ),
  270. );
  271. $url_link_parameters['monitored'] = FILTER_PROPERTY_MONITOR_USER_ID . '=' . $t_current_user_id . '&' . FILTER_PROPERTY_HIDE_STATUS . '=' . $t_hide_status_default;
  272. $c_filter['feedback'] = array(
  273. FILTER_PROPERTY_CATEGORY_ID => Array(
  274. '0' => META_FILTER_ANY,
  275. ),
  276. FILTER_PROPERTY_SEVERITY => Array(
  277. '0' => META_FILTER_ANY,
  278. ),
  279. FILTER_PROPERTY_STATUS => Array(
  280. '0' => config_get( 'bug_feedback_status' ),
  281. ),
  282. FILTER_PROPERTY_HIGHLIGHT_CHANGED => $t_default_show_changed,
  283. FILTER_PROPERTY_REPORTER_ID => Array(
  284. '0' => $t_current_user_id,
  285. ),
  286. FILTER_PROPERTY_HANDLER_ID => Array(
  287. '0' => META_FILTER_ANY,
  288. ),
  289. FILTER_PROPERTY_RESOLUTION => Array(
  290. '0' => META_FILTER_ANY,
  291. ),
  292. FILTER_PROPERTY_BUILD => Array(
  293. '0' => META_FILTER_ANY,
  294. ),
  295. FILTER_PROPERTY_VERSION => Array(
  296. '0' => META_FILTER_ANY,
  297. ),
  298. FILTER_PROPERTY_HIDE_STATUS => Array(
  299. '0' => $t_hide_status_default,
  300. ),
  301. FILTER_PROPERTY_MONITOR_USER_ID => Array(
  302. '0' => META_FILTER_ANY,
  303. ),
  304. );
  305. $url_link_parameters['feedback'] = FILTER_PROPERTY_REPORTER_ID . '=' . $t_current_user_id . '&' . FILTER_PROPERTY_STATUS . '=' . config_get( 'bug_feedback_status' ) . '&' . FILTER_PROPERTY_HIDE_STATUS . '=' . $t_hide_status_default;
  306. $c_filter['verify'] = array(
  307. FILTER_PROPERTY_CATEGORY_ID => Array(
  308. '0' => META_FILTER_ANY,
  309. ),
  310. FILTER_PROPERTY_SEVERITY => Array(
  311. '0' => META_FILTER_ANY,
  312. ),
  313. FILTER_PROPERTY_STATUS => Array(
  314. '0' => $t_bug_resolved_status_threshold,
  315. ),
  316. FILTER_PROPERTY_HIGHLIGHT_CHANGED => $t_default_show_changed,
  317. FILTER_PROPERTY_REPORTER_ID => Array(
  318. '0' => $t_current_user_id,
  319. ),
  320. FILTER_PROPERTY_HANDLER_ID => Array(
  321. '0' => META_FILTER_ANY,
  322. ),
  323. FILTER_PROPERTY_RESOLUTION => Array(
  324. '0' => META_FILTER_ANY,
  325. ),
  326. FILTER_PROPERTY_BUILD => Array(
  327. '0' => META_FILTER_ANY,
  328. ),
  329. FILTER_PROPERTY_VERSION => Array(
  330. '0' => META_FILTER_ANY,
  331. ),
  332. FILTER_PROPERTY_HIDE_STATUS => Array(
  333. '0' => $t_hide_status_default,
  334. ),
  335. FILTER_PROPERTY_MONITOR_USER_ID => Array(
  336. '0' => META_FILTER_ANY,
  337. ),
  338. );
  339. $url_link_parameters['verify'] = FILTER_PROPERTY_REPORTER_ID . '=' . $t_current_user_id . '&' . FILTER_PROPERTY_STATUS . '=' . $t_bug_resolved_status_threshold;
  340. $c_filter['my_comments'] = array(
  341. FILTER_PROPERTY_CATEGORY_ID => Array(
  342. '0' => META_FILTER_ANY,
  343. ),
  344. FILTER_PROPERTY_SEVERITY => Array(
  345. '0' => META_FILTER_ANY,
  346. ),
  347. FILTER_PROPERTY_STATUS => Array(
  348. '0' => META_FILTER_ANY,
  349. ),
  350. FILTER_PROPERTY_HIGHLIGHT_CHANGED => $t_default_show_changed,
  351. FILTER_PROPERTY_REPORTER_ID => Array(
  352. '0' => META_FILTER_ANY,
  353. ),
  354. FILTER_PROPERTY_HANDLER_ID => Array(
  355. '0' => META_FILTER_ANY,
  356. ),
  357. FILTER_PROPERTY_RESOLUTION => Array(
  358. '0' => META_FILTER_ANY,
  359. ),
  360. FILTER_PROPERTY_BUILD => Array(
  361. '0' => META_FILTER_ANY,
  362. ),
  363. FILTER_PROPERTY_VERSION => Array(
  364. '0' => META_FILTER_ANY,
  365. ),
  366. FILTER_PROPERTY_HIDE_STATUS => Array(
  367. '0' => $t_hide_status_default,
  368. ),
  369. FILTER_PROPERTY_MONITOR_USER_ID => Array(
  370. '0' => META_FILTER_ANY,
  371. ),
  372. FILTER_PROPERTY_NOTE_USER_ID=> Array(
  373. '0' => META_FILTER_MYSELF,
  374. ),
  375. );
  376. $url_link_parameters['my_comments'] = FILTER_PROPERTY_NOTE_USER_ID. '=' . META_FILTER_MYSELF . '&' . FILTER_PROPERTY_HIDE_STATUS . '=' . $t_hide_status_default;
  377. $rows = filter_get_bug_rows( $f_page_number, $t_per_page, $t_page_count, $t_bug_count, $c_filter[$t_box_title] );
  378. # Improve performance by caching category data in one pass
  379. if( helper_get_current_project() == 0 ) {
  380. $t_categories = array();
  381. foreach( $rows as $t_row ) {
  382. $t_categories[] = $t_row->category_id;
  383. }
  384. category_cache_array_rows( array_unique( $t_categories ) );
  385. }
  386. $t_filter = array_merge( $c_filter[$t_box_title], $t_filter );
  387. $box_title = lang_get( 'my_view_title_' . $t_box_title );
  388. # -- ====================== BUG LIST ========================= --
  389. ?>
  390. <table class="width100 my-buglist" cellspacing="1">
  391. <?php
  392. # -- Navigation header row --?>
  393. <thead>
  394. <tr class="my-buglist-nav">
  395. <?php
  396. # -- Viewing range info --?>
  397. <td class="form-title" colspan="2">
  398. <?php
  399. print_link( 'view_all_set.php?type=1&temporary=y&' . $url_link_parameters[$t_box_title], $box_title, false, 'subtle' );
  400. if( count( $rows ) > 0 ) {
  401. $v_start = $t_filter[FILTER_PROPERTY_ISSUES_PER_PAGE] * ( $f_page_number - 1 ) + 1;
  402. $v_end = $v_start + count( $rows ) - 1;
  403. }
  404. else {
  405. $v_start = 0;
  406. $v_end = 0;
  407. }
  408. echo "<span class=\"my-buglist-count\">($v_start - $v_end / $t_bug_count)</span>";
  409. ?>
  410. </td>
  411. </tr>
  412. </thead><tbody>
  413. <?php
  414. # -- Loop over bug rows and create $v_* variables --
  415. $t_count = count( $rows );
  416. for( $i = 0;$i < $t_count; $i++ ) {
  417. $t_bug = $rows[$i];
  418. $t_summary = string_display_line_links( $t_bug->summary );
  419. $t_last_updated = date( config_get( 'normal_date_format' ), $t_bug->last_updated );
  420. # choose color based on status
  421. $status_color = get_status_color( $t_bug->status );
  422. # Check for attachments
  423. $t_attachment_count = 0;
  424. if(( file_can_view_bug_attachments( $t_bug->id ) ) ) {
  425. $t_attachment_count = file_bug_attachment_count( $t_bug->id );
  426. }
  427. # grab the project name
  428. $project_name = project_get_field( $t_bug->project_id, 'name' );
  429. if ( VS_PRIVATE == $t_bug->view_state ) {
  430. $t_bug_class = 'my-buglist-private';
  431. } else {
  432. $t_bug_class = '';
  433. }
  434. ?>
  435. <tr class="my-buglist-bug <?php echo $t_bug_class?>" bgcolor="<?php echo $status_color?>">
  436. <?php
  437. # -- Bug ID and details link + Pencil shortcut --?>
  438. <td class="center my-buglist-id" valign="top" width ="0" nowrap="nowrap">
  439. <span class="small">
  440. <?php
  441. print_bug_link( $t_bug->id );
  442. echo '<br />';
  443. if( !bug_is_readonly( $t_bug->id ) && access_has_bug_level( $t_update_bug_threshold, $t_bug->id ) ) {
  444. echo '<a class="edit" href="' . string_get_bug_update_url( $t_bug->id ) . '"><img border="0" src="' . $t_icon_path . 'update.png' . '" alt="' . lang_get( 'update_bug_button' ) . '" /></a>';
  445. }
  446. if( ON == config_get( 'show_priority_text' ) ) {
  447. print_formatted_priority_string( $t_bug->status, $t_bug->priority );
  448. } else {
  449. print_status_icon( $t_bug->priority );
  450. }
  451. if ( $t_attachment_count > 0 ) {
  452. $t_href = string_get_bug_view_url( $t_bug->id ) . '#attachments';
  453. $t_href_title = sprintf( lang_get( 'view_attachments_for_issue' ), $t_attachment_count, $t_bug->id );
  454. $t_alt_text = $t_attachment_count . lang_get( 'word_separator' ) . lang_get( 'attachments' );
  455. echo "<a class=\"attachments\" href=\"$t_href\" title=\"$t_href_title\"><img src=\"${t_icon_path}attachment.png\" alt=\"$t_alt_text\" title=\"$t_alt_text\" /></a>";
  456. }
  457. if( VS_PRIVATE == $t_bug->view_state ) {
  458. echo '<img src="' . $t_icon_path . 'protected.gif" width="8" height="15" alt="' . lang_get( 'private' ) . '" />';
  459. }
  460. ?>
  461. </span>
  462. </td>
  463. <?php
  464. # -- Summary --?>
  465. <td class="left my-buglist-description" valign="top" width="100%">
  466. <?php
  467. if( ON == config_get( 'show_bug_project_links' ) && helper_get_current_project() != $t_bug->project_id ) {
  468. echo '<span class="small project">[', string_display_line( project_get_name( $t_bug->project_id ) ), '] </span>';
  469. }
  470. $t_bug_url = string_get_bug_view_url( $t_bug->id, null );
  471. $t_bug_url_title = string_html_specialchars( sprintf( lang_get( 'label' ), lang_get( 'issue_id' ) . $t_bug->id ) . lang_get( 'word_separator' ) . $t_bug->summary );
  472. echo "<span class=\"small summary\"><a href=\"$t_bug_url\" title=\"$t_bug_url_title\">$t_summary</a></span><br />";
  473. ?>
  474. <?php
  475. # type project name if viewing 'all projects' or bug is in subproject
  476. echo '<span class="small category">', string_display_line( category_full_name( $t_bug->category_id, true, $t_bug->project_id ) ), '</span>';
  477. echo '<span class="small last-modified"> - ';
  478. if( $t_bug->last_updated > strtotime( '-' . $t_filter[FILTER_PROPERTY_HIGHLIGHT_CHANGED] . ' hours' ) ) {
  479. echo '<b>' . $t_last_updated . '</b>';
  480. } else {
  481. echo $t_last_updated;
  482. }
  483. echo '</span>';
  484. ?>
  485. </td>
  486. </tr>
  487. <?php
  488. # -- end of Repeating bug row --
  489. }
  490. # -- ====================== end of BUG LIST ========================= --
  491. ?>
  492. </tbody>
  493. </table>
  494. <?php
  495. // Free the memory allocated for the rows in this box since it is not longer needed.
  496. unset( $rows );