'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 = ''; 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 ); } }