PageRenderTime 90ms CodeModel.GetById 20ms app.highlight 37ms RepoModel.GetById 13ms app.codeStats 1ms

/wp-content/plugins/broken-link-checker/includes/admin/table-printer.php

https://bitbucket.org/lgorence/quickpress
PHP | 761 lines | 518 code | 106 blank | 137 comment | 69 complexity | 4ea160f57695f8e7c28066238b7ef732 MD5 | raw file
  1<?php
  2
  3if ( !class_exists('blcTablePrinter') ) {
  4
  5/**
  6 * Utility class for printing the link listing table.
  7 * 
  8 * @package Broken Link Checker
  9 * @access public
 10 */
 11class blcTablePrinter {
 12	
 13	var $current_filter;       //The current search filter. Also contains the list of links to display. 
 14	var $page;                 //The current page number
 15	var $per_page;             //Max links per page
 16	/** @var wsBrokenLinkChecker */
 17	var $core;                 //A reference to the main plugin object
 18	var $neutral_current_url;  //The "safe" version of the current URL, for use in the bulk action form.
 19	
 20	var $bulk_actions_html = '';
 21	var $pagination_html = '';
 22	var $searched_link_type = '';
 23	
 24	var $columns;
 25	var $layouts;
 26	
 27	
 28	function blcTablePrinter($core){
 29		$this->core = $core;
 30		
 31		//Initialize layout and column definitions
 32		$this->setup_columns();
 33		$this->setup_layouts();
 34		
 35		//Figure out what the "safe" URL to acccess the current page would be.
 36		//This is used by the bulk action form. 
 37		$special_args = array('_wpnonce', '_wp_http_referer', 'action', 'selected_links');
 38		$this->neutral_current_url = remove_query_arg($special_args);				
 39	}
 40	
 41	
 42	/**
 43	 * Print the entire link table and associated navigation elements.
 44	 * 
 45	 * @param array $current_filter
 46	 * @param string $layout
 47	 * @param array $visible_columns
 48	 * @param bool $compact
 49	 * @return void
 50	 */
 51	function print_table($current_filter, $layout = 'flexible', $visible_columns = null, $compact = false){
 52		$this->current_filter = $current_filter;
 53		$this->page = $current_filter['page'];
 54		$this->per_page = $current_filter['per_page'];
 55
 56		$current_layout = $this->layouts[$layout];
 57		if ( empty($visible_columns) ){
 58			$visible_columns = $current_layout;
 59		}
 60		//Only allow columns actually present in this layout
 61		$visible_columns = array_intersect($visible_columns, $current_layout);
 62		
 63		echo '<form id="blc-bulk-action-form" action="', $this->neutral_current_url, '" method="post">';
 64		wp_nonce_field('bulk-action');
 65		
 66		//Top navigation
 67		$this->prepare_nav_html();
 68		$this->navigation($compact);
 69		
 70		//Table header
 71		$table_classes = array('widefat');
 72		if ( $compact ) { 
 73			$table_classes[] = 'compact'; 
 74		};
 75		if ( $this->core->conf->options['table_color_code_status'] ) { 
 76			$table_classes[] = 'color-code-link-status'; 
 77		};
 78		$table_classes[] = 'base-filter-' . $current_filter['base_filter'];
 79		printf(
 80			'<table class="%s" id="blc-links"><thead><tr>',
 81			implode(' ', $table_classes)
 82		);
 83		
 84		//The select-all checkbox
 85		echo '<th scope="col" class="column-checkbox check-column" id="cb"><input type="checkbox" /></th>';
 86		
 87		//Column headers
 88		foreach($current_layout as $column_id){
 89			$column = $this->columns[$column_id];
 90			
 91			$column_classes = array('column-'.$column_id);
 92			if ( isset($column['class']) ){
 93				$column_classes[] = $column['class'];
 94			}
 95			if ( !in_array($column_id, $visible_columns) ) {
 96				$column_classes[] = 'hidden';
 97			}
 98
 99			$heading = $column['heading'];
100			if ( isset($column['sortable']) && $column['sortable'] ) {
101				$orderby = $column['orderby'];
102				$current_orderby = isset($_GET['orderby']) ? $_GET['orderby'] : '';
103				$current_order = isset($_GET['order']) ? $_GET['order'] : 'asc';
104
105				if ( $orderby == $current_orderby ) {
106					$column_classes[] = 'sorted';
107					$column_classes[] = $current_order;
108					$order = ($current_order == 'asc') ? 'desc' : 'asc'; //Reverse the sort direction
109				} else {
110					$order = 'asc';
111					$column_classes[] = 'desc';
112					$column_classes[] = 'sortable';
113				}
114
115				$heading = sprintf(
116					'<a href="%s"><span>%s</span><span class="sorting-indicator"></span></a>',
117					add_query_arg(array(
118						'orderby' => $orderby,
119						'order' => $order,
120					)),
121					$heading
122				);
123			}
124
125			printf(
126				'<th scope="col" class="%s"%s>%s</th>',
127				implode(' ', $column_classes),
128				isset($column['id']) ? ' id="' . $column['id'] . '"' : '',
129				$heading
130			);
131		}
132		echo '</tr></thead>';
133		
134		//Table body
135		echo '<tbody id="the-list">';
136		$this->bulk_edit_form($visible_columns);
137		$rownum = 0;
138        foreach ($this->current_filter['links'] as $link) {
139        	$rownum++;
140        	$this->link_row($link, $current_layout, $visible_columns, $rownum);
141        	$this->link_details_row($link, $visible_columns, $rownum);
142       	}
143		echo '</tbody></table>';
144						
145		//Bottom navigation				
146		$this->navigation($compact, '2');
147		echo '</form>';
148	}
149	
150	/**
151	 * Print the "Bulk Actions" dropdown and navigation links
152	 *
153	 * @param bool $table_compact Whether to use the full or compact view.
154	 * @param string $suffix Optional. Appended to ID and name attributes of the bulk action dropdown. 
155	 * @return void
156	 */
157	function navigation($table_compact = false, $suffix = ''){
158		//Display the "Bulk Actions" dropdown
159		echo '<div class="tablenav">',
160				'<div class="alignleft actions">',
161					'<select name="action', $suffix ,'" id="blc-bulk-action', $suffix ,'">',
162						$this->bulk_actions_html,
163					'</select>',
164				' <input type="submit" name="doaction', $suffix ,'" id="doaction',$suffix,'" value="', 
165					esc_attr(__('Apply', 'broken-link-checker')),
166					'" class="button-secondary action">',
167				'</div>';
168	
169		//Display pagination links 
170		if ( !empty($this->pagination_html) ){
171			echo $this->pagination_html;
172		}
173		
174		//Display the view switch (only in the top nav. area)
175		if ( empty($suffix) ){		
176		?>
177		
178		<div class="view-switch">
179			<a href="<?php echo esc_url(add_query_arg('compact', '1', $_SERVER['REQUEST_URI'])) ?>"><img <?php if ( $table_compact ) echo 'class="current"'; ?> id="view-switch-list" src="<?php echo esc_url( includes_url( 'images/blank.gif' ) ); ?>" width="20" height="20" title="<?php _e('Compact View', 'broken-link-checker') ?>" alt="<?php _e('Compact View', 'broken-link-checker') ?>" /></a>
180			<a href="<?php echo esc_url(add_query_arg('compact', '0', $_SERVER['REQUEST_URI'])) ?>"><img <?php if ( !$table_compact ) echo 'class="current"'; ?> id="view-switch-excerpt" src="<?php echo esc_url( includes_url( 'images/blank.gif' ) ); ?>" width="20" height="20" title="<?php _e('Detailed View', 'broken-link-checker') ?>" alt="<?php _e('Detailed View', 'broken-link-checker') ?>" /></a>
181		</div>
182		
183		<?php
184		}
185		
186		echo '</div>';
187	}
188	
189	/**
190	 * Initialize the internal list of available table columns.
191	 * 
192	 * @return void
193	 */
194	function setup_columns(){
195		$this->columns = array(
196			'status' => array(
197				'heading' => __('Status', 'broken-link-checker'),
198				'content' => array($this, 'column_status'),
199			),
200			
201			'new-url' => array(
202		 		'heading' => __('URL', 'broken-link-checker'),
203		 		'content' => array($this, 'column_new_url'),
204				'sortable' => true,
205				'orderby' => 'url',
206			),
207			
208			'used-in' => array(
209				'heading' => __('Source', 'broken-link-checker'),
210				'class' => 'column-title',
211				'content' => array($this, 'column_used_in'),
212			),
213			
214			'new-link-text' => array(
215				'heading' => __('Link Text', 'broken-link-checker'),
216				'content' => array($this, 'column_new_link_text'),
217			),
218
219			'redirect-url' => array(
220				'heading' => __('Redirect URL', 'broken-link-checker'),
221				'content' => array($this, 'column_redirect_url'),
222			),
223		);
224	}
225	
226	/**
227	 * Initialize the list of available layouts
228	 * 
229	 * @return void
230	 */
231	function setup_layouts(){
232		$this->layouts = array(
233			'classic' =>  array('used-in', 'new-link-text', 'new-url'),
234			'flexible' => array('new-url', 'status', 'new-link-text', 'redirect-url', 'used-in', ),
235		);
236	}
237	
238	/**
239	 * Get a list of columns available in a specific table layout.
240	 * 
241	 * @param string $layout Layout ID.
242	 * @return array Associative array of column data indexed by column ID.
243	 */
244	function get_layout_columns($layout){
245		if ( isset($this->layouts[$layout]) ){
246			
247			$result = array();
248			foreach($this->layouts[$layout] as $column_id){
249				if ( isset($this->columns[$column_id]) )
250					$result[$column_id] = $this->columns[$column_id];
251			}
252			return $result;		
253				
254		} else {
255			return null;
256		}
257	}
258	
259	/**
260	 * Pre-generate some HTML fragments used for both the top and bottom navigation/bulk action boxes. 
261	 * 
262	 * @return void
263	 */
264	function prepare_nav_html(){
265		//Generate an <option> element for each possible bulk action. The list doesn't change,
266		//so we can do it once and reuse the generated HTML.
267		$bulk_actions = array(
268			'-1' => __('Bulk Actions', 'broken-link-checker'),
269			"bulk-edit" => __('Edit URL', 'broken-link-checker'),
270			"bulk-recheck" => __('Recheck', 'broken-link-checker'),
271			"bulk-deredirect" => __('Fix redirects', 'broken-link-checker'),
272			"bulk-not-broken" => __('Mark as not broken', 'broken-link-checker'),
273			"bulk-unlink" => __('Unlink', 'broken-link-checker'),
274		);
275		if ( EMPTY_TRASH_DAYS ){
276			$bulk_actions["bulk-trash-sources"] = __('Move sources to Trash', 'broken-link-checker');
277		} else {
278			$bulk_actions["bulk-delete-sources"] = __('Delete sources', 'broken-link-checker');
279		}
280		
281		$bulk_actions_html = '';
282		foreach($bulk_actions as $value => $name){
283			$bulk_actions_html .= sprintf('<option value="%s">%s</option>', $value, $name);
284		}
285		
286		$this->bulk_actions_html = $bulk_actions_html;
287		
288		//Pagination links can also be pre-generated.
289		//WP has a built-in function for pagination :)
290		$page_links = paginate_links( array(
291			'base' => add_query_arg( 'paged', '%#%' ),
292			'format' => '',
293			'prev_text' => __('&laquo;'),
294			'next_text' => __('&raquo;'),
295			'total' => $this->current_filter['max_pages'],
296			'current' => $this->page
297		));
298		
299		if ( $page_links ) {
300			$this->pagination_html = '<div class="tablenav-pages">';
301			$this->pagination_html .= sprintf( 
302				'<span class="displaying-num">' . __( 'Displaying %s&#8211;%s of <span class="current-link-count">%s</span>', 'broken-link-checker' ) . '</span>%s',
303				number_format_i18n( ( $this->page - 1 ) * $this->per_page + 1 ),
304				number_format_i18n( min( $this->page * $this->per_page, $this->current_filter['count'] ) ),
305				number_format_i18n( $this->current_filter['count'] ),
306				$page_links
307			); 
308			$this->pagination_html .= '</div>';
309		} else {
310			$this->pagination_html = '';
311		}
312	}
313	
314	/**
315	 * Print the bulk edit form.
316	 * 
317	 * @param array $visible_columns List of visible columns.
318	 * @return void
319	 */
320	function bulk_edit_form($visible_columns){
321		?>
322		<tr id="bulk-edit" class="inline-edit-rows"><td colspan="<?php echo count($visible_columns)+1; ?>">
323		<div id="bulk-edit-wrap">
324		<fieldset>
325			<h4><?php _e('Bulk Edit URLs'); ?></h4>
326			<label>
327				<span class="title"><?php _e('Find', 'broken-link-checker'); ?></span>
328				<input type="text" name="search" class="text">
329			</label>
330			<label>
331				<span class="title"><?php _e('Replace with', 'broken-link-checker'); ?></span>
332				<input type="text" name="replace" class="text">
333			</label>
334			
335			<div id="bulk-edit-options">
336				<span class="title">&nbsp;</span>
337				<label>
338					<input type="checkbox" name="case_sensitive">
339					<?php _e('Case sensitive', 'broken-link-checker'); ?>
340				</label>
341				<label>
342					<input type="checkbox" name="regex">
343					<?php _e('Regular expression', 'broken-link-checker'); ?>
344				</label>
345			</div>
346		</fieldset>			
347		
348		<p class="submit inline-edit-save">
349			<a href="#bulk-edit" class="button-secondary cancel alignleft" title="<?php echo esc_attr(__('Cancel', 'broken-link-checker')); ?>" accesskey="c"><?php _e('Cancel', 'broken-link-checker'); ?></a>
350			<input type="submit" name="bulk_edit" class="button-primary alignright" value="<?php 
351				_e('Update', 'broken-link-checker'); 
352			?>" accesskey="s">
353		</p>
354		</div>
355		</td></tr>
356		<?php	
357	}
358	
359	/**
360	 * Print the link row.
361	 * 
362	 * @param blcLink $link The link to display.
363	 * @param array $layout List of columns to output.
364	 * @param array $visible_columns List of visible columns.
365	 * @param integer $rownum Table row number.
366	 * @return void
367	 */
368	function link_row($link, $layout, $visible_columns, $rownum = 0){
369		
370		//Figure out what CSS classes the link row should have
371		$rowclass = ($rownum % 2)? 'alternate' : '';
372		
373    	$excluded = $this->core->is_excluded( $link->url ); 
374    	if ( $excluded ) $rowclass .= ' blc-excluded-link';
375    	
376    	if ( $link->redirect_count > 0){
377			$rowclass .= ' blc-redirect';
378		}
379    	
380    	$days_broken = 0;
381    	if ( $link->broken ){
382			//Add a highlight to broken links that appear to be permanently broken
383			$days_broken = intval( (time() - $link->first_failure) / (3600*24) );
384			if ( $days_broken >= $this->core->conf->options['failure_duration_threshold'] ){
385				$rowclass .= ' blc-permanently-broken';
386				if ( $this->core->conf->options['highlight_permanent_failures'] ){
387					$rowclass .= ' blc-permanently-broken-hl';
388				}
389			}
390		}
391		
392		$status = $link->analyse_status();
393		$rowclass .= ' link-status-' . $status['code'];
394		
395		//Retrieve link instances to display in the table
396		$instances = $link->get_instances();
397		
398		if ( !empty($instances) ){
399			//Put instances that match the selected link type at the top. Makes search results look better. 
400			if ( !empty($this->current_filter['search_params']['s_link_type']) ){
401				$s_link_type = $this->current_filter['search_params']['s_link_type'];
402			} else {
403				$s_link_type = '';
404			}
405			$instances = $this->sort_instances_for_display($instances, $s_link_type);
406		}
407		
408		printf(
409			'<tr id="blc-row-%s" class="blc-row %s" data-days-broken="%d">',
410			 $link->link_id,
411			 $rowclass,
412			 $days_broken
413		);
414		
415		//The checkbox used to select links is automatically printed in all layouts 
416		//and can't be disabled. Without it, bulk actions wouldn't work.
417		$this->column_checkbox($link);
418		
419		foreach($layout as $column_id){
420			$column = $this->columns[$column_id];
421			
422			printf(
423				'<td class="column-%s%s">',
424				$column_id,
425				in_array($column_id, $visible_columns) ? '' : ' hidden'
426			);						
427			
428			if ( isset($column['content']) ){
429				if ( is_callable($column['content']) ){
430					call_user_func($column['content'], $link, $instances);
431				} else {
432					echo $column['content'];
433				}
434			} else {
435				echo '[', $column_id, ']';
436			}
437			
438			echo '</td>';
439		}
440		
441		echo '</tr>';
442	} 
443	
444	/**
445	 * Print the details row for a specific link.
446	 * 
447	 * @uses blcTablePrinter::details_row_contents() 
448	 * 
449	 * @param object $link The link to display.
450	 * @param array $visible_columns List of visible columns.
451	 * @param integer $rownum Table row number.
452	 * @return void
453	 */
454	function link_details_row($link, $visible_columns, $rownum = 0){
455		printf(
456			'<tr id="link-details-%d" class="blc-link-details"><td colspan="%d">',
457			$link->link_id,
458			count($visible_columns)+1
459		);
460		$this->details_row_contents($link);
461		echo '</td></tr>';
462	}
463	
464	/**
465	 * Print the contents of the details row for a specific link.
466	 * 
467	 * @param blcLink $link
468	 * @return void
469	 */
470	public static function details_row_contents($link){
471		?>
472		<div class="blc-detail-container">
473			<div class="blc-detail-block" style="float: left; width: 49%;">
474		    	<ol style='list-style-type: none;'>
475		    	<?php if ( !empty($link->post_date) ) { ?>
476		    	<li><strong><?php _e('Post published on', 'broken-link-checker'); ?> :</strong>
477		    	<span class='post_date'><?php
478					echo date_i18n(get_option('date_format'),strtotime($link->post_date));
479		    	?></span></li>
480		    	<?php } ?>
481		    	<li><strong><?php _e('Link last checked', 'broken-link-checker'); ?> :</strong>
482		    	<span class='check_date'><?php
483					$last_check = $link->last_check;
484		    		if ( $last_check < strtotime('-10 years') ){
485						_e('Never', 'broken-link-checker');
486					} else {
487		    			echo date_i18n(get_option('date_format'), $last_check);
488		    		}
489		    	?></span></li>
490		    	
491		    	<li><strong><?php _e('HTTP code', 'broken-link-checker'); ?> :</strong>
492		    	<span class='http_code'><?php 
493		    		print $link->http_code; 
494		    	?></span></li>
495		    	
496		    	<li><strong><?php _e('Response time', 'broken-link-checker'); ?> :</strong>
497		    	<span class='request_duration'><?php 
498		    		printf( __('%2.3f seconds', 'broken-link-checker'), $link->request_duration); 
499		    	?></span></li>
500		    	
501		    	<li><strong><?php _e('Final URL', 'broken-link-checker'); ?> :</strong>
502		    	<span class='final_url'><?php 
503		    		print $link->final_url; 
504		    	?></span></li>
505		    	
506		    	<li><strong><?php _e('Redirect count', 'broken-link-checker'); ?> :</strong>
507		    	<span class='redirect_count'><?php 
508		    		print $link->redirect_count; 
509		    	?></span></li>
510		    	
511		    	<li><strong><?php _e('Instance count', 'broken-link-checker'); ?> :</strong>
512		    	<span class='instance_count'><?php 
513		    		print count($link->get_instances()); 
514		    	?></span></li>
515		    	
516		    	<?php if ( $link->broken && (intval( $link->check_count ) > 0) ){ ?>
517		    	<li><br/>
518				<?php 
519					printf(
520						_n('This link has failed %d time.', 'This link has failed %d times.', $link->check_count, 'broken-link-checker'),
521						$link->check_count
522					);
523					
524					echo '<br>';
525					
526					$delta = time() - $link->first_failure;
527					printf(
528						__('This link has been broken for %s.', 'broken-link-checker'),
529						blcUtility::fuzzy_delta($delta)
530					);
531				?>
532				</li>
533		    	<?php } ?>
534				</ol>
535			</div>
536			
537			<div class="blc-detail-block" style="float: right; width: 50%;">
538		    	<ol style='list-style-type: none;'>
539		    		<li><strong><?php _e('Log', 'broken-link-checker'); ?> :</strong>
540		    	<span class='blc_log'><?php 
541		    		print nl2br($link->log); 
542		    	?></span></li>
543				</ol>
544			</div>
545			
546			<div style="clear:both;"> </div>
547		</div>
548		<?php
549	}
550	
551	function column_checkbox($link){
552		?>
553		<th scope="row" class="check-column"><input type="checkbox" name="selected_links[]" value="<?php echo $link->link_id; ?>" /></th>
554		<?php
555	}
556
557	/**
558	 * @param blcLink $link
559	 * @param blcLinkInstance[] $instances
560	 */
561	function column_status($link, $instances){
562		printf(
563			'<table class="mini-status" title="%s">',
564			esc_attr(__('Show more info about this link', 'broken-link-checker'))
565		);
566		
567		$status = $link->analyse_status();
568		
569		printf(
570			'<tr class="link-status-row link-status-%s">
571				<td>
572					<span class="http-code">%s</span> <span class="status-text">%s</span>
573				</td>
574			</tr>',
575			$status['code'],
576			empty($link->http_code)?'':$link->http_code,
577			$status['text']
578		);
579		
580		//Last checked...
581		if ( $link->last_check != 0 ){
582			$last_check = _x('Checked', 'checked how long ago', 'broken-link-checker') . ' ';
583			$last_check .= blcUtility::fuzzy_delta(time() - $link->last_check, 'ago');
584			
585			printf(
586				'<tr class="link-last-checked"><td>%s</td></tr>',
587				$last_check
588			);
589		}
590		
591		
592		//Broken for...
593		if ( $link->broken ){
594			$delta = time() - $link->first_failure;
595			$broken_for = blcUtility::fuzzy_delta($delta);
596			printf(
597				'<tr class="link-broken-for"><td>%s %s</td></tr>',
598				__('Broken for', 'broken-link-checker'),
599				$broken_for
600			);
601		}
602		
603		echo '</table>';
604	}
605
606
607	/**
608	 * @param blcLink $link
609	 */
610	function column_new_url($link){
611		?>
612        <a href="<?php print esc_attr($link->url); ?>" target='_blank' class='blc-link-url' title="<?php echo esc_attr($link->url); ?>">
613        	<?php print $link->url; ?></a>
614        <input type='text' id='link-editor-<?php print $link->link_id; ?>' 
615        	value="<?php print esc_attr($link->url); ?>" 
616            class='blc-link-editor' style='display:none' />
617        <?php
618    	//Output inline action links for the link/URL                  	
619      	$actions = array();
620      	
621      	$actions['edit'] = "<span class='edit'><a href='javascript:void(0)' class='blc-edit-button' title='" . esc_attr( __('Edit link URL' , 'broken-link-checker') ) . "'>". __('Edit URL' , 'broken-link-checker') ."</a>";
622      	
623      	$actions['delete'] = "<span class='delete'><a class='submitdelete blc-unlink-button' title='" . esc_attr( __('Remove this link from all posts', 'broken-link-checker') ). "' ".
624			"href='javascript:void(0);'>" . __('Unlink', 'broken-link-checker') . "</a>";
625
626		if ( $link->broken ){
627			$actions['discard'] = sprintf(
628				'<span><a href="#" title="%s" class="blc-discard-button">%s</a>',
629				esc_attr(__('Remove this link from the list of broken links and mark it as valid', 'broken-link-checker')),
630				__('Not broken', 'broken-link-checker')
631			);
632		}
633
634		if ( !$link->dismissed && ($link->broken || ($link->redirect_count > 0)) ) {
635			$actions['dismiss'] = sprintf(
636				'<span><a href="#" title="%s" class="blc-dismiss-button">%s</a>',
637				esc_attr(__('Hide this link and do not report it again unless its status changes' , 'broken-link-checker')),
638				__('Dismiss', 'broken-link-checker')
639			);
640		} else if ( $link->dismissed ) {
641			$actions['undismiss'] = sprintf(
642				'<span><a href="#" title="%s" class="blc-undismiss-button">%s</a>',
643				esc_attr(__('Undismiss this link', 'broken-link-checker')),
644				__('Undismiss', 'broken-link-checker')
645			);
646		}
647
648		echo '<div class="row-actions">';
649		echo implode(' | </span>', $actions) .'</span>';
650		
651		echo "<span style='display:none' class='blc-cancel-button-container'> " .
652			 "| <a href='javascript:void(0)' class='blc-cancel-button' title='". esc_attr(__('Cancel URL editing' , 'broken-link-checker')) ."'>". __('Cancel' , 'broken-link-checker') ."</a></span>";
653
654		echo '</div>';
655		
656		?>
657		<div class="blc-url-editor-buttons">
658			<input type="button" class="button-secondary cancel alignleft blc-cancel-button" value="<?php echo esc_attr(__('Cancel', 'broken-link-checker')); ?>" />
659			<input type="button" class="button-primary save alignright blc-update-url-button" value="<?php echo esc_attr(__('Update URL', 'broken-link-checker')); ?>" />
660			<img class="waiting" style="display:none;" src="<?php echo esc_url( admin_url( 'images/wpspin_light.gif' ) ); ?>" alt="" />
661		</div>
662		<?php
663	}
664
665	/**
666	 * @param blcLink $link
667	 * @param blcLinkInstance[] $instances
668	 */
669	function column_used_in($link, $instances){
670		echo '<span class="blc-link-id" style="display:none;">',
671				$link->link_id,
672			 '</span>';
673				
674		if ( !empty($instances) ){
675			/** @var $instance blcLinkInstance */
676			$instance = reset($instances);
677			echo $instance->ui_get_source();
678			
679			$actions = $instance->ui_get_action_links();
680			
681			echo '<div class="row-actions">';
682			echo implode(' | </span>', $actions);
683			echo '</div>';
684			
685		} else {
686			_e("[An orphaned link! This is a bug.]", 'broken-link-checker');
687		}
688	}
689
690	/**
691	 * @param blcLink $link
692	 * @param blcLinkInstance[] $instances
693	 */
694	function column_new_link_text($link, $instances){
695		if ( empty($instances) ){
696			echo '<em>N/A</em>';
697		} else {
698			$instance = reset($instances); /** @var blcLinkInstance $instance */
699			echo $instance->ui_get_link_text();
700		}
701	}
702
703	function column_redirect_url($link, $instances) {
704		if ( $link->redirect_count > 0 ) {
705			printf(
706				'<a href="%1$s" target="_blank" class="blc-redirect-url" title="%1$s">%2$s</a>',
707				esc_attr($link->final_url),
708				esc_html($link->final_url)
709			);
710		}
711	}
712	
713	/**
714	 * Sort a list of link instances to be displayed in the "Broken Links" page.
715	 * 
716	 * Groups instances by container type and, if $search_link_type is specified,
717	 * puts instances that have a matching container type or parser type at the
718	 * beginning.
719	 * 
720	 * @param array $instances An array of blcLinkInstance objects.
721	 * @param string $searched_link_type Optional. The required container/parser type. 
722	 * @return array Sorted array.
723	 */
724	function sort_instances_for_display($instances, $searched_link_type = ''){
725		$this->searched_link_type = $searched_link_type;
726		usort($instances, array($this, 'compare_link_instances'));
727		return $instances;
728	}
729	
730	/**
731	 * Callback function for sorting link instances.
732	 * 
733	 * @see blcTablePrinter::sort_instances_for_display()
734	 * 
735	 * @param blcLinkInstance $a
736	 * @param blcLinkInstance $b
737	 * @return int
738	 */
739	function compare_link_instances($a, $b){
740		if ( !empty($this->searched_link_type) ){
741			if ( ($a->container_type == $this->searched_link_type) || ($a->parser_type == $this->searched_link_type) ){
742				if ( ($b->container_type == $this->searched_link_type) || ($b->parser_type == $this->searched_link_type) ){
743					return 0;
744				} else {
745					return -1;
746				}
747			} else {
748				if ( ($b->container_type == $this->searched_link_type) || ($b->parser_type == $this->searched_link_type) ){
749					return 1;
750				}
751			}
752		}
753		
754		return strcmp($a->container_type, $b->container_type);
755	}
756	
757}
758
759}//class_exists
760
761?>