Completed
Push — add/custom-footer-credit ( e10c01...2f6095 )
by
unknown
71:55 queued 55:59
created

theme-optimizations.php ➔ wpcom_is_pub_theme()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 3
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
eloc 2
nc 1
nop 0
dl 0
loc 3
rs 10
c 0
b 0
f 0
1
<?php
2
3
if( ! function_exists ( 'wpcom_is_vip' ) ){
4
	function wpcom_is_vip() {
5
		return false;
6
	}
7
}
8
if( ! function_exists ( 'wpcom_is_pub_theme' ) ){
9
	function wpcom_is_pub_theme() {
10
		return false;
11
	}
12
}
13
if( ! function_exists ( 'wpcom_is_premium_theme' ) ){
14
	function wpcom_is_premium_theme() {
15
		return false;
16
	}
17
}
18
if( ! function_exists ( 'wpcom_is_vip_theme' ) ){
19
	function wpcom_is_vip_theme() {
20
		return false;
21
	}
22
}
23
if( ! function_exists ( 'wpcom_is_a8c_theme' ) ){
24
	function wpcom_is_a8c_theme() {
25
		return false;
26
	}
27
}
28
/**
29
 * Create an output buffer to capture the HTML content of the footer.php theme
30
 * template. Used to change links, text, run a/b tests. Etc.
31
 *
32
 * @param string $page The HTML content from footer.php template file.
33
 * @return string $page HTML content.
34
 */
35
function wpcom_better_footer_links_buffer( $page ) {
36
	// Only add theme and colophon links for pub and premium themes, and VIP "partner" themes.
37
	if ( ! wpcom_is_pub_theme() && ! wpcom_is_premium_theme() && ! wpcom_is_vip_theme() && ! wpcom_is_a8c_theme() ) {
38
		return $page;
39
	}
40
41
	// Would like to only see footer content before wp_footer output.
42
	$output = preg_split( '/wpcom_wp_footer/i', $page, 2 );
43
44
	// Run "better link" filters.
45
	$footer = wpcom_better_footer_links( $output[0] );
46
47
	// Piece back together again.
48
	$page = implode( array( $footer, 'wpcom_wp_footer' . $output[1] ) );
49
50
	// If nothing to join, return empty string.
51
	if ( 'wpcom_wp_footer' === $page ) {
52
		return '';
53
	}
54
55
	// Replace any dangling references of glue code.
56
	$page = preg_replace( '/wpcom_wp_footer/i', '', $page );
57
58
	return $page;
59
}
60
61
/**
62
 * Better WP.com footer links.
63
 *
64
 * 1. Replace default "Powered by WordPress" text and link with
65
 * a link to WordPress.com and custom call-out text.
66
 *
67
 * 2. Replace theme name in footer with a link to relevant theme page on the Theme Showcase.
68
 * URL structure: http://theme.wordpress.com/themes/{theme-slug}/
69
 *
70
 * 3. Link to the Vertical landing page for sites that are stickered with a vertical.
71
 *
72
 * @param string $footer Footer HTML content to filter.
73
 * @return string $footer Filtered HTML content.
74
 */
