register_taxonomies(); self::instance()->register_post_types(); flush_rewrite_rules(); } public static function deactivate() { flush_rewrite_rules(); } public function get_cpts() { $cpts = get_option( self::CPT_OPTION, array() ); return is_array( $cpts ) ? array_map( array( $this, 'normalize_cpt_record' ), $cpts ) : array(); } public function get_taxonomies() { $taxonomies = get_option( self::TAX_OPTION, array() ); return is_array( $taxonomies ) ? array_map( array( $this, 'normalize_taxonomy_record' ), $taxonomies ) : array(); } public function get_cpt_overrides() { $cpts = get_option( self::CPT_OVERRIDE_OPTION, array() ); return is_array( $cpts ) ? array_map( array( $this, 'normalize_cpt_record' ), $cpts ) : array(); } public function get_taxonomy_overrides() { $tax = get_option( self::TAX_OVERRIDE_OPTION, array() ); return is_array( $tax ) ? array_map( array( $this, 'normalize_taxonomy_record' ), $tax ) : array(); } public function save_cpts( $cpts ) { update_option( self::CPT_OPTION, array_values( array_map( array( $this, 'normalize_cpt_record' ), $cpts ) ), false ); } public function save_taxonomies( $taxonomies ) { update_option( self::TAX_OPTION, array_values( array_map( array( $this, 'normalize_taxonomy_record' ), $taxonomies ) ), false ); } public function save_cpt_overrides( $cpts ) { update_option( self::CPT_OVERRIDE_OPTION, array_values( array_map( array( $this, 'normalize_cpt_record' ), $cpts ) ), false ); } public function save_taxonomy_overrides( $taxonomies ) { update_option( self::TAX_OVERRIDE_OPTION, array_values( array_map( array( $this, 'normalize_taxonomy_record' ), $taxonomies ) ), false ); } public function normalize_cpt_record( $record ) { $record = is_array( $record ) ? $record : array(); $custom_fields = array(); if ( ! empty( $record['custom_fields'] ) && is_array( $record['custom_fields'] ) ) { foreach ( $record['custom_fields'] as $field ) { if ( ! is_array( $field ) ) { continue; } $type = sanitize_key( $field['type'] ?? 'text' ); if ( ! in_array( $type, array( 'text', 'textarea', 'number', 'url', 'email', 'date', 'checkbox', 'select', 'radio' ), true ) ) { $type = 'text'; } $options = array(); if ( ! empty( $field['options'] ) && is_array( $field['options'] ) ) { foreach ( $field['options'] as $option ) { $option = sanitize_text_field( $option ); if ( '' !== $option ) { $options[] = $option; } } } $custom_fields[] = array( 'label' => sanitize_text_field( $field['label'] ?? '' ), 'key' => sanitize_key( $field['key'] ?? '' ), 'type' => $type, 'description' => sanitize_text_field( $field['description'] ?? '' ), 'options' => $options, ); } } $template_settings = $this->normalize_cpt_template_settings( $record['template_settings'] ?? array() ); return array( 'key' => sanitize_key( $record['key'] ?? '' ), 'singular_label' => sanitize_text_field( $record['singular_label'] ?? '' ), 'plural_label' => sanitize_text_field( $record['plural_label'] ?? '' ), 'slug' => sanitize_title( $record['slug'] ?? '' ), 'hierarchical' => ! empty( $record['hierarchical'] ) ? 1 : 0, 'object_type' => ! empty( $record['object_type'] ) && is_array( $record['object_type'] ) ? array_values( array_unique( array_map( 'sanitize_key', $record['object_type'] ) ) ) : array(), 'template_settings' => $this->normalize_taxonomy_template_settings( $record['template_settings'] ?? array() ), 'is_override' => ! empty( $record['is_override'] ) ? 1 : 0, ); } public function normalize_taxonomy_record( $record ) { $record = is_array( $record ) ? $record : array(); $template_settings = $this->normalize_cpt_template_settings( $record['template_settings'] ?? array() ); return array( 'key' => sanitize_key( $record['key'] ?? '' ), 'singular_label' => sanitize_text_field( $record['singular_label'] ?? '' ), 'plural_label' => sanitize_text_field( $record['plural_label'] ?? '' ), 'slug' => sanitize_title( $record['slug'] ?? '' ), 'hierarchical' => ! empty( $record['hierarchical'] ) ? 1 : 0, 'object_type' => ! empty( $record['object_type'] ) && is_array( $record['object_type'] ) ? array_values( array_unique( array_map( 'sanitize_key', $record['object_type'] ) ) ) : array(), 'template_settings' => $this->normalize_taxonomy_template_settings( $record['template_settings'] ?? array() ), 'is_override' => ! empty( $record['is_override'] ) ? 1 : 0, ); } public function normalize_cpt_template_settings( $settings ) { $settings = is_array( $settings ) ? $settings : array(); $single_mode = isset( $settings['single_mode'] ) && in_array( $settings['single_mode'], array( 'plugin', 'theme' ), true ) ? $settings['single_mode'] : 'plugin'; $archive_mode = isset( $settings['archive_mode'] ) && in_array( $settings['archive_mode'], array( 'plugin', 'theme' ), true ) ? $settings['archive_mode'] : 'plugin'; $archive_columns = absint( $settings['archive_columns'] ?? 3 ); if ( $archive_columns < 1 || $archive_columns > 4 ) { $archive_columns = 3; } return array( 'single_mode' => $single_mode, 'archive_mode' => $archive_mode, 'single_show_featured' => ! empty( $settings['single_show_featured'] ) ? 1 : 0, 'single_show_meta' => ! empty( $settings['single_show_meta'] ) ? 1 : 0, 'single_show_terms' => ! empty( $settings['single_show_terms'] ) ? 1 : 0, 'single_show_custom_fields' => ! empty( $settings['single_show_custom_fields'] ) ? 1 : 0, 'archive_show_featured' => ! empty( $settings['archive_show_featured'] ) ? 1 : 0, 'archive_show_excerpt' => ! empty( $settings['archive_show_excerpt'] ) ? 1 : 0, 'archive_show_meta' => ! empty( $settings['archive_show_meta'] ) ? 1 : 0, 'archive_columns' => $archive_columns, 'archive_intro' => sanitize_textarea_field( $settings['archive_intro'] ?? '' ), ); } public function normalize_taxonomy_template_settings( $settings ) { $settings = is_array( $settings ) ? $settings : array(); $archive_mode = isset( $settings['archive_mode'] ) && in_array( $settings['archive_mode'], array( 'plugin', 'theme' ), true ) ? $settings['archive_mode'] : 'plugin'; $archive_columns = absint( $settings['archive_columns'] ?? 3 ); if ( $archive_columns < 1 || $archive_columns > 4 ) { $archive_columns = 3; } return array( 'archive_mode' => $archive_mode, 'archive_show_featured' => ! empty( $settings['archive_show_featured'] ) ? 1 : 0, 'archive_show_excerpt' => ! empty( $settings['archive_show_excerpt'] ) ? 1 : 0, 'archive_show_meta' => ! empty( $settings['archive_show_meta'] ) ? 1 : 0, 'archive_columns' => $archive_columns, 'archive_intro' => sanitize_textarea_field( $settings['archive_intro'] ?? '' ), ); } public function get_cpt_template_settings( $post_type ) { $record = $this->get_any_managed_cpt_by_key( $post_type ); return $record['template_settings'] ?? $this->normalize_cpt_template_settings( array() ); } public function get_taxonomy_template_settings( $taxonomy ) { $record = $this->get_taxonomy_by_key( $taxonomy ) ?: $this->get_taxonomy_override_by_key( $taxonomy ); return $record['template_settings'] ?? $this->normalize_taxonomy_template_settings( array() ); } public function get_export_payload() { return array( 'plugin' => 'ansico-cpt-and-taxonomies', 'version' => ANSICO_CPTAX_VERSION, 'exported_at_gmt' => gmdate( 'c' ), 'cpts' => $this->get_cpts(), 'taxonomies' => $this->get_taxonomies(), 'cpt_overrides' => $this->get_cpt_overrides(), 'taxonomy_overrides' => $this->get_taxonomy_overrides(), ); } public function register_taxonomies() { foreach ( $this->get_taxonomies() as $taxonomy ) { if ( empty( $taxonomy['key'] ) ) { continue; } $attached_post_types = isset( $taxonomy['object_type'] ) && is_array( $taxonomy['object_type'] ) ? array_filter( $taxonomy['object_type'] ) : array( 'post' ); if ( empty( $attached_post_types ) ) { $attached_post_types = array( 'post' ); } register_taxonomy( $taxonomy['key'], $attached_post_types, $this->build_taxonomy_args( $taxonomy ) ); } } public function register_post_types() { foreach ( $this->get_cpts() as $cpt ) { if ( empty( $cpt['key'] ) ) { continue; } register_post_type( $cpt['key'], $this->build_post_type_args( $cpt ) ); } } public function build_taxonomy_args( $taxonomy, $existing_args = array() ) { $singular = $taxonomy['singular_label'] ?? ucfirst( $taxonomy['key'] ); $plural = $taxonomy['plural_label'] ?? $singular . 's'; $slug = $taxonomy['slug'] ?? $taxonomy['key']; $hierarchical = ! empty( $taxonomy['hierarchical'] ); $labels = array( 'name' => $plural, 'singular_name' => $singular, 'search_items' => sprintf( __( 'Search %s', 'ansico-cpt-and-taxonomies' ), $plural ), 'all_items' => sprintf( __( 'All %s', 'ansico-cpt-and-taxonomies' ), $plural ), 'parent_item' => sprintf( __( 'Parent %s', 'ansico-cpt-and-taxonomies' ), $singular ), 'parent_item_colon' => sprintf( __( 'Parent %s:', 'ansico-cpt-and-taxonomies' ), $singular ), 'edit_item' => sprintf( __( 'Edit %s', 'ansico-cpt-and-taxonomies' ), $singular ), 'update_item' => sprintf( __( 'Update %s', 'ansico-cpt-and-taxonomies' ), $singular ), 'add_new_item' => sprintf( __( 'Add New %s', 'ansico-cpt-and-taxonomies' ), $singular ), 'new_item_name' => sprintf( __( 'New %s Name', 'ansico-cpt-and-taxonomies' ), $singular ), 'menu_name' => $plural, ); return array_merge( $existing_args, array( 'labels' => $labels, 'public' => $existing_args['public'] ?? true, 'show_ui' => $existing_args['show_ui'] ?? true, 'show_admin_column' => $existing_args['show_admin_column'] ?? true, 'show_in_nav_menus' => $existing_args['show_in_nav_menus'] ?? true, 'show_tagcloud' => ! $hierarchical, 'show_in_rest' => $existing_args['show_in_rest'] ?? true, 'hierarchical' => $hierarchical, 'rewrite' => array( 'slug' => sanitize_title( $slug ) ), ) ); } public function build_post_type_args( $cpt, $existing_args = array() ) { $singular = $cpt['singular_label'] ?? ucfirst( $cpt['key'] ); $plural = $cpt['plural_label'] ?? $singular . 's'; $slug = $cpt['slug'] ?? $cpt['key']; $supports = isset( $cpt['supports'] ) && is_array( $cpt['supports'] ) ? array_values( array_filter( $cpt['supports'] ) ) : array( 'title', 'editor' ); $taxonomies = isset( $cpt['taxonomies'] ) && is_array( $cpt['taxonomies'] ) ? array_values( array_filter( $cpt['taxonomies'] ) ) : array(); if ( ! in_array( 'custom-fields', $supports, true ) && ! empty( $cpt['custom_fields'] ) ) { $supports[] = 'custom-fields'; } $labels = array( 'name' => $plural, 'singular_name' => $singular, 'menu_name' => $plural, 'name_admin_bar' => $singular, 'add_new' => __( 'Add New', 'ansico-cpt-and-taxonomies' ), 'add_new_item' => sprintf( __( 'Add New %s', 'ansico-cpt-and-taxonomies' ), $singular ), 'new_item' => sprintf( __( 'New %s', 'ansico-cpt-and-taxonomies' ), $singular ), 'edit_item' => sprintf( __( 'Edit %s', 'ansico-cpt-and-taxonomies' ), $singular ), 'view_item' => sprintf( __( 'View %s', 'ansico-cpt-and-taxonomies' ), $singular ), 'all_items' => sprintf( __( 'All %s', 'ansico-cpt-and-taxonomies' ), $plural ), 'search_items' => sprintf( __( 'Search %s', 'ansico-cpt-and-taxonomies' ), $plural ), 'parent_item_colon' => sprintf( __( 'Parent %s:', 'ansico-cpt-and-taxonomies' ), $singular ), 'not_found' => sprintf( __( 'No %s found.', 'ansico-cpt-and-taxonomies' ), strtolower( $plural ) ), 'not_found_in_trash' => sprintf( __( 'No %s found in Trash.', 'ansico-cpt-and-taxonomies' ), strtolower( $plural ) ), 'featured_image' => __( 'Featured image', 'ansico-cpt-and-taxonomies' ), 'set_featured_image' => __( 'Set featured image', 'ansico-cpt-and-taxonomies' ), 'remove_featured_image' => __( 'Remove featured image', 'ansico-cpt-and-taxonomies' ), 'use_featured_image' => __( 'Use as featured image', 'ansico-cpt-and-taxonomies' ), 'archives' => sprintf( __( '%s archives', 'ansico-cpt-and-taxonomies' ), $singular ), ); return array_merge( $existing_args, array( 'labels' => $labels, 'public' => $existing_args['public'] ?? true, 'show_ui' => $existing_args['show_ui'] ?? true, 'show_in_menu' => $existing_args['show_in_menu'] ?? true, 'show_in_rest' => $existing_args['show_in_rest'] ?? true, 'has_archive' => $existing_args['has_archive'] ?? true, 'rewrite' => array( 'slug' => sanitize_title( $slug ) ), 'exclude_from_search' => ! empty( $cpt['exclude_from_search'] ), 'can_export' => ! empty( $cpt['can_export'] ), 'supports' => $supports, 'taxonomies' => $taxonomies, 'menu_position' => $existing_args['menu_position'] ?? 20, 'menu_icon' => $existing_args['menu_icon'] ?? 'dashicons-admin-post', ) ); } public function filter_post_type_args( $args, $post_type ) { $override = $this->get_cpt_override_by_key( $post_type ); if ( ! $override ) { return $args; } return $this->build_post_type_args( $override, $args ); } public function filter_taxonomy_args( $args, $taxonomy ) { $override = $this->get_taxonomy_override_by_key( $taxonomy ); if ( ! $override ) { return $args; } return $this->build_taxonomy_args( $override, $args ); } public function attach_overridden_taxonomies_to_objects() { foreach ( $this->get_cpt_overrides() as $override ) { if ( empty( $override['key'] ) || empty( $override['taxonomies'] ) || ! is_array( $override['taxonomies'] ) ) { continue; } foreach ( $override['taxonomies'] as $taxonomy ) { if ( taxonomy_exists( $taxonomy ) ) { register_taxonomy_for_object_type( $taxonomy, $override['key'] ); } } } foreach ( $this->get_taxonomy_overrides() as $override ) { if ( empty( $override['key'] ) || empty( $override['object_type'] ) || ! is_array( $override['object_type'] ) ) { continue; } foreach ( $override['object_type'] as $object_type ) { if ( post_type_exists( $object_type ) ) { register_taxonomy_for_object_type( $override['key'], $object_type ); } } } } public function register_meta_boxes() { foreach ( $this->get_all_managed_cpts() as $cpt ) { if ( empty( $cpt['key'] ) || empty( $cpt['custom_fields'] ) || ! is_array( $cpt['custom_fields'] ) ) { continue; } add_meta_box( 'ansico_cptax_fields_' . $cpt['key'], __( 'Custom Fields', 'ansico-cpt-and-taxonomies' ), array( $this, 'render_meta_box' ), $cpt['key'], 'normal', 'default', array( 'fields' => $cpt['custom_fields'] ) ); } } public function render_meta_box( $post, $box ) { $fields = $box['args']['fields'] ?? array(); wp_nonce_field( 'ansico_cptax_save_fields', 'ansico_cptax_nonce' ); echo '
| '; echo ' | ';
switch ( $type ) {
case 'textarea':
echo '';
break;
case 'checkbox':
echo '';
break;
case 'select':
echo '';
break;
case 'radio':
foreach ( $options as $index => $option ) {
echo '';
}
break;
default:
echo '';
break;
}
if ( $description ) {
echo ' ' . esc_html( $description ) . ' '; } echo ' | ';
echo '
|---|