esc_html__( 'Directory Types', 'adirectory' ), 'singular_name' => esc_html__( 'Directory Type', 'adirectory' ), 'add_new_item' => esc_html__( 'Add New Directory Type', 'adirectory' ), 'new_item_name' => esc_html__( 'New Directory Type Name', 'adirectory' ), 'edit_item' => esc_html__( 'Edit Directory Type', 'adirectory' ), 'update_item' => esc_html__( 'Update Directory Type', 'adirectory' ), 'add_or_remove_items' => esc_html__( 'Add or remove directory types', 'adirectory' ), 'search_items' => esc_html__( 'Search Directory Types', 'adirectory' ), 'popular_items' => esc_html__( 'Popular Directory Types', 'adirectory' ), 'all_items' => esc_html__( 'All Directory Types', 'adirectory' ), 'parent_item' => esc_html__( 'Parent Directory Type', 'adirectory' ), 'choose_from_most_used' => esc_html__( 'Choose from the most used directory types', 'adirectory' ), 'parent_item_colon' => esc_html__( 'Parent Directory Type:', 'adirectory' ), 'menu_name' => esc_html__( 'Directory Types', 'adirectory' ), ]; $args = [ 'labels' => $labels, 'public' => true, 'show_in_nav_menus' => false, 'show_admin_column' => false, 'hierarchical' => false, 'show_tagcloud' => false, 'show_ui' => false, 'rewrite' => [ 'slug' => 'directory', 'with_front' => false, ], 'capabilities' => [ 'manage_terms' => 'manage_categories', 'edit_terms' => 'manage_categories', 'delete_terms' => 'manage_categories', 'assign_terms' => 'read', ], ]; // Register with post type as fallback. register_taxonomy( 'adqs_listing_types', [ 'post' ], $args ); } /** * Method register_post_types * Loops through all terms in adqs_listing_types and registers custom post types * using the term meta fields: adqs_directory_plural_name * * @return void */ public function register_post_types() { $directories = adqs_get_directories(); if ( empty( $directories ) ) { return; } foreach ( $directories as $directory ) { $this->register_post_type( $directory ); $this->add_post_type_hook( $directory->post_type ); } } /** * Register a custom post type for a specific directory type term. * * @param \WP_Term $directory The directory term object. * @return void */ public function register_post_type( $directory ) { $singular_name = $directory->name; $url_slug = $directory->slug; $plural_name = get_term_meta( $directory->term_id, 'adqs_directory_plural_name', true ); $post_type = get_term_meta( $directory->term_id, 'adqs_directory_post_type', true ); // Ensure we have plural_name, fallback to singular if ( empty( $plural_name ) ) { $plural_name = $singular_name; } $args = $this->get_post_type_args( $singular_name, $plural_name, $url_slug ); // In rare case $post_type is missing. if ( empty( $post_type ) ) { $post_type = adqs_create_post_type_key( $singular_name ); update_term_meta( $directory->term_id, 'adqs_directory_post_type', $post_type ); } register_post_type( $post_type, apply_filters( 'adqs_register_post_type_args', $args ) ); // Ensure WordPress recognizes this post type for admin bar. add_filter( 'admin_bar_post_types', static function ( $post_types ) use ( $post_type ) { $post_types[] = $post_type; return $post_types; } ); } /** * Add hooks for dynamic post types. * * @param string $directory_post_type The post type slug. * @return void */ private function add_post_type_hook( $directory_post_type ) { add_filter( 'manage_' . $directory_post_type . '_posts_columns', [ $this, 'add_columns' ] ); add_action( 'manage_' . $directory_post_type . '_posts_custom_column', [ $this, 'render_columns' ], 10, 2 ); add_filter( 'manage_edit-' . $directory_post_type . '_sortable_columns', [ $this, 'add_sortable_columns' ] ); // Future feature: add_filter( 'manage_taxonomies_' . $directory_post_type . '_columns', [ $this, 'manage_table_taxonomies' ] );. } /** * Method add_columns - Add custom columns to post type list table. * * @param array $columns The existing columns array. * @return array Modified columns array. */ public function add_columns( $columns ) { // Get the current post type to determine which taxonomies to show. $current_screen = get_current_screen(); $post_type = $current_screen ? $current_screen->post_type : ''; $new_columns = [ 'cb' => $columns['cb'], 'title' => esc_html__( 'Name', 'adirectory' ), 'preview_image' => esc_html__( 'Preview Image', 'adirectory' ), ]; $directory_taxonomies = adqs_get_directory_taxonomies( $post_type, 'object' ); if ( ! empty( $directory_taxonomies ) ) { $directory = adqs_get_directory_by_post_type( $post_type ); foreach ( $directory_taxonomies as $directory_taxonomy ) { $label = $directory_taxonomy->label ?? ''; // Only apply str_replace if directory exists and has a name. if ( $directory && ! empty( $directory->name ) ) { $label = str_replace( $directory->name, '', $label ); } $new_columns[ 'taxonomy-' . $directory_taxonomy->name ] = $label; } } unset( $columns['comments'] ); $new_columns['author'] = esc_html__( 'Author', 'adirectory' ); $new_columns['expire_on'] = esc_html__( 'Expire on', 'adirectory' ); $new_columns['date'] = esc_html__( 'Created at', 'adirectory' ); return $new_columns + $columns; } /** * Method add_sortable_columns - Define sortable columns. * * @param array $columns The existing sortable columns. * @return array Modified sortable columns. */ public function add_sortable_columns( $columns ) { $columns['expire_on'] = 'expire_on'; return $columns; } /** * Method render_columns - Render custom column content. * * @param string $column The column name. * @param int $post_id The post ID. * @return void */ public function render_columns( $column, $post_id ) { switch ( $column ) { case 'preview_image': $thumbnail = get_the_post_thumbnail( $post_id, [ 50, 50 ] ); if ( $thumbnail ) { echo wp_kses_post( $thumbnail ); } else { echo '' . esc_html__( 'No image', 'adirectory' ) . ''; } break; case 'status': $status = get_post_status( $post_id ); $status_obj = get_post_status_object( $status ); if ( $status_obj ) { echo '' . esc_html( $status_obj->label ) . ''; } break; case 'expire_on': // Check if "Never Expire" is set $never_expire = get_post_meta( $post_id, '_expiry_never', true ); if ( $never_expire === 'yes' ) { echo '' . esc_html__( 'Never', 'adirectory' ) . ''; } else { $expire_date = get_post_meta( $post_id, '_expiry_date', true ); if ( $expire_date ) { echo esc_html( date_i18n( get_option( 'date_format' ), strtotime( $expire_date ) ) ); } else { echo '' . esc_html__( 'No expiry', 'adirectory' ) . ''; } } // Add inline data for Quick Edit (similar to WooCommerce approach) $this->add_inline_data_for_post( $post_id ); break; } } /** * Add inline data for Quick Edit functionality. * This provides Featured and Expiration data to JavaScript for populating Quick Edit fields. * Similar to WooCommerce's approach - adds a hidden div with post-specific data. * * @param int $post_id The post ID. * @return void */ private function add_inline_data_for_post( $post_id ) { // Only add data for directory post types $post = get_post( $post_id ); if ( ! $post || ! adqs_is_directory_post_type( $post->post_type ) ) { return; } // Get Featured status $is_featured = get_post_meta( $post_id, '_is_featured', true ); $is_featured = ( $is_featured === 'yes' ) ? 'yes' : 'no'; // Get Expiration data $expiry_never = get_post_meta( $post_id, '_expiry_never', true ); $expiry_never = ( $expiry_never === 'yes' ) ? 'yes' : 'no'; $expiry_date = get_post_meta( $post_id, '_expiry_date', true ); $mm = ''; $jj = ''; $aa = ''; $hh = ''; $mn = ''; if ( ! empty( $expiry_date ) && $expiry_never !== 'yes' ) { // Parse expiry date: format is "YYYY-MM-DD HH:MM:SS" if ( strpos( $expiry_date, ' ' ) !== false ) { list($date_part, $time_part) = explode( ' ', $expiry_date ); if ( strpos( $date_part, '-' ) !== false ) { list($aa, $mm, $jj) = explode( '-', $date_part ); } if ( ! empty( $time_part ) && strpos( $time_part, ':' ) !== false ) { list($hh, $mn) = explode( ':', $time_part ); } } } // Output inline data as hidden div (similar to WooCommerce) printf( '