75
function wpcom_better_footer_links( $footer ) {
76
	// Only add theme and colophon links for pub and premium themes, and VIP "partner" themes.
77
	if ( ! wpcom_is_pub_theme() && ! wpcom_is_premium_theme() && ! wpcom_is_vip_theme() && ! wpcom_is_a8c_theme() ) {
78
		return $footer;
79
	}
80
81
	// Get current theme data.
82
	$theme = wp_get_theme();
83
84
	// Replace separator from content, since we are replacing theme and designer credits.
85
	// Any span separator with a .sep class will be matched and replaced by the regular expression.
86
	$footer = preg_replace("/\s\|\s(?=\<a)|\<span class=\"([^\"]+\s)?sep(\s[^\"]+)?\">.*<\/span>/i", '', $footer);
87
88
	// Handle WP.com footer text.
89
	$lang = get_bloginfo( 'language' );
90
91
	$_blog_id = get_current_blog_id();
92
	$vertical = site_vertical( $_blog_id );
93
94
	$noads = defined( 'NOADVERTS' ) || defined( 'NOADSUPGRADE' );
95
	if ( $vertical ) {
96
		if ( $noads ) {
97
			$credit_link = sprintf( '<a href="%s">%s.</a>', localized_wpcom_url( 'https://wordpress.com/' . $vertical . '/?ref=vertical_footer', $lang ), __( 'Blog at WordPress.com' ) );
98
		} else {
99
			$credit_link = sprintf( '<a href="%s">%s.</a>', localized_wpcom_url( 'https://wordpress.com/' . $vertical . '/?ref=vertical_footer', $lang ), __( 'Create a free website at WordPress.com' ) );
100
		}
101
	} else if ( $noads || mt_rand( 0, 1 ) ) {
102
		$credit_link = sprintf( '<a href="%s">%s.</a>', localized_wpcom_url( 'https://wordpress.com/?ref=footer_blog', $lang ), __( 'Blog at WordPress.com' ) );
103
	} else {
104
		$credit_link = sprintf( '<a href="%s">%s.</a>', localized_wpcom_url( 'https://wordpress.com/?ref=footer_website', $lang ), __( 'Create a free website or blog at WordPress.com' ) );
105
	}
106
107
	// Replace credit link in footer, and make sure it is replaced only once, to avoid duplicates.
108
	$credit_link = apply_filters( 'wpcom_better_footer_credit_link', $credit_link, $lang );
109
110
	// The regular expression to match the credit link replacement.
111
	$credit_regex = implode( '', array(
112
		'#' , // Open delimiter
113
			'<a[^>]*href="http(s?)://(([a-z]{2}|www)\.)?(wordpress|wordpress-fr|wpfr)\.(com|org|net)/?"([^>]+)?>' , // Opening link tag
114
			    '\s*'   , // Optional whitespace
115
			    '(.+?)' , // Any word or sentence
116
			    '\s*'   , // Optional whitespace
117
			'</a>'      , // Closing link tag
118
			'\.?'       , // Optional period
119
			'(\s*&[^;]+;\s*)?' , // Optional HTML Entity
120
		'#i' , // Ending delimiter & modifier
121
	) );
122
123
	// Add filter for specific themes that may need to tweak the regex a bit.
124
	$credit_regex = apply_filters( 'wpcom_better_footer_credit_regex', $credit_regex, $theme );
125
126
	// Get the full matches of the credit regular expression, proceed if match.
127
	if ( preg_match_all( $credit_regex, $footer, $matches, PREG_OFFSET_CAPTURE ) ) {
128
129
		// Get last match and offset.
130
		$match = array_pop( $matches[0] );
131
		$offset = $match[1];
132
133
		// Split the content into two parts, which we will join later on.
134
		$before = substr( $footer, 0, $offset );
135
		$after = substr( $footer, $offset );
136
137
		// Replace on the last part. Ensure we only do one replacement to avoid duplicates.
138
		$after = preg_replace( $credit_regex, $credit_link, $after, 1 );
139
140
		// Join the two parts.
141
		$footer = $before . $after;
142
143
	}
144
145
	// Themes that have duplicate footer credit links (e.g. "Powered by WordPress.com" + another credit link).
146
	$powered_by_themes = array(
147
		'pub/toujours',
148
	);
149
150
	// Remove "Proudly powered by WordPress" on selected themes.
151
	if ( in_array( $theme->stylesheet, $powered_by_themes ) ) {
152
		$powered_string = preg_quote( __( 'Proudly powered by WordPress' ), '#' );
153
		$powered_regex = sprintf( '#<a[^>]*href="http(s?)://(([a-z]{2}|www)\.)?wordpress\.(com|org)/?"([^>]+)?>%s</a>\.?#i', $powered_string );
154
		$footer = preg_replace( $powered_regex, '', $footer );
155
	}
156
157
	// Only add theme and colophon link for pub and premium themes.
158
	if ( wpcom_is_vip_theme() ) {
159
		return $footer;
160
	}
161
162
	// Handle adding Theme Name and colophon link to footer text.
163
	$theme_match = sprintf(
164
		'(?:\s*\|\s*)?'       . // Optional pipe with spaces (non-capturing)
165
		'(?:<span\s[^>]+>)?'  . // Optional opening span tag (non-capturing)
166
		'(Theme|%s)'          . // $1: "Theme" or the localized equivalent
167
		'\s*(?:&nbsp;)?:\s*'  . // Zero or more whitespace characters, a colon, zero or more whitespace characters
168
		'(%s|<a[^>]+>%s</a>)' . // $2: The theme name, or link
169
		'\.?'                 . // Optional period
170
		'(?:</span>)?'        . // Optional closing span tag (non-capturing)
171
		'\.?'                   // Optional period
172
173
		, preg_quote( __( 'Theme' ), '#' )
174
		, preg_quote( $theme->name, '#' )
175
		, preg_quote( $theme->name, '#' )
176
	);
177
178
	// Theme designer match.
179
	$designer_match = $theme_match . sprintf(
180
		'('                       . // Start $3
181
		    '\s*'                 . // Zero or more whitespace characters
182
		    '(?:<span\s[^>]+>)?'  . // Optional opening span tag (non-capturing)
183
		    '(?:by|%s)'           . // "by" or the localized equivalent (non-capturing)
184
		    '(?:</span>)?'        . // Optional closing span tag (non-capturing)
185
		    '\s*'                 . // Zero or more whitespace characters
186
		    '(<a[^>]+>.+?</a>)?'  . // $4: Maybe a full <a> element
187
		')'                       . // End $3
188
		'\.?'                       // Optional period
189
190
		, preg_quote( __( 'by' ), '#' ) // localized "by" preposition
191
	);
192
193
	// Match "Design by <shop>".
194
	$design_by = preg_quote( $credit_link, '#' ) . sprintf(
195
		'\.?'                . // Optional period
196
		'\s*'                . // Optional whitespace
197
		'(Design by|%s)'     . // "Design by" or localized equivalent
198
		'\s*'                . // Optional whitespace
199
		'(<a[^>]+>.+?</a>)'  . // Full link element
200
		'\.?'                  // Optional period
201
202
		, preg_quote( __( 'Design by' ), '#' )
203
	);
204
205
	if ( preg_match( "#$designer_match#i", $footer ) ) {
206
		$footer = preg_replace( "#$designer_match#i", '', $footer, 1 );
207
	}
208
209
	if ( preg_match( "#$theme_match#i", $footer ) ) {
210
		$footer = preg_replace( "#$theme_match#i", '', $footer, 1 );
211
	}
212
213
	if ( preg_match( "#$design_by#i", $footer ) ) {
214
		$footer = preg_replace( "#$design_by#i", $credit_link, $footer, 1 );
215
	}
216
217
	return $footer;
218
}
219
220
// Enable filters for footer content for all themes, except VIP sites.
221
function better_wpcom_link_init() {
222
	if ( ! wpcom_is_vip() )
223
		ob_start( 'wpcom_better_footer_links_buffer' );
224
}
225
add_action( 'get_footer', 'better_wpcom_link_init' );
226
227
// Enable filters on those themes that need special treatment.
228
function better_wpcom_link_workarounds_init() {
229
	if ( function_exists( 'blogly_widgets_init' ) && 'premium/blogly' === wp_get_theme()->stylesheet ) {
230
		add_action( 'get_sidebar', 'better_wpcom_link_init' );
231
	}
232
	if ( function_exists( 'designer_widgets_init' ) && 'premium/designer' === wp_get_theme()->stylesheet ) {
233
		add_action( 'get_header', 'better_wpcom_link_init' );
234
	}
235
}
236
add_action( 'init', 'better_wpcom_link_workarounds_init' );
237
238
// Enable filters Infinite Scroll footer conntent, except VIP sites.
239
//if ( ! wpcom_is_vip() ) {
240
	add_filter( 'infinite_scroll_credit', 'wpcom_better_footer_links' );
