__( 'Custom Code', 'admin-optimizer' ), 'plural' => __( 'Custom Codes', 'admin-optimizer' ), 'ajax' => false, ] ); } /** * Get columns. * * @return array */ public function get_columns(): array { return [ 'cb' => '', 'title' => __( 'Title', 'admin-optimizer' ), 'type' => __( 'Type', 'admin-optimizer' ), 'location' => __( 'Location', 'admin-optimizer' ), 'output' => __( 'Output', 'admin-optimizer' ), 'status' => __( 'Status', 'admin-optimizer' ), 'date' => __( 'Date', 'admin-optimizer' ), ]; } /** * Get sortable columns. * * @return array */ protected function get_sortable_columns(): array { return [ 'title' => [ 'title', false ], 'date' => [ 'date', true ], ]; } /** * Get post status views for the list table. * * @return array */ protected function get_views(): array { $statuses = $this->get_listable_post_statuses(); $counts = wp_count_posts( Custom_Code::POST_TYPE, 'readable' ); $current_status = $this->get_current_post_status(); $views = []; $total = 0; foreach ( $statuses as $status => $status_object ) { if ( 'trash' === $status ) { continue; } $total += isset( $counts->{$status} ) ? (int) $counts->{$status} : 0; } $views['all'] = $this->get_status_view_link( '', __( 'All', 'admin-optimizer' ), $total, '' === $current_status ); foreach ( $statuses as $status => $status_object ) { $count = isset( $counts->{$status} ) ? (int) $counts->{$status} : 0; if ( 0 === $count ) { continue; } $views[ $status ] = $this->get_status_view_link( $status, $status_object->label, $count, $status === $current_status ); } return $views; } /** * Get bulk actions. * * @return array */ protected function get_bulk_actions(): array { if ( 'trash' === $this->get_current_post_status() ) { return [ 'restore' => __( 'Restore', 'admin-optimizer' ), 'delete' => __( 'Delete Permanently', 'admin-optimizer' ), ]; } return [ 'activate' => __( 'Activate', 'admin-optimizer' ), 'deactivate' => __( 'Deactivate', 'admin-optimizer' ), 'trash' => __( 'Move to Trash', 'admin-optimizer' ), ]; } /** * Default column fallback. * * @param \WP_Post $item * @param string $column_name * @return string */ protected function column_default( $item, $column_name ): string { return ''; } /** * Checkbox column. * * @param \WP_Post $item * @return string */ protected function column_cb( $item ): string { return sprintf( '', absint( $item->ID ) ); } /** * Title column with row actions. * * @param \WP_Post $item * @return string */ protected function column_title( $item ): string { $edit_url = get_edit_post_link( $item->ID ); $trash_url = get_delete_post_link( $item->ID ); $toggle_url = wp_nonce_url( add_query_arg( [ 'action' => 'ao_cc_toggle_status', 'post' => absint( $item->ID ), ], admin_url( 'admin-post.php' ) ), 'ao_cc_toggle_status_' . absint( $item->ID ) ); $restore_url = wp_nonce_url( add_query_arg( [ 'action' => 'ao_cc_restore_code', 'post' => absint( $item->ID ), ], admin_url( 'admin-post.php' ) ), 'ao_cc_restore_code_' . absint( $item->ID ) ); $force_delete_url = wp_nonce_url( add_query_arg( [ 'action' => 'ao_cc_delete_code', 'post' => absint( $item->ID ), ], admin_url( 'admin-post.php' ) ), 'ao_cc_delete_code_' . absint( $item->ID ) ); $status = get_post_status( $item->ID ); $title = sprintf( '%s', esc_url( $edit_url ), esc_html( $item->post_title !== '' ? $item->post_title : __( '(no title)', 'admin-optimizer' ) ) ); if ( 'draft' === $status ) { $title .= ' — ' . esc_html__( 'Draft', 'admin-optimizer' ) . ''; } if ( 'trash' === $status ) { $actions = [ 'restore' => sprintf( '%s', esc_url( $restore_url ), esc_html__( 'Restore', 'admin-optimizer' ) ), 'delete' => sprintf( '%s', esc_url( $force_delete_url ), esc_js( __( 'Are you sure you want to permanently delete this item?', 'admin-optimizer' ) ), esc_html__( 'Delete Permanently', 'admin-optimizer' ) ), ]; } else { $is_published = 'publish' === $status; $toggle_label = $is_published ? __( 'Deactivate', 'admin-optimizer' ) : __( 'Activate', 'admin-optimizer' ); $actions = [ 'edit' => sprintf( '%s', esc_url( $edit_url ), esc_html__( 'Edit', 'admin-optimizer' ) ), 'toggle' => sprintf( '%s', esc_url( $toggle_url ), esc_html( $toggle_label ) ), 'trash' => sprintf( '%s', esc_url( $trash_url ), esc_js( __( 'Are you sure you want to trash this item?', 'admin-optimizer' ) ), esc_html__( 'Trash', 'admin-optimizer' ) ), ]; } return $title . $this->row_actions( $actions ); } /** * Type column. * * @param \WP_Post $item * @return string */ protected function column_type( $item ): string { $type = get_post_meta( $item->ID, '_ao_cc_type', true ); $labels = [ 'css' => 'CSS', 'js' => 'JavaScript', 'html' => 'HTML', ]; $labels = apply_filters( 'ao_cc_list_type_labels', $labels ); return esc_html( $labels[ $type ] ?? ucfirst( $type ) ); } /** * Location column. * * @param \WP_Post $item * @return string */ protected function column_location( $item ): string { $locations = get_post_meta( $item->ID, '_ao_cc_locations', true ); $post_ids = get_post_meta( $item->ID, '_ao_cc_post_ids', true ); $labels = []; if ( is_array( $locations ) && ! empty( $locations ) ) { foreach ( $locations as $key ) { $labels[] = Custom_Code::ALL_LOCATIONS[ $key ] ?? $key; } } if ( is_array( $post_ids ) && ! empty( $post_ids ) ) { $labels[] = sprintf( /* translators: %s: comma-separated list of post IDs */ __( 'Post IDs: %s', 'admin-optimizer' ), implode( ', ', array_map( 'absint', $post_ids ) ) ); } $output = $labels ? esc_html( implode( ', ', $labels ) ) : '—'; return apply_filters( 'ao_cc_list_location_output', $output, $item ); } /** * Output column — shows display method for CSS or position for JS/HTML. * * @param \WP_Post $item * @return string */ protected function column_output( $item ): string { $type = get_post_meta( $item->ID, '_ao_cc_type', true ); if ( 'css' === $type ) { $display_raw = get_post_meta( $item->ID, '_ao_cc_display', true ); $display = '' !== $display_raw ? $display_raw : 'inline'; return esc_html( ucfirst( $display ) ); } $position_labels = [ 'wp_head' => __( 'Head', 'admin-optimizer' ), 'wp_body_open' => __( 'Body open', 'admin-optimizer' ), 'wp_footer' => __( 'Footer', 'admin-optimizer' ), ]; $position = get_post_meta( $item->ID, '_ao_cc_position', true ); return isset( $position_labels[ $position ] ) ? esc_html( $position_labels[ $position ] ) : '—'; } /** * Post status column. * * @param \WP_Post $item * @return string */ protected function column_status( $item ): string { return 'publish' === $item->post_status ? esc_html__( 'Activated', 'admin-optimizer' ) : esc_html__( 'Deactivated', 'admin-optimizer' ); } /** * Date column. * * @param \WP_Post $item * @return string */ protected function column_date( $item ): string { return esc_html( get_the_date( get_option( 'date_format' ), $item ) ); } /** * Type filter dropdown rendered above the table. * * @param string $which * @return void */ public function extra_tablenav( $which ): void { if ( 'top' !== $which ) { return; } // phpcs:ignore WordPress.Security.NonceVerification.Recommended $current_type = isset( $_REQUEST['ao_cc_type_filter'] ) ? sanitize_key( wp_unslash( $_REQUEST['ao_cc_type_filter'] ) ) : ''; ?>