Shoora
9/10/2019 - 4:44 AM

wp-generate-dynamic-post-types-sub-pages.php

<?php

add_filter('acf/settings/remove_wp_meta_box', '__return_false');

// Post Type Subpages: Settings
function hwk_ptsp_settings(){
    $settings = array(
        
        array(
            // Le Post Type cible.
            'post_type'     => 'portfolio',
            
            // Le prefixe des Post Meta afin de définir les permaliens.
            'meta_prefix'   => 'slug_',
            
            // Ajout des pages dynamiques.
            'pages'         => array(
                array(
                    
                    // Titre qui sert à l'affichage.
                    'title'         => 'Présentation',
                    
                    // Slug des Query Vars, mais aussi des URL si aucun paramètre 'rewrite' n'est défini.
                    'name'          => 'presentation',
                    
                    // Activation de l'URL dynamique. Ajout d'un prefixe et/ou d'un suffixe pour cette page.
                    'rewrite'       => array(
                        'prepend'       => 'presentation',
                        'append'        => 'intro',
                    ),
                    
                    // Remplacer l'URL de base du Post Type?
                    'primary'       => true,
                    
                    // Activer la pagination dans les pages. Exemple: /page/2/.
                    'pagination'    => false,
                    
                    // Chemin du template à afficher. En partant de la racine du thème.
                    'template'      => 'single-portfolio.php'
                ),
                
                array(
                    'title'         => 'Vidéos',
                    'name'          => 'videos',
                    'primary'       => false,
                    'pagination'    => true,
                    'template'      => 'single-portfolio-videos.php'
                ),
                
                array(
                    'title'         => 'Photos',
                    'name'          => 'photos',
                    'rewrite'       => array(
                        'prepend'       => 'photos',
                        'append'        => 'flickr',
                    ),
                    'primary'       => false,
                    'pagination'    => true,
                    'template'      => 'single-portfolio-photos.php'
                )
            )
        )
        
    );
    
    return $settings;
}

// Post Type Subpages: Settings Get Post Types
function hwk_ptsp_get_post_types(){
    if(!$settings = hwk_ptsp_settings())
        return false;
    
    return $settings;
}

// Post Type Subpages: Settings Get Post Type
function hwk_ptsp_get_post_type($target_post_type){
    if(!$post_types = hwk_ptsp_get_post_types())
        return false;
    
    foreach($post_types as $post_type){
        if($post_type['post_type'] != $target_post_type)
            continue;
        
        return $post_type;
    }
    
    return false;
}

// Post Type Subpages: Settings Get Post Type Rewrite
function hwk_ptsp_get_post_type_rewrite($post_type){
    if(!($post_type_object = get_post_type_object($post_type)) || !($post_type_object_rewrite = $post_type_object->rewrite))
        return false;
    
    return $post_type_object_rewrite['slug'];
}

// Post Type Subpages: Settings Post Type has Primary
function hwk_ptsp_post_type_has_primary($target_post_type){
    if(!$post_types = hwk_ptsp_get_post_types())
        return;
    
    foreach($post_types as $post_type){
        if($post_type['post_type'] != $target_post_type)
            continue;
        
        foreach($post_type['pages'] as $page){
            if($page['primary'])
                return $page;
        }
    }
    
    return false;
}

// Post Type Subpages: Settings Get Page
function hwk_ptsp_get_page($page_name, $target_post_type){
    if( !($post_type = hwk_ptsp_get_post_type($target_post_type)) || !isset($post_type['pages']) || empty($post_type['pages']) )
        return false;

    foreach($post_type['pages'] as $page){
        if($page['name'] != $page_name)
            continue;
        
        return $page;
    }
    
    return false;
}

// Post Type Subpages: Settings Page has Rewrite
function hwk_ptsp_page_has_rewrite($page){
    if( isset($page['rewrite']) && (isset($page['rewrite']['prepend']) || isset($page['rewrite']['append'])) )
        return $page['rewrite'];
    
    return false;
}

