Custom post type and taxonomy permalinks

Here is some code I’ve cooked up based on some code I’ve already been working on. My original code works okay, however I haven’t tested this code because I haven’t seen your code. Here is what you need to do:

  1. on your post type definition, set the rewrite argument to false

  2. Put the following code after your post type code:

    //Create Permalink for news posts
    function wpse136458_create_permalink( $permalink, $post, $leavename, $sample ) {        
        $rewritecode = array(
            '%year%',
            '%monthnum%',
            '%day%',
            '%hour%',
            '%minute%',
            '%second%',
            $leavename? '' : '%postname%',
            '%post_id%',
            '%category%',
            '%author%',
            $leavename? '' : '%pagename%',
            '%category-news%'
            //Add custom permalink tags here
        );
        if ( '' != $permalink && !in_array($post->post_status, array('draft', 'pending', 'auto-draft')) ) {
            $unixtime = strtotime($post->post_date);
    
            $category = '';
            if ( strpos($permalink, '%category%') !== false ) {
                $cats = get_the_category($post->ID);
                if ( $cats ) {
                    usort($cats, '_usort_terms_by_ID'); // order by ID
                    $category = $cats[0]->slug;
                    if ( $parent = $cats[0]->parent )
                        $category = get_category_parents($parent, false, "https://wordpress.stackexchange.com/", true) . $category;
                }
                // show default category in permalinks, without
                // having to assign it explicitly
                if ( empty($category) ) {
                    $default_category = get_category( get_option( 'default_category' ) );
                    $category = is_wp_error( $default_category ) ? '' : $default_category->slug;
                }
            }
    
            $author="";
            if ( strpos($permalink, '%author%') !== false ) {
                $authordata = get_userdata($post->post_author);
                $author = $authordata->user_nicename;
            }
    
            $date = explode(" ",date('Y m d H i s', $unixtime));
    
            $cat_news="";
            if ( strpos($permalink, '%category-news%') !== false ) {
                $news_terms = wp_get_object_terms( $post->ID, 'category-news' );
                if( $news_terms ) {
                    $cat_news = $news_terms[0]->slug;   
                }
            }
            //Enter permalink manipulations here            
            $rewritereplace = array(
                $date[0],
                $date[1],
                $date[2],
                $date[3],
                $date[4],
                $date[5],
                $post->post_name,
                $post->ID,
                $category,
                $author,
                $post->post_name,
                $cat_news
                //Add custom tag replacements here
            );
            $permalink = str_replace($rewritecode, $rewritereplace, $permalink);
        }
        return $permalink;      
    }
    add_filter( 'post_type_link', 'wpse136458_create_permalink', 10, 4 );
    
    //Helper functions
    function struct_to_query( $struct, $post_type_slug ) {
        global $wp_rewrite  ;
        $querycode = array_merge( $wp_rewrite->queryreplace, array( 'paged=', 'feed=' ) );
        $tagcode = array_merge( $wp_rewrite->rewritecode, array( '%paged%', '%feed%' ) );
        $num_toks = preg_match_all('/%.+?%/', $struct, $toks);
        $tokens = $toks[0];
        $query_result = str_replace( $tagcode, $querycode, $tokens );
        $query_string = '';
        foreach( $query_result as $index => $value ) $query_string .= '&' . $value . '$matches[' . (string)( (int) $index + 1 ). ']';
        return 'index.php?post_type=" . $post_type_slug . $query_string;
    }
    
    function struct_to_regex( $struct ) {
        global $wp_rewrite  ;
        $regexcode = array_merge( $wp_rewrite->rewritereplace, array( "([0-9]{1,})', '(feed|rdf|rss|rss2|atom)' ) );
        $tagcode = array_merge( $wp_rewrite->rewritecode, array( '%paged%', '%feed%' ) );
        return rtrim( str_replace( $tagcode, $regexcode, $struct ), "https://wordpress.stackexchange.com/" ) . '?/?$';
    
    }
    function wpse136458_tax_regex( $taxonomy ) {
        $terms = get_terms( $taxonomy, array( 'hide_empty' => false ) );
        $slugs = wp_list_pluck( $terms, 'slug' );
        return '(' . implode( '|', $slugs) . ')';   
    }
    
    
    //Creates the complex rewrite rules 
    function wpse136458_rewrite_api() {
        add_rewrite_tag( '%category-news%', wpse136458_tax_regex( 'category-news' ) );
        $structs = array(
            '/news/%category-news%/%year/%monthnum%/%day%/page/%paged%/',
            '/news/%category-news%/%year/%monthnum%/%day%/feed/%feed%/',
            '/news/%category-news%/%year/%monthnum%/%day%/%feed%/',
            '/news/%category-news%/%year/%monthnum%/%day%/',
            '/news/%category-news%/%year/%monthnum%/page/%paged%/',
            '/news/%category-news%/%year/%monthnum%/feed/%feed%/',
            '/news/%category-news%/%year/%monthnum%/%feed%/',
            '/news/%category-news%/%year/%monthnum%/',
            '/news/%category-news%/%year/page/%paged%/',
            '/news/%category-news%/%year/feed/%feed%/',
            '/news/%category-news%/%year/%feed%/',
            '/news/%category-news%/%year/',
            '/news/%category-news%/page/%paged%/',
            '/news/%category-news%/feed/%feed%/',
            '/news/%category-news%/%feed%/',
            '/news/%category-news%/%postname%/',
            '/news/%category-news%/',
            '/news/%year/%monthnum%/%day%/page/%paged%/',
            '/news/%year/%monthnum%/%day%/feed/%feed%/',
            '/news/%year/%monthnum%/%day%/%feed%/',
            '/news/%year/%monthnum%/%day%/',
            '/news/%year/%monthnum%/page/%paged%/',
            '/news/%year/%monthnum%/feed/%feed%/',
            '/news/%year/%monthnum%/%feed%/',
            '/news/%year/%monthnum%/',
            '/news/%year/page/%paged%/',
            '/news/%year/feed/%feed%/',
            '/news/%year/%feed%/',
            '/news/%year/',
            '/news/page/%paged%/',
            '/news/feed/%feed%/',
            '/news/%feed%/',
            '/news/',
        );    
    
        foreach( $structs as $struct ) {
            add_rewrite_rule(
                struct_to_regex( $struct ),
                struct_to_query( $struct, 'news' ),
                'top'
            );
        }
    
        //This creates permalinks for news posts
        add_permastruct( 'news', 'news/%category-news%/%postname%/', array( 'walk_dirs' => false, 'endpoints'=>false ) );   
    }
    
    add_action( 'init', 'wpse136458_rewrite_api' );
    
    //Flush rewrite rules when adding, removing or deleting terms
    // Taxonomy created
    add_action( 'created_category-news', 'flush_rewrite_rules' );
    
    // Taxonomy edited
    add_action( 'edited_category-news', 'flush_rewrite_rules' );
    
    // Taxonomy Deleted
    add_action( 'delete_category-news', 'flush_rewrite_rules' );
    

I’ll post an in depth explanation after work. Let me know if it works for you

EDIT: Okay, here is the basic rundown: wpse136458_rewrite_api is the heart of how this works. It basically creates an array of permalink structures made from rewrite tags that follow the rules you specified, then creates the rewrite rules from those structures, using the helper functions struct_to_query (creates the query string) and struct_to_regex (creates the regex). The first line of the function, which I just added, creates a rewrite tag for your category-news taxonomy and the last line that calls add_permastructcreates a permastruct that WP uses for specific news posts.

wpse136458_create_permalink is a callback to the post-type_link filter that takes that news permalink and fills it in with the right data, like the category and the postname