'link',
'plural' => 'links',
'ajax' => false,
)
);
}
/**
* Reads a sanitized query arg.
*
* @param string $key Key.
* @return string
*/
public static function arg( $key ) {
// phpcs:ignore WordPress.Security.NonceVerification.Recommended -- Read-only list filters.
return isset( $_GET[ $key ] ) ? sanitize_text_field( wp_unslash( $_GET[ $key ] ) ) : '';
}
/**
* Columns.
*
* @return array
*/
public function get_columns() {
$columns = array(
'cb' => '',
'url' => __( 'URL', 'linktender' ),
'status' => __( 'Status', 'linktender' ),
'found_in' => __( 'Found in', 'linktender' ),
'last_checked' => __( 'Last checked', 'linktender' ),
);
/**
* Filters list table columns.
*
* @param array $columns Columns.
*/
return apply_filters( 'linktender_list_columns', $columns );
}
/**
* Sortable columns.
*
* @return array
*/
protected function get_sortable_columns() {
return array(
'url' => array( 'url', false ),
'status' => array( 'status', false ),
'last_checked' => array( 'last_checked', true ),
);
}
/**
* Views (status tabs).
*
* @return array
*/
protected function get_views() {
$current = self::arg( 'view' );
$current = '' === $current ? 'problems' : $current;
$labels = array(
'problems' => __( 'All problems', 'linktender' ),
'broken' => __( 'Broken', 'linktender' ),
'redirect' => __( 'Redirected', 'linktender' ),
'unverified' => __( 'Unverified', 'linktender' ),
'pending' => __( 'Not checked yet', 'linktender' ),
'ok' => __( 'OK', 'linktender' ),
'dismissed' => __( 'Marked as fine', 'linktender' ),
'all' => __( 'All links', 'linktender' ),
);
$views = array();
foreach ( $labels as $view => $label ) {
$url = add_query_arg(
array(
'page' => 'linktender',
'view' => $view,
),
admin_url( 'admin.php' )
);
$count = isset( $this->status_counts[ $view ] ) ? (int) $this->status_counts[ $view ] : 0;
$views[ $view ] = sprintf(
'%3$s (%4$s)',
esc_url( $url ),
$view === $current ? ' class="current" aria-current="page"' : '',
esc_html( $label ),
esc_html( number_format_i18n( $count ) )
);
}
return $views;
}
/**
* Bulk actions.
*
* @return array
*/
protected function get_bulk_actions() {
$actions = array(
'recheck' => __( 'Recheck', 'linktender' ),
'dismiss' => __( 'Mark as fine', 'linktender' ),
'undismiss' => __( 'Undo "mark as fine"', 'linktender' ),
'use_target' => __( 'Update redirects to final URL', 'linktender' ),
);
/**
* Filters bulk actions. Handle custom ones on the linktender_bulk_action action.
*
* @param array $actions Actions.
*/
return apply_filters( 'linktender_bulk_actions', $actions );
}
/**
* Filter dropdowns.
*
* @param string $which Top or bottom.
* @return void
*/
protected function extra_tablenav( $which ) {
if ( 'top' !== $which ) {
return;
}
$source = self::arg( 'source_type' );
$element = self::arg( 'element' );
$host = self::arg( 'host' );
?>
links;
$this->status_counts = $links->status_counts();
$per_page = $this->get_items_per_page( 'linktender_per_page', 30 );
$view = self::arg( 'view' );
$result = $links->query(
array(
'view' => '' === $view ? 'problems' : $view,
'search' => self::arg( 's' ),
'host' => self::arg( 'host' ),
'source_type' => self::arg( 'source_type' ),
'element' => self::arg( 'element' ),
'orderby' => self::arg( 'orderby' ),
'order' => self::arg( 'order' ),
'per_page' => $per_page,
'page' => $this->get_pagenum(),
)
);
$this->items = $result['items'];
$ids = wp_list_pluck( $this->items, 'id' );
$this->instances = $links->instances_for( $ids );
$this->counts = $links->instance_counts( $ids );
$this->_column_headers = array( $this->get_columns(), array(), $this->get_sortable_columns(), 'url' );
$this->set_pagination_args(
array(
'total_items' => $result['total'],
'per_page' => $per_page,
)
);
}
/**
* Empty state.
*
* @return void
*/
public function no_items() {
if ( LinkTender_Scanner::is_running() ) {
esc_html_e( 'Scanning your content in the background. Results appear here as links are checked.', 'linktender' );
return;
}
esc_html_e( 'No links here. Nice!', 'linktender' );
}
/**
* Checkbox column.
*
* @param object $item Row.
* @return string
*/
protected function column_cb( $item ) {
return sprintf( '', (int) $item->id );
}
/**
* URL column with row actions.
*
* @param object $item Row.
* @return string
*/
protected function column_url( $item ) {
$details = LinkTender_Admin::details_url( (int) $item->id );
$instances = isset( $this->instances[ (int) $item->id ] ) ? $this->instances[ (int) $item->id ] : array();
$has_a = false;
$elements = array();
foreach ( $instances as $instance ) {
$elements[ $instance->element ] = true;
if ( 'a' === $instance->element ) {
$has_a = true;
}
}
$out = '' . esc_html( $item->url ) . '';
$out .= ' ' . esc_html__( 'Open in a new tab', 'linktender' ) . '';
if ( ! empty( $item->final_url ) && 'redirect' === $item->status ) {
/* translators: %s: final URL after redirects. */
$out .= '→ ' . esc_html( $item->final_url ) . '
';
}
$out .= ''
. '
';
$actions = array(
'edit' => '' . esc_html__( 'Edit URL', 'linktender' ) . '',
'recheck' => '' . esc_html__( 'Recheck', 'linktender' ) . '',
);
if ( LinkTender_Links::final_url_is_usable( $item ) ) {
$actions['use_target'] = '' . esc_html__( 'Use final URL', 'linktender' ) . '';
}
if ( $has_a ) {
$actions['unlink'] = '' . esc_html__( 'Unlink', 'linktender' ) . '';
}
if ( (int) $item->dismissed ) {
$actions['undismiss'] = '' . esc_html__( 'Undo "fine"', 'linktender' ) . '';
} else {
$actions['dismiss'] = '' . esc_html__( 'Mark as fine', 'linktender' ) . '';
}
$actions['ignore_host'] = '' . esc_html__( 'Ignore domain', 'linktender' ) . '';
/**
* Filters row actions.
*
* @param array $actions Actions.
* @param object $item Link row.
*/
$actions = apply_filters( 'linktender_row_actions', $actions, $item );
return $out . $this->row_actions( $actions );
}
/**
* Status column.
*
* @param object $item Row.
* @return string
*/
protected function column_status( $item ) {
return LinkTender_Admin::status_badge( $item );
}
/**
* Found-in column.
*
* @param object $item Row.
* @return string
*/
protected function column_found_in( $item ) {
$instances = isset( $this->instances[ (int) $item->id ] ) ? $this->instances[ (int) $item->id ] : array();
$total = isset( $this->counts[ (int) $item->id ] ) ? $this->counts[ (int) $item->id ] : count( $instances );
$out = '';
foreach ( array_slice( $instances, 0, 3 ) as $instance ) {
$out .= '- ' . LinkTender_Admin::instance_label( $instance ) . '
';
}
$out .= '
';
if ( $total > 3 ) {
/* translators: %s: number of further places. */
$out .= '' . esc_html( sprintf( _n( 'and %s more place', 'and %s more places', $total - 3, 'linktender' ), number_format_i18n( $total - 3 ) ) ) . '';
}
return $out;
}
/**
* Last-checked column.
*
* @param object $item Row.
* @return string
*/
protected function column_last_checked( $item ) {
if ( empty( $item->last_checked ) ) {
return '—';
}
$time = strtotime( $item->last_checked . ' UTC' );
/* translators: %s: human time difference. */
return '' . esc_html( sprintf( __( '%s ago', 'linktender' ), human_time_diff( $time ) ) ) . '';
}
/**
* Fallback column.
*
* @param object $item Row.
* @param string $column_name Column.
* @return string
*/
protected function column_default( $item, $column_name ) {
/**
* Renders custom columns added via linktender_list_columns.
*
* @param string $html Output.
* @param object $item Link row.
* @param string $column_name Column.
*/
return (string) apply_filters( 'linktender_list_column', '', $item, $column_name );
}
}