From a9cb056e7e329a5c694eeda15156ff336f2389dc Mon Sep 17 00:00:00 2001 From: Viktor Miller Date: Wed, 14 Jan 2026 19:48:13 +0900 Subject: [PATCH] feat(03-04): add custom admin columns for job moderation Create DDHH_JM_Admin_UI class with custom columns for job_offer admin listing: - Anbieter (provider org name + contact person from user meta) - Standort (location from ACF field) - Art (job type from ACF field) - Eingereicht am (submission date) Removed default author/date columns to reduce clutter. Made columns sortable for efficient moderation workflow. Co-Authored-By: Claude Sonnet 4.5 --- includes/class-admin-ui.php | 255 ++++++++++++++++++++++++++++++++++++ 1 file changed, 255 insertions(+) create mode 100644 includes/class-admin-ui.php diff --git a/includes/class-admin-ui.php b/includes/class-admin-ui.php new file mode 100644 index 0000000..c531086 --- /dev/null +++ b/includes/class-admin-ui.php @@ -0,0 +1,255 @@ + $columns['cb'], + 'title' => $columns['title'], + 'provider' => __( 'Anbieter', 'ddhh-job-manager' ), + 'location' => __( 'Standort', 'ddhh-job-manager' ), + 'job_type' => __( 'Art', 'ddhh-job-manager' ), + 'submitted' => __( 'Eingereicht am', 'ddhh-job-manager' ), + ); + + return $new_columns; + } + + /** + * Render custom column content + * + * @param string $column Column name. + * @param int $post_id Post ID. + */ + public static function render_custom_columns( $column, $post_id ) { + switch ( $column ) { + case 'provider': + self::render_provider_column( $post_id ); + break; + + case 'location': + self::render_location_column( $post_id ); + break; + + case 'job_type': + self::render_job_type_column( $post_id ); + break; + + case 'submitted': + self::render_submitted_column( $post_id ); + break; + } + } + + /** + * Render provider column (organization name + contact person) + * + * @param int $post_id Post ID. + */ + private static function render_provider_column( $post_id ) { + $post = get_post( $post_id ); + if ( ! $post ) { + echo '—'; + return; + } + + // Get author user + $author_id = $post->post_author; + $org_name = get_user_meta( $author_id, 'ddhh_org_name', true ); + $contact_person = get_user_meta( $author_id, 'ddhh_contact_person', true ); + + if ( $org_name ) { + echo esc_html( $org_name ); + if ( $contact_person ) { + echo '
' . esc_html( $contact_person ) . ''; + } + } else { + // Fallback to author display name + $author = get_userdata( $author_id ); + if ( $author ) { + echo esc_html( $author->display_name ); + } else { + echo '—'; + } + } + } + + /** + * Render location column + * + * @param int $post_id Post ID. + */ + private static function render_location_column( $post_id ) { + $location = get_field( 'job_location', $post_id ); + echo $location ? esc_html( $location ) : '—'; + } + + /** + * Render job type column + * + * @param int $post_id Post ID. + */ + private static function render_job_type_column( $post_id ) { + $job_type = get_field( 'job_type', $post_id ); + + if ( $job_type ) { + // Get human-readable label + $labels = array( + 'vollzeit' => __( 'Vollzeit', 'ddhh-job-manager' ), + 'teilzeit' => __( 'Teilzeit', 'ddhh-job-manager' ), + 'ehrenamt' => __( 'Ehrenamt', 'ddhh-job-manager' ), + ); + + $label = isset( $labels[ $job_type ] ) ? $labels[ $job_type ] : $job_type; + echo esc_html( $label ); + } else { + echo '—'; + } + } + + /** + * Render submitted column (post creation date) + * + * @param int $post_id Post ID. + */ + private static function render_submitted_column( $post_id ) { + $date = get_the_date( 'd.m.Y H:i', $post_id ); + echo esc_html( $date ); + } + + /** + * Add sortable columns + * + * @param array $columns Sortable columns. + * @return array Modified sortable columns. + */ + public static function add_sortable_columns( $columns ) { + $columns['submitted'] = 'date'; + $columns['location'] = 'job_location'; + $columns['job_type'] = 'job_type'; + return $columns; + } + + /** + * Handle column sorting in admin query + * + * @param WP_Query $query The query object. + */ + public static function handle_column_sorting( $query ) { + if ( ! is_admin() || ! $query->is_main_query() ) { + return; + } + + $orderby = $query->get( 'orderby' ); + + // Handle ACF field sorting + if ( 'job_location' === $orderby ) { + $query->set( 'meta_key', 'job_location' ); + $query->set( 'orderby', 'meta_value' ); + } elseif ( 'job_type' === $orderby ) { + $query->set( 'meta_key', 'job_type' ); + $query->set( 'orderby', 'meta_value' ); + } + } + + /** + * Add status filter links with counts + * + * @param array $views Existing view links. + * @return array Modified view links. + */ + public static function add_status_filters( $views ) { + // Get post counts by status + $post_counts = wp_count_posts( 'job_offer' ); + + // Override default views with custom ones + $views = array(); + + // All + $all_count = $post_counts->publish + $post_counts->pending + $post_counts->draft + $post_counts->private; + $current_class = ( ! isset( $_GET['post_status'] ) ) ? ' class="current"' : ''; + $views['all'] = sprintf( + '%s (%d)', + admin_url( 'edit.php?post_type=job_offer' ), + $current_class, + __( 'Alle', 'ddhh-job-manager' ), + $all_count + ); + + // Pending (with emphasis) + if ( $post_counts->pending > 0 ) { + $pending_class = ( isset( $_GET['post_status'] ) && 'pending' === $_GET['post_status'] ) ? ' class="current"' : ''; + $views['pending'] = sprintf( + '%s (%d)', + admin_url( 'edit.php?post_type=job_offer&post_status=pending' ), + $pending_class, + __( 'Ausstehend', 'ddhh-job-manager' ), + $post_counts->pending + ); + } + + // Published + if ( $post_counts->publish > 0 ) { + $publish_class = ( isset( $_GET['post_status'] ) && 'publish' === $_GET['post_status'] ) ? ' class="current"' : ''; + $views['publish'] = sprintf( + '%s (%d)', + admin_url( 'edit.php?post_type=job_offer&post_status=publish' ), + $publish_class, + __( 'Veröffentlicht', 'ddhh-job-manager' ), + $post_counts->publish + ); + } + + // Draft + if ( $post_counts->draft > 0 ) { + $draft_class = ( isset( $_GET['post_status'] ) && 'draft' === $_GET['post_status'] ) ? ' class="current"' : ''; + $views['draft'] = sprintf( + '%s (%d)', + admin_url( 'edit.php?post_type=job_offer&post_status=draft' ), + $draft_class, + __( 'Entwurf', 'ddhh-job-manager' ), + $post_counts->draft + ); + } + + return $views; + } +}