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 <noreply@anthropic.com>
This commit is contained in:
255
includes/class-admin-ui.php
Normal file
255
includes/class-admin-ui.php
Normal file
@@ -0,0 +1,255 @@
|
|||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* Admin UI Enhancements
|
||||||
|
*
|
||||||
|
* @package DDHH_Job_Manager
|
||||||
|
*/
|
||||||
|
|
||||||
|
// Exit if accessed directly.
|
||||||
|
defined( 'ABSPATH' ) || exit;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Handles admin interface enhancements for job moderation
|
||||||
|
*/
|
||||||
|
class DDHH_JM_Admin_UI {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Setup admin hooks
|
||||||
|
*/
|
||||||
|
public static function setup_hooks() {
|
||||||
|
// Custom columns
|
||||||
|
add_filter( 'manage_job_offer_posts_columns', array( __CLASS__, 'add_custom_columns' ) );
|
||||||
|
add_action( 'manage_job_offer_posts_custom_column', array( __CLASS__, 'render_custom_columns' ), 10, 2 );
|
||||||
|
add_filter( 'manage_edit-job_offer_sortable_columns', array( __CLASS__, 'add_sortable_columns' ) );
|
||||||
|
|
||||||
|
// Status filters and views
|
||||||
|
add_filter( 'views_edit-job_offer', array( __CLASS__, 'add_status_filters' ) );
|
||||||
|
|
||||||
|
// Sort query modifications
|
||||||
|
add_action( 'pre_get_posts', array( __CLASS__, 'handle_column_sorting' ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Add custom columns to job_offer admin listing
|
||||||
|
*
|
||||||
|
* @param array $columns Existing columns.
|
||||||
|
* @return array Modified columns.
|
||||||
|
*/
|
||||||
|
public static function add_custom_columns( $columns ) {
|
||||||
|
// Remove default columns we're replacing
|
||||||
|
unset( $columns['author'] );
|
||||||
|
unset( $columns['date'] );
|
||||||
|
|
||||||
|
// Build new column array with custom columns
|
||||||
|
$new_columns = array(
|
||||||
|
'cb' => $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 '<br><small>' . esc_html( $contact_person ) . '</small>';
|
||||||
|
}
|
||||||
|
} 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(
|
||||||
|
'<a href="%s"%s>%s <span class="count">(%d)</span></a>',
|
||||||
|
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(
|
||||||
|
'<a href="%s"%s>%s <span class="count">(%d)</span></a>',
|
||||||
|
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(
|
||||||
|
'<a href="%s"%s>%s <span class="count">(%d)</span></a>',
|
||||||
|
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(
|
||||||
|
'<a href="%s"%s>%s <span class="count">(%d)</span></a>',
|
||||||
|
admin_url( 'edit.php?post_type=job_offer&post_status=draft' ),
|
||||||
|
$draft_class,
|
||||||
|
__( 'Entwurf', 'ddhh-job-manager' ),
|
||||||
|
$post_counts->draft
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
return $views;
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user