Ok, a few things I see here.
Your function is a copy of the original hook which still exists and still fires on every “init” (every page load, front or back).
Yours only fires when switching to your theme but never after that.
Also that function doesn’t write to the database, it checks for values and if it doesn’t find any under “elementor_cpt_support” it will default to using [ ‘page’, ‘post’, ‘portfolio’ ] as the value for $cpt_support and then loop through each of the types via “add_post_type_support”…but again, the issue is it only applies in your theme’s activation instance and not every time moving forward which explains why it’s not working when you navigate to a portfolio post type – you’re no longer activating the theme and your function doesn’t run.
The Elementor function continues to be used and doesn’t see “elementor_cpt_support” in the database so it supports only the 2 types which it defines as default. (back to square one)
This is fine though…because you want to use Elementor’s original check against the db anyway, only after your theme has prepared it.
You basically want to check if the db options exists, if it doesn’t, write your defaults, if it does, check to see if it already has your post type and if it doesn’t, update it…otherwise you’re good to go.
function mytheme_add_cpt_support() {
//if exists, assign to $cpt_support var
$cpt_support = get_option( 'elementor_cpt_support' );
//check if option DOESN'T exist in db
if( ! $cpt_support ) {
$cpt_support = [ 'page', 'post', 'portfolio' ]; //create array of our default supported post types
update_option( 'elementor_cpt_support', $cpt_support ); //write it to the database
}
//if it DOES exist, but portfolio is NOT defined
else if( ! in_array( 'portfolio', $cpt_support ) ) {
$cpt_support[] = 'portfolio'; //append to array
update_option( 'elementor_cpt_support', $cpt_support ); //update database
}
//otherwise do nothing, portfolio already exists in elementor_cpt_support option
}
add_action( 'after_switch_theme', 'mytheme_add_cpt_support' );