// Post Type Subpages: Settings Get Page Rewrite Output
function hwk_ptsp_get_page_rewrite_output($page, $slug){
    
    if(!hwk_ptsp_page_has_rewrite($page))
        return $page['name'];
    
    if(isset($page['rewrite']['prepend']) && !empty($page['rewrite']['prepend']))
        $slug = $page['rewrite']['prepend'] . '-' . $slug;
    
    if(isset($page['rewrite']['append']) && !empty($page['rewrite']['append']))
        $slug .= '-' . $page['rewrite']['append'];
    
    return $slug;
    
}

// Post Type Subpages: Rewrite Rules
add_action('generate_rewrite_rules', 'hwk_ptsp_rewrite_rules');
function hwk_ptsp_rewrite_rules($wp_rewrite){
    if(!$post_types = hwk_ptsp_get_post_types())
        return;
    
    $wp_rules   = $wp_rewrite->rules;
	$new_rules  = array();
    
    foreach($post_types as $post_type){
        if(!$post_type_rewrite = hwk_ptsp_get_post_type_rewrite($post_type['post_type']))
            continue;
        
        foreach($post_type['pages'] as $page){
            $tag = '([^/]+)';
            $prepend = $append = false;
            if(hwk_ptsp_page_has_rewrite($page)){
                if(isset($page['rewrite']['prepend']) && !empty($page['rewrite']['prepend']))
                    $tag = $page['rewrite']['prepend'] . '-' . $tag;
                
                if(isset($page['rewrite']['append']) && !empty($page['rewrite']['append']))
                    $tag .= '-' . $page['rewrite']['append'];
                
                $match = '&' . $page['name'] . '=$matches[2]';
                $paged = '&paged=$matches[3]';
                
            }else{
                $tag = $page['name'];
                $match = '&' . $page['name'] . '=' . $page['name'];
                $paged = '&paged=$matches[2]';
                
            }
            
            if($page['pagination'])
                $new_rules[$post_type_rewrite . '/([^/]+)/' . $tag . '/page/([0-9]{1,})/?$'] = 'index.php?' . $post_type['post_type'] . '=$matches[1]' . $match . $paged;
            
            $new_rules[$post_type_rewrite . '/([^/]+)/' . $tag . '/?$'] = 'index.php?' . $post_type['post_type'] . '=$matches[1]' . $match;
        }
    }

	$wp_rewrite->rules = array_merge($new_rules, $wp_rules);
}

// Post Type Subpages: Query Vars
add_filter('query_vars', 'hwk_ptsp_query_vars');
function hwk_ptsp_query_vars($vars){
    if(!$post_types = hwk_ptsp_get_post_types())
        return $vars;
    
    foreach($post_types as $post_type){
        foreach($post_type['pages'] as $page){
            $vars[] = $page['name'];
        }
    }

    return $vars;
}

// Post Type Subpages: Redirect
add_action('template_redirect', 'hwk_ptsp_redirect');
function hwk_ptsp_redirect(){
    if( !($post_id = get_the_ID()) || !($post_types = hwk_ptsp_get_post_types()) )
        return;
    
    foreach($post_types as $post_type){
        if(!is_singular($post_type['post_type']))
            continue;
        
        $query_var = false;
        foreach($post_type['pages'] as $page){
            if(get_query_var($page['name'])){
                $query_var = true;
                
                // Si pas de Page Rewrite et Query Var différent de la page OU Page Rewrite activé et Page Meta disponible mais ne correspond pas au Query Var: Redirection
                $has_rewrite = hwk_ptsp_page_has_rewrite($page);
                if( (!$has_rewrite && get_query_var($page['name']) != $page['name']) || ( $has_rewrite && ($slug = get_post_meta($post_id, $post_type['meta_prefix'] . $page['name'], true)) && get_query_var($page['name']) != $slug ) )
                    return wp_redirect(hwk_ptsp_get_sub_permalink($post_id, $page['name']), 301);
            }
            
        }
        
        // Aucune Query Var et le Post Type a une Page Primaire
        if(!$query_var && hwk_ptsp_post_type_has_primary($post_type['post_type']))
            return wp_redirect(get_permalink($post_id), 301);
    }
}

