SEO-friendly URLs for 3 post types and 3 taxonomies (immediately for these three types)

TASK

1) Post type `rc` (reabilitacionnye-centry)
		Post type    Taxonomy hierarchical                             Taxonomy flat 2 elements     post_name
					  `city_location` - Country/Region/City    `clinic_type`
	dom/rc            /rossiya/lipetskayz-oblast/lipeck         /chastnie                    /reabilitacionnii-centr-piramida
	dom/rc            /rossiya/lipetskayz-oblast/lipeck         /chastnie
	dom/rc            /rossiya/lipetskayz-oblast/lipeck

2) Post type `clinic` - similar to rc
		Post type    Taxonomy hierarchical                             Taxonomy flat 2 elements     post_name
					  `city_location` - Country/Region/City    `clinic_type`
	dom/clinic        /rossiya/lipetskayz-oblast/lipeck         /chastnie                   /reabilitacionnii-centr-piramida
	dom/clinic        /rossiya/lipetskayz-oblast/lipeck         /chastnie
	dom/clinic        /rossiya/lipetskayz-oblast/lipeck

3) Post type `specialist`
		Post type     Taxonomy hierarchical                       Taxonomy flat 50+ elements  post_name
					   `city_location`                    `specialty`
	dom/specialist    /rossiya/lipetskayz-oblast/lipeck   /specialty             /name
	dom/specialist    /rossiya/lipetskayz-oblast/lipeck   /specialty
	dom/specialist    /rossiya/lipetskayz-oblast/lipeck
<?php

// require_once get_stylesheet_directory() . '/_register_cpt_rerwrite_rules.php';

