1<?php 2 3# Copyright (c) 2012 John Reese 4# Licensed under the MIT license 5 6/** 7 * Display a list of changeset objects in tabular format. 8 * Assumes that a table with four columns has already been defined. 9 * @param array Changeset objects 10 * @param array Repository objects 11 */ 12function Source_View_Changesets( $p_changesets, $p_repos=null, $p_show_repos=true ) { 13 if ( !is_array( $p_changesets ) ) { 14 return; 15 } 16 17 plugin_push_current( 'Source' ); 18 $t_can_update = access_has_global_level( plugin_config_get( 'update_threshold' ) ); 19 plugin_pop_current(); 20 21 if ( is_null( $p_repos ) || !is_array( $p_repos ) ) { 22 $t_repos = SourceRepo::load_by_changesets( $p_changesets ); 23 } else { 24 $t_repos = $p_repos; 25 } 26 27 $t_use_porting = config_get( 'plugin_Source_enable_porting' ); 28 29 foreach( $p_changesets as $t_changeset ) { 30 $t_repo = $t_repos[ $t_changeset->repo_id ]; 31 $t_vcs = SourceVCS::repo( $t_repo ); 32 33 $t_changeset->load_bugs(); 34 $t_changeset->load_files(); 35 36 bug_cache_array_rows( $t_changeset->bugs ); 37 38 $t_author = Source_View_Author( $t_changeset, false ); 39 $t_committer = Source_View_Committer( $t_changeset, false ); 40 ?> 41 42<tr> 43 44<td class="category" width="25%" rowspan="<?php echo count( $t_changeset->files ) + 1 ?>"> 45 <a id="<?php echo $t_changeset->revision; ?>"></a> 46 <p class="no-margin" name="changeset<?php echo $t_changeset->id ?>"><?php echo string_display( 47 ( $p_show_repos ? $t_repo->name . ': ' : '' ) . 48 $t_vcs->show_changeset( $t_repo, $t_changeset ) 49 ) ?></p> 50 <p class="no-margin small lighter"> 51 <i class="fa fa-clock-o grey"></i> <?php echo string_display_line( $t_changeset->timestamp ) ?> 52 </p> 53 <p class="no-margin lighter"> 54 <i class="fa fa-user grey"></i> <?php echo $t_author ?></a> 55 </p> 56 <?php if ( $t_committer && $t_committer != $t_author ) { ?><br/><span class="small"><?php echo plugin_lang_get( 'committer', 'Source' ), ': ', $t_committer ?></span><?php } ?> 57 <?php if ( $t_use_porting ) { ?> 58 <p class="no-margin small lighter"><?php echo plugin_lang_get( 'ported', 'Source' ), ': ', 59 ( $t_changeset->ported ? string_display_line( $t_changeset->ported ) : 60 ( is_null( $t_changeset->ported ) ? plugin_lang_get( 'pending', 'Source' ) : plugin_lang_get( 'na', 'Source' ) ) ) ?> 61 </p> 62 <?php } ?> 63 <a class="btn btn-xs btn-primary btn-white btn-round" href="<?php echo plugin_page( 'view', false, 'Source' ) . '&id=' . $t_changeset->id ?>"> 64 <?php echo plugin_lang_get( 'details', 'Source' ) ?> 65 </a> 66 <?php 67 if ( $t_url = $t_vcs->url_changeset( $t_repo, $t_changeset ) ) { ?> 68 <a class="btn btn-xs btn-primary btn-white btn-round" href="<?php echo $t_url ?>"> 69 <?php echo plugin_lang_get( 'diff', 'Source' ) ?> 70 </a> 71 <?php } 72 ?> 73</td> 74 75<?php 76 # Build list of related issues the user has access to, with link 77 $t_view_bug_threshold = config_get('view_bug_threshold'); 78 $t_bugs = array_map( 79 'string_get_bug_view_link', 80 array_filter( 81 $t_changeset->bugs, 82 function( $p_bug_id ) use ( $t_view_bug_threshold ) { 83 return bug_exists( $p_bug_id ) 84 && access_has_bug_level( $t_view_bug_threshold, $p_bug_id ); 85 } 86 ) 87 ); 88?> 89<td colspan=2><?php 90 # The commit message is manually transformed (adding href, bug and bugnote 91 # links + nl2br) instead of calling string_display_links(), which avoids 92 # unwanted html tags processing by the MantisCoreFormatting plugin. 93 # Rationale: commit messages being plain text, any html they may contain 94 # should not be considered as formatting and must be displayed as-is. 95 echo string_nl2br( 96 string_process_bugnote_link( 97 string_process_bug_link( 98 string_insert_hrefs( 99 string_html_specialchars( $t_changeset->message ) 100 ) ) ) ); 101 ?> 102</td> 103<td> 104<?php 105 if( $t_bugs ) { 106 echo '<span class="bold">', 107 plugin_lang_get( 'affected_issues', 'Source' ), 108 '</span><br>'; 109 echo '<span>', implode( ', ', $t_bugs ), '</span>'; 110 } elseif( $t_can_update ) { 111?> 112 <form action="<?php echo plugin_page( 'attach' ) ?>" method="post"> 113 <?php echo form_security_field( 'plugin_Source_attach' ) ?> 114 <input type="hidden" name="id" value="<?php echo $t_changeset->id ?>"/> 115 <input type="hidden" name="redirect" value="<?php echo $t_changeset->revision ?>"/> 116 <?php echo plugin_lang_get( 'attach_to_issue' ) ?><br> 117 <input type="text" class="input-sm" name="bug_ids" size="12"/> 118 <input type="submit" 119 class="btn btn-sm btn-primary btn-white btn-round" 120 value="<?php echo plugin_lang_get( 'attach' ) ?>" /> 121 </form> 122<?php 123 } 124?> 125</td> 126</tr> 127 128 <?php foreach ( $t_changeset->files as $t_file ) { ?> 129<tr> 130<td class="small" colspan="2"><?php echo string_display_line( $t_vcs->show_file( $t_repo, $t_changeset, $t_file ) ) ?></td> 131<td class="center" width="15%"> 132 <?php 133 if ( $t_url = $t_vcs->url_diff( $t_repo, $t_changeset, $t_file ) ) { ?> 134 <a class="btn btn-xs btn-primary btn-white btn-round" href="<?php echo $t_url ?>"> 135 <?php echo plugin_lang_get( 'diff', 'Source' ) ?> 136 </a> 137 <?php } 138 if ( $t_url = $t_vcs->url_file( $t_repo, $t_changeset, $t_file ) ) { ?> 139 <a class="btn btn-xs btn-primary btn-white btn-round" href="<?php echo $t_url ?>"> 140 <?php echo plugin_lang_get( 'file', 'Source' ) ?> 141 </a> 142 <?php } 143 ?></td> 144</tr> 145 <?php } ?> 146 <?php 147 } 148} 149 150/** 151 * Display the author information for a changeset. 152 * @param object Changeset object 153 * @param boolean Echo information 154 */ 155function Source_View_Author( $p_changeset, $p_echo=true ) { 156 $t_author_name = !is_blank( $p_changeset->author ) ? string_display_line( $p_changeset->author ) : false; 157 $t_author_email = !is_blank( $p_changeset->author_email ) ? string_display_line( $p_changeset->author_email ) : false; 158 $t_author_username = $p_changeset->user_id > 0 ? prepare_user_name( $p_changeset->user_id ) : false; 159 160 if ( $t_author_username ) { 161 $t_output = $t_author_username; 162 163 } else if ( $t_author_name ) { 164 $t_output = $t_author_name; 165 166 } else { 167 $t_output = $t_author_email; 168 } 169 170 if ( $p_echo ) { 171 echo $t_output; 172 } else { 173 return $t_output; 174 } 175} 176 177/** 178 * Display the committer information for a changeset. 179 * @param object Changeset object 180 * @param boolean Echo information 181 */ 182function Source_View_Committer( $p_changeset, $p_echo=true ) { 183 $t_committer_name = !is_blank( $p_changeset->committer ) ? string_display_line( $p_changeset->committer ) : false; 184 $t_committer_email = !is_blank( $p_changeset->committer_email ) ? string_display_line( $p_changeset->committer_email ) : false; 185 $t_committer_username = $p_changeset->committer_id > 0 ? prepare_user_name( $p_changeset->committer_id ) : false; 186 187 if ( $t_committer_username ) { 188 $t_output = $t_committer_username; 189 190 } else if ( $t_committer_name ) { 191 $t_output = $t_committer_name; 192 193 } else { 194 $t_output = $t_committer_email; 195 } 196 197 if ( $p_echo ) { 198 echo $t_output; 199 } else { 200 return $t_output; 201 } 202} 203 204/** 205 * Display pagination links for changesets 206 * @param string $p_link URL to target page 207 * @param int $p_count Total number of changesets 208 * @param int $p_current Current page number 209 * @param int $p_perpage Number of changesets per page 210 */ 211function Source_View_Pagination( $p_link, $p_current, $p_count, $p_perpage = 25 ) { 212 if( $p_count > $p_perpage ) { 213 214 $t_pages = ceil( $p_count / $p_perpage ); 215 $t_block = max( 5, min( round( $t_pages / 10, -1 ), ceil( $t_pages / 6 ) ) ); 216 $t_page_set = array(); 217 218 $p_link .= '&offset='; 219 220 $t_page_link = function( $p_page, $p_text = null ) use( $p_current, $p_link ) { 221 if( is_null( $p_text ) ) { 222 $p_text = $p_page; 223 } 224 if( is_null( $p_page ) ) { 225 return '...'; 226 } elseif( $p_page == $p_current ) { 227 return "<strong>$p_page</strong>"; 228 } else { 229 $page_button = '<a class="btn btn-xs btn-primary btn-white btn-round" href="'. $p_link . $p_page .'">'.$p_text.'</a>'; 230 return $page_button; 231 } 232 }; 233 234 if( $t_pages > 15 ) { 235 $t_used_page = false; 236 $t_pages_per_block = 3; 237 for( $i = 1; $i <= $t_pages; $i++ ) { 238 if( $i <= $t_pages_per_block 239 || $i > $t_pages - $t_pages_per_block 240 || ( $i >= $p_current - $t_pages_per_block && $i <= $p_current + $t_pages_per_block ) 241 || $i % $t_block == 0) 242 { 243 $t_page_set[] = $i; 244 $t_used_page = true; 245 } else if( $t_used_page ) { 246 $t_page_set[] = null; 247 $t_used_page = false; 248 } 249 } 250 251 } else { 252 $t_page_set = range( 1, $t_pages ); 253 } 254 255 if( $p_current > 1 ) { 256 echo ' ', $t_page_link( 1, lang_get( 'first' ) ); 257 echo ' ', $t_page_link( $p_current - 1, lang_get( 'prev' ) ); 258 echo ' '; 259 } 260 261 $t_page_set = array_map( $t_page_link, $t_page_set ); 262 echo join( ' ', $t_page_set ); 263 264 if( $p_current < $t_pages ) { 265 echo ' ', $t_page_link( $p_current + 1, lang_get( 'next' ) ); 266 echo ' ', $t_page_link( $t_pages, lang_get( 'last' ) ); 267 } 268 } 269} 270