Advertisement
mbis

Rewrite CPT permalinks (alt way #2)

Jan 28th, 2023
834
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. <?php
  2.  
  3. /*
  4.  * Plugin Name: Hersteller/Dienstleistungen permalinks
  5.  * Plugin URI: http://maciejbis.net
  6.  * Description: A plugin that adjusts the functionality of this website
  7.  * Version: 1.0
  8.  * Author: Maciej Bis
  9.  * Author URI: http://www.maciejbis.net
  10.  * License: GPL2
  11. */
  12.  
  13. /**
  14.  * Detect CPT permalinks
  15.  */
  16. function bis_detect_cpt_permalinks( $query ) {
  17.     global $wpdb, $pm_query, $wp, $wp_rewrite, $orte_term;
  18.  
  19.     // 1. Extract the slugs
  20.     preg_match( '/datenrettung-([^\/]+)\/(([^\/]*)(-[^-\/]+)?)(?:\/|$)/Ui', $wp->request, $parts );
  21.  
  22.     if ( ! empty( $parts[2] ) ) {
  23.         $term_slug     = basename( $parts[1] );
  24.         $post_slug     = basename( $parts[2] );
  25.         $post_slug_alt = basename( $parts[3] );
  26.        
  27.         // 2A. Get all posts that have exact or similar slug extracted from URL
  28.         $sql_query = sprintf( 'SELECT ID FROM %1$s WHERE 1=1 AND (
  29.                 (post_type = "dienstleistung" AND (post_name = "%2$s" OR post_name LIKE "%2$s-%%")) OR
  30.                 (post_type = "hersteller" AND (post_name = "%3$s" OR post_name LIKE "%3$s-%%" OR post_name = "%2$s" OR post_name LIKE "%2$s-%%"))
  31.         )', $wpdb->posts, esc_sql( $post_slug ), esc_sql( $post_slug_alt ) );
  32.         $url_posts = $wpdb->get_col( $sql_query );
  33.        
  34.         // Example (can be removed later)
  35.         if ( $post_slug == 'permalink-manager' ) {
  36.             $post_id = (int) reset( $url_posts );
  37.             $post    = get_post( $post_id );
  38.            
  39.             $orte_term = get_term_by( 'slug', $term_slug, 'orte' );
  40.         } else {
  41.             // 2B. Get all posts that are assigned to a "ort" term extracted from URL
  42.             $sql_query = sprintf( 'SELECT object_id FROM %s AS tr LEFT JOIN %s AS t ON tr.term_taxonomy_id = t.term_id WHERE t.slug = "%s"', $wpdb->term_relationships, $wpdb->terms, esc_sql( $term_slug ) );
  43.             $ort_posts = $wpdb->get_col( $sql_query );
  44.  
  45.             // 2C. Check what posts are in both arrays (there should be only one post)
  46.             if ( ! empty( $url_posts ) && ! empty( $ort_posts ) ) {
  47.                 $found_posts = array_intersect( $url_posts, $ort_posts );
  48.  
  49.                 if ( ! empty( $found_posts ) ) {
  50.                     $post_id = (int) reset( $found_posts );
  51.                     $post    = get_post( $post_id );
  52.                 }
  53.             }  
  54.         }
  55.     } // If no post was found, check if the URL is used by a post without "orte" term
  56.     else if ( ! empty( $query['name'] ) ) {
  57.  
  58.         $sql_query = sprintf( 'SELECT ID, post_title FROM %1$s p WHERE post_type IN ( "dienstleistung", "hersteller" ) AND (post_name = "%2$s" OR post_name LIKE "%2$s-%%") AND post_status = "publish" AND ID NOT IN (SELECT object_id FROM %3$s tr INNER JOIN %4$s tt ON tr.term_taxonomy_id = tt.term_taxonomy_id AND tt.taxonomy = "orte")', $wpdb->posts, basename( $query['name'] ), $wpdb->term_relationships, $wpdb->term_taxonomy );
  59.         $post_id   = $wpdb->get_var( $sql_query );
  60.  
  61.         if ( ! empty( $post_id ) ) {
  62.             $post = get_post( $post_id );
  63.         }
  64.     }
  65.  
  66.     // 3. Set the query parameters
  67.     if ( ! empty( $post->post_name ) ) {
  68.         $new_query = array(
  69.             'post_type'       => $post->post_type,
  70.             $post->post_type  => $post->post_name,
  71.             'name'            => $post->post_name,
  72.             'do_not_redirect' => 1,
  73.         );
  74.     }
  75.  
  76.     // 4. Debug the query parameters
  77.     if ( isset( $_GET['debug_bis_query'] ) ) {
  78.         $new_query = ( ! empty( $new_query ) ) ? $new_query : $query;
  79.         var_dump( $parts );
  80.  
  81.         echo ( ! empty( $parts ) ) ? sprintf( '<h2>URL Parts:</h2><pre>%s</pre>', print_r( $parts, true ) ) : '';
  82.         echo ( ! empty( $sql_query ) ) ? sprintf( '<h2>SQL query:</h2><pre>%s</pre>', print_r( $sql_query, true ) ) : '';
  83.         echo ( ! empty( $query ) ) ? sprintf( '<h2>Old query value:</h2><pre>%s</pre>', print_r( $query, true ) ) : '';
  84.         echo ( ! empty( $new_query ) ) ? sprintf( '<h2>New query value Parts:</h2><pre>%s</pre>', print_r( $new_query, true ) ) : '';
  85.         echo ( ! empty( $term_slug ) ) ? sprintf( '<h2>Detected "orte" slug:</h2><pre>%s</pre>', print_r( $term_slug, true ) ) : '';
  86.  
  87.         die();
  88.     }
  89.  
  90.     // 5. Overwrite the query object & disable canonical redirect
  91.     if ( ! empty( $new_query ) ) {
  92.         remove_action( 'template_redirect', 'wp_old_slug_redirect' );
  93.         remove_action( 'template_redirect', 'redirect_canonical' );
  94.         add_filter( 'wpml_is_redirected', '__return_false', 99, 2 );
  95.         add_filter( 'pll_check_canonical_url', '__return_false', 99, 2 );
  96.  
  97.         $query = $new_query;
  98.     }
  99.  
  100.     return $query;
  101. }
  102.  
  103. add_filter( 'request', 'bis_detect_cpt_permalinks', 9999 );
  104.  
  105. /**
  106.  * Rewrite permalinks
  107.  */
  108. function bis_filter_cpt_permalinks( $permalink, $post, $leavename, $sample ) {
  109.     if ( empty( $post->post_type ) || $post->post_status !== 'publish' ) {
  110.         return $permalink;
  111.     }
  112.  
  113.     if ( in_array( $post->post_type, array(
  114.         'hersteller',
  115.         'dienstleistung'
  116.     ) ) ) {
  117.         // Get the slug of assigned 'orte' term
  118.         $o_terms       = wp_get_object_terms( $post->ID, 'orte' );
  119.         $o_lowest_term = ( ! is_wp_error( $o_terms ) && ! empty( $o_terms ) && is_object( $o_terms[0] ) ) ? bis_get_lowest_element( $o_terms[0], $o_terms ) : "";
  120.         $o_slug        = ( ! empty( $o_lowest_term->slug ) ) ? $o_lowest_term->slug : '';
  121.  
  122.         // A. Hersteller
  123.         if ( $post->post_type == 'hersteller' ) {
  124.  
  125.             // Get the slug of assigned 'herstellerkategorie' term
  126.             $h_terms       = wp_get_object_terms( $post->ID, 'herstellerkategorie' );
  127.             $h_lowest_term = ( ! is_wp_error( $h_terms ) && ! empty( $h_terms ) && is_object( $h_terms[0] ) ) ? bis_get_lowest_element( $h_terms[0], $h_terms ) : "";
  128.             $h_slug        = ( ! empty( $h_lowest_term->slug ) ) ? $h_lowest_term->slug : '';
  129.  
  130.             // If some specific 'herstellerkategorie' terms are assigned, the term slug should not be appended to the end of URL
  131.             // Permalink format: datenrettung-%orte_flat%/%hersteller%
  132.             if ( in_array( $h_slug, array( 'raid' ) ) && ! empty ( $o_slug ) ) {
  133.                 $new_permalink = sprintf( '%s/datenrettung-%s', trim( get_option( 'home' ), '/' ), $o_slug );
  134.                 $new_slug      = sanitize_title( $post->post_title );
  135.             } // Permalink format: datenrettung-%orte_flat%/%hersteller%-%herstellerkategorie%
  136.             else if ( ! empty( $o_slug ) && ! empty ( $h_slug ) ) {
  137.                 $new_permalink = sprintf( '%s/datenrettung-%s', trim( get_option( 'home' ), '/' ), $o_slug );
  138.                 $new_slug      = sprintf( '%s-%s', sanitize_title( $post->post_title ), $h_slug );
  139.             } // Permalink format: %hersteller%-%herstellerkategorie%
  140.             else {
  141.                 $new_permalink = trim( get_option( 'home' ), '/' );
  142.                 $new_slug      = sanitize_title( $post->post_title );
  143.             }
  144.         }
  145.  
  146.         // B. Dienstleistung
  147.         if ( $post->post_type == 'dienstleistung' ) {
  148.             // Permalink format: datenrettung-%orte_flat%/%dienstleistung%
  149.             if ( ! empty( $o_slug ) ) {
  150.                 $new_permalink = sprintf( '%s/datenrettung-%s', trim( get_option( 'home' ), '/' ), $o_slug );
  151.                 $new_slug      = sanitize_title( $post->post_title );
  152.             } // Permalink format: %dienstleistung%
  153.             else {
  154.                 $new_permalink = trim( get_option( 'home' ), '/' );
  155.                 $new_slug      = sanitize_title( $post->post_title );
  156.             }
  157.         }
  158.  
  159.         if ( ! empty( $sample ) ) {
  160.             $new_permalink .= "/%{$post->post_type}%";
  161.         } else if ( empty( $leavename ) ) {
  162.             $new_permalink .= "/{$new_slug}";
  163.         }
  164.  
  165.         $permalink = user_trailingslashit( $new_permalink );
  166.     }
  167.  
  168.     return $permalink;
  169. }
  170.  
  171. add_filter( 'post_type_link', 'bis_filter_cpt_permalinks', 1000, 4 );
  172.  
  173. /**
  174.  * Register [orte] shortcode
  175.  */
  176. function bis_orte_shortcode($atts, $content) {
  177.     global $orte_term;
  178.    
  179.     $atts = shortcode_atts( array(
  180.         'before'   => 'in',
  181.         'after'    => 'in',
  182.         'no-orte'  => ''
  183.     ), $atts, 'orte' );
  184.    
  185.     if ( !empty( $orte_term->slug ) ) {
  186.         $orte = $orte_term->name;
  187.     }
  188.  
  189.     // If 'orte' was found, use it
  190.     if(!empty($orte)) {
  191.         $html = (!empty($atts['before'])) ? $atts['before'] : '';
  192.         $html .= $orte;
  193.         $html .= (!empty($atts['after'])) ? $atts['after'] : '';   
  194.     }
  195.     // If no 'orte' was found, use alternative text (if set in shortcode)
  196.     else if(!empty($atts['no-orte'])) {
  197.         $html = $atts['no-orte'];
  198.     } else {
  199.         $html = '';
  200.     }
  201.    
  202.     return $html;
  203. }
  204. add_shortcode( 'orte', 'bis_orte_shortcode' );
  205.  
  206. /**
  207.  * Allow shortcodes in the titles
  208.  */
  209. add_filter( 'the_title', 'do_shortcode' );
  210.  
  211. /**
  212.  * Get the lowest-level term
  213.  */
  214. function bis_get_lowest_element( $first_element, $elements ) {
  215.     if ( ! empty( $elements ) && ! empty( $first_element ) ) {
  216.         // Get the ID of first element
  217.         if ( ! empty( $first_element->term_id ) ) {
  218.             $first_element_id = $first_element->term_id;
  219.             $parent_key       = 'parent';
  220.         } else if ( ! empty( $first_element->ID ) ) {
  221.             $first_element_id = $first_element->ID;
  222.             $parent_key       = 'post_parent';
  223.         } else if ( is_numeric( $first_element ) ) {
  224.             $first_element_id = $first_element;
  225.             $parent_key       = 'post_parent';
  226.         } else {
  227.             return false;
  228.         }
  229.  
  230.         $children = wp_filter_object_list( $elements, array(
  231.             $parent_key => $first_element_id
  232.         ) );
  233.         if ( ! empty( $children ) ) {
  234.             // Get the first term
  235.             $child_term    = reset( $children );
  236.             $first_element = bis_get_lowest_element( $child_term, $elements );
  237.         }
  238.     }
  239.  
  240.     return $first_element;
  241. }
  242.  
  243.  
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement