taxonomy ) { $parent_file = 'aio-podcast-studio'; $submenu_file = 'edit-tags.php?taxonomy=aiopod_categories&post_type=aiopod_podcasts'; } return $parent_file; } /** * Register the custom taxonomy "aiopod_categories". * * @since 1.0.0 */ public function register_taxonomy() { $labels = array( 'name' => _x( 'Podcast Categories', 'Taxonomy General Name', 'aio-podcast-studio' ), 'singular_name' => _x( 'Category', 'Taxonomy Singular Name', 'aio-podcast-studio' ), 'menu_name' => __( 'Podcast Categories', 'aio-podcast-studio' ), 'all_items' => __( 'All Categories', 'aio-podcast-studio' ), 'parent_item' => __( 'Parent Category', 'aio-podcast-studio' ), 'parent_item_colon' => __( 'Parent Category:', 'aio-podcast-studio' ), 'new_item_name' => __( 'New Category Name', 'aio-podcast-studio' ), 'add_new_item' => __( 'Add New Category', 'aio-podcast-studio' ), 'edit_item' => __( 'Edit Category', 'aio-podcast-studio' ), 'update_item' => __( 'Update Category', 'aio-podcast-studio' ), 'view_item' => __( 'View Category', 'aio-podcast-studio' ), 'separate_items_with_commas' => __( 'Separate categories with commas', 'aio-podcast-studio' ), 'add_or_remove_items' => __( 'Add or remove categories', 'aio-podcast-studio' ), 'choose_from_most_used' => __( 'Choose from the most used', 'aio-podcast-studio' ), 'popular_items' => __( 'Popular Categories', 'aio-podcast-studio' ), 'search_items' => __( 'Search Categories', 'aio-podcast-studio' ), 'not_found' => __( 'No categories found.', 'aio-podcast-studio' ), 'no_terms' => __( 'No categories', 'aio-podcast-studio' ), 'items_list' => __( 'Categories list', 'aio-podcast-studio' ), 'items_list_navigation' => __( 'Categories list navigation', 'aio-podcast-studio' ), ); $args = array( 'labels' => $labels, 'hierarchical' => true, 'public' => true, 'show_ui' => true, 'show_admin_column' => true, 'show_in_nav_menus' => true, 'show_in_rest' => true, 'show_tagcloud' => false, 'capabilities' => array( 'manage_terms' => 'manage_aiopod_options', 'edit_terms' => 'manage_aiopod_options', 'delete_terms' => 'manage_aiopod_options', 'assign_terms' => 'edit_aiopod_podcasts' ) ); register_taxonomy( 'aiopod_categories', array( 'aiopod_podcasts' ), $args ); } /** * Import standard podcast categories. * * @since 1.0.0 */ public function import_categories() { // Security check check_admin_referer( 'aiopod_import_categories', 'aiopod_import_categories_nonce' ); if ( ! current_user_can( 'manage_aiopod_options' ) ) { wp_die( __( 'Sorry, you don\'t have permission to perform this action.', 'aio-podcast-studio' ) ); } if ( ! taxonomy_exists( 'aiopod_categories' ) ) { wp_die( __( 'Podcast categories taxonomy is not registered.', 'aio-podcast-studio' ) ); } // Load standard categories require_once AIOPOD_PLUGIN_DIR . 'includes/podcast-categories.php'; if ( empty( $aiopod_categories ) || ! is_array( $aiopod_categories ) ) { wp_die( __( 'No categories available to import.', 'aio-podcast-studio' ) ); } $imported = 0; $duplicate = 0; $failed = 0; foreach ( $aiopod_categories as $parent_name => $children ) { $parent_slug = sanitize_title( $parent_name ); $parent_term = get_term_by( 'slug', $parent_slug, 'aiopod_categories' ); // Insert parent if missing if ( ! $parent_term ) { $result = wp_insert_term( $parent_name, 'aiopod_categories', array( 'slug' => $parent_slug ) ); if ( is_wp_error( $result ) ) { $failed++; continue; } $parent_id = (int) $result['term_id']; $imported++; } else { $parent_id = (int) $parent_term->term_id; $duplicate++; } // Insert children if ( empty( $children ) ) { continue; } foreach ( $children as $child_name ) { $child_slug = sanitize_title( $child_name ); $child_term = get_term_by( 'slug', $child_slug, 'aiopod_categories' ); if ( $child_term ) { $duplicate++; continue; } $result = wp_insert_term( $child_name, 'aiopod_categories', array( 'slug' => $child_slug, 'parent' => $parent_id ) ); if ( is_wp_error( $result ) ) { $failed++; continue; } $imported++; } } // Store results for admin notice set_transient( 'aiopod_imported_categories', array( 'imported' => $imported, 'duplicate' => $duplicate, 'failed' => $failed ), 30 ); // Mark as imported (used for button label: Import → Sync) update_option( 'aiopod_imported_categories', 'yes' ); // Redirect to Categories page wp_safe_redirect( admin_url( 'edit-tags.php?taxonomy=aiopod_categories' ) ); exit; } /** * Display admin notices. * * @since 1.0.0 */ public function admin_notices() { $result = get_transient( 'aiopod_imported_categories' ); if ( false === $result || ! is_array( $result ) ) { return; } // Remove transient so notice shows only once delete_transient( 'aiopod_imported_categories' ); $imported = isset( $result['imported'] ) ? (int) $result['imported'] : 0; $duplicate = isset( $result['duplicate'] ) ? (int) $result['duplicate'] : 0; $failed = isset( $result['failed'] ) ? (int) $result['failed'] : 0; $total = $imported + $duplicate + $failed; if ( 0 === $total ) { return; } // Default notice $status = 'success'; $message = sprintf( __( 'Categories synced successfully. Total: %1$d (Added: %2$d, Existing: %3$d, Failed: %4$d).', 'aio-podcast-studio' ), $total, $imported, $duplicate, $failed ); if ( $failed === $total ) { $status = 'error'; $message = __( 'Sorry! Category import failed. Please try again.', 'aio-podcast-studio' ); } elseif ( $imported === $total ) { $message = __( 'Congrats! Categories imported successfully.', 'aio-podcast-studio' ); } elseif ( $failed > 0 ) { $status = 'warning'; } printf( '

%s

← %s

', esc_attr( $status ), wp_kses_post( $message ), esc_url( admin_url( 'admin.php?page=aio-podcast-studio' ) ), esc_html__( 'Go to Dashboard', 'aio-podcast-studio' ) ); } /** * Add custom form fields. * * @since 1.0.0 */ public function add_form_fields() { $form = 'add'; require_once AIOPOD_PLUGIN_DIR . 'admin/partials/categories/custom-fields.php'; } /** * Edit custom form fields. * * @since 1.0.0 * @param object $term Taxonomy term object. */ public function edit_form_fields( $term ) { $form = 'edit'; $image_id = (int) get_term_meta( $term->term_id, 'image_id', true ); $image = get_term_meta( $term->term_id, 'image', true ); if ( empty( $image ) && $image_id > 0 ) { $image = wp_get_attachment_url( $image_id ); } require_once AIOPOD_PLUGIN_DIR . 'admin/partials/categories/custom-fields.php'; } /** * Save custom form fields. * * @since 1.0.0 * @param int $term_id Term ID. */ public function save_form_fields( $term_id ) { // Check if "aiopod_category_fields_nonce" nonce is set if ( isset( $_POST['aiopod_category_fields_nonce'] ) ) { // Verify that the nonce is valid if ( wp_verify_nonce( sanitize_text_field( wp_unslash( $_POST['aiopod_category_fields_nonce'] ) ), 'aiopod_save_category_fields' ) ) { // OK to save meta data $image = isset( $_POST['image'] ) ? aiopod_sanitize_url( wp_unslash( $_POST['image'] ) ) : ''; update_term_meta( $term_id, 'image', $image ); // Keep the attachment ID in sync with the image URL (corrects stale/missing IDs). $image_id = ! empty( $image ) ? (int) attachment_url_to_postid( $image ) : 0; update_term_meta( $term_id, 'image_id', $image_id ); } } } /** * Retrieve the table columns. * * @since 1.0.0 * @param array $columns Array of default table columns. * @return array $columns Updated list of table columns. */ public function get_columns( $columns ) { unset( $columns['description'] ); $columns = aiopod_insert_array_after( 'cb', $columns, array( 'image' => '' )); $columns = aiopod_insert_array_after( 'slug', $columns, array( 'tax_id' => __( 'ID', 'aio-podcast-studio' ) )); return $columns; } /** * This function renders the custom columns in the list table. * * @since 1.0.0 * @param string $content Content of the column. * @param string $column Name of the column. * @param string $term_id Term ID. */ public function custom_column_content( $content, $column, $term_id ) { switch ( $column ) { case 'image': $content = aiopod_the_image( array( 'term_id' => $term_id, 'size' => 'thumbnail', 'width' => '75px', 'alt' => '', 'placeholder' => AIOPOD_PLUGIN_PLACEHOLDER_IMAGE_URL, 'echo' => false ) ); break; case 'tax_id': $content = $term_id; break; } return $content; } /** * Delete attachments. * * @since 1.0.0 * @param int $term_id Term ID. * @param string $taxonomy Taxonomy Name. */ public function pre_delete_term( $term_id, $taxonomy ) { if ( 'aiopod_categories' !== $taxonomy ) { return; } aiopod_delete_term_attachments( $term_id ); } }