241
//}
242
243
/**
244
 * Filters the default footer credits regex.
245
 *
246
 * @param string $credit_regex The regular expression for the footer credit.
247
 * @param object $theme The object returned by `wp_get_theme()`
248
 * @return string
249
 */
250
function wpcom_better_footer_credit_regex_filter( $credit_regex, $theme ) {
251
	// Twotone renders the social menu after the credit links. If there is a WordPress.com link in the menu,
252
	// it will break the footer credits. Adding a space before the actual link fixes this.
253
	if ( 'premium/twotone' === $theme->stylesheet ) {
254
		$credit_regex = str_replace( '#<a', '#\s<a', $credit_regex );
255
	}
256
	return $credit_regex;
257
}
258
add_filter( 'wpcom_better_footer_credit_regex', 'wpcom_better_footer_credit_regex_filter', 10, 2 );
259
260
/**
261
 * Add an HTML comment flag for wp_footer output so that our footer replacement
262
 * script knows when to stop looking for more footer content.
263
 */
264
function wpcom_footer_html_comment_flag() {
265
	echo "<!-- wpcom_wp_footer -->\n";
266
}
267
add_action( 'wp_footer', 'wpcom_footer_html_comment_flag', 9 );
268
269
/**
270
 * Add theme name to Twenty Ten footer
271
 */