// Post Type Subpages: Template
add_filter('template_include', 'hwk_ptsp_template');
function hwk_ptsp_template($template){
    if( !($post_id = get_the_ID()) || !($post_types = hwk_ptsp_get_post_types()) )
        return;
    
    foreach($post_types as $post_type){
        if(!is_singular($post_type['post_type']))
            continue;
        
        foreach($post_type['pages'] as $page){
            
            // Template de la Page par défaut
            if( get_query_var($page['name']) && ($new_template = locate_template(array($page['template']))) )
                return $new_template;
            
        }
    }
    
    return $template;
}

// Post Type Subpages: Save Post Slug
add_action('save_post', 'hwk_ptsp_save_post', 10, 2);
function hwk_ptsp_save_post($post_id, $post){
    if(!$post_type = hwk_ptsp_get_post_type($post->post_type))
        return;
        
    // Aucun Meta Parent: Création du meta par défaut
    if(!get_post_meta($post_id, $post_type['meta_prefix'] . 'parent', true))
        update_post_meta($post_id, $post_type['meta_prefix'] . 'parent', get_post_field('post_name', $post_id));
    
    // Aucun Meta Page: Création des metas par défaut
    foreach($post_type['pages'] as $page){
        if( !get_post_meta($post_id, $post_type['meta_prefix'] . $page['name'], true) && hwk_ptsp_page_has_rewrite($page) )
            update_post_meta($post_id, $post_type['meta_prefix'] . $page['name'], get_post_field('post_name', $post_id));
        
    }
    
    // Meta Parent: Sanitize & Update du post->name
    if( ($new_slug = get_post_meta($post_id, $post_type['meta_prefix'] . 'parent', true)) && $new_slug != $post->post_name){
        $new_slug = sanitize_title($new_slug);
        wp_update_post(array(
            'ID'        => $post_id,
            'post_name' => $new_slug
        ));
    }
}

// Post Type Subpages: Update Meta
add_action('added_post_meta',   'hwk_ptsp_update_meta', 10, 4);
add_action('updated_post_meta', 'hwk_ptsp_update_meta', 10, 4);
function hwk_ptsp_update_meta($meta_id, $post_id, $meta_key, $meta_value){
    if(!$post_type = hwk_ptsp_get_post_type(get_post_type($post_id)))
        return;
    
    // Meta Parent: Sanitize & Update du post->name
    if($meta_key == $post_type['meta_prefix'] . 'parent'){
        $new_slug = sanitize_title($meta_value);
        update_post_meta($post_id, $post_type['meta_prefix'] . 'parent', $new_slug);
        return wp_update_post(array(
            'ID'        => $post_id,
            'post_name' => $new_slug
        ));
    }
    
    foreach($post_type['pages'] as $page){
        if($meta_key != $post_type['meta_prefix'] . $page['name'])
            continue;
        
        // Meta Page: Sanitize & Update
        return update_post_meta($post_id, $post_type['meta_prefix'] . $page['name'], sanitize_title($meta_value));
    }
}

// Post Type Subpages: Get Permalink
add_filter('post_link',         'hwk_ptsp_get_permalink', 10, 3);
add_filter('post_type_link',    'hwk_ptsp_get_permalink', 10, 3);
function hwk_ptsp_get_permalink($permalink, $post){
    if(!$post_types = hwk_ptsp_get_post_types())
        return $permalink;
    
    foreach($post_types as $post_type){
        
        // Mauvais Post Type ou le Post Type n'a pas de Page Primaire ou le Post Type n'a pas de Rewrite configuré
        if(!isset($post->post_type) || $post->post_type != $post_type['post_type'] || !hwk_ptsp_post_type_has_primary($post_type['post_type']) || !($post_type_rewrite = hwk_ptsp_get_post_type_rewrite($post_type['post_type'])))
            continue;
        
        foreach($post_type['pages'] as $page){
            
            // La Page n'est pas Primaire
            if(!$page['primary'])
                continue;
            
            // Page Primaire activée - Pas de paramètre Rewrite: Afficher le Page Name de base
            if( !hwk_ptsp_page_has_rewrite($page) )
                return home_url(user_trailingslashit($post_type_rewrite . '/' . $post->post_name . '/' . $page['name']));
            
            // Page Primaire activée - Paramètre Rewrite: Afficher l'URL dynamique
            if( ($slug = get_post_meta($post->ID, $post_type['meta_prefix'] . $page['name'], true)) && !empty($slug) )
                return home_url(user_trailingslashit($post_type_rewrite . '/' . $post->post_name . '/' . hwk_ptsp_get_page_rewrite_output($page, $slug) ));
            
        }
    }

    return $permalink;
}

