View difference between Paste ID: pd5d5itk and DEQTrunM
SHOW: | | - or go back to the newest paste.
1
<?php
2
3
/*
4-
 * Plugin Name: Rewrite "Hersteller" & "Dienstleistungen" permalinks
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 ad permalinks
14+
 * Detect CPT permalinks
15
 */
16
function bis_detect_cpt_permalinks( $query ) {
17-
	global $wpdb, $pm_query, $wp, $wp_rewrite;
17+
	global $wpdb, $pm_query, $wp, $wp_rewrite, $orte_term;
18
19
	// 1. Extract the slugs
20-
	preg_match( '/datenrettung-([^\/]+)\/(([^\/]*)(-[^-\/]+))(?:\/|$)/Ui', $wp->request, $parts );
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-
		$sql_query = sprintf( 'SELECT ID FROM %1$s WHERE 1=1 AND 
27+
28-
		(
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
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-%%"))
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-
		)
31+
		)', $wpdb->posts, esc_sql( $post_slug ), esc_sql( $post_slug_alt ) );
32-
		', $wpdb->posts, esc_sql( $post_slug ), esc_sql( $post_slug_alt ) );
32+
33
		
34
		// Example (can be removed later)
35-
		// 2B. Get all posts that are assigned to a "ort" term extracted from URL
35+
		if ( $post_slug == 'permalink-manager' ) {
36-
		$term_slug = basename( $parts[1] );
36+
			$post_id = (int) reset( $url_posts );
37
			$post    = get_post( $post_id );
38-
		$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 ) );
38+
			
39
			$orte_term = get_term_by( 'slug', $term_slug, 'orte' );
40-
		$ort_posts = $wpdb->get_col( $sql_query );
40+
41
			// 2B. Get all posts that are assigned to a "ort" term extracted from URL
42-
		// 2C. Check what posts are in both arrays (there should be only one post)
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-
		if ( ! empty( $url_posts ) && ! empty( $ort_posts ) ) {
43+
			$ort_posts = $wpdb->get_col( $sql_query );
44-
			$found_posts = array_intersect( $url_posts, $ort_posts );
44+
45
			// 2C. Check what posts are in both arrays (there should be only one post)
46-
			if ( ! empty( $found_posts ) ) {
46+
			if ( ! empty( $url_posts ) && ! empty( $ort_posts ) ) {
47-
				$post_id = (int) reset( $found_posts );
47+
				$found_posts = array_intersect( $url_posts, $ort_posts );
48-
				$post    = get_post( $post_id );
48+
49
				if ( ! empty( $found_posts ) ) {
50
					$post_id = (int) reset( $found_posts );
51
					$post    = get_post( $post_id );
52-
		if ( ! empty( $post->post_name ) ) {
52+
				}
53-
			$new_query = array(
53+
			}	
54-
				'post_type'       => $post->post_type,
54+
55-
				$post->post_type  => $post->post_name,
55+
	} // If no post was found, check if the URL is used by a post without "orte" term
56-
				'name'            => $post->post_name,
56+
	else if ( ! empty( $query['name'] ) ) {
57-
				'do_not_redirect' => 1,
57+
58-
			);
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-
		// 3. Debug the query parameters
61+
		if ( ! empty( $post_id ) ) {
62-
		if ( isset( $_GET['debug_bis_query'] ) ) {
62+
			$post = get_post( $post_id );
63-
			printf( '<pre>%s</pre> <pre>%s</pre> <pre>%s</pre>', print_r( $parts, true ), print_r( $query, true ), print_r( $new_query, true ) );
63+
64-
			die();
64+
65
66
	// 3. Set the query parameters
67-
		// 4. Overwrite the query object & Disable canonical redirect
67+
	if ( ! empty( $post->post_name ) ) {
68-
		if ( ! empty( $new_query ) ) {
68+
		$new_query = array(
69-
			remove_action( 'template_redirect', 'wp_old_slug_redirect' );
69+
			'post_type'       => $post->post_type,
70-
			remove_action( 'template_redirect', 'redirect_canonical' );
70+
			$post->post_type  => $post->post_name,
71-
			add_filter( 'wpml_is_redirected', '__return_false', 99, 2 );
71+
			'name'            => $post->post_name,
72-
			add_filter( 'pll_check_canonical_url', '__return_false', 99, 2 );
72+
			'do_not_redirect' => 1,
73
		);
74-
			$query = $new_query;
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-
function pm_filter_cpt_permalinks( $permalink, $post ) {
86+
87
		die();
88
	}
89
90
	// 5. Overwrite the query object & disable canonical redirect
91-
	if ( in_array( $post->post_type, array( 'hersteller', 'dienstleistung' ) ) ) {
91+
	if ( ! empty( $new_query ) ) {
92-
		// Get the slug of assigned 'orte' term 
92+
		remove_action( 'template_redirect', 'wp_old_slug_redirect' );
93
		remove_action( 'template_redirect', 'redirect_canonical' );
94-
		$o_lowest_term = ( ! is_wp_error( $o_terms ) && ! empty( $o_terms ) && is_object( $o_terms[0] ) ) ? pm_get_lowest_element( $o_terms[0], $o_terms ) : "";
94+
		add_filter( 'wpml_is_redirected', '__return_false', 99, 2 );
95
		add_filter( 'pll_check_canonical_url', '__return_false', 99, 2 );
96
97-
		// A. Hersteller (datenrettung-%orte_flat%/%hersteller%-%herstellerkategorie%)
97+
		$query = $new_query;
98
	}
99
100-
			// Get the slug of assigned 'herstellerkategorie' term 
100+
101
}
102-
			$h_lowest_term = ( ! is_wp_error( $h_terms ) && ! empty( $h_terms ) && is_object( $h_terms[0] ) ) ? pm_get_lowest_element( $h_terms[0], $h_terms ) : "";
102+
103
add_filter( 'request', 'bis_detect_cpt_permalinks', 9999 );
104
105-
			$new_permalink = sprintf( '%s/datenrettung-%s/%s-%s', trim( get_option( 'home' ), '/' ), $o_slug, sanitize_title( $post->post_title ), $h_slug );
105+
106
 * Rewrite permalinks
107
 */
108-
		// B. Datenrettung (datenrettung-%orte_flat%/%dienstleistung%)
108+
function bis_filter_cpt_permalinks( $permalink, $post, $leavename, $sample ) {
109
	if ( empty( $post->post_type ) || $post->post_status !== 'publish' ) {
110-
			$new_permalink = sprintf( '%s/datenrettung-%s/%s', trim( get_option( 'home' ), '/' ), $o_slug, sanitize_title( $post->post_title ) );
110+
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-
add_filter( 'post_type_link', 'pm_filter_cpt_permalinks', 1000, 2 );
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-
function pm_get_lowest_element( $first_element, $elements ) {
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-
		$children = wp_filter_object_list( $elements, array( $parent_key => $first_element_id ) );
140+
			else {
141
				$new_permalink = trim( get_option( 'home' ), '/' );
142
				$new_slug      = sanitize_title( $post->post_title );
143
			}
144-
			$first_element = pm_get_lowest_element( $child_term, $elements );
144+
145
146
		// B. Dienstleistung
147
		if ( $post->post_type == 'dienstleistung' ) {
148
			// Permalink format: datenrettung-%orte_flat%/%dienstleistung%
149-
}
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