## registration of post types and taxonomies
add_action( 'init', 'register_post_types_2019_02_10', 0 );
function register_post_types_2019_02_10(){

	// Taxonomy - City: country/region/city
	register_taxonomy( 'city_location', ['rc','clinic','specialist'], [
		'labels' => [
			'name'           => 'Cities',
			'singular_name'  => 'City',
		],
		// IMPORTANT! The element must always be the 3rd level - Country/region/city
		'rewrite' => [
			'slug'         => 'rc',
			'hierarchical' => true,
			'with_front'   => 0,
			'feed'         => 0,
		],
		'hierarchical'       => true,
		'public'             => true,
		'show_admin_column'  => true,
		'show_in_nav_menus'  => true,
		//'update_count_callback' => 'city_location_update_count_callback',
	] );

	// Taxonomy - Type: Government/Private
	register_taxonomy( 'clinic_type', ['rc','clinic'], [
		'labels' => [
			'name'          => 'Type (clinics)',
			'singular_name' => 'Type (clinics)',
			'menu_name'     => 'Type (clinics)'
		],
		'hierarchical'       => true,
		'public'             => false,
		'rewrite'            => false,
		'query_var'          => true, // query_var, so that the request for the term works...
		'publicly_queryable' => true, // query_var, so that the request for the term works...
		'show_ui'            => true,
		'show_in_quick_edit' => true,
		'show_tagcloud'      => false,
		'show_admin_column'  => true,
		'show_in_nav_menus'  => false,
	] );

	// Taxonomy - Specialty: Programmer/Dentist/...
	register_taxonomy( 'specialty', ['specialist'], [
		'labels' => [
			'name'          => 'Specialties',
			'singular_name' => 'Specialty',
			'menu_name'     => 'Specialty'
		],
		'hierarchical'       => true,
		'public'             => false,
		'rewrite'            => false,
		'query_var'          => true, // query_var, so that the request for the term works...
		'publicly_queryable' => true, // query_var, so that the request for the term works...
		'show_ui'            => true,
		'show_in_quick_edit' => true,
		'show_tagcloud'      => false,
		'show_admin_column'  => true,
		'show_in_nav_menus'  => false,
	] );

	// Post type - rc
	register_post_type( 'rc', [
		'labels' => [
			'name'          => 'Regional Centers',
			'singular_name' => 'RCenter',
		],
		'taxonomies'          => [ 'city_location', 'clinic_type' ],
		'public'              => true,
		'query_var'           => true,
		'rewrite'             => [
			'slug'       => 'rc/%city_location%/%clinic_type%', // + /%post_name%
			'with_front' => false,
			'feeds'      => false,
			'pages'      => false,
			'paged'      => false,
			'feed'       => false,
		],
		'show_in_menu'        => true,
		'has_archive'         => true,
		'supports'            => [ 'title', 'editor', 'author', 'thumbnail', 'excerpt', 'custom-fields', 'revisions' ],
		'show_ui'             => true,
		'show_in_nav_menus'   => false,
		'menu_icon' => 'dashicons-editor-ul',
	] );

	// Post type - clinic
	register_post_type( 'clinic', [
		'labels' => [
			'name'          => 'Clinics',
			'singular_name' => 'Clinic',
		],
		'taxonomies' => [ 'city_location', 'clinic_type' ],
		'public'     => true,
		'query_var'  => true,
		'rewrite'    => [
			'slug'       => 'clinic/%city_location%/%clinic_type%', // + /%post_name%
			'with_front' => false,
			'feeds'      => false,
			'pages'      => false,
			'paged'      => false,
			'feed'       => false,
		],
		'show_in_menu'      => true,
		'has_archive'       => true,
		'supports'          => [ 'title', 'editor', 'author', 'thumbnail', 'excerpt', 'custom-fields', 'revisions' ],
		'show_ui'           => true,
		'show_in_nav_menus' => false,
		'menu_icon'         => 'dashicons-editor-ul',
	] );

	// Post type - specialist
	register_post_type( 'specialist', [
		'labels' => [
			'name'          => 'Specialists',
			'singular_name' => 'Specialist',
		],
		'taxonomies' => [ 'city_location', 'specialty' ],
		'public'     => true,
		'query_var'  => true,
		'rewrite'    => [
			'slug'       => 'specialist/%city_location%/%specialty%', // + /%post_name%
			'with_front' => false,
			'feeds'      => false,
			'pages'      => false,
			'paged'      => false,
			'feed'       => false,
		],
		'show_in_menu'      => true,
		'has_archive'       => true,
		'supports'          => [ 'title', 'editor', 'author', 'thumbnail', 'excerpt', 'custom-fields', 'revisions' ],
		'show_ui'           => true,
		'show_in_nav_menus' => false,
		'menu_icon' => 'dashicons-groups',
	] );

	if( 'SEO' ){

		//add_action('wp', 'xxxxxxx'); // debug
		function xxxxxxx($wp){
			print_r( get_queried_object() );
			print_r( $wp );
			print_r( $GLOBALS['wp_rewrite'] );
			exit;
		}

		## adjust query parameters
		add_action( 'request', function( $vars ){

			if( !empty($vars['city_location']) ){

				$_city_location = explode( '/', $vars['city_location'] );
				$_end = end( $_city_location );

				// caching works
				if( ! $trans_data = chpu_term_names_cache('get') ){
					$trans_data = chpu_term_names_cache('set');
				}

				if( in_array( $_end, $trans_data['clinic_types']) ){
					$vars['clinic_type'] = array_pop( $_city_location );
					$_end = end( $_city_location );
				}

				if( in_array( $_end, $trans_data['specialties']) ){
					$vars['specialty'] = array_pop( $_city_location );
					$_end = end( $_city_location );
				}

				$vars['city_location'] = $_end; // last element
			}

			return $vars;
		} );

		## Rebuild rewrite rules for post types
		## '(post_type)_rewrite_rules'
		foreach( ['rc','clinic','specialist'] as $post_type ){

			add_filter( $post_type .'_rewrite_rules', function( $rules ) use ( $post_type ){

				$key = '('. $post_type . ')/('. '[^/]+/[^/]+/[^/]+' /*country/region/city*/ .')/([^/]+)/([^/]+)/?$';
				//$key = '('. $post_type . ')/(.+?)/([^/]+)/([^/]+)/?$';

				if( 'specialist' === $post_type )
					$val = 'index.php?post_type=$matches[1]&city_location=$matches[2]&specialty=$matches[3]&name=$matches[4]';
				else
					$val = 'index.php?post_type=$matches[1]&city_location=$matches[2]&clinic_type=$matches[3]&name=$matches[4]';

				return [
					$key              => $val,
					"($post_type)/?$" => 'index.php?post_type=$matches[1]',
				];
			} );

		}

		## add rewrite rules for 'city_location'
		## 'city_location'.'_rewrite_rules'
		add_filter( 'city_location'.'_rewrite_rules', function( $rules ){

			/*
			[rc/(.+?)/page/?([0-9]{1,})/?$] => index.php?city_location=$matches[1]&paged=$matches[2]
			[rc/(.+?)/?$] => index.php?city_location=$matches[1]
			*/

			// must be after the post type rules for 'realty'
			$_first_part = '(rc|clinic|specialist)/(.+?)';
			$_pade_part  = 'page/?([0-9]{1,})';

			$rules = [
				"$_first_part/$_pade_part/?$" => 'index.php?post_type=$matches[1]&city_location=$matches[2]&paged=$matches[3]',
				"$_first_part/?$"             => 'index.php?post_type=$matches[1]&city_location=$matches[2]',
			];

			return $rules;
		} );

		## Fill in the permalink for the post type
		add_filter( 'post_type_link', 'rc_permalink', 1, 2 );
		function rc_permalink( $permalink, $post ){
			if( false === strpos($permalink, '%city_location%') )
				return $permalink;

			return strtr( $permalink, [
				'%city_location%' => __build_tax_uri( get_the_terms( $post, 'city_location') ), // multiple levels - asd/asd
				'%clinic_type%'   => __build_tax_uri( get_the_terms( $post, 'clinic_type') ),   // one level - asd
				'%specialty%'     => __build_tax_uri( get_the_terms( $post, 'specialty') ),     // one level - asd
			] );
		}

		## Gets the chain of labels for the specified term - 'parent/child/child'
		function __build_tax_uri( $terms ){
			if( is_wp_error($terms) || empty($terms) || ! ( is_object(reset($terms)) || is_object($terms) ) )
				return 'no_terms'; // no term in taxonomy, but it should be...

			$term = is_object(reset($terms)) ? reset($terms) : $terms;
			$path = array( $term->slug );
			while( $term->parent ){
				$term = get_term( $term->parent );
				$path[] = $term->slug;
			}

			return implode( '/', array_reverse($path) );
		}

		## Reset the cache when a term is updated
		add_action( 'edited_term',  'update_cache_chpu_term_names_hook', 10, 3 );
		add_action( 'created_term', 'update_cache_chpu_term_names_hook', 10, 3 );
		add_action( 'delete_term',  'update_cache_chpu_term_names_hook', 10, 3 );
		function update_cache_chpu_term_names_hook( $term_id, $tt_id, $taxonomy ){
			if( in_array( $taxonomy, ['clinic_type','specialty']) )
				chpu_term_names_cache( 'set' );
		}

		function chpu_term_names_cache( $action = 'get' ){

			$opt_name = 'chpu_term_names_cache';

			if( 'get' === $action ){
				return get_option( $opt_name );
			}

			if( 'clear' === $action ){
				update_option( $opt_name, '' );
			}

			if( 'set' === $action ){
				$clinic_types = get_terms([
					'taxonomy' => 'clinic_type',
					'fields'   => 'id=>slug',
				]);

				$specialties  = get_terms([
					'taxonomy' => 'specialty',
					'fields'   => 'id=>slug',
				]);

				$data = [
					'clinic_types' => $clinic_types,
					'specialties'  => $specialties
				];

				update_option( $opt_name, $data );

				return $data;
			}

		}

	}

}

## remove the selected term from the top in the checkbox list of terms
add_filter( 'wp_terms_checklist_args', 'set_checked_ontop_default', 10 );
function set_checked_ontop_default( $args ){
	// change the default parameter to false
	if( ! isset($args['checked_ontop']) )
		$args['checked_ontop'] = false;

	return $args;
}

## Remove the "All Categories" and "Most Used" tabs from the taxonomy meta boxes on the post edit screen.
add_action( 'admin_print_footer_scripts', 'hide_tax_metabox_tabs_admin_styles', 99 );
function hide_tax_metabox_tabs_admin_styles(){
	$cs = get_current_screen();
	if( $cs->base !== 'post' || empty($cs->post_type) ) return; // not on the post edit page
?>
<style>
	.postbox div.tabs-panel{ max-height:1200px; border:0; }
	.category-tabs{ display:none; }
</style>
<?php
}

## Convert checkboxes to radios on the post edit pages
add_action( 'admin_print_footer_scripts', 'func_hook_admin_footer_scripts', 99 );
function func_hook_admin_footer_scripts(){
	if( get_current_screen()->base !== 'post' )
		return;
?>
<script>
[ 'city_location', 'clinic_type' ].forEach(function(taxname){
	jQuery( '#' + taxname + 'div input[type="checkbox"]' ).prop( 'type', 'radio' );
})
</script>
<?php
}