// Post Type Subpages: Get Sub Permalink
function hwk_ptsp_get_sub_permalink($post_id, $page_name = false){
    if( !$page_name || !($post_types = hwk_ptsp_get_post_types()) )
        return get_permalink($post_id);
    
    foreach($post_types as $post_type){
        
        // Mauvais Post Type ou le Post Type n'a pas de Rewrite activé
        if( get_post_type($post_id) != $post_type['post_type'] || !($post_type_rewrite = hwk_ptsp_get_post_type_rewrite($post_type['post_type'])) )
            continue;
        
        // Si la Page n'existe pas, retourner l'URL du parent
        if(!$page = hwk_ptsp_get_page($page_name, $post_type['post_type']))
            return get_permalink($post_id);
        
        // Si la page n'a pas de paramètre Rewrite: Afficher le Page Name de base
        if( !hwk_ptsp_page_has_rewrite($page) )
            return home_url(user_trailingslashit($post_type_rewrite . '/' . get_post_field('post_name', $post_id) . '/' . $page['name']));
        
        // Retourner l'URL dynamique
        if( ($slug = get_post_meta($post_id, $post_type['meta_prefix'] . $page_name, true)) && !empty($slug) )
            return home_url(user_trailingslashit( $post_type_rewrite . '/' . get_post_field('post_name', $post_id) . '/' . hwk_ptsp_get_page_rewrite_output($page, $slug) ));
        
    }
    
    return get_permalink($post_id);
}

// Post Type Subpages: Edit After Title
add_action('edit_form_after_title', 'hwk_ptsp_edit_after_title');
function hwk_ptsp_edit_after_title($post){
    if(!$post_types = hwk_ptsp_get_post_types())
        return;
    
    foreach($post_types as $post_type){
        if(get_post_type() != $post_type['post_type'])
            continue;

        foreach($post_type['pages'] as $page){
            if($page['primary'])
                continue;
            
            // Si la page a un paramètre Rewrite et qu'un Post Meta est défini avec un slug: Afficher l'URL
            if( hwk_ptsp_page_has_rewrite($page) && ($slug = get_post_meta($post->ID, $post_type['meta_prefix'] . $page['name'], true)) && !empty($slug) ){
                ?>
                <div id="edit-slug-box">
                    <strong>Permalien <?php echo $page['title']; ?> :</strong>
                    <a href="<?php echo hwk_ptsp_get_sub_permalink($post->ID, $page['name']); ?>"><?php echo hwk_ptsp_get_sub_permalink($post->ID, $page['name']); ?></a>
                </div>
                <?php
                
            }
            
        }
    }
}