272
function wpcomthemes_twentyten_credits() {
273
	echo 'Theme: Twenty Ten'; // leave untranslated for regex match, will be translated in final output
274
}
275
add_action( 'twentyten_credits', 'wpcomthemes_twentyten_credits' );
276
277
/**
278
 * Add theme name to Twenty Eleven footer
279
 */
280
function wpcomthemes_twentyeleven_credits() {
281
	echo 'Theme: Twenty Eleven <span class="sep"> | </span>'; // leave untranslated for regex match, will be translated in final output
282
}
283
add_action( 'twentyeleven_credits', 'wpcomthemes_twentyeleven_credits' );
284
285
/**
286
 * Add theme name to Twenty Twelve footer
287
 */
288
function wpcomthemes_twentytwelve_credits() {
289
	echo 'Theme: Twenty Twelve.'; // leave untranslated for regex match, will be translated in final output
290
}
291
add_action( 'twentytwelve_credits', 'wpcomthemes_twentytwelve_credits' );
292
293
/**
294
 * Add theme name to Twenty Thirteen footer
295
 */
296
function wpcomthemes_twentythirteen_credits() {
297
	echo 'Theme: Twenty Thirteen.'; // leave untranslated for regex match, will be translated in final output
298
}
299
add_action( 'twentythirteen_credits', 'wpcomthemes_twentythirteen_credits' );
300
301
/**
302
 * Add theme name to Twenty Fourteen footer
303
 */
304
function wpcomthemes_twentyfourteen_credits() {
305
	echo 'Theme: Twenty Fourteen.'; // leave untranslated for regex match, will be translated in final output
306
}
307
add_action( 'twentyfourteen_credits', 'wpcomthemes_twentyfourteen_credits' );
308
309
/**
310
 * Add theme name to Twenty Fifteen footer
311
 */
312
function wpcomthemes_twentyfifteen_credits() {
313
	echo 'Theme: Twenty Fifteen.'; // leave untranslated for regex match, will be translated in final output
314
}
315
add_action( 'twentyfifteen_credits', 'wpcomthemes_twentyfifteen_credits' );
316
317
/**
318
 * Add theme name to Twenty Sixteen footer
319
 */
320
function wpcomthemes_twentysixteen_credits() {
321
	echo 'Theme: Twenty Sixteen.'; // leave untranslated for regex match, will be translated in final output
322
}
323
add_action( 'twentysixteen_credits', 'wpcomthemes_twentysixteen_credits' );
324
325