// Post Type Subpages: YOAST Hooks
if(function_exists('wpseo_replace_vars')):

    // Post Type Subpages: YOAST Canonical
    add_filter('wpseo_canonical', 'hwk_ptsp_yoast_canonical');
    function hwk_ptsp_yoast_canonical($canonical){
        if( !($post_id = get_the_ID()) || !($post_types = hwk_ptsp_get_post_types()) )
            return $canonical;
        
        foreach($post_types as $post_type){
            if(!is_singular($post_type['post_type']))
                continue;
            
            foreach($post_type['pages'] as $page){
                if(!get_query_var($page['name']))
                    continue;
                
                return hwk_ptsp_get_sub_permalink($post_id, $page['name']);
                
            }
        }
        
        return $canonical;
    }

    // Post Type Subpages: YOAST Title
    add_filter('wpseo_title', 'hwk_ptsp_yoast_title');
    function hwk_ptsp_yoast_title($title){
        if( !($post_id = get_the_ID()) || !($post_types = hwk_ptsp_get_post_types()) )
            return $title;
        
        foreach($post_types as $post_type){
            if(!is_singular($post_type['post_type']))
                continue;
            
            foreach($post_type['pages'] as $page){
                if(!get_query_var($page['name']))
                    continue;
                
                // Page Primaire activée: Retourner le titre du meta Yoast
                if( $page['primary'] && ($yoast_title = get_post_meta($post_id, '_yoast_wpseo_title', true)) && !empty($yoast_title) )
                    return $yoast_title;
                
                // Page Primaire activée: Retourner le titre de l'option Yoast
                if($page['primary'] && ($yoast_titles = get_option('wpseo_titles')) && isset($yoast_titles['title-' . $post_type['post_type']]) && !empty($yoast_titles['title-' . $post_type['post_type']]) )
                    return apply_filters('the_title', wpseo_replace_vars($yoast_titles['title-' . $post_type['post_type']], get_post($post_id)));
                
                // Retourner le titre du meta
                if($meta_title = get_post_meta($post_id, $post_type['meta_prefix'] . $page['name'] . '_meta_title', true) && !empty($meta_title))
                    return $meta_title;
                
                // Retourner le titre de l'option Yoast
                if( ($yoast_titles = get_option('wpseo_titles')) && isset($yoast_titles['title-' . $post_type['post_type']]) && !empty($yoast_titles['title-' . $post_type['post_type']]) )
                    return apply_filters('the_title', wpseo_replace_vars($page['title'] . ' ' . $yoast_titles['title-' . $post_type['post_type']], get_post($post_id)));
                
                // Aucune condition remplis, retourner un titre générique
                return $page['title'] . ' ' . get_the_title($post_id) . ' - ' . get_bloginfo('name');
                    
            }
        }
        
        return $title;
    }

    // Post Type Subpages: YOAST Description
    add_filter('wpseo_metadesc', 'hwk_ptsp_yoast_description');
    function hwk_ptsp_yoast_description($description){
        if( !($post_id = get_the_ID()) || !($post_types = hwk_ptsp_get_post_types()) )
            return $description;
        
        foreach($post_types as $post_type){
            if(!is_singular($post_type['post_type']))
                continue;
            
            foreach($post_type['pages'] as $page){
                if(!get_query_var($page['name']))
                    continue;
                
                // Page Primaire activée: Retourner la description du meta Yoast
                if( $page['primary'] && ($yoast_desc = get_post_meta($post_id, '_yoast_wpseo_desc', true)) && !empty($yoast_desc) )
                    return $yoast_desc;
                
                // Page Primaire activée: Retourner la description de l'option Yoast
                if($page['primary'] && ($yoast_titles = get_option('wpseo_titles')) && isset($yoast_titles['metadesc-' . $post_type['post_type']]) && !empty($yoast_titles['metadesc-' . $post_type['post_type']]) )
                    return apply_filters('the_title', wpseo_replace_vars($yoast_titles['metadesc-' . $post_type['post_type']], get_post($post_id)));
                
                // Retourner la description du meta
                if($meta_desc = get_post_meta($post_id, $post_type['meta_prefix'] . $page['name'] . '_meta_description', true) && !empty($meta_desc))
                    return $meta_desc;
                
                // Retourner la description de l'option Yoast
                if( ($yoast_titles = get_option('wpseo_titles')) && isset($yoast_titles['metadesc-' . $post_type['post_type']]) && !empty($yoast_titles['metadesc-' . $post_type['post_type']]) )
                    return apply_filters('the_title', wpseo_replace_vars($page['title'] . ' ' . $yoast_titles['metadesc-' . $post_type['post_type']], get_post($post_id)));
                
                // Aucune condition remplis, retourner une description générique
                return $page['title'] . ' ' . get_the_title($post_id) . ' - ' . get_bloginfo('name');
                
            }
        }
        
        return $description;
    }

endif;